|
| 1 | +module Test.Frequency where |
| 2 | + |
| 3 | +import Prelude |
| 4 | + |
| 5 | +import Control.Monad.Gen (class MonadGen, frequency) |
| 6 | +import Control.Monad.State (State, class MonadState, get, put, evalStateT) |
| 7 | +import Data.Array (replicate, group', length) |
| 8 | +import Data.Array.NonEmpty (toNonEmpty) |
| 9 | +import Data.Newtype (unwrap) |
| 10 | +import Data.NonEmpty ((:|), NonEmpty(..)) |
| 11 | +import Data.Traversable (sequence) |
| 12 | +import Data.Tuple (Tuple(..)) |
| 13 | +import Effect (Effect) |
| 14 | +import Math (remainder) |
| 15 | +import Partial.Unsafe (unsafeCrashWith) |
| 16 | +import Test.Assert (assert) |
| 17 | + |
| 18 | +newtype TestGenFrequency a = TestGenFrequency (State Number a) |
| 19 | +derive newtype instance testGenFunctor :: Functor TestGenFrequency |
| 20 | +derive newtype instance testGenApply :: Apply TestGenFrequency |
| 21 | +derive newtype instance testGenBind :: Bind TestGenFrequency |
| 22 | +derive newtype instance testGenApplicative :: Applicative TestGenFrequency |
| 23 | +derive newtype instance testGenMonad :: Monad TestGenFrequency |
| 24 | +derive newtype instance testGenMonadState :: MonadState Number TestGenFrequency |
| 25 | + |
| 26 | +instance testGenMonadGen :: MonadGen TestGenFrequency where |
| 27 | + sized _ = unsafeCrashWith "sized should not be called" |
| 28 | + resize _ _ = unsafeCrashWith "resize should not be called" |
| 29 | + chooseBool = pure unit >>= \_ -> unsafeCrashWith "chooseBool should not be called" |
| 30 | + chooseFloat s e = do |
| 31 | + c <- get |
| 32 | + put (c + 1.0) |
| 33 | + pure ((s + c) `remainder` e) |
| 34 | + chooseInt _ _ = unsafeCrashWith "chooseFloat should not be called" |
| 35 | + |
| 36 | +runTestGenFrequency :: TestGenFrequency ~> State Number |
| 37 | +runTestGenFrequency (TestGenFrequency x) = x |
| 38 | + |
| 39 | +check :: Effect Unit |
| 40 | +check = |
| 41 | + let |
| 42 | + abcGen :: TestGenFrequency String |
| 43 | + abcGen = |
| 44 | + frequency $ |
| 45 | + ( Tuple 10.0 $ pure "A" ) :| |
| 46 | + [ Tuple 20.0 $ pure "B" |
| 47 | + , Tuple 0.0 $ pure "Z" |
| 48 | + , Tuple 30.0 $ pure "C" |
| 49 | + , Tuple 40.0 $ pure "D" |
| 50 | + , Tuple 50.0 $ pure "E" |
| 51 | + , Tuple 50.0 $ pure "F" |
| 52 | + ] |
| 53 | + abcArrGen = sequence $ replicate 200 abcGen |
| 54 | + abcArr = runTestGenFrequency abcArrGen `evalStateT` 0.0 # unwrap |
| 55 | + actual = group' abcArr <#> \nea -> case toNonEmpty nea of |
| 56 | + NonEmpty x xs -> Tuple (length xs + 1) x |
| 57 | + expected = |
| 58 | + [ (Tuple 10 "A") |
| 59 | + , (Tuple 20 "B") |
| 60 | + , (Tuple 30 "C") |
| 61 | + , (Tuple 40 "D") |
| 62 | + , (Tuple 50 "E") |
| 63 | + , (Tuple 50 "F") |
| 64 | + ] |
| 65 | + in |
| 66 | + assert (expected == actual) |
0 commit comments