dump-0.2.7: spec/Spec.hs
import Test.Hspec
import Test.QuickCheck
import Text.InterpolatedString.Perl6
import Data.List (isPrefixOf)
import Debug.Dump
import Internal.Parser
import Internal.Utils
main = spec
spec = hspec $ do
describe "wrapInParens" $ do
it "should work" $ do
wrapInParens "a" `shouldBe` "(a)"
wrapInParens "" `shouldBe` "()"
describe "parseLeaf" $ do
let p = parseLeaf (\xs->("",xs)) '"'
it "knows to stop on regular quote" $ do
p [q|a" |] `shouldBe` ([q|a"|], " ")
it "knows not to terminate after escaped quote" $ do
p [q|a\"" |] `shouldBe` ([q|a\""|], " ")
it "does not trip up on escape characters" $ do
p [q|a\\ |] `shouldBe` ([q|a\\ |], "")
it "does not trip up on escape character at the end" $ do
p [q|a\\|] `shouldBe` ([q|a\\|], "")
describe "parseExpr" $ do
let p = parseExpr .> fst
it "handles flat" $ do
p "asd" `shouldBe` "asd"
p "asd,asd" `shouldBe` "asd"
p "asd,a,sd" `shouldBe` "asd"
it "handles parens" $ do
p "(a,b)" `shouldBe` "(a,b)"
p "(a,b) (a,b)" `shouldBe` "(a,b) (a,b)"
p "(a,b), c" `shouldBe` "(a,b)"
p "((a), b), c" `shouldBe` "((a), b)"
p "((a,b),(a,b)), a" `shouldBe` "((a,b),(a,b))"
it "handles char literals" $ do
p "','" `shouldBe` "','"
p "',', a" `shouldBe` "','"
it "handles string literals" $ do
p [q|","|] `shouldBe` [q|","|]
p [q|",", a|] `shouldBe` [q|","|]
it "handles list literals" $ do
p "[a,b]" `shouldBe` "[a,b]"
it "treats string literals as leaves" $ do
p [q|"(", a|] `shouldBe` [q|"("|]
it "support escaping in leaves" $ do
p [q|"\"", a|] `shouldBe` [q|"\""|]
p [q|"a" ++ "b", a|] `shouldBe` [q|"a" ++ "b"|]
it "misc" $ do
p [q|"((", a|] `shouldBe` [q|"(("|]
p [q|"()(", a|] `shouldBe` [q|"()("|]
p "(a, )" `shouldBe` "(a, )"
p "(, b)" `shouldBe` "(, b)"
it "shouldn't modify the list" $ do
p "[" `shouldBe` "["
p "([)]" `shouldBe` "([)]"
-- p "([)], a" `shouldBe` "([)]"
it "shouldn't modify the list (QuickCheck)" $ property $ let
prop :: String -> Property
prop s = (parseExpr s $> fst) `isPrefixOf` s
$> counterexample [d|show s, parseExpr s|]
in prop
describe "parseExp'" $ do
it "should work" $ do
let p = parseExp'
p [] "asd" `shouldBe` ("asd", "")
p [] "a,b" `shouldBe` ("a", "b")
p ")" "a,b" `shouldBe` ("a,b", "")
p [] "(a,b)" `shouldBe` ("(a,b)", "")
p [] "(a,b),c" `shouldBe` ("(a,b)", "c")
p [] "[a,b],c" `shouldBe` ("[a,b]", "c")
p "]]" "],b],c" `shouldBe` ("],b]", "c")
p [] [q|"a,b",c|] `shouldBe` ([q|"a,b"|], "c")
p [] [q|',',c|] `shouldBe` ([q|','|], "c")
p [] [q|'"',c|] `shouldBe` ([q|'"'|], "c")
-- p [] [q|'\',',|] `shouldBe` ([q|'\','|], "c")
p [] [q|"\",",c|] `shouldBe` ([q|"\","|], "c")
p [] [q|'\'',c|] `shouldBe` ([q|'\''|], "c")
p [] [q|(\),c|] `shouldBe` ([q|(\)|], "c")
-- TODO decide
-- it "should? handle quotes int its own stack" $ do
-- p ['"'] [q|a,b",c|] `shouldBe` ([q|a,b"|], "c")
-- p ['"'] [q|(a",c|] `shouldBe` ([q|(a"|], "c")
-- p ['\''] [q|,',c|] `shouldBe` ([q|,'|], "c")
describe "splitOnCommas" $ do
it "should work" $ do
let s = splitOnCommas
s "a" `shouldBe` ["a"]
s "a,b" `shouldBe` ["a", "b"]
s "a, b" `shouldBe` ["a", " b"]
s "(a)" `shouldBe` ["(a)"]
s "(a, b)" `shouldBe` ["(a, b)"]
s "(a, b), b" `shouldBe` ["(a, b)", " b"]
s "','" `shouldBe` ["','"]
s "a ',' b" `shouldBe` ["a ',' b"]
s "(a, b \")\"), b" `shouldBe` ["(a, b \")\")", " b"]
s "(a, b \")\\\",\"), b" `shouldBe` ["(a, b \")\\\",\")", " b"]
describe "Debug.Dump" $ do
-- TODO decide if this is useful enough to warrant support
-- it "should execute even if empty" $ do
-- [d||] `shouldBe` ""
it "should work with single literal" $ do
[d|1|] `shouldBe` "(1) = 1"
it "should work with simple expression" $ do
[d|1 + 1|] `shouldBe` "(1 + 1) = 2"
it "should work with bindings" $ do
let a = 1
[d|a|] `shouldBe` "(a) = 1"
[d|a + 1|] `shouldBe` "(a + 1) = 2"
it "should work with comma separated expressions" $ do
[d|1, 2|] `shouldBe` "(1) = 1\t (2) = 2"
let i = 0.25
let f = (1 -)
[d|i, 1/i, f i, f (1/i)|] `shouldBe`
"(i) = 0.25\t (1/i) = 4.0\t (f i) = 0.75\t (f (1/i)) = -3.0"
it "should step over commas in sub-expressions" $ do
[d|(1, 2), 1|] `shouldBe` "((1, 2)) = (1,2)\t (1) = 1"