-- | Immutable DB chunks tests.
module Test.Ouroboros.Storage.ImmutableDB.Chunks (tests) where

import Data.List (sort)
import Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal (ChunkNo (..), chunksBetween)
import Test.QuickCheck
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (testProperty)
import Test.Util.Orphans.Arbitrary ()

property_chunksBetween_is_never_empty :: ChunkNo -> ChunkNo -> Bool
property_chunksBetween_is_never_empty :: ChunkNo -> ChunkNo -> Bool
property_chunksBetween_is_never_empty ChunkNo
cn1 ChunkNo
cn2 =
  Bool -> Bool
not ([ChunkNo] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn1 ChunkNo
cn2))

property_chunksBetween_is_singleton_when_bounds_are_equal :: ChunkNo -> Property
property_chunksBetween_is_singleton_when_bounds_are_equal :: ChunkNo -> Property
property_chunksBetween_is_singleton_when_bounds_are_equal ChunkNo
cn =
  ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn ChunkNo
cn [ChunkNo] -> [ChunkNo] -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== [ChunkNo
cn]

property_chunksBetween_is_invariant_to_argument_order :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_is_invariant_to_argument_order :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_is_invariant_to_argument_order ChunkNo
cn1 ChunkNo
cn2 =
  ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn1 ChunkNo
cn2 [ChunkNo] -> [ChunkNo] -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn2 ChunkNo
cn1

property_chunksBetween_result_is_sorted :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_is_sorted :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_is_sorted ChunkNo
cn1 ChunkNo
cn2 =
  let result :: [ChunkNo]
result = ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn1 ChunkNo
cn2
   in [ChunkNo]
result [ChunkNo] -> [ChunkNo] -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== [ChunkNo] -> [ChunkNo]
forall a. Ord a => [a] -> [a]
sort [ChunkNo]
result

property_chunksBetween_result_length_indicates_inclusive_bounds :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_length_indicates_inclusive_bounds :: ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_length_indicates_inclusive_bounds cn1 :: ChunkNo
cn1@(ChunkNo Word64
a) cn2 :: ChunkNo
cn2@(ChunkNo Word64
b) =
  let expected :: Integer
expected = Integer
1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer
forall a. Num a => a -> a
abs (Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger Word64
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger Word64
b)
      observed :: Integer
observed = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ [ChunkNo] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (ChunkNo -> ChunkNo -> [ChunkNo]
chunksBetween ChunkNo
cn1 ChunkNo
cn2)
   in Integer
observed Integer -> Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Integer
expected

tests :: TestTree
tests :: TestTree
tests =
  TestName -> [TestTree] -> TestTree
testGroup
    TestName
"ImmutableDB chunking"
    [ TestName -> (ChunkNo -> ChunkNo -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"chunksBetween is never empty" ChunkNo -> ChunkNo -> Bool
property_chunksBetween_is_never_empty
    , TestName -> (ChunkNo -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty
        TestName
"chunksBetween is singleton when bounds are equal"
        ChunkNo -> Property
property_chunksBetween_is_singleton_when_bounds_are_equal
    , TestName -> (ChunkNo -> ChunkNo -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty
        TestName
"chunksBetween is invariant to argument order"
        ChunkNo -> ChunkNo -> Property
property_chunksBetween_is_invariant_to_argument_order
    , TestName -> (ChunkNo -> ChunkNo -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty
        TestName
"chunksBetween result is sorted"
        ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_is_sorted
    , TestName -> (ChunkNo -> ChunkNo -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty
        TestName
"chunksBetween result length indicates inclusive bounds"
        ChunkNo -> ChunkNo -> Property
property_chunksBetween_result_length_indicates_inclusive_bounds
    ]