UNPKG

26.3 kBMarkdownView Raw
1# JSVerify
2
3<img src="https://raw.githubusercontent.com/jsverify/jsverify/master/jsverify-300.png" align="right" height="100" />
4
5> Property based checking. Like QuickCheck.
6
7[![Build Status](https://secure.travis-ci.org/jsverify/jsverify.svg?branch=master)](http://travis-ci.org/jsverify/jsverify)
8[![NPM version](https://badge.fury.io/js/jsverify.svg)](http://badge.fury.io/js/jsverify)
9[![Dependency Status](https://david-dm.org/jsverify/jsverify.svg)](https://david-dm.org/jsverify/jsverify)
10[![devDependency Status](https://david-dm.org/jsverify/jsverify/dev-status.svg)](https://david-dm.org/jsverify/jsverify#info=devDependencies)
11[![Code Climate](https://img.shields.io/codeclimate/github/jsverify/jsverify.svg)](https://codeclimate.com/github/jsverify/jsverify)
12
13## Getting Started
14
15Install the module with: `npm install jsverify`
16
17## Synopsis
18
19```js
20var jsc = require("jsverify");
21
22// forall (f : bool -> bool) (b : bool), f (f (f b)) = f(b).
23var boolFnAppliedThrice =
24 jsc.forall("bool -> bool", "bool", function (f, b) {
25 return f(f(f(b))) === f(b);
26 });
27
28jsc.assert(boolFnAppliedThrice);
29// OK, passed 100 tests
30```
31
32## Documentation
33
34### Usage with [mocha](http://visionmedia.github.io/mocha/)
35
36Using jsverify with mocha is easy, just define the properties and use `jsverify.assert`.
37
38Starting from version 0.4.3 you can write your specs without any boilerplate:
39
40```js
41describe("sort", function () {
42 jsc.property("idempotent", "array nat", function (arr) {
43 return _.isEqual(sort(sort(arr)), sort(arr));
44 });
45});
46```
47
48You can also provide `--jsverifyRngState state` command line argument, to run tests with particular random generator state.
49
50```
51$ mocha examples/nat.js
52
531) natural numbers are less than 90:
54 Error: Failed after 49 tests and 1 shrinks. rngState: 074e9b5f037a8c21d6; Counterexample: 90;
55
56$ mocha examples/nat.js --grep 'are less than' --jsverifyRngState 074e9b5f037a8c21d6
57
581) natural numbers are less than 90:
59 Error: Failed after 1 tests and 1 shrinks. rngState: 074e9b5f037a8c21d6; Counterexample: 90;
60```
61
62Errorneous case is found with first try.
63
64### Usage with [jasmine](http://pivotal.github.io/jasmine/)
65
66Check [jasmineHelpers.js](helpers/jasmineHelpers.js) and [jasmineHelpers2.js](helpers/jasmineHelpers2.js) for jasmine 1.3 and 2.0 respectively.
67
68## API Reference
69
70> _Testing shows the presence, not the absence of bugs._
71>
72> Edsger W. Dijkstra
73
74To show that propositions hold, we need to construct proofs.
75There are two extremes: proof by example (unit tests) and formal (machine-checked) proof.
76Property-based testing is somewhere in between.
77We formulate propositions, invariants or other properties we believe to hold, but
78only test it to hold for numerous (randomly generated) values.
79
80Types and function signatures are written in [Coq](http://coq.inria.fr/)/[Haskell](http://www.haskell.org/haskellwiki/Haskell) influented style:
81C# -style `List<T> filter(List<T> v, Func<T, bool> predicate)` is represented by
82`filter(v: array T, predicate: T -> bool): array T` in our style.
83
84Methods and objects live in `jsc` object, e.g. `shrink.bless` method is used by
85```js
86var jsc = require("jsverify");
87var foo = jsc.shrink.bless(...);
88```
89
90Methods starting with `.dot` are prototype methods:
91```js
92var arb = jsc.nat;
93var arb2 = jsc.nat.smap(f, g);
94```
95
96`jsverify` can operate with both synchronous and asynchronous-promise properties.
97Generally every property can be wrapped inside [functor](http://learnyouahaskell.com/functors-applicative-functors-and-monoids),
98for now in either identity or promise functor, for synchronous and promise properties respectively.
99
100### Properties
101
102- `forall(arbs: arbitrary a ..., userenv: (map arbitrary)?, prop : a -> property): property`
103
104 Property constructor
105
106- `check (prop: property, opts: checkoptions?): result`
107
108 Run random checks for given `prop`. If `prop` is promise based, result is also wrapped in promise.
109
110 Options:
111 - `opts.tests` - test count to run, default 100
112 - `opts.size` - maximum size of generated values, default 50
113 - `opts.quiet` - do not `console.log`
114 - `opts.rngState` - state string for the rng
115
116 The `result` is `true` if check succeeds, otherwise it's an object with various fields:
117 - `counterexample` - an input for which property fails.
118 - `tests` - number of tests run before failing case is found
119 - `shrinks` - number of shrinks performed
120 - `exc` - an optional exception thrown by property function
121 - `rngState` - random number generator's state before execution of the property
122
123- `assert(prop: property, opts: checkoptions?) : void`
124
125 Same as `check`, but throw exception if property doesn't hold.
126
127- `property(name: string, ...)`
128
129 Assuming there is globally defined `it`, the same as:
130
131 ```js
132 it(name, function () {
133 jsc.assert(jsc.forall(...));
134 }
135 ```
136
137 You can use `property` to write facts too:
138 ```js
139 jsc.property("+0 === -0", function () {
140 return +0 === -0;
141 });
142 ```
143
144- `compile(desc: string, env: typeEnv?): arbitrary a`
145
146 Compile the type describiption in provided type environment, or default one.
147
148- `sampler(arb: arbitrary a, genSize: nat = 10): (sampleSize: nat?) -> a`
149
150 Create a sampler for a given arbitrary with an optional size. Handy when used in
151 a REPL:
152 ```
153 > jsc = require('jsverify') // or require('./lib/jsverify') w/in the project
154 ...
155 > jsonSampler = jsc.sampler(jsc.json, 4)
156 [Function]
157 > jsonSampler()
158 0.08467432763427496
159 > jsonSampler()
160 [ [ [] ] ]
161 > jsonSampler()
162 ''
163 > sampledJson(2)
164 [-0.4199344692751765, false]
165 ```
166
167### Types
168
169- `generator a` is a function `(size: nat) -> a`.
170- `show` is a function `a -> string`.
171- `shrink` is a function `a -> [a]`, returning *smaller* values.
172- `arbitrary a` is a triple of generator, shrink and show functions.
173 - `{ generator: nat -> a, shrink : a -> array a, show: a -> string }`
174
175### Blessing
176
177We chose to respresent generators and shrinks by functions, yet we would
178like to have additional methods on them. Thus we *bless* objects with
179additional properties.
180
181Usually you don't need to bless anything explicitly, as all combinators
182return blessed values.
183
184See [perldoc for bless](http://perldoc.perl.org/functions/bless.html).
185
186### DSL for input parameters
187
188There is a small DSL to help with `forall`. For example the two definitions below are equivalent:
189```js
190var bool_fn_applied_thrice = jsc.forall("bool -> bool", "bool", check);
191var bool_fn_applied_thrice = jsc.forall(jsc.fn(jsc.bool()), jsc.bool(), check);
192```
193
194The DSL is based on a subset of language recognized by [typify-parser](https://github.com/phadej/typify-parser):
195- *identifiers* are fetched from the predefined environment.
196- *applications* are applied as one could expect: `"array bool"` is evaluated to `jsc.array(jsc.bool)`.
197- *functions* are supported: `"bool -> bool"` is evaluated to `jsc.fn(jsc.bool)`.
198- *square brackets* are treated as a shorthand for the array type: `"[nat]"` is evaluated to `jsc.array(jsc.nat)`.
199- *union*: `"bool | nat"` is evaulated to `jsc.oneof(jsc.bool, jsc.nat)`.
200 - **Note** `oneof` cannot be shrinked, because the union is untagged, we don't know which shrink to use.
201- *anonymous records*: `"{ b: bool; n: nat}"` is evaluated to `jsc.record({ n: jsc.bool, n: jsc.nat })`.
202
203### Arbitrary data
204
205- `.smap(f: a -> b, g: b -> a, newShow: (b -> string)?): arbitrary b`
206
207 Transform `arbitrary a` into `arbitrary b`. For example:
208
209 `g` should be a [right inverse](http://en.wikipedia.org/wiki/Surjective_function#Surjections_as_right_invertible_functions) of `f`, but doesn't need to be complete inverse.
210 i.e. i.e. `f` doesn't need to be invertible, only surjective.
211
212 ```js
213 var positiveIntegersArb = nat.smap(
214 function (x) { return x + 1; },
215 function (x) { return x - 1; });
216 ```
217
218 ```js
219 var setNatArb = jsc.array(jsc.nat).smap(_.uniq, _.identity);
220 ```
221
222 Right inverse means that *f(g(y)) = y* for all *y* in *Y*. Here *Y* is a type of **arrays of unique natural numbers**. For them
223 ```js
224 _.uniq(_.identity(y)) = _.uniq(y) = y
225 ```
226
227 Opposite: *g(f(x))* for all *x* in *X*, doesn't need to hold. *X* is **arrays of natural numbers**:
228 ```js
229 _.identity(_uniq([0, 0])) = [0]] != [0, 0]
230 ```
231
232 We need an inverse for shrinking, and there right inverse is enough. We can always *pull back* `smap`ped value and shrink the preimage, and *map* or *push forward* shrinked preimages again.
233
234- `bless(arb: {...}): arbitrary a`
235
236 Bless almost arbitrary structure to be proper arbitrary. *Note*: this function mutates argument.
237
238 #### Example:
239
240 ```js
241 var arbTokens = jsc.bless({
242 generator: function () {
243 switch (jsc.random(0, 2)) {
244 case 0: return "foo";
245 case 1: return "bar";
246 case 2: return "quux";
247 }
248 }
249 });
250 ```
251
252### Primitive arbitraries
253
254- `integer: arbitrary integer`
255- `integer(maxsize: nat): arbitrary integer`
256- `integer(minsize: integer, maxsize: integer): arbitrary integer`
257
258 Integers, ℤ
259
260- `nat: arbitrary nat`
261- `nat(maxsize: nat): arbitrary nat`
262
263 Natural numbers, ℕ (0, 1, 2...)
264
265- `number: arbitrary number`
266- `number(maxsize: number): arbitrary number`
267- `number(min: number, max: number): arbitrary number`
268
269 JavaScript numbers, "doubles", ℝ. `NaN` and `Infinity` are not included.
270
271- `uint8: arbitrary nat`
272- `uint16: arbitrary nat`
273- `uint32: arbitrary nat`
274
275- `int8: arbitrary integer`
276- `int16: arbitrary integer`
277- `int32: arbitrary integer`
278
279- `bool: arbitrary bool`
280
281 Booleans, `true` or `false`.
282
283- `datetime: arbitrary datetime`
284
285 Random datetime
286
287- `elements(args: array a): arbitrary a`
288
289 Random element of `args` array.
290
291- `falsy: arbitrary *`
292
293 Generates falsy values: `false`, `null`, `undefined`, `""`, `0`, and `NaN`.
294
295- `constant(x: a): arbitrary a`
296
297 Returns an unshrinkable arbitrary that yields the given object.
298
299### Arbitrary combinators
300
301- `nonshrink(arb: arbitrary a): arbitrary a`
302
303 Non shrinkable version of arbitrary `arb`.
304
305- `unit: arbitrary ()`
306
307- `either(arbA: arbitrary a, arbB : arbitrary b): arbitrary (either a b)`
308
309- `pair(arbA: arbitrary a, arbB : arbitrary b): arbitrary (pair a b)`
310
311 If not specified `a` and `b` are equal to `value()`.
312
313- `tuple(arbs: (arbitrary a, arbitrary b...)): arbitrary (a, b...)`
314
315- `dict(arb: arbitrary a): arbitrary (dict a)`
316
317 Generates a JavaScript object with properties of type `A`.
318
319- `array(arb: arbitrary a): arbitrary (array a)`
320
321- `nearray(arb: arbitrary a): arbitrary (array a)`
322
323- `json: arbitrary json`
324
325 JavaScript Objects: boolean, number, string, array of `json` values or object with `json` values.
326
327- `oneof(gs : array (arbitrary a)...) : arbitrary a`
328
329 Randomly uses one of the given arbitraries.
330
331### Arbitrary records
332
333- `record(spec: { key: arbitrary a... }, userenv: env?): arbitrary { key: a... }`
334
335 Generates a javascript object with given record spec.
336
337- `generator.record(gen: { key: generator a... }): generator { key: a... }`
338
339- `shrink.record(shrs: { key: shrink a... }): shrink { key: a... }`
340
341### Arbitrary strings
342
343- `char: arbitrary char` &mdash; Single character
344
345- `asciichar: arbitrary char` &mdash; Single ascii character (0x20-0x7e inclusive, no DEL)
346
347- `string: arbitrary string`
348
349- `nestring: arbitrary string` &mdash; Generates strings which are not empty.
350
351- `asciistring: arbitrary string`
352
353- `asciinestring: arbitrary string`
354
355### Arbitrary functions
356
357- `fn(arb: arbitrary a): arbitrary (b -> a)`
358- `fun(arb: arbitrary a): arbitrary (b -> a)`
359
360### Small arbitraries
361
362- `generator.small(gen: generator a): generator a`
363- `small(arb: arbitrary a): arbitrary a`
364
365Create a generator (abitrary) which will generate smaller values, i.e. generator's `size` parameter is decreased logarithmically.
366
367```js
368jsc.property("small array of small natural numbers", "small (array nat)", function (arr) {
369 return Array.isArray(arr);
370});
371
372jsc.property("small array of normal natural numbers", "(small array) nat", function (arr) {
373 return Array.isArray(arr);
374});
375```
376
377### Generator functions
378
379A generator function, `generator a`, is a function `(size: nat) -> a`, which generates a value of given size.
380
381Generator combinators are auto-curried:
382
383```js
384var xs = jsc.generator.array(jsc.nat.generator, 1); // ≡
385var ys = jsc.generator.array(jsc.nat.generator)(1);
386```
387
388In purely functional approach `generator a` would be explicitly stateful computation:
389`(size: nat, rng: randomstate) -> (a, randomstate)`.
390*JSVerify* uses an implicit random number generator state,
391but the value generation is deterministic (tests reproduceable),
392if the primitives from *random* module are used.
393
394- `generator.bless(f: nat -> a): generator a`
395
396 Bless function with `.map` and `.flatmap` properties.
397
398- `.map(f: a -> b): generator b`
399
400 Map `generator a` into `generator b`. For example:
401
402 ```js
403 positiveIntegersGenerator = nat.generator.map(
404 function (x) { return x + 1; });
405 ```
406
407- `.flatmap(f: a -> generator b): generator b`
408
409 Monadic bind for generators. Also `flatMap` version is supported.
410
411- `generator.constant(x: a): generator a`
412
413- `generator.combine(gen: generator a..., f: a... -> b): generator b`
414
415- `generator.oneof(gens: list (generator a)): generator a`
416
417- `generator.recursive(genZ: generator a, genS: generator a -> generator a): generator a`
418
419- `generator.pair(genA: generator a, genB: generator b): generator (a, b)`
420
421- `generator.either(genA: generator a, genB: generator b): generator (either a b)`
422
423- `generator.unit: generator ()`
424
425 `unit` is an empty tuple, i.e. empty array in JavaScript representation. This is useful as a building block.
426
427- `generator.tuple(gens: (generator a, generator b...)): generator (a, b...)`
428
429- `generator.array(gen: generator a): generator (array a)`
430
431- `generator.nearray(gen: generator a): generator (array a)`
432
433- `generator.dict(gen: generator a): generator (dict a)`
434
435### Shrink functions
436
437A shrink function, `shrink a`, is a function `a -> [a]`, returning an array of *smaller* values.
438
439Shrink combinators are auto-curried:
440
441```js
442var xs = jsc.shrink.array(jsc.nat.shrink, [1]); // ≡
443var ys = jsc.shrink.array(jsc.nat.shrink)([1]);
444```
445
446- `shrink.bless(f: a -> [a]): shrink a`
447
448 Bless function with `.smap` property.
449
450- `.smap(f: a -> b, g: b -> a): shrink b`
451
452 Transform `shrink a` into `shrink b`. For example:
453
454 ```js
455 positiveIntegersShrink = nat.shrink.smap(
456 function (x) { return x + 1; },
457 function (x) { return x - 1; });
458 ```
459
460- `shrink.noop: shrink a`
461
462- `shrink.pair(shrA: shrink a, shrB: shrink b): shrink (a, b)`
463
464- `shrink.either(shrA: shrink a, shrB: shrink b): shrink (either a b)`
465
466- `shrink.tuple(shrs: (shrink a, shrink b...)): shrink (a, b...)`
467
468- `shrink.array(shr: shrink a): shrink (array a)`
469
470- `shrink.nearray(shr: shrink a): shrink (nearray a)`
471
472### Show functions
473
474- `show.def(x : a): string`
475
476 Currently implemented as `JSON.stringify`.
477
478- `show.pair(showA: a -> string, showB: b -> string, x: (a, b)): string`
479
480- `show.either(showA: a -> string, showB: b -> string, e: either a b): string`
481
482- `show.tuple(shrinks: (a -> string, b -> string...), x: (a, b...)): string`
483
484- `show.array(shrink: a -> string, x: array a): string`
485
486### Random functions
487
488- `random(min: int, max: int): int`
489
490 Returns random int from `[min, max]` range inclusively.
491
492 ```js
493 getRandomInt(2, 3) // either 2 or 3
494 ```
495
496- `random.number(min: number, max: number): number`
497
498 Returns random number from `[min, max)` range.
499
500### either
501
502- `either.left(value: a): either a b`
503
504- `either.right(value: b): either a b`
505
506- `either.either(l: a -> x, r: b -> x): x`
507
508- `either.isEqual(other: either a b): bool`
509
510 TODO: add `eq` optional parameter
511
512- `either.bimap(f: a -> c, g: b -> d): either c d`
513
514 ```js
515 either.bimap(compose(f, g), compose(h, i)) ≡ either.bimap(g, i).bimap(f, h);
516 ```
517
518- `either.first(f: a -> c): either c b`
519
520 ```js
521 either.first(f) ≡ either.bimap(f, utils.identity)
522 ```
523
524- `either.second(g: b -> d): either a d`
525
526 ```js
527 either.second(g) === either.bimap(utils.identity, g)
528 ```
529
530### Utility functions
531
532Utility functions are exposed (and documented) only to make contributions to jsverify more easy.
533The changes here don't follow semver, i.e. there might be backward-incompatible changes even in patch releases.
534
535Use [underscore.js](http://underscorejs.org/), [lodash](https://lodash.com/), [ramda](http://ramda.github.io/ramdocs/docs/), [lazy.js](http://danieltao.com/lazy.js/) or some other utility belt.
536
537- `utils.isEqual(x: json, y: json): bool`
538
539 Equality test for `json` objects.
540
541- `utils.isApproxEqual(x: a, y: b, opts: obj): bool`
542
543 Tests whether two objects are approximately and optimistically equal.
544 Returns `false` only if they are distinguisable not equal.
545 This function works with cyclic data.
546
547 Takes optional 'opts' parameter with properties:
548
549 - `fnEqual` - whether all functions are considered equal (default: yes)
550 - `depth` - how deep to recurse until treating as equal (default: 5)
551
552- `utils.force(x: a | () -> a) : a`
553
554 Evaluate `x` as nullary function, if it is one.
555
556- `utils.merge(x... : obj): obj`
557
558 Merge two objects, a bit like `_.extend({}, x, y)`.
559
560## FAQ
561
562### Why do all the examples import the library as jsc instead of jsv?
563
564Does JSC originate with [JSCheck](http://www.jscheck.org/)?
565
566**A:** Yes
567
568### smap requires an inverse function, which isn't always practical. Is this complexity related to shrinking?
569
570**A:** Yes. We don't want to give an easy-to-use interface which forgets
571shrinking altogether. Note, that *right* inverse is enough, which is most
572likely easy to write, even *complete* inverse doesn't exist.
573
574## Contributing
575
576- `README.md` is generated from the source with [ljs](https://github.com/phadej/ljs)
577- `jsverify.standalone.js` is also generated by the build process
578- Before creating a pull request run `make test`, yet travis will do it for you.
579
580## Release History
581
582- **0.6.0** &mdash; *2015-06-19* &mdash; Minor but major release!
583 - added `jsc.utils.isApproxEqual`
584- **0.6.0-beta.2** &mdash; *2015-05-31* &mdash; Beta!
585 - Fix issue [#113](https://github.com/jsverify/jsverify/issues/113) - Shrink of tuple with arrays failed.
586- **0.6.0-beta.1** &mdash; *2015-05-04* &mdash; Beta!
587 - FAQ section
588 - Improved `smap` documentation
589 - `flatmap` is also `flatMap`
590 - Fix function arbitrary
591 - `small` arbitraries
592 - `jsc.generator.record`
593 - Thanks to @peterjoel for reporting issues
594- **0.6.0-alpha.6** &mdash; *2015-04-25* &mdash; Fix issues #98
595 - Documentation imporovements
596 - Fix issue [#98](https://github.com/jsverify/jsverify/issues/98) - error while generating `int32` values
597- **0.6.0-alpha.5** &mdash; *2015-04-23* &mdash; Fix issue #99
598 - Documentation improvements
599 - Fix issue #99 (`suchthat` shrink)
600- **0.6.0-alpha.4** &mdash; *2015-04-26* &mdash; Fix issue #87
601 - jsc.property didn't fail with asynchronous properties
602 - thanks @Ezku for reporting
603- **0.6.0-alpha.3** &mdash; *2015-04-24* &mdash; promise shrink fixed
604- **0.6.0-alpha.2** &mdash; *2015-04-24* &mdash; jsc.bless
605 - Added `jsc.bless`
606- **0.6.0-alpha.1** &mdash; *2015-04-22* &mdash; Preview
607 - Using lazy sequences for shrink results
608 - *Breaking changes:*
609 - `jsc.map` renamed to `jsc.dict`
610 - `jsc.value` removed, use `jsc.json`
611 - `jsc.string()` removed, use `jsc.string`
612 - `shrink.isomap` renamed to `shrink.smap`
613- **0.5.3** &mdash; *2015-04-21* &mdash; More algebra
614 - `unit` and `either` arbitraries
615 - `arbitrary.smap` to help creating compound data
616- **0.5.2** &mdash; *2015-04-10* &mdash; `show.def` -change
617- **0.5.1** &mdash; *2015-02-19* &mdash; Dependencies bump
618 - We also work on 0.12 and iojs!
619- **0.5.0** &mdash; *2014-12-24* &mdash; Merry Chrismas 2014!
620 - Documention cleanup
621- **0.5.0-beta.2** &mdash; *2014-12-21* &mdash; Beta 2!
622 - Pair &amp; tuple related code cleanup
623 - Update `CONTRIBUTING.md`
624 - Small documentation type fixes
625 - Bless `jsc.elements` shrink
626- **0.5.0-beta.1** &mdash; *2014-12-20* &mdash; Beta!
627 - `bless` don't close over (uses `this`)
628 - Cleanup generator module
629 - Other code cleanup here and there
630- **0.4.6** &mdash; *2014-11-30* &mdash; better shrinks &amp; recursive
631 - Implemented shrinks: [#51](https://github.com/jsverify/jsverify/issues/51)
632 - `jsc.generator.recursive`: [#37](https://github.com/jsverify/jsverify/issues/37)
633 - array, nearray &amp; map generators return a bit smaller results (*log2* of size)
634- **0.4.5** &mdash; *2014-11-22* &mdash; stuff
635 - `generator.combine` &amp; `.flatmap`
636 - `nat`, `integer`, `number` &amp; and `string` act as objects too
637- **0.4.4** &mdash; *2014-11-22* &mdash; new generators
638 - New generators: `nearray`, `nestring`
639 - `generator.constant`
640 - zero-ary `jsc.property` (it ∘ assert)
641 - `jsc.sampler`
642- **0.4.3** &mdash; *2014-11-08* &mdash; jsc.property
643 - Now you can write your bdd specs without any boilerplate
644 - support for nat-litearls in dsl [#36](https://github.com/jsverify/jsverify/issues/36)
645 ```js
646 describe("Math.abs", function () {
647 jsc.property("result is non-negative", "integer 100", function (x) {
648 return Math.abs(x) >= 0;
649 });
650 });
651 ```
652 - Falsy generator [#42](https://github.com/jsverify/jsverify/issues/42)
653- **0.4.2** &mdash; *2014-11-03* &mdash; User environments for DSL
654 - User environments for DSL
655 - Generator prototype `map`, and shrink prototype `isomap`
656 - JSON generator works with larger sizes
657- **0.4.1** Move to own organization in GitHub
658- **0.4.0** &mdash; *2014-10-27* &mdash; typify-dsl &amp; more arbitraries.
659 Changes from **0.3.6**:
660 - DSL for `forall` and `suchthat`
661 - new primitive arbitraries
662 - `oneof` behaves as in QuickCheck (BREAKING CHANGE)
663 - `elements` is new name of old `oneof`
664 - Other smaller stuff under the hood
665- **0.4.0**-beta.4 generator.oneof
666- **0.4.0**-beta.3 Expose shrink and show modules
667- **0.4.0**-beta.2 Move everything around
668 - Better looking README.md!
669- **0.4.0**-beta.1 Beta!
670 - Dev Dependencies update
671- **0.4.0**-alpha8 oneof &amp; record -dsl support
672 - also `jsc.compile`
673 - record is shrinkable!
674- **0.4.0**-alpha7 oneof &amp; record
675 - *oneof* and *record* generator combinators ([@fson](https://github.com/fson))
676 - Fixed uint\* generators
677 - Default test size increased to 10
678 - Numeric generators with size specified are independent of test size ([#20](https://github.com/phadej/jsverify/issues/20))
679- **0.4.0**-alpha6 more primitives
680 - int8, int16, int32, uint8, uint16, uint32
681 - char, asciichar and asciistring
682 - value &rarr; json
683 - use eslint
684- **0.4.0**-alpha5 move david to be devDependency
685- **0.4.0**-alpha4 more typify
686 - `suchchat` supports typify dsl
687 - `oneof` &rarr; `elements` to be in line with QuickCheck
688 - Added versions of examples using typify dsl
689- **0.4.0**-alpha3 David, npm-freeze and jscs
690- **0.4.0**-alpha2 Fix typo in readme
691- **0.4.0**-alpha1 typify
692 - DSL for `forall`
693 ```js
694 var bool_fn_applied_thrice = jsc.forall("bool -> bool", "bool", check);
695 ```
696
697 - generator arguments, which are functions are evaluated. One can now write:
698 ```js
699 jsc.forall(jsc.nat, check) // previously had to be jsc.nat()
700 ```
701
702- **0.3.6** map generator
703- **0.3.5** Fix forgotten rngState in console output
704- **0.3.4** Dependencies update
705- **0.3.3** Dependencies update
706- **0.3.2** `fun` &rarr; `fn`
707- **0.3.1** Documentation typo fixes
708- **0.3.0** Major changes
709 - random generate state handling
710 - `--jsverifyRngState` parameter value used when run on node
711 - karma tests
712 - use make
713 - dependencies update
714- **0.2.0** Use browserify
715- **0.1.4** Mocha test suite
716 - major cleanup
717- **0.1.3** gen.show and exception catching
718- **0.1.2** Added jsc.assert
719- **0.1.1** Use grunt-literate
720- **0.1.0** Usable library
721- **0.0.2** Documented preview
722- **0.0.1** Initial preview
723
724## Related work
725
726### JavaScript
727
728- [JSCheck](http://www.jscheck.org/)
729- [claire](https://npmjs.org/package/claire)
730- [gent](https://npmjs.org/package/gent)
731- [fatcheck](https://npmjs.org/package/fatcheck)
732- [quickcheck](https://npmjs.org/package/quickcheck)
733- [qc.js](https://bitbucket.org/darrint/qc.js/)
734- [quick\_check](https://www.npmjs.org/package/quick_check)
735- [gencheck](https://github.com/graue/gentest)
736- [node-quickcheck](https://github.com/mcandre/node-quickcheck)
737
738### Others
739
740- [Wikipedia - QuickCheck](http://en.wikipedia.org/wiki/QuickCheck)
741- [Haskell - QuickCheck](http://hackage.haskell.org/package/QuickCheck) [Introduction](http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck1)
742- [Erlang - QuviQ](http://www.quviq.com/index.html)
743- [Erlang - triq](https://github.com/krestenkrab/triq)
744- [Scala - ScalaCheck](https://github.com/rickynils/scalacheck)
745- [Clojure - test.check](https://github.com/clojure/test.check)
746- [Python - Hypothesis](https://github.com/DRMacIver/hypothesis)
747
748The MIT License (MIT)
749
750Copyright (c) 2013-2015 Oleg Grenrus
751
752Permission is hereby granted, free of charge, to any person obtaining a copy
753of this software and associated documentation files (the "Software"), to deal
754in the Software without restriction, including without limitation the rights
755to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
756copies of the Software, and to permit persons to whom the Software is
757furnished to do so, subject to the following conditions:
758
759The above copyright notice and this permission notice shall be included in
760all copies or substantial portions of the Software.
761
762THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
763IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
764FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
765AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
766LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
767OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
768THE SOFTWARE.