use of one.util.streamex.Internals.TailSpliterator in project streamex by amaembo.
the class TestHelpers method checkSpliterator.
/*
* Tests whether spliterators produced by given supplier produce the
* expected result under various splittings
*
* This test is single-threaded. Its behavior is randomized, but random seed
* will be printed in case of failure, so the results could be reproduced
*/
public static <T> void checkSpliterator(String msg, List<T> expected, Supplier<Spliterator<T>> supplier) {
List<T> seq = new ArrayList<>();
// Test characteristics
Spliterator<T> forCharacteristics = supplier.get();
if (forCharacteristics.hasCharacteristics(Spliterator.SORTED)) {
// must not fail
forCharacteristics.getComparator();
}
assertTrue(forCharacteristics.estimateSize() >= 0);
// Test forEachRemaining
Spliterator<T> sequential = supplier.get();
sequential.forEachRemaining(seq::add);
assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
sequential.forEachRemaining(t -> fail(msg + ": Advance called with " + t));
assertEquals(msg, expected, seq);
// Test tryAdvance
seq.clear();
sequential = supplier.get();
while (true) {
AtomicBoolean called = new AtomicBoolean();
boolean res = sequential.tryAdvance(t -> {
seq.add(t);
called.set(true);
});
if (res != called.get()) {
fail(msg + (res ? ": Consumer not called, but spliterator returned true" : ": Consumer called, but spliterator returned false"));
}
if (!res)
break;
}
assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
assertEquals(msg, expected, seq);
// Test TailSpliterator
if (sequential instanceof TailSpliterator) {
seq.clear();
TailSpliterator.forEachWithTail(supplier.get(), seq::add);
assertEquals(msg, expected, seq);
seq.clear();
sequential = supplier.get();
while (sequential != null) {
sequential = TailSpliterator.tryAdvanceWithTail(sequential, seq::add);
}
}
assertEquals(msg, expected, seq);
// Test advance+remaining
for (int i = 1; i < Math.min(4, expected.size() - 1); i++) {
seq.clear();
sequential = supplier.get();
for (int j = 0; j < i; j++) assertTrue(msg, sequential.tryAdvance(seq::add));
sequential.forEachRemaining(seq::add);
assertEquals(msg, expected, seq);
}
// Test trySplit
withRandom(r -> {
repeat(500, n -> {
Spliterator<T> spliterator = supplier.get();
List<Spliterator<T>> spliterators = new ArrayList<>();
spliterators.add(spliterator);
int p = r.nextInt(10) + 2;
for (int i = 0; i < p; i++) {
int idx = r.nextInt(spliterators.size());
Spliterator<T> split = spliterators.get(idx).trySplit();
if (split != null)
spliterators.add(idx, split);
}
List<Integer> order = IntStreamEx.ofIndices(spliterators).boxed().toMutableList();
Collections.shuffle(order, r);
List<T> list = StreamEx.of(order).mapToEntry(idx -> {
Spliterator<T> s = spliterators.get(idx);
Stream.Builder<T> builder = Stream.builder();
s.forEachRemaining(builder);
assertFalse(msg, s.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
s.forEachRemaining(t -> fail(msg + ": Advance called with " + t));
return builder.build();
}).sortedBy(Entry::getKey).values().flatMap(Function.identity()).toList();
assertEquals(msg, expected, list);
});
repeat(500, n -> {
Spliterator<T> spliterator = supplier.get();
List<Spliterator<T>> spliterators = new ArrayList<>();
spliterators.add(spliterator);
int p = r.nextInt(30) + 2;
for (int i = 0; i < p; i++) {
int idx = r.nextInt(spliterators.size());
Spliterator<T> split = spliterators.get(idx).trySplit();
if (split != null)
spliterators.add(idx, split);
}
List<List<T>> results = StreamEx.<List<T>>generate(ArrayList::new).limit(spliterators.size()).toMutableList();
int count = spliterators.size();
while (count > 0) {
int i;
do {
i = r.nextInt(spliterators.size());
spliterator = spliterators.get(i);
} while (spliterator == null);
if (!spliterator.tryAdvance(results.get(i)::add)) {
spliterators.set(i, null);
count--;
}
}
List<T> list = StreamEx.of(results).flatMap(List::stream).toList();
assertEquals(msg, expected, list);
});
});
}
Aggregations