Package gherkin.formatter

Source Code of gherkin.formatter.FilterFormatter

package gherkin.formatter;

import gherkin.formatter.model.Background;
import gherkin.formatter.model.BasicStatement;
import gherkin.formatter.model.Examples;
import gherkin.formatter.model.Feature;
import gherkin.formatter.model.Range;
import gherkin.formatter.model.Row;
import gherkin.formatter.model.Scenario;
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;
import gherkin.formatter.model.Tag;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

public class FilterFormatter implements Formatter {
    private final Formatter formatter;
    private final Filter filter;
    private List<Tag> featureTags;
    private List<Tag> featureElementTags;
    private List<Tag> examplesTags;

    private List<BasicStatement> featureEvents;
    private List<BasicStatement> backgroundEvents;
    private List<BasicStatement> featureElementEvents;
    private List<BasicStatement> examplesEvents;
    private String featureName;
    private String featureElementName;
    private String examplesName;
    private Range featureElementRange;
    private Range examplesRange;

    public FilterFormatter(Formatter formatter, List filters) {
        this.formatter = formatter;
        this.filter = detectFilter(filters);

        featureTags = new ArrayList<Tag>();
        featureElementTags = new ArrayList<Tag>();
        examplesTags = new ArrayList<Tag>();

        featureEvents = new ArrayList<BasicStatement>();
        backgroundEvents = new ArrayList<BasicStatement>();
        featureElementEvents = new ArrayList<BasicStatement>();
        examplesEvents = new ArrayList<BasicStatement>();
    }

    private Filter detectFilter(List filters) {
        Set<Class> filterClasses = new HashSet<Class>();
        for (Object filter : filters) {
            filterClasses.add(filter.getClass());
        }
        if (filterClasses.size() > 1) {
            throw new IllegalArgumentException("Inconsistent filters: " + filters + ". Only one type [line,name,tag] can be used at once.");
        }

        Class<?> typeOfFilter = filters.get(0).getClass();
        if (String.class.isAssignableFrom(typeOfFilter)) {
            return new TagFilter(filters);
        } else if (Number.class.isAssignableFrom(typeOfFilter)) {
            return new LineFilter(filters);
        } else if (Pattern.class.isAssignableFrom(typeOfFilter)) {
            return new PatternFilter(filters);
        } else {
            throw new RuntimeException("Could not create filter method for unknown filter of type: " + typeOfFilter);
        }
    }

    @Override
    public void uri(String uri) {
        formatter.uri(uri);
    }

    @Override
    public void feature(Feature feature) {
        featureTags = feature.getTags();
        featureName = feature.getName();
        featureEvents = new ArrayList<BasicStatement>();
        featureEvents.add(feature);
    }

    @Override
    public void background(Background background) {
        featureElementName = background.getName();
        featureElementRange = background.getLineRange();
        backgroundEvents = new ArrayList<BasicStatement>();
        backgroundEvents.add(background);
    }

    @Override
    public void scenario(Scenario scenario) {
        replay();
        featureElementTags = scenario.getTags();
        featureElementName = scenario.getName();
        featureElementRange = scenario.getLineRange();
        featureElementEvents = new ArrayList<BasicStatement>();
        featureElementEvents.add(scenario);
    }

    @Override
    public void scenarioOutline(ScenarioOutline scenarioOutline) {
        replay();
        featureElementTags = scenarioOutline.getTags();
        featureElementName = scenarioOutline.getName();
        featureElementRange = scenarioOutline.getLineRange();
        featureElementEvents = new ArrayList<BasicStatement>();
        featureElementEvents.add(scenarioOutline);
    }

    @Override
    public void examples(Examples examples) {
        replay();
        examplesTags.addAll(examples.getTags());
        examplesName = examples.getName();

        Range tableBodyRange;
        switch (examples.getRows().size()) {
            case 0:
                tableBodyRange = new Range(examples.getLineRange().getLast(), examples.getLineRange().getLast());
                break;
            case 1:
                tableBodyRange = new Range(examples.getRows().get(0).getLine(), examples.getRows().get(0).getLine());
                break;
            default:
                tableBodyRange = new Range(examples.getRows().get(1).getLine(), examples.getRows().get(examples.getRows().size() - 1).getLine());
        }
        examplesRange = new Range(examples.getLineRange().getFirst(), tableBodyRange.getLast());
        if (filter.evaluate(Collections.<Tag>emptyList(), Collections.<String>emptyList(), Collections.singletonList(tableBodyRange))) {
            examples.setRows(filter.filterTableBodyRows(examples.getRows()));
        }
        examplesEvents = new ArrayList<BasicStatement>();
        examplesEvents.add(examples);

    }

    @Override
    public void step(Step step) {
        if (!featureElementEvents.isEmpty()) {
            featureElementEvents.add(step);
        } else {
            backgroundEvents.add(step);
        }
        featureElementRange = new Range(featureElementRange.getFirst(), step.getLineRange().getLast());
    }

    public void table(List<Row> table) {
    }

    @Override
    public void eof() {
        replay();
        formatter.eof();
    }

    @Override
    public void syntaxError(String state, String event, List<String> legalEvents, String uri, Integer line) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void done() {
        formatter.done();
    }

    @Override
    public void close() {
        formatter.close();
    }

    @Override
    public void startOfScenarioLifeCycle(Scenario scenario) {
        // NoOp
    }

    @Override
    public void endOfScenarioLifeCycle(Scenario scenario) {
        // NoOp
    }

    private void replay() {
        List<Tag> feTags = new ArrayList<Tag>(featureTags);
        feTags.addAll(featureElementTags);
        List<String> feNames = Arrays.asList(featureName, featureElementName);
        List<Range> feRanges = Arrays.asList(featureElementRange);
        boolean featureElementOk = filter.evaluate(feTags, feNames, feRanges);

        List<Tag> exTags = new ArrayList<Tag>(feTags);
        exTags.addAll(examplesTags);
        List<String> exNames = new ArrayList<String>(feNames);
        exNames.add(examplesName);
        List<Range> exRanges = new ArrayList<Range>(feRanges);
        exRanges.add(examplesRange);
        boolean examplesOk = filter.evaluate(exTags, exNames, exRanges);

        if (featureElementOk || examplesOk) {
            replayEvents(featureEvents);
            replayEvents(backgroundEvents);
            replayEvents(featureElementEvents);
            if (examplesOk) {
                replayEvents(examplesEvents);
            }
        }
        examplesEvents.clear();
        examplesTags.clear();
        examplesName = null;
        examplesRange = null;
    }

    private void replayEvents(List<BasicStatement> events) {
        for (BasicStatement event : events) {
            event.replay(formatter);
        }
        events.clear();
    }

}
TOP

Related Classes of gherkin.formatter.FilterFormatter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.