{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Main (main) where import Data.Bytes (Bytes) import Data.Bytes.Metrics (levenshteinWithTolerance) import Data.Word (Word8) import Test.Tasty (TestTree, defaultMain, testGroup) import Test.Tasty.QuickCheck (Arbitrary (..), discard, testProperty, (===)) import qualified Data.Bytes as Bytes import qualified Data.Bytes.Text.Ascii as Ascii import qualified Data.Primitive as Prim import qualified Test.Tasty.QuickCheck as TQC main :: IO () main = defaultMain tests tests :: TestTree tests = testGroup "Tests" [ testGroup "sanity properties" [ testProperty "commutative" $ \a b -> let d = levenshteinWithTolerance 100 a b d' = levenshteinWithTolerance 100 b a in d === d' , testProperty "non-negative" $ \a b -> case levenshteinWithTolerance 100 a b of Nothing -> discard Just d -> d >= 0 , testProperty "zero distance to self" $ \t a -> levenshteinWithTolerance (abs t) a a === Just 0 , testProperty "distance to empty is length" $ \a -> let d = Bytes.length a in levenshteinWithTolerance d a Bytes.empty === Just d ] , testGroup "golden tests" [ testProperty "hellofworld" $ let a = Ascii.fromString "hello world" b = Ascii.fromString "hellofworld" in levenshteinWithTolerance 10 a b == Just 1 , testProperty "xyzzy" $ let a = Ascii.fromString "xyzzy" b = Ascii.fromString "syzygy" in levenshteinWithTolerance 10 a b == Just 3 ] ] instance Arbitrary Bytes where arbitrary = do bs :: [Word8] <- TQC.arbitrary pure $ Bytes.fromByteArray $ Prim.byteArrayFromList bs