diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Elias Lawson-Fox (c) 2017
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Elias Lawson-Fox nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# language-elm
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = putStrLn "Fuck"
diff --git a/language-elm.cabal b/language-elm.cabal
new file mode 100644
--- /dev/null
+++ b/language-elm.cabal
@@ -0,0 +1,48 @@
+name:                language-elm
+version:             0.0.1.0
+synopsis:            Generate elm code
+description:         Generate elm code from an ast
+homepage:            https://github.com/eliaslfox/language-elm#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Elias Lawson-Fox
+maintainer:          eliaslfox@gmail.com
+copyright:           2017 Elias Lawson-Fox
+category:            Web
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Expression, Decleration, Type, Import, Program
+  build-depends:       base >= 4.7 && < 5, 
+                       HUnit >= 1 && < 2, 
+                       pretty,
+                       MissingH,
+                       regex-compat
+  default-language:    Haskell2010
+
+executable language-elm-exe
+  hs-source-dirs:      app
+  main-is:             Main.hs
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  build-depends:       base
+                     , language-elm
+  default-language:    Haskell2010
+
+test-suite language-elm-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , language-elm
+                     , HUnit
+                     , pretty
+                     , MissingH
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/eliaslfox/language-elm
diff --git a/src/Decleration.hs b/src/Decleration.hs
new file mode 100644
--- /dev/null
+++ b/src/Decleration.hs
@@ -0,0 +1,28 @@
+module Decleration where
+
+import Type
+import Expression
+import Text.PrettyPrint
+
+data Dec
+    = Dec String TypeDec [Expr] Expr
+    | DecType String [String] [(String, [TypeDec])]
+    | DecTypeAlias String [String] TypeDec
+
+toDocD :: Dec -> Doc
+toDocD dec =
+    case dec of
+        Dec str typeDec args body ->
+               text str <+> text "::" <+> toDocT typeDec $+$
+               hang (text str <+> (hsep . map toDoc $ args) <+> text "=") 4 (toDoc body)
+
+        DecTypeAlias str typeParams t->
+            text "type alias" <+> text str <+> (hsep . map text $ typeParams) <+> text "=" <+> toDocT t
+
+        DecType str typeParams types ->
+            text "type" <+> text str <+> (hsep . map text $ typeParams) <+> text "=" <+>
+                (hsep . punctuate (text " |") . map toDec $ types)
+
+            where
+                toDec (str, t) =
+                    text str <+> (hsep . map vopParam $ t)
diff --git a/src/Expression.hs b/src/Expression.hs
new file mode 100644
--- /dev/null
+++ b/src/Expression.hs
@@ -0,0 +1,112 @@
+module Expression where
+
+import Text.PrettyPrint hiding (Str)
+import Data.Maybe
+
+data Expr
+    = App String [Expr]
+    | Case Expr [(Expr, Expr)]
+    | Let Expr [(Expr, Expr)] 
+    | List [Expr]
+    | Tuple2 Expr Expr
+    | Tuple3 Expr Expr Expr
+    | Op String Expr Expr
+    | Parens Expr
+    | Str String
+    | Int Int
+    | Under
+    | BoolTrue
+    | BoolFalse
+    | Record (Maybe Expr) [(String, Expr)]
+
+var :: String -> Expr
+var str = App str []
+
+-- Takes an expression
+-- if its a single variable or tuple then id
+-- else wrap it in parens
+vop :: Expr -> Doc
+vop expr =
+    case expr of
+        App str [] ->
+            text str
+
+        Tuple2 exp1 exp2 ->
+            toDoc $ Tuple2 exp1 exp2
+
+        Tuple3 expr1 expr2 expr3 ->
+            toDoc $ Tuple3 expr1 expr2 expr3
+
+        Str str ->
+            doubleQuotes $ text str
+
+        Record a b ->
+            toDoc $ Record a b
+
+        other ->
+            parens $ toDoc other
+
+toDoc :: Expr -> Doc
+toDoc expr =
+    case expr of
+        App str exprs ->
+            text str <+> (hsep . map vop $ exprs)
+
+        Tuple2 expr1 expr2 ->
+            parens $ toDoc expr1 <> comma <+> toDoc expr2
+
+        Tuple3 expr1 expr2 expr3 ->
+            parens $ toDoc expr1 <> comma <+> toDoc expr2 <> comma <+> toDoc expr3
+
+        Str str ->
+            doubleQuotes . text $ str
+
+        Op op expr1 expr2 ->
+           vop expr1 <+> text op <+> vop expr2 
+
+        Case expr exprs ->
+            hang (text "case" <+> vop expr <+> text "of") 4 (vcat . map caseToDoc $ exprs)
+
+            where
+                caseToDoc (expr1, expr2) =
+                    toDoc expr1 <+> text "->" $$ (nest 4 $ toDoc expr2)
+
+
+        List exprs ->
+            char '[' <> (hsep . punctuate (text ",") . map toDoc $ exprs) <> char ']'
+
+        Let expr exprs ->
+            text "let" $+$ (nest 4 . vcat . map letToDoc $ exprs) $+$ text "in" $+$ (nest 4 $ toDoc expr)
+              
+            where
+                letToDoc (expr1, expr2) =
+                    toDoc expr1 <+> char '=' <+> toDoc expr2
+
+        Int i ->
+            int i
+
+        Under ->
+            char '_'
+
+        BoolTrue ->
+            text "True"
+
+        BoolFalse ->
+            text "False"
+
+        Record Nothing [] ->
+            text "{}"
+
+        Record (Just main) [] ->
+            toDoc main
+
+        Record main parts ->
+            let
+                front = fmap (\x -> toDoc x <+> char '|') main
+            in
+               char '{' <+> (Data.Maybe.fromMaybe empty front)
+               <+> nest 4 (hsep . punctuate (char ',') . map docPart $ parts)
+               <+> char '}'
+            where
+                docPart (name, value) =
+                    text name <+> char '=' <+> toDoc value
diff --git a/src/Import.hs b/src/Import.hs
new file mode 100644
--- /dev/null
+++ b/src/Import.hs
@@ -0,0 +1,55 @@
+module Import where
+
+import Text.PrettyPrint
+
+data ImportType
+    = Everything
+    | Select [ImportItem]
+    | ExposeNothing
+
+data ImportItem 
+    = Item String
+    | ItemExposing String [String]
+    | ItemEvery String
+
+data Import = Import String (Maybe String) ImportType
+
+docItem :: ImportItem -> Doc
+docItem item =
+    case item of
+        Item str ->
+            text str
+
+        ItemExposing name exposes ->
+            text name <> (parens . hsep . punctuate (text ",") . map text $ exposes)
+
+        ItemEvery name ->
+            text name <> text "(..)"
+
+exposingDoc :: ImportType -> Doc
+exposingDoc importType =
+    case importType of
+        Everything ->
+            text "exposing (..)"
+
+        ExposeNothing ->
+            empty
+
+        Select imports ->
+            text "exposing" <+> (parens . hsep . punctuate (text ",") . map docItem $ imports)
+
+toDocI :: Import -> Doc
+toDocI (Import name as exposing) =
+    text "import" <+> text name <+> asDoc <+> exposingDoc exposing
+
+    where
+        asDoc =
+            case as of
+                Nothing ->
+                    empty
+
+                Just str ->
+                    text "as" <+> text str
+            
+                
+
diff --git a/src/Program.hs b/src/Program.hs
new file mode 100644
--- /dev/null
+++ b/src/Program.hs
@@ -0,0 +1,29 @@
+module Program where
+
+import Import
+import Decleration
+import Text.PrettyPrint
+import Data.String.Utils
+import Text.Regex
+import Data.List
+
+data Program = Program String ImportType [Import] [Dec]
+
+genProgram :: Program -> Doc
+genProgram (Program name exports imports declerations) =
+    text "module" <+> text name <+> exposingDoc exports 
+    $+$ (foldl ($+$) empty . map toDocI $ imports)
+    $+$ (foldl ($+$) empty . map toDocD $ declerations)
+
+renderProgram :: Program -> String
+renderProgram program =
+    let 
+        str = (render . genProgram $ program) ++ "\n"
+    in
+        join "\n" . map addNewline . split "\n" $ str
+    where
+        addNewline line =
+            if (or $ map (\s -> isInfixOf s line) ["::", "type"]) then
+                "\n" ++ line
+            else
+                line
diff --git a/src/Type.hs b/src/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Type.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Type where
+
+import Expression
+import Text.PrettyPrint
+import Data.Maybe
+
+data TypeDec
+    = Params String [TypeDec]
+    | TApp [TypeDec]
+    | TTuple2 TypeDec TypeDec
+    | TRecord (Maybe String) [(String, TypeDec)]
+
+tvar :: String -> TypeDec
+tvar str =
+    Params str []
+
+vopTApp :: TypeDec -> Doc
+vopTApp t =
+    case t of
+        Params str types ->
+            toDocT $ Params str types
+            
+        TRecord main decs ->
+            toDocT $ TRecord main decs
+
+        _ ->
+            parens $ toDocT t
+
+vopParam :: TypeDec -> Doc
+vopParam t =
+    case t of
+        Params str [] ->
+            text str
+
+        _ ->
+            parens $ toDocT t
+        
+
+toDocT :: TypeDec -> Doc
+toDocT t =
+    case t of
+        Params p decs ->
+            text p <+> (hsep . map vopParam $ decs)
+
+        TApp types ->
+            hsep . punctuate (text " ->") . map vopTApp $ types
+            
+        TTuple2 t1 t2 ->
+            lparen <> toDocT t1 <> comma <+> toDocT t2 <> rparen
+
+        TRecord Nothing [] ->
+            "{}"
+
+        TRecord (Just main) [] ->
+            text main
+
+        TRecord main decs ->
+            let
+                front = fmap (\x -> text x <+> "|") main
+            in
+                "{" <+> Data.Maybe.fromMaybe empty front
+                <+> (hsep . punctuate "," . map docDec $ decs)
+                <+>  "}"
+            where 
+                docDec (name, dec) =
+                    text name <+> ":" <+> toDocT dec
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,325 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import Test.HUnit
+import Expression
+import Type
+import Decleration
+import Import
+import Program
+import Text.PrettyPrint hiding (Str)
+import Control.Monad 
+import Data.String.Utils
+
+assertString :: String -> String -> String -> Assertion 
+assertString preface expected actual =
+  unless (actual == expected) (assertFailure msg)
+   where msg = (if null preface then "" else preface ++ "\n") ++
+                "expected:\n\n" ++ expected ++ "\n but got:\n\n" ++ actual ++
+                "\n" ++ (show . length $ expected) ++ " - "
+                ++ (show . length $ actual)
+
+testRender ast =
+    (render . toDoc $ ast) ++ "\n"
+
+testRenderDec ast =
+    (render . toDocD $ ast) ++ "\n"
+
+testApp =
+        [ do
+            assertEqual "No arguments" (text "f") (toDoc $ App "f" [])
+        , do
+            assertEqual "single var" (text "f a") (toDoc $ App "f" [App "a" []])
+            assertEqual "two vars" (text "f a b") (toDoc $ App "f" [App "a" [], App "b" []])
+        , do
+            assertEqual "parens" (text "f (a b)") (toDoc $ App "f" [App "a" [App "b" []]])
+        ]
+
+testCase =
+    [ do
+        text <- readFile "test/case1.txt"
+        let
+            ast =
+                Case (App "color" [])
+                    [ (App "Red" [], Str "red")
+                    , (App "Blue" [], Str "blue")
+                    , (App "Green" [], Str "green")
+                    ]
+        assertEqual "colors" text $ testRender ast
+    , do
+        text <- readFile "test/case2.txt"
+        let
+            ast =
+                Case (App "m" [])
+                    [ (App "Just" [var "data"], var "data")
+                    , (var "Nothing", Str "")
+                    ]
+        assertEqual "maybe" text $ testRender ast
+    , do
+        text <- readFile "test/case3.txt"
+        let
+            ast =
+                Case (Tuple2 (var "a") (var "b"))
+                    [ (Tuple2 (Int  1) (Int 2), BoolTrue)
+                    , (Under, BoolFalse)
+                    ]
+        assertEqual "tuple" text $ testRender ast 
+    , do
+        text <- readFile "test/case4.txt"
+        let
+            ast =
+                Case (App "f" [var "x"])
+                    [ (BoolTrue, Str "true")
+                    , (BoolFalse, Str "false")
+                    ]
+
+        assertEqual "application" text $ testRender ast
+    , do
+        text <- readFile "test/case5.txt"
+        let
+            ast =
+                Case (var "b")
+                    [ (BoolTrue,
+                        Let (Str "true")
+                            [ (Under, App "Debug.log" [Str "logging", Str "its true"]) 
+                            ])
+                    , (BoolFalse,
+                        Let (Str "false")
+                            [ (Under, App "Debug.log" [Str "logging", Str "its false"]) 
+                            ])
+                    ]
+
+        assertEqual "let in case" text $ testRender ast
+    ]
+
+testLet =
+    [ do
+        text <- readFile "test/let1.txt"
+        let
+            ast =
+                Let (var "a")
+                    [ (var "a", Int 5) ]
+
+        assertEqual "application" text $ testRender ast 
+    , do
+        text <- readFile "test/let2.txt"
+        let
+            ast =
+                Let (App "f" [var "a", var "b"])
+                    [ (var "a", Int 5)
+                    , (var "b", Int 6)
+                    ]
+        assertEqual "more variables" text $ testRender ast
+    ]
+
+testOp =
+    [ do
+        assertEqual "plus" (text "a + b") (toDoc $ Op "+" (var "a") (var "b"))
+        assertEqual "compose" (text "a <<< b") (toDoc $ Op "<<<" (var "a") (var "b"))
+        assertEqual "longer names" (text "abc >>> def") 
+            (toDoc $ Op ">>>" (var "abc") (var "def"))
+        assertEqual "parens" (text "(f a) + (g b)")
+            (toDoc $ (Op "+" (App "f" [var "a"]) (App "g" [var "b"])))
+    ]
+
+testList =
+    [ do
+        assertEqual "empty" (text "[]") (toDoc $ List [])
+    , do
+        assertEqual "some stuff" (text "[1, 2, 3]")
+            (toDoc $ List [Int 1, Int 2, Int 3])
+    ]
+
+testRecord =
+    [ do
+        assertEqual "empty" (text "{}") (toDoc $ Record Nothing [])
+        assertEqual "no sets" (text "a") (toDoc $ Record (Just $ var "a") [])
+        assertEqual "some stuff"
+            (text "{ a | b = 5 }")
+            (toDoc $ Record (Just $ var "a") [("b", Int 5)])
+    ]
+
+testType =
+    [ do
+        assertEqual "simple" (text "a") (toDocT $ tvar "a")
+        assertEqual "param" (text "Maybe a") (toDocT $ Params "Maybe" [tvar "a"])
+        assertEqual "multi param" (text "Result String Int")
+            (toDocT $ Params "Result" [tvar "String", tvar "Int"])
+    , do
+        assertEqual "app" (text "a -> b")
+            (toDocT $ TApp [tvar "a", tvar "b"])
+        assertEqual "more app" (text "a -> b -> c")
+            (toDocT $ TApp [tvar "a", tvar "b", tvar "c"])
+        assertEqual "nested app" (text "(a -> b) -> a -> b")
+            (toDocT $ TApp [TApp [tvar "a", tvar "b"], tvar "a", tvar "b"])
+    , do
+        assertEqual "more nested stuff" (text "Maybe (a -> b) String")
+            (toDocT $ Params "Maybe" [TApp [tvar "a", tvar "b"], tvar "String"])
+        assertEqual "alternate nesting" (text "Maybe (Maybe a)")
+            (toDocT $ Params "Maybe" [Params "Maybe" [tvar "a"]])
+    , do
+        assertEqual "record types" (text "{}") (toDocT $ TRecord Nothing [])
+        assertEqual "memier record types"
+            (text "{ a : Int, b : Int }")
+            (toDocT $ TRecord Nothing [("a", tvar "Int"), ("b", tvar "Int")])
+        assertEqual "the dankest rarest memes"
+            (text "{ a | b : Int }")
+            (toDocT $ TRecord (Just "a") [("b", tvar "Int")])
+    ]
+
+testDec =
+    [ do
+        text <- readFile "test/dec.txt"
+        let
+            ast =
+                Dec
+                    "withDefault"
+                    (TApp [tvar "a", Params "Maybe" [tvar "a"], tvar "a"])
+                    [var "default", var "maybe"]
+                    (Case 
+                        (var "maybe")
+                        [ (App "Just" [var "data"], var "data")
+                        , (var "Nothing", var "default")
+                        ])
+        assertEqual "test" text $ testRenderDec ast
+    ]
+
+testDecType =
+    [ do
+        assertEqual "what even goes here?" (text "type User = User String")
+            (toDocD $ DecType "User" [] [("User", [tvar "String"])])
+        assertEqual "que??" (text "type Color = Red | Blue | Green")
+            (toDocD $ DecType "Color" [] [("Red", []), ("Blue", []), ("Green", [])])
+        assertEqual ":(" (text "type Data = DataA (Maybe String) | DataB (String -> Int)")
+            (toDocD $ DecType "Data" []
+                [ ("DataA", [Params "Maybe" [tvar "String"]])
+                , ("DataB", [TApp [tvar "String", tvar "Int"]])
+                ])
+        assertEqual "noh" (text "type Maybe a = Nothing | Just a")
+            (toDocD $ DecType "Maybe" ["a"]
+                [ ("Nothing", [])
+                , ("Just", [tvar "a"])
+                ])
+    ]
+
+testDecTypeAlias =
+    [ do
+        assertEqual "this stuff" (text "type alias Model = Int")
+            (toDocD $ DecTypeAlias "Model" [] (tvar "Int"))
+        assertEqual "dubple" (text "type alias Duple a = (a, a)")
+            (toDocD $ DecTypeAlias "Duple" ["a"] $ TTuple2 (tvar "a") (tvar "a"))
+    ]
+
+testImport =
+    [ do
+        assertEqual "wut" (text "import List") (toDocI $ Import "List" Nothing ExposeNothing)
+        assertEqual "wut" (text "import List as L") (toDocI $ Import "List" (Just "L") ExposeNothing)
+        assertEqual "wut" (text "import List exposing (map)") (toDocI $ Import "List" Nothing $ Select [Item "map"])
+        assertEqual "wut" (text "import List as L exposing (map)")
+            (toDocI $ Import "List" (Just "L") $ Select [Item "map"])
+        assertEqual "wut" (text "import List exposing (List(..))")
+            (toDocI $ Import "List" Nothing $ Select [ItemEvery "List"])
+        assertEqual "wut" (text "import List exposing (List(Cons))")
+            (toDocI $ Import "List" Nothing $ Select [ItemExposing "List" ["Cons"]])
+    ]
+
+testProgram =
+    [ do
+        file <- readFile "test/program1.elm"
+
+        let
+            ast =
+                Program
+                    "Maybe"
+                    (Select 
+                        [ ItemExposing "Maybe" ["Just", "Nothing"]
+                        , Item "andThen"
+                        , Item "map"
+                        , Item "map2"
+                        , Item "map3"
+                        , Item "map4"
+                        , Item "map5"
+                        , Item "withDefault"
+                        ])
+
+                   []
+                   [ DecType "Maybe" ["a"] [ ("Nothing", []), ("Just", [tvar "a"]) ]
+                   , Dec "withDefault" 
+                        (TApp [tvar "a", Params "Maybe" [tvar "a"], tvar "a"])
+                        [var "default", var "maybe"] 
+                        (Case (var "maybe")
+                        [ (App "Just" [var "value"], var "value")
+                        , (var "Nothing", var "default")
+                        ])
+                   , Dec "map"
+                        (TApp 
+                            [ TApp [tvar "a", tvar "b"]
+                            , Params "Maybe" [tvar "a"]
+                            , Params "Maybe" [tvar "b"]
+                            ])
+                        [var "f", var "maybe"]
+                        (Case (var "maybe")
+                            [ (App "Just" [var "value"], App "Just" [App "f" [var "value"]])
+                            , (var "Nothing", var "Nothing")
+                            ])
+                    , Dec "map2"
+                        (TApp
+                            [ TApp [tvar "a", tvar "b", tvar "value"]
+                            , Params "Maybe" [tvar "a"]
+                            , Params "Maybe" [tvar "b"]
+                            , Params "Maybe" [tvar "value"]
+                            ])
+                        [var "func", var "ma", var "mb"]
+                        (Case (Tuple2 (var "ma") (var "mb"))
+                            [ (Tuple2 (App "Just" [var "a"]) (App "Just" [var "b"])
+                                , App "Just" [App "func" [var "a", var "b"]])
+                            , (var "_", var "Nothing")
+                            ])
+                   , Dec "map3"
+                        (TApp
+                            [ TApp 
+                                [ tvar "a"
+                                , tvar "b"
+                                , tvar "c"
+                                , tvar "value"
+                                ]
+                            , Params "Maybe" [tvar "a"]
+                            , Params "Maybe" [tvar "b"]
+                            , Params "Maybe" [tvar "c"]
+                            , Params "Maybe" [tvar "value"]
+                            ])
+                        [var "func", var "ma", var "mb", var "mc"]
+                        (Case (Tuple3 (var "ma") (var "mb") (var "mc"))
+                            [ (Tuple3
+                                (App "Just" [var "a"])
+                                (App "Just" [var "b"])
+                                (App "Just" [var "c"]),
+                              (App "Just" [App "func" [var "a", var "b", var "c"]]))
+                            , (var "_", var "Nothing")
+                            ]
+                        )
+                        
+
+                   ]
+        Main.assertString "meh" file $ renderProgram ast
+    ]
+
+tests = 
+    TestList 
+        [ "test var" ~: testApp
+        , "test case" ~: testCase
+        , "test let" ~: testLet
+        , "test op" ~: testOp
+        , "test list" ~: testList
+        , "test record" ~: testRecord
+        , "test type" ~: testType
+        , "test dec type alias" ~: testDecTypeAlias
+        , "test dec type" ~: testDecType
+        , "test dec" ~: testDec
+        , "test import" ~: testImport
+        , "test program" ~: testProgram
+        ]
+
+main :: IO Counts
+main = runTestTT tests
