Permalink
Browse files

Refactoring for #525. WIP.

  • Loading branch information...
1 parent 111a82c commit 51da5a80bf5f22210a70132e9fe13e14c2735897 @aslakhellesoy aslakhellesoy committed Jun 25, 2013
Showing with 299 additions and 659 deletions.
  1. +1 −1 android-test/project.properties
  2. +6 −6 android-test/src/cucumber/android/test/CucumberActivitySteps.java
  3. +1 −1 android/project.properties
  4. +46 −37 android/src/cucumber/api/android/CucumberInstrumentation.java
  5. +0 −92 android/src/cucumber/runtime/android/AndroidBackend.java
  6. +0 −102 android/src/cucumber/runtime/android/AndroidClasspathMethodScanner.java
  7. +11 −11 android/src/cucumber/runtime/android/AndroidFormatter.java
  8. +0 −65 android/src/cucumber/runtime/android/AndroidJavaStepDefinition.java
  9. +0 −80 android/src/cucumber/runtime/android/AndroidMethodFormat.java
  10. +1 −1 android/src/cucumber/runtime/android/AndroidObjectFactory.java
  11. +43 −0 android/src/cucumber/runtime/android/AndroidReflections.java
  12. +12 −7 android/src/cucumber/runtime/android/AndroidResource.java
  13. +9 −10 android/src/cucumber/runtime/android/AndroidResourceLoader.java
  14. +0 −67 android/src/cucumber/runtime/android/JavaHookDefinition.java
  15. +0 −50 android/src/cucumber/runtime/android/JavaSnippet.java
  16. +12 −1 core/src/main/java/cucumber/runtime/MethodFormat.java
  17. +4 −15 core/src/main/java/cucumber/runtime/Runtime.java
  18. +0 −71 core/src/main/java/cucumber/runtime/io/ClasspathResourceLoader.java
  19. +14 −0 core/src/main/java/cucumber/runtime/io/Reflections.java
  20. +86 −0 core/src/main/java/cucumber/runtime/io/ResourceLoaderReflections.java
  21. +6 −6 groovy/src/main/java/cucumber/runtime/groovy/GroovyBackend.java
  22. +27 −16 java/src/main/java/cucumber/runtime/java/JavaBackend.java
  23. +8 −8 java/src/main/java/cucumber/runtime/java/{ClasspathMethodScanner.java → MethodScanner.java}
  24. +10 −10 java/src/test/java/cucumber/runtime/java/{ClasspathMethodScannerTest.java → MethodScannerTest.java}
  25. +2 −2 pom.xml
@@ -1,3 +1,3 @@
-target=android-8
+target=android-17
@mfellner

mfellner Jun 25, 2013

Member

The target should probably remain android-8. The latest API level available on Maven central is 16.

The pom.xml is also configured to use API level 8.

I believe maven-android-plugin does not use the values from project.properties at this time but it should be consistent.

android.library=false
android.library.reference.1=../android
@@ -8,34 +8,34 @@
import cucumber.api.java.en.When;
public class CucumberActivitySteps extends ActivityInstrumentationTestCase2<CucumberActivity> {
- private int mSteps;
+ private int steps;
public CucumberActivitySteps() {
super(CucumberActivity.class);
}
@Before
public void before() {
- assertEquals(0, mSteps);
+ assertEquals(0, steps);
}
@After
public void after() {
- assertEquals(3, mSteps);
+ assertEquals(3, steps);
}
@Given("^I have a test$")
public void I_have_a_test() {
- assertEquals(1, ++mSteps);
+ assertEquals(1, ++steps);
}
@When("^I test$")
public void I_test() {
- assertEquals(2, ++mSteps);
+ assertEquals(2, ++steps);
}
@Then("^I succeed$")
public void I_succeed() {
- assertEquals(3, ++mSteps);
+ assertEquals(3, ++steps);
}
}
@@ -1,2 +1,2 @@
-target=android-8
+target=android-17
@mfellner

mfellner Jun 25, 2013

Member

