diff --git a/ocaml-export.cabal b/ocaml-export.cabal
--- a/ocaml-export.cabal
+++ b/ocaml-export.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           ocaml-export
-version:        0.2.0.0
+version:        0.3.0.0
 synopsis:       Convert Haskell types in OCaml types
 description:    README.md
 category:       Web
@@ -24,7 +24,7 @@
 library
   hs-source-dirs:
       src
-  ghc-options: -Wall -Wredundant-constraints -fprint-potential-instances
+  ghc-options: -Wall
   build-depends:
       base >= 4.7 && < 5
     , aeson
@@ -66,7 +66,7 @@
   main-is: Spec.hs
   hs-source-dirs:
       test
-  ghc-options: -fprint-potential-instances
+  ghc-options: -Wall
   build-depends:
       base
     , aeson
diff --git a/src/OCaml/BuckleScript/Decode.hs b/src/OCaml/BuckleScript/Decode.hs
--- a/src/OCaml/BuckleScript/Decode.hs
+++ b/src/OCaml/BuckleScript/Decode.hs
@@ -235,7 +235,7 @@
         case Map.lookup typeRef ds of
           Just parOCamlTypeMetaData -> do
             let prefix = stext $ mkModulePrefix decOCamlTypeMetaData parOCamlTypeMetaData
-            pure $ "(fun a -> unwrapResult (" <> prefix  <> "decode" <> (stext . textUppercaseFirst $ name) <+> "a))"             
+            pure $ "(fun a -> unwrapResult (" <> prefix  <> "decode" <> (stext . textUppercaseFirst $ name) <+> "a))"
 
           -- in case of a Haskell sum of products, ocaml-export creates a definition for each product
           -- within the same file as the sum. These products will not be in the dependencies map.
@@ -267,81 +267,83 @@
 
 instance HasDecoder EnumeratorConstructor where
   render (EnumeratorConstructor name) = pure $ "| Some \"" <> stext name <> "\" -> Js_result.Ok" <+> stext name
-  
+
 instance HasDecoderRef OCamlPrimitive where
   renderRef OUnit = pure $ parens "()"
   renderRef ODate = pure "date"
   renderRef OInt = pure "int"
   renderRef OBool = pure "bool"
   renderRef OChar = pure "char"
-  renderRef OFloat = pure "float"
+  renderRef OFloat = pure "Aeson.Decode.float" -- this is to prevent overshadowing warning
   renderRef OString = pure "string"
-
   renderRef (OList (OCamlPrimitive OChar)) = pure "string"
 
-  renderRef (OList datatype@(OCamlDatatype typeRef name _)) =
-    if isTypeParameterRef datatype
-    then
-      pure . parens $ "list" <+> (parens $ "fun a -> unwrapResult (decode" <> (stext . textUppercaseFirst $ name) <+> "a)")
-    else do
-      mOCamlTypeMetaData <- asks topLevelOCamlTypeMetaData
-      case mOCamlTypeMetaData of
-        Nothing -> fail $ "OCaml.BuckleScript.Decode (HasDecoderRef (OList (OCamlDatatype typeRep name _))) mOCamlTypeMetaData is Nothing:\n\n" ++ (show datatype)
-        Just decOCamlTypeMetaData -> do
-          ds <- asks (dependencies . userOptions)
-          case Map.lookup typeRef ds of
-            Just parOCamlTypeMetaData -> do
-              let prefix = stext $ mkModulePrefix decOCamlTypeMetaData parOCamlTypeMetaData
-              pure . parens $ "list" <+> (parens $ "fun a -> unwrapResult (" <> prefix <> "decode" <> (stext . textUppercaseFirst $ name) <+> "a)")
-            Nothing -> fail ("OCaml.BuckleScript.Decode (HasDecoderRef (OList (OCamlDatatype typeRep name _))) expected to find dependency:\n\n" ++ show typeRef ++ "\n\nin\n\n" ++ show ds)
-
   renderRef (OList datatype) = do
-    dt <- renderRef datatype
+    dt <- renderRefWithUnwrapResult datatype
     pure . parens $ "list" <+> dt
 
   renderRef (OOption _) = pure ""
 
   renderRef (OEither v0 v1) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
     pure $ parens $ "either" <+> dv0 <+> dv1
 
   renderRef (OTuple2 v0 v1) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
     pure $ parens $ "pair" <+> dv0 <+> dv1
 
   renderRef (OTuple3 v0 v1 v2) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
