-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
314 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"env": { | ||
"node": true | ||
}, | ||
"rules": { | ||
"strict": true, | ||
"quotes": false, | ||
"no-use-before-define": "func", | ||
"no-unused-vars": [2, "all"], | ||
"no-mixed-requires": [1, true], | ||
"max-depth": [1, 5], | ||
"max-len": [1, 80, 4], | ||
"eqeqeq": false, | ||
"no-path-concat": false, | ||
"no-else-return": true, | ||
"no-eq-null": true, | ||
"no-lonely-if": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
node_modules/ | ||
out/ | ||
checkers.js | ||
checkers.js.map | ||
.repl/ | ||
target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules/ | ||
out/ | ||
checkers.js.map | ||
.repl/ | ||
target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,69 @@ | ||
# checkers | ||
ClojureScript's test.check packaged up for JavaScript | ||
|
||
Property-based testing for JavaScript via ClojureScript's [test.check](https://github.com/clojure/test.check). | ||
|
||
test.check is a Clojure property-based testing tool inspired by [QuickCheck](http://www.quviq.com/products/erlang-quickcheck/). The core idea of test.check is that instead of enumerating expected input and output for unit tests, you write properties about your function that should hold true for all inputs. This lets you write concise, powerful tests. | ||
|
||
Checkers brings the power of test.check to plain ol' JavaScript. | ||
|
||
# Install | ||
|
||
npm install checkers --save | ||
|
||
# Usage | ||
|
||
```js | ||
var checkers = require('checkers'); | ||
var gen = checkers.gen; | ||
|
||
// Property is incorrect | ||
checkers.forAll( | ||
[gen.int], | ||
function(i) { | ||
return i * i > i; | ||
} | ||
).check(1000); | ||
|
||
// Property is now correct | ||
checkers.forAll( | ||
[gen.int], | ||
function(i) { | ||
return i * i >= i; | ||
} | ||
).check(1000); | ||
|
||
// Check property with a particular seed | ||
checkers.forAll( | ||
[gen.int], | ||
function(i) { | ||
return i * i >= i; | ||
} | ||
).check(1000, {seed: 1422111938215}); | ||
``` | ||
|
||
## Documentation | ||
|
||
More coming soon! | ||
|
||
## TODO | ||
|
||
* Generator tests | ||
* Generator docs | ||
* Tutorial | ||
* Better examples | ||
|
||
## Development | ||
|
||
See `npm run` or `package.json` for a list of available scripts. | ||
|
||
You will need [leiningen](http://leiningen.org/) in order to build locally. | ||
|
||
## License | ||
|
||
Distributed under the Eclipse Public License. | ||
|
||
checkers is Copyright © 2015 Glen Mailer and contributors. | ||
|
||
[test.check](https://github.com/clojure/test.check/) is Copyright | ||
Rich Hickey, Reid Draper and contributors. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
(ns checkers | ||
(:require [cljs.test.check :as tc] | ||
[cljs.test.check.properties :as prop] | ||
[cljs.test.check.generators :as gen] | ||
[goog.object])) | ||
|
||
;; Interop utils | ||
(def format (aget (js/require "util") "format")) | ||
|
||
(defn- obj-seq | ||
"Seq from enumerable keys of a JS Object" | ||
[obj] | ||
(for [k (goog.object/getKeys obj)] | ||
[k (aget obj k)])) | ||
|
||
(defn- arrayify | ||
"Force a generator's output to be a JS array" | ||
[generator] | ||
(fn [& args] (gen/fmap into-array (apply generator args)))) | ||
|
||
(defn- obj-assoc [obj k v] (doto obj (aset (clj->js k) v))) | ||
(defn- into-object [associative] (reduce-kv obj-assoc #js {} associative)) | ||
(defn- objectify | ||
"Force a generator's output to be a JS object" | ||
[generator] | ||
(fn [& args] (gen/fmap into-object (apply generator args)))) | ||
|
||
;; Check API | ||
|
||
(defn format-args [arglist] | ||
(.join (into-array (map #(format "%j" %) arglist)) ",")) | ||
|
||
(defn generate-message | ||
[{:keys [num-tests fail seed] | ||
{:keys [smallest]} :shrunk}] | ||
(format "Failed after %d test(s)\nInput: %s\nShrunk to: %s\nSeed: %s" | ||
num-tests (format-args fail) (format-args smallest) seed)) | ||
|
||
(defn check | ||
"Wrap up quick-check to take options as a JS object and throw on failure" | ||
[property n & [opts]] | ||
(let [opts (apply concat (js->clj opts :keywordize-keys true)) | ||
{:keys [result] :as r} (apply tc/quick-check n property opts)] | ||
(if-not result | ||
(let [ex (js/Error. (generate-message r))] | ||
(aset ex "result" (clj->js r)) | ||
(throw ex))))) | ||
|
||
(aset js/exports "forAll" | ||
(fn [& args] | ||
(let [p (apply prop/for-all* args)] | ||
(aset p "check" #(check p %1 %2)) | ||
p))) | ||
|
||
(aset js/exports "sample" (comp into-array gen/sample)) | ||
|
||
;; Generator API | ||
|
||
(aset js/exports "gen" #js {}) | ||
|
||
|
||
(aset js/exports "gen" "fmap" gen/fmap) | ||
(aset js/exports "gen" "return" gen/return) | ||
(aset js/exports "gen" "bind" gen/bind) | ||
|
||
; Combinators & Helpers | ||
(aset js/exports "gen" "resize" gen/resize) | ||
(aset js/exports "gen" "choose" gen/choose) | ||
(aset js/exports "gen" "oneOf" gen/one-of) | ||
(aset js/exports "gen" "frequency" gen/frequency) | ||
(aset js/exports "gen" "elements" gen/elements) | ||
(aset js/exports "gen" "suchThat" gen/such-that) | ||
(aset js/exports "gen" "notEmpty" gen/not-empty) | ||
(aset js/exports "gen" "noShrink" gen/no-shrink) | ||
(aset js/exports "gen" "shrink2" gen/shrink-2) | ||
|
||
; Data Types | ||
(aset js/exports "gen" "boolean" gen/boolean) | ||
(aset js/exports "gen" "tuple" (arrayify gen/tuple)) | ||
|
||
(aset js/exports "gen" "int" gen/int) | ||
(aset js/exports "gen" "nat" gen/nat) | ||
(aset js/exports "gen" "posInt" gen/pos-int) | ||
(aset js/exports "gen" "negInt" gen/neg-int) | ||
(aset js/exports "gen" "sPosInt" gen/s-pos-int) | ||
(aset js/exports "gen" "sNegInt" gen/s-neg-int) | ||
|
||
(aset js/exports "gen" "array" (arrayify gen/vector)) | ||
(aset js/exports "gen" "shuffle" (arrayify gen/shuffle)) | ||
|
||
(aset js/exports "gen" "obj" (objectify gen/map)) | ||
(def ^:private gen-hash-map (objectify gen/hash-map)) | ||
(aset js/exports "gen" "object" | ||
(fn [obj] (apply gen-hash-map (apply concat (obj-seq obj))))) | ||
|
||
(aset js/exports "gen" "char" gen/char) | ||
(aset js/exports "gen" "charAscii" gen/char-ascii) | ||
(aset js/exports "gen" "charAlphanum" gen/char-alphanumeric) | ||
(aset js/exports "gen" "charAlpha" gen/char-alpha) | ||
|
||
(aset js/exports "gen" "string" gen/string) | ||
(aset js/exports "gen" "stringAscii" gen/string-ascii) | ||
(aset js/exports "gen" "stringAlphanum" gen/string-alphanumeric) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// This file was generated by the ClojureScript compiler. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "checkers", | ||
"version": "0.9.0", | ||
"description": "Property-based testing for JavaScript via ClojureScript's test.check", | ||
"main": "checkers.js", | ||
"scripts": { | ||
"clean": "lein clean", | ||
"build": "lein cljsbuild once release", | ||
"build-dev": "lein cljsbuild once dev", | ||
"dev": "lein cljsbuild auto dev", | ||
"test": "mocha", | ||
"repl": "./scripts/repl", | ||
"prepublish": "npm run clean && npm run build" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/glenjamin/checkers.git" | ||
}, | ||
"keywords": [ | ||
"test", | ||
"testing", | ||
"property-based", | ||
"quickcheck" | ||
], | ||
"author": "Glen Mailer <[email protected]>", | ||
"license": "EPL", | ||
"bugs": { | ||
"url": "https://github.com/glenjamin/checkers/issues" | ||
}, | ||
"homepage": "https://github.com/glenjamin/checkers", | ||
"devDependencies": { | ||
"lodash": "^2.4.1", | ||
"mocha": "^2.1.0", | ||
"source-map-support": "^0.2.9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
(defproject checkers "0.9.0-SNAPSHOT" | ||
:description "Property-based testing for JavaScript via ClojureScript's test.check" | ||
:url "https://github.com/glenjamin/checkers" | ||
|
||
:dependencies [[org.clojure/clojure "1.6.0"] | ||
[org.clojure/clojurescript "0.0-2665"] | ||
[org.clojure/test.check "0.7.0"]] | ||
|
||
:plugins [[lein-cljsbuild "1.0.4"]] | ||
|
||
:source-paths ["cljs"] | ||
|
||
:clean-targets ["out" "checkers.js" "checkers.js.map"] | ||
|
||
:cljsbuild { | ||
:builds [{:id "dev" | ||
:source-paths ["cljs"] | ||
:compiler {:output-to "checkers.js" | ||
:output-dir "out/dev" | ||
:preamble ["notice.txt"] | ||
:optimizations :simple | ||
:pretty-print true | ||
:cache-analysis true | ||
:source-map "checkers.js.map" | ||
:language-in :ecmascript5 | ||
:language-out :ecmascript5}} | ||
{:id "release" | ||
:source-paths ["cljs"] | ||
:compiler {:output-to "checkers.js" | ||
:output-dir "out/release" | ||
:preamble ["notice.txt"] | ||
:optimizations :advanced | ||
:pretty-print true | ||
:cache-analysis true | ||
:language-in :ecmascript5 | ||
:language-out :ecmascript5}}]}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/sh | ||
rlwrap lein trampoline run -m clojure.main scripts/repl.clj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
(require | ||
'[cljs.repl :as repl] | ||
'[cljs.repl.node :as node]) | ||
|
||
(repl/repl* (node/repl-env) | ||
{:output-dir "out/repl" | ||
:optimizations :none | ||
:cache-analysis true | ||
:source-map true}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/*eslint-env mocha */ | ||
var _ = require('lodash'); | ||
|
||
var checkers = require('..'); | ||
var gen = checkers.gen; | ||
|
||
describe("checkers", function() { | ||
it("checks that squaring makes things bigger or the same", function() { | ||
checkers.forAll( | ||
[gen.int], | ||
function(i) { | ||
return i * i >= i; | ||
} | ||
).check(1000); | ||
}); | ||
it("checks Array.sort is the same as _.sortBy on strings", function() { | ||
checkers.forAll( | ||
[gen.array(gen.int)], | ||
function(arr) { | ||
var lodash = _.sortBy(arr, function(x) { return '' + x; }); | ||
var stdlib = arr.slice(); | ||
stdlib.sort(); | ||
return _.isEqual(stdlib, lodash); | ||
} | ||
).check(100); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
--require test/source-map-support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require('source-map-support').install(); |