diff --git a/src/Jack/Runner.js b/src/Jack/Runner.js index ec3a775..ffd03b1 100644 --- a/src/Jack/Runner.js +++ b/src/Jack/Runner.js @@ -1,29 +1,33 @@ "use strict"; exports.findProperties = function (module) { - return function () { - var properties = {}; - var exports = require(module); + return function (tuple) { + return function () { + var properties = {}; + var badPropertyNames = []; + var exports = require(module); - for (var name in exports) { - if (name.startsWith("prop_")) { - var property = exports[name]; + for (var name in exports) { + if (name.startsWith("prop_")) { + var property = exports[name]; - if (typeof property !== "object") { - // not an object, so not a property test - continue; - } + if (typeof property !== "object") { + // not an object, so not a property test + badPropertyNames.push(name); + continue; + } - if (!property.hasOwnProperty("Property :: Gen Result")) { - // 'Property :: Gen Result' field was missing, so not a property test - continue; - } + if (!property.hasOwnProperty("Property :: Gen Result")) { + // 'Property :: Gen Result' field was missing, so not a property test + continue; + } - properties[name] = property; + properties[name] = property; + } } - } - return properties; + return tuple(badPropertyNames)(properties); + }; }; }; diff --git a/src/Jack/Runner.purs b/src/Jack/Runner.purs index 396001e..6fefda4 100644 --- a/src/Jack/Runner.purs +++ b/src/Jack/Runner.purs @@ -4,10 +4,12 @@ module Jack.Runner ( , checkModules ) where +import Data.Traversable (for) import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log) import Control.Monad.Eff.Random (RANDOM) +import Data.Tuple.Nested (type (/\), (/\)) import Data.StrMap (StrMap) import Data.StrMap as StrMap import Data.Array as Array @@ -24,13 +26,29 @@ jackMain modules = do checkModule :: forall e. String -> Eff ("random" :: RANDOM, "console" :: CONSOLE | e) Boolean checkModule moduleName = do let + rat ns = do + log "" + log "*** Warning ***" + _ <- for ns $ \n -> do + log $ "- " <> n <> " starts with prop_ but is not of type Property" + log "" + log " You may be trying to define something like:" + log " prop_example :: Int -> Property" + log "" + log " Jack doesn't have Arbitrary like QuickCheck, and so cannot automatically provide" + log " property inputs in the same way; it uses forAll instead." + log " See https://github.com/jystic/purescript-jack#getting-started for some property" + log " examples to get started with." + log "" pyjamas b1 name prop = do log $ "=== " <> name <> " from " <> moduleName <> " ===" b2 <- check prop log $ "" pure $ b1 && b2 - props <- findProperties moduleName + (badPropNames /\ props) <- findProperties moduleName (/\) + + when (not <<< Array.null $ badPropNames) $ rat badPropNames StrMap.foldM pyjamas true props checkModules :: forall e. Array String -> Eff ("random" :: RANDOM, "console" :: CONSOLE | e) Boolean @@ -41,6 +59,10 @@ checkModules modules = in Array.foldM loop true modules -foreign import findProperties :: forall e. String -> Eff e (StrMap Property) +foreign import findProperties :: + forall e a b. + String -> + (a -> b -> a /\ b) -> + Eff e (Array String /\ StrMap Property) foreign import exit :: forall e. Int -> Eff e Unit diff --git a/test/Foo.purs b/test/Foo.purs index 287adb0..f4db5a0 100644 --- a/test/Foo.purs +++ b/test/Foo.purs @@ -102,3 +102,7 @@ prop_even_strings_end_with_evens = property false Just x -> property $ elem x evens + +prop_bad :: Int -> Property +prop_bad n = + property $ elem n [1,2,3]