packages feed

fuzzily-0.2.0.0: tests/tests.hs

module Main where

import Protolude (
  Bool (False, True),
  Char,
  IO,
  Int,
  Maybe (Just, Nothing),
  Monad (return),
  Ord ((>)),
  fst,
  head,
  identity,
  map,
  ($),
  (<$>),
 )

import Test.HUnit (Assertion, Test (..), runTestTT, (@?=))
import Text.Fuzzily as Fu (
  CaseSensitivity (HandleCase, IgnoreCase),
  Fuzzy (Fuzzy, original, rendered, score),
  filter,
  match,
  simpleFilter,
  test,
 )


from :: [Assertion] -> Test
from xs = TestList (map TestCase xs)


tests :: Test
tests =
  TestList
    [ TestLabel "test" $
        TestList
          [ TestLabel "returns true when fuzzy match" $
              from
                [ Fu.test "back" "imaback" @?= True
                , Fu.test "back" "bakck" @?= True
                , Fu.test "shig" "osh kosh modkhigow" @?= True
                , Fu.test "" "osh kosh modkhigow" @?= True
                ]
          , TestLabel "should return false when no fuzzy match" $
              from
                [ Fu.test "back" "abck" @?= False
                , Fu.test "okmgk" "osh kosh modkhigow" @?= False
                ]
          ]
    , TestLabel "match" $
        TestList
          [ TestLabel
              "returns a greater score for consecutive matches of pattern"
              $ from
                [ (>)
                    (Fu.score <$> Fu.match IgnoreCase ("", "") identity "abcd" "zabcd")
                    (Fu.score <$> Fu.match IgnoreCase ("", "") identity "abcd" "azbcd")
                    @?= True
                ]
          , TestLabel
              "returns the string as is if no pre/post and case sensitive"
              $ from
                [ Fu.rendered
                    <$> Fu.match
                      HandleCase
                      ("", "")
                      identity
                      "ab"
                      "ZaZbZ"
                      @?= Just "ZaZbZ"
                ]
          , TestLabel "returns Nothing on no match" $
              from
                [ Fu.match
                    IgnoreCase
                    ("", "")
                    identity
                    "ZEBRA!"
                    "ZaZbZ"
                    @?= Nothing
                ]
          , TestLabel "is case sensitive if specified" $
              from
                [ Fu.match
                    HandleCase
                    ("", "")
                    identity
                    "hask"
                    "Haskell"
                    @?= Nothing
                ]
          , TestLabel "wraps pre and post around matches" $
              from
                [ Fu.rendered
                    <$> Fu.match
                      HandleCase
                      ("<", ">")
                      identity
                      "brd"
                      "bread"
                      @?= Just "<b><r>ea<d>"
                ]
          ]
    , TestLabel "filter" $
        TestList
          [ TestLabel "returns list untouched when given empty pattern" $
              from
                [ ( Fu.original
                      `map` ( Fu.filter
                                HandleCase
                                ("", "")
                                identity
                                ""
                                ["abc", "def"]
                            )
                  )
                    @?= ["abc", "def"]
                ]
          , TestLabel "returns the highest score first" $
              from
                [ (@?=)
                    (head (Fu.filter HandleCase ("", "") identity "cb" ["cab", "acb"]))
                    (head (Fu.filter HandleCase ("", "") identity "cb" ["acb"]))
                ]
          , TestLabel "keeps original casing when filtering case insensitive" $
              from
                [ ( Fu.original
                      `map` ( Fu.filter
                                IgnoreCase
                                ("", "")
                                identity
                                "abc"
                                ["aBc"]
                            )
                  )
                    @?= ["aBc"]
                ]
          ]
    , TestLabel "README examples" $
        TestList
          [ TestLabel "hsk" $
              from
                [ ( match
                      IgnoreCase
                      ("<", ">")
                      fst
                      "hsk"
                      ("Haskell", 1995 :: Int)
                  )
                    @?= Just
                      ( Fuzzy
                          { original = ("Haskell", 1995)
                          , rendered = "<H>a<s><k>ell"
                          , score = 5
                          }
                      )
                ]
          , TestLabel "langs" $
              from
                [ let
                    langs :: [([Char], Int)]
                    langs =
                      [ ("Standard ML", 1990)
                      , ("OCaml", 1996)
                      , ("Scala", 2003)
                      ]
                    result = filter IgnoreCase ("<", ">") fst "ML" langs
                    expected =
                      [ Fuzzy
                          { original = ("Standard ML", 1990)
                          , rendered = "Standard <M><L>"
                          , score = 4
                          }
                      , Fuzzy
                          { original = ("OCaml", 1996)
                          , rendered = "OCa<m><l>"
                          , score = 4
                          }
                      ]
                  in
                    result @?= expected
                ]
          , TestLabel "simple filter" $
              from
                [ simpleFilter "vm" ["vim", "emacs", "virtual machine"]
                    @?= ["vim", "virtual machine"]
                ]
          , TestLabel "test" $
              from
                [test "brd" "bread" @?= True]
          ]
    ]


runTests :: IO ()
runTests = do
  _ <- runTestTT tests
  return ()


-- | For now, main will run our tests.
main :: IO ()
main = runTests