jsonlogic-0.1.0.0: test/Operation/String/TestSubstr.hs
module Operation.String.TestSubstr where
import Generator.Generic
import Hedgehog as H (assert, failure, forAll, property, (===))
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import JsonLogic.Json (Json (..))
import JsonLogic.Pure.Evaluator (apply)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit as U (assertEqual, testCase)
import Utils
substrUnitTests :: TestTree
substrUnitTests =
testGroup
"substr unit tests"
[ testCase "substr empty" $
U.assertEqual
"Empty substr should return an empty string"
(Right $ jStr "")
(apply [] (jObj [("substr", jArr [])]) jNull),
testCase "first example site" $
U.assertEqual
"logic {\"substr\": [\"jsonlogic\", 4]} => \"logic\""
(Right $ jStr "logic")
(apply [] (jObj [("substr", jArr [jStr "jsonlogic", jNum 4])]) jNull),
testCase "second example site" $
U.assertEqual
"logic {\"substr\": [\"jsonlogic\", -5]} => \"logic\""
(Right $ jStr "logic")
(apply [] (jObj [("substr", jArr [jStr "jsonlogic", jNum $ -5])]) jNull),
testCase "third example site" $
U.assertEqual
"logic {\"substr\": [\"jsonlogic\", 1, 3]} => \"son\""
(Right $ jStr "son")
(apply [] (jObj [("substr", jArr [jStr "jsonlogic", jNum 1, jNum 3])]) jNull),
testCase "fourth example site" $
U.assertEqual
"logic {\"substr\": [\"jsonlogic\", 4, -2]} => \"son\""
(Right $ jStr "log")
(apply [] (jObj [("substr", jArr [jStr "jsonlogic", jNum 4, jNum $ -2])]) jNull),
testCase "two negative indexes" $
U.assertEqual
"logic {\"substr\": [\"jsonlogic\", -5, -2]} => \"log\""
(Right $ jStr "log")
(apply [] (jObj [("substr", jArr [jStr "jsonlogic", jNum $ -5, jNum $ -2])]) jNull)
]
substrGeneratorTests :: TestTree
substrGeneratorTests =
testGroup
"substr generator tests"
-- Indexing using positive does same as drop
[ hTestProperty "substr with positive value" $
property $ do
(jsonStr, str) <- forAll genGenericJsonString
index <- forAll $ Gen.int (Range.constant 0 $ length str)
let rule = jObj [("substr", jArr [jsonStr, jNum $ fromIntegral index])]
Right (jStr $ drop index str) === apply [] rule jsonStr,
-- Indexing with negative values returns end
hTestProperty "substr with negative value" $
property $ do
(jsonStr, str) <- forAll genGenericNonEmptyJsonString
index <- forAll $ Gen.int (Range.constant (-1) (-length str))
let rule = jObj [("substr", jArr [jsonStr, jNum $ fromIntegral index])]
case apply [] rule jsonStr of
-- Length is the equal to the negative index
Right (JsonString res) -> H.assert $ length res == -index
_ -> H.failure,
-- The evaluation returns the same result as take . drop
hTestProperty "substr with start and final index works like take . drop" $
property $ do
(jsonStr, str) <- forAll genGenericJsonString
-- Take and drop value
index <- forAll $ Gen.int (Range.constant 0 $ length str)
endIndex <- forAll $ Gen.int (Range.constant 0 $ length str)
-- Assert the result is the same
let rule = jObj [("substr", jArr [jsonStr, jNum $ fromIntegral index, jNum $ fromIntegral endIndex])]
Right (jStr $ take endIndex $ drop index str) === apply [] rule jsonStr,
-- The take part also works with negative indexes
hTestProperty "substr with start and final negative index" $
property $ do
(jsonStr, str) <- forAll genGenericNonEmptyJsonString
-- Positive start index, negative end index
index <- forAll $ Gen.int (Range.constant 0 $ length str - 1)
endIndex <- forAll $ Gen.int (Range.constant (-1) (-length str))
-- Create rule and evaluate
let rule = jObj [("substr", jArr [jsonStr, jNum $ fromIntegral index, jNum $ fromIntegral endIndex])]
case apply [] rule jsonStr of
-- Assert the length is as expected
Right (JsonString res) -> H.assert $ length res == max 0 (length str - index + endIndex)
_ -> H.failure
]