Upload files to "java/base"
This commit is contained in:
202
java/base/Selector.java
Normal file
202
java/base/Selector.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package base;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
||||
*/
|
||||
public final class Selector {
|
||||
|
||||
private final Class<?> owner;
|
||||
private final List<String> modes;
|
||||
private final Set<String> variantNames = new LinkedHashSet<>();
|
||||
private final Map<String, Consumer<TestCounter>> variants =
|
||||
new LinkedHashMap<>();
|
||||
|
||||
public Selector(final Class<?> owner, final String... modes) {
|
||||
this.owner = owner;
|
||||
this.modes = List.of(modes);
|
||||
}
|
||||
|
||||
public Selector variant(
|
||||
final String name,
|
||||
final Consumer<TestCounter> operations
|
||||
) {
|
||||
Asserts.assertTrue(
|
||||
"Duplicate variant " + name,
|
||||
variants.put(name.toLowerCase(), operations) == null
|
||||
);
|
||||
variantNames.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static void check(
|
||||
final boolean condition,
|
||||
final String format,
|
||||
final Object... args
|
||||
) {
|
||||
if (!condition) {
|
||||
throw new IllegalArgumentException(String.format(format, args));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public void main(final String... args) {
|
||||
try {
|
||||
final String mode;
|
||||
if (modes.isEmpty()) {
|
||||
check(
|
||||
args.length >= 1,
|
||||
"At least one argument expected, found %s",
|
||||
args.length
|
||||
);
|
||||
mode = "";
|
||||
} else {
|
||||
check(
|
||||
args.length >= 2,
|
||||
"At least two arguments expected, found %s",
|
||||
args.length
|
||||
);
|
||||
mode = args[0];
|
||||
}
|
||||
|
||||
final List<String> vars = Arrays.stream(args)
|
||||
.skip(modes.isEmpty() ? 0 : 1)
|
||||
.flatMap(arg -> Arrays.stream(arg.split("[ +]+")))
|
||||
.toList();
|
||||
|
||||
test(mode, vars);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
System.err.println("ERROR: " + e.getMessage());
|
||||
if (modes.isEmpty()) {
|
||||
System.err.println("Usage: " + owner.getName() + " VARIANT...");
|
||||
} else {
|
||||
System.err.println(
|
||||
"Usage: " + owner.getName() + " MODE VARIANT..."
|
||||
);
|
||||
System.err.println("Modes: " + String.join(", ", modes));
|
||||
}
|
||||
System.err.println("Variants: " + String.join(", ", variantNames));
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void test(final String mode, List<String> vars) {
|
||||
final int modeNo = modes.isEmpty() ? -1 : modes.indexOf(mode);
|
||||
check(modes.isEmpty() || modeNo >= 0, "Unknown mode '%s'", mode);
|
||||
if (variantNames.contains("Base") && !vars.contains("Base")) {
|
||||
vars = new ArrayList<>(vars);
|
||||
vars.add(0, "Base");
|
||||
}
|
||||
|
||||
vars.forEach(variant ->
|
||||
check(
|
||||
variants.containsKey(variant.toLowerCase()),
|
||||
"Unknown variant '%s'",
|
||||
variant
|
||||
)
|
||||
);
|
||||
|
||||
final Map<String, String> properties = modes.isEmpty()
|
||||
? Map.of("variant", String.join("+", vars))
|
||||
: Map.of("variant", String.join("+", vars), "mode", mode);
|
||||
final TestCounter counter = new TestCounter(owner, modeNo, properties);
|
||||
counter.printHead();
|
||||
vars.forEach(variant ->
|
||||
counter.scope("Testing " + variant, () ->
|
||||
variants.get(variant.toLowerCase()).accept(counter)
|
||||
)
|
||||
);
|
||||
counter.printStatus();
|
||||
}
|
||||
|
||||
public static <V extends Tester> Composite<V> composite(
|
||||
final Class<?> owner,
|
||||
final Function<TestCounter, V> factory,
|
||||
final String... modes
|
||||
) {
|
||||
return new Composite<>(
|
||||
owner,
|
||||
factory,
|
||||
(tester, counter) -> tester.test(),
|
||||
modes
|
||||
);
|
||||
}
|
||||
|
||||
public static <V> Composite<V> composite(
|
||||
final Class<?> owner,
|
||||
final Function<TestCounter, V> factory,
|
||||
final BiConsumer<V, TestCounter> tester,
|
||||
final String... modes
|
||||
) {
|
||||
return new Composite<>(owner, factory, tester, modes);
|
||||
}
|
||||
|
||||
public List<String> getModes() {
|
||||
return modes.isEmpty() ? List.of("~") : modes;
|
||||
}
|
||||
|
||||
public List<String> getVariants() {
|
||||
return List.copyOf(variants.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
||||
*/
|
||||
public static final class Composite<V> {
|
||||
|
||||
private final Selector selector;
|
||||
private final Function<TestCounter, V> factory;
|
||||
private final BiConsumer<V, TestCounter> tester;
|
||||
private List<Consumer<? super V>> base;
|
||||
|
||||
private Composite(
|
||||
final Class<?> owner,
|
||||
final Function<TestCounter, V> factory,
|
||||
final BiConsumer<V, TestCounter> tester,
|
||||
final String... modes
|
||||
) {
|
||||
selector = new Selector(owner, modes);
|
||||
this.factory = factory;
|
||||
this.tester = tester;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final Composite<V> variant(
|
||||
final String name,
|
||||
final Consumer<? super V>... parts
|
||||
) {
|
||||
if ("Base".equalsIgnoreCase(name)) {
|
||||
base = List.of(parts);
|
||||
return v(name.toLowerCase());
|
||||
} else {
|
||||
return v(name, parts);
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private Composite<V> v(
|
||||
final String name,
|
||||
final Consumer<? super V>... parts
|
||||
) {
|
||||
selector.variant(name, counter -> {
|
||||
final V variant = factory.apply(counter);
|
||||
for (final Consumer<? super V> part : base) {
|
||||
part.accept(variant);
|
||||
}
|
||||
for (final Consumer<? super V> part : parts) {
|
||||
part.accept(variant);
|
||||
}
|
||||
tester.accept(variant, counter);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public Selector selector() {
|
||||
return selector;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user