Skip to content

Commit

Permalink
quickcheck/property tests for IntCharSet
Browse files Browse the repository at this point in the history
includes generator for IntCharSet; addresses #662
  • Loading branch information
lsf37 committed Dec 8, 2019
1 parent 004faaa commit a79432e
Show file tree
Hide file tree
Showing 2 changed files with 260 additions and 0 deletions.
89 changes: 89 additions & 0 deletions jflex/src/test/java/jflex/core/IntCharSetGen.java
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 jflex/src/test/java/jflex/core/IntCharSetProperties.java
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());
}
}

0 comments on commit a79432e

Please sign in to comment.