Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Gherkin v4 #1035

Merged
merged 31 commits into from
May 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5f704b9
Update versions to 2.0.0-SNAPSHOT and gherkin to 4.0.0.
brasmusson Jul 16, 2016
51c8656
Change the maven groupId to io.cucumber.
brasmusson Jul 31, 2016
aca512d
[Core] Updated core for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
5df2263
[JUnit] Updated junit for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
41c169a
[Java] Updated java for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
d66b876
[Java8] Updated java8 for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
de5fe34
[Android] Updated android for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
c9af7f5
[Clojure] Updated clojure for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
46a35ba
[Groovy] Udated groovy for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
7c88881
[JRuby] Updated jruby for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
7841adf
[Jython] Updated jython for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
d50a9d9
[Rhino] Updated rhino for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
90ce0a3
[Scala] Updated scala for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
9021844
[TestNG] Updated testng for the use of Gherkin v4.0.0.
brasmusson Jul 16, 2016
1af20c5
Use the tag-expressions library.
brasmusson Sep 6, 2016
3b226f6
[Core] Update the Pretty formatter to use events.
brasmusson Jan 3, 2017
15cf206
[Core] Update the HTML formatter to use events.
brasmusson Jan 3, 2017
603a537
Timestamp all events.
brasmusson Jan 6, 2017
78d1fa8
Update to use gherkin v4.1.1.
brasmusson Mar 18, 2017
b3795da
Remove usage of reflection to access data of Gherkin classes.
brasmusson Dec 18, 2016
6675ff8
[Core] update to Gherkin5.
brasmusson Dec 18, 2016
b61e551
[Junit] update to Gherkin5.
brasmusson Dec 19, 2016
f7f47cb
[Java] update to Gherkin5.
brasmusson Dec 19, 2016
372d2f8
[Java] Fix the code generation for the Georgian language.
brasmusson Dec 19, 2016
c249030
[Android] update to Gherkin5.
brasmusson Dec 20, 2016
f18c845
[Core] Add language to pickles.
brasmusson Jan 21, 2017
c4fe882
[Java] Add language to pickles.
brasmusson Jan 21, 2017
ea184e6
[Android] Do not pass the language outside the pickle.
brasmusson Jan 21, 2017
fe3a8bb
[Core] Do not pass the language outside the pickle.
brasmusson Jan 21, 2017
4243175
[Java] Do not pass the language outside the pickle.
brasmusson Jan 21, 2017
fd1b645
[Junit] Do not pass the language outside the pickle.
brasmusson Jan 21, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions android/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>info.cukes</groupId>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.2.6-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>cucumber-android</artifactId>
Expand All @@ -30,7 +30,7 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import android.app.Instrumentation;
import android.os.Bundle;
import cucumber.api.Result;
import cucumber.api.TestCase;
import cucumber.api.event.EventHandler;
import cucumber.api.event.EventPublisher;
import cucumber.api.event.TestCaseFinished;
import cucumber.api.event.TestCaseStarted;
import cucumber.api.event.TestStepFinished;
import cucumber.api.formatter.Formatter;
import cucumber.runtime.Runtime;
import gherkin.formatter.model.Feature;
import gherkin.formatter.model.Match;
import gherkin.formatter.model.Result;
import gherkin.formatter.model.Scenario;

