blob: 46093d073fe717b0915a53578329fc6de321c6b8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Dennis Wagelaar.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dennis Wagelaar - initial API and
* implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.m2m.atl.emftvm.util.tests;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.m2m.atl.common.ATLLogger;
import org.eclipse.m2m.atl.emftvm.CodeBlock;
import org.eclipse.m2m.atl.emftvm.EmftvmFactory;
import org.eclipse.m2m.atl.emftvm.EmftvmPackage;
import org.eclipse.m2m.atl.emftvm.util.LazyBag;
import org.eclipse.m2m.atl.emftvm.util.LazyCollection;
import org.eclipse.m2m.atl.emftvm.util.LazyOrderedSet;
import org.eclipse.m2m.atl.emftvm.util.LazySet;
import org.eclipse.m2m.atl.emftvm.util.NativeCodeBlock;
import org.eclipse.m2m.atl.emftvm.util.StackFrame;
/**
* Tests {@link LazySet}.
*
* @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
*/
public class LazySetTest extends LazyCollectionTest {
private final Set<String> dataSource = new HashSet<String>();
{
dataSource.add("One");
dataSource.add("Two");
dataSource.add("Three");
dataSource.add("Three");
}
/**
* {@inheritDoc}
*/
@Override
protected Set<String> getDataSource() {
return dataSource;
}
/**
* {@inheritDoc}
*/
@Override
protected LazySet<String> getTestLazyCollection() {
// Don't reuse lazy collections because their cache takes over when it
// is complete
return new LazySet<String>(getDataSource());
}
/**
* {@inheritDoc}
*/
@Override
protected <T> LazySet<T> getEmptyLazyCollection() {
return new LazySet<T>(null);
}
/**
* Tests {@link LazySet#collect(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testCollect() {
final LazySet<String> set = getTestLazyCollection();
final LazyBag<Integer> lengths = set.collect(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return ((String) frame.getLocal(0)).length();
}
});
assertEquals(set.size(), lengths.size());
final Iterator<Integer> lengthIt = lengths.iterator();
for (String element : set) {
assertEquals(element.length(), lengthIt.next().intValue());
}
assertFalse(lengthIt.hasNext());
final LazyBag<Object> nulls = set.collect(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
});
assertEquals(set.size(), nulls.size());
final Iterator<Object> nullIt = nulls.iterator();
for (@SuppressWarnings("unused")
String element : set) {
assertNull(nullIt.next());
}
assertFalse(nullIt.hasNext());
}
/**
* Tests {@link LazySet#equals(Object)}.
*/
public void testEquals() {
final LazySet<String> set = getTestLazyCollection();
assertTrue(set.equals(set));
assertFalse(set.equals(this));
assertFalse(set.equals(null));
assertTrue(set.equals(getDataSource()));
assertTrue(set.equals(set.asSet()));
assertFalse(set.equals(set.including(null)));
assertFalse(set.equals(set.excluding(set.asSequence().first())));
assertFalse(set.equals(set.excluding(set.asSequence().last())));
}
/**
* Tests {@link LazySet#flatten()}.
*/
public void testFlatten() {
final LazySet<String> set = getTestLazyCollection();
final LazySet<?> newSet = set.flatten();
assertEquals(set, newSet);
final LazySet<LazySet<String>> setSet = new LazySet<LazySet<String>>().including(set);
assertEquals(set, setSet.flatten());
final LazySet<LazySet<LazySet<String>>> setSetSet = new LazySet<LazySet<LazySet<String>>>().including(setSet);
assertEquals(set, setSetSet.flatten());
final LazySet<LazyBag<LazySet<String>>> setBagSet = new LazySet<LazyBag<LazySet<String>>>()
.including(new LazyBag<LazySet<String>>().including(set).including(set));
assertEquals(set, setBagSet.flatten());
}
/**
* Tests {@link LazySet#hashCode()}.
*/
public void testHashCode() {
final LazySet<String> set = getTestLazyCollection();
assertEquals(set.asSet().hashCode(), set.hashCode());
assertEquals(getDataSource().hashCode(), set.hashCode());
assertFalse(set.hashCode() == set.including("Four").hashCode());
}
/**
* Tests {@link LazySet#asString()}.
*/
public void testAsString() {
final LazyCollection<String> list = getTestLazyCollection();
assertEquals(getDataSource().toString().replace("[", "Set{'").replace(", ", "', '").replace("]", "'}"),
list.asString(EmftvmFactory.eINSTANCE.createExecEnv()));
}
/**
* Tests {@link LazySet#intersection(LazySet)}.
*/
public void testIntersection() {
final LazySet<String> set = getTestLazyCollection();
final LazySet<String> intersection = set.intersection(set);
assertEquals(set, intersection);
assertEquals(set.excluding("Three"), set.intersection(set.excluding("Three")));
assertEquals(new LazySet<String>(), set.intersection(new LazySet<String>()));
assertEquals(new LazySet<String>(), new LazySet<String>().intersection(set));
final LazySet<String> otherSet = new LazySet<String>().including("One").including("Two");
assertEquals(otherSet, set.intersection(otherSet));
assertEquals(otherSet, otherSet.intersection(set));
}
/**
* Tests {@link LazySet#intersection(LazyBag)}.
*/
public void testIntersection_LazyBag() {
final LazySet<String> set = getTestLazyCollection();
final LazyBag<String> bag = set.asBag();
final LazySet<String> intersection = set.intersection(bag);
assertEquals(set, intersection);
assertEquals(set.excluding("Three"), set.intersection(bag.excluding("Three")));
assertEquals(new LazySet<String>(), set.intersection(new LazyBag<String>()));
assertEquals(new LazySet<String>(), new LazySet<String>().intersection(bag));
final LazyBag<String> otherBag = new LazyBag<String>().including("One").including("Two");
assertEquals(otherBag.asSet(), set.intersection(otherBag));
}
/**
* Tests {@link LazyCollection#isUnique(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testIsUnique() {
final LazyCollection<String> list = getTestLazyCollection();
assertFalse(list.isUnique(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return null;
}
}));
assertTrue(list.isUnique(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return frame.getLocal(0);
}
}));
assertTrue(list.excluding("Three").isUnique(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return frame.getLocal(0);
}
}));
}
/**
* Tests {@link LazySet#reject(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testReject() {
final LazySet<String> set = getTestLazyCollection();
final String element = set.asSequence().last();
final LazySet<String> rejected = set.reject(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return ((String) frame.getLocal(0)).equals(element);
}
});
assertEquals(set.size() - 1, rejected.size());
assertFalse(rejected.contains(element));
assertEquals(set.excluding(element), rejected);
assertEquals(0, set.reject(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return true;
}
}).size());
assertEquals(set.size(), set.reject(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return false;
}
}).size());
}
/**
* Tests {@link LazySet#select(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testSelect() {
final LazySet<String> set = getTestLazyCollection();
final String element = set.asSequence().last();
final LazySet<String> selected = set.select(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return ((String) frame.getLocal(0)).equals(element);
}
});
assertEquals(1, selected.size());
assertTrue(selected.contains(element));
for (String s : selected) {
assertEquals(element, s);
}
assertEquals(0, set.select(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return false;
}
}).size());
assertEquals(set.size(), set.select(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return true;
}
}).size());
}
/**
* Tests {@link LazySet#subtract(LazySet)}.
*/
public void testSubtract() {
final LazySet<String> set = getTestLazyCollection();
assertEquals(new LazySet<String>(), set.subtract(set));
assertEquals(set, set.subtract(new LazySet<String>()));
assertEquals(set, set.subtract(new LazySet<String>().including("other")));
final LazySet<String> otherSet = set.excluding(set.asSequence().first());
assertFalse(set.equals(set.subtract(otherSet)));
assertFalse(otherSet.equals(set.subtract(otherSet)));
}
/**
* Tests {@link LazySet#symmetricDifference(LazySet)}.
*/
public void testSymmetricDifference() {
final LazySet<String> set = getTestLazyCollection();
assertEquals(new LazySet<String>(), set.symmetricDifference(set));
assertEquals(set, set.symmetricDifference(new LazySet<String>()));
assertEquals(set.including("other"), set.symmetricDifference(new LazySet<String>().including("other")));
final String element = set.asSequence().first();
final LazySet<String> otherSet = set.excluding(element);
assertEquals(new LazySet<String>().including(element), set.symmetricDifference(otherSet));
assertEquals(new LazySet<String>().including(element), set.symmetricDifference(otherSet));
}
/**
* Tests {@link LazySet#union(LazySet)}.
*/
public void testUnion() {
final LazySet<String> set = getTestLazyCollection();
assertEquals(set, set.union(set));
assertEquals(set, set.union(new LazySet<String>()));
assertEquals(set, new LazySet<String>().union(set));
}
/**
* Tests {@link LazySet#union(LazyBag)}.
*/
public void testUnion_LazyBag() {
final LazySet<String> set = getTestLazyCollection();
final LazyBag<String> bag = set.asBag();
final LazyBag<String> union = set.union(bag);
assertEquals(set.size() + bag.size(), union.size());
for (String s : set) {
assertEquals(2, union.count(s));
}
assertEquals(bag, set.union(new LazyBag<String>()));
assertEquals(bag, new LazySet<String>().union(bag));
}
/**
* Tests {@link LazySet#sortedBy(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testSortedBy() {
final LazySet<String> set = getTestLazyCollection();
final List<String> expected = new ArrayList<String>(getDataSource());
Collections.sort(expected);
final LazyOrderedSet<String> sortedSet = set.sortedBy(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return frame.getLocal(0);
}
});
assertEquals(expected, sortedSet);
final List<Object> data = new ArrayList<Object>();
for (int i = 1; i < 100; i++) {
Iterator<EObject> contents = EmftvmPackage.eINSTANCE.eResource().getAllContents();
while (contents.hasNext()) {
data.add(contents.next());
}
}
final List<Object> expected2 = new ArrayList<Object>(data);
final LazySet<Object> set2 = new LazySet<Object>(data);
final CodeBlock byHashCode = new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
@Override
public Object execute(final StackFrame frame) {
return frame.getLocal(0).hashCode();
}
};
final long refStart2 = System.nanoTime();
Collections.sort(expected2, new Comparator<Object>() {
public int compare(Object o1, Object o2) {
return ((Integer) byHashCode.execute(byHashCode.getParentFrame().getSubFrame(byHashCode, o1))).compareTo(
((Integer) byHashCode.execute(byHashCode.getParentFrame().getSubFrame(byHashCode, o2))));
}
});
final long refEnd2 = System.nanoTime();
final LazyOrderedSet<Object> sortedSet2 = set2.sortedBy(byHashCode);
sortedSet2.last(); // force eval
final long lazyEnd2 = System.nanoTime();
assertEquals(new LazyOrderedSet<Object>(expected2), sortedSet2);
ATLLogger.info(String.format("Collections.sort() : %d ms, LazySet.sortedBy() : %d ms", (refEnd2 - refStart2) / 1000000L, (lazyEnd2 - refEnd2) / 1000000L));
}
}