renatoathaydes / spock-reports

This project creates a global extension to Spock to create test reports.
Apache License 2.0
273 stars 68 forks source link

nextSpecExtraInfo() method signature change from 2.2.0-groovy-3.0 #241

Closed Frankie0701 closed 1 year ago

Frankie0701 commented 1 year ago

Hi team, I recently upgraded from 1.7.1 to 2.3.0-groovy-3.0, and notice our custom spec template doesn't work anymore. After some investigation, notice nextSpecExtraInfo(data) is removed and replace by nextSpecExtraInfo(data, feature, iteration) from 2.2.0-groovy-3.0. From README, features.eachFeature { name, result, blocks, iterations, params -> } is iterating members of the current feature instead of feature itself, and I also tried with features.forEach(), it's iterating over Map<String, TemplateReportCreator>, which doesn't solve my issue. I would like to know how to get single feature info from features for nextSpecExtraInfo(data, feature, iteration)? thanks

renatoathaydes commented 1 year ago

Checkout the example MD template.

It looks something like this:

## Features
<%
    features.eachFeature { name, result, blocks, iterations, params ->
%>
### $name
<%
 writePendingFeature( featureMethod.getAnnotation( spock.lang.PendingFeature ) )
 def feature = delegate
 writeTagOrAttachment( feature )
 if (result != "IGNORED") {
      if ( utils.isUnrolled( feature ) ) {
          iterations.each { iter ->
              writeExtraInfo( utils.nextSpecExtraInfo( data, feature, iter.info ) )
          }
      } else {
          writeExtraInfo( utils.nextSpecExtraInfo( data, feature ) )
     }
 }
 def iterationTimes = iterations.collect { it.time ?: 0L }
 def totalTime = fmt.toTimeDuration( iterationTimes.sum() )
%>
Frankie0701 commented 1 year ago

Hi @renatoathaydes ,

Thanks, it works! I also found another workaround to get all FeatureInfo and iterate the list, but I think this one is better. I will close the ticket, IMHO if you could also put this delegate into README, that would be perfect, cheers!

Frankie0701 commented 1 year ago

I am reopening this cuz this seems not working when the test has @Unroll, which give me exception as following, the delegate is returning array of FeatureInfo

[Test worker] WARN com.athaydes.spockframework.report.template.TemplateReportCreator - Unexpected error creating report groovy.lang.MissingMethodException: No signature of method: static com.athaydes.spockframework.report.util.Utils.nextSpecExtraInfo() is applicable for argument types: (com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo...) values: [com.athaydes.spockframework.report.internal.SpecData@64f8ac69, ...] Possible solutions: nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo), nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo, org.spockframework.runtime.model.IterationInfo), nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData) at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1584) at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1570) at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:157) at groovy.tmp.templates.GStringTemplateScript1$_getTemplate_closure1$_closure10$_closure27.doCall(GStringTemplateScript1.groovy:326) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035) at groovy.lang.Closure.call(Closure.java:412)

renatoathaydes commented 1 year ago

I cannot reproduce this. Can you verify you're using the latest version of spock-reports?

renatoathaydes commented 1 year ago

Also, make sure you're using Groovy 4.

Frankie0701 commented 1 year ago

I am using 2.3.2-groovy-3.0 as we haven't planned to upgrade to groovy 4.0+ yet.

renatoathaydes commented 1 year ago

@Frankie0701 if you want someone to fix this for you, please provide a small, self-contained test project to easily reproduce this with the latest version of the 2.x branch. If you want a fix quickly, please consider submitting a pull request yourself. This problem sounds like a very easy fix to me, but I can't spend much time on this right now.

Frankie0701 commented 1 year ago

Hi @renatoathaydes , I upgraded to groovy 4 to have a try, however the issue remains. Paste the stacktrace as it seems different from what I pasted before. I do debugged a bit on the code, but didn't spot the issue, as from debug, delegate is assigned correctly when test is with @Unroll. I will try to see if I could create a small project to easily reproduce it [Test worker] WARN com.athaydes.spockframework.report.template.TemplateReportCreator - Unexpected error creating report groovy.lang.MissingMethodException: No signature of method: static com.athaydes.spockframework.report.util.Utils.nextSpecExtraInfo() is applicable for argument types: (com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo...) values: [com.athaydes.spockframework.report.internal.SpecData@2362abba, ...] Possible solutions: nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo), nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData, org.spockframework.runtime.model.FeatureInfo, org.spockframework.runtime.model.IterationInfo), nextSpecExtraInfo(com.athaydes.spockframework.report.internal.SpecData) at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1644) at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1630) at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321) at groovy.tmp.templates.GStringTemplateScript1$_getTemplate_closure1$_closure10$_closure27.doCall(GStringTemplateScript1.groovy:326) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at groovy.lang.Closure.call(Closure.java:418) at org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(DefaultGroovyMethods.java:2302) at org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(DefaultGroovyMethods.java:2282) at org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(DefaultGroovyMethods.java:2332) at org.codehaus.groovy.runtime.dgm$216.doMethodInvoke(Unknown Source) at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321) at groovy.tmp.templates.GStringTemplateScript1$_getTemplate_closure1$_closure10.doCall(GStringTemplateScript1.groovy:321) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at com.athaydes.spockframework.report.template.TemplateReportCreator$_handleUnrolledFeature_closure2.doCall(TemplateReportCreator.groovy:163) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at groovy.lang.Closure.call(Closure.java:418) at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntryAndCounter(DefaultGroovyMethods.java:5804) at org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(DefaultGroovyMethods.java:2512) at org.codehaus.groovy.runtime.dgm$217.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:253) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:57) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139) at com.athaydes.spockframework.report.template.TemplateReportCreator.handleUnrolledFeature(TemplateReportCreator.groovy:156) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:342) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:63) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203) at com.athaydes.spockframework.report.template.TemplateReportCreator$_createFeaturesCallback_closure1.doCall(TemplateReportCreator.groovy:138) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279) at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1401) at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1338) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1091) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321) at groovy.tmp.templates.GStringTemplateScript1$_getTemplate_closure1.doCall(GStringTemplateScript1.groovy:247) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009) at groovy.lang.Closure.call(Closure.java:418) at groovy.lang.Closure$WritableClosure.writeTo(Closure.java:921) at groovy.lang.Closure$WritableClosure.toString(Closure.java:1064) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:198) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:75) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) at com.athaydes.spockframework.report.template.TemplateReportCreator.reportFor(TemplateReportCreator.groovy:126) at com.athaydes.spockframework.report.template.TemplateReportCreator$reportFor.callCurrent(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185) at com.athaydes.spockframework.report.template.TemplateReportCreator.createReportFor(TemplateReportCreator.groovy:99) at com.athaydes.spockframework.report.IReportCreator$createReportFor.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139) at com.athaydes.spockframework.report.SpecInfoListener.createReport(SpockReportExtension.groovy:283) at com.athaydes.spockframework.report.SpecInfoListener.afterSpec(SpockReportExtension.groovy:194) at org.spockframework.runtime.MasterRunListener.afterSpec(MasterRunListener.java:64) at org.spockframework.runtime.MasterRunSupervisor.afterSpec(MasterRunSupervisor.java:128) at org.spockframework.runtime.PlatformSpecRunner.runSpec(PlatformSpecRunner.java:56) at org.spockframework.runtime.SpecNode.around(SpecNode.java:63) at org.spockframework.runtime.SpecNode.around(SpecNode.java:11) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at com.sun.proxy.$Proxy5.stop(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71) at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

Frankie0701 commented 1 year ago

I notice a silly mistake from our side in the spec template introduced when fixing the breaking change, no real issue here