Skip to content

Commit

Permalink
Let unexpected-check run more iterations when an error is found to im…
Browse files Browse the repository at this point in the history
…prove input shrinking
  • Loading branch information
sunesimonsen committed Jun 5, 2016
1 parent fb02c11 commit 190228e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
48 changes: 42 additions & 6 deletions documentation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,26 @@ Finally we make the assertion:
expect(function (arr) {
var sorted = sort(arr);
expect(sorted, 'to have length', arr.length);
expect(sort(arr), 'to be sorted');
expect(sorted, 'to be sorted');
}, 'to be valid for all', arrays);
```

But that assumption as actually not true as the build-in sort functions is based
on converting items to strings and comparing them. So you will get the following error:

```output
Ran 300 iterations and found 8 errors
Ran 1000 iterations and found 14 errors
counterexample:
Generated input: [ 10, 2 ]
Generated input: [ 2, 10 ]
expected [ 10, 2 ] to be sorted
```

If we wanted to fix the problem, we would need to use a comparison function:

```js
function sort(arr) {
function sortNumbers(arr) {
return [].concat(arr).sort(function (a, b) {
return a - b;
});
Expand All @@ -101,9 +101,9 @@ function sort(arr) {

```js
expect(function (arr) {
var sorted = sort(arr);
var sorted = sortNumbers(arr);
expect(sorted, 'to have length', arr.length);
expect(sort(arr), 'to be sorted');
expect(sorted, 'to be sorted');
}, 'to be valid for all', arrays);
```

Expand Down Expand Up @@ -178,6 +178,42 @@ return expect(function (text) {
}, 'to be valid for all', g.string);
```

## Options

* `generators` (default []): an array of generators used to generate the example
data.
* `maxIterations` (default 300): the number of iterations that the subject
function it ran when no errors occur.
* `maxErrorIterations` (default 1000): the number of iterations unexpected-check
can use to find a better error when an error occurs.
* `maxErrors` (default 20): the number of found errors before stopping the input
shrinking process.

```js
expect(function (arr) {
var sorted = sort(arr);
expect(sorted, 'to have length', arr.length);
expect(sorted, 'to be sorted');
}, 'to be valid for all', {
generators: [arrays],
maxIterations: 100,
maxErrorIterations: 100,
maxErrors: 15
});
```

```output
Ran 100 iterations and found 4 errors
counterexample:
Generated input: [ 0, -1, 4, 10 ]
expected [ -1, 0, 10, 4 ] to be sorted
```

As you can see the input shrinking is worse with less iterations, but it will be
a bit faster.

## Source

The source for this plugin can be found on
Expand Down
9 changes: 7 additions & 2 deletions lib/unexpected-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
};

expect.addAssertion('<function> to be valid for all <object>', function (expect, subject, options) {
var generators = options.generators;
var generators = options.generators || [];
var maxIterations = options.maxIterations || 300;
var maxErrorIterations = options.maxErrorIterations || 1000;
var maxErrors = options.maxErrors || 20;

function createTask() {
Expand Down Expand Up @@ -80,7 +81,11 @@

return promiseLoop(function () {
return (
i < maxIterations &&
(
errors === 0
? i < maxIterations
: i < maxErrorIterations
) &&
errors < maxErrors &&
(errors === 0 || hasShrinkableGenerators())
);
Expand Down
3 changes: 2 additions & 1 deletion test/unexpected-check.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ describe('unexpected-check', function () {
.and('last item to be greater than or equal to all', arr);
}, 'to be valid for all', {
generators: [arrays],
maxIterations: 130,
maxIterations: 50,
maxErrorIterations: 130,
maxErrors: 15
});
}, 'to throw',
Expand Down

0 comments on commit 190228e

Please sign in to comment.