packages feed

radixtree-0.6.0.0: test/Spec.hs

{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE ViewPatterns          #-}
import           Data.Attoparsec.Text
import           Data.Coerce
import           Data.List              (sortOn)
import qualified Data.RadixTree         as R
import qualified Data.Text              as T
import           Test.SmallCheck
import           Test.SmallCheck.Series
import           Test.Tasty
import           Test.Tasty.SmallCheck

sortOnLengthDesc :: [T.Text] -> [T.Text]
sortOnLengthDesc = sortOn (negate . T.length)

mkAlternatives :: NonEmpty (NonEmpty Char) -> [T.Text]
mkAlternatives = sortOnLengthDesc . map T.pack . coerce

naiiveSameAsRadix :: Monad m => Bool -> Property m
naiiveSameAsRadix doCompress =
  forAll $ \(mkAlternatives -> alternatives) ->
    let
      rparse
        | doCompress = R.parse_ $! R.fromFoldable_ alternatives
        | otherwise = case R.compressBy (T.concat alternatives) (R.fromFoldable_ alternatives) of
            Just crt -> R.parse_ $! crt
            Nothing  -> error "could not compress radixtree!"
    in forAll $ \(textS :: NonEmpty Char) ->
      let text = T.pack (coerce textS)
      in parseOnly (choice (map string alternatives)) text ==
         parseOnly rparse text

lookupSameishAsParse :: Property IO
lookupSameishAsParse =
  forAll $ \alternatives ->
  let
    !rt = R.fromFoldable_ (mkAlternatives alternatives)
    !p = R.parse_ rt <* endOfInput
  in forAll $ \(textS :: NonEmpty Char) ->
    let text = T.pack (coerce textS)
    in case (parseOnly p text, R.lookup_ rt text) of
      (Right x1, Just x2) -> x1 == x2
      (Left  _ , Nothing) -> True
      _                   -> False

main :: IO ()
main = defaultMain $ testGroup "radixtree"
  [ testProperty "naiive parsing has the same result as radix tree parsing" (naiiveSameAsRadix False)
  , testProperty "naiive parsing has the same result as radix tree parsing when compressed"
    (naiiveSameAsRadix True)
  , testProperty "lookup ~ parse" lookupSameishAsParse
  ]