-    dv2 <- renderRef v2
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
+    dv2 <- renderRefWithUnwrapResult v2
     pure $ parens $ "tuple3" <+> dv0 <+> dv1 <+> dv2
 
   renderRef (OTuple4 v0 v1 v2 v3) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
-    dv2 <- renderRef v2
-    dv3 <- renderRef v3
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
+    dv2 <- renderRefWithUnwrapResult v2
+    dv3 <- renderRefWithUnwrapResult v3
     pure $ parens $ "tuple4" <+> dv0 <+> dv1 <+> dv2 <+> dv3
 
   renderRef (OTuple5 v0 v1 v2 v3 v4) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
-    dv2 <- renderRef v2
-    dv3 <- renderRef v3
-    dv4 <- renderRef v4
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
+    dv2 <- renderRefWithUnwrapResult v2
+    dv3 <- renderRefWithUnwrapResult v3
+    dv4 <- renderRefWithUnwrapResult v4
     pure $ parens $ "tuple5" <+> dv0 <+> dv1 <+> dv2 <+> dv3 <+> dv4
 
   renderRef (OTuple6 v0 v1 v2 v3 v4 v5) = do
-    dv0 <- renderRef v0
-    dv1 <- renderRef v1
-    dv2 <- renderRef v2
-    dv3 <- renderRef v3
-    dv4 <- renderRef v4
-    dv5 <- renderRef v5
+    dv0 <- renderRefWithUnwrapResult v0
+    dv1 <- renderRefWithUnwrapResult v1
+    dv2 <- renderRefWithUnwrapResult v2
+    dv3 <- renderRefWithUnwrapResult v3
+    dv4 <- renderRefWithUnwrapResult v4
+    dv5 <- renderRefWithUnwrapResult v5
     pure $ parens $ "tuple6" <+> dv0 <+> dv1 <+> dv2 <+> dv3 <+> dv4 <+> dv5
 
 -- Util
+
+renderRefWithUnwrapResult :: OCamlDatatype -> Reader TypeMetaData Doc
+renderRefWithUnwrapResult datatype@(OCamlDatatype typeRef name _) = do
+  if isTypeParameterRef datatype
+  then
+    pure . parens $ "fun a -> unwrapResult (decode" <> (stext . textUppercaseFirst $ name) <+> "a)"
+  else do
+    mOCamlTypeMetaData <- asks topLevelOCamlTypeMetaData
+    case mOCamlTypeMetaData of
+      Nothing -> fail $ "OCaml.BuckleScript.Decode.renderRefWithUnwrapResult mOCamlTypeMetaData is Nothing:\n\n" ++ (show datatype)
+      Just decOCamlTypeMetaData -> do
+        ds <- asks (dependencies . userOptions)
+        case Map.lookup typeRef ds of
+          Just parOCamlTypeMetaData -> do
+            let prefix = stext $ mkModulePrefix decOCamlTypeMetaData parOCamlTypeMetaData
+            pure . parens $ "fun a -> unwrapResult (" <> prefix <> "decode" <> (stext . textUppercaseFirst $ name) <+> "a)"
+          Nothing -> fail ("OCaml.BuckleScript.Decode.renderRefWithUnwrapResult expected to find dependency:\n\n" ++ show typeRef ++ "\n\nin\n\n" ++ show ds)
+renderRefWithUnwrapResult ref = renderRef ref
+
     
 -- | "<name>" -> decode <name>
 renderSumCondition :: T.Text -> Doc -> Reader TypeMetaData Doc
@@ -428,7 +430,7 @@
       renderedVal <- render x'
       renderedInternal <- mk name (i+1) xs
       let iDoc = (stext . T.pack . show $ i)
