package nl.utwente.viskell.haskell.typeparser; import nl.utwente.viskell.haskell.env.Environment; import nl.utwente.viskell.haskell.type.Type; import nl.utwente.viskell.haskell.type.TypeClass; import org.junit.Assert; import org.junit.Test; /** Tests the TypeBuilder */ public class TypeBuilderTest { /** * Test helper that checks if parsing a String and then converting it back * gives the same result. */ private void roundtrip(String hs) { convert(hs, hs); } /** * Test helper that checks if parsing a String gives the expected result. */ private void convert(String from, String to) { Assert.assertEquals(to, new Environment().buildType(from).prettyPrint()); } @Test public void testBuildConstT() { this.roundtrip("Int"); } @Test public void testBuildVarT() { this.roundtrip("a"); } @Test public void testBuildFuncT() { this.roundtrip("a -> b"); } @Test public void testBuildListT() { this.roundtrip("[a]"); } @Test public void testBuildTupleT() { this.roundtrip("(String, Int)"); } @Test public void testMaybeA() { this.roundtrip("Maybe a"); } @Test public void testMaybeInt() { this.roundtrip("Maybe Int"); } @Test public void testMaybeFunc() { this.roundtrip("Maybe (Int -> Int)"); } @Test public void testMaybeMaybe() { this.roundtrip("Maybe (Maybe a)"); } @Test public void testMaybeSink() { this.roundtrip("Maybe Int -> Maybe [a]"); } @Test public void testKitchenSink() { this.roundtrip("[a] -> [b] -> [(a, b)]"); } @Test public void testPrefixUnit() { this.convert("()", "()"); } @Test public void testPrefixTuple() { this.convert("(,) a b", "(a, b)"); } @Test public void testPrefixTriple(){ this.convert("(,,) a b c", "(a, b, c)"); } @Test public void testPrefixList() { this.convert("[] a", "[a]"); } @Test public void testTypeClass() { Environment env = new Environment(); env.addTypeClass(new TypeClass("Num", Type.con("Int"), Type.con("Float"), Type.con("Double"))); env.addTypeClass(new TypeClass("Eq", Type.con("Int"), Type.con("Float"), Type.con("Double"), Type.con("Char"), Type.con("Bool"))); env.addTypeClass(new TypeClass("Functor")); Assert.assertEquals("Num a", env.buildType("Num a => a").prettyPrint()); Assert.assertEquals("Num a -> Num a", env.buildType("(Num a) => (a -> a)").prettyPrint()); Assert.assertEquals("Num a -> b", env.buildType("(Num a, Nonexistent b) => a -> b").prettyPrint()); Assert.assertEquals("Num a -> Eq b", env.buildType("(Num a, Eq b) => a -> b").prettyPrint()); Assert.assertEquals("(a -> b) -> (Functor f) a -> (Functor f) b", env.buildType("Functor f => (a -> b) -> f a -> f b").prettyPrint()); } }