146 lines
5.3 KiB
Java
146 lines
5.3 KiB
Java
package expression.common;
|
|
|
|
import base.ExtendedRandom;
|
|
import base.Functional;
|
|
import expression.ToMiniString;
|
|
import expression.common.ExpressionKind.Variables;
|
|
|
|
import java.util.*;
|
|
import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Stream;
|
|
|
|
/**
|
|
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
|
*/
|
|
public class TestGeneratorBuilder<C> {
|
|
private final ExtendedRandom random;
|
|
|
|
private final Generator.Builder<C> generator;
|
|
private final NodeRendererBuilder<C> renderer;
|
|
|
|
private final List<Function<List<Node<C>>, Stream<Node<C>>>> basicTests = new ArrayList<>();
|
|
private final List<Node<C>> consts;
|
|
private final boolean verbose;
|
|
|
|
public TestGeneratorBuilder(
|
|
final ExtendedRandom random,
|
|
final Supplier<C> constant,
|
|
final List<C> constants,
|
|
final boolean verbose
|
|
) {
|
|
this.random = random;
|
|
this.verbose = verbose;
|
|
|
|
generator = Generator.builder(constant, random);
|
|
renderer = new NodeRendererBuilder<>(random);
|
|
|
|
consts = Functional.map(constants, Node::constant);
|
|
basicTests.add(vars -> consts.stream());
|
|
basicTests.add(List::stream);
|
|
}
|
|
|
|
private Node<C> c() {
|
|
return random.randomItem(consts);
|
|
}
|
|
|
|
private Node<C> v(final List<Node<C>> variables) {
|
|
return random.randomItem(variables);
|
|
}
|
|
|
|
private static <C> Node<C> f(final String name, final int priority, final Node<C> arg) {
|
|
return Node.op(name, priority, arg);
|
|
}
|
|
|
|
private static <C> Node<C> f(final String left, final Node<C> arg) {
|
|
return Node.op(left, Integer.MAX_VALUE, arg);
|
|
}
|
|
|
|
private static <C> Node<C> f(final String name, final Node<C> arg1, final Node<C> arg2) {
|
|
return Node.op(name, arg1, arg2);
|
|
}
|
|
|
|
@SafeVarargs
|
|
private void basicTests(final Function<List<Node<C>>, Node<C>>... tests) {
|
|
Arrays.stream(tests).map(test -> test.andThen(Stream::of)).forEachOrdered(basicTests::add);
|
|
}
|
|
|
|
public void unary(final String name, final int priority) {
|
|
generator.add(name, (priority & 1) * 2 - 1);
|
|
renderer.unary(name, priority);
|
|
|
|
if (verbose) {
|
|
basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream()).map(a -> f(name, priority, a)));
|
|
} else {
|
|
basicTests(vars -> f(name, priority, c()), vars -> f(name, priority, v(vars)));
|
|
}
|
|
|
|
final Function<List<Node<C>>, Node<C>> p1 = vars -> f(name, priority, f(name, priority, f("+", v(vars), c())));
|
|
final Function<List<Node<C>>, Node<C>> p2 = vars -> f("*", v(vars), f("*", v(vars), f(name, priority, c())));
|
|
basicTests(
|
|
vars -> f(name, priority, f("+", v(vars), v(vars))),
|
|
vars -> f(name, priority, f(name, priority, v(vars))),
|
|
vars -> f(name, priority, f("/", f(name, priority, v(vars)), f("+", v(vars), v(vars)))),
|
|
p1,
|
|
p2,
|
|
vars -> f("+", p1.apply(vars), p2.apply(vars))
|
|
);
|
|
}
|
|
|
|
public void unary(final String left, final String right) {
|
|
generator.add(left, 1);
|
|
renderer.unary(left, right);
|
|
|
|
if (verbose) {
|
|
basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream()).map(a -> f(left, a)));
|
|
} else {
|
|
basicTests(vars -> f(left, c()), vars -> f(left, v(vars)));
|
|
}
|
|
|
|
final Function<List<Node<C>>, Node<C>> p1 = vars -> f(left, f(left, f("+", v(vars), c())));
|
|
final Function<List<Node<C>>, Node<C>> p2 = vars -> f("*", v(vars), f("*", v(vars), f(left, c())));
|
|
basicTests(
|
|
vars -> f(left, f("+", v(vars), v(vars))),
|
|
vars -> f(left, f(left, v(vars))),
|
|
vars -> f(left, f("/", f(left, v(vars)), f("+", v(vars), v(vars)))),
|
|
p1,
|
|
p2,
|
|
vars -> f("+", p1.apply(vars), p2.apply(vars))
|
|
);
|
|
}
|
|
|
|
public void binary(final String name, final int priority) {
|
|
generator.add(name, 2);
|
|
renderer.binary(name, priority);
|
|
|
|
if (verbose) {
|
|
basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream().limit(3))
|
|
.flatMap(a -> consts.stream().map(b -> f(name, a, b))));
|
|
} else {
|
|
basicTests(
|
|
vars -> f(name, c(), c()),
|
|
vars -> f(name, v(vars), c()),
|
|
vars -> f(name, c(), v(vars)),
|
|
vars -> f(name, v(vars), v(vars))
|
|
);
|
|
}
|
|
|
|
final Function<List<Node<C>>, Node<C>> p1 = vars -> f(name, f(name, f("+", v(vars), c()), v(vars)), v(vars));
|
|
final Function<List<Node<C>>, Node<C>> p2 = vars -> f("*", v(vars), f("*", v(vars), f(name, c(), v(vars))));
|
|
|
|
basicTests(
|
|
vars -> f(name, f(name, v(vars), v(vars)), v(vars)),
|
|
vars -> f(name, v(vars), f(name, v(vars), v(vars))),
|
|
vars -> f(name, f(name, v(vars), v(vars)), f(name, v(vars), v(vars))),
|
|
vars -> f(name, f("-", f(name, v(vars), v(vars)), c()), f("+", v(vars), v(vars))),
|
|
p1,
|
|
p2,
|
|
vars -> f("+", p1.apply(vars), p2.apply(vars))
|
|
);
|
|
}
|
|
|
|
public <E extends ToMiniString> TestGenerator<C,E> build(final Variables<E> variables) {
|
|
return new TestGenerator<>(generator.build(variables, basicTests), renderer.build());
|
|
}
|
|
}
|