dzen-dhall-1.0.0: test/DzenDhall/Test/AST.hs
{-# OPTIONS -Wno-name-shadowing -Wno-orphans #-}
{-# LANGUAGE TemplateHaskell #-}
module DzenDhall.Test.AST
( getTests
)
where
import DzenDhall.AST
import DzenDhall.Config
import DzenDhall.Data
import Control.Arrow
import Data.Text hiding (split)
import Test.Hspec
import Test.Tasty
import Test.Tasty.HUnit
import Test.QuickCheck (CoArbitrary (..), Arbitrary (..), counterexample, withMaxSuccess, (===), (==>))
import qualified Test.QuickCheck as QC
import Test.QuickCheck.Arbitrary ()
import Generic.Random
import qualified Test.Tasty.QuickCheck as QC
txt :: Text -> AST
txt = ASTText
getTests :: TestTree
getTests =
testGroup "AST"
[ testGroup "DzenDhall.Data.split" $
[ testCase "splits ASTText correctly" $ do
let tree = txt (pack "123456")
split 0 tree `shouldBe` (mempty, tree)
split 1 tree `shouldBe` (txt "1", txt "23456")
split 2 tree `shouldBe` (txt "12", txt "3456")
split 3 tree `shouldBe` (txt "123", txt "456")
split 7 tree `shouldBe` (txt "123456", mempty)
split 8 tree `shouldBe` (txt "123456", mempty)
, testCase "splits branches correctly" $ do
let tree = txt "abc" <> txt "def"
split 0 tree `shouldBe` (mempty, tree)
split 1 tree `shouldBe` (txt "a", txt "bc" <> txt "def")
split 2 tree `shouldBe` (txt "ab", txt "c" <> txt "def")
split 3 tree `shouldBe` (txt "abc", txt "def")
, testCase "splits `ASTPadding` correctly" $ do
let tree = ASTPadding 4 PRight (txt "a")
split 0 tree `shouldBe` (mempty, tree)
split 1 tree `shouldBe` (txt "a", txt " ")
split 2 tree `shouldBe` (txt "a" <> txt " ", txt " ")
split 3 tree `shouldBe` (txt "a" <> txt " ", txt " ")
split 4 tree `shouldBe` (txt "a" <> txt " ", mempty)
split 5 tree `shouldBe` (txt "a" <> txt " ", mempty)
, testCase "DzenDhall.Data.splitAST calculates consumed lengths correctly for Txt" $ do
let tree = txt "123456"
splitAST 0 tree `shouldBe` EmptyL tree
splitAST 1 tree `shouldBe` Twain (txt "1") (txt "23456") 1
splitAST 2 tree `shouldBe` Twain (txt "12") (txt "3456") 2
splitAST 6 tree `shouldBe` EmptyR (txt "123456") 6
splitAST 7 tree `shouldBe` EmptyR (txt "123456") 6
, testCase "Calculates consumed lengths correctly for ASTs" $ do
let tree = txt "123" <> txt "456"
splitAST 0 tree `shouldBe` EmptyL tree
splitAST 1 tree `shouldBe` Twain (txt "1") (txt "23" <> txt "456") 1
splitAST 2 tree `shouldBe` Twain (txt "12") (txt "3" <> txt "456") 2
splitAST 6 tree `shouldBe` EmptyR tree 6
splitAST 7 tree `shouldBe` EmptyR tree 6
let tree = txt "12" <> txt "34" <> txt "56"
splitAST 0 tree `shouldBe` EmptyL tree
splitAST 1 tree `shouldBe` Twain (txt "1")
(txt "2" <> txt "34" <> txt "56")
1
splitAST 2 tree `shouldBe` Twain (txt "12")
(txt "34" <> txt "56")
2
splitAST 3 tree `shouldBe` Twain (txt "12" <> txt "3")
(txt "4" <> txt "56")
3
splitAST 4 tree `shouldBe` Twain (txt "12" <> txt "34")
(txt "56")
4
splitAST 5 tree `shouldBe` Twain (txt "12" <> txt "34" <> txt "5")
(txt "6")
5
splitAST 6 tree `shouldBe` EmptyR (txt "12" <> txt "34" <> txt "56") 6
splitAST 7 tree `shouldBe` EmptyR (txt "12" <> txt "34" <> txt "56") 6
let tree = (txt "12" <> txt "34") <> txt "56"
splitAST 0 tree `shouldBe` EmptyL tree
splitAST 1 tree `shouldBe` Twain (txt "1")
((txt "2" <> txt "34") <> txt "56")
1
splitAST 2 tree `shouldBe` Twain (txt "12")
(txt "34" <> txt "56")
2
splitAST 3 tree `shouldBe` Twain (txt "12" <> txt "3")
(txt "4" <> txt "56")
3
splitAST 4 tree `shouldBe` Twain (txt "12" <> txt "34")
(txt "56")
4
splitAST 5 tree `shouldBe` Twain ((txt "12" <> txt "34") <> txt "5")
(txt "6")
5
splitAST 6 tree `shouldBe` EmptyR ((txt "12" <> txt "34") <> txt "56") 6
splitAST 7 tree `shouldBe` EmptyR ((txt "12" <> txt "34") <> txt "56") 6
]
, testGroup "Generic tests"
[ QC.testProperty "AST.split preserves lengths"
prop_ast_split_preserves_widths
, QC.testProperty "AST.split returns ASTs with correct lengths"
prop_ast_split_returns_correct_lengths
]
]
prop_ast_split_preserves_widths :: AST -> Int -> QC.Property
prop_ast_split_preserves_widths ast position =
withMaxSuccess 10000 $
counterexample (show $ split position ast) $
astWidth ast === (uncurry (+) $ astWidth *** astWidth $ split position ast)
prop_ast_split_returns_correct_lengths :: AST -> Int -> QC.Property
prop_ast_split_returns_correct_lengths ast position =
withMaxSuccess 10000 $
position >= 0 && astWidth ast >= position ==>
counterexample (show $ split position ast) $
astWidth (fst (split position ast)) === position
instance Arbitrary Text where
arbitrary = Data.Text.pack <$> arbitrary
instance CoArbitrary Text where
coarbitrary = coarbitrary . Data.Text.unpack
instance Arbitrary Color where
arbitrary = genericArbitraryU
instance CoArbitrary Color
instance Arbitrary Button where
arbitrary = genericArbitraryU
instance CoArbitrary Button
instance Arbitrary ClickableArea where
arbitrary = genericArbitraryU
instance CoArbitrary ClickableArea
instance Arbitrary Position where
arbitrary = genericArbitraryU
instance CoArbitrary Position
instance Arbitrary AbsolutePosition where
arbitrary = genericArbitraryU
instance CoArbitrary AbsolutePosition
instance Arbitrary Property where
arbitrary = genericArbitraryU
instance CoArbitrary Property
instance Arbitrary Shape where
arbitrary = genericArbitraryU
instance CoArbitrary Shape
instance Arbitrary Padding where
arbitrary = genericArbitraryU
instance CoArbitrary Padding
instance Arbitrary AST where
arbitrary = genericArbitraryU
instance CoArbitrary AST