package unify; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.Unify; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import junit.framework.Assert; public class UnifyTest extends Unify { /** * Testing the unification for cases with (n)one pair and without generics. */ @Test public void unifyTestTrivial() { /* * INIT */ TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); UnifyType number = tf.getSimpleType("Number"); UnifyType object = tf.getSimpleType("Object"); UnifyType integer = tf.getSimpleType("Integer"); UnifyType doubl = tf.getSimpleType("Double"); fcb.add(number, object); fcb.add(integer, number); fcb.add(doubl, number); IFiniteClosure fc = fcb.getCollectionExample(); /* * Test 1: * * unify({ }) = { } */ Set eq = new HashSet(); Set> expected = new HashSet<>(); expected.add(new HashSet<>()); Set> actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 2: * * (a <. Number) */ UnifyType tphA = tf.getPlaceholderType("a"); eq = new HashSet<>(); eq.add(new UnifyPair(tphA, number, PairOperator.SMALLERDOT)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, integer, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, doubl, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 3: * * (Integer <. a) */ eq = new HashSet<>(); eq.add(new UnifyPair(integer, tphA, PairOperator.SMALLERDOT)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, integer, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, object, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 4: * * (a <.? Number) */ eq = new HashSet<>(); eq.add(new UnifyPair(tphA, number, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 5: * * (a <.? ? super Integer) */ UnifyType supInteger = tf.getSuperType(integer); UnifyType supNumber = tf.getSuperType(number); UnifyType supObject = tf.getSuperType(object); eq = new HashSet<>(); eq.add(new UnifyPair(tphA, supInteger, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, integer, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, object, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supInteger, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supNumber, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supObject, PairOperator.EQUALSDOT)); actual = unify(eq, fc); System.out.println("? super Integer"); System.out.println(actual); actual = filterGeneratedTPHsMultiple(actual); Assert.assertEquals(expected, actual); /* * Test 6: * * (Number <.? a) * */ eq = new HashSet<>(); UnifyType extNumber = tf.getExtendsType(number); UnifyType extObject = tf.getExtendsType(object); UnifyType supDouble = tf.getSuperType(doubl); eq.add(new UnifyPair(number, tphA, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, extNumber, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, extObject, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supInteger, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supDouble, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, supNumber, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 7: * * (? extends Number <.? a) */ eq = new HashSet<>(); eq.add(new UnifyPair(extNumber, tphA, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, extNumber, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, extObject, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 8: * * (a <.? ? extends Number) */ UnifyType extInteger = tf.getExtendsType(integer); UnifyType extDouble = tf.getExtendsType(doubl); eq = new HashSet<>(); eq.add(new UnifyPair(tphA, extNumber, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, extNumber, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, extInteger, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, extDouble, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, doubl, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, integer, PairOperator.EQUALSDOT)); addAsSet(expected, new UnifyPair(tphA, number, PairOperator.EQUALSDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 8: * * (Integer <. Number) */ eq = new HashSet<>(); eq.add(new UnifyPair(integer, number, PairOperator.SMALLERDOT)); expected = new HashSet<>(); expected.add(new HashSet<>()); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 9: * * (Integer <.? Number) */ eq = new HashSet<>(); eq.add(new UnifyPair(integer, number, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 10: * * (a <. b) */ UnifyType tphB = tf.getPlaceholderType("b"); eq = new HashSet<>(); eq.add(new UnifyPair(tphA, tphB, PairOperator.SMALLERDOT)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, tphB, PairOperator.SMALLERDOT)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); /* * Test 11: * * (a <.? b) */ eq = new HashSet<>(); eq.add(new UnifyPair(tphA, tphB, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); addAsSet(expected, new UnifyPair(tphA, tphB, PairOperator.SMALLERDOTWC)); actual = unify(eq, fc); Assert.assertEquals(expected, actual); } @Test public void unifyTestSimple() { /* * INIT */ TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); UnifyType number = tf.getSimpleType("Number"); UnifyType object = tf.getSimpleType("Object"); UnifyType integer = tf.getSimpleType("Integer"); UnifyType doubl = tf.getSimpleType("Double"); //fcb.add(number, object); fcb.add(integer, number); //fcb.add(doubl, number); IFiniteClosure fc = fcb.getCollectionExample(); /* * Test 1: * * (Vector <. Vector) * (List <. List) * * Expected: * {(b = Number), (a = Number)}, {(b = Number), (a = Integer)}, {(b = Number), (a = Integer)} * (b = Integer), */ UnifyType tphA = tf.getPlaceholderType("a"); UnifyType tphB = tf.getPlaceholderType("b"); UnifyType extB = tf.getExtendsType(tphB); UnifyType extNum = tf.getExtendsType(number); Set eq = new HashSet(); eq.add(new UnifyPair(tf.getSimpleType("Vector", tphA), tf.getSimpleType("Vector", extB), PairOperator.SMALLERDOT)); eq.add(new UnifyPair(tf.getSimpleType("List", tphB), tf.getSimpleType("List", extNum), PairOperator.SMALLERDOT)); Set> expected = new HashSet<>(); Set> actual = unify(eq, fc); System.out.println(actual); //Assert.assertEquals(actual, expected); /* * Test 2: * * Vector <. List * */ UnifyType extA = tf.getExtendsType(tphA); eq = new HashSet(); eq.add(new UnifyPair(tf.getSimpleType("Vector", extA), tf.getSimpleType("Vector", extNum), PairOperator.SMALLERDOT)); expected = new HashSet<>(); actual = unify(eq, fc); //System.out.println(actual); //Assert.assertEquals(actual, expected); /* * Test 3: * * Vector <. List * */ eq = new HashSet(); eq.add(new UnifyPair(tf.getSimpleType("Vector", extNum), tf.getSimpleType("Vector", extA), PairOperator.SMALLERDOT)); expected = new HashSet<>(); actual = unify(eq, fc); //System.out.println(actual); //Assert.assertEquals(actual, expected); /* * Test 4: * * LinkedList <. Deque <. Queue <. Collection * * Vector <. List * List <. AbstractList * ? extends Number <.? b */ eq = new HashSet(); eq.add(new UnifyPair(tf.getSimpleType("LinkedList", number), tf.getSimpleType("Deque", tphA), PairOperator.SMALLERDOT)); eq.add(new UnifyPair(tf.getSimpleType("Deque", tphA), tf.getSimpleType("Queue", tphB), PairOperator.SMALLERDOT)); eq.add(new UnifyPair(extNum, tphB, PairOperator.SMALLERDOTWC)); expected = new HashSet<>(); actual = unify(eq, fc); //System.out.println(actual); //Assert.assertEquals(actual, expected); } /** * These are tests that specifically test cases where the old unify algorithm was incomplete. */ @Test public void unifyTestExtension() { /* * INIT */ TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); UnifyType number = tf.getSimpleType("Number"); UnifyType object = tf.getSimpleType("Object"); UnifyType integer = tf.getSimpleType("Integer"); UnifyType doubl = tf.getSimpleType("Double"); //fcb.add(number, object); fcb.add(integer, number); //fcb.add(doubl, number); IFiniteClosure fc = fcb.getCollectionExample(); /* * Test 1: * This is a Test for the extension of case 1 in the cartesian product of step 4. * * (a <. Vector) * (List <. List) * * Expected: * (b = Integer), (a = Vector) * (b = ? extends Integer), (a = Vector), * (b = ? extends Integer), (a = Vector), * (b = ? super Integer), (a = Vector) * (b = ? super Integer), (a = Vector) * (b = ? super Integer), (a = Vector) * (b = ? super Integer), (a = Vector) * (b = ? extends Number), (a = Vector) * (b = ? extends Number), (a = Vector) * (b = ? extends Number), (a = Vector) * (b = ? extends Number), (a = Vector) */ UnifyType tphA = tf.getPlaceholderType("a"); UnifyType tphB = tf.getPlaceholderType("b"); UnifyType extB = tf.getExtendsType(tphB); UnifyType extNum = tf.getExtendsType(number); Set eq = new HashSet(); eq.add(new UnifyPair(tphA, tf.getSimpleType("Stack", tphB), PairOperator.SMALLERDOT)); eq.add(new UnifyPair(tf.getSimpleType("List", integer), tf.getSimpleType("List", tphB), PairOperator.SMALLERDOT)); Set> expected = new HashSet<>(); Set> actual = unify(eq, fc); System.out.println(actual); //Assert.assertEquals(actual, expected); /* * Test 2: * * This is a test for th extension of case 2 of the cartesian product of step 4. * * TODO */ /* * Test 3: * This is a test for the extension of case 3 of the cartesian product of step 4. * * (a <.? ? sup b) * (b = Number) */ UnifyType supB = tf.getSuperType(tphB); eq = new HashSet<>(); eq.add(new UnifyPair(tphA, supB, PairOperator.SMALLERDOTWC)); eq.add(new UnifyPair(tphB, number, PairOperator.EQUALSDOT)); expected = new HashSet<>(); actual = unify(eq, fc); System.out.println(actual); //Assert.assertEquals(expected, actual); /* * Test 4: * This is a test for the extension of case 4 of the cartesian product of step 4. * * */ } @Test public void unifyTestComplex() { /* * INIT */ TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); UnifyType tphT = tf.getPlaceholderType("T"); UnifyType vector = tf.getSimpleType("Vector", tphT); UnifyType number = tf.getSimpleType("Number"); UnifyType integer = tf.getSimpleType("Integer"); UnifyType object = tf.getSimpleType("Object"); UnifyType matrix = tf.getSimpleType("Matrix"); UnifyType vectorvectorint = tf.getSimpleType("Vector", tf.getSimpleType("Vector", integer)); fcb.add(integer, number); fcb.add(matrix, vectorvectorint); fcb.add(vector, object); IFiniteClosure fc = fcb.getFiniteClosure(); Set eq = new HashSet(); eq.add(new UnifyPair(tf.getSimpleType("Matrix"), tf.getSimpleType("Vector", tf.getPlaceholderType("a")), PairOperator.SMALLERDOT)); Set> expected = new HashSet<>(); Set> actual = unify(eq, fc); System.out.println("Test Matrix:"); System.out.println(actual); } @Test public void applyTypeUnificationRulesTest() { } @Test public void calculatePairSetsTest() { } @Test public void permuteParamsTest() { TypeFactory tf = new TypeFactory(); ArrayList> candidates = new ArrayList<>(); UnifyType p11 = tf.getPlaceholderType("p11"); UnifyType p12 = tf.getExtendsType(tf.getSimpleType("p12")); UnifyType p13 = tf.getSimpleType("p13"); UnifyType p21 = tf.getPlaceholderType("p21"); UnifyType p22 = tf.getPlaceholderType("p22"); UnifyType p31 = tf.getSimpleType("p31", "T"); Set p1 = new HashSet<>(); p1.add(p11); p1.add(p12); p1.add(p13); Set p2 = new HashSet<>(); p2.add(p21); p2.add(p22); Set p3 = new HashSet<>(); p3.add(p31); candidates.add(p1); candidates.add(p2); candidates.add(p3); /* * Expected Result: * { | x in { p11, p12, p13}, y in { p21, p22 }, z in { p31 }} */ Set expected = Arrays.stream(new TypeParams[] { new TypeParams(p11, p21, p31), new TypeParams(p11, p22, p31), new TypeParams(p12, p21, p31), new TypeParams(p12, p22, p31), new TypeParams(p13, p21, p31), new TypeParams(p13, p22, p31) }).collect(Collectors.toSet()); Set actual = permuteParams(candidates); Assert.assertEquals(expected, actual); } private Set> filterGeneratedTPHsMultiple(Set> set) { return set.stream().map(x -> filterGeneratedTPHs(x)).collect(Collectors.toSet()); } private Set filterGeneratedTPHs(Set set) { return set.stream().filter(x -> !((x.getRhsType() instanceof PlaceholderType) && ((PlaceholderType) x.getRhsType()).isGenerated())). filter(x -> !((x.getLhsType() instanceof PlaceholderType) && ((PlaceholderType) x.getLhsType()).isGenerated())).collect(Collectors.toSet()); } private void addAsSet(Set> addTo, UnifyPair... mPairs) { addTo.add(new HashSet<>(Arrays.stream(mPairs).collect(Collectors.toSet()))); } }