aeson-jsonpath-0.3.0.2: test/spec/ParserSpec.hs
module ParserSpec
( spec )
where
import qualified Text.ParserCombinators.Parsec as P
import Data.Aeson.JSONPath.Parser (pQuery)
import Data.Either (isLeft)
import Data.Aeson.JSONPath.Types
import Test.Hspec
import Prelude
spec :: Spec
spec = do
describe "Parse query string" $ do
it "parses query: $" $
P.parse pQuery "" "$"
`shouldBe`
Right (Query{queryType=Root,querySegments=[]})
it "parses query: $.store" $
P.parse pQuery "" "$.store"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}]
}
it "parses query: $['store']" $
P.parse pQuery "" "$['store']"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Name "store"]
}]
}
it "parses query: $.store.books" $
P.parse pQuery "" "$.store.books"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}]
}
it "parses query: $.store.books[0]" $
P.parse pQuery "" "$.store.books[0]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Index 0]
}]
}
it "parses query: $.store.books[0,2]" $
P.parse pQuery "" "$.store.books[0,2]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Index 0, Index 2]
}]
}
it "parses query: $.store.books[1:3]" $
P.parse pQuery "" "$.store.books[1:3]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [ArraySlice (Just 1, Just 3, 1)]
}]
}
it "parses query: $.store.books[1:4:2]" $
P.parse pQuery "" "$.store.books[1:4:2]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [ArraySlice (Just 1, Just 4, 2)]
}]
}
it "parses query: $.store.books[-1:-4:-2]" $
P.parse pQuery "" "$.store.books[-1:-4:-2]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [ArraySlice (Just (-1), Just (-4), (-2))]
}]
}
it "parses query: $.store.books[1:3, 0, 1]" $
P.parse pQuery "" "$.store.books[1:3, 0, 1]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [ArraySlice (Just 1, Just 3, 1), Index 0, Index 1]
}]
}
it "parses query: $.*" $
P.parse pQuery "" "$.*"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = WildcardSegment
}]
}
it "parses query: $[*]" $
P.parse pQuery "" "$[*]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [WildcardSelector]
}]
}
it "parses query: $..*" $
P.parse pQuery "" "$..*"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Descendant,
segment = WildcardSegment
}]
}
it "parses query: $..[*]" $
P.parse pQuery "" "$..[*]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Descendant,
segment = Bracketed [WildcardSelector]
}]
}
it "fails with $.1startsWithNum" $
P.parse pQuery "" "$.1startsWithNum"
`shouldSatisfy` isLeft
it "parses query $.©®±×÷Ωπ•€→∀∃∈≠≤≥✓λ" $
P.parse pQuery "" "$.©®±×÷Ωπ•€→∀∃∈≠≤≥✓λ"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "©®±×÷Ωπ•€→∀∃∈≠≤≥✓λ"
}]
}
it "parses query: $._" $
P.parse pQuery "" "$._"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "_"
}]
}
it "parses query: $.underscore_key" $
P.parse pQuery "" "$.underscore_key"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "underscore_key"
}]
}
it "parses query: $[0,TAB/LINEFEED/RETURN/SPACE1]" $
P.parse pQuery "" "$[0,\n\t\r 1]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Index 0, Index 1]
}]
}
describe "parses JSPFilter Query" $ do
it "$[?@.category == 'reference']" $
P.parse pQuery "" "$[?@.category == 'reference']"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "category"]
}) Equal (CompLit (LitString "reference")))]])]
}]
}
it "test expr: $..books[?@.price].title" $
P.parse pQuery "" "$..books[?@.price].title"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Descendant,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Test (FilterQuery Query {
queryType = Current,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "price"
}]
})]])]
}, QuerySegment {
segmentType = Child,
segment = Dotted "title"
}]
}
it "and expr: $[?@.price < 20 && @.price > 10]" $
P.parse pQuery "" "$[?@.price < 20 && @.price > 10]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Less (CompLit (LitNum 20.0))), Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Greater (CompLit (LitNum 10.0)))]])]
}]
}
it "or expr: $[?@.price < 20 || @.price > 10]" $
P.parse pQuery "" "$[?@.price < 20 || @.price > 10]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Less (CompLit (LitNum 20.0)))], LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Greater (CompLit (LitNum 10.0)))]])]
}]
}
it "root filter: $..books[?$.price].title" $
P.parse pQuery "" "$..books[?$.price].title"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Descendant,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Test (FilterQuery Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "price"
}]
})]])]
}, QuerySegment {
segmentType = Child,
segment = Dotted "title"
}]
}
it "not expr: $[?!(@.price < 20 && @.price > 10)]" $
P.parse pQuery "" "$[?!(@.price < 20 && @.price > 10)]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [NotParen (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Less (CompLit (LitNum 20.0))), Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Greater (CompLit (LitNum 10.0)))]])]])]
}]
}
it "scientific: $.store.books[?@.price < -1e20]" $
P.parse pQuery "" "$.store.books[?@['price'] < -1e20]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Less (CompLit (LitNum (-1.0e20))))]])]
}]
}
it "double: $.store.books[?@.price < 0.01]" $
P.parse pQuery "" "$.store.books[?@['price'] < 0.01]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "price"]
}) Less (CompLit (LitNum (1.0e-2))))]])]
}]
}
it "bool: $.store.books[?@.is_available == true]" $
P.parse pQuery "" "$.store.books[?@.is_available == true]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "is_available"]
}) Equal (CompLit (LitBool True)))]])]
}]
}
it "null: $.store.books[?@.is_available == null]" $
P.parse pQuery "" "$.store.books[?@.is_available == null]"
`shouldBe`
Right Query {
queryType = Root,
querySegments = [QuerySegment {
segmentType = Child,
segment = Dotted "store"
}, QuerySegment {
segmentType = Child,
segment = Dotted "books"
}, QuerySegment {
segmentType = Child,
segment = Bracketed [Filter (LogicalOr [LogicalAnd [Comparison (Comp (CompSQ SingularQuery {
singularQueryType = CurrentSQ,
singularQuerySegments = [NameSQSeg "is_available"]
}) Equal (CompLit LitNull))]])]
}]
}