Annotation Interface Togglz
TestFeatureManager for the test.
Allows the user to control the state of a Feature for a test or specification.
It can only be used to manage one feature enum at a time,
as the TestFeatureManager doesn't support multiple features.
Parallel Execution Support
This extension supports Spock's parallel execution capability.
Every specification and test annotated with @Togglz will acquire READ_WRITE lock
for the key TogglzExtension.TOGGLZ_FEATURE_RESOURCE.
Where to apply
Can be applied on individual tests and on the specification.
When applied on an individual test it will only affect that test.
When applied on an specification it will behave as if every test was annotated with the same annotation.
If both test and specification is annotated, then both will be merged, and the feature annotation will override the specification annotation on conflicts.
Here are some examples:
| Annotation on Specification | Annotation on Test | Result |
|---|---|---|
@Togglz(allEnabled = MyFeature) |
- | allEnabled = MyFeature |
| - | @Togglz(allDisabled = MyFeature) |
allDisabled = MyFeature |
@Togglz(allEnabled = MyFeature) |
@Togglz(allDisabled = MyFeature) |
allDisabled = MyFeature |
@Togglz(allEnabled = MyFeature) |
@Togglz(disable = {[MyFeature.One]}) |
allEnabled = MyFeature, disable = {[MyFeature.One]}) |
@Togglz(allEnabled = MyFeature) |
@Togglz(allDisabled = MyFeature, enable = {[MyFeature.One]}) |
allDisabled = MyFeature, enable = {[MyFeature.One]}) |
Enabling/disabling individual features
You always have to have either allEnabled or allDisabled defined for a test.
You can inherit the value from the specification (see the Where to apply chapter).
If you have used allDisabled then you can enable individual features using the enable setting.
The same applies for allEnabled and disabled.
Note: enable/disabled expect a closure that returns a list, not a list directly.
Here are some examples:
@Togglz(allDisabled = MyFeature)
class MyTest extends Specification {
def "test allDisabled"() {
expect:
!MyFeature.ONE.active
!MyFeature.TWO.active
}
@Togglz(enable = {[MyFeature.One]})
def "enable feature one"() {
expect:
MyFeature.ONE.active
!MyFeature.TWO.active
}
@Togglz(enable = {[MyFeature.TWO]})
def "enable feature one"() {
expect:
!MyFeature.ONE.active
MyFeature.TWO.active
}
}
Injecting TestFeatureManager into a test
You can declare TestFeatureManager as a parameter to any test that is either
directly annotated with @Togglz or it's Specification is annotated with it.
Here are some examples:
@Togglz(allDisabled = MyFeature)
class MyTest extends Specification {
def "injection in non data-driven feature"(TestFeatureManager testFeatureManager) {
expect:
MyFeatures.values().every { !it.active }
when:
testFeatureManager.enable(MyFeatures.ONE)
then:
MyFeatures.ONE.active
}
def "data-driven disabled"(MyFeatures feature, TestFeatureManager testFeatureManager) {
expect:
MyFeatures.values().every { !it.active }
when:
testFeatureManager.enable(feature)
then:
feature.active
where:
feature << MyFeatures.values()
}
}
Advanced usage
As enable/disabled use a closure, you can add logic to control which feature is enabled/disabled.
The closure gets PreconditionContext as parameter
so you can use it to control which feature is returned.
Use this feature with care!
Here is an example:
@Togglz(allDisabled = MyFeatures,
enable = { PreconditionContext pc -> pc.os.windows ? [MyFeatures.ONE] : [MyFeatures.TWO] })
def "all disabled with individual enabled using PreconditionContext"() {
given:
def os = OperatingSystem.getCurrent()
expect:
MyFeatures.ONE.active == os.windows
MyFeatures.TWO.active == !os.windows
!MyFeatures.THREE.active
}
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classMarker class to indicate that the field has the default value. -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionClass<? extends org.togglz.core.Feature>Feature class that should have every feature disabled.Class<? extends org.togglz.core.Feature>Feature class that should have every feature enabled.The inverse ofenable()It cannot be combined withallDisabled(). It is mutually exclusive withenable().Can be used in conjunction withallDisabled()to enable individual features again.
-
Element Details
-
allEnabled
Class<? extends org.togglz.core.Feature> allEnabledFeature class that should have every feature enabled.Example Usage:
@Togglz(allEnable = MyFeature)It is mutually exclusive with
allDisabled().- Default:
- org.togglz.spock.Togglz.None.class
-
allDisabled
Class<? extends org.togglz.core.Feature> allDisabledFeature class that should have every feature disabled.It is mutually exclusive with
allEnabled().- Default:
- org.togglz.spock.Togglz.None.class
-
enable
Can be used in conjunction withallDisabled()to enable individual features again.Define a closure that returns a list of features to enable.
Example Usage:
@Togglz(allDisable = MyFeature, enable = {[MyFeature.ONE]})- It cannot be combined with
allEnabled(). - It is mutually exclusive with
disable().
- Default:
- org.togglz.spock.Togglz.None.class
- It cannot be combined with
-
disable
The inverse ofenable()- It cannot be combined with
allDisabled(). - It is mutually exclusive with
enable().
- Default:
- org.togglz.spock.Togglz.None.class
- It cannot be combined with
-