import java.io.PrintWriter;
import java.io.StringWriter;
Expand All @@ -30,7 +34,7 @@
* hook threw an exception other than an {@link AssertionError}</li>
* </ul>
*/
public class AndroidInstrumentationReporter extends NoOpFormattingReporter {
public class AndroidInstrumentationReporter implements Formatter {

/**
* Tests status keys.
Expand Down Expand Up @@ -74,9 +78,44 @@ public static class StatusCodes {
private Result severestResult;

/**
* The feature of the current test execution.
* The location in the feature file of the current test case.
*/
private Feature currentFeature;
private String currentPath;

/**
* The name of the current test case.
*/
private String currentTestCaseName;

/**
* The event handler for the {@link TestCaseStarted} events.
*/
private final EventHandler<TestCaseStarted> testCaseStartedHandler = new EventHandler<TestCaseStarted>() {
@Override
public void receive(TestCaseStarted event) {
startTestCase(event.testCase);
}
};

/**
* The event handler for the {@link TestStepFinished} events.
*/
private final EventHandler<TestStepFinished> testStepFinishedHandler = new EventHandler<TestStepFinished>() {
@Override
public void receive(TestStepFinished event) {
finishTestStep(event.result);
}
};

/**
* The event handler for the {@link TestCaseFinished} events.
*/
private final EventHandler<TestCaseFinished> testCaseFinishedHandler = new EventHandler<TestCaseFinished>() {
@Override
public void receive(TestCaseFinished event) {
finishTestCase();
}
};

/**
* Creates a new instance for the given parameters
Expand All @@ -96,36 +135,26 @@ public AndroidInstrumentationReporter(
}

@Override
public void feature(final Feature feature) {
currentFeature = feature;
public void setEventPublisher(final EventPublisher publisher) {
publisher.registerHandlerFor(TestCaseStarted.class, testCaseStartedHandler);
publisher.registerHandlerFor(TestCaseFinished.class, testCaseFinishedHandler);
publisher.registerHandlerFor(TestStepFinished.class, testStepFinishedHandler);
}

@Override
public void startOfScenarioLifeCycle(final Scenario scenario) {
void startTestCase(final TestCase testCase) {
currentPath = testCase.getPath();
currentTestCaseName = testCase.getName();
resetSeverestResult();
final Bundle testStart = createBundle(currentFeature, scenario);
final Bundle testStart = createBundle(currentPath, currentTestCaseName);
instrumentation.sendStatus(StatusCodes.START, testStart);
}

@Override
public void before(final Match match, final Result result) {
checkAndSetSeverestStepResult(result);
}

@Override
public void result(final Result result) {
void finishTestStep(final Result result) {
checkAndSetSeverestStepResult(result);
}

@Override
public void after(final Match match, final Result result) {
checkAndSetSeverestStepResult(result);
}

@Override
public void endOfScenarioLifeCycle(final Scenario scenario) {

final Bundle testResult = createBundle(currentFeature, scenario);
void finishTestCase() {
final Bundle testResult = createBundle(currentPath, currentTestCaseName);

if (severestResult.getStatus().equals(Result.FAILED)) {

Expand All @@ -149,7 +178,7 @@ public void endOfScenarioLifeCycle(final Scenario scenario) {
return;
}

if (severestResult.getStatus().equals(Result.UNDEFINED.getStatus())) {
if (severestResult.getStatus().equals(Result.UNDEFINED)) {
testResult.putString(StatusKeys.STACK, getStackTrace(new MissingStepDefinitionError(getLastSnippet())));
instrumentation.sendStatus(StatusCodes.ERROR, testResult);
return;
Expand All @@ -161,15 +190,15 @@ public void endOfScenarioLifeCycle(final Scenario scenario) {
/**
* Creates a template bundle for reporting the start and end of a test.
*
* @param feature the {@link Feature} of the current execution
* @param scenario the {@link Scenario} of the current execution
* @param path of the feature file of the current execution
* @param name of the test case of the current execution
* @return the new {@link Bundle}
*/
private Bundle createBundle(final Feature feature, final Scenario scenario) {
private Bundle createBundle(final String path, final String testCaseName) {
final Bundle bundle = new Bundle();
bundle.putInt(StatusKeys.NUMTESTS, numberOfTests);
bundle.putString(StatusKeys.CLASS, String.format("%s %s", feature.getKeyword(), feature.getName()));
bundle.putString(StatusKeys.TEST, String.format("%s %s", scenario.getKeyword(), scenario.getName()));
bundle.putString(StatusKeys.CLASS, String.format("%s", path));
bundle.putString(StatusKeys.TEST, String.format("%s", testCaseName));
return bundle;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package cucumber.runtime.android;

import android.util.Log;
import cucumber.api.event.EventHandler;
import cucumber.api.event.EventPublisher;
import cucumber.api.event.TestCaseStarted;
import cucumber.api.event.TestRunFinished;
import cucumber.api.event.TestStepStarted;
import cucumber.api.formatter.Formatter;
import cucumber.runtime.Runtime;
import gherkin.formatter.model.Background;
import gherkin.formatter.model.Examples;
import gherkin.formatter.model.Feature;
import gherkin.formatter.model.Scenario;
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;
import java.util.List;

/**
* Logs information about the currently executed statements to androids logcat.
*/
public class AndroidLogcatReporter extends NoOpFormattingReporter {
public class AndroidLogcatReporter implements Formatter {

/**
* The {@link cucumber.runtime.Runtime} to get the errors and snippets from for writing them to the logcat at the end of the execution.
Expand All @@ -26,9 +25,43 @@ public class AndroidLogcatReporter extends NoOpFormattingReporter {
private final String logTag;

/**
* Holds the feature's uri.
* The event handler that logs the {@link TestCaseStarted} events.
*/
private String uri;
private final EventHandler<TestCaseStarted> testCaseStartedHandler = new EventHandler<TestCaseStarted>() {
@Override
public void receive(TestCaseStarted event) {
Log.d(logTag, String.format("%s", event.testCase.getName()));
}
};

/**
* The event handler that logs the {@link TestStepStarted} events.
*/
private final EventHandler<TestStepStarted> testStepStartedHandler = new EventHandler<TestStepStarted>() {
@Override
public void receive(TestStepStarted event) {
if (!event.testStep.isHook()) {
Log.d(logTag, String.format("%s", event.testStep.getStepText()));
}
}
};

/**
* The event handler that logs the {@link TestRunFinished} events.
*/
private EventHandler<TestRunFinished> runFinishHandler = new EventHandler<TestRunFinished>() {

@Override
public void receive(TestRunFinished event) {
for (final Throwable throwable : runtime.getErrors()) {
Log.e(logTag, throwable.toString());
}

for (final String snippet : runtime.getSnippets()) {
Log.w(logTag, snippet);
}
}
};

/**
* Creates a new instance for the given parameters.
Expand All @@ -42,53 +75,9 @@ public AndroidLogcatReporter(final Runtime runtime, final String logTag) {
}

@Override
public void uri(final String uri) {
this.uri = uri;
}

@Override
public void feature(final Feature feature) {
Log.d(logTag, String.format("%s: %s (%s)%n%s", feature.getKeyword(), feature.getName(), uri, feature.getDescription()));
}

@Override
public void background(final Background background) {
Log.d(logTag, background.getName());
}

@Override
public void scenario(final Scenario scenario) {
Log.d(logTag, String.format("%s: %s", scenario.getKeyword(), scenario.getName()));
}

@Override
public void scenarioOutline(final ScenarioOutline scenarioOutline) {
Log.d(logTag, String.format("%s: %s", scenarioOutline.getKeyword(), scenarioOutline.getName()));
}

@Override
public void examples(final Examples examples) {
Log.d(logTag, String.format("%s: %s", examples.getKeyword(), examples.getName()));
}

@Override
public void step(final Step step) {
Log.d(logTag, String.format("%s%s", step.getKeyword(), step.getName()));
}

@Override
public void syntaxError(final String state, final String event, final List<String> legalEvents, final String uri, final Integer line) {
Log.e(logTag, String.format("syntax error '%s' %s:%d", event, uri, line));
}

@Override
public void done() {
for (final Throwable throwable : runtime.getErrors()) {
Log.e(logTag, throwable.toString());
}

for (final String snippet : runtime.getSnippets()) {
Log.w(logTag, snippet);
}
public void setEventPublisher(final EventPublisher publisher) {
publisher.registerHandlerFor(TestCaseStarted.class, testCaseStartedHandler);
publisher.registerHandlerFor(TestStepStarted.class, testStepStartedHandler);
publisher.registerHandlerFor(TestRunFinished.class, runFinishHandler);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import android.util.Log;
import cucumber.api.CucumberOptions;
import cucumber.api.StepDefinitionReporter;
import cucumber.api.event.TestRunFinished;
import cucumber.api.formatter.Formatter;
import cucumber.api.java.ObjectFactory;
import cucumber.runtime.Backend;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.CucumberException;
Expand All @@ -14,12 +17,10 @@
import cucumber.runtime.RuntimeOptionsFactory;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.java.JavaBackend;
import cucumber.api.java.ObjectFactory;
import cucumber.runtime.java.ObjectFactoryLoader;
import cucumber.runtime.model.CucumberFeature;
import dalvik.system.DexFile;
import gherkin.formatter.Formatter;
import gherkin.formatter.Reporter;
import gherkin.events.PickleEvent;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -67,9 +68,9 @@ public class CucumberExecutor {
private final Runtime runtime;

/**
* The actual {@link CucumberFeature}s to run.
* The actual {@link PickleEvent}s to run stored in {@link PickleStruct}s.
*/
private final List<CucumberFeature> cucumberFeatures;
private final List<PickleEvent> pickleEvents;

/**
* Creates a new instance for the given parameters.
Expand All @@ -89,7 +90,8 @@ public CucumberExecutor(final Arguments arguments, final Instrumentation instrum

ResourceLoader resourceLoader = new AndroidResourceLoader(context);
this.runtime = new Runtime(resourceLoader, classLoader, createBackends(), runtimeOptions);
this.cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader);
List<CucumberFeature> cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader, runtime.getEventBus());
this.pickleEvents = FeatureCompiler.compile(cucumberFeatures, this.runtime);
}

/**
Expand All @@ -102,25 +104,23 @@ public void execute() {

// TODO: This is duplicated in info.cucumber.Runtime.

final Reporter reporter = runtimeOptions.reporter(classLoader);
final Formatter formatter = runtimeOptions.formatter(classLoader);

final StepDefinitionReporter stepDefinitionReporter = runtimeOptions.stepDefinitionReporter(classLoader);
runtime.getGlue().reportStepDefinitions(stepDefinitionReporter);
runtime.reportStepDefinitions(stepDefinitionReporter);

for (final CucumberFeature cucumberFeature : cucumberFeatures) {
cucumberFeature.run(formatter, reporter, runtime);
for (final PickleEvent pickleEvent : pickleEvents) {
runtime.getRunner().runPickle(pickleEvent);
}

formatter.done();
formatter.close();
runtime.getEventBus().send(new TestRunFinished(runtime.getEventBus().getTime()));
}

/**
* @return the number of actual scenarios, including outlined
*/
public int getNumberOfConcreteScenarios() {
return ScenarioCounter.countScenarios(cucumberFeatures);
return pickleEvents.size();
}

private void trySetCucumberOptionsToSystemProperties(final Arguments arguments) {
Expand Down
Loading