-- | Domain-specific Hedgehog generators. -- -- These are used in multiple test modules, so broken out here for clearer re-use. module Generator ( clientMessages , serverMessages , appIDs , phases , sides , offerMessages ) where import Protolude hiding (toS) import Protolude.Conv (toS) import Hedgehog (MonadGen(..)) import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import MagicWormhole.Internal.Messages ( ClientMessage(..) , ServerMessage(..) , MailboxMessage(..) , WelcomeMessage(..) , AppID(..) , Side(..) , MessageID(..) , Phase(..) , Body(..) , Nameplate(..) , Mailbox(..) , Mood(..) ) import qualified MagicWormhole.Internal.FileTransfer as F ( Offer(..) , DirectoryMode(..) ) clientMessages :: MonadGen m => m ClientMessage clientMessages = Gen.choice [ Bind <$> appIDs <*> sides , pure List , pure Allocate , Claim <$> genNameplates , Release <$> Gen.maybe genNameplates , Open <$> mailboxes , Add <$> phases <*> bodies , Close <$> Gen.maybe mailboxes <*> Gen.maybe moods , Ping <$> Gen.int Range.linearBounded ] messageIDs :: MonadGen m => m MessageID messageIDs = MessageID <$> Gen.int16 (Range.linear 0 maxBound) appIDs :: MonadGen m => m AppID appIDs = AppID <$> Gen.choice [ Gen.text (Range.linear 0 100) Gen.unicode , Gen.element [ "lothar.com/wormhole/text-or-file-xfer" , "tahoe-lafs.org/tahoe-lafs/v1" ] ] sides :: MonadGen m => m Side sides = Side <$> Gen.text (Range.linear 0 10) Gen.hexit phases :: MonadGen m => m Phase phases = Gen.choice [ pure PakePhase , pure VersionPhase , ApplicationPhase <$> Gen.int (Range.linear 0 maxBound) ] bodies :: MonadGen m => m Body bodies = Body <$> Gen.bytes (Range.linear 0 1024) genNameplates :: MonadGen m => m Nameplate genNameplates = Nameplate <$> Gen.text (Range.linear 0 10) Gen.unicode mailboxes :: MonadGen m => m Mailbox mailboxes = Mailbox <$> Gen.text (Range.singleton 13) alphaNum where alphaNum = Gen.element "abcdefghijklmnopqrstuvwxyz09123456789" moods :: MonadGen m => m Mood moods = Gen.element [ Happy, Lonely, Scary, Errory ] serverMessages :: MonadGen m => m ServerMessage serverMessages = Gen.choice [ Welcome <$> welcomeMessages , Nameplates <$> Gen.list (Range.linear 0 10) genNameplates , Allocated <$> genNameplates , Claimed <$> mailboxes , pure Released , Message <$> mailboxMessages , pure Closed , pure Ack , Pong <$> Gen.int Range.linearBounded , Error <$> Gen.text (Range.linear 0 100) Gen.unicode <*> clientMessages ] mailboxMessages :: MonadGen m => m MailboxMessage mailboxMessages = MailboxMessage <$> sides <*> phases <*> Gen.maybe messageIDs <*> bodies welcomeMessages :: MonadGen m => m WelcomeMessage welcomeMessages = WelcomeMessage <$> Gen.maybe (Gen.text (Range.linear 0 1024) Gen.unicode) <*> Gen.maybe (Gen.text (Range.linear 0 1024) Gen.unicode) directoryModes :: MonadGen m => m F.DirectoryMode directoryModes = Gen.choice [ return F.ZipFileDeflated ] offerMessages :: MonadGen m => m F.Offer offerMessages = Gen.choice [ F.Message <$> (Gen.text (Range.linear 0 1024) Gen.unicode) , F.File <$> toS <$> (Gen.text (Range.linear 0 100) Gen.unicode) <*> (fromIntegral <$> (Gen.int (Range.linear 0 maxBound))) , F.Directory <$> directoryModes -- (toS <$> (Gen.text (Range.linear 0 100) Gen.unicode)) <*> (toS <$> (Gen.text (Range.linear 0 100) Gen.unicode)) <*> (fromIntegral <$> (Gen.int (Range.linear 0 maxBound))) <*> (fromIntegral <$> (Gen.int (Range.linear 0 maxBound))) <*> (fromIntegral <$> (Gen.int (Range.linear 0 maxBound))) ]