blob: 4ed18e0d1548887692f58cf3f550b1c55ab77dec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xbase.tests.lib;
import java.util.Comparator;
import java.util.NoSuchElementException;
import org.eclipse.xtext.xbase.lib.Functions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Procedures;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Ordering;
/**
* @author Sebastian Zarnekow - Initial contribution and API
*/
public abstract class BaseIterablesIteratorsTest<IterableOrIterator> extends Assert {
protected Integer first = Integer.valueOf(1);
protected Integer second = Integer.valueOf(2);
protected Integer third = Integer.valueOf(3);
protected Integer forth = Integer.valueOf(4);
protected Integer fifth = Integer.valueOf(5);
protected abstract IterableOrIterator[] testData(Integer... elements);
protected abstract IterableOrIterator[] nullableTestData(Integer... elements);
protected abstract IterableOrIterator dummy();
protected abstract boolean is(IterableOrIterator input, Integer... elements);
protected abstract IterableOrIterator operator_plus(IterableOrIterator first, IterableOrIterator second);
protected boolean canIterateTwice() {
return true;
}
@Test public void testOperatorPlus_Same() {
IterableOrIterator[] data = testData(first, second);
for(int i = 0;i < data.length; i++) {
if (canIterateTwice())
assertTrue(is(operator_plus(data[i], data[i]), first, second, first, second));
else
assertTrue(is(operator_plus(data[i], data[i]), first, second));
}
}
@Test public void testOperatorPlus() {
IterableOrIterator[] firstData = testData(first, second);
IterableOrIterator[] secondData = testData(third, forth);
for(int i = 0;i < firstData.length; i++) {
assertTrue(is(operator_plus(firstData[i], secondData[i]), first, second, third, forth));
}
}
@Test public void testOperatorPlus_NPE_left() {
try {
operator_plus(null, dummy());
fail("expected NullPointerException");
} catch(NullPointerException npe) {
// expected
}
}
@Test public void testOperatorPlus_NPE_right() {
try {
operator_plus(dummy(), null);
fail("expected NullPointerException");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract Integer findFirst(IterableOrIterator input, Functions.Function1<Integer, Boolean> filter);
@Test public void testFindFirst_empty() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
};
for(IterableOrIterator testMe: testData()) {
Integer last = findFirst(testMe, filter);
assertNull("empty input yields null", last);
}
}
@Test public void testFindFirst_noMatch() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return false;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findFirst(testMe, filter);
assertNull("unmatched input yields null", last);
}
}
@Test public void testFindFirst_allMatches() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findFirst(testMe, filter);
assertEquals(first, last);
}
}
@Test public void testFindFirst_oneMatch() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return second.equals(p);
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findFirst(testMe, filter);
assertEquals(second, last);
}
}
@Test public void testFindFirst_exceptionInFilter() {
final RuntimeException expectedException = new RuntimeException();
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
throw expectedException;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
try {
findFirst(testMe, filter);
fail("expected exception");
} catch(RuntimeException e) {
assertSame(expectedException, e);
}
}
}
@Test public void testFindFirst_exceptionInFilter_emptyInput() {
final RuntimeException expectedException = new RuntimeException();
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
throw expectedException;
}
};
for(IterableOrIterator testMe: testData()) {
assertNull(findFirst(testMe, filter));
}
}
@Test public void testFindFirst_NPE_noFilter() {
for(IterableOrIterator testMe: testData()) {
try {
findFirst(testMe, null);
fail("Expected NPE");
} catch(NullPointerException npe) {
// expected
}
}
}
@Test public void testFindFirst_NPE_noInput() {
try {
findLast(null, new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
});
fail("Expected NPE");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract Integer findLast(IterableOrIterator input, Functions.Function1<Integer, Boolean> filter);
@Test public void testFindLast_empty() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
};
for(IterableOrIterator testMe: testData()) {
Integer last = findLast(testMe, filter);
assertNull("empty input yields null", last);
}
}
@Test public void testFindLast_noMatch() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return false;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findLast(testMe, filter);
assertNull("unmatched input yields null", last);
}
}
@Test public void testFindLast_allMatches() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findLast(testMe, filter);
assertEquals(third, last);
}
}
@Test public void testFindLast_oneMatch() {
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return second.equals(p);
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = findLast(testMe, filter);
assertEquals(second, last);
}
}
@Test public void testFindLast_exceptionInFilter() {
final RuntimeException expectedException = new RuntimeException();
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
throw expectedException;
}
};
for(IterableOrIterator testMe: testData(first, second, third)) {
try {
findLast(testMe, filter);
fail("expected exception");
} catch(RuntimeException e) {
assertSame(expectedException, e);
}
}
}
@Test public void testFindLast_exceptionInFilter_emptyInput() {
final RuntimeException expectedException = new RuntimeException();
Function1<Integer, Boolean> filter = new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
throw expectedException;
}
};
for(IterableOrIterator testMe: testData()) {
Integer last = findLast(testMe, filter);
assertEquals(null, last);
}
}
@Test public void testFindLast_NPE_noFilter() {
for(IterableOrIterator testMe: testData()) {
try {
findLast(testMe, null);
fail("Expected NPE");
} catch(NullPointerException npe) {
// expected
}
}
}
@Test public void testFindLast_NPE_noInput() {
try {
findLast(null, new Functions.Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return true;
}
});
fail("Expected NPE");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract Integer last(IterableOrIterator input);
@Test public void testLast_empty() {
for(IterableOrIterator testMe: testData()) {
Integer last = last(testMe);
assertNull("empty input yields null", last);
}
}
@Test public void testLast_oneEntry() {
for(IterableOrIterator testMe: testData(first)) {
Integer last = last(testMe);
assertEquals(first, last);
}
}
@Test public void testLast_entryIsNull() {
for(IterableOrIterator testMe: nullableTestData((Integer)null)) {
Integer last = last(testMe);
assertEquals(null, last);
}
}
@Test public void testLast_moreEntries() {
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer last = last(testMe);
assertEquals(third, last);
}
}
@Test public void testLast_NPE() {
try {
last(null);
fail("expeced NPE");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract Integer head(IterableOrIterator input);
@Test public void testHead_empty() {
for(IterableOrIterator testMe: testData()) {
Integer head = head(testMe);
assertNull("empty input yields null", head);
}
}
@Test public void testHead_oneEntry() {
for(IterableOrIterator testMe: testData(first)) {
Integer head = head(testMe);
assertEquals(first, head);
}
}
@Test public void testHead_entryIsNull() {
for(IterableOrIterator testMe: nullableTestData((Integer)null)) {
Integer head = head(testMe);
assertEquals(null, head);
}
}
@Test public void testHead_moreEntries() {
for(IterableOrIterator testMe: testData(first, second, third)) {
Integer head = head(testMe);
assertEquals(first, head);
}
}
@Test public void testHead_NPE() {
try {
head(null);
fail("expeced NPE");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract void forEach(IterableOrIterator input, Procedures.Procedure2<Integer, Integer> proc);
static class ForEachLoopCounter implements Procedures.Procedure2<Integer, Integer> {
private int expectedIndex = 0;
private final Integer[] values;
ForEachLoopCounter(Integer... values) {
this.values = values;
}
@Override
public void apply(Integer value, Integer index) {
assertEquals(expectedIndex, index.intValue());
assertEquals(values[expectedIndex], value);
expectedIndex++;
}
}
@Test public void testForEachWithIndex_empty() {
for(IterableOrIterator testMe: testData()) {
ForEachLoopCounter counter = new ForEachLoopCounter();
forEach(testMe, counter);
assertEquals(0, counter.expectedIndex);
}
}
@Test public void testForEachWithIndex_empty_noProcedure() {
for(IterableOrIterator testMe: testData()) {
try {
forEach(testMe, null);
fail("expeced NPE");
} catch(NullPointerException e) {
// expected
}
}
}
@Test public void testForEachWithIndex_oneEntry() {
for(IterableOrIterator testMe: testData(first)) {
ForEachLoopCounter counter = new ForEachLoopCounter(first);
forEach(testMe, counter);
assertEquals(1, counter.expectedIndex);
}
}
@Test public void testForEachWithIndex_entryIsNull() {
for(IterableOrIterator testMe: nullableTestData((Integer)null)) {
ForEachLoopCounter counter = new ForEachLoopCounter((Integer)null);
forEach(testMe, counter);
assertEquals(1, counter.expectedIndex);
}
}
@Test public void testForEachWithIndex_moreEntries() {
for(IterableOrIterator testMe: testData(first, second, forth)) {
ForEachLoopCounter counter = new ForEachLoopCounter(first, second, forth);
forEach(testMe, counter);
assertEquals(3, counter.expectedIndex);
}
}
@Test public void testForEachWithIndex_NPE() {
try {
forEach(null, new ForEachLoopCounter());
fail("expeced NPE");
} catch(NullPointerException npe) {
// expected
}
}
protected abstract IterableOrIterator takeWhile(IterableOrIterator input, Functions.Function1<Integer, Boolean> filter);
protected abstract IterableOrIterator dropWhile(IterableOrIterator input, Functions.Function1<Integer, Boolean> filter);
protected abstract Integer min(IterableOrIterator input);
protected abstract Integer max(IterableOrIterator input);
protected abstract Integer min(IterableOrIterator input, Comparator<? super Integer> comparator);
protected abstract Integer max(IterableOrIterator input, Comparator<? super Integer> comparator);
protected abstract Integer minBy(IterableOrIterator input, Functions.Function1<? super Integer, String> compareBy);
protected abstract Integer maxBy(IterableOrIterator input, Functions.Function1<? super Integer, String> compareBy);
@Test public void testTakeWhile() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
IterableOrIterator taken = takeWhile(testMe, new Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return p <= 3;
}
});
assertTrue(is(taken, first, second, third));
}
}
@Test public void testDropWhile() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
IterableOrIterator tail = dropWhile(testMe, new Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return p <= 3;
}
});
assertTrue(is(tail, forth, fifth));
}
}
@Test public void testMinComparable() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer min = min(testMe);
assertEquals(first, min);
}
}
@Test public void testMaxComparable() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer max = max(testMe);
assertEquals(fifth, max);
}
}
@Test(expected = NoSuchElementException.class)
public void testMinEmpty() {
for (IterableOrIterator testMe : testData()) {
min(testMe);
}
}
@Test(expected = NoSuchElementException.class)
public void testMaxEmpty() {
for (IterableOrIterator testMe : testData()) {
max(testMe);
}
}
@Test public void testMinComparator() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer min = min(testMe, Ordering.natural().reverse());
assertEquals(fifth, min);
}
}
@Test public void testMaxComparator() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer max = max(testMe, Ordering.natural().reverse());
assertEquals(first, max);
}
}
@Test public void testMinBy() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer min = minBy(testMe, new Function1<Integer, String>() {
@Override
public String apply(Integer p) {
return Integer.toBinaryString(p);
}
});
assertEquals(first, min);
}
}
@Test public void testMaxBy() {
for (IterableOrIterator testMe : testData(first, second, third, forth, fifth)) {
Integer max = maxBy(testMe, new Function1<Integer, String>() {
@Override
public String apply(Integer p) {
return Integer.toBinaryString(p);
}
});
assertEquals(third, max);
}
}
}