<commit_before>module Test.StrongCheck
  ( Result(..)
  , class Testable, test
  , quickCheck
  , quickCheck'
  , quickCheckWithSeed
  , quickCheckPure
  , smallCheck
  , smallCheckPure
  , statCheck
  , statCheckPure
  , assert
  , assertEq, (===)
  , assertNotEq, (/==)
  , annotate, (<?>)
  , module Exports
  )
  where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Effect.Exception (throwException, error)
import Control.Monad.Free (Free)
import Control.Monad.Trampoline (runTrampoline)

import Data.Array as A
import Data.Foldable (class Foldable)
import Data.Int as Int
import Data.Lazy (Lazy)
import Data.List (List(..), length)
import Data.List as List
import Data.Maybe (maybe)
import Data.Tuple (Tuple(..))

import Math as Math

import Test.StrongCheck.Arbitrary (class Arbitrary, arbitrary)
import Test.StrongCheck.Gen (GenT, Gen, GenState(..), collectAll, sample', decorateSeed)
import Test.StrongCheck.LCG (Seed, randomSeed, runSeed)

import Test.StrongCheck.Arbitrary (class Arbitrary, arbitrary, class Coarbitrary, coarbitrary) as Exports
import Test.StrongCheck.LCG (Seed, mkSeed) as Exports

-- | The result of a property test.
data Result = Success | Failed String

derive instance eqResult :: Eq Result
derive instance ordResult :: Ord Result

instance showResult :: Show Result where
  show Success = "Success"
  show (Failed msg) = "Failed: " <> msg

instance semigroupResult :: Semigroup Result where
  append Success Success = Success
  append (Failed msg) Success = Failed msg
  append Success (Failed msg) = Failed msg
  append (Failed m1) (Failed m2) = Failed (m1 <> "\n" <> m2)

instance monoidResult :: Monoid Result where
  mempty = Success

-- | A class for types that can be treated as a property test result.
class Testable prop where
  test :: prop -> Gen Result

instance testableBoolean :: Testable Boolean where
  test true = pure Success
  test false = pure $ Failed "Test returned false"

instance testableResult :: Testable Result where
  test = pure

instance testableFunction :: (Arbitrary t, Testable prop) => Testable (t -> prop) where
  test f = test <<< f =<< arbitrary

instance testableGen :: Testable prop => Testable (GenT (Free Lazy) prop) where
  test = flip bind test

-- | Checks the proposition for 100 random values.
quickCheck :: forall prop. Testable prop => prop -> Effect Unit
quickCheck prop = quickCheck' 100 prop

-- | Checks the proposition for the specified number of random values.
quickCheck' :: forall prop. Testable prop => Int -> prop -> Effect Unit
quickCheck' n prop = do
  seed <- randomSeed
  quickCheckWithSeed seed n prop

-- | Checks the proposition for the specified number of random values, starting with a specific seed.
quickCheckWithSeed :: forall prop. Testable prop => Seed -> Int -> prop -> Effect Unit
quickCheckWithSeed seed n prop = check (quickCheckPure n seed) prop

-- | Checks the proposition for the specified number of random values in a pure
-- | setting, returning an array of results.
quickCheckPure :: forall prop. Testable prop => Int -> Seed -> prop -> Array (Tuple Seed Result)
quickCheckPure n s prop = runTrampoline $ sample' n (defState s) (decorateSeed (test prop))

-- | Exhaustively checks the proposition for all possible values. Assumes the
-- | generator is a finite generator.
smallCheck :: forall prop. Testable prop => prop -> Effect Unit
smallCheck prop = do
  seed <- randomSeed<commit_msg>simplified 'lazy' testable GenT instance<commit_after>module Test.StrongCheck
  ( Result(..)
  , class Testable, test
  , quickCheck
  , quickCheck'
  , quickCheckWithSeed
  , quickCheckPure
  , smallCheck
  , smallCheckPure
  , statCheck
  , statCheckPure
  , assert
  , assertEq, (===)
  , assertNotEq, (/==)
  , annotate, (<?>)
  , module Exports
  )
  where

import Prelude

import Control.Monad.Free (Free)
import Control.Monad.Trampoline (runTrampoline)
import Data.Array as A
import Data.Foldable (class Foldable)
import Data.Int as Int
import Data.List (List(..), length)
import Data.List as List
import Data.Maybe (maybe)
import Data.Tuple (Tuple(..))
import Effect (Effect)
import Effect.Console (log)
import Effect.Exception (throwException, error)
import Math as Math
import Test.StrongCheck.Arbitrary (class Arbitrary, arbitrary)
import Test.StrongCheck.Arbitrary (class Arbitrary, arbitrary, class Coarbitrary, coarbitrary) as Exports
import Test.StrongCheck.Gen (GenT, Gen, GenState(..), collectAll, sample', decorateSeed)
import Test.StrongCheck.LCG (Seed, mkSeed) as Exports
import Test.StrongCheck.LCG (Seed, randomSeed, runSeed)

-- | The result of a property test.
data Result = Success | Failed String

derive instance eqResult :: Eq Result
derive instance ordResult :: Ord Result

instance showResult :: Show Result where
  show Success = "Success"
  show (Failed msg) = "Failed: " <> msg

instance semigroupResult :: Semigroup Result where
  append Success Success = Success
  append (Failed msg) Success = Failed msg
  append Success (Failed msg) = Failed msg
  append (Failed m1) (Failed m2) = Failed (m1 <> "\n" <> m2)

instance monoidResult :: Monoid Result where
  mempty = Success

-- | A class for types that can be treated as a property test result.
class Testable prop where
  test :: prop -> Gen Result

instance testableBoolean :: Testable Boolean where
  test true = pure Success
  test false = pure $ Failed "Test returned false"

instance testableResult :: Testable Result where
  test = pure

instance testableFunction :: (Arbitrary t, Testable prop) => Testable (t -> prop) where
  test f = test <<< f =<< arbitrary

instance testableGen :: Testable prop => Testable (GenT (Free (Function Unit)) prop) where
  test genProp = 
    genProp >>= test

-- | Checks the proposition for 100 random values.
quickCheck :: forall prop. Testable prop => prop -> Effect Unit
quickCheck prop = quickCheck' 100 prop

-- | Checks the proposition for the specified number of random values.
quickCheck' :: forall prop. Testable prop => Int -> prop -> Effect Unit
quickCheck' n prop = do
  seed <- randomSeed
  quickCheckWithSeed seed n prop

-- | Checks the proposition for the specified number of random values, starting with a specific seed.
quickCheckWithSeed :: forall prop. Testable prop => Seed -> Int -> prop -> Effect Unit
quickCheckWithSeed seed n prop = check (quickCheckPure n seed) prop

-- | Checks the proposition for the specified number of random values in a pure
-- | setting, returning an array of results.
quickCheckPure :: forall prop. Testable prop => Int -> Seed -> prop -> Array (Tuple Seed Result)
quickCheckPure n s prop = runTrampoline $ sample' n (defState s) (decorateSeed (test prop))

-- | Exhaustively checks the proposition for all possible values. Assumes the
-- | generator is a finite generator.
smallCheck :: forall prop. Testable prop => prop -> Effect Unit
smallCheck prop = do
  seed <- randomSeed
{'fraction_non_alphanumeric': 0.09258453054709041, 'fraction_numerical': 0.002902336380786533, 'mean_word_length': 4.127976190476191, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7288293', 'n_tokens_mistral': 2040, 'n_tokens_neox': 1967, 'n_words': 809}