| /******************************************************************************* |
| * 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); |
| } |
| } |
| } |