mima-tools/test/Mima/Vm/FlagSpec.hs
2020-03-28 19:32:21 +00:00

85 lines
3.2 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Mima.Vm.FlagSpec (spec) where
import qualified Data.Aeson.Types as A
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Test.Hspec
import Test.QuickCheck
import Mima.Vm.Flags
import Mima.Vm.Metadata
import Mima.Vm.Word
readOnlyFlags :: [MimaAddress] -> Flags
readOnlyFlags addresses = Flags (Set.fromList addresses) mempty mempty
executeFlags :: [MimaAddress] -> Flags
executeFlags addresses = Flags mempty (Set.fromList addresses) mempty
breakpointFlags :: [MimaAddress] -> Flags
breakpointFlags addresses = Flags mempty mempty (Set.fromList addresses)
executableBetween :: Bool -> MimaAddress -> MimaAddress -> Metadata
executableBetween executable start stop = Metadata mempty
[ RangeFromTo (Map.singleton "executable" (A.Bool executable)) start stop
]
overlappingExecutableFlags :: Flags
overlappingExecutableFlags = flags
where
baseMetadata = executableBetween True 1 20
metadata = baseMetadata <> executableBetween False 4 6
flags = flagsFromMetadata metadata
tripleOverlappingExecutableFlags :: Flags
tripleOverlappingExecutableFlags = flags
where
baseMetadata = executableBetween True 1 20
metadata = baseMetadata
<> executableBetween False 4 6
<> executableBetween True 5 6
flags = flagsFromMetadata metadata
spec :: Spec
spec = do
describe "readonlyAt" $
it "returns the correct set value" $ do
readonlyAt (readOnlyFlags [2, 5]) 2 `shouldBe` True
readonlyAt (readOnlyFlags [2, 5]) 5 `shouldBe` True
readonlyAt (readOnlyFlags [2, 5]) 3 `shouldBe` False
describe "executeAt" $ do
it "returns the correct set value" $ do
executableAt (executeFlags [20, 200]) 2 `shouldBe` False
executableAt (executeFlags [20, 200]) 20 `shouldBe` True
executableAt (executeFlags [20, 200]) 200 `shouldBe` True
it "returns true if none are set" $ property $ \x ->
let word = fromInteger x
in executableAt mempty word
context "with nested ranges" $ do
it "returns the correct value for unaffected areas" $ do
let flags = overlappingExecutableFlags
executableAt flags 1 `shouldBe` True
executableAt flags 3 `shouldBe` True
executableAt flags 7 `shouldBe` True
executableAt flags 20 `shouldBe` True
it "returns the correct value for affected areas" $ do
let flags = overlappingExecutableFlags
executableAt flags 4 `shouldBe` False
executableAt flags 5 `shouldBe` False
executableAt flags 6 `shouldBe` False
it "returns the correct value for triple affected areas" $ do
let flags = tripleOverlappingExecutableFlags
executableAt flags 1 `shouldBe` True
executableAt flags 4 `shouldBe` False
executableAt flags 5 `shouldBe` True
executableAt flags 6 `shouldBe` True
executableAt flags 20 `shouldBe` True
describe "breakpointAt" $
it "returns the correct set value" $ do
breakpointAt (breakpointFlags [20, 200]) 2 `shouldBe` False
breakpointAt (breakpointFlags [20, 200]) 20 `shouldBe` True
breakpointAt (breakpointFlags [20, 200]) 200 `shouldBe` True