-
-
Notifications
You must be signed in to change notification settings - Fork 389
/
Copy pathFuzzySearch.hs
52 lines (48 loc) · 2 KB
/
FuzzySearch.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
module FuzzySearch (tests) where
import Data.Maybe (isJust, mapMaybe)
import Data.Text (Text)
import qualified Data.Text as Text
import Prelude hiding (filter)
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import Text.Fuzzy.Parallel
tests :: TestTree
tests =
testGroup
"Fuzzy search"
[ testGroup "match"
[ testCase "empty" $
match "" "" @?= Just 0
, testCase "camel case" $
match "myImportantField" "myImportantField" @?= Just 262124
, testCase "a" $
mapMaybe (matchInput "a") ["", "a", "aa", "aaa", "A", "AA", "aA", "Aa"]
@?= [("a",3),("aa",3),("aaa",3),("aA",3),("Aa",1)]
, testCase "lowercase words" $
mapMaybe (matchInput "abc") ["abc", "abcd", "axbc", "axbxc", "def"]
@?= [("abc", 25), ("abcd", 25), ("axbc", 7), ("axbxc", 5)]
, testCase "lower upper mix" $
mapMaybe (matchInput "abc") ["abc", "aBc", "axbC", "axBxC", "def"]
@?= [("abc", 25), ("aBc", 25), ("axbC", 7), ("axBxC", 5)]
, testCase "prefixes" $
mapMaybe (matchInput "alpha") (Text.inits "alphabet")
@?= [("alpha", 119), ("alphab", 119), ("alphabe", 119), ("alphabet", 119)]
, testProperty "x `isSubsequenceOf` y => match x y returns Just"
prop_matchIfSubsequence
]
]
where
matchInput :: Text -> Text -> Maybe (Text, Int)
matchInput needle candidate = (candidate,) <$> match needle candidate
prop_matchIfSubsequence :: Property
prop_matchIfSubsequence =
forAll genNonEmptyText $ \haystack ->
forAll (genSubsequence haystack) $ \needle ->
isJust (match needle haystack)
where
genNonEmptyText =
Text.pack <$> listOf1 (elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'])
genSubsequence :: Text -> Gen Text
genSubsequence =
fmap Text.pack . sublistOf . Text.unpack