6
6
import cucumber .api .TypeRegistryConfigurer ;
7
7
import cucumber .api .CucumberOptions ;
8
8
import cucumber .api .StepDefinitionReporter ;
9
+ import cucumber .api .event .TestRunStarted ;
10
+ import cucumber .runner .EventBus ;
11
+ import cucumber .runner .Runner ;
12
+ import cucumber .runner .TimeService ;
13
+ import cucumber .runtime .BackendSupplier ;
14
+ import cucumber .runtime .FeaturePathFeatureSupplier ;
15
+ import cucumber .runtime .filter .Filters ;
16
+ import cucumber .runtime .formatter .Plugins ;
17
+ import cucumber .runtime .filter .RerunFilters ;
18
+ import cucumber .runtime .formatter .PluginFactory ;
19
+ import cucumber .runtime .model .FeatureLoader ;
20
+ import cucumber .runtime .ThreadLocalRunnerSupplier ;
21
+ import cucumber .runtime .RuntimeGlueSupplier ;
9
22
import io .cucumber .stepexpression .TypeRegistry ;
10
23
import cucumber .api .event .TestRunFinished ;
11
24
import cucumber .api .java .ObjectFactory ;
15
28
import cucumber .runtime .DefaultTypeRegistryConfiguration ;
16
29
import cucumber .runtime .Env ;
17
30
import cucumber .runtime .Reflections ;
18
- import cucumber .runtime .Runtime ;
19
31
import cucumber .runtime .RuntimeOptions ;
20
32
import cucumber .runtime .RuntimeOptionsFactory ;
21
- import cucumber .runtime .Stats ;
33
+ import cucumber .runtime .formatter . Stats ;
22
34
import cucumber .runtime .UndefinedStepsTracker ;
23
35
import cucumber .runtime .formatter .AndroidInstrumentationReporter ;
24
36
import cucumber .runtime .formatter .AndroidLogcatReporter ;
@@ -56,11 +68,6 @@ public final class CucumberExecutor {
56
68
*/
57
69
private final Instrumentation instrumentation ;
58
70
59
- /**
60
- * The {@link java.lang.ClassLoader} for all test relevant classes.
61
- */
62
- private final ClassLoader classLoader ;
63
-
64
71
/**
65
72
* The {@link cucumber.runtime.ClassFinder} to find all to be loaded classes.
66
73
*/
@@ -71,15 +78,10 @@ public final class CucumberExecutor {
71
78
*/
72
79
private final RuntimeOptions runtimeOptions ;
73
80
74
- /**
75
- * The {@link cucumber.runtime.Runtime} to run with.
76
- */
77
- private final Runtime runtime ;
78
-
79
- /**
80
- * The actual {@link PickleEvent}s to run stored in {@link PickleStruct}s.
81
- */
82
81
private final List <PickleEvent > pickleEvents ;
82
+ private final EventBus bus ;
83
+ private final Plugins plugins ;
84
+ private final Runner runner ;
83
85
84
86
/**
85
87
* Creates a new instance for the given parameters.
@@ -91,44 +93,52 @@ public final class CucumberExecutor {
91
93
public CucumberExecutor (final Arguments arguments , final Instrumentation instrumentation ) {
92
94
93
95
trySetCucumberOptionsToSystemProperties (arguments );
94
-
95
96
final Context context = instrumentation .getContext ();
96
97
this .instrumentation = instrumentation ;
97
- this . classLoader = context .getClassLoader ();
98
+ ClassLoader classLoader = context .getClassLoader ();
98
99
this .classFinder = createDexClassFinder (context );
99
100
this .runtimeOptions = createRuntimeOptions (context ).noSummaryPrinter ();
100
101
101
102
ResourceLoader resourceLoader = new AndroidResourceLoader (context );
102
- this .runtime = new Runtime (resourceLoader , classLoader , createBackends (), runtimeOptions );
103
+
104
+ this .bus = new EventBus (TimeService .SYSTEM );
105
+ this .plugins = new Plugins (classLoader , new PluginFactory (), bus , runtimeOptions );
106
+ RuntimeGlueSupplier glueSupplier = new RuntimeGlueSupplier ();
107
+ this .runner = new ThreadLocalRunnerSupplier (runtimeOptions , bus , createBackends (), glueSupplier ).get ();
108
+ FeatureLoader featureLoader = new FeatureLoader (resourceLoader );
109
+ FeaturePathFeatureSupplier featureSupplier = new FeaturePathFeatureSupplier (featureLoader , runtimeOptions );
110
+ RerunFilters rerunFilters = new RerunFilters (runtimeOptions , featureLoader );
111
+ Filters filters = new Filters (runtimeOptions , rerunFilters );
103
112
UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker ();
104
- undefinedStepsTracker .setEventPublisher (runtime . getEventBus () );
113
+ undefinedStepsTracker .setEventPublisher (bus );
105
114
Stats stats = new Stats ();
106
- stats .setEventPublisher (runtime . getEventBus () );
115
+ stats .setEventPublisher (bus );
107
116
108
117
AndroidInstrumentationReporter instrumentationReporter = new AndroidInstrumentationReporter (undefinedStepsTracker , instrumentation );
109
- runtimeOptions .addPlugin (instrumentationReporter );
110
- runtimeOptions .addPlugin (new AndroidLogcatReporter (stats , undefinedStepsTracker , TAG ));
111
-
112
- List <CucumberFeature > cucumberFeatures = runtimeOptions .cucumberFeatures (resourceLoader , runtime .getEventBus ());
113
- this .pickleEvents = FeatureCompiler .compile (cucumberFeatures , this .runtime );
118
+ plugins .addPlugin (instrumentationReporter );
119
+ plugins .addPlugin (new AndroidLogcatReporter (stats , undefinedStepsTracker , TAG ));
120
+
121
+ // Start the run before reading the features.
122
+ // Allows the test source read events to be broadcast properly
123
+ List <CucumberFeature > features = featureSupplier .get ();
124
+ bus .send (new TestRunStarted (bus .getTime ()));
125
+ for (CucumberFeature feature : features ) {
126
+ feature .sendTestSourceRead (bus );
127
+ }
128
+ this .pickleEvents = FeatureCompiler .compile (features , filters );
114
129
instrumentationReporter .setNumberOfTests (getNumberOfConcreteScenarios ());
115
130
}
116
131
117
132
/**
118
133
* Runs the cucumber scenarios with the specified arguments.
119
134
*/
120
135
public void execute () {
121
-
122
- // TODO: This is duplicated in info.cucumber.Runtime.
123
-
124
- final StepDefinitionReporter stepDefinitionReporter = runtimeOptions .stepDefinitionReporter (classLoader );
125
- runtime .reportStepDefinitions (stepDefinitionReporter );
126
-
136
+ final StepDefinitionReporter stepDefinitionReporter = plugins .stepDefinitionReporter ();
137
+ runner .reportStepDefinitions (stepDefinitionReporter );
127
138
for (final PickleEvent pickleEvent : pickleEvents ) {
128
- runtime . getRunner () .runPickle (pickleEvent );
139
+ runner .runPickle (pickleEvent );
129
140
}
130
-
131
- runtime .getEventBus ().send (new TestRunFinished (runtime .getEventBus ().getTime ()));
141
+ bus .send (new TestRunFinished (bus .getTime ()));
132
142
}
133
143
134
144
/**
@@ -171,13 +181,19 @@ private RuntimeOptions createRuntimeOptions(final Context context) {
171
181
throw new CucumberException ("No CucumberOptions annotation" );
172
182
}
173
183
174
- private Collection <? extends Backend > createBackends () {
175
- final Reflections reflections = new Reflections (classFinder );
176
- final ObjectFactory delegateObjectFactory = ObjectFactoryLoader .loadObjectFactory (classFinder , Env .INSTANCE .get (ObjectFactory .class .getName ()));
177
- final AndroidObjectFactory objectFactory = new AndroidObjectFactory (delegateObjectFactory , instrumentation );
178
- final TypeRegistryConfigurer typeRegistryConfigurer = reflections .instantiateExactlyOneSubclass (TypeRegistryConfigurer .class , MultiLoader .packageName (runtimeOptions .getGlue ()), new Class [0 ], new Object [0 ], new DefaultTypeRegistryConfiguration ());
179
- final TypeRegistry typeRegistry = new TypeRegistry (typeRegistryConfigurer .locale ());
180
- typeRegistryConfigurer .configureTypeRegistry (typeRegistry );
181
- return singletonList (new JavaBackend (objectFactory , classFinder , typeRegistry ));
184
+ private BackendSupplier createBackends () {
185
+ return new BackendSupplier () {
186
+ @ Override
187
+ public Collection <? extends Backend > get () {
188
+ final Reflections reflections = new Reflections (classFinder );
189
+ final ObjectFactory delegateObjectFactory = ObjectFactoryLoader .loadObjectFactory (classFinder , Env .INSTANCE .get (ObjectFactory .class .getName ()));
190
+ final AndroidObjectFactory objectFactory = new AndroidObjectFactory (delegateObjectFactory , instrumentation );
191
+ final TypeRegistryConfigurer typeRegistryConfigurer = reflections .instantiateExactlyOneSubclass (TypeRegistryConfigurer .class , MultiLoader .packageName (runtimeOptions .getGlue ()), new Class [0 ], new Object [0 ], new DefaultTypeRegistryConfiguration ());
192
+ final TypeRegistry typeRegistry = new TypeRegistry (typeRegistryConfigurer .locale ());
193
+ typeRegistryConfigurer .configureTypeRegistry (typeRegistry );
194
+ return singletonList (new JavaBackend (objectFactory , classFinder , typeRegistry ));
195
+ }
196
+ };
197
+
182
198
}
183
199
}
0 commit comments