packages feed

tahoe-chk-0.1.0.2: test/SpecUtil.hs

module SpecUtil where

import Hedgehog (Property, assert, diff, forAll, property)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range

import Test.Tasty (
    TestTree,
    testGroup,
 )
import Test.Tasty.HUnit (assertEqual, testCase)
import Test.Tasty.Hedgehog (testProperty)

import qualified Data.ByteString as BS

import Tahoe.Util (ceilDiv, chunkedBy)

tests :: TestTree
tests =
    testGroup
        "utilities"
        [ testProperty "BS.concat . chunkedBy n == id" prop_chunkedBy_identity
        , testProperty "The length of every result element, except sometimes the last, equals n" prop_chunkedBy_length
        , testCeilDiv
        ]

testCeilDiv :: TestTree
testCeilDiv = testCase "ceiling division" $ do
    assertEqual "evenly divisible" (ceilDiv 2 1) (2 :: Integer)
    assertEqual "needs rounding" (ceilDiv 3 2) (2 :: Integer)

prop_chunkedBy_identity :: Property
prop_chunkedBy_identity = property $ do
    someBytes <- forAll $ Gen.bytes (Range.linear 1 100)
    someSize <- forAll $ Gen.int (Range.linear 1 100)

    diff someBytes (==) (BS.concat . chunkedBy someSize $ someBytes)

prop_chunkedBy_length :: Property
prop_chunkedBy_length = property $ do
    someBytes <- forAll $ Gen.bytes (Range.linear 1 100)
    someSize <- forAll $ Gen.int (Range.linear 1 100)

    let chunks = chunkedBy someSize someBytes

        -- Handle the possibly-short element separately.
        equalSize = tail . reverse $ chunks
        short = last chunks

    -- All the rest should have the same length
    assert (all ((someSize ==) . BS.length) equalSize)

    -- And the last should just be no longer.
    assert (BS.length short <= someSize)