diff --git a/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/PreconditionContext.java b/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/PreconditionContext.java index 1bebf9fa7c..cad33cc740 100644 --- a/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/PreconditionContext.java +++ b/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/PreconditionContext.java @@ -24,13 +24,14 @@ import spock.lang.IgnoreIf; import spock.lang.PendingFeatureIf; import spock.lang.Requires; +import spock.lang.Specification; import spock.util.environment.Jvm; import spock.util.environment.OperatingSystem; /** * The context (delegate) for a {@link Requires}, {@link IgnoreIf} or {@link PendingFeatureIf} condition. */ -public class PreconditionContext { +public class PreconditionContext { private final Object theSharedInstance; private final Object theInstance; private final Map dataVariables; @@ -88,11 +89,11 @@ public Jvm getJvm() { * @since 2.0 * @return the test instance */ - public Object getInstance() { + public S getInstance() { if (theInstance == null) { throw new InstanceContextException(); } - return theInstance; + return (S) theInstance; } /** @@ -103,11 +104,11 @@ public Object getInstance() { * @since 2.1 * @return the shared instance */ - public Object getShared() { + public S getShared() { if (theSharedInstance == null) { throw new SharedContextException(); } - return theSharedInstance; + return (S) theSharedInstance; } /** diff --git a/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/RetryConditionContext.java b/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/RetryConditionContext.java index 560075f225..ed9d9a57f1 100644 --- a/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/RetryConditionContext.java +++ b/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/RetryConditionContext.java @@ -1,9 +1,11 @@ package org.spockframework.runtime.extension.builtin; +import spock.lang.Specification; + /** * The context (delegate) for a {@link spock.lang.Retry} condition. */ -public class RetryConditionContext { +public class RetryConditionContext { private final Object instance; private final Throwable failure; @@ -27,8 +29,8 @@ public Throwable getFailure() { * * @return the current {@code Specification} instance */ - public Object getInstance() { - return instance; + public S getInstance() { + return (S) instance; } } diff --git a/spock-core/src/main/resources/dsld/spk.dsld b/spock-core/src/main/resources/dsld/spock_tests.dsld similarity index 59% rename from spock-core/src/main/resources/dsld/spk.dsld rename to spock-core/src/main/resources/dsld/spock_tests.dsld index fe900dbd36..5fd5bd32b7 100644 --- a/spock-core/src/main/resources/dsld/spk.dsld +++ b/spock-core/src/main/resources/dsld/spock_tests.dsld @@ -14,6 +14,7 @@ package dsld +import org.codehaus.groovy.ast.* import org.codehaus.groovy.ast.expr.* assertVersion(groovyEclipse: "2.7.2") // tested against this version @@ -50,3 +51,29 @@ contribute( } } + +// From https://issues.apache.org/jira/browse/GROOVY-9510 +// Properly resolve the delegatesTo for the closures of these extensions +def hasPrecondition = { annotatedBy(name('spock.lang.Requires') | name('spock.lang.IgnoreIf') | name('spock.lang.PendingFeatureIf')) } + +contribute(inClosure() & isThisType() & bind(classes: enclosingClass(subType('spock.lang.Specification'))) + & (enclosingClass(conditions: hasPrecondition()) | enclosingMethod(conditions: hasPrecondition()))) { + for (AnnotationNode pre : conditions) { + def condition = pre.getMember('value') + if (condition.getCode().is(currentNode)) { + delegateType = resolver.resolve("org.spockframework.runtime.extension.builtin.PreconditionContext<${classes[0].getName()}>") + return + } + } +} + +contribute(inClosure() & isThisType() & bind(classes: enclosingClass(subType('spock.lang.Specification'))) + & (enclosingClass(annotations: annotatedBy('spock.lang.Retry')) | enclosingMethod(annotations: annotatedBy('spock.lang.Retry')))) { + for (AnnotationNode retry : annotations) { + def condition = retry.getMember('condition') + if (condition.getCode().is(currentNode)) { + delegateType = resolver.resolve("org.spockframework.runtime.extension.builtin.RetryConditionContext<${classes[0].getName()}>") + return + } + } +} diff --git a/spock-core/src/main/resources/org/spockframework/idea/spock.gdsl b/spock-core/src/main/resources/org/spockframework/idea/spock.gdsl index f3b2f5ffe5..0a2746dd87 100644 --- a/spock-core/src/main/resources/org/spockframework/idea/spock.gdsl +++ b/spock-core/src/main/resources/org/spockframework/idea/spock.gdsl @@ -45,3 +45,14 @@ contributor(ctx, { }) +// From https://issues.apache.org/jira/browse/GROOVY-9510 +// Properly resolve the delegatesTo for the closures of these extensions +def conditionalExtensions = ['spock.lang.Requires', 'spock.lang.IgnoreIf', 'spock.lang.PendingFeatureIf'] + .collect { annot -> context(ctype: "spock.lang.Specification", scope: closureScope(annotationName: annot))} +contributor(conditionalExtensions, { + delegatesTo(findClass('org.spockframework.runtime.extension.builtin.PreconditionContext')) +}) + +contributor(context(ctype: "spock.lang.Specification", scope: closureScope(annotationName: 'spock.lang.Retry')), { + delegatesTo(findClass('org.spockframework.runtime.extension.builtin.RetryConditionContext')) +})