Skip to content

Commit 6bb1e76

Browse files
authored
Make @IgnoreIf repeatable (#1030) (#1188)
1 parent f169167 commit 6bb1e76

5 files changed

Lines changed: 112 additions & 14 deletions

File tree

docs/extensions.adoc

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,12 @@ later feature methods may depend on earlier feature methods having executed.
102102

103103
=== IgnoreIf
104104

105-
To ignore a feature method under certain conditions, annotate it with `spock.lang.IgnoreIf`,
105+
To ignore a feature method or specification under certain conditions, annotate it with `spock.lang.IgnoreIf`,
106106
followed by a predicate:
107107

108-
[source,groovy]
108+
[source,groovy,indent=0]
109109
----
110-
@IgnoreIf({ System.getProperty("os.name").contains("windows") })
111-
def "I'll run everywhere but on Windows"() { ... }
110+
include::{sourcedir}/extension/IgnoreIfDocSpec.groovy[tag=example-a]
112111
----
113112

114113
To make predicates easier to read and write, the following properties are available inside the closure:
@@ -124,10 +123,17 @@ To make predicates easier to read and write, the following properties are availa
124123

125124
Using the `os` property, the previous example can be rewritten as:
126125

127-
[source,groovy]
126+
[source,groovy,indent=0]
128127
----
129-
@IgnoreIf({ os.windows })
130-
def "I'll run everywhere but on Windows"() { ... }
128+
include::{sourcedir}/extension/IgnoreIfDocSpec.groovy[tag=example-b]
129+
----
130+
131+
If multiple `@IgnoreIf` annotations are present, they are effectively combined with a logical "or".
132+
The annotated element is skipped if any of the conditions evaluates to `true`:
133+
134+
[source,groovy,indent=0]
135+
----
136+
include::{sourcedir}/extension/IgnoreIfDocSpec.groovy[tag=example-c]
131137
----
132138

133139
Care should be taken when ignoring feature methods in a spec class annotated with `spock.lang.Stepwise` since
@@ -137,10 +143,9 @@ To use IDE support like code completion, you can also use the argument to the cl
137143
`org.spockframework.runtime.extension.builtin.PreconditionContext`. This enables the IDE with type information
138144
which is not available otherwise:
139145

140-
[source,groovy]
146+
[source,groovy,indent=0]
141147
----
142-
@IgnoreIf({ PreconditionContext it -> it.os.windows })
143-
def "I'll run everywhere but on Windows"() { ... }
148+
include::{sourcedir}/extension/IgnoreIfDocSpec.groovy[tag=example-d]
144149
----
145150

146151
If applied to a data driven feature, the closure can also access the data variables.

docs/release_notes.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ include::include.adoc[]
1616

1717
- `@Issue` is now repeatable
1818

19+
- `@IgnoreIf` is now repeatable
20+
1921
- `@Requires` is now repeatable
2022

2123
- `@See` is now repeatable

spock-core/src/main/java/spock/lang/IgnoreIf.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@
1616

1717
package spock.lang;
1818

19-
import java.lang.annotation.ElementType;
20-
import java.lang.annotation.Retention;
21-
import java.lang.annotation.RetentionPolicy;
22-
import java.lang.annotation.Target;
19+
import java.lang.annotation.*;
2320

2421
import groovy.lang.Closure;
2522

2623
import org.spockframework.runtime.extension.ExtensionAnnotation;
2724
import org.spockframework.runtime.extension.builtin.IgnoreIfExtension;
2825
import org.spockframework.runtime.extension.builtin.PreconditionContext;
26+
import org.spockframework.util.Beta;
2927

3028
/**
3129
* Ignores the annotated spec, feature or selected iterations if the given condition holds.
@@ -48,6 +46,17 @@
4846
@Retention(RetentionPolicy.RUNTIME)
4947
@Target({ElementType.TYPE, ElementType.METHOD})
5048
@ExtensionAnnotation(IgnoreIfExtension.class)
49+
@Repeatable(IgnoreIf.Container.class)
5150
public @interface IgnoreIf {
5251
Class<? extends Closure> value();
52+
53+
/**
54+
* @since 2.0
55+
*/
56+
@Beta
57+
@Retention(RetentionPolicy.RUNTIME)
58+
@Target({ElementType.TYPE, ElementType.METHOD})
59+
@interface Container {
60+
IgnoreIf[] value();
61+
}
5362
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.spockframework.docs.extension
2+
3+
import org.spockframework.runtime.extension.builtin.PreconditionContext
4+
import spock.lang.IgnoreIf
5+
import spock.lang.Specification
6+
7+
class IgnoreIfDocSpec extends Specification {
8+
// tag::example-a[]
9+
@IgnoreIf({ System.getProperty("os.name").toLowerCase().contains("windows") })
10+
def "I'll run everywhere but on Windows"() {
11+
// end::example-a[]
12+
expect:
13+
true
14+
}
15+
16+
// tag::example-b[]
17+
@IgnoreIf({ os.windows })
18+
def "I will run everywhere but on Windows"() {
19+
// end::example-b[]
20+
expect:
21+
true
22+
}
23+
24+
// tag::example-c[]
25+
@IgnoreIf({ os.windows })
26+
@IgnoreIf({ jvm.java8 })
27+
def "I'll run everywhere but on Windows or anywhere on Java 8"() {
28+
// end::example-c[]
29+
expect:
30+
true
31+
}
32+
33+
// tag::example-d[]
34+
@IgnoreIf({ PreconditionContext it -> it.os.windows })
35+
def "I will run everywhere but not on Windows"() {
36+
// end::example-d[]
37+
expect:
38+
true
39+
}
40+
}

spock-specs/src/test/groovy/org/spockframework/smoke/extension/IgnoreIfExtension.groovy

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.spockframework.smoke.extension
1818

1919
import org.spockframework.EmbeddedSpecification
20+
import org.spockframework.runtime.ConditionNotSatisfiedError
2021
import org.spockframework.runtime.extension.ExtensionException
2122
import spock.lang.*
2223

@@ -163,6 +164,47 @@ class Bar extends Closure {
163164
ee.message == 'Failed to instantiate condition'
164165
}
165166

167+
@IgnoreIf({ true })
168+
@IgnoreIf({ false })
169+
def "feature is ignored if at least one IgnoreIf annotation is true"() {
170+
expect: false
171+
}
172+
173+
def "feature is not ignored if all IgnoreIf annotations are false"() {
174+
when:
175+
runner.runSpecBody """
176+
@IgnoreIf({ false })
177+
@IgnoreIf({ false })
178+
def foo() {
179+
expect: false
180+
}
181+
"""
182+
183+
then:
184+
thrown(ConditionNotSatisfiedError)
185+
}
186+
187+
@IgnoreIf({ a == 1 })
188+
@IgnoreIf({ false })
189+
def "feature is ignored if data variable accessing IgnoreIf annotation is true"() {
190+
expect: false
191+
where: a = 1
192+
}
193+
194+
@IgnoreIf({ a == 1 })
195+
@IgnoreIf({ a != 1 })
196+
def "feature is ignored if at least one data variable accessing IgnoreIf annotation is true"() {
197+
expect: false
198+
where: a = 1
199+
}
200+
201+
@IgnoreIf({ true })
202+
@IgnoreIf({ a != 1 })
203+
def "feature is ignored if non data variable accessing IgnoreIf annotation is true"() {
204+
expect: false
205+
where: a = 1
206+
}
207+
166208
def "@IgnoreIf provides condition access to Specification instance shared fields"() {
167209
when:
168210
def result = runner.runWithImports("""

0 commit comments

Comments
 (0)