javaslang.test.Property Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javaslang-test Show documentation
Show all versions of javaslang-test Show documentation
A property check framework for Javaslang.
/* / \____ _ _ ____ ______ / \ ____ __ _______
* / / \/ \ / \/ \ / /\__\/ // \/ \ // /\__\ JΛVΛSLΛNG
* _/ / /\ \ \/ / /\ \\__\\ \ // /\ \ /\\/ \ /__\ \ Copyright 2014-2017 Javaslang, http://javaslang.io
* /___/\_/ \_/\____/\_/ \_/\__\/__/\__\_/ \_// \__/\_____/ Licensed under the Apache License, Version 2.0
*/
package javaslang.test;
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*\
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
import java.util.Objects;
import java.util.Random;
import javaslang.*;
import javaslang.control.Option;
import javaslang.control.Try;
import javaslang.control.Try.NonFatalException;
/**
* A property builder which provides a fluent API to build checkable properties.
*
* @author Daniel Dietrich
* @since 1.2.0
*/
public class Property {
private final String name;
private Property(String name) {
this.name = name;
}
/**
* Defines a new Property.
*
* @param name property name
* @return a new {@code Property}
* @throws NullPointerException if name is null.
* @throws IllegalArgumentException if name is empty or consists of whitespace only
*/
public static Property def(String name) {
Objects.requireNonNull(name, "name is null");
if (name.trim().isEmpty()) {
throw new IllegalArgumentException("name is empty");
}
return new Property(name);
}
private static void logSatisfied(String name, int tries, long millis, boolean exhausted) {
if (exhausted) {
log(String.format("%s: Exhausted after %s tests in %s ms.", name, tries, millis));
} else {
log(String.format("%s: OK, passed %s tests in %s ms.", name, tries, millis));
}
}
private static void logFalsified(String name, int currentTry, long millis) {
log(String.format("%s: Falsified after %s passed tests in %s ms.", name, currentTry - 1, millis));
}
private static void logErroneous(String name, int currentTry, long millis, String errorMessage) {
log(String.format("%s: Errored after %s passed tests in %s ms with message: %s", name, Math.max(0, currentTry - 1), millis, errorMessage));
}
private static void log(String msg) {
System.out.println(msg);
}
/**
* Creates an Error caused by an exception when obtaining a generator.
*
* @param position The position of the argument within the argument list of the property, starting with 1.
* @param size The size hint passed to the {@linkplain Arbitrary} which caused the error.
* @param cause The error which occurred when the {@linkplain Arbitrary} tried to obtain the generator {@linkplain Gen}.
* @return a new Error instance.
*/
private static Error arbitraryError(int position, int size, Throwable cause) {
return new Error(String.format("Arbitrary %s of size %s: %s", position, size, cause.getMessage()), cause);
}
/**
* Creates an Error caused by an exception when generating a value.
*
* @param position The position of the argument within the argument list of the property, starting with 1.
* @param size The size hint of the arbitrary which called the generator {@linkplain Gen} which caused the error.
* @param cause The error which occurred when the {@linkplain Gen} tried to generate a random value.
* @return a new Error instance.
*/
private static Error genError(int position, int size, Throwable cause) {
return new Error(String.format("Gen %s of size %s: %s", position, size, cause.getMessage()), cause);
}
/**
* Creates an Error caused by an exception when testing a Predicate.
*
* @param cause The error which occurred when applying the {@linkplain java.util.function.Predicate}.
* @return a new Error instance.
*/
private static Error predicateError(Throwable cause) {
return new Error("Applying predicate: " + cause.getMessage(), cause);
}
/**
* Returns a logical for all quantor of 1 given variables.
*
* @param 1st variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @return a new {@code ForAll1} instance of 1 variables
*/
public ForAll1 forAll(Arbitrary a1) {
return new ForAll1<>(name, a1);
}
/**
* Returns a logical for all quantor of 2 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @return a new {@code ForAll2} instance of 2 variables
*/
public ForAll2 forAll(Arbitrary a1, Arbitrary a2) {
return new ForAll2<>(name, a1, a2);
}
/**
* Returns a logical for all quantor of 3 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @return a new {@code ForAll3} instance of 3 variables
*/
public ForAll3 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3) {
return new ForAll3<>(name, a1, a2, a3);
}
/**
* Returns a logical for all quantor of 4 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @param a4 4th variable of this for all quantor
* @return a new {@code ForAll4} instance of 4 variables
*/
public ForAll4 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4) {
return new ForAll4<>(name, a1, a2, a3, a4);
}
/**
* Returns a logical for all quantor of 5 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @param a4 4th variable of this for all quantor
* @param a5 5th variable of this for all quantor
* @return a new {@code ForAll5} instance of 5 variables
*/
public ForAll5 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5) {
return new ForAll5<>(name, a1, a2, a3, a4, a5);
}
/**
* Returns a logical for all quantor of 6 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @param a4 4th variable of this for all quantor
* @param a5 5th variable of this for all quantor
* @param a6 6th variable of this for all quantor
* @return a new {@code ForAll6} instance of 6 variables
*/
public ForAll6 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6) {
return new ForAll6<>(name, a1, a2, a3, a4, a5, a6);
}
/**
* Returns a logical for all quantor of 7 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @param 7th variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @param a4 4th variable of this for all quantor
* @param a5 5th variable of this for all quantor
* @param a6 6th variable of this for all quantor
* @param a7 7th variable of this for all quantor
* @return a new {@code ForAll7} instance of 7 variables
*/
public ForAll7 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6, Arbitrary a7) {
return new ForAll7<>(name, a1, a2, a3, a4, a5, a6, a7);
}
/**
* Returns a logical for all quantor of 8 given variables.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @param 7th variable type of this for all quantor
* @param 8th variable type of this for all quantor
* @param a1 1st variable of this for all quantor
* @param a2 2nd variable of this for all quantor
* @param a3 3rd variable of this for all quantor
* @param a4 4th variable of this for all quantor
* @param a5 5th variable of this for all quantor
* @param a6 6th variable of this for all quantor
* @param a7 7th variable of this for all quantor
* @param a8 8th variable of this for all quantor
* @return a new {@code ForAll8} instance of 8 variables
*/
public ForAll8 forAll(Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6, Arbitrary a7, Arbitrary a8) {
return new ForAll8<>(name, a1, a2, a3, a4, a5, a6, a7, a8);
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll1 {
private final String name;
private final Arbitrary a1;
ForAll1(String name, Arbitrary a1) {
this.name = name;
this.a1 = a1;
}
/**
* Returns a checkable property that checks values of the 1 variables of this {@code ForAll} quantor.
*
* @param predicate A 1-ary predicate
* @return a new {@code Property1} of 1 variables.
*/
public Property1 suchThat(CheckedFunction1 predicate) {
final CheckedFunction1 proposition = (t1) -> new Condition(true, predicate.apply(t1));
return new Property1<>(name, a1, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll2 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
ForAll2(String name, Arbitrary a1, Arbitrary a2) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
}
/**
* Returns a checkable property that checks values of the 2 variables of this {@code ForAll} quantor.
*
* @param predicate A 2-ary predicate
* @return a new {@code Property2} of 2 variables.
*/
public Property2 suchThat(CheckedFunction2 predicate) {
final CheckedFunction2 proposition = (t1, t2) -> new Condition(true, predicate.apply(t1, t2));
return new Property2<>(name, a1, a2, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll3 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
ForAll3(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
}
/**
* Returns a checkable property that checks values of the 3 variables of this {@code ForAll} quantor.
*
* @param predicate A 3-ary predicate
* @return a new {@code Property3} of 3 variables.
*/
public Property3 suchThat(CheckedFunction3 predicate) {
final CheckedFunction3 proposition = (t1, t2, t3) -> new Condition(true, predicate.apply(t1, t2, t3));
return new Property3<>(name, a1, a2, a3, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll4 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final Arbitrary a4;
ForAll4(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
}
/**
* Returns a checkable property that checks values of the 4 variables of this {@code ForAll} quantor.
*
* @param predicate A 4-ary predicate
* @return a new {@code Property4} of 4 variables.
*/
public Property4 suchThat(CheckedFunction4 predicate) {
final CheckedFunction4 proposition = (t1, t2, t3, t4) -> new Condition(true, predicate.apply(t1, t2, t3, t4));
return new Property4<>(name, a1, a2, a3, a4, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll5 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final Arbitrary a4;
private final Arbitrary a5;
ForAll5(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
this.a5 = a5;
}
/**
* Returns a checkable property that checks values of the 5 variables of this {@code ForAll} quantor.
*
* @param predicate A 5-ary predicate
* @return a new {@code Property5} of 5 variables.
*/
public Property5 suchThat(CheckedFunction5 predicate) {
final CheckedFunction5 proposition = (t1, t2, t3, t4, t5) -> new Condition(true, predicate.apply(t1, t2, t3, t4, t5));
return new Property5<>(name, a1, a2, a3, a4, a5, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll6 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final Arbitrary a4;
private final Arbitrary a5;
private final Arbitrary a6;
ForAll6(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
this.a5 = a5;
this.a6 = a6;
}
/**
* Returns a checkable property that checks values of the 6 variables of this {@code ForAll} quantor.
*
* @param predicate A 6-ary predicate
* @return a new {@code Property6} of 6 variables.
*/
public Property6 suchThat(CheckedFunction6 predicate) {
final CheckedFunction6 proposition = (t1, t2, t3, t4, t5, t6) -> new Condition(true, predicate.apply(t1, t2, t3, t4, t5, t6));
return new Property6<>(name, a1, a2, a3, a4, a5, a6, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @param 7th variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll7 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final Arbitrary a4;
private final Arbitrary a5;
private final Arbitrary a6;
private final Arbitrary a7;
ForAll7(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6, Arbitrary a7) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
this.a5 = a5;
this.a6 = a6;
this.a7 = a7;
}
/**
* Returns a checkable property that checks values of the 7 variables of this {@code ForAll} quantor.
*
* @param predicate A 7-ary predicate
* @return a new {@code Property7} of 7 variables.
*/
public Property7 suchThat(CheckedFunction7 predicate) {
final CheckedFunction7 proposition = (t1, t2, t3, t4, t5, t6, t7) -> new Condition(true, predicate.apply(t1, t2, t3, t4, t5, t6, t7));
return new Property7<>(name, a1, a2, a3, a4, a5, a6, a7, proposition);
}
}
/**
* Represents a logical for all quantor.
*
* @param 1st variable type of this for all quantor
* @param 2nd variable type of this for all quantor
* @param 3rd variable type of this for all quantor
* @param 4th variable type of this for all quantor
* @param 5th variable type of this for all quantor
* @param 6th variable type of this for all quantor
* @param 7th variable type of this for all quantor
* @param 8th variable type of this for all quantor
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class ForAll8 {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final Arbitrary a4;
private final Arbitrary a5;
private final Arbitrary a6;
private final Arbitrary a7;
private final Arbitrary a8;
ForAll8(String name, Arbitrary a1, Arbitrary a2, Arbitrary a3, Arbitrary a4, Arbitrary a5, Arbitrary a6, Arbitrary a7, Arbitrary a8) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
this.a5 = a5;
this.a6 = a6;
this.a7 = a7;
this.a8 = a8;
}
/**
* Returns a checkable property that checks values of the 8 variables of this {@code ForAll} quantor.
*
* @param predicate A 8-ary predicate
* @return a new {@code Property8} of 8 variables.
*/
public Property8 suchThat(CheckedFunction8 predicate) {
final CheckedFunction8 proposition = (t1, t2, t3, t4, t5, t6, t7, t8) -> new Condition(true, predicate.apply(t1, t2, t3, t4, t5, t6, t7, t8));
return new Property8<>(name, a1, a2, a3, a4, a5, a6, a7, a8, proposition);
}
}
/**
* Represents a 1-ary checkable property.
*
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class Property1 implements Checkable {
private final String name;
private final Arbitrary a1;
private final CheckedFunction1 predicate;
Property1(String name, Arbitrary a1, CheckedFunction1 predicate) {
this.name = name;
this.a1 = a1;
this.predicate = predicate;
}
/**
* Returns an implication which composes this Property as pre-condition and a given post-condition.
*
* @param postcondition The postcondition of this implication
* @return A new Checkable implication
*/
public Checkable implies(CheckedFunction1 postcondition) {
final CheckedFunction1 implication = (t1) -> {
final Condition precondition = predicate.apply(t1);
if (precondition.isFalse()) {
return Condition.EX_FALSO_QUODLIBET;
} else {
return new Condition(true, postcondition.apply(t1));
}
};
return new Property1<>(name, a1, implication);
}
@Override
public CheckResult check(Random random, int size, int tries) {
Objects.requireNonNull(random, "random is null");
if (tries < 0) {
throw new IllegalArgumentException("tries < 0");
}
final long startTime = System.currentTimeMillis();
try {
final Gen gen1 = Try.of(() -> a1.apply(size)).recover(x -> { throw arbitraryError(1, size, x); }).get();
boolean exhausted = true;
for (int i = 1; i <= tries; i++) {
try {
final T1 val1 = Try.of(() -> gen1.apply(random)).recover(x -> { throw genError(1, size, x); }).get();
try {
final Condition condition = Try.of(() -> predicate.apply(val1)).recover(x -> { throw predicateError(x); }).get();
if (condition.precondition) {
exhausted = false;
if (!condition.postcondition) {
logFalsified(name, i, System.currentTimeMillis() - startTime);
return new CheckResult.Falsified(name, i, Tuple.of(val1));
}
}
} catch(NonFatalException nonFatal) {
logErroneous(name, i, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, i, (Error) nonFatal.getCause(), Option.some(Tuple.of(val1)));
}
} catch(NonFatalException nonFatal) {
logErroneous(name, i, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, i, (Error) nonFatal.getCause(), Option.none());
}
}
logSatisfied(name, tries, System.currentTimeMillis() - startTime, exhausted);
return new CheckResult.Satisfied(name, tries, exhausted);
} catch(NonFatalException nonFatal) {
logErroneous(name, 0, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, 0, (Error) nonFatal.getCause(), Option.none());
}
}
}
/**
* Represents a 2-ary checkable property.
*
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class Property2 implements Checkable {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final CheckedFunction2 predicate;
Property2(String name, Arbitrary a1, Arbitrary a2, CheckedFunction2 predicate) {
this.name = name;
this.a1 = a1;
this.a2 = a2;
this.predicate = predicate;
}
/**
* Returns an implication which composes this Property as pre-condition and a given post-condition.
*
* @param postcondition The postcondition of this implication
* @return A new Checkable implication
*/
public Checkable implies(CheckedFunction2 postcondition) {
final CheckedFunction2 implication = (t1, t2) -> {
final Condition precondition = predicate.apply(t1, t2);
if (precondition.isFalse()) {
return Condition.EX_FALSO_QUODLIBET;
} else {
return new Condition(true, postcondition.apply(t1, t2));
}
};
return new Property2<>(name, a1, a2, implication);
}
@Override
public CheckResult check(Random random, int size, int tries) {
Objects.requireNonNull(random, "random is null");
if (tries < 0) {
throw new IllegalArgumentException("tries < 0");
}
final long startTime = System.currentTimeMillis();
try {
final Gen gen1 = Try.of(() -> a1.apply(size)).recover(x -> { throw arbitraryError(1, size, x); }).get();
final Gen gen2 = Try.of(() -> a2.apply(size)).recover(x -> { throw arbitraryError(2, size, x); }).get();
boolean exhausted = true;
for (int i = 1; i <= tries; i++) {
try {
final T1 val1 = Try.of(() -> gen1.apply(random)).recover(x -> { throw genError(1, size, x); }).get();
final T2 val2 = Try.of(() -> gen2.apply(random)).recover(x -> { throw genError(2, size, x); }).get();
try {
final Condition condition = Try.of(() -> predicate.apply(val1, val2)).recover(x -> { throw predicateError(x); }).get();
if (condition.precondition) {
exhausted = false;
if (!condition.postcondition) {
logFalsified(name, i, System.currentTimeMillis() - startTime);
return new CheckResult.Falsified(name, i, Tuple.of(val1, val2));
}
}
} catch(NonFatalException nonFatal) {
logErroneous(name, i, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, i, (Error) nonFatal.getCause(), Option.some(Tuple.of(val1, val2)));
}
} catch(NonFatalException nonFatal) {
logErroneous(name, i, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, i, (Error) nonFatal.getCause(), Option.none());
}
}
logSatisfied(name, tries, System.currentTimeMillis() - startTime, exhausted);
return new CheckResult.Satisfied(name, tries, exhausted);
} catch(NonFatalException nonFatal) {
logErroneous(name, 0, System.currentTimeMillis() - startTime, nonFatal.getCause().getMessage());
return new CheckResult.Erroneous(name, 0, (Error) nonFatal.getCause(), Option.none());
}
}
}
/**
* Represents a 3-ary checkable property.
*
* @author Daniel Dietrich
* @since 1.2.0
*/
public static class Property3 implements Checkable {
private final String name;
private final Arbitrary a1;
private final Arbitrary a2;
private final Arbitrary a3;
private final CheckedFunction3