tvl-depot/test/Xanthous/Data/LevelsSpec.hs
Griffin Smith 6b0bab0e85 Add support for multiple levels
Add a data structure, based on the zipper comonad, which provides
support for multiple levels, each of which is its own entity map. The
current level is provided by coreturn, which the `entities` lens has
been updated to use. Nothing currently supports going up or down levels
yet - that's coming next.
2020-01-04 23:48:51 -05:00

60 lines
2.7 KiB
Haskell

--------------------------------------------------------------------------------
module Xanthous.Data.LevelsSpec (main, test) where
--------------------------------------------------------------------------------
import Test.Prelude hiding (levels)
--------------------------------------------------------------------------------
import qualified Data.Aeson as JSON
--------------------------------------------------------------------------------
import Xanthous.Util (between)
import Xanthous.Data.Levels
--------------------------------------------------------------------------------
main :: IO ()
main = defaultMain test
test :: TestTree
test = testGroup "Xanthous.Data.Levels"
[ testGroup "current"
[ testProperty "view is extract" $ \(levels :: Levels Int) ->
levels ^. current === extract levels
, testProperty "set replaces current" $ \(levels :: Levels Int) new ->
extract (set current new levels) === new
, testProperty "set extract is id" $ \(levels :: Levels Int) ->
set current (extract levels) levels === levels
, testProperty "set y ∘ set x ≡ set y" $ \(levels :: Levels Int) x y ->
set current y (set current x levels) === set current y levels
]
, localOption (QuickCheckTests 20)
$ testBatch $ semigroup @(Levels Int) (error "unused", 1 :: Int)
, testGroup "next/prev"
[ testGroup "nextLevel"
[ testProperty "seeks forwards" $ \(levels :: Levels Int) genned ->
(pos . runIdentity . nextLevel (Identity genned) $ levels)
=== pos levels + 1
, testProperty "maintains the invariant" $ \(levels :: Levels Int) genned ->
let levels' = runIdentity . nextLevel (Identity genned) $ levels
in between 0 (length levels') $ pos levels'
, testProperty "extract is total" $ \(levels :: Levels Int) genned ->
let levels' = runIdentity . nextLevel (Identity genned) $ levels
in total $ extract levels'
]
, testGroup "prevLevel"
[ testProperty "seeks backwards" $ \(levels :: Levels Int) ->
case prevLevel levels of
Nothing -> property Discard
Just levels' -> pos levels' === pos levels - 1
, testProperty "maintains the invariant" $ \(levels :: Levels Int) ->
case prevLevel levels of
Nothing -> property Discard
Just levels' -> property $ between 0 (length levels') $ pos levels'
, testProperty "extract is total" $ \(levels :: Levels Int) ->
case prevLevel levels of
Nothing -> property Discard
Just levels' -> total $ extract levels'
]
]
, testGroup "JSON"
[ testProperty "toJSON/parseJSON round-trip" $ \(levels :: Levels Int) ->
JSON.decode (JSON.encode levels) === Just levels
]
]