package cuke4duke.internal.jvmclass; import cuke4duke.StepMother; import cuke4duke.annotation.Order; import cuke4duke.internal.java.JavaAnalyzer; import cuke4duke.internal.java.JavaHook; import cuke4duke.spi.ExceptionFactory; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; import java.util.Collections; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; public class ClassLanguageTest { private ClassLanguage language; @Before public void createLanguage() throws Throwable { language = new ClassLanguage(mock(ClassLanguageMixin.class), mock(ExceptionFactory.class), mock(StepMother.class), Collections.<ClassAnalyzer> emptyList()); } @Test public void shouldLoadExistingClassFromJavaFileName() throws Throwable { language.load_code_file("foo/java/lang/String.class"); } @Test(expected = ClassNotFoundException.class) public void shouldFailToLoadMissingClassFromJavaFileName() throws Throwable { language.load_code_file("foo/java/lang/Strix.class"); } public static class A { private final B b; public A(B b) { this.b = b; } @cuke4duke.annotation.Before() @Order(1) public void doA() { assertEquals("Heldlo from B", b.message); } } public static class B { public String message; @cuke4duke.annotation.Before() @Order(2) public void doB() { message = "Hello from B"; } } @Test public void shouldRunBeforeHooksInOrderOfDependencies() throws Throwable { ObjectFactory objectFactory = new PicoFactory(); ClassLanguageMixin languageMixin = mock(ClassLanguageMixin.class); language = new ClassLanguage(languageMixin, mock(ExceptionFactory.class), mock(StepMother.class), Collections.<ClassAnalyzer>singletonList(new JavaAnalyzer()), objectFactory); language.addClass(A.class); language.addClass(B.class); language.begin_scenario(null); InOrder order = inOrder(languageMixin); order.verify(languageMixin).add_hook(eq("before"), argThat(isHook("doA"))); order.verify(languageMixin).add_hook(eq("before"), argThat(isHook("doB"))); } private Matcher<JavaHook> isHook(String methodName) { return new HookMatcher(methodName); } private class HookMatcher extends BaseMatcher<JavaHook> { private final String methodName; private String actualMethodName; public HookMatcher(String methodName) { this.methodName = methodName; } public void describeTo(Description description) { description.appendText("Expected " + methodName + ", but got " + actualMethodName); } public boolean matches(Object o) { JavaHook hook = (JavaHook) o; actualMethodName = hook.getMethod().getName(); return methodName.equals(actualMethodName); } } }