/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* 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:
* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
*******************************************************************************/
package org.rascalmpl.value;
import java.net.URI;
import java.net.URISyntaxException;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.exceptions.FactTypeDeclarationException;
import org.rascalmpl.value.exceptions.FactTypeUseException;
import org.rascalmpl.value.impl.reference.ValueFactory;
import org.rascalmpl.value.type.Type;
import org.rascalmpl.value.type.TypeFactory;
import org.rascalmpl.value.type.TypeStore;
import junit.framework.TestCase;
public class TestTypeFactory extends TestCase {
private TypeFactory ft = TypeFactory.getInstance();
private ValueFactory ff = ValueFactory.getInstance();
private Type[] types = new Type[] { ft.integerType(), ft.realType(),
ft.sourceLocationType(), ft.valueType(),
ft.listType(ft.integerType()), ft.setType(ft.realType()) };
public void testGetInstance() {
if (TypeFactory.getInstance() != ft) {
fail("getInstance did not return the same reference");
}
}
public void testGetTypeByDescriptor() {
// TODO: needs to be tested, after we've implemented it
}
public void testValueType() {
if (ft.valueType() != ft.valueType()) {
fail("valueType should be canonical");
}
}
public void testIntegerType() {
if (ft.integerType() != ft.integerType()) {
fail("integerType should be canonical");
}
}
public void testDoubleType() {
if (ft.realType() != ft.realType()) {
fail("doubleType should be canonical");
}
}
public void testStringType() {
if (ft.stringType() != ft.stringType()) {
fail("stringType should be canonical");
}
}
public void testSourceLocationType() {
if (ft.sourceLocationType() != ft.sourceLocationType()) {
fail("sourceLocationType should be canonical");
}
}
public void testTupleTypeOfType() {
Type t = ft.tupleType(types[0]);
if (t != ft.tupleType(types[0])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 1);
}
public void testTupleTypeOfTypeType() {
Type t = ft.tupleType(types[0], types[1]);
if (t != ft.tupleType(types[0], types[1])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 2);
}
public void testTupleTypeOfTypeTypeType() {
Type t = ft.tupleType(types[0], types[1], types[2]);
if (t != ft.tupleType(types[0], types[1], types[2])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 3);
}
public void testTupleTypeOfTypeTypeTypeType() {
Type t = ft.tupleType(types[0], types[1], types[2], types[3]);
if (t != ft.tupleType(types[0], types[1], types[2], types[3])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 4);
}
public void testTupleTypeOfTypeTypeTypeTypeType() {
Type t = ft.tupleType(types[0], types[1], types[2], types[3],
types[4]);
if (t != ft.tupleType(types[0], types[1], types[2], types[3],
types[4])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 5);
}
public void testTupleTypeOfTypeTypeTypeTypeTypeType() {
Type t = ft.tupleType(types[0], types[1], types[2], types[3],
types[4], types[5]);
if (t != ft.tupleType(types[0], types[1], types[2], types[3],
types[4], types[5])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 6);
}
public void testTupleTypeOfTypeTypeTypeTypeTypeTypeType() {
Type t = ft.tupleType(types[0], types[1], types[2], types[3],
types[4], types[5]);
if (t != ft.tupleType(types[0], types[1], types[2], types[3],
types[4], types[5])) {
fail("tuple types should be canonical");
}
testTupleTypeOf(t, 6);
}
private void testTupleTypeOf(Type t, int width) {
if (t.getArity() != width) {
fail("tuple arity broken");
}
for (int i = 0; i < t.getArity(); i++) {
if (t.getFieldType(i) != types[i % types.length]) {
fail("Tuple field type unexpected");
}
}
}
private void testRelationTypeOf(Type t, int width) {
if (t.getArity() != width) {
fail("relation arity broken");
}
for (int i = 0; i < t.getArity(); i++) {
if (t.getFieldType(i) != types[i % types.length]) {
fail("Relation field type unexpected");
}
}
}
public void testTupleTypeOfIValueArray() {
// a and b shadow the 'types' field
try {
IValue[] a = new IValue[] { ff.integer(1), ff.real(1.0),
ff.sourceLocation(new URI("file://bla"), 0, 0, 0, 0, 0, 0) };
IValue[] b = new IValue[] { ff.integer(1), ff.real(1.0),
ff.sourceLocation(new URI("file://bla"), 0, 0, 0, 0, 0, 0) };
Type t = ft.tupleType(a);
if (t != ft.tupleType(b)) {
fail("tuples should be canonical");
}
testTupleTypeOf(t, 3);
} catch (URISyntaxException e) {
fail(e.toString());
}
}
public void testSetTypeOf() {
Type type = ft.setType(ft.integerType());
if (type != ft.setType(ft.integerType())) {
fail("set should be canonical");
}
}
public void testRelTypeType() {
try {
TypeStore store = new TypeStore();
Type namedType = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
// note that the declared type of namedType needs to be Type
Type type = ft.relTypeFromTuple(namedType);
Type namedType2 = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
if (type != ft.relTypeFromTuple(namedType2)) {
fail("relation types should be canonical");
}
if (type.getFieldType(0) != ft.integerType() &&
type.getFieldType(1) != ft.integerType()) {
fail("relation should mimick tuple field types");
}
} catch (FactTypeUseException e) {
fail("type error for correct relation");
}
}
public void testListRelTypeType() {
try {
TypeStore store = new TypeStore();
Type namedType = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
// note that the declared type of namedType needs to be Type
Type type = ft.lrelTypeFromTuple(namedType);
Type namedType2 = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
if (type != ft.lrelTypeFromTuple(namedType2)) {
fail("list relation types should be canonical");
}
if (type.getFieldType(0) != ft.integerType() &&
type.getFieldType(1) != ft.integerType()) {
fail("list relation should mimick tuple field types");
}
} catch (FactTypeUseException e) {
fail("type error for correct list relation");
}
}
public void testRelTypeNamedType() {
try {
TypeStore store = new TypeStore();
Type namedType = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
// note that the declared type of namedType needs to be AliasType
Type type = ft.relTypeFromTuple(namedType);
Type namedType2 = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
if (type != ft.relTypeFromTuple(namedType2)) {
fail("relation types should be canonical");
}
} catch (FactTypeUseException e) {
fail("type error for correct relation");
}
}
public void testListRelTypeNamedType() {
try {
TypeStore store = new TypeStore();
Type namedType = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
// note that the declared type of namedType needs to be AliasType
Type type = ft.lrelTypeFromTuple(namedType);
Type namedType2 = ft.aliasType(store, "myTuple", ft.tupleType(ft.integerType(), ft.integerType()));
if (type != ft.lrelTypeFromTuple(namedType2)) {
fail("list relation types should be canonical");
}
} catch (FactTypeUseException e) {
fail("type error for correct list relation");
}
}
public void testRelTypeTupleType() {
Type tupleType = ft
.tupleType(ft.integerType(), ft.integerType());
// note that the declared type of tupleType needs to be TupleType
Type type = ft.relTypeFromTuple(tupleType);
Type tupleType2 = ft.tupleType(ft.integerType(), ft
.integerType());
if (type != ft.relTypeFromTuple(tupleType2)) {
fail("relation types should be canonical");
}
}
public void testListRelTypeTupleType() {
Type tupleType = ft
.tupleType(ft.integerType(), ft.integerType());
// note that the declared type of tupleType needs to be TupleType
Type type = ft.lrelTypeFromTuple(tupleType);
Type tupleType2 = ft.tupleType(ft.integerType(), ft
.integerType());
if (type != ft.lrelTypeFromTuple(tupleType2)) {
fail("list relation types should be canonical");
}
}
public void testRelTypeOfType() {
Type type = ft.relType(types[0]);
if (type != ft.relType(types[0])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 1);
}
public void testRelTypeOfTypeType() {
Type type = ft.relType(types[0], types[1]);
if (type != ft.relType(types[0], types[1])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 2);
}
public void testRelTypeOfTypeTypeType() {
Type type = ft.relType(types[0], types[1], types[2]);
if (type != ft.relType(types[0], types[1], types[2])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 3);
}
public void testRelTypeOfTypeTypeTypeType() {
Type type = ft.relType(types[0], types[1], types[2], types[3]);
if (type != ft.relType(types[0], types[1], types[2], types[3])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 4);
}
public void testRelTypeOfTypeTypeTypeTypeType() {
Type type = ft.relType(types[0], types[1], types[2], types[3], types[4]);
if (type != ft.relType(types[0], types[1], types[2], types[3], types[4])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 5);
}
public void testRelTypeOfTypeTypeTypeTypeTypeType() {
Type type = ft.relType(types[0], types[1], types[2], types[3], types[4], types[5]);
if (type != ft.relType(types[0], types[1], types[2], types[3], types[4], types[5])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 6);
}
public void testRelTypeOfTypeTypeTypeTypeTypeTypeType() {
Type type = ft.relType(types[0], types[1], types[2], types[3], types[4], types[5]);
if (type != ft.relType(types[0], types[1], types[2], types[3], types[4], types[5])) {
fail("relation types should be canonical");
}
testRelationTypeOf(type, 6);
}
public void testNamedType() {
try {
TypeStore ts = new TypeStore();
Type t1 = ft.aliasType(ts, "myType", ft.integerType());
Type t2 = ft.aliasType(ts, "myType", ft.integerType());
if (t1 != t2) {
fail("named types should be canonical");
}
try {
ft.aliasType(ts, "myType", ft.realType());
fail("Should not be allowed to redeclare a type name");
} catch (FactTypeDeclarationException e) {
// this should happen
}
} catch (FactTypeDeclarationException e) {
fail("the above should be type correct");
}
}
public void testListType() {
Type t1 = ft.listType(ft.integerType());
Type t2 = ft.listType(ft.integerType());
if (t1 != t2) {
fail("named types should be canonical");
}
}
}