-      pure $ indent 1 $ "(match Aeson.Decode." <> renderedVal <+> ("v." <> parens iDoc) <+> "with"
+      pure $ indent 1 $ "(match" <+> (if oCamlValueIsFloat x' then "" else "Aeson.Decode.") <> renderedVal <+> ("v." <> parens iDoc) <+> "with"
         <$$>
           indent 1
             ("| v" <> iDoc <+> "->" <$$> (indent 2 renderedInternal)
diff --git a/src/OCaml/BuckleScript/Encode.hs b/src/OCaml/BuckleScript/Encode.hs
--- a/src/OCaml/BuckleScript/Encode.hs
+++ b/src/OCaml/BuckleScript/Encode.hs
@@ -13,7 +13,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-module OCaml.BuckleScript.Encode 
+module OCaml.BuckleScript.Encode
   ( toOCamlEncoderSourceWith
   , toOCamlEncoderInterfaceWith
   ) where
@@ -339,34 +339,34 @@
 
   renderRef (OList datatype) = do
     dd <- renderRef datatype
-    return . parens $ "Aeson.Encode.list" <+> dd
+    pure . parens $ "Aeson.Encode.list" <+> dd
 
   renderRef (OOption datatype) = do
     dd <- renderRef datatype
-    return $ "Aeson.Encode.optional" <+> dd
+    pure . parens $ "Aeson.Encode.optional" <+> dd
 
   renderRef (OEither t0 t1) = do
     dt0 <- renderRef t0
     dt1 <- renderRef t1
-    return $ "Aeson.Encode.either" <+> dt0 <+> dt1
+    pure . parens $ "Aeson.Encode.either" <+> dt0 <+> dt1
 
   renderRef (OTuple2 t0 t1) = do
     dt0 <- renderRef t0
     dt1 <- renderRef t1
-    return $ "Aeson.Encode.pair" <+> dt0 <+> dt1
+    pure . parens $ "Aeson.Encode.pair" <+> dt0 <+> dt1
 
   renderRef (OTuple3 t0 t1 t2) = do
     dt0 <- renderRef t0
     dt1 <- renderRef t1
     dt2 <- renderRef t2
-    return $ "Aeson.Encode.tuple3" <+> dt0 <+> dt1 <+> dt2
+    pure . parens $ "Aeson.Encode.tuple3" <+> dt0 <+> dt1 <+> dt2
 
   renderRef (OTuple4 t0 t1 t2 t3) = do
     dt0 <- renderRef t0
     dt1 <- renderRef t1
     dt2 <- renderRef t2
     dt3 <- renderRef t3
-    return $ "Aeson.Encode.tuple4" <+> dt0 <+> dt1 <+> dt2 <+> dt3
+    pure . parens $ "Aeson.Encode.tuple4" <+> dt0 <+> dt1 <+> dt2 <+> dt3
     
   renderRef (OTuple5 t0 t1 t2 t3 t4) = do
     dt0 <- renderRef t0
@@ -374,7 +374,7 @@
     dt2 <- renderRef t2
     dt3 <- renderRef t3
     dt4 <- renderRef t4
-    return $ "Aeson.Encode.tuple5" <+> dt0 <+> dt1 <+> dt2 <+> dt3 <+> dt4
+    pure . parens $ "Aeson.Encode.tuple5" <+> dt0 <+> dt1 <+> dt2 <+> dt3 <+> dt4
 
   renderRef (OTuple6 t0 t1 t2 t3 t4 t5) = do
     dt0 <- renderRef t0
@@ -383,7 +383,7 @@
     dt3 <- renderRef t3
     dt4 <- renderRef t4
     dt5 <- renderRef t5
-    return $ "Aeson.Encode.tuple6" <+> dt0 <+> dt1 <+> dt2 <+> dt3 <+> dt4 <+> dt5
+    pure . parens $ "Aeson.Encode.tuple6" <+> dt0 <+> dt1 <+> dt2 <+> dt3 <+> dt4 <+> dt5
 
 -- | Variable names for the members of constructors
 --   Used in pattern matches
diff --git a/src/OCaml/BuckleScript/Internal/Module.hs b/src/OCaml/BuckleScript/Internal/Module.hs
--- a/src/OCaml/BuckleScript/Internal/Module.hs
+++ b/src/OCaml/BuckleScript/Internal/Module.hs
@@ -65,7 +65,7 @@
 import OCaml.BuckleScript.Types
 
 -- servant
-import Servant.API ((:>))
+import Servant.API ((:>), (:<|>))
 
 -- template-haskell
 import Language.Haskell.TH
@@ -106,11 +106,8 @@
     { eocDeclaration :: ByteString
     , eocInterface   :: Maybe ByteString
     , eocSpec        :: Maybe ByteString
-    }
-
-
-
-
+    } deriving (Show)
+    
 
 -- ==============================================
 -- Type Level Functions
@@ -215,6 +212,9 @@
 -- | Help function for HasEmbeddedFile.
 class HasEmbeddedFile' api where
   mkFiles' :: Bool -> Bool -> Proxy api -> Q [Exp]
+
+instance (HasEmbeddedFile' a, HasEmbeddedFile' b) => HasEmbeddedFile' (a :<|> b) where
+  mkFiles' includeInterface includeSpec Proxy = (<>) <$> mkFiles' includeInterface includeSpec (Proxy :: Proxy a) <*> mkFiles' includeInterface includeSpec (Proxy :: Proxy b)
 
 instance (HasEmbeddedFile' a, HasEmbeddedFile' b) => HasEmbeddedFile' (a :> b) where
   mkFiles' includeInterface includeSpec Proxy = (<>) <$> mkFiles' includeInterface includeSpec (Proxy :: Proxy a) <*> mkFiles' includeInterface includeSpec (Proxy :: Proxy b)
diff --git a/src/OCaml/BuckleScript/Types.hs b/src/OCaml/BuckleScript/Types.hs
--- a/src/OCaml/BuckleScript/Types.hs
+++ b/src/OCaml/BuckleScript/Types.hs
@@ -50,6 +50,7 @@
   , getTypeParameters
   , isTypeParameterRef
   , mkModulePrefix
+  , oCamlValueIsFloat
   ) where
 
 -- base
