blob: 59369d3e20fc62a457e69cd39cd403d91d125265 [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.Iterator;
import java.util.List;
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.LazyBagOnCollection;
import org.eclipse.m2m.atl.emftvm.util.LazyCollection;
import org.eclipse.m2m.atl.emftvm.util.LazyList;
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 LazyBag}.
*
* @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
*/
public class LazyBagTest extends LazyCollectionTest {
private final List<String> dataSource = new ArrayList<String>();
{
dataSource.add("One");
dataSource.add("Two");
dataSource.add("Three");
dataSource.add("Three");
}
/**
* {@inheritDoc}
*/
@Override
protected List<String> getDataSource() {
return dataSource;
}
/**
* {@inheritDoc}
*/
@Override
protected LazyBag<String> getTestLazyCollection() {
// Don't reuse lazy collections because their cache takes over when it
// is complete
return new LazyBag<String>(getDataSource());
}
/**
* {@inheritDoc}
*/
@Override
protected <T> LazyBag<T> getEmptyLazyCollection() {
return new LazyBag<T>(null);
}
/**
* Tests {@link LazyBag#collect(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testCollect() {
final LazyBag<String> bag = getTestLazyCollection();
final LazyBag<Integer> lengths = bag.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(bag.size(), lengths.size());
final Iterator<Integer> lengthIt = lengths.iterator();
for (String element : bag) {
assertEquals(element.length(), lengthIt.next().intValue());
}
assertFalse(lengthIt.hasNext());
final LazyBag<Object> nulls = bag.collect(new NativeCodeBlock() {
{
setParentFrame(new StackFrame(EmftvmFactory.eINSTANCE.createExecEnv(), this));
getLocalVariables().add(EmftvmFactory.eINSTANCE.createLocalVariable());
}
});
assertEquals(bag.size(), nulls.size());
final Iterator<Object> nullIt = nulls.iterator();
for (@SuppressWarnings("unused")
String element : bag) {
assertNull(nullIt.next());
}
assertFalse(nullIt.hasNext());
}
/**
* Tests {@link LazyBag#equals(Object)}.
*/
public void testEquals() {
final LazyBag<String> bag = getTestLazyCollection();
assertTrue(bag.equals(bag));
assertFalse(bag.equals(this));
assertFalse(bag.equals(null));
assertFalse(bag.equals(getDataSource()));
assertTrue(bag.equals(bag.asBag()));
assertFalse(bag.equals(bag.including(null)));
assertFalse(bag.equals(bag.excluding(bag.asSequence().first())));
assertFalse(bag.equals(bag.excluding(bag.asSequence().last())));
}
/**
* Tests {@link LazyBag#flatten()}.
*/
public void testFlatten() {
final LazyBag<String> bag = getTestLazyCollection();
final LazyBag<?> newBag = bag.flatten();
assertEquals(bag, newBag);
final LazyBag<LazyBag<String>> bagBag = new LazyBag<LazyBag<String>>().including(bag);
assertEquals(bag, bagBag.flatten());
final LazyBag<LazyBag<LazyBag<String>>> bagBagBag = new LazyBag<LazyBag<LazyBag<String>>>().including(bagBag);
assertEquals(bag, bagBagBag.flatten());
final LazyBag<LazySet<LazyBag<String>>> bagSetBag = new LazyBag<LazySet<LazyBag<String>>>()
.including(new LazySet<LazyBag<String>>().including(bag).including(bag));
assertEquals(bag, bagSetBag.flatten());
}
/**
* Tests {@link LazyBag#hashCode()}.
*/
public void testHashCode() {
final LazyBag<String> bag = getTestLazyCollection();
assertEquals(bag.asBag().hashCode(), bag.hashCode());
assertFalse(getDataSource().hashCode() == bag.hashCode());
assertFalse(bag.hashCode() == bag.including("Four").hashCode());
}
/**
* Tests {@link LazyBag#asString()}.
*/
public void testAsString() {
final LazyCollection<String> bag = getTestLazyCollection();
assertEquals(getDataSource().toString().replace("[", "Bag{'").replace(", ", "', '").replace("]", "'}"),
bag.asString(EmftvmFactory.eINSTANCE.createExecEnv()));
}
/**
* Tests {@link LazyBag#intersection(LazyBag)}.
*/
public void testIntersection() {
final LazyBag<String> bag = getTestLazyCollection();
final LazyBag<String> intersection = bag.intersection(bag);
assertEquals(bag, intersection);
assertEquals(bag.excluding("Three"), bag.intersection(bag.excluding("Three")));
assertEquals(new LazyBag<String>(), bag.intersection(new LazyBag<String>()));
assertEquals(new LazyBag<String>(), new LazyBag<String>().intersection(bag));
final LazyBag<String> otherBag = new LazyBag<String>().including("One").including("Two").including("Three");
assertEquals(otherBag, bag.intersection(otherBag));
assertEquals(otherBag, otherBag.intersection(bag));
}
/**
* Tests {@link LazyBag#intersection(LazySet)}.
*/
public void testIntersection_LazySet() {
final LazyBag<String> bag = getTestLazyCollection();
final LazySet<String> set = bag.asSet();
final LazySet<String> intersection = bag.intersection(set);
assertEquals(set, intersection);
assertEquals(set.excluding("Three"), bag.intersection(set.excluding("Three")));
assertEquals(new LazySet<String>(), bag.intersection(new LazySet<String>()));
assertEquals(new LazySet<String>(), new LazyBag<String>().intersection(set));
final LazySet<String> otherSet = new LazySet<String>().including("One").including("Two").including("Three");
assertEquals(otherSet, bag.intersection(otherSet));
}
/**
* Tests {@link LazyBag#reject(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testReject() {
final LazyBag<String> bag = getTestLazyCollection();
final String element = bag.asSequence().last();
final LazyBag<String> rejected = bag.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(bag.size() - bag.count(element), rejected.size());
assertFalse(rejected.contains(element));
assertEquals(bag.excluding(element), rejected);
assertEquals(0, bag.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(bag.size(), bag.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 LazyBag#select(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testSelect() {
final LazyBag<String> bag = getTestLazyCollection();
final String element = bag.asSequence().last();
final LazyBag<String> selected = bag.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(bag.count(element), selected.size());
assertTrue(selected.contains(element));
for (String s : selected) {
assertEquals(element, s);
}
assertEquals(0, bag.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(bag.size(), bag.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 LazyBag#union(LazyBag)}.
*/
public void testUnion() {
final LazyBag<String> bag = getTestLazyCollection();
final LazyBag<String> union = bag.union(bag);
assertEquals(bag.size() * 2, union.size());
for (String s : bag) {
assertEquals(bag.count(s) * 2, union.count(s));
}
assertEquals(bag, bag.union(new LazyBag<String>()));
assertEquals(bag, new LazyBag<String>().union(bag));
}
/**
* Tests {@link LazyBag#union(LazySet)}.
*/
public void testUnion_LazySet() {
final LazyBag<String> bag = getTestLazyCollection();
final LazySet<String> set = bag.asSet();
final LazyBag<String> union = bag.union(set);
assertEquals(bag.size() + set.size(), union.size());
for (String s : bag) {
assertEquals(bag.count(s) + 1, union.count(s));
}
assertEquals(bag, bag.union(new LazySet<String>()));
}
/**
* Tests {@link LazyBag#sortedBy(org.eclipse.m2m.atl.emftvm.CodeBlock)}.
*/
public void testSortedBy() {
final LazyBag<String> bag = getTestLazyCollection();
final List<String> expected = new ArrayList<String>(getDataSource());
Collections.sort(expected);
final LazyList<String> sortedList = bag.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, sortedList);
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 LazyBag<Object> bag2 = new LazyBagOnCollection<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 LazyList<Object> sortedList2 = bag2.sortedBy(byHashCode);
sortedList2.last(); // force eval
final long lazyEnd2 = System.nanoTime();
assertEquals(expected2, sortedList2);
ATLLogger.info(String.format("Collections.sort() : %d ms, LazyBag.sortedBy() : %d ms", (refEnd2 - refStart2) / 1000000L, (lazyEnd2 - refEnd2) / 1000000L));
}
}