Patched for Cameron Bateman.
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/types/TypeComparatorTests.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/types/TypeComparatorTests.java
new file mode 100644
index 0000000..6be3304
--- /dev/null
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/types/TypeComparatorTests.java
@@ -0,0 +1,307 @@
+package org.eclipse.jst.jsf.core.tests.types;
+
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jst.jsf.core.internal.types.CompositeType;
+import org.eclipse.jst.jsf.core.internal.types.IAssignable;
+import org.eclipse.jst.jsf.core.internal.types.TypeComparator;
+
+/**
+ * Unit tests for the composite type comparator. Indirectly exercises
+ * type transfomer and coercers.
+ *
+ * @author cbateman
+ *
+ */
+public class TypeComparatorTests extends TestCase
+{
+ // basic types
+ private final CompositeType simpleString =
+ new CompositeType("Ljava.lang.String;", IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType simpleInteger =
+ new CompositeType(Signature.SIG_INT, IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType simpleLong =
+ new CompositeType(Signature.SIG_LONG, IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType simpleBoolean =
+ new CompositeType(Signature.SIG_BOOLEAN, IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType simpleDouble =
+ new CompositeType(Signature.SIG_DOUBLE, IAssignable.ASSIGNMENT_TYPE_RHS);
+
+ // boxed types
+ private final CompositeType boxedInteger =
+ new CompositeType("Ljava.lang.Integer;", IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType boxedLong =
+ new CompositeType("Ljava.lang.Long;", IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType boxedBoolean =
+ new CompositeType("Ljava.lang.Boolean;", IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType boxedDouble =
+ new CompositeType("Ljava.lang.Double;", IAssignable.ASSIGNMENT_TYPE_RHS);
+
+ // single interface types
+ private final CompositeType comparableType =
+ new CompositeType("Ljava.lang.Comparable;", IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType mapType =
+ new CompositeType("Ljava.util.Map;", IAssignable.ASSIGNMENT_TYPE_RHS);
+
+
+ // multi-types
+ private final CompositeType objectAndComparable =
+ new CompositeType(new String[] {"Ljava.lang.Object;", "Ljava.lang.Comparable;"}
+ , IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType objectAndMap =
+ new CompositeType(new String[] {"Ljava.lang.Object;", "Ljava.util.Map;"}
+ , IAssignable.ASSIGNMENT_TYPE_RHS);
+ private final CompositeType objectAndCollection =
+ new CompositeType(new String[] {"Ljava.lang.Object;", "Ljava.util.Collection;"}
+ , IAssignable.ASSIGNMENT_TYPE_RHS);
+
+
+ /**
+ * Sanity check on simple types
+ */
+ public void testSimpleTypes()
+ {
+ // simple integers always same
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, simpleInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple longs always same
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, simpleLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple double always same
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, simpleDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple boolean always same
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleBoolean, simpleBoolean);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple strings always same
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleString, simpleString);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * test type compatibility coercing to integer
+ */
+ public void testIntegerCoercions()
+ {
+ // simple longs can coerce to integer
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, simpleLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple doubles can coerce to integer
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, simpleDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // strings can coerce to integer
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, simpleString);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // booleans cannot coerce to integer
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, simpleBoolean);
+ assertFalse(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * test type compatibility coercing to long
+ */
+ public void testLongCoercions()
+ {
+ // simple integer can coerce to long
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, simpleInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple doubles can coerce to long
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, simpleDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // strings can coerce to long
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, simpleString);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // booleans cannot coerce to long
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, simpleBoolean);
+ assertFalse(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * test type compatibility coercing to double
+ */
+ public void testDoubleCoercions()
+ {
+ // simple longs can coerce to double
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, simpleLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // simple integer can coerce to double
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, simpleInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // strings can coerce to double
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, simpleString);
+
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // booleans cannot coerce to double
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, simpleBoolean);
+
+ assertFalse(result.getSeverity() == Diagnostic.OK);
+ }
+ /**
+ * test type compatibility coercing to string
+ */
+ public void testStringCoercions()
+ {
+ // everything coerces to String
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleString, simpleLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // everything coerces to String
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleString, simpleDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // everything coerces to String
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleString, simpleInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // everything coerces to String
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleString, simpleBoolean);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * Test compatibilty of boxed types when their simple type is expected
+ */
+ public void testSimpleToBoxConversions()
+ {
+ // Integer should convert to int
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleInteger, boxedInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // Long should convert to long
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleLong, boxedLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // Double should convert to double
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleDouble, boxedDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // Boolean should convert to boolean
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(simpleBoolean, boxedBoolean);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * Test compatibilty of simple types when their boxed type is expected
+ */
+ public void testBoxToSimpleConversions()
+ {
+ // int should convert to Integer
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(boxedInteger, simpleInteger);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // long should convert to Long
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(boxedLong, simpleLong);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // double should convert to Double
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(boxedDouble, simpleDouble);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // boolean should convert to Boolean
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(boxedBoolean, simpleBoolean);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+ }
+
+ /**
+ * Test compatiblity when an interface is expected against a list of
+ * possible types
+ */
+ public void testObjectLists()
+ {
+ // check for comparable
+ Diagnostic result =
+ TypeComparator.
+ calculateTypeCompatibility(comparableType, objectAndComparable);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // not comparable
+ result = TypeComparator.
+ calculateTypeCompatibility(comparableType, objectAndCollection);
+ assertFalse(result.getSeverity() == Diagnostic.OK);
+
+ // check for map
+ result =
+ TypeComparator.
+ calculateTypeCompatibility(mapType, objectAndMap);
+ assertTrue(result.getSeverity() == Diagnostic.OK);
+
+ // not map
+ result = TypeComparator.
+ calculateTypeCompatibility(mapType, objectAndCollection);
+ assertFalse(result.getSeverity() == Diagnostic.OK);
+ }
+}