Skip to content

Commit

Permalink
Merge branch 'master' into android
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Sep 12, 2013
2 parents b86999f + b0496b3 commit e44cc9c
Show file tree
Hide file tree
Showing 24 changed files with 388 additions and 56 deletions.
2 changes: 2 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## [1-1-5-SNAPSHOT (Git master)](https://github.com/cucumber/cucumber-jvm/compare/v1.1.4...master)

* [Core] Step Definition and Hook timeout is now a `long` instead of an `int`. (Aslak Hellesøy)
* [Rhino] Before and After hooks support ([#587](https://github.com/cucumber/cucumber-jvm/pull/587) Rui Figueira)
* [Android] Separate CI job for Android. ([#581](https://github.com/cucumber/cucumber-jvm/issues/581), [#584](https://github.com/cucumber/cucumber-jvm/pull/584) Björn Rasmusson)
* [Android] Add support for Dependency Injection via cucumber-picocontainer, cucumber-guice, cucumber-spring etx. (Aslak Hellesøy)
* [TestNG] Java Calculator TestNG example project ([#579](https://github.com/cucumber/cucumber-jvm/pull/579) Dmytro Chyzhykov)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/runtime/Timeout.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.concurrent.atomic.AtomicBoolean;

public class Timeout {
public static <T> T timeout(Callback<T> callback, int timeoutMillis) throws Throwable {
public static <T> T timeout(Callback<T> callback, long timeoutMillis) throws Throwable {
if (timeoutMillis == 0) {
return callback.call();
} else {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/runtime/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static boolean isInstantiable(Class<?> clazz) {
return Modifier.isPublic(clazz.getModifiers()) && !Modifier.isAbstract(clazz.getModifiers()) && !isNonStaticInnerClass;
}

public static Object invoke(final Object target, final Method method, int timeoutMillis, final Object... args) throws Throwable {
public static Object invoke(final Object target, final Method method, long timeoutMillis, final Object... args) throws Throwable {
return Timeout.timeout(new Timeout.Callback<Object>() {
@Override
public Object call() throws Throwable {
Expand Down
44 changes: 39 additions & 5 deletions examples/java-helloworld/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,50 @@ The Cucumber runtime parses command line options to know what features to run, w
When you use the JUnit runner, these options are generated from the `@Cucumber.Options` annotation on your test.

Sometimes it can be useful to override these options without changing or recompiling the JUnit class. This can be done with the
`cucumber.options` system property. Here are a couple of examples:
`cucumber.options` system property. The general form is:

With Maven:
Using Maven:
```
mvn -Dcucumber.options="..." test
```

Using Ant:
```
JAVA_OPTIONS='-Dcucumber.options="..."' ant runcukes
```

Let's look at some things you can do with `cucumber.options`. Try this:
```
-Dcucumber.options="--help"
```

That should list all the available options.

#### Run a subset of Features or Scenarios

Specify a particular scenario by *line* (and use the pretty format)

```
-Dcucumber.options="classpath:cucumber/examples/java/helloworld/helloworld.feature:4 --format pretty"
```

This works because Maven puts `./src/test/resources` on your `classpath`.
You can also specify files to run by filesystem path:

```
mvn -Dcucumber.options="--format junit:target/cucumber-junit-report.xml" test
-Dcucumber.options="src/test/resources/cucumber/examples/java/helloworld/helloworld.feature:4 --format pretty"
```

Or with Ant:
You can also specify what to run by *tag*:

```
_JAVA_OPTIONS='-Dcucumber.options="--format json-pretty:target/cucumber-json-report.json"' ant runcukes
-Dcucumber.options="--tags @bar --format pretty"
```

#### Specify a different formatter:

For example a JUnit formatter:
```
-Dcucumber.options="--format junit:target/cucumber-junit-report.xml"
```

2 changes: 1 addition & 1 deletion groovy/src/main/code_generator/I18n.groovy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class ${i18n.underscoredIsoCode.toUpperCase()} {
GroovyBackend.instance.addStepDefinition(regexp, 0, body);
}

public static void ${java.text.Normalizer.normalize(kw, java.text.Normalizer.Form.NFD)}(Pattern regexp, int timeoutMillis, Closure body) throws Throwable {
public static void ${java.text.Normalizer.normalize(kw, java.text.Normalizer.Form.NFD)}(Pattern regexp, long timeoutMillis, Closure body) throws Throwable {
GroovyBackend.instance.addStepDefinition(regexp, timeoutMillis, body);
}
<% } %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public String getSnippet(Step step, FunctionNameSanitizer functionNameSanitizer)
return snippetGenerator.getSnippet(step, null);
}

public void addStepDefinition(Pattern regexp, int timeoutMillis, Closure body) {
public void addStepDefinition(Pattern regexp, long timeoutMillis, Closure body) {
glue.addStepDefinition(new GroovyStepDefinition(regexp, timeoutMillis, body, currentLocation(), instance));
}

Expand All @@ -132,11 +132,11 @@ public void registerWorld(Closure closure) {
worldClosure = closure;
}

public void addBeforeHook(TagExpression tagExpression, int timeoutMillis, Closure body) {
public void addBeforeHook(TagExpression tagExpression, long timeoutMillis, Closure body) {
glue.addBeforeHook(new GroovyHookDefinition(tagExpression, timeoutMillis, body, currentLocation(), instance));
}

public void addAfterHook(TagExpression tagExpression, int timeoutMillis, Closure body) {
public void addAfterHook(TagExpression tagExpression, long timeoutMillis, Closure body) {
glue.addAfterHook(new GroovyHookDefinition(tagExpression, timeoutMillis, body, currentLocation(), instance));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

public class GroovyHookDefinition implements HookDefinition {
private final TagExpression tagExpression;
private final int timeoutMillis;
private final long timeoutMillis;
private final Closure body;
private final GroovyBackend backend;
private final StackTraceElement location;

public GroovyHookDefinition(TagExpression tagExpression, int timeoutMillis, Closure body, StackTraceElement location, GroovyBackend backend) {
public GroovyHookDefinition(TagExpression tagExpression, long timeoutMillis, Closure body, StackTraceElement location, GroovyBackend backend) {
this.tagExpression = tagExpression;
this.timeoutMillis = timeoutMillis;
this.body = body;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
public class GroovyStepDefinition implements StepDefinition {
private final Pattern pattern;
private final JdkPatternArgumentMatcher argumentMatcher;
private final int timeoutMillis;
private final long timeoutMillis;
private final Closure body;
private final StackTraceElement location;
private final GroovyBackend backend;
private List<ParameterInfo> parameterInfos;

public GroovyStepDefinition(Pattern pattern, int timeoutMillis, Closure body, StackTraceElement location, GroovyBackend backend) {
public GroovyStepDefinition(Pattern pattern, long timeoutMillis, Closure body, StackTraceElement location, GroovyBackend backend) {
this.pattern = pattern;
this.timeoutMillis = timeoutMillis;
this.backend = backend;
Expand Down
4 changes: 2 additions & 2 deletions java/src/main/code_generator/I18n.java.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public @interface ${kw} {
String value();

/**
* @return max amount of time this is allowed to run for. 0 (default) means no restriction.
* @return max amount of milliseconds this is allowed to run for. 0 (default) means no restriction.
*/
int timeout() default 0;
long timeout() default 0;
}

4 changes: 2 additions & 2 deletions java/src/main/java/cucumber/api/java/After.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
String[] value() default {};

/**
* @return max amount of time this is allowed to run for. 0 (default) means no restriction.
* @return max amount of milliseconds this is allowed to run for. 0 (default) means no restriction.
*/
int timeout() default 0;
long timeout() default 0;

/**
* The order in which this hook should run. Higher numbers are run first.
Expand Down
4 changes: 2 additions & 2 deletions java/src/main/java/cucumber/api/java/Before.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
String[] value() default {};

/**
* @return max amount of time this is allowed to run for. 0 (default) means no restriction.
* @return max amount of milliseconds this is allowed to run for. 0 (default) means no restriction.
*/
int timeout() default 0;
long timeout() default 0;

/**
* The order in which this hook should run. Lower numbers are run first.
Expand Down
10 changes: 5 additions & 5 deletions java/src/main/java/cucumber/runtime/java/JavaBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public String getSnippet(Step step, FunctionNameSanitizer functionNameSanitizer)
void addStepDefinition(Annotation annotation, Method method) {
try {
objectFactory.addClass(method.getDeclaringClass());
glue.addStepDefinition(new JavaStepDefinition(method, pattern(annotation), timeout(annotation), objectFactory));
glue.addStepDefinition(new JavaStepDefinition(method, pattern(annotation), timeoutMillis(annotation), objectFactory));
} catch (DuplicateStepDefinitionException e) {
throw e;
} catch (Throwable e) {
Expand All @@ -123,21 +123,21 @@ private Pattern pattern(Annotation annotation) throws Throwable {
return Pattern.compile(regexpString);
}

private int timeout(Annotation annotation) throws Throwable {
private long timeoutMillis(Annotation annotation) throws Throwable {
Method regexpMethod = annotation.getClass().getMethod("timeout");
return (Integer) Utils.invoke(annotation, regexpMethod, 0);
return (Long) Utils.invoke(annotation, regexpMethod, 0);
}

void addHook(Annotation annotation, Method method) {
objectFactory.addClass(method.getDeclaringClass());

if (annotation.annotationType().equals(Before.class)) {
String[] tagExpressions = ((Before) annotation).value();
int timeout = ((Before) annotation).timeout();
long timeout = ((Before) annotation).timeout();
glue.addBeforeHook(new JavaHookDefinition(method, tagExpressions, ((Before) annotation).order(), timeout, objectFactory));
} else {
String[] tagExpressions = ((After) annotation).value();
int timeout = ((After) annotation).timeout();
long timeout = ((After) annotation).timeout();
glue.addAfterHook(new JavaHookDefinition(method, tagExpressions, ((After) annotation).order(), timeout, objectFactory));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
class JavaHookDefinition implements HookDefinition {

private final Method method;
private final int timeout;
private final long timeoutMillis;
private final TagExpression tagExpression;
private final int order;
private final ObjectFactory objectFactory;

public JavaHookDefinition(Method method, String[] tagExpressions, int order, int timeout, ObjectFactory objectFactory) {
public JavaHookDefinition(Method method, String[] tagExpressions, int order, long timeoutMillis, ObjectFactory objectFactory) {
this.method = method;
this.timeout = timeout;
this.timeoutMillis = timeoutMillis;
tagExpression = new TagExpression(asList(tagExpressions));
this.order = order;
this.objectFactory = objectFactory;
Expand Down Expand Up @@ -56,7 +56,7 @@ public void execute(Scenario scenario) throws Throwable {
throw new CucumberException("Hooks must declare 0 or 1 arguments. " + method.toString());
}

Utils.invoke(objectFactory.getInstance(method.getDeclaringClass()), method, timeout, args);
Utils.invoke(objectFactory.getInstance(method.getDeclaringClass()), method, timeoutMillis, args);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@
class JavaStepDefinition implements StepDefinition {
private final Method method;
private final Pattern pattern;
private final int timeout;
private final long timeout;
private final JdkPatternArgumentMatcher argumentMatcher;
private final ObjectFactory objectFactory;
private List<ParameterInfo> parameterInfos;

public JavaStepDefinition(Method method, Pattern pattern, int timeout, ObjectFactory objectFactory) {
public JavaStepDefinition(Method method, Pattern pattern, long timeoutMillis, ObjectFactory objectFactory) {
this.method = method;
this.parameterInfos = ParameterInfo.fromMethod(method);
this.pattern = pattern;
this.argumentMatcher = new JdkPatternArgumentMatcher(pattern);
this.timeout = timeout;
this.timeout = timeoutMillis;
this.objectFactory = objectFactory;
}

Expand Down
5 changes: 5 additions & 0 deletions rhino/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.cobertura</groupId>
<artifactId>cobertura</artifactId>
Expand Down
44 changes: 29 additions & 15 deletions rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package cucumber.runtime.rhino;

import static cucumber.runtime.io.MultiLoader.packageName;
import gherkin.formatter.model.Step;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeFunction;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.regexp.NativeRegExp;
import org.mozilla.javascript.tools.shell.Global;

import cucumber.runtime.Backend;
import cucumber.runtime.CucumberException;
import cucumber.runtime.Glue;
Expand All @@ -8,18 +22,6 @@
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.snippets.FunctionNameSanitizer;
import cucumber.runtime.snippets.SnippetGenerator;
import gherkin.formatter.model.Step;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeFunction;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.regexp.NativeRegExp;
import org.mozilla.javascript.tools.shell.Global;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import static cucumber.runtime.io.MultiLoader.packageName;

public class RhinoBackend implements Backend {
private static final String JS_DSL = "/cucumber/runtime/rhino/dsl.js";
Expand Down Expand Up @@ -56,7 +58,7 @@ public void loadGlue(Glue glue, List<String> gluePaths) {

@Override
public void setUnreportedStepExecutor(UnreportedStepExecutor executor) {
//Not used yet
// Not used yet
}

@Override
Expand All @@ -72,7 +74,7 @@ public String getSnippet(Step step, FunctionNameSanitizer functionNameSanitizer)
return snippetGenerator.getSnippet(step, functionNameSanitizer);
}

private StackTraceElement stepDefLocation() {
private StackTraceElement jsLocation() {
Throwable t = new Throwable();
StackTraceElement[] stackTraceElements = t.getStackTrace();
for (StackTraceElement stackTraceElement : stackTraceElements) {
Expand All @@ -89,8 +91,20 @@ private StackTraceElement stepDefLocation() {
}

public void addStepDefinition(Global jsStepDefinition, NativeRegExp regexp, NativeFunction bodyFunc, NativeFunction argumentsFromFunc) throws Throwable {
StackTraceElement stepDefLocation = stepDefLocation();
StackTraceElement stepDefLocation = jsLocation();
RhinoStepDefinition stepDefinition = new RhinoStepDefinition(cx, scope, jsStepDefinition, regexp, bodyFunc, stepDefLocation, argumentsFromFunc);
glue.addStepDefinition(stepDefinition);
}

public void addBeforeHook(Function fn, String[] tags, int order, long timeoutMillis) {
StackTraceElement stepDefLocation = jsLocation();
RhinoHookDefinition hookDefinition = new RhinoHookDefinition(cx, scope, fn, tags, order, timeoutMillis, stepDefLocation);
glue.addBeforeHook(hookDefinition);
}

public void addAfterHook(Function fn, String[] tags, int order, long timeoutMillis) {
StackTraceElement stepDefLocation = jsLocation();
RhinoHookDefinition hookDefinition = new RhinoHookDefinition(cx, scope, fn, tags, order, timeoutMillis, stepDefLocation);
glue.addAfterHook(hookDefinition);
}
}
Loading

0 comments on commit e44cc9c

Please sign in to comment.