package cucumber.runtime.java; import cucumber.api.java.en.Given; import cucumber.runtime.AmbiguousStepDefinitionsException; import cucumber.runtime.DuplicateStepDefinitionException; import cucumber.runtime.Glue; import cucumber.runtime.Runtime; import cucumber.runtime.RuntimeOptions; import cucumber.runtime.io.ClasspathResourceLoader; import gherkin.I18n; import gherkin.formatter.Reporter; import gherkin.formatter.model.Comment; import gherkin.formatter.model.Match; import gherkin.formatter.model.Result; import gherkin.formatter.model.Scenario; import gherkin.formatter.model.Step; import gherkin.formatter.model.Tag; import org.junit.Test; import org.mockito.ArgumentCaptor; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; public class JavaStepDefinitionTest { private static final List<Comment> NO_COMMENTS = Collections.emptyList(); private static final Method THREE_DISABLED_MICE; private static final Method THREE_BLIND_ANIMALS; private static final I18n ENGLISH = new I18n("en"); static { try { THREE_DISABLED_MICE = Defs.class.getMethod("threeDisabledMice", String.class); THREE_BLIND_ANIMALS = Defs.class.getMethod("threeBlindAnimals", String.class); } catch (NoSuchMethodException e) { throw new InternalError("dang"); } } private final Defs defs = new Defs(); private final JavaBackend backend = new JavaBackend(new SingletonFactory(defs)); private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); private final RuntimeOptions runtimeOptions = new RuntimeOptions(""); private final Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions); private final Glue glue = runtime.getGlue(); @org.junit.Before public void loadNoGlue() { backend.loadGlue(glue, Collections.<String>emptyList()); } @Test(expected = DuplicateStepDefinitionException.class) public void throws_duplicate_when_two_stepdefs_with_same_regexp_found() throws Throwable { backend.addStepDefinition(THREE_BLIND_ANIMALS.getAnnotation(Given.class), THREE_DISABLED_MICE); backend.addStepDefinition(THREE_BLIND_ANIMALS.getAnnotation(Given.class), THREE_BLIND_ANIMALS); } @Test public void throws_ambiguous_when_two_matches_are_found() throws Throwable { backend.addStepDefinition(THREE_DISABLED_MICE.getAnnotation(Given.class), THREE_DISABLED_MICE); backend.addStepDefinition(THREE_BLIND_ANIMALS.getAnnotation(Given.class), THREE_BLIND_ANIMALS); Reporter reporter = mock(Reporter.class); runtime.buildBackendWorlds(reporter, Collections.<Tag>emptySet(), mock(Scenario.class)); Tag tag = new Tag("@foo", 0); runtime.runBeforeHooks(reporter, asSet(tag)); runtime.runStep("some.feature", new Step(NO_COMMENTS, "Given ", "three blind mice", 1, null, null), reporter, ENGLISH); ArgumentCaptor<Result> result = ArgumentCaptor.forClass(Result.class); verify(reporter).result(result.capture()); assertEquals(AmbiguousStepDefinitionsException.class, result.getValue().getError().getClass()); } @Test public void does_not_throw_ambiguous_when_nothing_is_ambiguous() throws Throwable { backend.addStepDefinition(THREE_DISABLED_MICE.getAnnotation(Given.class), THREE_DISABLED_MICE); Reporter reporter = new Reporter() { @Override public void before(Match match, Result result) { throw new UnsupportedOperationException(); } @Override public void result(Result result) { if (result.getError() != null) { throw new RuntimeException(result.getError()); } } @Override public void after(Match match, Result result) { throw new UnsupportedOperationException(); } @Override public void match(Match match) { } @Override public void embedding(String mimeType, byte[] data) { } @Override public void write(String text) { } }; runtime.buildBackendWorlds(reporter, Collections.<Tag>emptySet(), mock(Scenario.class)); Tag tag = new Tag("@foo", 0); Set<Tag> tags = asSet(tag); runtime.runBeforeHooks(reporter, tags); Step step = new Step(NO_COMMENTS, "Given ", "three blind mice", 1, null, null); runtime.runStep("some.feature", step, reporter, ENGLISH); assertTrue(defs.foo); assertFalse(defs.bar); } public static class Defs { public boolean foo; public boolean bar; @Given(value = "three (.*) mice") public void threeDisabledMice(String disability) { foo = true; } @Given(value = "three blind (.*)") public void threeBlindAnimals(String animals) { bar = true; } } private <T> Set<T> asSet(T... items) { Set<T> set = new HashSet<T>(); set.addAll(asList(items)); return set; } }