@@ -562,3 +563,9 @@
 zipWithRightRemainder [] bs = ([], bs)
 zipWithRightRemainder _ab [] = ([], [])
 zipWithRightRemainder (a:as) (b:bs) = ([(a,b)], []) <> zipWithRightRemainder as bs
+
+-- | BuckleScript has a 'float' type that conflicts when you do 'open Aeson.Decode'
+--   float must be appended with 'Aeson.Decode'. 
+oCamlValueIsFloat :: OCamlValue -> Bool
+oCamlValueIsFloat (OCamlPrimitiveRef OFloat) = True
+oCamlValueIsFloat _ = False
diff --git a/test/Dependency.hs b/test/Dependency.hs
--- a/test/Dependency.hs
+++ b/test/Dependency.hs
@@ -5,48 +5,22 @@
 {-# LANGUAGE TypeOperators #-}
 
 module Dependency where
-
 -- base
-import Data.Monoid ((<>))
 import GHC.Generics (Generic)
-
 -- aeson
 import Data.Aeson (FromJSON, ToJSON)
-
 -- containers
 import Data.Map as Map
-
 -- hspec
 import Test.Hspec
-
--- hspec-aeson-golden
-import Test.Aeson.Internal.ADT.GoldenSpecs
-
 -- QuickCheck
 import Test.QuickCheck
-
 -- quickcheck-arbitrary-adt
 import Test.QuickCheck.Arbitrary.ADT
-
--- text
-import Data.Text (Text)
-
--- time
-import Data.Time
-import Data.Time.Clock.POSIX
-
 -- ocaml-export
 import OCaml.Export
 import Product (ProductPackage, Person)
-import Util
 
---mkGolden :: forall a. (ToADTArbitrary a, ToJSON a) => Proxy a -> IO ()
---mkGolden Proxy = mkGoldenFileForType 10 (Proxy :: Proxy a) "test/interface/golden/golden/dependency"
-
---mkGoldenFiles :: IO ()
---mkGoldenFiles = do
---  mkGolden (Proxy :: Proxy Class)
-
 type DependencyPackage
   =    OCamlPackage "dependency" '[ProductPackage] :> (
        OCamlModule '["Class"] :> Class)
@@ -58,17 +32,7 @@
 type SchoolPackage
   =    OCamlPackage "school" '[DependencyPackage] :> (
        OCamlModule '["School"] :> School)
-{-
-data Person = Person
-  { id :: Int
-  , name :: Maybe String
-  } deriving (Show, Eq, Generic, OCamlType, FromJSON, ToJSON)
 
-instance Arbitrary Person where
-  arbitrary = Person <$> arbitrary <*> arbitrary
-
-instance ToADTArbitrary Person
--}
 data Class = Class
   { subject   :: String
   , students  :: [Person] -- from another package
@@ -139,7 +103,6 @@
 
 type SubsPackage = OCamlPackage "subs" NoDependency :>
   (OCamlModule '["AtoE"] :> A :> (OCamlSubModule "One" :> B :> (OCamlSubModule "Two" :> C) :> D) :> E)
---   (OCamlModule '["AtoE"] :> OCamlSubModule '["One"] :> A)
 
 spec :: Spec
 spec = do
diff --git a/test/File.hs b/test/File.hs
--- a/test/File.hs
+++ b/test/File.hs
@@ -7,26 +7,15 @@
 {-# LANGUAGE TypeOperators #-}
 
 module File where
-
 -- base
 import Data.Proxy
 import GHC.Generics (Generic)
-
 -- aeson
 import Data.Aeson
-
--- hspec
-import Test.Hspec
-
--- hspec-golden-aeson
-import Test.Aeson.Internal.ADT.GoldenSpecs
-
 -- QuickCheck
 import Test.QuickCheck
-
 -- quickcheck-arbitrary-adt
 import Test.QuickCheck.Arbitrary.ADT
-
 -- ocaml-export
 import OCaml.Export
 
@@ -89,7 +78,7 @@
 instance (Arbitrary a, Arbitrary b) => Arbitrary (Wrapper a b) where
   arbitrary = Wrapper <$> arbitrary <*> arbitrary <*> arbitrary
 
-instance (ToADTArbitrary a, ToADTArbitrary b) => ToADTArbitrary (Wrapper a b)
+instance (Arbitrary a, ToADTArbitrary a, Arbitrary b, ToADTArbitrary b) => ToADTArbitrary (Wrapper a b)
 
 instance OCamlType (Wrapper TypeParameterRef0 TypeParameterRef1) where
   toOCamlType _ = typeableToOCamlType (Proxy :: Proxy (Wrapper TypeParameterRef0 TypeParameterRef1))
diff --git a/test/FileApp.hs b/test/FileApp.hs
--- a/test/FileApp.hs
+++ b/test/FileApp.hs
@@ -1,18 +1,13 @@
 {-# LANGUAGE DataKinds #-}
-
 {-# LANGUAGE TemplateHaskell #-}
 
 module FileApp where
-
 -- containers
 import qualified Data.Map as Map
-
 -- hspec
 import Test.Hspec
-
 -- servant-server
 import Servant
-
 -- ocaml-export
 import OCaml.Export
 import File
@@ -23,6 +18,7 @@
 fileMap :: Map.Map String EmbeddedOCamlFiles
 fileMap = Map.fromList $(mkFiles True False (Proxy :: Proxy FilePackage))
 
+compareInterfaceFiles :: FilePath -> SpecWith ()
 compareInterfaceFiles = compareFiles "test/interface" "file" True
 
 spec :: Spec
diff --git a/test/Product.hs b/test/Product.hs
--- a/test/Product.hs
+++ b/test/Product.hs
@@ -1,42 +1,25 @@
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-
-{-# LANGUAGE FlexibleInstances #-}
-
-
--- for OCaml Module
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE TypeOperators #-}
-
 {-# LANGUAGE TemplateHaskell #-}
-
+{-# LANGUAGE TypeOperators #-}
 
 module Product where
-
 -- base
-import Data.Monoid ((<>))
 import GHC.Generics
--- text
-import Data.Text (Text)
 -- time
 import Data.Time
-import Data.Time.Clock.POSIX
--- containers
-import qualified Data.Map as Map
-
 -- aeson
 import Data.Aeson (FromJSON, ToJSON)
-
 -- hspec
-import Test.Hspec
+import Test.Hspec (SpecWith)
 -- QuickCheck
 import Test.QuickCheck
 -- quickcheck-arbitrary-adt
 import Test.QuickCheck.Arbitrary.ADT
--- hspec-golden-aeson
-import Test.Aeson.Internal.ADT.GoldenSpecs
 -- ocaml-export
 import OCaml.Export hiding (mkGoldenFiles)
 import Util
@@ -52,59 +35,15 @@
   :<|> OCamlModule '["TwoTypeParameters"] :> TwoTypeParameters TypeParameterRef0 TypeParameterRef1
   :<|> OCamlModule '["ThreeTypeParameters"] :> Three TypeParameterRef0 TypeParameterRef1 TypeParameterRef2
   :<|> OCamlModule '["SubTypeParameter"] :> SubTypeParameter TypeParameterRef0 TypeParameterRef1 TypeParameterRef2
-  :<|> OCamlModule '["UnnamedProduct"] :> UnnamedProduct)
-
-mkGolden :: forall a. (ToADTArbitrary a, ToJSON a) => Proxy a -> IO ()
-mkGolden Proxy = mkGoldenFileForType 10 (Proxy :: Proxy a) "test/interface/golden/golden/product"
+  :<|> OCamlModule '["UnnamedProduct"] :> UnnamedProduct
+  :<|> OCamlModule '["ComplexProduct"] :> OCamlTypeInFile Simple "test/ocaml/Simple" :> ComplexProduct)
 
-mkGoldenFiles :: IO ()
-mkGoldenFiles = do
-  mkGolden (Proxy :: Proxy SimpleChoice)
-  mkGolden (Proxy :: Proxy Person)
-  mkGolden (Proxy :: Proxy Company)
-  mkGolden (Proxy :: Proxy Suit)
-  mkGolden (Proxy :: Proxy Card)
-  mkGolden (Proxy :: Proxy Company2)
-  mkGolden (Proxy :: Proxy (OneTypeParameter TypeParameterRef0))
-  mkGolden (Proxy :: Proxy (TwoTypeParameters TypeParameterRef0 TypeParameterRef1))
-  mkGolden (Proxy :: Proxy (Three TypeParameterRef0 TypeParameterRef1 TypeParameterRef2))
-  mkGolden (Proxy :: Proxy (SubTypeParameter TypeParameterRef0 TypeParameterRef1 TypeParameterRef2))
-  mkGolden (Proxy :: Proxy UnnamedProduct)
-  
+compareInterfaceFiles :: FilePath -> SpecWith ()
 compareInterfaceFiles = compareFiles "test/interface" "product" True
 
+compareNoInterfaceFiles :: FilePath -> SpecWith ()
 compareNoInterfaceFiles = compareFiles "test/nointerface" "product" False
 
-
-spec :: Spec
-spec = do
-  runIO $ mkGoldenFiles
-  
-  let dir = "test/interface/temp"
-  runIO $ mkPackage (Proxy :: Proxy ProductPackage) (PackageOptions dir "product" Map.empty True $ Just $ SpecOptions "__tests__/product" "golden/product" "http://localhost:8081")
-  
-  describe "OCaml Declaration with Interface: Product Types" $ do
-    compareInterfaceFiles "Person"
-    compareInterfaceFiles "Company"
-    compareInterfaceFiles "Card"
-    compareInterfaceFiles "OneTypeParameter"
-    compareInterfaceFiles "TwoTypeParameters"
-    compareInterfaceFiles "ThreeTypeParameters"
-    compareInterfaceFiles "SubTypeParameter"
-    compareInterfaceFiles "UnnamedProduct"
-    
-  let dir2 = "test/nointerface/temp"
-  runIO $ mkPackage (Proxy :: Proxy ProductPackage) (PackageOptions dir2 "product" Map.empty False Nothing)
-
-  describe "OCaml Declaration without Interface: Product Types" $ do
-    compareNoInterfaceFiles "Person"
-    compareNoInterfaceFiles "Company"
-    compareNoInterfaceFiles "Card"
-    compareNoInterfaceFiles "OneTypeParameter"
-    compareNoInterfaceFiles "TwoTypeParameters"
-    compareNoInterfaceFiles "ThreeTypeParameters"
-    compareNoInterfaceFiles "SubTypeParameter"
-
 data SimpleChoice =
   SimpleChoice
     { choice :: Either String Int
@@ -231,3 +170,37 @@
   arbitrary = UnnamedProduct <$> arbitrary <*> arbitrary
 
 instance ToADTArbitrary UnnamedProduct
+
+data Simple =
+  Simple
+    { sa :: Int
+    , sb :: String
+    } deriving (Eq,Show,Generic,FromJSON,ToJSON)
+
+instance OCamlType Simple where
+  toOCamlType _ = typeableToOCamlType (Proxy :: Proxy Simple)
+
+instance ToADTArbitrary Simple
+instance Arbitrary Simple where
+  arbitrary = Simple <$> arbitrary <*> arbitrary
+
+data ComplexProduct =
+  ComplexProduct
+    { cp0 :: Either Person [Int]
+    , cp1 :: [(Int, Either String Double)]
+    , cp2 :: [[Int]]
+    , cp3 :: Maybe [Int]
+    , cp4 :: Either Simple Int
+    } deriving (Eq,Show,Generic,OCamlType,FromJSON,ToJSON)
+
+instance Arbitrary ComplexProduct where
+  arbitrary = do
+    k0 <- choose (1,3)
+    v0 <- vector k0
+
+    k1 <- choose (1,3)
+    v1 <- vector k1
+    
+    ComplexProduct <$> arbitrary <*> pure v0 <*> pure v1 <*> arbitrary <*> arbitrary
+
+instance ToADTArbitrary ComplexProduct
diff --git a/test/ProductApp.hs b/test/ProductApp.hs
--- a/test/ProductApp.hs
+++ b/test/ProductApp.hs
@@ -4,5 +4,42 @@
 
 import OCaml.Export
 import Product
+-- containers
+import qualified Data.Map as Map
+-- hspec
+import Test.Hspec
 
+fileMap :: Map.Map String EmbeddedOCamlFiles
+fileMap = Map.fromList $(mkFiles True False (Proxy :: Proxy ProductPackage))
+
 $(mkOCamlSpecServer "ProductPackage" (Proxy :: Proxy ProductPackage))
+
+spec :: Spec
+spec = do
+  runIO $ mkGoldenFiles (Proxy :: Proxy ProductPackage) 10 "test/interface/golden/golden/product"  
+
+  let dir = "test/interface/temp"
+  runIO $ mkPackage (Proxy :: Proxy ProductPackage) (PackageOptions dir "product" fileMap True $ Just $ SpecOptions "__tests__/product" "golden/product" "http://localhost:8081")
+  
+  describe "OCaml Declaration with Interface: Product Types" $ do
+    compareInterfaceFiles "Person"
+    compareInterfaceFiles "Company"
+    compareInterfaceFiles "Card"
+    compareInterfaceFiles "OneTypeParameter"
+    compareInterfaceFiles "TwoTypeParameters"
+    compareInterfaceFiles "ThreeTypeParameters"
+    compareInterfaceFiles "SubTypeParameter"
+    compareInterfaceFiles "UnnamedProduct"
+    compareInterfaceFiles "ComplexProduct"
+    
+  let dir2 = "test/nointerface/temp"
+  runIO $ mkPackage (Proxy :: Proxy ProductPackage) (PackageOptions dir2 "product" fileMap False Nothing)
+
+  describe "OCaml Declaration without Interface: Product Types" $ do
+    compareNoInterfaceFiles "Person"
+    compareNoInterfaceFiles "Company"
+    compareNoInterfaceFiles "Card"
+    compareNoInterfaceFiles "OneTypeParameter"
+    compareNoInterfaceFiles "TwoTypeParameters"
+    compareNoInterfaceFiles "ThreeTypeParameters"
+    compareNoInterfaceFiles "SubTypeParameter"
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -6,76 +6,27 @@
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TypeOperators #-}
 
-
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveFunctor      #-}
-{-# LANGUAGE DeriveFoldable     #-}
-{-# LANGUAGE DeriveTraversable  #-}
-{-# LANGUAGE FlexibleInstances  #-}
-{-# LANGUAGE KindSignatures  #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE PolyKinds  #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UndecidableInstances #-}
-
-import Network.Wai.Handler.Warp
-import Network.Wai
-import Network.Wai.Middleware.RequestLogger (logStdout)
-import System.Process
-
 -- base
 import Control.Concurrent (forkIO)
 import Data.Monoid ((<>))
-import GHC.TypeLits
-
--- ByteString
-import Data.ByteString (unpack)
-
 -- hspec
-import           Test.Hspec
-
--- hspec-aeson-golden
-import Test.Aeson.GenericSpecs
-
-
--- servant
-import Servant
-
--- servant-server
-import Servant.API
-
--- text
-import Data.Text (Text)
-
+import Test.Hspec
 -- ocaml-export
-import OCaml.Export
 import qualified Dependency as D
-import qualified File as File
 import qualified FileApp as File
-import qualified Options as Options
 import qualified Product as Product
-import ProductApp
+import qualified ProductApp as Product
 import qualified Sum as Sum
 import SumApp
-
-logAllMiddleware :: Application -> Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
-logAllMiddleware app req respond = do
-    d <- requestBody req
-    print $ requestHeaders req
-    print $ d
-    app req respond
-
--- npm start --prefix path/to/your/app
+import OCaml.Export
+-- warp
+import Network.Wai.Handler.Warp
 
 main :: IO ()
 main = do
   hspec Product.spec
   hspec Sum.spec
   hspec File.spec
---  hspec Options.spec
   hspec D.spec
 
   hspec $
@@ -84,14 +35,8 @@
         (mkOCamlTypeMetaData (Proxy :: Proxy Product.ProductPackage)) <> (mkOCamlTypeMetaData (Proxy :: Proxy D.DependencyPackageWithoutProduct))
           `shouldBe` mkOCamlTypeMetaData (Proxy :: Proxy D.DependencyPackage)
 
---  print $ ocamlPackageTypeCount (Proxy :: Proxy Product.ProductPackage)
-
---  print $ mkOCamlTypeMetaData (Proxy :: Proxy Product.ProductPackage)
   print $ mkOCamlTypeMetaData (Proxy :: Proxy D.SubsPackage)
   
-  _ <- forkIO $ run 8081 productPackageApp
+  _ <- forkIO $ run 8081 Product.productPackageApp
   _ <- forkIO $ run 8082 sumPackageApp
   run 8083 File.filePackageApp
-
--- curl -i -d '"hi"' -H 'Content-type: application/json' -X POST http://localhost:8081/x/y
- 
diff --git a/test/Sum.hs b/test/Sum.hs
--- a/test/Sum.hs
+++ b/test/Sum.hs
@@ -1,12 +1,10 @@
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE OverloadedStrings #-}
-
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE TypeOperators #-}
-
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
 
 module Sum where
 
@@ -50,8 +48,10 @@
   :<|> OCamlModule '["Result"] :> Result TypeParameterRef0 TypeParameterRef1
   :<|> OCamlModule '["NewType"] :> NewType)
 
+compareInterfaceFiles :: FilePath -> SpecWith ()
 compareInterfaceFiles = compareFiles "test/interface" "sum" True
 
+compareNoInterfaceFiles :: FilePath -> SpecWith ()
 compareNoInterfaceFiles = compareFiles "test/nointerface" "sum" False
 
 mkGolden :: forall a. (ToADTArbitrary a, ToJSON a) => Proxy a -> IO ()
diff --git a/test/Util.hs b/test/Util.hs
--- a/test/Util.hs
+++ b/test/Util.hs
@@ -1,31 +1,18 @@
-module Util where
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 
+module Util where
 -- base
 import Data.Monoid ((<>))
 import Data.Time
-
 -- text
 import qualified Data.Text.IO as T
-
--- ocaml-export
-import OCaml.Export hiding (Options)
-
-
-import System.Directory (doesFileExist)
-
 -- filepath
 import System.FilePath.Posix ((</>))
-
 -- hspec
 import Test.Hspec
-
 -- QuickCheck
 import Test.QuickCheck
 
--- quickcheck-arbitrary-adt
-import Test.QuickCheck.Arbitrary.ADT
-import Test.Aeson.Internal.ADT.GoldenSpecs
-
 instance Arbitrary UTCTime where
   arbitrary =
     UTCTime <$> (ModifiedJulianDay <$> (2000 +) <$> arbitrary)
@@ -38,7 +25,6 @@
 adtToPath :: ADT -> FilePath
 adtToPath Options = "options"
 
-
 compareFiles :: FilePath -> FilePath -> Bool -> FilePath -> SpecWith ()
 compareFiles rootDir categoryDir compareInterfaceAndSpecFiles typeName =
   it typeName $ do
@@ -60,32 +46,3 @@
     goldenPath = rootDir </> "golden" </> categoryDir
     testSpecPath   = rootDir </> "temp" </> "__tests__" </> categoryDir
     goldenSpecPath = rootDir </> "golden" </> "__tests__" </> categoryDir
-
-{-
-testOCamlTypeWithInterface :: ADT -> FilePath -> OCamlInterface -> SpecWith ()
-testOCamlTypeWithInterface adt typeName ocamlFile =
-  it typeName $ do
-    createOCamlFileWithInterface testPath specPath typeName ocamlFile
-    automated   <- T.readFile (testPath   <> "/" <> typeName <> ".ml")
-    handWritten <- T.readFile (goldenPath <> "/" <> typeName <> ".ml")
-
-    automated2   <- T.readFile (testPath   <> "/" <> typeName <> ".mli")
-    handWritten2 <- T.readFile (goldenPath <> "/" <> typeName <> ".mli")
-
-    automated `shouldBe` handWritten
-    automated2 `shouldBe` handWritten2
-
-    fe <- doesFileExist (specGoldenPath <> "/" <> typeName <> "_spec.ml")
-    if fe
-      then do
-        automated3   <- T.readFile (specPath <> "/" <> typeName <> "_spec.ml")
-        handWritten3 <- T.readFile (specGoldenPath <> "/" <> typeName <> "_spec.ml")
-        automated3 `shouldBe` handWritten3
-      else pure ()
-  where
-    adtPath    = adtToPath adt
-    testPath   = "test/interface/temp/" <> adtPath
-    goldenPath = "test/interface/golden/" <> adtPath
-    specPath  = "test/interface/temp/__tests__/" <> adtPath
-    specGoldenPath  = "test/interface/golden/__tests__/" <> adtPath
--}