Here the target should probably also remain at version 8 (16 at the most).

@aslakhellesoy

aslakhellesoy Jun 25, 2013

Owner

I think IDEA asked me to generate it and I said yes.

Mind explaining why it's good to stay with 8? Will it still work with newer versions?

@mfellner

mfellner Jun 25, 2013

Member

I think it's a good idea to use a lower API level, because on newer Android versions there are APIs and functionality available that don't exist on older versions. Upwards compatibility is not an issue as far as I know.

One might accidentally introduce such functionality into cucumber-android and thus break compatibility for users wanting to test applications on older Android versions.

Even though the installation base is small one might consider dropping the level down to 6. I developed and tested cucumber-android with level 8 though, so I don't know if anything would break.

android.library=true
@@ -6,14 +6,14 @@
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
-import cucumber.runtime.android.AndroidBackend;
-import cucumber.runtime.android.AndroidClasspathMethodScanner;
-import cucumber.runtime.android.AndroidFormatter;
-import cucumber.runtime.android.AndroidResourceLoader;
import cucumber.runtime.Backend;
+import cucumber.runtime.CucumberException;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
+import cucumber.runtime.android.*;
+import cucumber.runtime.io.Reflections;
import cucumber.runtime.io.ResourceLoader;
+import cucumber.runtime.java.JavaBackend;
import cucumber.runtime.model.*;
import ext.android.test.ClassPathPackageInfoSource;
import gherkin.formatter.Formatter;
@@ -39,19 +39,19 @@
public static final int REPORT_VALUE_RESULT_FAILURE = -2;
public static final String REPORT_KEY_STACK = "stack";
public static final String TAG = "cucumber-android";
- private RuntimeOptions mRuntimeOptions;
- private ResourceLoader mResourceLoader;
- private ClassLoader mClassLoader;
- private Runtime mRuntime;
- private String mPackageOfTests;
- private String mFeatures;
+ private RuntimeOptions runtimeOptions;
+ private ResourceLoader resourceLoader;
+ private ClassLoader classLoader;
+ private Runtime runtime;
+ private String packageOfTests;
+ private String features;
@Override
public void onCreate(Bundle arguments) {
super.onCreate(arguments);
Context context = getContext();
- mClassLoader = context.getClassLoader();
+ classLoader = context.getClassLoader();
// For glue and features either use the provided arguments or try to find a RunWithCucumber annotated class.
// If nothing works, default values will be used instead.
@@ -60,19 +60,19 @@ public void onCreate(Bundle arguments) {
String testClass = arguments.getString(ARGUMENT_TEST_CLASS);
testClass = testClass != null ? testClass : "null";
- mPackageOfTests = arguments.getString(ARGUMENT_TEST_PACKAGE);
+ packageOfTests = arguments.getString(ARGUMENT_TEST_PACKAGE);
try {
- Class<?> clazz = mClassLoader.loadClass(testClass);
+ Class<?> clazz = classLoader.loadClass(testClass);
boolean annotationWasPresent = readRunWithCucumberAnnotation(clazz);
// If the class is not RunWithCucumber annotated, maybe it's Cucumber annotated?
if (!annotationWasPresent) {
SEARCH_ANNOTATION:
for (Method m : clazz.getMethods()) {
for (Annotation a : m.getAnnotations()) {
- if (a.annotationType().getName().startsWith("cucumber") && mPackageOfTests == null) {
- mPackageOfTests = testClass.substring(0, testClass.lastIndexOf("."));
+ if (a.annotationType().getName().startsWith("cucumber") && packageOfTests == null) {
+ packageOfTests = testClass.substring(0, testClass.lastIndexOf("."));
break SEARCH_ANNOTATION;
}
}
@@ -82,23 +82,32 @@ public void onCreate(Bundle arguments) {
Log.w(TAG, e.toString());
}
} else {
- ClassPathPackageInfoSource source = AndroidClasspathMethodScanner.classPathPackageInfoSource(context);
- for (Class<?> clazz : source.getPackageInfo(context.getPackageName()).getTopLevelClassesRecursive()) {
- if (readRunWithCucumberAnnotation(clazz)) break;
- }
+ throw new CucumberException("bad args");
+// ClassPathPackageInfoSource source = AndroidClasspathMethodScanner.classPathPackageInfoSource(context);
+// for (Class<?> clazz : source.getPackageInfo(context.getPackageName()).getTopLevelClassesRecursive()) {
+// if (readRunWithCucumberAnnotation(clazz)) break;
+// }
}
Properties properties = new Properties();
- mPackageOfTests = mPackageOfTests != null ? mPackageOfTests : defaultGlue();
- mFeatures = mFeatures != null ? mFeatures : defaultFeatures();
+ packageOfTests = packageOfTests != null ? packageOfTests : defaultGlue();
+ features = features != null ? features : defaultFeatures();
- properties.setProperty("cucumber.options", String.format("-g %s %s", mPackageOfTests, mFeatures));
- mRuntimeOptions = new RuntimeOptions(properties);
+ properties.setProperty("cucumber.options", String.format("-g %s %s", packageOfTests, features));
+ runtimeOptions = new RuntimeOptions(properties);
- mResourceLoader = new AndroidResourceLoader(context);
+ resourceLoader = new AndroidResourceLoader(context);
+// resourceLoader = new ClasspathResourceLoader(classLoader);
List<Backend> backends = new ArrayList<Backend>();
- backends.add(new AndroidBackend(this));
- mRuntime = new Runtime(mResourceLoader, mClassLoader, backends, mRuntimeOptions);
+// backends.add(new AndroidBackend(this));
+
+ String apkPath = context.getPackageCodePath();
+ ClassPathPackageInfoSource.setApkPaths(new String[]{apkPath});
+ ClassPathPackageInfoSource source = new ClassPathPackageInfoSource();
+
+ Reflections androidReflections = new AndroidReflections(source);
+ backends.add(new JavaBackend(new AndroidObjectFactory(this), androidReflections));
+ runtime = new Runtime(resourceLoader, classLoader, backends, runtimeOptions);
start();
}
@@ -110,8 +119,8 @@ private boolean readRunWithCucumberAnnotation(Class<?> clazz) {
RunWithCucumber annotation = clazz.getAnnotation(RunWithCucumber.class);
if (annotation != null) {
// isEmpty() only available in Android API 9+
- mPackageOfTests = annotation.glue().equals("") ? defaultGlue() : annotation.glue();
- mFeatures = annotation.features().equals("") ? defaultFeatures() : annotation.features();
+ packageOfTests = annotation.glue().equals("") ? defaultGlue() : annotation.glue();
+ features = annotation.features().equals("") ? defaultFeatures() : annotation.features();
return true;
}
return false;
@@ -129,7 +138,7 @@ private String defaultGlue() {
public void onStart() {
Looper.prepare();
- List<CucumberFeature> cucumberFeatures = mRuntimeOptions.cucumberFeatures(mResourceLoader);
+ List<CucumberFeature> cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader);
int numScenarios = 0;
for (CucumberFeature feature : cucumberFeatures) {
@@ -148,14 +157,14 @@ public void onStart() {
}
AndroidReporter reporter = new AndroidReporter(numScenarios);
- mRuntimeOptions.formatters.clear();
- mRuntimeOptions.formatters.add(reporter);
+ runtimeOptions.formatters.clear();
+ runtimeOptions.formatters.add(reporter);
for (CucumberFeature cucumberFeature : cucumberFeatures) {
- Formatter formatter = mRuntimeOptions.formatter(mClassLoader);
- cucumberFeature.run(formatter, reporter, mRuntime);
+ Formatter formatter = runtimeOptions.formatter(classLoader);
+ cucumberFeature.run(formatter, reporter, runtime);
}
- Formatter formatter = mRuntimeOptions.formatter(mClassLoader);
+ Formatter formatter = runtimeOptions.formatter(classLoader);
formatter.done();
printSummary();
@@ -165,10 +174,10 @@ public void onStart() {
}
private void printSummary() {
- for (Throwable t : mRuntime.getErrors()) {
+ for (Throwable t : runtime.getErrors()) {
Log.e(TAG, t.toString());
}
- for (String s : mRuntime.getSnippets()) {
+ for (String s : runtime.getSnippets()) {
Log.w(TAG, s);
}
}
@@ -298,7 +307,7 @@ public void result(Result result) {
mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, result.getErrorMessage());
} else if (result.getStatus().equals("undefined")) {
// There was a missing step definition, report an error.
- List<String> snippets = mRuntime.getSnippets();
+ List<String> snippets = runtime.getSnippets();
String report = String.format("Missing step-definition\n\n%s\nfor step '%s'",
snippets.get(snippets.size() - 1),
mStep.getName());
@@ -1,92 +0,0 @@
-package cucumber.runtime.android;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import cucumber.api.java.After;
-import cucumber.api.java.Before;
-import cucumber.runtime.*;
-import cucumber.runtime.java.ObjectFactory;
-import cucumber.runtime.snippets.SnippetGenerator;
-import gherkin.formatter.model.Step;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.regex.Pattern;
-
-public class AndroidBackend implements Backend {
- private final SnippetGenerator mSnippetGenerator = new SnippetGenerator(new JavaSnippet());
- private final ObjectFactory mObjectFactory;
- private final AndroidClasspathMethodScanner mClasspathMethodScanner;
- private Glue mGlue;
-
- public AndroidBackend(Instrumentation instrumentation) {
- mClasspathMethodScanner = new AndroidClasspathMethodScanner(instrumentation.getContext());
- mObjectFactory = new AndroidObjectFactory(instrumentation);
- }
-
- @Override
- public void loadGlue(Glue glue, List<String> gluePaths) {
- mGlue = glue;
- mClasspathMethodScanner.scan(this, gluePaths);
- }
-
- @Override
- public void setUnreportedStepExecutor(UnreportedStepExecutor executor) {
- }
-
- @Override
- public void buildWorld() {
- mObjectFactory.start();
- }
-
- @Override
- public void disposeWorld() {
- mObjectFactory.stop();
- }
-
- @Override
- public String getSnippet(Step step) {
- return mSnippetGenerator.getSnippet(step);
- }
-
- void addStepDefinition(Annotation annotation, Method method) {
- try {
- mObjectFactory.addClass(method.getDeclaringClass());
- mGlue.addStepDefinition(new AndroidJavaStepDefinition(
- method,
- pattern(annotation),
- timeout(annotation),
- mObjectFactory
- ));
- } catch (DuplicateStepDefinitionException e) {
- throw e;
- } catch (Throwable e) {
- throw new CucumberException(e);
- }
- }
-
- private Pattern pattern(Annotation annotation) throws Throwable {
- Method regexpMethod = annotation.getClass().getMethod("value");
- String regexpString = (String) Utils.invoke(annotation, regexpMethod, 0);
- return Pattern.compile(regexpString);
- }
-
- private int timeout(Annotation annotation) throws Throwable {
- Method regexpMethod = annotation.getClass().getMethod("timeout");
- return (Integer) Utils.invoke(annotation, regexpMethod, 0);
- }
-
- void addHook(Annotation annotation, Method method) {
- mObjectFactory.addClass(method.getDeclaringClass());
- if (annotation.annotationType().equals(Before.class)) {
- String[] tagExpressions = ((Before) annotation).value();
- int timeout = ((Before) annotation).timeout();
- mGlue.addBeforeHook(new JavaHookDefinition(method, tagExpressions, ((Before) annotation).order(), timeout, mObjectFactory));
- } else {
- String[] tagExpressions = ((After) annotation).value();
- int timeout = ((After) annotation).timeout();
- mGlue.addAfterHook(new JavaHookDefinition(method, tagExpressions, ((After) annotation).order(), timeout, mObjectFactory));
- }
- }
-}
Oops, something went wrong.

0 comments on commit 51da5a8

Please sign in to comment.