jsonlogic-0.1.0.0: test/Operation/Data/TestVar.hs
{-# LANGUAGE OverloadedLists #-}
module Operation.Data.TestVar where
import qualified Data.List as L
import Generator.Data
import Generator.Generic
import Hedgehog (forAll, property, (===))
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import JsonLogic.Json
import JsonLogic.Pure.Evaluator
import Test.Tasty
import Test.Tasty.HUnit as U
import Utils
varUnitTests :: TestTree
varUnitTests =
testGroup
"Var unit tests"
-- logic {"var":""} data 1 => 1
[ testCase "logic {\"var\":\"\"} data {\"x\":1}" $
U.assertEqual
"Simple var case is correct"
(Right $ JsonNumber 1)
(apply [] (JsonObject [("var", JsonString "")]) (JsonNumber 1)),
-- logic {"var":"x"} data 1 => Null
testCase "logic {\"var\":\"x\"} data {\"x\":1}" $
U.assertEqual
"Simple var case is correct"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonString "x")]) (JsonNumber 1)),
-- logic {"var":true} data 1 => Null
testCase "logic {\"var\":true} data {\"x\":1}" $
U.assertEqual
"Simple var case is correct"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonBool True)]) (JsonNumber 1)),
-- logic {"var":"x"} data{"x":1} => 1
testCase "logic {\"var\":\"x\"} data {\"x\":1}" $
U.assertEqual
"Simple var case is correct"
(Right $ JsonNumber 1)
(apply [] (JsonObject [("var", JsonString "x")]) (JsonObject [("x", JsonNumber 1)])),
-- logic {"var":"x"} => Null
testCase "logic {\"var\":\"x\"} data {}" $
U.assertEqual
"Empty data gives Null"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonString "x")]) JsonNull),
-- logic {"var":"x"} data {"x":[1,2,3]} => [1,2,3]
testCase "logic {\"var\":\"x\"} data {\"x\":[1,2,3]\"}" $
U.assertEqual
"Substitutes arraytype correctly"
(Right $ JsonArray [JsonNumber 1, JsonNumber 2, JsonNumber 3])
(apply [] (JsonObject [("var", JsonString "x")]) (JsonObject [("x", JsonArray [JsonNumber 1, JsonNumber 2, JsonNumber 3])])),
-- logic {"var":"x.y"} data {"x":{"y":1}} => 1
testCase "logic {\"var\":\"x.y\"} data {\"x\":{\"y\":1}\"}" $
U.assertEqual
"Access nested parameter 'x.y'"
(Right $ JsonNumber 1)
(apply [] (JsonObject [("var", JsonString "x.y")]) (JsonObject [("x", JsonObject [("y", JsonNumber 1)])])),
-- logic {"var":"y"} data {"x":{"y":1}} => Null
testCase "logic {\"var\":\"y\"} data {\"x\":{\"y\":1}\"}" $
U.assertEqual
"Parameter not accessed on correct level"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonString "y")]) $ JsonObject [("x", JsonObject [("y", JsonNumber 1)])]),
-- logic {"var":{}} data 1 => Null
testCase "logic {\"var\":[]} data 1 " $
U.assertEqual
"Indexing with an object returns null"
(Right $ JsonNumber 1)
(apply [] (JsonObject [("var", JsonArray [])]) $ JsonNumber 1),
-- logic {"var":{}} data 1 => Null
testCase "logic {\"var\":{}} data 1 " $
U.assertEqual
"Indexing with an object returns null"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonObject [])]) $ JsonNumber 1),
-- logic {"var":[["y"]]} data {"y":{"y":1}} => Null
testCase "logic {\"var\":[[\"y\"]]} data {\"y\":{\"y\":1}\"}" $
U.assertEqual
"Indexing with nested array gives back null"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonObject [])]) $ JsonObject [("y", JsonObject [("y", JsonNumber 1)])]),
-- logic {"var":["", true]} data null => Null
testCase "logic {\"var\":[\"\", true]} data null" $
U.assertEqual
"null value does not always return backup"
(Right JsonNull)
(apply [] (JsonObject [("var", JsonArray [JsonString "", JsonBool True])]) JsonNull)
]
varGeneratorTests :: TestTree
varGeneratorTests =
testGroup
"Var generator tests"
[ hTestProperty "null, empty string, and empty array return entire data" $
property $ do
-- Logic that all returns the entire data
let nullVar = JsonObject [("var", JsonNull)]
emptyStringVar = JsonObject [("var", JsonString "")]
emptyArrayVar = JsonObject [("var", JsonArray [])]
dataJson <- forAll $ Gen.sized genSizedRandomJson
-- All of them return the entire data
Right dataJson === apply [] nullVar dataJson
Right dataJson === apply [] emptyStringVar dataJson
Right dataJson === apply [] emptyArrayVar dataJson,
hTestProperty "bool, nested array, and empty object var return nothing" $
property $ do
-- Logic that all returns null
boolJson <- forAll genGenericJsonBool
arrJson <- forAll $ Gen.sized genSizedNestedJsonArray
let boolVar = JsonObject [("var", fst boolJson)]
arrVar = JsonObject [("var", JsonArray [arrJson])]
objVar = JsonObject [("var", JsonObject [])]
dataJson <- forAll $ Gen.sized genSizedRandomJson
-- All of them return null
Right JsonNull === apply [] boolVar dataJson
Right JsonNull === apply [] arrVar dataJson
Right JsonNull === apply [] objVar dataJson,
hTestProperty "Number var returns index" $
property $ do
-- Insert Json data at index
index <- forAll $ Gen.int $ Range.constant 0 15
let logic = JsonObject [("var", JsonNumber $ fromIntegral index)]
-- Generate random Json and random data and inject it at the index
dataJson <- forAll $ Gen.sized genSizedRandomJson
randomJson <- forAll $ Gen.sized genSizedRandomJsonArray
resultJson <- forAll $ return $ insertAtPath [show index] dataJson randomJson
-- Check that the index returns the data
Right dataJson === apply [] logic resultJson,
hTestProperty "String var returns item" $
property $ do
-- The member to index
(indexJson, indexStr) <- forAll genGenericNonEmptyJsonString
let logic = JsonObject [("var", indexJson)]
-- Generate random Json and random data and inject it at the string member
randomJson <- forAll $ Gen.sized genSizedRandomJsonArray
dataJson <- forAll $ Gen.sized genSizedRandomJson
resultJson <- forAll $ return $ insertAtPath [indexStr] dataJson randomJson
-- Check that the data is found at the index
Right dataJson === apply [] logic resultJson,
hTestProperty "Nested indexing for strings returns item correctly" $
property $ do
-- Generate a list of strings denoting a path
-- f.e ["aa", "bb"] is path "aa.bb" in Json
recIndex <- forAll $ Gen.list (Range.constant 2 10) $ snd <$> genGenericNonEmptyJsonString
let logic = JsonObject [("var", JsonString $ L.intercalate "." recIndex)]
-- Generate random Json and random data and inject it at path
randomJson <- forAll $ Gen.sized genSizedRandomJsonObject
dataJson <- forAll $ Gen.sized genSizedRandomJson
resultJson <- forAll $ return $ insertAtPath recIndex dataJson (JsonObject randomJson)
-- Verify the data is found at the path in the Json
Right dataJson === apply [] logic resultJson,
hTestProperty "Default var takes first value if it returns a value" $
property $ do
-- Use var null to always convert to a valid item
(stringJson, _) <- forAll genGenericNonEmptyJsonString
let logic = JsonObject [("var", JsonArray [JsonNull, stringJson])]
dataJson <- forAll $ Gen.sized genSizedRandomJsonArray
-- Verify we get the entire data as result and not the default
Right dataJson === apply [] logic dataJson,
hTestProperty "Defaults correctly to second value" $
property $ do
-- Json bool so it always defaults to the stringJson
(stringJson, _) <- forAll genGenericNonEmptyJsonString
let logic = JsonObject [("var", JsonArray [JsonBool True, stringJson])]
randomJson <- forAll $ Gen.sized genSizedRandomJsonArray
-- Verify the default value as the result
Right stringJson === apply [] logic randomJson
]