packages feed

language-puppet-1.5.1: tests/Parser/ExprSpec.hs

{-# LANGUAGE OverloadedLists #-}

module Parser.ExprSpec (spec) where

import Puppet.Parser
import Puppet.Parser.Internal
import Test.Hspec
import Test.Hspec.Megaparsec
import Text.Megaparsec
import XPrelude

expressions :: [(Text, Expression)]
expressions =
  [ ("5 + 3 * 2", 5 + 3 * 2),
    ("5+2 == 7", Equal (5 + 2) 7),
    ("include(foo::bar)", Terminal (UFunctionCall "include" ["foo::bar"])),
    ("fail(('foo'))", Terminal (UFunctionCall "fail" ["foo"])),
    ("test(foo,bar)", Terminal (UFunctionCall "test" ["foo", "bar"])),
    ("extlib::test()", Terminal (UFunctionCall "extlib::test" [])),
    ("extlib::test(fail('foo'))", Terminal (UFunctionCall "extlib::test" [Terminal (UFunctionCall "fail" [Terminal (UString "foo")])])),
    ("test(extlib::test())", Terminal (UFunctionCall "test" [Terminal (UFunctionCall "extlib::test" [])])),
    ("test ( foo , bar )", Terminal (UFunctionCall "test" ["foo", "bar"])),
    ( "$y ? {\
      \ undef   => 'undef',\
      \ default => 'default',\
      \ }",
      ConditionalValue
        (Terminal (UVariableReference "y"))
        [ SelectorValue UUndef :!: Terminal (UString "undef"),
          SelectorDefault :!: Terminal (UString "default")
        ]
    ),
    ("$x", Terminal (UVariableReference "x")),
    ("x($y)", Terminal (UFunctionCall "x" [Terminal (UVariableReference "y")])),
    ("\"$\"", Terminal (UInterpolable [Terminal (UString "$")])),
    ("\"${x}\"", Terminal (UInterpolable [Terminal (UVariableReference "x")])),
    ("$x[ 3 ]", Lookup (Terminal (UVariableReference "x")) (Terminal (UNumber 3))),
    ("\"${ os[ 'architecture' ]}\"", Terminal (UInterpolable [Lookup (Terminal (UVariableReference "os")) (Terminal (UString "architecture"))])),
    ("\"${facts['os']['architecture']}\"", Terminal (UInterpolable [Lookup (Lookup (Terminal (UVariableReference "facts")) (Terminal (UString "os"))) (Terminal (UString "architecture"))])),
    ("\"${x[$y]}\"", Terminal (UInterpolable [Lookup (Terminal (UVariableReference "x")) (Terminal (UVariableReference "y"))])),
    ("\"${x($y)}\"", Terminal (UInterpolable [Terminal (UFunctionCall "x" [Terminal (UVariableReference "y")])])),
    ( "\"${x($y)}$'\"",
      Terminal
        ( UInterpolable
            [ Terminal (UFunctionCall "x" [Terminal (UVariableReference "y")]),
              Terminal (UString "$"),
              Terminal (UString "'")
            ]
        )
    )
  ]

invalid :: [Text]
invalid =
  [ "$os['name]",
    -- pending
    -- , "$os ['name']"
    -- interpolation
    "\"${os['name]}\"",
    "\"${os[name}\"",
    "\"${os[name]\""
  ]

testExpression (t, e) = it ("should parse " <> toS t) $ parse (expression <* eof) "" t `shouldParse` e

testInvalid s = it ("rejects " <> toS s) $ shouldFailOn (parse (expression <* eof) "") s

spec = do
  describe "Expression parser" $ mapM_ testExpression expressions
  describe "Invalid expression" $ mapM_ testInvalid invalid