blob: cd6c74a9ac51345c237503c78a248a2bfd6f9e6c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2017 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 static com.google.common.collect.Lists.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.xtext.xbase.lib.Functions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IteratorExtensions;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure2;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Iterators;
/**
* @author Sven Efftinge - Initial contribution and API
* @author Karsten Thoms - testMap, testFlatMap
*/
public class IteratorExtensionsTest extends BaseIterablesIteratorsTest<Iterator<Integer>> {
@Test public void testToIterable() throws Exception {
ArrayList<String> list = newArrayList("A","B");
for (String s : IteratorExtensions.toIterable(list.iterator())) {
assertTrue(list.contains(s));
}
}
@Override
protected boolean canIterateTwice() {
return false;
}
@SuppressWarnings("unchecked")
@Override
protected Iterator<Integer>[] testData(Integer... elements) {
return new Iterator[] { Iterators.forArray(elements) };
}
@SuppressWarnings("unchecked")
@Override
protected Iterator<Integer>[] nullableTestData(Integer... elements) {
return new Iterator[] { Iterators.forArray(elements) };
}
@Override
protected Iterator<Integer> dummy() {
return Collections.<Integer>emptyList().iterator();
}
@Override
protected boolean is(Iterator<Integer> input, Integer... elements) {
return Iterators.elementsEqual(input, Iterators.forArray(elements));
}
@Override
protected Iterator<Integer> operator_plus(Iterator<Integer> first, Iterator<Integer> second) {
return IteratorExtensions.operator_plus(first, second);
}
@Override
protected Integer findFirst(Iterator<Integer> input, Function1<Integer, Boolean> filter) {
return IteratorExtensions.findFirst(input, filter);
}
@Override
protected Integer findLast(Iterator<Integer> input, Function1<Integer, Boolean> filter) {
return IteratorExtensions.findLast(input, filter);
}
@Override
protected Integer last(Iterator<Integer> input) {
return IteratorExtensions.last(input);
}
@Override
protected Integer head(Iterator<Integer> input) {
return IteratorExtensions.head(input);
}
@Override
protected void forEach(Iterator<Integer> input, Procedure2<Integer, Integer> proc) {
IteratorExtensions.forEach(input, proc);
}
@Override
protected Iterator<Integer> takeWhile(Iterator<Integer> input, Function1<Integer, Boolean> filter) {
return IteratorExtensions.takeWhile(input, filter);
}
@Override
protected Iterator<Integer> dropWhile(Iterator<Integer> input, Function1<Integer, Boolean> filter) {
return IteratorExtensions.dropWhile(input, filter);
}
@Override
protected Integer max(Iterator<Integer> input) {
return IteratorExtensions.max(input);
}
@Override
protected Integer max(Iterator<Integer> input, Comparator<? super Integer> comparator) {
return IteratorExtensions.max(input, comparator);
}
@Override
protected Integer maxBy(Iterator<Integer> input, Function1<? super Integer, String> compareBy) {
return IteratorExtensions.maxBy(input, compareBy);
}
@Override
protected Integer min(Iterator<Integer> input) {
return IteratorExtensions.min(input);
}
@Override
protected Integer min(Iterator<Integer> input, Comparator<? super Integer> comparator) {
return IteratorExtensions.min(input, comparator);
}
@Override
protected Integer minBy(Iterator<Integer> input, Function1<? super Integer, String> compareBy) {
return IteratorExtensions.minBy(input, compareBy);
}
@Test public void testIndexed() {
Iterator<Pair<Integer, String>> result = IteratorExtensions.indexed(newArrayList("foo", "bar").iterator());
assertEquals(new Pair<Integer, String>(0, "foo"), result.next());
assertEquals(new Pair<Integer, String>(1, "bar"), result.next());
assertFalse(result.hasNext());
}
@Test
public void testToMap() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
pairs.add(new Pair<Integer, String>(1, "A"));
pairs.add(new Pair<Integer, String>(1, "a"));
pairs.add(new Pair<Integer, String>(2, "B"));
pairs.add(new Pair<Integer, String>(2, "b"));
Function1<Pair<Integer, String>, Integer> computeKeys = new Function1<Pair<Integer, String>, Integer>() {
@Override
public Integer apply(Pair<Integer, String> p) {
return p.getKey();
}
};
Map<Integer, Pair<Integer, String>> map = IteratorExtensions.toMap(pairs.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 2, map.size());
Assert.assertTrue("Contains 1 as key", map.keySet().contains(1));
Assert.assertEquals("Contains entry 1->a for key 1", map.get(1), new Pair<Integer, String>(1, "a"));
Assert.assertTrue("Contains 2 as key", map.keySet().contains(2));
Assert.assertEquals("Contains entry 2->b for key 2", map.get(2), new Pair<Integer, String>(2, "b"));
}
@Test
public void testToMap__WhenEmptyList() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
Function1<Pair<Integer, String>, Integer> computeKeys = new Function1<Pair<Integer, String>, Integer>() {
@Override
public Integer apply(Pair<Integer, String> p) {
return p.getKey();
}
};
Map<Integer, Pair<Integer, String>> map = IteratorExtensions.toMap(pairs.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 0, map.size());
}
@Test
public void testToMap__WhenCalculatedKeyNull() {
List<String> names = new ArrayList<String>();
names.add("Mueller");
names.add("Schneider");
names.add("Schmidt");
names.add("Koch");
Function1<String, String> computeKeys = new Function1<String, String>() {
@Override
public String apply(String p) {
return p.contains("y") ? "y" : null;
}
};
Map<String, String> map = IteratorExtensions.toMap(names.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 1, map.size());
Assert.assertTrue("Contains null as key", map.keySet().contains(null));
Assert.assertEquals("Contains entry Koch for key null", "Koch", map.get(null));
}
@Test
public void testToMap__WhenNoValuesForKey() {
List<String> names = new ArrayList<String>();
names.add("Mueller");
names.add("Schneider");
names.add("Schmidt");
names.add("Koch");
Function1<String, Boolean> computeKeys = new Function1<String, Boolean>() {
@Override
public Boolean apply(String p) {
return p.contains("y");
}
};
Map<Boolean, String> map = IteratorExtensions.toMap(names.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 1, map.size());
Assert.assertTrue("Contains FALSE as key", map.keySet().contains(Boolean.FALSE));
Assert.assertTrue("Contains entry Mueller for key FALSE", map.get(Boolean.FALSE).equals("Koch"));
Assert.assertNull("Contains no entry for key Boolean.TRUE", map.get(Boolean.TRUE));
}
@Test(expected = NullPointerException.class)
public void testToMap__WhenFunctionNull() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
Function1<Pair<Integer, String>, Integer> computeKeys = null;
IteratorExtensions.toMap(pairs.iterator(), computeKeys);
}
@Test
public void testGroupBy() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
pairs.add(new Pair<Integer, String>(1, "A"));
pairs.add(new Pair<Integer, String>(1, "a"));
pairs.add(new Pair<Integer, String>(2, "B"));
pairs.add(new Pair<Integer, String>(2, "b"));
Function1<Pair<Integer, String>, Integer> computeKeys = new Function1<Pair<Integer, String>, Integer>() {
@Override
public Integer apply(Pair<Integer, String> p) {
return p.getKey();
}
};
Map<Integer, List<Pair<Integer, String>>> map = IteratorExtensions.groupBy(pairs.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 2, map.size());
Assert.assertTrue("Contains 1 as key", map.keySet().contains(1));
Assert.assertEquals("Contains 2 entries for key 1", 2, map.get(1).size());
Assert.assertEquals("Contains entry 1->A for key 1", new Pair<Integer, String>(1, "A"), map.get(1).get(0));
Assert.assertEquals("Contains entry 1->a for key 1", new Pair<Integer, String>(1, "a"), map.get(1).get(1));
Assert.assertTrue("Contains 2 as key", map.keySet().contains(2));
Assert.assertEquals("Contains 2 entries for key 2", 2, map.get(2).size());
Assert.assertEquals("Contains entry 2->B for key 2", new Pair<Integer, String>(2, "B"), map.get(2).get(0));
Assert.assertEquals("Contains entry 2->b for key 2", new Pair<Integer, String>(2, "b"), map.get(2).get(1));
}
@Test
public void testGroupBy__WhenEmptyList() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
Function1<Pair<Integer, String>, Integer> computeKeys = new Function1<Pair<Integer, String>, Integer>() {
@Override
public Integer apply(Pair<Integer, String> p) {
return p.getKey();
}
};
Map<Integer, List<Pair<Integer, String>>> map = IteratorExtensions.groupBy(pairs.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 0, map.size());
}
@Test
public void testGroupBy__WhenCalculatedKeyNull() {
List<String> names = new ArrayList<String>();
names.add("Mueller");
names.add("Schneider");
names.add("Schmidt");
names.add("Koch");
Function1<String, String> computeKeys = new Function1<String, String>() {
@Override
public String apply(String p) {
return p.contains("y") ? "y" : null;
}
};
Map<String, List<String>> map = IteratorExtensions.groupBy(names.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 1, map.size());
Assert.assertTrue("Contains null as key", map.keySet().contains(null));
Assert.assertEquals("Contains 4 entries for key null", 4, map.get(null).size());
}
@Test
public void testGroupBy__WhenNoValuesForKey() {
List<String> names = new ArrayList<String>();
names.add("Mueller");
names.add("Schneider");
names.add("Schmidt");
names.add("Koch");
Function1<String, Boolean> computeKeys = new Function1<String, Boolean>() {
@Override
public Boolean apply(String p) {
return p.contains("y");
}
};
Map<Boolean, List<String>> map = IteratorExtensions.groupBy(names.iterator(), computeKeys);
Assert.assertEquals("Expected grouped map size", 1, map.size());
Assert.assertTrue("Contains FALSE as key", map.keySet().contains(Boolean.FALSE));
Assert.assertEquals("Contains 4 entries for key Boolean.FALSE", 4, map.get(Boolean.FALSE).size());
Assert.assertTrue("Contains entry Mueller for key FALSE", map.get(Boolean.FALSE).contains("Mueller"));
Assert.assertNull("Contains no entry for key Boolean.TRUE", map.get(Boolean.TRUE));
}
@Test(expected = NullPointerException.class)
public void testGroupBy__WhenFunctionNull() {
List<Pair<Integer, String>> pairs = new ArrayList<Pair<Integer, String>>();
Function1<Pair<Integer, String>, Integer> computeKeys = null;
IteratorExtensions.groupBy(pairs.iterator(), computeKeys);
}
@Test public void testReject() {
Function1<Integer, Boolean> function = new Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return p % 2 == 0;
}
};
assertEquals(newArrayList(1,3,5),newArrayList(IteratorExtensions.reject(newArrayList(1,2,3,4,5).iterator(), function)));
Function1<Integer, Boolean> functionNullSafe = new Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return p == null || p % 2 == 0;
}
};
assertEquals(newArrayList(1,5),newArrayList(IteratorExtensions.reject(newArrayList(1,2,null,4,5).iterator(), functionNullSafe)));
try {
newArrayList(IteratorExtensions.reject(null, function));
fail("NullPointerException expected");
} catch (NullPointerException e) {
// expected NPE
}
try {
newArrayList(IteratorExtensions.reject(newArrayList(1,2,3).iterator(), null));
fail("NullPointerException expected");
} catch (NullPointerException e) {
// expected NPE
}
Function1<Integer, Boolean> brokenFunction = new Function1<Integer, Boolean>() {
@Override
public Boolean apply(Integer p) {
return null;
}
};
try {
newArrayList(IteratorExtensions.reject(newArrayList(1,2,3).iterator(), brokenFunction));
fail("NullPointerException expected");
} catch (NullPointerException e) {
// expected NPE
}
}
@Test public void testMap () {
ArrayList<String> list = newArrayList("foo", "bar");
final Functions.Function1<String, String> function = new Functions.Function1<String, String>() {
@Override
public String apply(String p) {
return "Hello "+p;
}
};
assertEquals(newArrayList("Hello foo", "Hello bar"), newArrayList(IteratorExtensions.map(list.iterator(), function)));
// test that the returned iterator supports remove on the underyling list
// therefore we need a function that maps to the same object contained in the list
final Functions.Function1<String, String> functionForRemove = new Functions.Function1<String, String>() {
@Override
public String apply(String p) {
return "foo".equals(p) ? p : "Hello "+p;
}
};
assertTrue(list.contains("foo"));
assertEquals(2, list.size());
assertEquals(newArrayList("foo", "Hello bar"), newArrayList(IteratorExtensions.map(list.iterator(), functionForRemove)));
Iterator<String> iterator = IteratorExtensions.map(list.iterator(), functionForRemove);
iterator.next();
iterator.remove();
assertTrue(!list.contains("foo"));
assertEquals(1, list.size());
}
@Test public void testFlatMap () {
ArrayList<String> list = newArrayList("foo", "bar");
final Functions.Function1<String, Iterator<String>> function = new Functions.Function1<String, Iterator<String>>() {
@Override
public Iterator<String> apply(String p) {
return newArrayList("Hello", p).iterator();
}
};
assertEquals(newArrayList("Hello", "foo", "Hello", "bar"), newArrayList(IteratorExtensions.flatMap(list.iterator(), function)));
}
@Test public void testContains() {
ArrayList<String> list = newArrayList("element1", "element2", "element3", null);
assertTrue(IteratorExtensions.contains(list.iterator(), "element3"));
assertTrue(IteratorExtensions.contains(list.iterator(), new String("element3")));
assertTrue(IteratorExtensions.contains(list.iterator(), null));
assertFalse(IteratorExtensions.contains(list.iterator(), "element4"));
assertFalse(IteratorExtensions.contains(list.iterator(), new String("element4")));
}
}