@@ -29,7 +29,9 @@ public IDataIterator createFeatureDataIterator(SpockExecutionContext context) {
2929 if (context .getCurrentFeature ().getDataProcessorMethod () == null ) {
3030 return new SingleEmptyIterationDataIterator ();
3131 }
32- return new DataProcessorIterator (supervisor , context , new FeatureDataProviderIterator (supervisor , context ));
32+ return new IterationFilterIterator (supervisor , context ,
33+ new DataProcessorIterator (supervisor , context ,
34+ new FeatureDataProviderIterator (supervisor , context )));
3335 }
3436
3537 private abstract static class BaseDataIterator implements IDataIterator {
@@ -201,6 +203,88 @@ public void close() throws Exception {
201203 }
202204 }
203205
206+ private static class IterationFilterIterator extends BaseDataIterator {
207+ private final IDataIterator delegate ;
208+ private final List <String > dataVariableNames ;
209+ private final boolean logFilteredIterations ;
210+ private IStackTraceFilter stackTraceFilter ;
211+
212+ private IterationFilterIterator (IRunSupervisor supervisor , SpockExecutionContext context , IDataIterator delegate ) {
213+ super (supervisor , context );
214+ this .delegate = delegate ;
215+ dataVariableNames = delegate .getDataVariableNames ();
216+
217+ RunnerConfiguration runnerConfiguration = context
218+ .getRunContext ()
219+ .getConfiguration (RunnerConfiguration .class );
220+ logFilteredIterations = runnerConfiguration .logFilteredIterations ;
221+ if (logFilteredIterations ) {
222+ stackTraceFilter = runnerConfiguration .filterStackTrace ? new StackTraceFilter (context .getSpec ()) : new DummyStackTraceFilter ();
223+ }
224+ }
225+
226+ @ Override
227+ public int getEstimatedNumIterations () {
228+ return delegate .getEstimatedNumIterations ();
229+ }
230+
231+ @ Override
232+ public List <String > getDataVariableNames () {
233+ return dataVariableNames ;
234+ }
235+
236+ @ Override
237+ public void close () throws Exception {
238+ delegate .close ();
239+ }
240+
241+ @ Override
242+ public boolean hasNext () {
243+ return delegate .hasNext ();
244+ }
245+
246+ @ Override
247+ public Object [] next () {
248+ while (true ) {
249+ Object [] next = delegate .next ();
250+
251+ // delegate.next() will return null if an error occurred
252+ if (next == null ) {
253+ return null ;
254+ }
255+
256+ MethodInfo filterMethod = context .getCurrentFeature ().getFilterMethod ();
257+ if (filterMethod == null ) {
258+ return next ;
259+ }
260+
261+ try {
262+ // do not use invokeRaw here, as that would report Assertion Error to the supervisor
263+ filterMethod .invoke (context .getSharedInstance (), next );
264+ return next ;
265+ } catch (AssertionError ae ) {
266+ if (logFilteredIterations ) {
267+ StringJoiner stringJoiner = new StringJoiner (", " , "Filtered iteration [" , "]:\n " );
268+ for (int i = 0 ; i < dataVariableNames .size (); i ++) {
269+ stringJoiner .add (dataVariableNames .get (i ) + ": " + next [i ]);
270+ }
271+ StringWriter sw = new StringWriter ();
272+ sw .write (stringJoiner .toString ());
273+ stackTraceFilter .filter (ae );
274+ try (PrintWriter pw = new PrintWriter (sw )) {
275+ ae .printStackTrace (pw );
276+ }
277+ System .err .println (sw );
278+ }
279+ // filter block does not like these values, try next ones if available
280+ } catch (Throwable t ) {
281+ supervisor .error (context .getErrorInfoCollector (), new ErrorInfo (filterMethod , t , getErrorContext ()));
282+ return null ;
283+ }
284+ }
285+ }
286+ }
287+
204288 private static class DataProcessorIterator extends BaseDataIterator {
205289 private final IDataIterator delegate ;
206290 private final List <String > dataVariableNames ;
@@ -262,8 +346,6 @@ private static class FeatureDataProviderIterator extends BaseDataIterator {
262346 private final int estimatedNumIterations ;
263347 private final List <String > dataVariableNames ;
264348 private boolean firstIteration = true ;
265- private boolean logFilteredIterations = true ;
266- private IStackTraceFilter stackTraceFilter ;
267349
268350 public FeatureDataProviderIterator (IRunSupervisor supervisor , SpockExecutionContext context ) {
269351 super (supervisor , context );
@@ -272,14 +354,6 @@ public FeatureDataProviderIterator(IRunSupervisor supervisor, SpockExecutionCont
272354 dataProviders = createDataProviders ();
273355 dataProviderIterators = createDataProviderIterators ();
274356 estimatedNumIterations = estimateNumIterations (dataProviderIterators );
275-
276- RunnerConfiguration runnerConfiguration = context
277- .getRunContext ()
278- .getConfiguration (RunnerConfiguration .class );
279- logFilteredIterations = runnerConfiguration .logFilteredIterations ;
280- if (logFilteredIterations ) {
281- stackTraceFilter = runnerConfiguration .filterStackTrace ? new StackTraceFilter (context .getSpec ()) : new DummyStackTraceFilter ();
282- }
283357 }
284358
285359 @ Override
@@ -308,60 +382,29 @@ public Object[] next() {
308382 }
309383 firstIteration = false ;
310384
311- while (true ) {
312- // advances iterators and computes args
313- Object [] next = new Object [dataProviders .length ];
314- for (int i = 0 ; i < dataProviders .length ; ) {
315- try {
316- // if the filter block excluded an iteration
317- // this might be called after the last iteration
318- // so just return null if no further data is available
319- // to just cause the iteration to be skipped
320- if (!dataProviderIterators [i ].hasNext ()) {
321- return null ;
322- }
323- Object [] nextValues = dataProviderIterators [i ].next ();
324- if (nextValues == null ) {
325- return null ;
326- }
327- System .arraycopy (nextValues , 0 , next , i , nextValues .length );
328- i += nextValues .length ;
329- } catch (Throwable t ) {
330- supervisor .error (context .getErrorInfoCollector (), new ErrorInfo (context .getCurrentFeature ().getDataProviders ().get (i ).getDataProviderMethod (), t , getErrorContext ()));
385+ // advances iterators and computes args
386+ Object [] next = new Object [dataProviders .length ];
387+ for (int i = 0 ; i < dataProviders .length ; ) {
388+ try {
389+ // if the filter block excluded an iteration
390+ // this might be called after the last iteration
391+ // so just return null if no further data is available
392+ // to just cause the iteration to be skipped
393+ if (!dataProviderIterators [i ].hasNext ()) {
331394 return null ;
332395 }
333- }
334-
335- MethodInfo filterMethod = context .getCurrentFeature ().getFilterMethod ();
336-
337- if (filterMethod == null ) {
338- return next ;
339- }
340-
341- try {
342- // do not use invokeRaw here, as that would report Assertion Error to the supervisor
343- filterMethod .invoke (null , next );
344- return next ;
345- } catch (AssertionError ae ) {
346- if (logFilteredIterations ) {
347- StringJoiner stringJoiner = new StringJoiner (", " , "Filtered iteration [" , "]:\n " );
348- for (int i = 0 ; i < dataVariableNames .size (); i ++) {
349- stringJoiner .add (dataVariableNames .get (i ) + ": " + next [i ]);
350- }
351- StringWriter sw = new StringWriter ();
352- sw .write (stringJoiner .toString ());
353- stackTraceFilter .filter (ae );
354- try (PrintWriter pw = new PrintWriter (sw )) {
355- ae .printStackTrace (pw );
356- }
357- System .err .println (sw );
396+ Object [] nextValues = dataProviderIterators [i ].next ();
397+ if (nextValues == null ) {
398+ return null ;
358399 }
359- // filter block does not like these values, try next ones if available
400+ System .arraycopy (nextValues , 0 , next , i , nextValues .length );
401+ i += nextValues .length ;
360402 } catch (Throwable t ) {
361- supervisor .error (context .getErrorInfoCollector (), new ErrorInfo (filterMethod , t , getErrorContext ()));
403+ supervisor .error (context .getErrorInfoCollector (), new ErrorInfo (context . getCurrentFeature (). getDataProviders (). get ( i ). getDataProviderMethod () , t , getErrorContext ()));
362404 return null ;
363405 }
364406 }
407+ return next ;
365408 }
366409
367410 @ Override
0 commit comments