@@ -1,17 +1,24 @@
11{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE ScopedTypeVariables #-}
23
34module Main where
45
6+import Control.Applicative
57import Database.Bloodhound
68import Data.Aeson
9+import Data.List (nub)
10+import Data.List.NonEmpty (NonEmpty(..))
711import Data.Time.Calendar (Day(..))
812import Data.Time.Clock (secondsToDiffTime, UTCTime(..))
913import Data.Text (Text)
14+import qualified Data.Text as T
1015import GHC.Generics (Generic)
1116import Network.HTTP.Client
1217import qualified Network.HTTP.Types.Status as NHTS
1318import Prelude hiding (filter, putStrLn)
1419import Test.Hspec
20+import Test.Hspec.QuickCheck (prop)
21+import Test.QuickCheck
1522
1623testServer :: Server
1724testServer = Server "http://localhost:9200"
@@ -104,6 +111,27 @@ data BulkTest = BulkTest { name :: Text } deriving (Eq, Generic, Show)
104111instance FromJSON BulkTest
105112instance ToJSON BulkTest
106113
114+noDuplicates :: Eq a => [a] -> Bool
115+noDuplicates xs = nub xs == xs
116+
117+instance Arbitrary RegexpFlags where
118+ arbitrary = oneof [ pure AllRegexpFlags
119+ , pure NoRegexpFlags
120+ , SomeRegexpFlags <$> arbitrary
121+ ]
122+
123+instance Arbitrary a => Arbitrary (NonEmpty a) where
124+ arbitrary = liftA2 (:|) arbitrary arbitrary
125+
126+instance Arbitrary RegexpFlag where
127+ arbitrary = oneof [ pure AnyString
128+ , pure Automaton
129+ , pure Complement
130+ , pure Empty
131+ , pure Intersection
132+ , pure Interval
133+ ]
134+
107135main :: IO ()
108136main = hspec $ do
109137
@@ -314,7 +342,7 @@ main = hspec $ do
314342 it "returns document for regexp filter" $ do
315343 _ <- insertData
316344 let filter = RegexpFilter (FieldName "user") (Regexp "bite.*app")
317− (RegexpFlags "ALL") (CacheName "test") False (CacheKey "key")
345+ AllRegexpFlags (CacheName "test") False (CacheKey "key")
318346 let search = mkSearch Nothing (Just filter)
319347 myTweet <- searchTweet search
320348 myTweet `shouldBe` Right exampleTweet
@@ -322,7 +350,26 @@ main = hspec $ do
322350 it "doesn't return document for non-matching regexp filter" $ do
323351 _ <- insertData
324352 let filter = RegexpFilter (FieldName "user")
325− (Regexp "boy") (RegexpFlags "ALL")
353+ (Regexp "boy") AllRegexpFlags
326354 (CacheName "test") False (CacheKey "key")
327355 let search = mkSearch Nothing (Just filter)
328356 searchExpectNoResults search
357+ describe "ToJSON RegexpFlags" $ do
358+ it "generates the correct JSON for AllRegexpFlags" $
359+ toJSON AllRegexpFlags `shouldBe` String "ALL"
360+
361+ it "generates the correct JSON for NoRegexpFlags" $
362+ toJSON NoRegexpFlags `shouldBe` String "NONE"
363+
364+ it "generates the correct JSON for SomeRegexpFlags" $
365+ let flags = AnyString :| [ Automaton
366+ , Complement
367+ , Empty
368+ , Intersection
369+ , Interval ]
370+ in toJSON (SomeRegexpFlags flags) `shouldBe` String "ANYSTRING|AUTOMATON|COMPLEMENT|EMPTY|INTERSECTION|INTERVAL"
371+
372+ prop "removes duplicates from flags" $ \(flags :: RegexpFlags) ->
373+ let String str = toJSON flags
374+ flagStrs = T.splitOn "|" str
375+ in noDuplicates flagStrs