Skip to content

Commit c61b273

Browse files
committed
Add property-based testing for SideEffectSet
1 parent e54a683 commit c61b273

5 files changed

Lines changed: 51 additions & 90 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ target
1414
forge-download
1515
out
1616
run
17+
.jqwik-database
1718

1819
/dependency-reduced-pom.xml
1920
*-private.sh

build-logic/src/main/kotlin/buildlogic.common-java.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ configure<CheckstyleExtension> {
3030
}
3131

3232
tasks.withType<Test>().configureEach {
33-
useJUnitPlatform()
33+
useJUnitPlatform {
34+
includeEngines("junit-jupiter", "jqwik")
35+
}
3436
}
3537

3638
dependencies {
3739
"compileOnly"(stringyLibs.getLibrary("jsr305"))
3840
"testImplementation"(platform(stringyLibs.getLibrary("junit-bom")))
3941
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-api"))
4042
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-params"))
43+
"testImplementation"(stringyLibs.getLibrary("jqwik"))
4144
"testImplementation"(platform(stringyLibs.getLibrary("mockito-bom")))
4245
"testImplementation"(stringyLibs.getLibrary("mockito-core"))
4346
"testImplementation"(stringyLibs.getLibrary("mockito-junit-jupiter"))

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ junit-jupiter-api.module = "org.junit.jupiter:junit-jupiter-api"
6666
junit-jupiter-params.module = "org.junit.jupiter:junit-jupiter-params"
6767
junit-jupiter-engine.module = "org.junit.jupiter:junit-jupiter-engine"
6868

69+
jqwik = "net.jqwik:jqwik:1.9.0"
70+
6971
mockito-bom = "org.mockito:mockito-bom:5.11.0"
7072
mockito-core.module = "org.mockito:mockito-core"
7173
mockito-junit-jupiter.module = "org.mockito:mockito-junit-jupiter"

worldedit-core/src/test/java/com/sk89q/worldedit/util/SideEffectSetTest.java

Lines changed: 42 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -19,107 +19,60 @@
1919

2020
package com.sk89q.worldedit.util;
2121

22-
import com.google.common.base.Preconditions;
23-
import com.google.common.collect.Maps;
24-
import org.junit.jupiter.api.Test;
22+
import net.jqwik.api.ForAll;
23+
import net.jqwik.api.Property;
2524

26-
import java.util.Arrays;
27-
import java.util.EnumSet;
2825
import java.util.Map;
29-
import java.util.Set;
30-
import java.util.function.Function;
31-
import java.util.stream.Collectors;
32-
33-
import static org.junit.jupiter.api.Assertions.assertEquals;
3426

3527
public class SideEffectSetTest {
36-
private static void assertAppliesWithState(Map<SideEffect, SideEffect.State> expected, SideEffectSet set) {
37-
Preconditions.checkArgument(
38-
expected.keySet().containsAll(EnumSet.allOf(SideEffect.class)),
39-
"Expected map must contain all side effects"
40-
);
41-
42-
Set<SideEffect> appliedSet = expected.entrySet().stream()
43-
.filter(e -> e.getValue() != SideEffect.State.OFF)
44-
.map(Map.Entry::getKey)
45-
.collect(Collectors.toSet());
46-
assertEquals(appliedSet, set.getSideEffectsToApply());
47-
assertEquals(!appliedSet.isEmpty(), set.doesApplyAny());
48-
for (SideEffect effect : SideEffect.values()) {
49-
assertEquals(
50-
appliedSet.contains(effect), set.shouldApply(effect), "Does not apply expected effect: " + effect
51-
);
52-
assertEquals(
53-
expected.get(effect), set.getState(effect),
54-
"Does not have expected state for effect: " + effect
55-
);
56-
}
57-
}
58-
59-
private static Map<SideEffect, SideEffect.State> initStateMap(Function<SideEffect, SideEffect.State> stateFunction) {
60-
return Arrays.stream(SideEffect.values()).collect(Collectors.toMap(Function.identity(), stateFunction));
61-
}
62-
63-
@Test
64-
public void defaults() {
65-
assertAppliesWithState(
66-
initStateMap(SideEffect::getDefaultValue),
67-
SideEffectSet.defaults()
68-
);
28+
@Property
29+
public boolean stateOrDefaultIsCorrect(
30+
@ForAll Map<SideEffect, SideEffect.State> stateMap,
31+
@ForAll SideEffect effectToTest
32+
) {
33+
SideEffectSet set = new SideEffectSet(stateMap);
34+
return set.getState(effectToTest) == stateMap.getOrDefault(effectToTest, effectToTest.getDefaultValue());
6935
}
7036

71-
@Test
72-
public void noneExposed() {
73-
assertAppliesWithState(
74-
initStateMap(effect -> {
75-
if (effect.isExposed()) {
76-
return SideEffect.State.OFF;
77-
} else {
78-
return effect.getDefaultValue();
79-
}
80-
}),
81-
SideEffectSet.none()
82-
);
37+
@Property
38+
public boolean shouldApplyUnlessOff(
39+
@ForAll Map<SideEffect, SideEffect.State> stateMap,
40+
@ForAll SideEffect effectToTest
41+
) {
42+
SideEffectSet set = new SideEffectSet(stateMap);
43+
return set.shouldApply(effectToTest)
44+
== (stateMap.getOrDefault(effectToTest, effectToTest.getDefaultValue()) != SideEffect.State.OFF);
8345
}
8446

85-
@Test
86-
public void allOn() {
87-
Map<SideEffect, SideEffect.State> expected = initStateMap(effect -> SideEffect.State.ON);
88-
assertAppliesWithState(
89-
expected,
90-
new SideEffectSet(expected)
91-
);
47+
@Property
48+
public boolean withChangesState(
49+
@ForAll Map<SideEffect, SideEffect.State> stateMap,
50+
@ForAll SideEffect effectToTest,
51+
@ForAll SideEffect.State stateToSet
52+
) {
53+
SideEffectSet set = new SideEffectSet(stateMap).with(effectToTest, stateToSet);
54+
return set.getState(effectToTest) == stateToSet;
9255
}
9356

94-
@Test
95-
public void allDelayed() {
96-
Map<SideEffect, SideEffect.State> expected = initStateMap(effect -> SideEffect.State.DELAYED);
97-
assertAppliesWithState(
98-
expected,
99-
new SideEffectSet(expected)
100-
);
101-
}
102-
103-
@Test
104-
public void allOff() {
105-
Map<SideEffect, SideEffect.State> expected = initStateMap(effect -> SideEffect.State.OFF);
106-
assertAppliesWithState(
107-
expected,
108-
new SideEffectSet(expected)
109-
);
110-
}
111-
112-
@Test
113-
public void with() {
114-
Map<SideEffect, SideEffect.State> expected = initStateMap(SideEffect::getDefaultValue);
115-
SideEffectSet set = SideEffectSet.defaults();
116-
57+
@Property
58+
public boolean anyShouldApplyEqualsDoesApplyAny(@ForAll Map<SideEffect, SideEffect.State> stateMap) {
59+
SideEffectSet set = new SideEffectSet(stateMap);
60+
boolean anyShouldApply = false;
11761
for (SideEffect effect : SideEffect.values()) {
118-
for (SideEffect.State state : SideEffect.State.values()) {
119-
expected = Maps.transformEntries(expected, (e, s) -> e == effect ? state : s);
120-
set = set.with(effect, state);
121-
assertAppliesWithState(expected, set);
62+
if (set.shouldApply(effect)) {
63+
anyShouldApply = true;
64+
break;
12265
}
12366
}
67+
return anyShouldApply == set.doesApplyAny();
68+
}
69+
70+
@Property
71+
public boolean shouldApplyEqualsApplySetContains(
72+
@ForAll Map<SideEffect, SideEffect.State> stateMap,
73+
@ForAll SideEffect effectToTest
74+
) {
75+
SideEffectSet set = new SideEffectSet(stateMap);
76+
return set.shouldApply(effectToTest) == set.getSideEffectsToApply().contains(effectToTest);
12477
}
12578
}

worldedit-core/src/test/resources/junit-platform.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ junit.jupiter.execution.parallel.mode.default=concurrent
33
junit.jupiter.execution.parallel.mode.classes.default=same_thread
44
junit.jupiter.execution.parallel.config.strategy=dynamic
55
junit.jupiter.execution.parallel.config.dynamic.factor=4
6+
7+
jqwik.tries.default = 10000

0 commit comments

Comments
 (0)