diff --git a/src/main/java/be/klak/junit/jasmine/JasmineDescriptions.java b/src/main/java/be/klak/junit/jasmine/JasmineDescriptions.java index b6c9fd5..d8ddb20 100755 --- a/src/main/java/be/klak/junit/jasmine/JasmineDescriptions.java +++ b/src/main/java/be/klak/junit/jasmine/JasmineDescriptions.java @@ -1,40 +1,24 @@ package be.klak.junit.jasmine; import java.util.Collection; -import java.util.Map; - import org.junit.runner.Description; -import be.klak.rhino.RhinoContext; - - class JasmineDescriptions { - private final Description rootDescription; - private final Map specsMap; - private final RhinoContext rhinoContext; + private final Description rootDescription; + private final Collection specs; - JasmineDescriptions(Description rootDescription, Map specsMap, RhinoContext context) { - this.rootDescription = rootDescription; - this.specsMap = specsMap; - this.rhinoContext = context; - } + public JasmineDescriptions(Description rootDescription, Collection specs) { + this.rootDescription = rootDescription; + this.specs = specs; + } - public Description getRootDescription() { - return rootDescription; - } - - public Collection getAllSpecs() { - return specsMap.values(); - } - - public void executeSpec(Description description) { - getSpec(description).execute(rhinoContext); - } - - public JasmineSpec getSpec(Description description) { - return specsMap.get(description.getDisplayName()); - } + public Description getRootDescription() { + return rootDescription; + } + public Collection getSpecs() { + return specs; + } } diff --git a/src/main/java/be/klak/junit/jasmine/JasmineJSSuiteConverter.java b/src/main/java/be/klak/junit/jasmine/JasmineJSSuiteConverter.java index 093ed29..19bb70c 100755 --- a/src/main/java/be/klak/junit/jasmine/JasmineJSSuiteConverter.java +++ b/src/main/java/be/klak/junit/jasmine/JasmineJSSuiteConverter.java @@ -1,9 +1,8 @@ package be.klak.junit.jasmine; import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.Map; - +import java.util.ArrayList; +import java.util.List; import org.junit.runner.Description; import org.mozilla.javascript.NativeArray; @@ -11,49 +10,58 @@ import org.mozilla.javascript.NativeObject; import be.klak.rhino.RhinoContext; +public class JasmineJSSuiteConverter { -class JasmineJSSuiteConverter { + private final RhinoContext context; - private final NativeArray baseSuites; - private final RhinoContext context; + public JasmineJSSuiteConverter(RhinoContext context) { + this.context = context; + } - JasmineJSSuiteConverter(NativeArray baseSuites, RhinoContext context) { - this.baseSuites = baseSuites; - this.context = context; - } + public JasmineDescriptions convertToJunitDescriptions(Class testClass, NativeArray baseSuites) { + Description rootDescription = Description.createSuiteDescription(testClass); + List specs = convertSuiteArrayToDescriptions(baseSuites, rootDescription, new ArrayList()); + return new JasmineDescriptions(rootDescription, specs); + } - public JasmineDescriptions convertToJunitDescriptions(Class testClass) { - Description rootDescription = Description.createSuiteDescription(testClass); - Map specsMap = convertSuiteArrayToDescriptions(this.baseSuites, rootDescription); - return new JasmineDescriptions(rootDescription, specsMap, context); - } + private List convertSuiteArrayToDescriptions(NativeArray suiteArray, Description rootDescription, + List processed) { + List specs = new ArrayList(); + for (Object idObj : suiteArray.getIds()) { + NativeObject suite = (NativeObject) suiteArray.get((Integer) idObj, suiteArray); - private Map convertSuiteArrayToDescriptions(NativeArray suiteArray, Description rootDescription) { - Map specsMap = new HashMap(); - for (Object idObj : suiteArray.getIds()) { - NativeObject suite = (NativeObject) suiteArray.get((Integer) idObj, suiteArray); + String description = (String) suite.get("description", suite); + if (!processed.contains(description)) { + Description suiteDescription = addSuiteToDescription(rootDescription, processed, description); + specs.addAll(convertToJunitDescription(suite, suiteDescription)); - Description suiteDescription = Description - .createSuiteDescription((String) suite.get("description", suite), (Annotation[]) null); - rootDescription.addChild(suiteDescription); - specsMap.putAll(convertToJunitDescription(suite, suiteDescription)); - } + NativeArray subSuites = (NativeArray) context.executeFunction(suite, "suites"); + convertSuiteArrayToDescriptions(subSuites, suiteDescription, processed); + } + } - return specsMap; - } + return specs; + } - private Map convertToJunitDescription(NativeObject suite, Description description) { - Map specsMap = new HashMap(); - NativeArray specsArray = (NativeArray) context.executeFunction(suite, "specs"); - for (Object idObj : specsArray.getIds()) { - NativeObject spec = (NativeObject) specsArray.get((Integer) idObj, specsArray); + private Description addSuiteToDescription(Description description, List processed, String suiteName) { + processed.add(suiteName); + Description suiteDescription = Description.createSuiteDescription(suiteName, (Annotation[]) null); + description.addChild(suiteDescription); + return suiteDescription; + } - JasmineSpec jasmineSpec = new JasmineSpec(spec); - specsMap.put(jasmineSpec.toString(), jasmineSpec); - description.addChild(jasmineSpec.getDescription()); - } + private List convertToJunitDescription(NativeObject suite, Description description) { + List specsMap = new ArrayList(); + NativeArray specsArray = (NativeArray) context.executeFunction(suite, "specs"); + for (Object idObj : specsArray.getIds()) { + NativeObject spec = (NativeObject) specsArray.get((Integer) idObj, specsArray); - return specsMap; - } + JasmineSpec jasmineSpec = new JasmineSpec(spec); + specsMap.add(jasmineSpec); + description.addChild(jasmineSpec.getDescription()); + } + + return specsMap; + } } diff --git a/src/main/java/be/klak/junit/jasmine/JasmineTestRunner.java b/src/main/java/be/klak/junit/jasmine/JasmineTestRunner.java index 228b463..a5a6155 100755 --- a/src/main/java/be/klak/junit/jasmine/JasmineTestRunner.java +++ b/src/main/java/be/klak/junit/jasmine/JasmineTestRunner.java @@ -3,7 +3,6 @@ package be.klak.junit.jasmine; import java.lang.annotation.Annotation; import java.lang.reflect.Method; - import org.apache.commons.lang.StringUtils; import org.junit.After; import org.junit.Before; @@ -15,173 +14,172 @@ import org.mozilla.javascript.tools.debugger.Main; import be.klak.rhino.RhinoContext; - public class JasmineTestRunner extends Runner { - private static final int SLEEP_TIME_MILISECONDS = 50; - private static final String JASMINE_LIB_DIR = "/lib/jasmine-1.0.2/"; + private static final int SLEEP_TIME_MILISECONDS = 50; + private static final String JASMINE_LIB_DIR = "/lib/jasmine-1.0.2/"; - private JasmineDescriptions jasmineSuite; + private JasmineDescriptions jasmineSuite; - private final RhinoContext rhinoContext; - private final JasmineSuite suiteAnnotation; - private final Class testClass; + private final RhinoContext rhinoContext; + private final JasmineSuite suiteAnnotation; + private final Class testClass; - @JasmineSuite - private class DefaultSuite { - } + @JasmineSuite + private class DefaultSuite { + } - public JasmineTestRunner(Class testClass) { - this.testClass = testClass; - this.suiteAnnotation = getJasmineSuiteAnnotationFromTestClass(); + public JasmineTestRunner(Class testClass) { + this.testClass = testClass; + this.suiteAnnotation = getJasmineSuiteAnnotationFromTestClass(); - Main debugger = null; - if (this.suiteAnnotation.debug()) { - debugger = this.rhinoContext.createDebugger(); - } + Main debugger = null; + if (this.suiteAnnotation.debug()) { + debugger = this.rhinoContext.createDebugger(); + } - this.rhinoContext = setUpRhinoScope(); + this.rhinoContext = setUpRhinoScope(); - if (this.suiteAnnotation.debug()) { - debugger.doBreak(); - } - } + if (this.suiteAnnotation.debug()) { + debugger.doBreak(); + } + } - private RhinoContext setUpRhinoScope() { - RhinoContext context = new RhinoContext(); - context.loadEnv(suiteAnnotation.jsRootDir()); - setUpJasmine(context); + private RhinoContext setUpRhinoScope() { + RhinoContext context = new RhinoContext(); + context.loadEnv(suiteAnnotation.jsRootDir()); + setUpJasmine(context); - context.load(suiteAnnotation.sourcesRootDir() + "/", suiteAnnotation.sources()); - context.load(suiteAnnotation.jsRootDir() + "/specs/", getJasmineSpecs(suiteAnnotation)); - return context; - } + context.load(suiteAnnotation.sourcesRootDir() + "/", suiteAnnotation.sources()); + context.load(suiteAnnotation.jsRootDir() + "/specs/", getJasmineSpecs(suiteAnnotation)); + return context; + } - private void setUpJasmine(RhinoContext context) { - context.load(getJsLibDir() + "jasmine.js"); - context.load(getJsLibDir() + "jasmine.delegator_reporter.js"); + private void setUpJasmine(RhinoContext context) { + context.load(getJsLibDir() + "jasmine.js"); + context.load(getJsLibDir() + "jasmine.delegator_reporter.js"); - context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());"); - } + context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());"); + } - private JasmineSuite getJasmineSuiteAnnotationFromTestClass() { - JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class); - if (suiteAnnotation == null) { - suiteAnnotation = DefaultSuite.class.getAnnotation(JasmineSuite.class); - } - return suiteAnnotation; - } + private JasmineSuite getJasmineSuiteAnnotationFromTestClass() { + JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class); + if (suiteAnnotation == null) { + suiteAnnotation = DefaultSuite.class.getAnnotation(JasmineSuite.class); + } + return suiteAnnotation; + } - private String[] getJasmineSpecs(JasmineSuite suiteAnnotation) { - if (suiteAnnotation.specs().length == 0) { - return new String[] { StringUtils.uncapitalize(testClass.getSimpleName()).replace("Test", "Spec") + ".js" }; - } - return suiteAnnotation.specs(); - } + private String[] getJasmineSpecs(JasmineSuite suiteAnnotation) { + if (suiteAnnotation.specs().length == 0) { + return new String[] { StringUtils.uncapitalize(testClass.getSimpleName()).replace("Test", "Spec") + ".js" }; + } + return suiteAnnotation.specs(); + } - private void resetEnvjsWindowSpace() { - this.rhinoContext.evalJS("window.location = '" + suiteAnnotation.jsRootDir() + "/lib/blank.html';"); - } + private void resetEnvjsWindowSpace() { + this.rhinoContext.evalJS("window.location = '" + suiteAnnotation.jsRootDir() + "/lib/blank.html';"); + } - private String getJsLibDir() { - return suiteAnnotation.jsRootDir() + JASMINE_LIB_DIR; - } + private String getJsLibDir() { + return suiteAnnotation.jsRootDir() + JASMINE_LIB_DIR; + } - private JasmineDescriptions getJasmineDescriptions() { - if (this.jasmineSuite == null) { - NativeArray baseSuites = (NativeArray) rhinoContext.evalJS("jasmine.getEnv().currentRunner().suites()"); - this.jasmineSuite = new JasmineJSSuiteConverter(baseSuites, rhinoContext).convertToJunitDescriptions(testClass); - } - return this.jasmineSuite; - } + private JasmineDescriptions getJasmineDescriptions() { + if (this.jasmineSuite == null) { + NativeArray baseSuites = (NativeArray) rhinoContext.evalJS("jasmine.getEnv().currentRunner().suites()"); + this.jasmineSuite = new JasmineJSSuiteConverter(rhinoContext).convertToJunitDescriptions(testClass, baseSuites); + } + return this.jasmineSuite; + } - @Override - public Description getDescription() { - return getJasmineDescriptions().getRootDescription(); - } + @Override + public Description getDescription() { + return getJasmineDescriptions().getRootDescription(); + } - @Override - public void run(RunNotifier notifier) { - generateSpecRunnerIfNeeded(); + @Override + public void run(RunNotifier notifier) { + generateSpecRunnerIfNeeded(); - for (JasmineSpec spec : getJasmineDescriptions().getAllSpecs()) { - Object testClassInstance = createTestClassInstance(); - fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, Before.class); + for (JasmineSpec spec : getJasmineDescriptions().getSpecs()) { + Object testClassInstance = createTestClassInstance(); + fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, Before.class); - try { - notifier.fireTestStarted(spec.getDescription()); - spec.execute(rhinoContext); - while (!spec.isDone()) { - waitALittle(); - } + try { + notifier.fireTestStarted(spec.getDescription()); + spec.execute(rhinoContext); + while (!spec.isDone()) { + waitALittle(); + } - reportSpecResultToNotifier(notifier, spec); - resetEnvjsWindowSpace(); - } finally { - fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, After.class); - } - } + reportSpecResultToNotifier(notifier, spec); + resetEnvjsWindowSpace(); + } finally { + fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, After.class); + } + } - this.rhinoContext.exit(); - } + this.rhinoContext.exit(); + } - private Object createTestClassInstance() { - try { - return testClass.newInstance(); - } catch (Exception ex) { - throw new RuntimeException("Unable to create a new instance of testClass " + testClass.getSimpleName() - + " using a no-arg constructor", ex); - } - } + private Object createTestClassInstance() { + try { + return testClass.newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Unable to create a new instance of testClass " + testClass.getSimpleName() + + " using a no-arg constructor", ex); + } + } - private void fireMethodsWithSpecifiedAnnotationIfAny(Object testClassInstance, Class annotation) { - for (Method method : testClass.getMethods()) { + private void fireMethodsWithSpecifiedAnnotationIfAny(Object testClassInstance, Class annotation) { + for (Method method : testClass.getMethods()) { - try { - if (method.getAnnotation(annotation) != null) { - method.setAccessible(true); - Class[] parameterTypes = method.getParameterTypes(); - if (parameterTypes.length == 0) { - method.invoke(testClassInstance, (Object[]) null); - } else if (parameterTypes.length == 1 && RhinoContext.class.isAssignableFrom(parameterTypes[0])) { - method.invoke(testClassInstance, new Object[] { this.rhinoContext }); - } else { - throw new IllegalStateException("Annotated method does not have zero or rhinoContext as parameterTypes"); - } - } - } catch (Exception ex) { - throw new RuntimeException( - "Exception while firing " + annotation.getSimpleName() + " method: " + method.getName(), ex); - } - } - } + try { + if (method.getAnnotation(annotation) != null) { + method.setAccessible(true); + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 0) { + method.invoke(testClassInstance, (Object[]) null); + } else if (parameterTypes.length == 1 && RhinoContext.class.isAssignableFrom(parameterTypes[0])) { + method.invoke(testClassInstance, new Object[] { this.rhinoContext }); + } else { + throw new IllegalStateException("Annotated method does not have zero or rhinoContext as parameterTypes"); + } + } + } catch (Exception ex) { + throw new RuntimeException( + "Exception while firing " + annotation.getSimpleName() + " method: " + method.getName(), ex); + } + } + } - private void generateSpecRunnerIfNeeded() { - if (suiteAnnotation.generateSpecRunner()) { - String[] jasmineSpecs = getJasmineSpecs(suiteAnnotation); - new JasmineSpecRunnerGenerator(jasmineSpecs, suiteAnnotation, suiteAnnotation.jsRootDir() + "/runners", - testClass.getSimpleName() - + "Runner.html") - .generate(); - } - } + private void generateSpecRunnerIfNeeded() { + if (suiteAnnotation.generateSpecRunner()) { + String[] jasmineSpecs = getJasmineSpecs(suiteAnnotation); + new JasmineSpecRunnerGenerator(jasmineSpecs, suiteAnnotation, suiteAnnotation.jsRootDir() + "/runners", + testClass.getSimpleName() + + "Runner.html") + .generate(); + } + } - private void reportSpecResultToNotifier(RunNotifier notifier, JasmineSpec spec) { - if (spec.isPassed(rhinoContext)) { - notifier.fireTestFinished(spec.getDescription()); - } else if (spec.isFailed(rhinoContext)) { - notifier.fireTestFailure(spec.getJunitFailure(rhinoContext)); - } else { - throw new IllegalStateException("Unexpected spec status received: " + spec); - } - } + private void reportSpecResultToNotifier(RunNotifier notifier, JasmineSpec spec) { + if (spec.isPassed(rhinoContext)) { + notifier.fireTestFinished(spec.getDescription()); + } else if (spec.isFailed(rhinoContext)) { + notifier.fireTestFailure(spec.getJunitFailure(rhinoContext)); + } else { + throw new IllegalStateException("Unexpected spec status received: " + spec); + } + } - private void waitALittle() { - try { - Thread.sleep(SLEEP_TIME_MILISECONDS); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private void waitALittle() { + try { + Thread.sleep(SLEEP_TIME_MILISECONDS); + } catch (Exception e) { + throw new RuntimeException(e); + } + } }