jsonlogic-0.1.0.0: test/Operation/Data/TestMissing.hs
module Operation.Data.TestMissing where
import qualified Data.Map as M
import Generator.Data
import Generator.Generic
import Generator.Utils
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 Text.Read (readMaybe)
import Utils
missingUnitTests :: TestTree
missingUnitTests =
testGroup
"missing unit tests"
[ testCase "logic {\"missing\":[]} data {} => []" $
U.assertEqual
"empty case"
(Right $ jArr [])
(apply [] (jObj [("missing", jArr [])]) (jObj [])),
testCase "logic {\"missing\":[\"a\", \"b\"]} data {\"a\":\"apple\", \"c\":\"carrot\"} => [\"b\"]" $
U.assertEqual
"first test case on site"
(Right $ jArr [jStr "b"])
(apply [] (jObj [("missing", jArr [jStr "a", jStr "b"])]) (jObj [("a", jStr "apple"), ("c", jStr "carrot")])),
testCase "logic {\"missing\":[\"a\", \"b\"]} data {\"a\":\"apple\", \"b\":\"banana\"} => []" $
U.assertEqual
"second test case on site"
(Right $ jArr [])
(apply [] (jObj [("missing", jArr [jStr "a", jStr "b"])]) (jObj [("a", jStr "apple"), ("b", jStr "banana")])),
testCase "logic {\"missing\":[0, 1]} data [\"apple\", \"banana\"] => []" $
U.assertEqual
"missing in lists"
(Right $ jArr [])
(apply [] (jObj [("missing", jArr [jNum 0, jNum 1])]) (jArr [jStr "apple", jStr "banana"])),
testCase "logic {\"missing\":[0, 1]} data [\"apple\"] => [1]" $
U.assertEqual
"missing in lists"
(Right $ jArr [jNum 1])
(apply [] (jObj [("missing", jArr [jNum 0, jNum 1])]) (jArr [jStr "apple"])),
testCase "logic {\"if\":[{\"missing\":[\"a\", \"b\"]}, \"Not enough fruit\", \"OK to proceed\"]} data {\"a\":\"apple\", \"b\":\"banana\"} => \"Ok to proceed\"" $
U.assertEqual
"third test case on site"
(Right $ jStr "OK to proceed")
(apply [] (jObj [("if", jArr [jObj [("missing", jArr [jStr "a", jStr "b"])], jStr "Not enough fruit", jStr "OK to proceed"])]) (jObj [("a", jStr "apple"), ("b", jStr "banana")]))
]
missingGeneratorTests :: TestTree
missingGeneratorTests =
testGroup
"missing generator tests"
[ hTestProperty "missing over emty" $
property $ do
-- Create rule and data
let missingEmpty = jObj [("missing", jArr [])]
dataJsonArray <- forAll $ Gen.sized genSizedRandomJsonArray
dataJsonObject <- forAll $ Gen.sized genSizedRandomJsonObject
-- Empty rule over any data returns empty array
Right (jArr []) === apply [] missingEmpty dataJsonArray
Right (jArr []) === apply [] missingEmpty (JsonObject dataJsonObject),
hTestProperty "Using integer index on array" $
property $ do
-- Generate random data
jsonData <- forAll $ Gen.sized genSizedRandomJson
-- Create the rule
x <- forAll $ Gen.int $ Range.constant 0 30
let rule = jObj [("missing", jArr [jNum $ fromIntegral x])]
-- Only returns empty array if the index is missing
case jsonData of
(JsonArray js) | x < length js -> Right (jArr []) === apply [] rule jsonData
(JsonString s) | x < length s -> Right (jArr []) === apply [] rule jsonData
-- If the index is a number and that index is in the dict it is indexed
(JsonObject o) | M.member (show x) o -> Right (jArr []) === apply [] rule jsonData
_ -> Right (jArr [jNum $ fromIntegral x]) === apply [] rule jsonData,
hTestProperty "Using string index on array" $
property $ do
-- Generate random array
jsonData@(JsonArray js) <- forAll $ Gen.sized genSizedRandomJsonArray
(indexJson, indexStr) <- forAll genGenericNonEmptyJsonString
-- Item should be in result since it cannot be present
let rule = jObj [("missing", jArr [indexJson])]
case readMaybe indexStr :: Maybe Int of
-- The string is by chance a number, if it is within the range the index is succesful
Just i | i >= 0 && i < length js -> Right (jArr []) === apply [] rule jsonData
-- Index is not present since it is a string or outside the range
_ -> Right (jArr [indexJson]) === apply [] rule jsonData,
hTestProperty "Using string index on object" $
property $ do
-- Generate data
jsonData <- forAll $ increaseSizeBy 1 $ Gen.sized genSizedRandomJsonObject
-- Choose a random item from the object
indexStr <- forAll $ Gen.element $ M.keys jsonData
let rule = jObj [("missing", jArr [jStr indexStr])]
-- The item should not be missing
Right (jArr []) === apply [] rule (JsonObject jsonData),
hTestProperty "Using integer index on object" $
property $ do
-- Random data
jsonData <- forAll $ Gen.sized genSizedRandomJsonObject
-- Generate random index
x <- forAll $ Gen.int $ Range.constant 0 30
let rule = jObj [("missing", jArr [jNum $ fromIntegral x])]
-- Item should be missing
if M.member (show x) jsonData
then Right (jArr []) === apply [] rule (JsonObject jsonData)
else Right (jArr [jNum $ fromIntegral x]) === apply [] rule (JsonObject jsonData)
]