module Main where import Prelude hiding (choose) import Data.Primitive import Test.QuickCheck.Instances import Test.Tasty import Test.Tasty.Runners import Test.Tasty.HUnit import Test.Tasty.QuickCheck import PrimitiveExtras.By6Bits (By6Bits) import qualified Focus import qualified Test.QuickCheck as QuickCheck import qualified Test.QuickCheck.Property as QuickCheck import qualified Main.Transaction as Transaction import qualified Main.Gens as Gen import qualified PrimitiveExtras.By6Bits as By6Bits import qualified PrimitiveExtras.SmallArray as SmallArray import qualified PrimitiveExtras.PrimArray as PrimArray import qualified Data.Serialize as Serialize import qualified Data.Vector.Primitive as PrimitiveVector main = defaultMain $ testGroup "All" $ [ testGroup "SmallArray" $ [ testCase "set" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [1, 4, 3] (SmallArray.toList (SmallArray.set 1 4 array)) , testCase "insert" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [1, 4, 2, 3] (SmallArray.toList (SmallArray.insert 1 4 array)) , testCase "unset" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [1, 3] (SmallArray.toList (SmallArray.unset 1 array)) , testCase "focus insert, when exists" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [1, 4, 3] (SmallArray.toList (snd (runIdentity (SmallArray.focusOnFoundElement (Focus.insert 4) (== 2) (const False) array)))) , testCase "focus insert, when doesn't exist" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [4, 1, 2, 3] (SmallArray.toList (snd (runIdentity (SmallArray.focusOnFoundElement (Focus.insert 4) (== 4) (const False) array)))) , testCase "focus delete" $ let array = SmallArray.list [1, 2, 3] in assertEqual "" [1, 3] (SmallArray.toList (snd (runIdentity (SmallArray.focusOnFoundElement Focus.delete (== 2) (const False) array)))) ] , testGroup "By6Bits" $ [ testCase "empty" $ do assertEqual "" (replicate (finiteBitSize (undefined :: Int)) Nothing) (By6Bits.toMaybeList (By6Bits.empty :: By6Bits Int32)) , testProperty "toMaybeList, maybeList" $ forAll Gen.maybeList $ \ maybeList -> maybeList === By6Bits.toMaybeList (By6Bits.maybeList maybeList) , testCase "unset" $ assertEqual "" ([Just 1, Nothing, Nothing, Just 3] <> replicate (finiteBitSize (undefined :: Int) - 4) Nothing) (By6Bits.toMaybeList (By6Bits.unset 1 (By6Bits.maybeList [Just 1, Just 2, Nothing, Just 3]))) , testTransactionProperty "set" Gen.setTransaction , testTransactionProperty "unset" Gen.unsetTransaction , testTransactionProperty "focusInsert" Gen.focusInsertTransaction , testTransactionProperty "focusDelete" Gen.focusDeleteTransaction , testTransactionProperty "unfoldl" Gen.unfoldlTransaction , testTransactionProperty "lookup" Gen.lookupTransaction , testTransactionProperty "composite" Gen.transaction ] , testGroup "PrimArray" $ [ testProperty "Construction from primitive vector" $ let gen = do offset <- choose (0, 2) length <- choose (0, 100) listSize <- let minSize = offset + length in choose (minSize, minSize + 100) list :: [Int32] <- replicateM listSize arbitrary return (list, offset, length) in forAll gen $ \ (inputList, offset, length) -> let !inputVec = PrimitiveVector.fromList inputList !sliceVec = PrimitiveVector.slice offset length inputVec !sliceList = PrimitiveVector.toList sliceVec in sliceList === primArrayToList (PrimArray.primitiveVector sliceVec) , testProperty "Serializes well with as in memory" $ forAll (Gen.primArray Gen.element) $ \ primArray -> Right primArray === Serialize.runGet (PrimArray.cerealGetAsInMemory Serialize.get) (Serialize.runPut ((PrimArray.cerealPutAsInMemory Serialize.put) primArray)) ] ] testTransactionProperty name transactionGen = testProperty (showString "Transaction: " name) $ forAll ((,) <$> Gen.maybeList <*> transactionGen) $ \ (maybeList, transaction) -> case transaction of Transaction.Transaction name applyToMaybeList applyToBy6Bits -> let ssa = By6Bits.maybeList maybeList (result1, newMaybeList) = runState applyToMaybeList maybeList (result2, newSsa) = runState applyToBy6Bits ssa newSsaMaybeList = By6Bits.toMaybeList newSsa in QuickCheck.counterexample ("transaction: " <> show name <> "\nnewMaybeList1: " <> show newMaybeList <> "\nnewMaybeList2: " <> show newSsaMaybeList <> "\nresult1: " <> show result1 <> "\nresult2: " <> show result2) (newMaybeList == By6Bits.toMaybeList newSsa && result1 == result2)