-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
quickcheck/property tests for IntCharSet
includes generator for IntCharSet; addresses #662
- Loading branch information
Showing
2 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
* JFlex 1.8.0-SNAPSHOT * | ||
* Copyright (C) 1998-2019 Gerwin Klein <[email protected]> * | ||
* All rights reserved. * | ||
* * | ||
* License: BSD * | ||
* * | ||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
|
||
package jflex.core; | ||
|
||
import com.pholser.junit.quickcheck.generator.GenerationStatus; | ||
import com.pholser.junit.quickcheck.generator.Generator; | ||
import com.pholser.junit.quickcheck.generator.InRange; | ||
import com.pholser.junit.quickcheck.generator.Size; | ||
import com.pholser.junit.quickcheck.random.SourceOfRandomness; | ||
import jflex.chars.Interval; | ||
|
||
/** | ||
* Generator for random {@link IntCharSet} instances. | ||
* | ||
* @author Gerwin Klein | ||
* @version JFlex 1.8.0-SNAPSHOT | ||
* @see IntCharSet | ||
*/ | ||
public class IntCharSetGen extends Generator<IntCharSet> { | ||
|
||
/** Min bound for intervals */ | ||
private int minChar = 0; | ||
/** Max bound for intervals. Small for speed, and more likely edge cases. */ | ||
private int maxChar = 50; | ||
|
||
/** Min bound for number of intervals (0 = empty set) */ | ||
private int minSize = 0; | ||
/** Max bound for number of intervals */ | ||
private int maxSize = 5; | ||
|
||
/** Constructs generator for IntCharSet */ | ||
public IntCharSetGen() { | ||
super(IntCharSet.class); | ||
} | ||
|
||
@Override | ||
public IntCharSet generate(SourceOfRandomness r, GenerationStatus status) { | ||
IntCharSet result = new IntCharSet(); | ||
|
||
int numIntervals = r.nextInt(minSize, maxSize); | ||
for (int i = 0; i < numIntervals; i++) { | ||
int start = r.nextInt(minChar, maxChar); | ||
int end = r.nextInt(start, maxChar); | ||
|
||
// pick default with higher probability | ||
switch (r.nextInt(0, 4)) { | ||
case 0: | ||
result.add(IntCharSet.ofCharacter(start)); | ||
break; | ||
case 1: | ||
result.add(start); | ||
break; | ||
default: | ||
result.add(new Interval(start, end)); | ||
break; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* Configure this generator to only produce intervals in the given range. | ||
* | ||
* @param range annotation that contains the intervals constraints | ||
*/ | ||
public void configure(InRange range) { | ||
minChar = Math.max(0, range.minInt()); | ||
maxChar = Math.min(range.maxInt(), CharClasses.maxChar); | ||
} | ||
|
||
/** | ||
* Configure this generator to only produce IntCharSets with a given range of number of intervals. | ||
* | ||
* @param size annotation that contains how many intervals the IntCharSet should contain at least | ||
* and at most | ||
*/ | ||
public void configure(Size size) { | ||
minSize = size.min(); | ||
maxSize = size.max(); | ||
} | ||
} |
171 changes: 171 additions & 0 deletions
171
jflex/src/test/java/jflex/core/IntCharSetProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
* JFlex 1.8.0-SNAPSHOT * | ||
* Copyright (C) 1998-2019 Gerwin Klein <[email protected]> * | ||
* All rights reserved. * | ||
* * | ||
* License: BSD * | ||
* * | ||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
|
||
package jflex.core; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
|
||
import com.pholser.junit.quickcheck.Property; | ||
import com.pholser.junit.quickcheck.generator.InRange; | ||
import com.pholser.junit.quickcheck.runner.JUnitQuickcheck; | ||
import org.junit.runner.RunWith; | ||
|
||
/** | ||
* Property-based tests for {@link IntCharSet} | ||
* | ||
* @author Gerwin Klein | ||
* @version JFlex 1.8.0-SNAPSHOT | ||
* @see IntCharSet | ||
*/ | ||
@RunWith(JUnitQuickcheck.class) | ||
public class IntCharSetProperties { | ||
|
||
@Property | ||
public void addIsUnion(IntCharSet s1, IntCharSet s2) { | ||
IntCharSet union = IntCharSet.copyOf(s1); | ||
union.add(s2); | ||
|
||
assertThat(union.invariants()).isTrue(); | ||
|
||
assertThat(IntCharSet.isSubSet(s1, union)).isTrue(); | ||
assertThat(IntCharSet.isSubSet(s2, union)).isTrue(); | ||
|
||
for (int i : union) { | ||
assertThat(s1.contains(i) || s2.contains(i)).isTrue(); | ||
} | ||
} | ||
|
||
@Property | ||
public void andIsIntersection( | ||
@InRange(maxInt = 100) IntCharSet s1, @InRange(maxInt = 100) IntCharSet s2) { | ||
IntCharSet inter = s1.and(s2); | ||
|
||
assertThat(inter.invariants()).isTrue(); | ||
|
||
assertThat(IntCharSet.isSubSet(inter, s1)).isTrue(); | ||
assertThat(IntCharSet.isSubSet(inter, s2)).isTrue(); | ||
|
||
for (int i : s1) { | ||
assertThat(!s2.contains(i) || inter.contains(i)).isTrue(); | ||
} | ||
} | ||
|
||
@Property | ||
public void andCommutes(IntCharSet s1, IntCharSet s2) { | ||
assertThat(s1.and(s2)).isEqualTo(s2.and(s1)); | ||
} | ||
|
||
@Property | ||
public void addSelf(IntCharSet set) { | ||
IntCharSet setPre = IntCharSet.copyOf(set); | ||
set.add(setPre); | ||
assertThat(set).isEqualTo(setPre); | ||
} | ||
|
||
@Property | ||
public void addIdemPotent(IntCharSet s1, IntCharSet s2) { | ||
IntCharSet union1 = IntCharSet.copyOf(s1); | ||
union1.add(s2); | ||
IntCharSet union2 = IntCharSet.copyOf(union1); | ||
union2.add(s2); | ||
assertThat(union2).isEqualTo(union1); | ||
} | ||
|
||
@Property | ||
public void subIsDifference(IntCharSet s1, IntCharSet s2) { | ||
IntCharSet diff = IntCharSet.copyOf(s1); | ||
// use intersection to ensure that argument of sub is contained in s1 | ||
diff.sub(s1.and(s2)); | ||
|
||
assertThat(diff.invariants()).isTrue(); | ||
|
||
assertThat(IntCharSet.isSubSet(diff, s1)).isTrue(); | ||
assertThat(diff.and(s2).containsElements()).isFalse(); | ||
|
||
// union of the diff and s2 should be equal to union of s1 and s2 | ||
diff.add(s2); | ||
IntCharSet s3 = IntCharSet.copyOf(s1); | ||
s3.add(s2); | ||
assertThat(diff).isEqualTo(s3); | ||
} | ||
|
||
@Property | ||
public void containsItsElements(IntCharSet set) { | ||
for (int i : set) assertThat(set.contains(i)).isTrue(); | ||
} | ||
|
||
@Property | ||
public void allCharsContainsEverything(IntCharSet set) { | ||
assertThat(IntCharSet.allChars().contains(set)).isTrue(); | ||
} | ||
|
||
@Property | ||
public void addSubEq(IntCharSet s1, IntCharSet s2) { | ||
IntCharSet s1Pre = IntCharSet.copyOf(s1); | ||
IntCharSet inter = s1.and(s2); | ||
|
||
s1.sub(inter); | ||
s1.add(inter); | ||
|
||
assertThat(s1).isEqualTo(s1Pre); | ||
} | ||
|
||
@Property | ||
public void addEmpty(IntCharSet set) { | ||
IntCharSet setPre = IntCharSet.copyOf(set); | ||
set.add(new IntCharSet()); | ||
assertThat(set).isEqualTo(setPre); | ||
} | ||
|
||
@Property | ||
public void subEmpty(IntCharSet set) { | ||
IntCharSet setPre = IntCharSet.copyOf(set); | ||
set.sub(new IntCharSet()); | ||
assertThat(set).isEqualTo(setPre); | ||
} | ||
|
||
@Property | ||
public void andEmpty(IntCharSet set) { | ||
assertThat(set.and(new IntCharSet())).isEqualTo(new IntCharSet()); | ||
} | ||
|
||
@Property | ||
public void addAll(IntCharSet set) { | ||
set.add(IntCharSet.allChars()); | ||
assertThat(set).isEqualTo(IntCharSet.allChars()); | ||
} | ||
|
||
@Property | ||
public void subSelf(IntCharSet set) { | ||
set.sub(IntCharSet.copyOf(set)); | ||
assertThat(set).isEqualTo(new IntCharSet()); | ||
} | ||
|
||
@Property | ||
public void andAll(IntCharSet set) { | ||
assertThat(set.and(IntCharSet.allChars())).isEqualTo(set); | ||
} | ||
|
||
@Property | ||
public void andSelf(IntCharSet set) { | ||
assertThat(set.and(set)).isEqualTo(set); | ||
} | ||
|
||
@Property | ||
public void complement(IntCharSet set) { | ||
IntCharSet comp = IntCharSet.allChars(); | ||
comp.sub(set); | ||
|
||
assertThat(comp.invariants()).isTrue(); | ||
assertThat(comp.and(set).containsElements()).isFalse(); | ||
|
||
comp.add(set); | ||
assertThat(comp).isEqualTo(IntCharSet.allChars()); | ||
} | ||
} |