600 lines
18 KiB
Java
600 lines
18 KiB
Java
package aud.exam.prep;
|
|
|
|
import org.junit.jupiter.params.ParameterizedTest;
|
|
import org.junit.jupiter.params.provider.ArgumentsSource;
|
|
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|
|
|
public abstract class SequenceProcessorTest<S> {
|
|
|
|
protected final Comparator<Integer> cmp = Integer::compareTo;
|
|
|
|
protected final SequenceProcessor<Integer, S> processor;
|
|
|
|
protected SequenceProcessorTest(SequenceProcessor<Integer, S> processor) {
|
|
this.processor = processor;
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_createAndIterateWork(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_findOfNonExistsIsFalse(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.find(s, -1));
|
|
assertFalse(processor.find(s, 999));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_findOfExistsIsTrue(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
for (var n : list) {
|
|
assertTrue(processor.find(s, n));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_findBinaryOfNonExistsIsFalse(List<Integer> list) {
|
|
list.sort(cmp);
|
|
S s = processor.create(list);
|
|
assertFalse(processor.findBinary(s, -1, cmp));
|
|
assertFalse(processor.findBinary(s, 999, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_findBinaryOfExistsIsTrue(List<Integer> list) {
|
|
list.sort(Comparable::compareTo);
|
|
S s = processor.create(list);
|
|
for (var n : list) {
|
|
assertTrue(processor.findBinary(s, n, cmp));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideOfNotExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.override(s, -1, -5));
|
|
assertFalse(processor.override(s, 999, -5));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
for (int i = 0; i < list.size(); i++) {
|
|
var to = -(i*i) - 5;
|
|
|
|
assertTrue(processor.override(s, list.get(i), to));
|
|
list.set(i, to);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideAllOfNotExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.overrideAll(s, -1, -5));
|
|
assertFalse(processor.overrideAll(s, 999, -5));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideAllOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
for (int i = 0; i < list.size(); i++) {
|
|
var from = list.get(i);
|
|
var to = -(i*i) - 5;
|
|
|
|
assertTrue(processor.overrideAll(s, from, to));
|
|
list.replaceAll(k ->
|
|
Objects.equals(k, from) ? to : k);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideAtOfBadIndexIsFalseAndDoesNotModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.overrideAt(s, -5, -1));
|
|
assertFalse(processor.overrideAt(s, -5, 999));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_overrideAtOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
for (int i = 0; i < list.size(); i++) {
|
|
var to = -(i*i) - 5;
|
|
|
|
assertTrue(processor.overrideAt(s, to, i));
|
|
list.set(i, to);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_insertInOrderWorks(List<Integer> list) {
|
|
list.sort(cmp);
|
|
S s = processor.create(list);
|
|
|
|
for (int i = -1; i < 110; i++) {
|
|
processor.insertInOrder(s, i, cmp);
|
|
|
|
list.add(i);
|
|
list.sort(cmp);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_removeOfNonExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.remove(s, -1));
|
|
assertFalse(processor.remove(s, 999));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_removeOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
while (!list.isEmpty()) {
|
|
var toRemove = list.get(list.size()/2);
|
|
|
|
list.remove(toRemove);
|
|
assertTrue(processor.remove(s, toRemove));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_removeAllOfNonExistsIsFalseAndDoesNotModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.removeAll(s, -1));
|
|
assertFalse(processor.removeAll(s, 999));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_removeAllOfExistsIsTrueAndDoesModify(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
while (!list.isEmpty()) {
|
|
var toRemove = list.get(list.size()/2);
|
|
|
|
list.removeAll(Collections.singleton(toRemove));
|
|
assertTrue(processor.removeAll(s, toRemove));
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_ifAscendingOfUnsortedIsFalse(List<Integer> list) {
|
|
assumeTrue(list.size() > 2, "The list is to small");
|
|
|
|
list.add(list.size()/2, -1);
|
|
S s = processor.create(list);
|
|
assertFalse(processor.isAscending(s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_ifAscendingOfSortedIsTrue(List<Integer> list) {
|
|
list.sort(cmp);
|
|
S s = processor.create(list);
|
|
assertTrue(processor.isAscending(s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_maxWorks(List<Integer> list) {
|
|
list.add(-1);
|
|
S s = processor.create(list);
|
|
var max = list
|
|
.stream()
|
|
.max(cmp)
|
|
.orElseThrow();
|
|
assertEquals(max, processor.max(s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_secondMaxWorks(List<Integer> list) {
|
|
list.add(-1);
|
|
list.add(-2);
|
|
S s = processor.create(list);
|
|
var max = list
|
|
.stream()
|
|
.sorted(cmp.reversed())
|
|
.skip(1)
|
|
.findFirst()
|
|
.orElseThrow();
|
|
assertEquals(max, processor.secondMax(s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessOrEqualOfSameIsTrue(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertTrue(processor.isItemWiseLessOrEqual(s, s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessOrEqualWithPlus5Works(List<Integer> list) {
|
|
S a = processor.create(list);
|
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
if (i % 2 == 0) {
|
|
list.set(i, list.get(i)+5);
|
|
}
|
|
}
|
|
S b = processor.create(list);
|
|
|
|
assertTrue(processor.isItemWiseLessOrEqual(a, b, cmp));
|
|
|
|
assumeTrue(!list.isEmpty(), "List must not be empty to be less then");
|
|
assertFalse(processor.isItemWiseLessOrEqual(b, a, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessOrEqualWithMoreElementsWorks(List<Integer> list) {
|
|
S a = processor.create(list);
|
|
|
|
for (int i = 1; i < 4; i++) {
|
|
list.add(-i);
|
|
}
|
|
S b = processor.create(list);
|
|
|
|
assertTrue(processor.isItemWiseLessOrEqual(a, b, cmp));
|
|
assertFalse(processor.isItemWiseLessOrEqual(b, a, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessOfSameIsFalse(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.isItemWiseLess(s, s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessWithAlmostSameIsTrue(List<Integer> list) {
|
|
S a = processor.create(list);
|
|
|
|
var index = list.size()/2;
|
|
if (list.isEmpty()) {
|
|
list.add(1);
|
|
} else {
|
|
list.set(index, list.get(index)+1);
|
|
}
|
|
S b = processor.create(list);
|
|
|
|
assertTrue(processor.isItemWiseLess(a, b, cmp));
|
|
assertFalse(processor.isItemWiseLess(b, a, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isItemWiseLessWithPlus5Works(List<Integer> list) {
|
|
S a = processor.create(list);
|
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
if (i % 2 == 0) {
|
|
list.set(i, list.get(i)+5);
|
|
}
|
|
}
|
|
if (list.isEmpty()) {
|
|
list.add(1);
|
|
}
|
|
S b = processor.create(list);
|
|
|
|
assertTrue(processor.isItemWiseLess(a, b, cmp));
|
|
assertFalse(processor.isItemWiseLess(b, a, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_isLexSmallerOfSameIfFalse(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
assertFalse(processor.isLexSmaller(s, s, cmp));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(DoubleLatinProvider.class)
|
|
void testThat_isLexSmallerWithWorksLikeStrings(String stringA, String stringB) {
|
|
S a = toSequenceByAscii(stringA);
|
|
S b = toSequenceByAscii(stringB);
|
|
|
|
assertEquals(
|
|
stringA.compareTo(stringB) < 0,
|
|
processor.isLexSmaller(a, b, cmp));
|
|
|
|
assertEquals(
|
|
stringB.compareTo(stringA) < 0,
|
|
processor.isLexSmaller(b, a, cmp));
|
|
}
|
|
|
|
protected S toSequenceByAscii(String string) {
|
|
var list = string
|
|
.chars()
|
|
.boxed()
|
|
.collect(Collectors.toList());
|
|
return processor.create(list);
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_exchangePairsWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
for (int i = 1; i < list.size()-1; i += 2) {
|
|
Collections.swap(list, i, i+1);
|
|
}
|
|
|
|
processor.exchangePairs(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_rotateTriplesWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
for (int i = 1; i < list.size()-2; i += 3) {
|
|
Collections.swap(list, i+1, i+2);
|
|
Collections.swap(list, i, i+1);
|
|
}
|
|
|
|
processor.rotateTriples(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_doubleAllKeysWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
list = list
|
|
.stream()
|
|
.flatMap(n ->
|
|
Stream.of(n, n))
|
|
.collect(Collectors.toList());
|
|
|
|
processor.doubleAllKeys(s);
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_rotateRightWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
if (list.size() > 1) {
|
|
var right = list.remove(list.size()-1);
|
|
list.add(0, right);
|
|
}
|
|
|
|
s = processor.rotateRight(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_rotateLeftWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
if (list.size() > 1) {
|
|
var left = list.remove(0);
|
|
list.add(left);
|
|
}
|
|
|
|
s = processor.rotateLeft(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(DuplicateListProvider.class)
|
|
void testThat_removeDuplicatesWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
var noDuplicatesList = new ArrayList<Integer>();
|
|
for (var n : list) {
|
|
if (noDuplicatesList.isEmpty() || !Objects.equals(n, noDuplicatesList.get(noDuplicatesList.size()-1))) {
|
|
noDuplicatesList.add(n);
|
|
}
|
|
}
|
|
|
|
processor.removeDuplicates(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(noDuplicatesList, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_invertWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
Collections.reverse(list);
|
|
s = processor.invert(s);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_cloneWorks(List<Integer> list) {
|
|
S a = processor.create(list);
|
|
S b = processor.clone(a);
|
|
|
|
assertNotSame(a, b);
|
|
assertTrue(processor.check(b));
|
|
assertIterableEquals(list, processor.iterate(b));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(DoubleListProvider.class)
|
|
void testThat_cloneWorks(List<Integer> listA, List<Integer> listB) {
|
|
S a = processor.create(listA);
|
|
S b = processor.create(listB);
|
|
|
|
var list = new ArrayList<Integer>();
|
|
while(!listA.isEmpty() || !listB.isEmpty()) {
|
|
if (!listA.isEmpty()) {
|
|
list.add(listA.remove(0));
|
|
}
|
|
if (!listB.isEmpty()) {
|
|
list.add(listB.remove(0));
|
|
}
|
|
}
|
|
|
|
S s = processor.alternate(a, b);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(list, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(DoubleListProvider.class)
|
|
void testThat_mergeWorks(List<Integer> listA, List<Integer> listB) {
|
|
listA.sort(cmp);
|
|
S a = processor.create(listA);
|
|
|
|
listB.sort(cmp);
|
|
S b = processor.create(listB);
|
|
|
|
listA.addAll(listB);
|
|
listA.sort(cmp);
|
|
|
|
S s = processor.merge(a, b, cmp);
|
|
|
|
assertTrue(processor.check(s));
|
|
assertIterableEquals(listA, processor.iterate(s));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_divideAlternatingWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
var div = List.of(new ArrayList<Integer>(), new ArrayList<Integer>());
|
|
for (int i = 0; i < list.size(); i++) {
|
|
div.get(i % 2).add(list.get(i));
|
|
}
|
|
|
|
var p = processor.divideAlternating(s);
|
|
|
|
assertTrue(processor.check(p.fst));
|
|
assertIterableEquals(div.get(0), processor.iterate(p.fst));
|
|
|
|
assertTrue(processor.check(p.snd));
|
|
assertIterableEquals(div.get(1), processor.iterate(p.snd));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListOfRunsProvider.class)
|
|
void testThat_divideAlternatingByRunsWorks(List<List<Integer>> runs) {
|
|
var list = runs
|
|
.stream()
|
|
.flatMap(List::stream)
|
|
.collect(Collectors.toList());
|
|
S s = processor.create(list);
|
|
|
|
var div = List.of(new ArrayList<Integer>(), new ArrayList<Integer>());
|
|
for (int i = 0; i < runs.size(); i++) {
|
|
div.get(i % 2).addAll(runs.get(i));
|
|
}
|
|
|
|
var p = processor.divideAlternatingByRuns(s, cmp);
|
|
|
|
assertTrue(processor.check(p.fst));
|
|
assertIterableEquals(div.get(0), processor.iterate(p.fst));
|
|
|
|
assertTrue(processor.check(p.snd));
|
|
assertIterableEquals(div.get(1), processor.iterate(p.snd));
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@ArgumentsSource(ListProvider.class)
|
|
void testThat_divideByPivotWorks(List<Integer> list) {
|
|
S s = processor.create(list);
|
|
|
|
var pivot = list.isEmpty() ? 50 : list.get(0);
|
|
var div = list
|
|
.stream()
|
|
.collect(Collectors.groupingBy(n ->
|
|
(int) Math.signum(cmp.compare(n, pivot))));
|
|
|
|
div.putIfAbsent(-1, List.of());
|
|
div.putIfAbsent(+1, List.of());
|
|
|
|
var p = processor.divideByPivot(s, pivot, cmp);
|
|
|
|
assertTrue(processor.check(p.fst));
|
|
assertIterableEquals(div.get(-1), processor.iterate(p.fst));
|
|
|
|
assertTrue(processor.check(p.snd));
|
|
assertIterableEquals(div.get(+1), processor.iterate(p.snd));
|
|
}
|
|
} |