content: module Interpreter.EvalSpec (spec) where
  
  import Puppet.Interpreter
  import Puppet.Parser.Internal
  import Puppet.Runner
  import Test.Hspec
  import Text.Megaparsec (eof, errorBundlePretty, parse)
  import XPrelude
  
  evaluations =
    [ "4 + 2 == 6",
      "[1,2][1] == 2",
      "[1,[1,2]][1][0] == 1",
      "[1,2,3] + [4,5,6] == [1,2,3,4,5,6]",
      "{a => 1} + {b => 2} == {a=>1, b=>2 }",
      "[1,2,3] << 10 == [1,2,3,10]",
      "[1,2,3] << [4,5] == [1,2,3,[4,5]]",
      "4 / 2.0 == 2",
      "$kernel == 'Linux'",
      "$facts['os']['architecture'] == 'amd64'",
      -- string interpolation
      "\"$kernel\" == 'Linux'",
      "\"${kernel} box\" == 'Linux box'",
      "\"${os['architecture']}\" == 'amd64'",
      "\"${os['release']['major']}\" == '7'",
      "\"${facts['kernel']}\" == 'Linux'",
      "\"${facts['os']['architecture']}\" == 'amd64'",
      --
      "$settings::confdir == '/etc/puppet'",
      "regsubst('127', '([0-9]+)', '<\\1>', 'G') == '<127>'",
      "regsubst(['1','2','3'], '([0-9]+)', '<\\1>', 'G') == ['<1>','<2>','<3>']",
      "versioncmp('2.1','2.2') == -1",
      "inline_template('a','b') == 'ab'"
    ]
  
  testEvaluation t =
    let item = it ("should evaluate " <> t)
     in case check (toS t) of
          Left ctx -> context ctx $ item False
          Right b -> item b
  
  check :: Text -> Either String Bool
  check t =
    case parse (expression <* eof) "dummy" t of
      Left err -> Left $ "Parsing error. Are you sure the input is correct ?\n" <> errorBundlePretty err
      Right e -> case dummyEval (resolveExpression e) of
        Right (PBoolean True) -> Right True
        _ -> Right False
  
  spec = do
    describe "Evaluation of expressions" $ mapM_ testEvaluation evaluations
  