{-| Module: Instances Description: Instances of Arbitrary for various types. In particular, stuff from: * "Capnp.Untyped.Pure" * "Capnp.Gen.Capnp.Schema.Pure" -} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE RecordWildCards #-} module Instances () where import Data.Word import Test.QuickCheck import Test.QuickCheck.Instances () import qualified Data.Vector as V import Capnp.Gen.Capnp.Schema.Pure import qualified Capnp.Untyped.Pure as PU -- Generate an arbitrary "unknown" tag, i.e. one with a value unassigned -- by the schema. The parameter is the number of tags assigned by the schema. arbitraryTag :: Word16 -> Gen Word16 arbitraryTag numTags = max numTags <$> arbitrary instance Arbitrary Node where shrink = genericShrink arbitrary = do id <- arbitrary displayName <- arbitrary displayNamePrefixLength <- arbitrary scopeId <- arbitrary parameters <- arbitrarySmallerVec isGeneric <- arbitrary nestedNodes <- arbitrarySmallerVec annotations <- arbitrarySmallerVec union' <- arbitrary pure Node{..} instance Arbitrary Node'SourceInfo where shrink = genericShrink arbitrary = do id <- arbitrary docComment <- arbitrary members <- arbitrarySmallerVec pure Node'SourceInfo{..} instance Arbitrary Node'SourceInfo'Member where shrink = genericShrink arbitrary = Node'SourceInfo'Member <$> arbitrary instance Arbitrary Node' where shrink = genericShrink arbitrary = oneof [ pure Node'file , Node'struct <$> arbitrary , Node'enum <$> arbitrary , Node'interface <$> arbitrary , Node'const <$> arbitrary , Node'annotation <$> arbitrary , Node'unknown' <$> arbitraryTag 6 ] instance Arbitrary Node'enum where shrink = genericShrink arbitrary = Node'enum' <$> arbitrarySmallerVec instance Arbitrary Node'struct where shrink = genericShrink arbitrary = do dataWordCount <- arbitrary pointerCount <- arbitrary preferredListEncoding <- arbitrary isGroup <- arbitrary discriminantCount <- arbitrary discriminantOffset <- arbitrary fields <- arbitrarySmallerVec pure Node'struct'{..} instance Arbitrary Node'interface where shrink = genericShrink arbitrary = Node'interface' <$> arbitrarySmallerVec <*> arbitrarySmallerVec instance Arbitrary Node'const where shrink = genericShrink arbitrary = Node'const' <$> arbitrary <*> arbitrary instance Arbitrary Node'annotation where shrink = genericShrink arbitrary = do type_ <- arbitrary targetsFile <- arbitrary targetsConst <- arbitrary targetsEnum <- arbitrary targetsEnumerant <- arbitrary targetsStruct <- arbitrary targetsField <- arbitrary targetsUnion <- arbitrary targetsGroup <- arbitrary targetsInterface <- arbitrary targetsMethod <- arbitrary targetsParam <- arbitrary targetsAnnotation <- arbitrary pure Node'annotation'{..} instance Arbitrary Node'NestedNode where shrink = genericShrink arbitrary = Node'NestedNode <$> arbitrary <*> arbitrary instance Arbitrary Field where shrink = genericShrink arbitrary = do name <- arbitrary codeOrder <- arbitrary annotations <- arbitrary discriminantValue <- arbitrary union' <- arbitrary ordinal <- arbitrary pure Field{..} instance Arbitrary Field' where shrink = genericShrink arbitrary = oneof [ Field'slot <$> arbitrary , Field'group <$> arbitrary ] instance Arbitrary Field'slot where shrink = genericShrink arbitrary = do offset <- arbitrary type_ <- arbitrary defaultValue <- arbitrary hadExplicitDefault <- arbitrary pure Field'slot'{..} instance Arbitrary Field'group where shrink = genericShrink arbitrary = Field'group' <$> arbitrary instance Arbitrary Field'ordinal where shrink = genericShrink arbitrary = oneof [ pure Field'ordinal'implicit , Field'ordinal'explicit <$> arbitrary ] instance Arbitrary Enumerant where shrink = genericShrink arbitrary = Enumerant <$> arbitrary <*> arbitrary <*> arbitrarySmallerVec instance Arbitrary Superclass where shrink = genericShrink arbitrary = Superclass <$> arbitrary <*> arbitrary instance Arbitrary Method where shrink = genericShrink arbitrary = do name <- arbitrary codeOrder <- arbitrary implicitParameters <- arbitrary paramStructType <- arbitrary paramBrand <- arbitrary resultStructType <- arbitrary resultBrand <- arbitrary annotations <- arbitrary pure Method{..} instance Arbitrary CapnpVersion where shrink = genericShrink arbitrary = CapnpVersion <$> arbitrary <*> arbitrary <*> arbitrary instance Arbitrary Node'Parameter where shrink = genericShrink arbitrary = Node'Parameter <$> arbitrary instance Arbitrary Brand where shrink = genericShrink arbitrary = Brand <$> arbitrarySmallerVec instance Arbitrary Brand'Scope where shrink = genericShrink arbitrary = Brand'Scope <$> arbitrary <*> arbitrary instance Arbitrary Brand'Scope' where shrink = genericShrink arbitrary = oneof [ Brand'Scope'bind <$> arbitrarySmallerVec , pure Brand'Scope'inherit , Brand'Scope'unknown' <$> arbitraryTag 2 ] instance Arbitrary Brand'Binding where shrink = genericShrink arbitrary = oneof [ pure Brand'Binding'unbound , Brand'Binding'type_ <$> arbitrary , Brand'Binding'unknown' <$> arbitraryTag 2 ] instance Arbitrary Value where shrink = genericShrink arbitrary = oneof [ pure Value'void , Value'bool <$> arbitrary , Value'int8 <$> arbitrary , Value'int16 <$> arbitrary , Value'int32 <$> arbitrary , Value'int64 <$> arbitrary , Value'uint8 <$> arbitrary , Value'uint16 <$> arbitrary , Value'uint32 <$> arbitrary , Value'uint64 <$> arbitrary , Value'float32 <$> arbitrary , Value'float64 <$> arbitrary , Value'text <$> arbitrary , Value'data_ <$> arbitrary , Value'list <$> arbitrary , Value'enum <$> arbitrary , Value'struct <$> arbitrary , pure Value'interface , Value'anyPointer <$> arbitrary , Value'unknown' <$> arbitraryTag 19 ] instance Arbitrary Annotation where shrink = genericShrink arbitrary = Annotation <$> arbitrary <*> arbitrary <*> arbitrary instance Arbitrary ElementSize where shrink = genericShrink arbitrary = oneof [ pure ElementSize'empty , pure ElementSize'bit , pure ElementSize'byte , pure ElementSize'twoBytes , pure ElementSize'fourBytes , pure ElementSize'eightBytes , pure ElementSize'pointer , pure ElementSize'inlineComposite , ElementSize'unknown' <$> arbitraryTag 8 ] instance Arbitrary Type'anyPointer where shrink = genericShrink arbitrary = oneof [ Type'anyPointer'unconstrained <$> arbitrary , Type'anyPointer'parameter <$> arbitrary , Type'anyPointer'implicitMethodParameter <$> arbitrary ] instance Arbitrary Type'anyPointer'unconstrained where shrink = genericShrink arbitrary = oneof [ pure Type'anyPointer'unconstrained'anyKind , pure Type'anyPointer'unconstrained'struct , pure Type'anyPointer'unconstrained'list , pure Type'anyPointer'unconstrained'capability ] instance Arbitrary Type'anyPointer'parameter where shrink = genericShrink arbitrary = Type'anyPointer'parameter' <$> arbitrary <*> arbitrary instance Arbitrary Type'anyPointer'implicitMethodParameter where shrink = genericShrink arbitrary = Type'anyPointer'implicitMethodParameter' <$> arbitrary instance Arbitrary Type where shrink = genericShrink arbitrary = oneof [ pure Type'void , pure Type'bool , pure Type'int8 , pure Type'int16 , pure Type'int32 , pure Type'int64 , pure Type'uint8 , pure Type'uint16 , pure Type'uint32 , pure Type'uint64 , pure Type'float32 , pure Type'float64 , pure Type'text , pure Type'data_ , Type'list <$> arbitrary , Type'enum <$> arbitrary , Type'struct <$> arbitrary , Type'interface <$> arbitrary , Type'anyPointer <$> arbitrary , Type'unknown' <$> arbitraryTag 21 ] instance Arbitrary Type'list where shrink = genericShrink arbitrary = Type'list' <$> arbitrary instance Arbitrary Type'enum where shrink = genericShrink arbitrary = Type'enum' <$> arbitrary <*> arbitrary instance Arbitrary Type'struct where shrink = genericShrink arbitrary = Type'struct' <$> arbitrary <*> arbitrary instance Arbitrary Type'interface where shrink = genericShrink arbitrary = Type'interface' <$> arbitrary <*> arbitrary instance Arbitrary CodeGeneratorRequest where shrink = genericShrink arbitrary = do capnpVersion <- arbitrary nodes <- arbitrarySmallerVec requestedFiles <- arbitrarySmallerVec sourceInfo <- arbitrarySmallerVec pure CodeGeneratorRequest{..} instance Arbitrary CodeGeneratorRequest'RequestedFile where shrink = genericShrink arbitrary = CodeGeneratorRequest'RequestedFile <$> arbitrary <*> arbitrary <*> arbitrary instance Arbitrary CodeGeneratorRequest'RequestedFile'Import where shrink = genericShrink arbitrary = CodeGeneratorRequest'RequestedFile'Import <$> arbitrary <*> arbitrary instance Arbitrary a => Arbitrary (PU.Slice a) where shrink = genericShrink arbitrary = PU.Slice <$> arbitrarySmallerVec arbitrarySmallerVec :: Arbitrary a => Gen (V.Vector a) arbitrarySmallerVec = sized $ \size -> do -- Make sure the elements are scaled down relative to -- the size of the vector: vec <- arbitrary :: Gen (V.Vector ()) let gen = resize (size `div` V.length vec) arbitrary traverse (const gen) vec instance Arbitrary PU.Struct where shrink = genericShrink arbitrary = sized $ \_ -> PU.Struct <$> arbitrary <*> arbitrary instance Arbitrary PU.List where shrink = genericShrink arbitrary = oneof [ PU.List0 <$> arbitrarySmallerVec , PU.List1 <$> arbitrarySmallerVec , PU.List8 <$> arbitrarySmallerVec , PU.List16 <$> arbitrarySmallerVec , PU.List32 <$> arbitrarySmallerVec , PU.List64 <$> arbitrarySmallerVec , PU.ListPtr <$> arbitrarySmallerVec , PU.ListStruct <$> arbitrarySmallerVec ] instance Arbitrary PU.Ptr where shrink (PU.PtrStruct s) = PU.PtrStruct <$> shrink s shrink (PU.PtrList l) = PU.PtrList <$> shrink l shrink (PU.PtrCap _) = [] arbitrary = oneof [ PU.PtrStruct <$> arbitrary , PU.PtrList <$> arbitrary -- We never generate capabilites, as we can't marshal Clients back in, -- so many of the invariants we check don't hold for caps. ]