{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} module TestsUtils.Generators where import qualified Data.Aeson.KeyMap as X import qualified Data.List as L import qualified Data.List.NonEmpty as NE import qualified Data.Map as M import qualified Data.Text as T import qualified Data.Versions as Versions import Database.Bloodhound import Generic.Random import TestsUtils.ApproxEq import TestsUtils.Import instance Arbitrary NominalDiffTime where arbitrary = fromInteger <$> arbitrary #if !MIN_VERSION_QuickCheck(2,8,0) instance (Arbitrary k, Ord k, Arbitrary v) => Arbitrary (M.Map k v) where arbitrary = M.fromList <$> arbitrary #endif instance Arbitrary Text where arbitrary = T.pack <$> arbitrary instance Arbitrary UTCTime where arbitrary = UTCTime <$> arbitrary <*> (fromRational . toRational <$> choose (0 :: Double, 86400)) instance Arbitrary Day where arbitrary = ModifiedJulianDay . (2000 +) <$> arbitrary shrink = (ModifiedJulianDay <$>) . shrink . toModifiedJulianDay #if !MIN_VERSION_QuickCheck(2,9,0) instance Arbitrary a => Arbitrary (NonEmpty a) where arbitrary = liftA2 (:|) arbitrary arbitrary #endif arbitraryScore :: Gen Score arbitraryScore = fmap getPositive <$> arbitrary instance (Arbitrary a, Typeable a) => Arbitrary (Hit a) where arbitrary = Hit <$> arbitrary <*> arbitrary <*> arbitraryScore <*> arbitrary <*> return Nothing <*> arbitrary <*> arbitrary <*> return Nothing instance Arbitrary HitFields where arbitrary = pure (HitFields M.empty) shrink = const [] instance Arbitrary HitsTotalRelation where arbitrary = oneof [pure HTR_EQ, pure HTR_GTE] instance Arbitrary HitsTotal where arbitrary = do tot <- getPositive <$> arbitrary relation_ <- arbitrary return $ HitsTotal tot relation_ instance (Arbitrary a, Typeable a) => Arbitrary (SearchHits a) where arbitrary = reduceSize $ do tot <- arbitrary score <- arbitraryScore hs <- arbitrary return $ SearchHits tot score hs reduceSize :: Gen a -> Gen a reduceSize f = sized $ \n -> resize (n `div` 2) f arbitraryAlphaNum :: Gen Char arbitraryAlphaNum = oneof [ choose ('a', 'z'), choose ('A', 'Z'), choose ('0', '9') ] instance Arbitrary RoutingValue where arbitrary = RoutingValue . T.pack <$> listOf1 arbitraryAlphaNum instance Arbitrary AliasRouting where arbitrary = oneof [ allAlias, one, theOther, both' ] where one = GranularAliasRouting <$> (Just <$> arbitrary) <*> pure Nothing theOther = GranularAliasRouting Nothing <$> (Just <$> arbitrary) both' = GranularAliasRouting <$> (Just <$> arbitrary) <*> (Just <$> arbitrary) allAlias = AllAliasRouting <$> arbitrary instance Arbitrary FieldName where arbitrary = FieldName . T.pack <$> listOf1 arbitraryAlphaNum #if MIN_VERSION_base(4,10,0) -- Test.QuickCheck.Modifiers qcNonEmptyToNonEmpty :: NonEmptyList a -> NonEmpty a qcNonEmptyToNonEmpty (NonEmpty (a : xs)) = (a :| xs) qcNonEmptyToNonEmpty (NonEmpty []) = error "NonEmpty was empty!" instance Arbitrary a => Arbitrary (NonEmpty a) where arbitrary = qcNonEmptyToNonEmpty <$> arbitrary #endif instance Arbitrary ScriptFields where arbitrary = pure $ ScriptFields $ X.fromList [] shrink = const [] instance Arbitrary ScriptParams where arbitrary = pure $ ScriptParams $ X.fromList [ ("a", Number 42), ("b", String "forty two") ] shrink = const [] instance Arbitrary RegexpFlags where arbitrary = oneof [ pure AllRegexpFlags, pure NoRegexpFlags, SomeRegexpFlags <$> genUniqueFlags ] where genUniqueFlags = NE.fromList . L.nub <$> listOf1 arbitrary instance Arbitrary IndexAliasCreate where arbitrary = IndexAliasCreate <$> arbitrary <*> reduceSize arbitrary instance Arbitrary Query where arbitrary = reduceSize $ oneof [ TermQuery <$> arbitrary <*> arbitrary, TermsQuery <$> arbitrary <*> arbitrary, QueryMatchQuery <$> arbitrary, QueryMultiMatchQuery <$> arbitrary, QueryBoolQuery <$> arbitrary, QueryBoostingQuery <$> arbitrary, QueryCommonTermsQuery <$> arbitrary, ConstantScoreQuery <$> arbitrary <*> arbitrary, QueryDisMaxQuery <$> arbitrary, QueryFuzzyLikeThisQuery <$> arbitrary, QueryFuzzyLikeFieldQuery <$> arbitrary, QueryFuzzyQuery <$> arbitrary, QueryHasChildQuery <$> arbitrary, QueryHasParentQuery <$> arbitrary, IdsQuery <$> arbitrary, QueryIndicesQuery <$> arbitrary, MatchAllQuery <$> arbitrary, QueryMoreLikeThisQuery <$> arbitrary, QueryMoreLikeThisFieldQuery <$> arbitrary, QueryNestedQuery <$> arbitrary, QueryPrefixQuery <$> arbitrary, QueryQueryStringQuery <$> arbitrary, QuerySimpleQueryStringQuery <$> arbitrary, QueryRangeQuery <$> arbitrary, QueryRegexpQuery <$> arbitrary ] -- TODO: Implement shrink -- shrink = genericShrink instance Arbitrary Filter where arbitrary = Filter <$> arbitrary shrink (Filter q) = Filter <$> shrink q instance Arbitrary ReplicaBounds where arbitrary = oneof [ replicasBounded, replicasLowerBounded, pure ReplicasUnbounded ] where replicasBounded = do Positive a <- arbitrary Positive b <- arbitrary return (ReplicasBounded a b) replicasLowerBounded = do Positive a <- arbitrary return (ReplicasLowerBounded a) instance Arbitrary NodeAttrName where arbitrary = NodeAttrName . T.pack <$> listOf1 arbitraryAlphaNum instance Arbitrary NodeAttrFilter where arbitrary = do n <- arbitrary xs <- listOf1 (listOf1 arbitraryAlphaNum) let (s, ss) = unpackConsPartial xs ts = T.pack <$> s :| ss return (NodeAttrFilter n ts) where -- listOf1 means this shouldn't blow up. unpackConsPartial (x : xs) = (x, xs) unpackConsPartial _ = error "unpackConsPartial failed but shouldn't have" #if MIN_VERSION_versions(6,0,0) instance Arbitrary VersionNumber where arbitrary = do chunks <- Versions.Chunks <$> arbitrary return $ VersionNumber $ Versions.Version Nothing chunks Nothing Nothing instance Arbitrary Versions.Chunk where arbitrary = oneof [ Versions.Numeric <$> arbitrary, do n <- chooseInt (1, 5) Versions.Alphanum . T.pack <$> replicateM n (chooseEnum ('a', 'z'))] #else instance Arbitrary VersionNumber where arbitrary = do chunks <- arbitrary return $ VersionNumber $ Versions.Version { Versions._vEpoch = Nothing, Versions._vChunks = chunks, Versions._vRel = [], Versions._vMeta = Nothing} instance Arbitrary Versions.VUnit where arbitrary = oneof [ Versions.Digits . fromIntegral <$> chooseInt (0, 1000), do n <- chooseInt (1, 5) Versions.Str . T.pack <$> replicateM n (chooseEnum ('a', 'z'))] #endif instance Arbitrary TemplateQueryKeyValuePairs where arbitrary = TemplateQueryKeyValuePairs . X.fromList <$> arbitrary shrink (TemplateQueryKeyValuePairs x) = map (TemplateQueryKeyValuePairs . X.fromList) . shrink $ X.toList x instance Arbitrary IndexName where arbitrary = do n <- chooseInt (5, 15) indewName <- T.pack <$> replicateM n (chooseEnum ('a', 'z')) return $ either (\e -> error $ "Invalid generated IndexName " <> show indewName <> ":" <> T.unpack e) id $ mkIndexName indewName deriving newtype instance Arbitrary DocId instance Arbitrary Version where arbitrary = genericArbitraryU deriving newtype instance Arbitrary BuildHash deriving newtype instance Arbitrary IndexAliasRouting deriving newtype instance Arbitrary ShardCount deriving newtype instance Arbitrary ReplicaCount deriving newtype instance Arbitrary TemplateName deriving newtype instance Arbitrary IndexPattern deriving newtype instance Arbitrary QueryString deriving newtype instance Arbitrary CacheName deriving newtype instance Arbitrary CacheKey deriving newtype instance Arbitrary Existence deriving newtype instance Arbitrary CutoffFrequency deriving newtype instance Arbitrary Analyzer deriving newtype instance Arbitrary MaxExpansions deriving newtype instance Arbitrary Lenient deriving newtype instance Arbitrary Tiebreaker deriving newtype instance Arbitrary Boost deriving newtype instance Arbitrary BoostTerms deriving newtype instance Arbitrary MinimumMatch deriving newtype instance Arbitrary DisableCoord deriving newtype instance Arbitrary IgnoreTermFrequency deriving newtype instance Arbitrary MinimumTermFrequency deriving newtype instance Arbitrary MaxQueryTerms instance Arbitrary Fuzziness where arbitrary = genericArbitraryU deriving newtype instance Arbitrary PrefixLength deriving newtype instance Arbitrary RelationName deriving newtype instance Arbitrary PercentMatch deriving newtype instance Arbitrary StopWord deriving newtype instance Arbitrary QueryPath deriving newtype instance Arbitrary AllowLeadingWildcard deriving newtype instance Arbitrary LowercaseExpanded deriving newtype instance Arbitrary EnablePositionIncrements deriving newtype instance Arbitrary AnalyzeWildcard deriving newtype instance Arbitrary GeneratePhraseQueries deriving newtype instance Arbitrary Locale deriving newtype instance Arbitrary MaxWordLength deriving newtype instance Arbitrary MinWordLength deriving newtype instance Arbitrary PhraseSlop deriving newtype instance Arbitrary MinDocFrequency deriving newtype instance Arbitrary MaxDocFrequency deriving newtype instance Arbitrary Regexp instance Arbitrary SimpleQueryStringQuery where arbitrary = genericArbitraryU instance Arbitrary FieldOrFields where arbitrary = genericArbitraryU instance Arbitrary SimpleQueryFlag where arbitrary = genericArbitraryU instance Arbitrary RegexpQuery where arbitrary = genericArbitraryU instance Arbitrary QueryStringQuery where arbitrary = genericArbitraryU instance Arbitrary RangeQuery where arbitrary = genericArbitraryU instance Arbitrary RangeValue where arbitrary = genericArbitraryU instance Arbitrary PrefixQuery where arbitrary = genericArbitraryU instance Arbitrary NestedQuery where arbitrary = genericArbitraryU instance Arbitrary MoreLikeThisFieldQuery where arbitrary = genericArbitraryU instance Arbitrary MoreLikeThisQuery where arbitrary = genericArbitraryU instance Arbitrary IndicesQuery where arbitrary = genericArbitraryU deriving newtype instance Arbitrary IgnoreUnmapped deriving newtype instance Arbitrary MinChildren deriving newtype instance Arbitrary MaxChildren deriving newtype instance Arbitrary AggregateParentScore instance Arbitrary HasParentQuery where arbitrary = genericArbitraryU instance Arbitrary HasChildQuery where arbitrary = genericArbitraryU instance Arbitrary FuzzyQuery where arbitrary = genericArbitraryU instance Arbitrary FuzzyLikeFieldQuery where arbitrary = genericArbitraryU instance Arbitrary FuzzyLikeThisQuery where arbitrary = genericArbitraryU instance Arbitrary DisMaxQuery where arbitrary = genericArbitraryU instance Arbitrary CommonTermsQuery where arbitrary = genericArbitraryU instance Arbitrary DistanceRange where arbitrary = genericArbitraryU instance Arbitrary MultiMatchQuery where arbitrary = genericArbitraryU instance Arbitrary LessThanD where arbitrary = genericArbitraryU instance Arbitrary LessThanEqD where arbitrary = genericArbitraryU instance Arbitrary GreaterThanD where arbitrary = genericArbitraryU instance Arbitrary GreaterThanEqD where arbitrary = genericArbitraryU instance Arbitrary LessThan where arbitrary = genericArbitraryU instance Arbitrary LessThanEq where arbitrary = genericArbitraryU instance Arbitrary GreaterThan where arbitrary = genericArbitraryU instance Arbitrary GreaterThanEq where arbitrary = genericArbitraryU instance Arbitrary GeoPoint where arbitrary = genericArbitraryU deriving newtype instance Arbitrary NullValue instance Arbitrary MinimumMatchHighLow where arbitrary = genericArbitraryU instance Arbitrary CommonMinimumMatch where arbitrary = genericArbitraryU instance Arbitrary BoostingQuery where arbitrary = genericArbitraryU instance Arbitrary BoolQuery where arbitrary = genericArbitraryU instance Arbitrary MatchQuery where arbitrary = genericArbitraryU instance Arbitrary MultiMatchQueryType where arbitrary = genericArbitraryU instance Arbitrary BooleanOperator where arbitrary = genericArbitraryU instance Arbitrary ZeroTermsQuery where arbitrary = genericArbitraryU instance Arbitrary MatchQueryType where arbitrary = genericArbitraryU instance Arbitrary SearchAliasRouting where arbitrary = genericArbitraryU instance Arbitrary ScoreType where arbitrary = genericArbitraryU instance Arbitrary Distance where arbitrary = genericArbitraryU instance Arbitrary DistanceUnit where arbitrary = genericArbitraryU instance Arbitrary DistanceType where arbitrary = genericArbitraryU instance Arbitrary OptimizeBbox where arbitrary = genericArbitraryU instance Arbitrary GeoBoundingBoxConstraint where arbitrary = genericArbitraryU instance Arbitrary GeoFilterType where arbitrary = genericArbitraryU instance Arbitrary GeoBoundingBox where arbitrary = genericArbitraryU instance Arbitrary LatLon where arbitrary = genericArbitraryU instance Arbitrary RangeExecution where arbitrary = genericArbitraryU instance Arbitrary RegexpFlag where arbitrary = genericArbitraryU instance Arbitrary BoolMatch where arbitrary = genericArbitraryU instance Arbitrary Term where arbitrary = genericArbitraryU instance Arbitrary IndexMappingsLimits where arbitrary = genericArbitraryU instance Arbitrary IndexSettings where arbitrary = genericArbitraryU instance Arbitrary TokenChar where arbitrary = genericArbitraryU instance Arbitrary Ngram where arbitrary = genericArbitraryU instance Arbitrary TokenizerDefinition where arbitrary = genericArbitraryU deriving newtype instance Arbitrary TokenFilter instance Arbitrary NgramFilter where arbitrary = genericArbitraryU instance Arbitrary EdgeNgramFilterSide where arbitrary = genericArbitraryU instance Arbitrary TokenFilterDefinition where arbitrary = genericArbitraryU instance Arbitrary Language where arbitrary = genericArbitraryU instance Arbitrary Shingle where arbitrary = genericArbitraryU deriving newtype instance Arbitrary CharFilter instance Arbitrary AnalyzerDefinition where arbitrary = genericArbitraryU -- TODO: This should have a proper generator that doesn't -- create garbage that has to be filtered out. instance Arbitrary CharFilterDefinition where arbitrary = oneof [ CharFilterDefinitionMapping . chomp <$> arbitrary, CharFilterDefinitionPatternReplace <$> arbitrary <*> arbitrary <*> arbitrary ] where chomp = M.map T.strip . M.mapKeys (T.replace "=>" "" . T.strip) instance Arbitrary Analysis where arbitrary = genericArbitraryU deriving newtype instance Arbitrary Tokenizer instance Arbitrary Compression where arbitrary = genericArbitraryU deriving newtype instance Arbitrary Bytes instance Arbitrary AllocationPolicy where arbitrary = genericArbitraryU instance Arbitrary InitialShardCount where arbitrary = genericArbitraryU instance Arbitrary FSType where arbitrary = genericArbitraryU instance Arbitrary CompoundFormat where arbitrary = genericArbitraryU instance Arbitrary FsSnapshotRepo where arbitrary = genericArbitraryU deriving newtype instance Arbitrary SnapshotRepoName instance Arbitrary DirectGeneratorSuggestModeTypes where arbitrary = genericArbitraryU instance Arbitrary DirectGenerators where arbitrary = genericArbitraryU instance Arbitrary PhraseSuggesterCollate where arbitrary = genericArbitraryU instance Arbitrary PhraseSuggesterHighlighter where arbitrary = genericArbitraryU deriving newtype instance Arbitrary Size instance Arbitrary PhraseSuggester where arbitrary = genericArbitraryU instance Arbitrary SuggestType where arbitrary = genericArbitraryU instance Arbitrary Suggest where arbitrary = genericArbitraryU instance Arbitrary FunctionScoreQuery where arbitrary = genericArbitraryU instance Arbitrary FunctionScoreFunction where arbitrary = genericArbitraryU instance Arbitrary FunctionScoreFunctions where arbitrary = genericArbitraryU instance Arbitrary ComponentFunctionScoreFunction where arbitrary = genericArbitraryU instance Arbitrary Script where arbitrary = genericArbitraryU deriving newtype instance Arbitrary ScriptLanguage instance Arbitrary ScriptSource where arbitrary = genericArbitraryU instance Arbitrary ScoreMode where arbitrary = genericArbitraryU instance Arbitrary BoostMode where arbitrary = genericArbitraryU deriving newtype instance Arbitrary Seed instance Arbitrary FieldValueFactor where arbitrary = genericArbitraryU deriving newtype instance Arbitrary Weight deriving newtype instance Arbitrary Factor deriving newtype instance Arbitrary FactorMissingFieldValue instance Arbitrary FactorModifier where arbitrary = genericArbitraryU instance Arbitrary UpdatableIndexSetting where arbitrary = resize 10 genericArbitraryU newtype UpdatableIndexSetting' = UpdatableIndexSetting' UpdatableIndexSetting deriving stock (Eq, Show, Typeable) deriving newtype (ToJSON, FromJSON, ApproxEq) instance Arbitrary UpdatableIndexSetting' where arbitrary = do settings <- arbitrary return $ UpdatableIndexSetting' $ case settings of RoutingAllocationInclude xs -> RoutingAllocationInclude (dropDuplicateAttrNames xs) RoutingAllocationExclude xs -> RoutingAllocationExclude (dropDuplicateAttrNames xs) RoutingAllocationRequire xs -> RoutingAllocationRequire (dropDuplicateAttrNames xs) x -> x where dropDuplicateAttrNames = NE.fromList . L.nubBy sameAttrName . NE.toList sameAttrName a b = nodeAttrFilterName a == nodeAttrFilterName b shrink (UpdatableIndexSetting' x) = map UpdatableIndexSetting' (shrink x) instance Arbitrary InnerHits where arbitrary = genericArbitraryU