content: {-# LANGUAGE OverloadedStrings #-}
  module Main (main) where
  
  import LispVal ( LispVal )
  import Eval
      ( basicEnv,
        getFileContents,
        runASTinEnv,
        safeExec,
        textToEvalForm )
  
  import qualified Data.Text as T
  
  import Test.Tasty ( defaultMain, testGroup, TestName, TestTree )
  import Test.Tasty.Golden ( goldenVsString )
  import qualified Data.ByteString.Lazy.Char8 as C
  import Data.Functor ((<&>))
  
  main :: IO ()
  main = defaultMain tests
  
  tests :: TestTree
  tests = testGroup "Golden Tests"
    [   tastyGoldenRun "add"           "test/add.scm"              "test/ans/add.txt"
      , tastyGoldenRun "if/then"       "test/if_alt.scm"           "test/ans/if_alt.txt"
      , tastyGoldenRun "let"           "test/let.scm"              "test/ans/let.txt"
      , tastyGoldenRun "lambda let"    "test/test_let.scm"         "test/ans/test_let.txt"
      , tastyGoldenRun "eval bool"     "test/eval_boolean.scm"     "test/ans/eval_boolean.txt"
      , tastyGoldenRun "eval bool ops" "test/eval_boolean_ops.scm" "test/ans/eval_boolean_ops.txt"
      , tastyGoldenRun "eval lambda"    "test/eval_lambda.scm"     "test/ans/eval_lambda.txt"
      , tastyGoldenRun "quote"          "test/test_quote.scm"      "test/ans/test_quote.txt"
      , tastyGoldenRun "car"            "test/test_car.scm"        "test/ans/test_car.txt"
      , tastyGoldenRun "cdr"            "test/test_cdr.scm"        "test/ans/test_cdr.txt"
      , tastyGoldenRun "cadadr"         "test/test_cadadr.scm"     "test/ans/test_cadadr.txt"
      , tastyGoldenRun "greater than"   "test/test_gt.scm"         "test/ans/test_gt.txt"
      , tastyGoldenRun "lexical scope 1" "test/test_scope1.scm"    "test/ans/test_scope1.txt"
      , tastyGoldenRun "lexical scope 2" "test/test_scope2.scm"    "test/ans/test_scope2.txt"
      , tastyGoldenFail "issue #23"      "test/test_scope3.scm"    "test/ans/test_scope3.txt"
      , tastyGoldenRun "issue #25"       "test/test_scope4.scm"    "test/ans/test_scope4.txt"
      , tastyGoldenRun "Recursion 1"    "test/test_fix.scm"        "test/ans/test_fix.txt"
      , tastyGoldenRun "Recursion 2"    "test/test_fix2.scm"       "test/ans/test_fix2.txt"
      , tastyGoldenRun "Mutual Recursion 2" "test/test_mutual_rec.scm" "test/ans/test_mutual_rec.txt"
      , tastyGoldenRun "fn args"         "test/test_args.scm"      "test/ans/test_args.txt"
      , tastyGoldenRun "fold"            "test/test_fold.scm"      "test/ans/test_fold.txt"
    ]
  
  tastyGoldenRun :: TestName -> T.Text -> FilePath -> TestTree
  tastyGoldenRun testName testFile correct =
    goldenVsString testName correct $
      evalTextTest "lib/stdlib.scm" testFile <&> C.pack . show
  
  tastyGoldenFail :: TestName -> T.Text -> FilePath -> TestTree
  tastyGoldenFail testName testFile correct =
    goldenVsString testName correct $
      safeExec (evalTextTest "lib/stdlib.scm" testFile) <&>
        either C.pack (C.pack . show)
  
  evalTextTest :: T.Text -> T.Text -> IO LispVal --REPL
  evalTextTest stdlib file= do
    stdlib' <- getFileContents $ T.unpack stdlib
    f <- getFileContents $ T.unpack file
    runASTinEnv basicEnv $ textToEvalForm stdlib'  f
  