/*
* This software is subject to the terms of the Eclipse Public License v1.0
* Agreement, available at the following URL:
* http://www.eclipse.org/legal/epl-v10.html.
* You must accept the terms of that agreement to use this software.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package mondrian.olap.fun;
import mondrian.calc.*;
import mondrian.calc.impl.ArrayTupleList;
import mondrian.mdx.ResolvedFunCall;
import mondrian.olap.*;
import mondrian.olap.type.*;
import mondrian.test.FoodMartTestCase;
import junit.framework.Assert;
import java.io.PrintWriter;
import java.util.*;
/**
* <code>CrossJoint</code> tests the collation order of positive and negative
* infinity, and {@link Double#NaN}.
*
* @author <a>Richard M. Emberson</a>
* @since Jan 14, 2007
*/
public class CrossJoinTest extends FoodMartTestCase {
static List<List<Member>> m3 = Arrays.asList(
Arrays.<Member>asList(new TestMember("k"), new TestMember("l")),
Arrays.<Member>asList(new TestMember("m"), new TestMember("n")));
static List<List<Member>> m4 = Arrays.asList(
Arrays.<Member>asList(new TestMember("U"), new TestMember("V")),
Arrays.<Member>asList(new TestMember("W"), new TestMember("X")),
Arrays.<Member>asList(new TestMember("Y"), new TestMember("Z")));
static final Comparator<List<Member>> memberComparator =
new Comparator<List<Member>>() {
public int compare(List<Member> ma1, List<Member> ma2) {
for (int i = 0; i < ma1.size(); i++) {
int c = ma1.get(i).compareTo(ma2.get(i));
if (c < 0) {
return c;
} else if (c > 0) {
return c;
}
}
return 0;
}
};
private CrossJoinFunDef crossJoinFunDef;
public CrossJoinTest() {
}
public CrossJoinTest(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
crossJoinFunDef = new CrossJoinFunDef(new NullFunDef());
}
protected void tearDown() throws Exception {
super.tearDown();
}
////////////////////////////////////////////////////////////////////////
// Iterable
////////////////////////////////////////////////////////////////////////
public void testListTupleListTupleIterCalc() {
if (! Util.Retrowoven) {
CrossJoinFunDef.CrossJoinIterCalc calc =
crossJoinFunDef.new CrossJoinIterCalc(
getResolvedFunCall(), null);
doTupleTupleIterTest(calc);
}
}
protected void doTupleTupleIterTest(
CrossJoinFunDef.CrossJoinIterCalc calc)
{
TupleList l4 = makeListTuple(m4);
String s4 = toString(l4);
String e4 = "{[U, V], [W, X], [Y, Z]}";
Assert.assertEquals(e4, s4);
TupleList l3 = makeListTuple(m3);
String s3 = toString(l3);
String e3 = "{[k, l], [m, n]}";
Assert.assertEquals(e3, s3);
TupleIterable iterable = calc.makeIterable(l4, l3);
String s = toString(iterable);
String e =
"{[U, V, k, l], [U, V, m, n], [W, X, k, l], "
+ "[W, X, m, n], [Y, Z, k, l], [Y, Z, m, n]}";
Assert.assertEquals(e, s);
}
////////////////////////////////////////////////////////////////////////
// Immutable List
////////////////////////////////////////////////////////////////////////
public void testImmutableListTupleListTupleListCalc() {
CrossJoinFunDef.ImmutableListCalc calc =
crossJoinFunDef.new ImmutableListCalc(
getResolvedFunCall(), null);
doTupleTupleListTest(calc);
}
protected void doTupleTupleListTest(
CrossJoinFunDef.BaseListCalc calc)
{
TupleList l4 = makeListTuple(m4);
String s4 = toString(l4);
String e4 = "{[U, V], [W, X], [Y, Z]}";
Assert.assertEquals(e4, s4);
TupleList l3 = makeListTuple(m3);
String s3 = toString(l3);
String e3 = "{[k, l], [m, n]}";
Assert.assertEquals(e3, s3);
TupleList list = calc.makeList(l4, l3);
String s = toString(list);
String e =
"{[U, V, k, l], [U, V, m, n], [W, X, k, l], "
+ "[W, X, m, n], [Y, Z, k, l], [Y, Z, m, n]}";
Assert.assertEquals(e, s);
TupleList subList = list.subList(0, 6);
s = toString(subList);
Assert.assertEquals(6, subList.size());
Assert.assertEquals(e, s);
subList = subList.subList(0, 6);
s = toString(subList);
Assert.assertEquals(6, subList.size());
Assert.assertEquals(e, s);
subList = subList.subList(1, 5);
s = toString(subList);
e = "{[U, V, m, n], [W, X, k, l], [W, X, m, n], [Y, Z, k, l]}";
Assert.assertEquals(4, subList.size());
Assert.assertEquals(e, s);
subList = subList.subList(2, 4);
s = toString(subList);
e = "{[W, X, m, n], [Y, Z, k, l]}";
Assert.assertEquals(2, subList.size());
Assert.assertEquals(e, s);
subList = subList.subList(1, 2);
s = toString(subList);
e = "{[Y, Z, k, l]}";
Assert.assertEquals(1, subList.size());
Assert.assertEquals(e, s);
subList = list.subList(1, 4);
s = toString(subList);
e = "{[U, V, m, n], [W, X, k, l], [W, X, m, n]}";
Assert.assertEquals(3, subList.size());
Assert.assertEquals(e, s);
subList = list.subList(2, 4);
s = toString(subList);
e = "{[W, X, k, l], [W, X, m, n]}";
Assert.assertEquals(2, subList.size());
Assert.assertEquals(e, s);
subList = list.subList(2, 3);
s = toString(subList);
e = "{[W, X, k, l]}";
Assert.assertEquals(1, subList.size());
Assert.assertEquals(e, s);
subList = list.subList(4, 4);
s = toString(subList);
e = "{}";
Assert.assertEquals(0, subList.size());
Assert.assertEquals(e, s);
}
////////////////////////////////////////////////////////////////////////
// Mutable List
////////////////////////////////////////////////////////////////////////
public void testMutableListTupleListTupleListCalc() {
CrossJoinFunDef.MutableListCalc calc =
crossJoinFunDef.new MutableListCalc(
getResolvedFunCall(), null);
doMTupleTupleListTest(calc);
}
protected void doMTupleTupleListTest(
CrossJoinFunDef.BaseListCalc calc)
{
TupleList l1 = makeListTuple(m3);
String s1 = toString(l1);
String e1 = "{[k, l], [m, n]}";
Assert.assertEquals(e1, s1);
TupleList l2 = makeListTuple(m4);
String s2 = toString(l2);
String e2 = "{[U, V], [W, X], [Y, Z]}";
Assert.assertEquals(e2, s2);
TupleList list = calc.makeList(l1, l2);
String s = toString(list);
String e = "{[k, l, U, V], [k, l, W, X], [k, l, Y, Z], "
+ "[m, n, U, V], [m, n, W, X], [m, n, Y, Z]}";
Assert.assertEquals(e, s);
if (false) {
// Cannot apply Collections.reverse to TupleList
// because TupleList.set always returns null.
// (This is a violation of the List contract, but it is inefficient
// to construct a list to return.)
Collections.reverse(list);
s = toString(list);
e = "{[m, n, Y, Z], [m, n, W, X], [m, n, U, V], "
+ "[k, l, Y, Z], [k, l, W, X], [k, l, U, V]}";
Assert.assertEquals(e, s);
}
// sort
Collections.sort(list, memberComparator);
s = toString(list);
e = "{[k, l, U, V], [k, l, W, X], [k, l, Y, Z], "
+ "[m, n, U, V], [m, n, W, X], [m, n, Y, Z]}";
Assert.assertEquals(e, s);
List<Member> members = list.remove(1);
s = toString(list);
e = "{[k, l, U, V], [k, l, Y, Z], [m, n, U, V], "
+ "[m, n, W, X], [m, n, Y, Z]}";
Assert.assertEquals(e, s);
}
////////////////////////////////////////////////////////////////////////
// Helper methods
////////////////////////////////////////////////////////////////////////
protected String toString(TupleIterable l) {
StringBuffer buf = new StringBuffer(100);
buf.append('{');
int j = 0;
for (List<Member> o : l) {
if (j++ > 0) {
buf.append(", ");
}
buf.append(o);
}
buf.append('}');
return buf.toString();
}
protected TupleList makeListTuple(List<List<Member>> ms) {
final TupleList list = new ArrayTupleList(ms.get(0).size());
for (List<Member> m : ms) {
list.add(m);
}
return list;
}
protected ResolvedFunCall getResolvedFunCall() {
FunDef funDef = new TestFunDef();
Exp[] args = new Exp[0];
Type returnType =
new SetType(
new TupleType(
new Type[] {
new MemberType(null, null, null, null),
new MemberType(null, null, null, null)}));
return new ResolvedFunCall(funDef, args, returnType);
}
////////////////////////////////////////////////////////////////////////
// Helper classes
////////////////////////////////////////////////////////////////////////
public static class TestFunDef implements FunDef {
TestFunDef() {
}
public Syntax getSyntax() {
throw new UnsupportedOperationException();
}
public String getName() {
throw new UnsupportedOperationException();
}
public String getDescription() {
throw new UnsupportedOperationException();
}
public int getReturnCategory() {
throw new UnsupportedOperationException();
}
public int[] getParameterCategories() {
throw new UnsupportedOperationException();
}
public Exp createCall(Validator validator, Exp[] args) {
throw new UnsupportedOperationException();
}
public String getSignature() {
throw new UnsupportedOperationException();
}
public void unparse(Exp[] args, PrintWriter pw) {
throw new UnsupportedOperationException();
}
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
throw new UnsupportedOperationException();
}
}
public static class NullFunDef implements FunDef {
NullFunDef() {
}
public Syntax getSyntax() {
return Syntax.Function;
}
public String getName() {
return "";
}
public String getDescription() {
return "";
}
public int getReturnCategory() {
return 0;
}
public int[] getParameterCategories() {
return new int[0];
}
public Exp createCall(Validator validator, Exp[] args) {
return null;
}
public String getSignature() {
return "";
}
public void unparse(Exp[] args, PrintWriter pw) {
//
}
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
return null;
}
}
}
// End CrossJoinTest.java