hq-json-0.1.1: test/HQ/Query/ParserSpec.hs
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
module HQ.Query.ParserSpec (spec) where
import Data.Aeson (Value (..))
import HQ.Optic
import HQ.Query (Query (..))
import HQ.Query.Parser (parseQuery)
import HQ.Transformation hiding (Compose)
import HQ.Transformation qualified as T
import Relude hiding (Compose, Const)
import Test.Syd
spec :: Spec
spec = describe "HQ.Query.Parser" $ do
it "parses queries" $ forM_ happyCases $ \(input, expected) ->
parseQuery input `shouldBe` Right expected
it "rejects invalid queries" $ forM_ rejectCases $ \input ->
parseQuery input `shouldSatisfy` isLeft
happyCases :: [(Text, Query)]
happyCases =
[ ("fold @foo", Fold (Field "foo")),
("fold each", Fold Each),
("fold @foo.each.@bar", Fold (Compose (Compose (Field "foo") Each) (Field "bar"))),
("preview @foo.each", Preview (Compose (Field "foo") Each)),
("preview each.@foo", Preview (Compose Each (Field "foo"))),
("preview @name", Preview (Field "name")),
("fold @my_field", Fold (Field "my_field")),
("preview @field123", Preview (Field "field123")),
("preview @foo_bar_1", Preview (Field "foo_bar_1")),
("fold id", Fold Id),
("preview id.@foo", Preview (Compose Id (Field "foo"))),
("fold keys", Fold Keys),
("fold values", Fold Values),
("preview @obj.keys", Preview (Compose (Field "obj") Keys)),
("preview keys._String", Preview (Compose Keys (Prism PString))),
("fold values.@x", Fold (Compose Values (Field "x"))),
("fold ix 10", Fold (Ix 10)),
("fold filter @age == 30", Fold (Filter (Field "age") (Equal (Number 30)))),
("fold @users.filter (each . @age) (== 30)", Fold (Compose (Field "users") (Filter (Compose Each (Field "age")) (Equal (Number 30))))),
("over each.filter @age == 30 +1", Over (Compose Each (Filter (Field "age") (Equal (Number 30)))) (Add 1)),
("fold (@foo)", Fold (Field "foo")),
("fold ((@foo))", Fold (Field "foo")),
("fold (@foo . @bar)", Fold (Compose (Field "foo") (Field "bar"))),
("fold filter (@age) (== 30)", Fold (Filter (Field "age") (Equal (Number 30)))),
("over keys trim", Over Keys Trim),
("delete values", Delete Values),
(" preview @foo ", Preview (Field "foo")),
("preview @foo . @bar", Preview (Compose (Field "foo") (Field "bar"))),
("preview@foo", Preview (Field "foo")),
("\tpreview\t@foo\t", Preview (Field "foo")),
("fold _String", Fold (Prism PString)),
("fold _Number", Fold (Prism PNumber)),
("fold _Bool", Fold (Prism PBool)),
("fold _Null", Fold (Prism PNull)),
("fold _Array", Fold (Prism PArray)),
("fold _Object", Fold (Prism PObject)),
("fold _Just", Fold PrismJust),
("fold each._String", Fold (Compose Each (Prism PString))),
("fold @data._Number", Fold (Compose (Field "data") (Prism PNumber))),
("fold _Array.ix 0", Fold (Compose (Prism PArray) (Ix 0))),
("over @foo +1", Over (Field "foo") (Add 1)),
("over each trim", Over Each Trim),
("over @foo.each +1", Over (Compose (Field "foo") Each) (Add 1)),
("over @n +1 . == 3", Over (Field "n") (T.Compose (Add 1) (Equal (Number 3)))),
("over @title ++\"!\"", Over (Field "title") (ConcatString "!")),
("over@foo+1", Over (Field "foo") (Add 1)),
("set @name \"bob\"", Over (Field "name") (Const (String "bob"))),
("set each 0", Over Each (Const (Number 0))),
("set @users.each.@name \"anon\"", Over (Compose (Compose (Field "users") Each) (Field "name")) (Const (String "anon")))
]
rejectCases :: [Text]
rejectCases =
[ "fold @users.filter (each . @age == 30)",
"fold @users.filter (each . @age, == 30)",
"fold ()",
"",
"unknown @foo",
"fold",
"fold foo",
"fold @",
"folder @foo",
"fold eachx",
"fold ix0",
"over @foo"
]