Coder Social home page Coder Social logo

testcheck-js's Introduction

TestCheck.js Build Status

Generative property testing for JavaScript.

TestCheck.js is a library for generative testing of program properties, ala QuickCheck.

By providing a specification of the JavaScript program in the form of properties, the properties can be tested to remain true for a large number of randomly generated cases. In the case of a test failure, the smallest possible failing test case is found.

Getting started

Install testcheck using yarn

yarn add --dev testcheck

Or using npm

npm install --save-dev testcheck

Then require it into your testing environment and start testing.

const { check, gen, property } = require('testcheck');

const result = check(
  property(
    gen.int,
    x => x - x === 0
  )
)

Have a favorite test framework?

TestCheck.js is a testing utility and not a complete test-running framework. It doesn't replace test frameworks like AVA, Jasmine, or Mocha.

If you use AVA then check out ava-check, a testcheck AVA plugin.

const test = require('ava')
const { check, gen } = require('ava-check')

test('addition is commutative', check(gen.int, gen.int, (t, numA, numB) => {
  t.true(numA + numB === numB + numA)
}))

If you use Jasmine or Jest then check out jasmine-check, a testcheck Jasmine (or Jest) plugin.

require('jasmine-check').install()

describe('Maths', () => {
  check.it('addition is commutative', gen.int, gen.int, (numA, numB) => {
    expect(numA + numB).toEqual(numB + numA)
  })
})

If you use Mocha then check out mocha-testcheck, a testcheck Mocha plugin.

require('mocha-testcheck').install();
const { expect } = require('chai');

describe('Maths', () => {
  check.it('addition is commutative', gen.int, gen.int, (numA, numB) => {
    expect(numA + numB).to.equal(numB + numA)
  })
})

If you use Tape then check out tape-check, a testcheck Tape plugin.

const test = require('tape')
const { check, gen } = require('tape-check')

test('addition is commutative', check(gen.int, gen.int, (t, numA, numB) => {
  t.plan(1)
  t.equal(numA + numB, numB + numA)
}));

Type definitions

This module includes type definitions for Flow type and Typescript. Simply require or import this module and enjoy type suggestions and corrections.

Using TestCheck.js

See the complete API documentation for all available generators and utilities, or the Walkthrough Guide for a more thorough walkthrough.

Try it! Open the developer console while viewing the docs to follow along with the examples below.

Defining properties

A property is simply a function which is expected to always return true, we might also call these properties "assumptions" or "expectations".

For example, say we wanted to test the assumption that any number subtracted from itself will be 0, we could define this property as:

function (x) {
  return x - x === 0
}

Or as another example, let's determine that sorting an array is stable and idempotent, which is to say that sorting a sorted array shouldn't do anything. We could write:

function (arr) {
  var arrCopy = arr.slice()
  return deepEqual(arrCopy.sort(), arr.sort().sort())
}

That's really it! The only thing special about this property function is that it is pure, e.g. it relies only on the provided arguments to determine its return value (no other reading or writing!).

If you can start to describe your program in terms of its properties, then testcheck can test them for you.

Generating test cases

Once we've defined some properties, we generate test cases for each properties by describing the types of values for each argument.

For testing our first property, we need numbers:

gen.int

For the second, we need arrays of numbers

gen.array(gen.int)

There are a wide variety of value generators, we've only scratched the surface. We can generate random JSON with gen.JSON, pick amongst a set of values with gen.returnOneOf, nested arrays with ints gen.nested(gen.array, gen.int) and much more. You can even define your own generators with generator.then(), and gen.sized.

Checking the properties

Finally, we check our properties using our test case generator (in this case, up to 1000 different tests before concluding).

const result = check(
  property(
    // the arguments generator
    gen.int,
    // the property function to test
    x => x - x === 0
  ),
  { numTests: 1000 }
)

check runs through random cases looking for failure, and when it doesn't find any failures, it returns:

{ result: true, numTests: 1000, seed: 1406779597155 }

Smallest failing test

Let's try another property: the sum of two integers is the same or larger than either of the integers alone.

check(
  property(
    gen.int, gen.int,
    (a, b) => a + b >= a && a + b >= b
  )
)

check runs through random cases again. This time it found a failing case, so it returns:

{ result: false,
  failingSize: 2,
  numTests: 3,
  fail: [ 2, -1 ],
  shrunk:
   { totalNodesVisited: 2,
     depth: 1,
     result: false,
     smallest: [ 0, -1 ] } }

Something is wrong. Either:

  1. Our assumption is wrong (e.g. bug in our software).
  2. The test code is wrong.
  3. The generated test data is too broad.

In this case, our problem is that our generated data is too broad for our assumption. What's going on?

We can see that the fail case 2, -1 would in fact not be correct, but it might not be immediately clear why. This is where test case shrinking comes in handy. The shrunk key provides information about the shrinking process and most importantly, the smallest values that still fail: 0, -1.

We forgot about an edge case! If one of the integers is negative, then the sum will not be larger. This shrunken test case illustrated this much better than the original failing test did. Now we know that we can either improve our property or make the test data more specific:

check(property(
  gen.posInt, gen.posInt,
  (a, b) => a + b >= a && a + b >= b
));

With our correction, our property passes all tests.

Thinking in random distributions

It's important to remember that your test is only as good as the data being provided. While testcheck provides tools to generate random data, thinking about what that data looks like may help you write better tests. Also, because the data generated is random, a test may pass which simply failed to uncover a corner case.

"Testing shows the presence, not the absence of bugs"

— Dijkstra, 1969

Sampling Test Data

Visualizing the data check generates may help diagnose the quality of a test. Use sample and sampleOne to get a look at what a generator produces:

const { gen, sample, sampleOne } = require('testcheck')

sample(gen.int)
// [ 0, 0, 2, -1, 3, 5, -4, 0, 3, 5 ]

sampleOne(gen.int)
// -23

The Size of Test Data

Test data generators have an implicit size property, which could be used to determine the maximum value for a generated integer or the max length of a generated array. testcheck begins by generating small test cases and gradually increases the size.

So if you wish to test very large numbers or extremely long arrays, running check the default 100 times with maxSize of 200, you may not get what you expect.

Data relationships

Let's test an assumption that should clearly be wrong: a string split by another string always returns an array of length 1.

check(property(
  gen.asciiString.notEmpty(), gen.asciiString.notEmpty(),
  (str, separator) => str.split(separator).length === 1
))

Unless you got lucky, you probably saw this check pass. This is because we're testing for a relationship between these strings. If separator is not found in str, then this test passes. The second unrelated random string is very unlikely to be found within the first random string.

We could change the test to be aware of this relationship such that the separator is always contained within the str by using then().

check(property(
  gen.asciiString.notEmpty().then(str =>
    [ str, gen.substring(str).notEmpty() ]),
  ([ str, separator ]) => str.split(separator).length === 1
))

Now separator is a random substring of str and the test fails with the smallest failing arguments: [ ' ', ' ' ].

We can test this example out ourselves, with the value ' ' generated for both str and separator, we can run ' '.split(' ').length to see that we in fact get 2, not 1.

License

Copyright 2014-Present Lee Byron

TestCheck.js is distributed under the BSD-3-Clause license.

Atop the shoulders of giants

TestCheck.js is based on Clojure's test.check which is inspired by Haskell's QuickCheck. Many gracious thanks goes to all of the brilliance and hard work enabling this project to exist.

Clojure's test.check is Copyright Rich Hickey, Reid Draper and contributors and is distributed under the Eclipse Public License.

testcheck-js's People

Contributors

danielrosenwasser avatar davidmccabe avatar dbousamra avatar fson avatar garbles avatar leebyron avatar modocache avatar mortonfox avatar patrickjs avatar samwgoldman avatar wdoug avatar wodin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

testcheck-js's Issues

Add global testcheck variables on the docs site for easy interaction in dev tools

Many javascript libraries add their exports as global variables on their docs site. This makes it easy to pop open the console and test out different methods of the library in a repl right next to the actual docs. This would be super useful to quickly test out sampling different generators, etc.

I would personally love to have each of the top level exports (check, property, sample, sampleOne, gen, Generator) be added to window since that is how they will commonly be used. Something indicating that those variables are globally defined would also be nice such as how the Immutable.js docs site log some initial info showing that Immutable is globally defined.

gen.uniqueArray() repeats undefined and null

Loving the property testing. Thanks for your library and catering for tape.

Just playing with this generator. It seams that null and undefined are being repeated.

gen.uniqueArray(gen.primitive, {size: ...})

I am unfamiliar with Clojure. However I imagine that maybe both are considered nil and nil never matches itself? My workaround is this...

const undef = Symbol('undefined');
const nul = Symbol('null');
const uniqueFn = v => ((v === undefined) ? undef : (v === null) ? nul : v);
...
gen.uniqueArray(gen.primitive, uniqueFn, {size: ...})

Is this a known issue? Maybe the default unique fn needs to be adjusted for the quirks of Javascript.

Custom generator and shrinking

I don't think this functionality exists but is there currently a way to create a new generator type with custom shrinking behaviour?

`ava-check` not published on npm?

npm ERR! 404 Registry returned 404 for GET on https://registry.npmjs.org/ava-check
npm ERR! 404 
npm ERR! 404  'ava-check' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)

property function issue with throws assertion

According to the TypeScript declarations the property function of property allows to return void. The documentation and the JSDoc right above it say it should return true or false, so this is a bit of an inconsistency.

export function property<A>(
genA: ValueGenerator<A>,
f: (a: A) => boolean | void
): Property<[A]>;

Unfortunate this results in some unexpected behaviour when using the throws assertion from chai. In this example I'm explicitly not using mocha-testcheck, despite working in a mocha workspace, partially to properly show the issue, but also because no TypeScript declarations exist for that package yet.

describe('testcheck issue reproduction', () => {
  it('should throw an error', () => {
    const checkResult = check(
      property(
        gen.undefined,
        () => chai.assert.throws(() => { // (1)
          throw new Error(); // (2)
        }),
      ),
    );

    assert.isTrue(checkResult.result); // (3)
  });
});

The property function at (1) is an arrow function returning the result of chai.assert.throws which is void. According to the TypeScript declarations this is absolutely valid.
The tested function at (2) throws an error and therefore confirms the assertion at (1).

Expected behaviour
The checkResult.result at (3) should be true since the assertion was successful and the property function completed.
Actual behaviour
The checkResult.result at (3) contains an Error and the assertion fails.

Additional information
The arrow function returning void work perfectly fine with any of my other assertions, but throws seems to have some issues.

Solutions
Easiest would be to remove the void return type from the TypeScript declarations, although this might break some code and removes the ability to create simple property arrow function and requires us to change the arrow function at (1) to return true at the end of it:

        () => {
          assert.throws(() => {
            throw new Error();
          });
          return true;
        },

Alternatively testcheck could interpret undefined returned by the property function just like it would do with true.

jasmine-check and Jest

I'm trying to use jasmine-check with Jest and I'm getting the error caused by jasmine not being a global variable. Is Jasmine required to use jasmine-check with Jest?

Trying to create 'numerical keys' for an array using .then method is not working

Issue:

I'm trying to create a non-numerical keys for the array and it is not working on the latest master(build on 04-14-2018 - testcheck@^1.0.0-rc.2). Seems like it used to work for the old code that is published to npm.

Working Example on the console of 'http://leebyron.com/testcheck-js ':

const arr = gen.array(gen.int,{size:10})

const oneMoreArr = arr.then(val => {
val['foo'] = ()=> console.log('Hello')
return val;
});
sampleOne(oneMoreArr2)
sampleOne(oneMoreArr2).foo();

Output:

sampleOne(oneMoreArr2)

[7, 3, 29, 10, 16, -29, 4, -14, 23, 19, foo: ƒ]

sampleOne(oneMoreArr2).foo();

Hello
=====================================================================
For the same code output on the master build from 04-14-2018 (testcheck@^1.0.0-rc.2)


sampleOne(oneMoreArr2)

[[ 18, -29, -28, 27, -14, -11, -3, -16, -27, -10 ] - (missing key 'foo')

sampleOne(oneMoreArr2).foo();

undefined - (expected hello to be logged)

Support for async properties

I'd like to write properties asynchronous behaviours. My understanding is that testcheck-js doesn't support itat the moment (at least the mocha bridge).

gettng an 'async' error on non-async code

I'm getting the error ava-check cannot check tests with async assertions with the following code:

import test from 'ava';
import { check, gen } from 'ava-check';

function range(from, to) {
  const result = [];
  for (let x = from; x <= to; x += 1) {
    result.push(x);
  }
  return result;
}

const inc = x => x + 1;

test(
    'range length is the difference between its inputs',
    check(gen.sPosInt.then(int => gen.sPosInt.then(x => [int, x + int])), (t, [min, max]) => {
        t.true(range(min, max).length === inc(max - min));
    })
);

Help the AVA team deliver first-class support for TestCheck.js

Hello 👋

Back in February @danr raised an issue with AVA on how to get first-class support for tools like TestCheck.js. We've reached a consensus on implementing a t.try() assertion for which the calling code can determine whether to accept the results:

// pseudo-code for ava-check:
function check(genA, genB, implementation) {
  return async t => {
    while (true) {
      const result = await t.try(implementation, genA(), genB())
      if (result.passed || cannotMinimizeFurther()) {
        return result.commit()
      }
    }
  }
}

AVA recently stopped exposing its internal Test instance which has broken ava-check: avajs/ava#1835. Ideally we implement t.try() so TestCheck.js no longer has to rely on internals, but we need somebody to do the work. So, here's your call to action! Chime in on avajs/ava#1692 if you want to help out.

Many thanks!

Example function fails when running testcheck installed from npm, works when testcheck built from source

Ubuntu: 16.04, 4.9 kernel
Node: v6.9.2
installed testcheck-js via: npm install --save-dev testcheck
opened node repl in shell, then ran

const { check, property, gen } = require('testcheck')

check(property(gen.int, (x) => x - x === 0))

Got the following error:

node_modules/testcheck/dist/testcheck.js:280

function Ig(a,b){var c=oc(b)?T.a(ze,b):b,d=Yb.a(c,Rf);return Fg(function(b,c,d){return function(b,c){return a.b?a.b(d.a?d.a(b,c):d.call(null,b,c)):a.call(null,d.a?d.a(b,c):d.call(null,b,c))}}(b,c,d))}function Jg(a,b){var c=oc(a)?T.a(ze,a):a,d=Yb.a(c,Rf);return Fg(function(a,c,d){return function(a,c){var e=d.a?d.a(a,c):d.call(null,a,c),e=b.b?b.b(e):b.call(null,e),e=oc(e)?T.a(ze,e):e,e=Yb.a(e,Rf);return e.a?e.a(a,c):e.call(null,a,c)}}(a,c,d))}function Kg(a,b){return Ig(ed.a(ug,a),b)}
                                                                                                                                                                   
TypeError: Cannot read property 'a' of null
    at node_modules/testcheck/dist/testcheck.js:280:309
    at node_modules/testcheck/dist/testcheck.js:280:421
    at node_modules/testcheck/dist/testcheck.js:280:323
    at node_modules/testcheck/dist/testcheck.js:280:323
    at node_modules/testcheck/dist/testcheck.js:279:400)
    at Function.b (node_modules/testcheck/dist/testcheck.js:290:615)
    at node_modules/testcheck/dist/testcheck.js:292:744
    ...

I cloned the repo and ran npm run build and everything works perfect, so it seems to be an issue with the npm package itself.

Please, let me know if there is any more info that would be useful.

_checkPlanCount is undefined

__checkPlanCount in ava is undefined, which leads to tests failing.

However, you have assertCount and planCount available (might be plannedCount, just remember there was one).

Shrinking?

Does testcheck-js support shrinking? I don't see any docs on it. I think it would be very useful feature, and I guess most of users expect QuickCheck-like tool to have it.
I had nice experience with quickcheckjs - it does some shrinking itself and also allows to add custom shrinkers. As far as docs states, jsverify has shrinking too.

Generate functions?

Hi,

just read through the docs and didn't see a way to generate functions. What's the reason for that? Always wanted to try out this library but I have a higher order function I'd like to test with it. Not sure if this is something this project was intended for. 😄

Edit: Just to clarify, I was hoping there was a way to generate functions that not just return random data but with JS-specifics like different this bindings, function expressions vs. function declarations, async functions, functions that crash etc.

Thanks!

Status of the project

Hi,

Simple question : is the project still usable today ? Or do you know alternatives ?

Happy to see that you (again) took inspiration from the Clojure(Script) community.

By the way, we met at ReactEurope 2015. Cheers !

gen.array(gen.any) takes super long

Single test (using mocha-testcheck) that takes gen.array(gen.any) never completes. Mocha times out the browser locks up. Are these not safe to use together?

gen.oneOf should ensure argument is an array

Applying a constraint to oneOf to ensure the arguments are correct should provide the user with a friendly message when it has been used incorrectly, the current message leaks some of the implementation detail and not so intuitive.

const ts = require("testcheck")
ts.sample(ts.gen.oneOf(ts.gen.posInt, ts.gen.numberWithin(0, 100)))

Error: [object Object] is not ISeqable
    at Error (native)
    at E (/usr/src/app/node_modules/testcheck/dist/testcheck.js:90:423)
    at /usr/src/app/node_modules/testcheck/dist/testcheck.js:210:56
    at Ce (/usr/src/app/node_modules/testcheck/dist/testcheck.js:160:54)
    at Be.h.Y (/usr/src/app/node_modules/testcheck/dist/testcheck.js:162:291)
    at E (/usr/src/app/node_modules/testcheck/dist/testcheck.js:90:313)
    at Xe (/usr/src/app/node_modules/testcheck/dist/testcheck.js:183:52)
    at to (/usr/src/app/node_modules/testcheck/dist/testcheck.js:442:143)
    at Object.exports.gen.oneOf (/usr/src/app/node_modules/testcheck/dist/testcheck.js:734:136)
    at repl:1:18

gen.oneOf throws an an error (not ISeqable)

The following code taken from the docs throws an error:

const numOrBool = gen.oneOf([ gen.int, gen.boolean ])

sample(numOrBool)

Output:

Error: [object Object],[object Object] is not ISeqable
    at E (/home/runner/node_modules/testcheck/dist/testcheck.js:90:423)
    at /home/runner/node_modules/testcheck/dist/testcheck.js:210:56
    at Ce (/home/runner/node_modules/testcheck/dist/testcheck.js:160:54)
    at Be.h.Y (/home/runner/node_modules/testcheck/dist/testcheck.js:162:291)
    at E (/home/runner/node_modules/testcheck/dist/testcheck.js:90:313)
    at Xe (/home/runner/node_modules/testcheck/dist/testcheck.js:183:52)
    at to (/home/runner/node_modules/testcheck/dist/testcheck.js:442:143)
    at Object.exports.gen.oneOf (/home/runner/node_modules/testcheck/dist/testcheck.js:734:136)
    at evalmachine.<anonymous>:3:23
    at Script.runInContext (vm.js:133:20)

Published version of `testcheck` way behind docs?

Sorry to blow up the issues, but I'm trying to get started using testcheck on a project, and keep running into issues! :)

Seems there has been 250 commits since last publish, and nothing seems to work quite like the docs say, for instance gen.then or gen.notEmpty. When I built from source, everything works fine. Is there something keeping the newer builds from being published to npm?

Option to fail check on thrown error

Currently, testcheck expects a boolean response for test pass/fail. Throwing an error implies the test is broken, not failing - which is different.

Ideally, an option can be presented which will treat thrown errors as test failures (and thus re-run the test). The error should be captured and presented as part of the "result"

feature request: gen.float

I wondered what your thoughts were on adding gen.float, or if you could recommend what the best approach might be for me achieving this using what is already available.

I'm looking for a generator similar to gen.number but that only generates numbers with decimal places, rather than a mixture of whole numbers and those with decimal places.

Feel free to close if I'm on the wrong track, thanks for your time.

Support of typed arrays?

IDK about others, but I would be definitely happy to see a generator for Typed Arrays (uint8, float32, etc) with length as provided option.

Mutable generated values are sometimes reused while shrinking

Open a console at http://leebyron.com/testcheck-js/api (or equivalent). Run this program and inspect the result, and compare out.result with out.shrunk.result.

out = check(
  property(
    gen.posInt.then(x => ({ x })).then(c => gen.object({ c, unused: gen.int })).then(({ c }) => c ),
    c => {
      if (c.used) throw new Error('used');
      c.used = true;
      return (c.x === 0);
    }
  )
)

Expected behaviour: The test finds a failing case, and then shrinks it to a smaller case that finds the same failure. Thus out.result === out.shrunk.result === false.

Actual behaviour: The test finds a failing case, tries to shrink it, but reuses the existing c that has already been mutated by a previous run. This changes the result, because the precondition fails and an exception is thrown instead. Thus out.result !== out.shrunk.result.

In practice this means that once a test fails, shrinking can result in misleading error messages, because the shrink tests are run against input that has already been mutated by previous tests.

Type definitions (typescript & flow) for jasmine-check package

jasmine-check.d.ts cannot be found in the latest distribution 1.0.0-rc.0

untitled

untitled1

untitled1

The library is great but I cannot use it with TypeScript and Jest without first having jasmine-check.d.ts.
Please place it in the same root directory as jasmine-check.ts.
Thanks!

Flow compatibility with globally available functions

I'm using jasmine-check's install function, which I believe globally exposes variables like gen and check, which at runtime is working totally fine. I'm having trouble convincing Flow that these variable are indeed available, however. Here's the install code:

import { install } from 'jasmine-check'

install()

Here are two examples of the Flow errors I'm receiving:

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/routes/Linking/store.test.js:265:5

Cannot resolve name check.

     262│     })
     263│   })
     264│   describe('FETCH_ENTITIES_SUCCESS', () => {
     265│     check.it(
     266│       'propertly updates state with the mapped entities',
     267│       testcheckOptions,
     268│       gen.array(genEntityAPI()),


Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/routes/Linking/store.test.js:268:7

Cannot resolve name gen.

     265│     check.it(
     266│       'propertly updates state with the mapped entities',
     267│       testcheckOptions,
     268│       gen.array(genEntityAPI()),
     269│       entitiesAPI => {
     270│         const action = {
     271│           type: Actions.FETCH_ENTITIES_SUCCESS,

For the time being, my workaround is...

declare var gen: any
declare var check: any

...but of course this is hackish and only a temporary solution.

It may also be a separate issue, but when I try and install the type definitions for testcheck using flow-typed, it's 404ing.

Here's the command I'm running...

$ npx flow-typed install [email protected]

...and the response that I'm receiving...

!! No [email protected] libdefs found in flow-typed for the explicitly requested libdefs. !!

Consider using `flow-typed create-stub [email protected]` to generate an empty libdef that you can fill in.

This is slightly confusing to me, since I've seen the Flow libdefs in this module. Is there an alternative way of installing these that I'm unaware of? Apologies if this is a separate issue, but I thought I'd include that herein just in case it's related.

[TypeScript] Can't use string, array or object as value in shape generator

Documentation shows the following example for shape generator:

gen({
  type: 'Place',
  name: gen.string,
  location: [ gen.number, gen.number ],
  address: {
    street: gen.string,
    city: gen.string
  }
})

This works perfectly fine in plain JS in master.

But in TS:

gen({
  type: 'Place'
})

causes compilation error: Type 'string' is not assignable to type 'ValueGenerator<{}>'

gen({
  location: [ gen.number, gen.number ],
})

causes compilation error: Type 'ValueGenerator<number>[]' is not assignable to type 'ValueGenerator<{}>'.

gen({
  address: {
    street: gen.string,
    city: gen.string
  }
})

causes compilation error: Type '{ street: ValueGenerator<string>; city: ValueGenerator<string>; }' is not assignable to type 'ValueGenerator<{}>'.

ava-check and tape-check

I cannot install either tape-check or ava-check. I tried both npm install and yarn install but they are both failing.

Interest in Flow type definitions?

I translated the TypeScript declarations to Flow. Would you be interested in incorporating them into this library (delivered like the d.ts file?). If not, is it OK to publish to FlowTyped?

ava-check inadvertently thinks tests are async and fails

the example test fails

const test = require('ava')
const { check, gen } = require('ava-check')

test('addition is commutative', check(gen.int, gen.int, (t, numA, numB) => {
  t.true(numA + numB === numB + numA)
}))

TypeError {
message: 'ava-check cannot check tests with async assertions.',
}

[jasmine-check] eslint configuration question

I'm just setting this up for use in my Jest project and I get errors about check and gen not being defined. I can just add them as globals in my eslintrc, but I figured I'd check if there was a better way that I was missing? The reason I ask is because I noticed that flow is treating check and gen as any

Thanks!

Generators for values of object shapes always generate `{}`

Per the documentation, I'm trying to generate a simple object shape like so:

gen.sample({ x: gen.string })

But the output of the string generator is always just an empty object:

      [ { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} },
        { x: {} } ]

Relevant parts of my yarn.lock:

jasmine-check@^1.0.0-rc.0:
  version "1.0.0-rc.0"
  resolved "https://registry.yarnpkg.com/jasmine-check/-/jasmine-check-1.0.0-rc.0.tgz#117728c150078ecf211986c5f164275b71e937a4"
  dependencies:
    testcheck "^1.0.0-rc"

testcheck@^1.0.0-rc, testcheck@^1.0.0-rc.2:
  version "1.0.0-rc.2"
  resolved "https://registry.yarnpkg.com/testcheck/-/testcheck-1.0.0-rc.2.tgz#11356a25b84575efe0b0857451e85b5fa74ee4e4"

Requiring externally seems to break

Excuse the poor title. Not sure how to describe this behaviour.

I have an internal npm package 'example-generators', that exposes a generators.js file like so:

var testcheck = require('testcheck');
var gen = testcheck.gen;
exports.genBoolean = gen.returnOneOf([true, false]);

In another node project, I have a single source file, test.js, where I require('example-generators') like so:

var testcheck = require('testcheck')
var generators = require('example-generators')

I then call:

var bools = testcheck.sample(generators.genBoolean)

and am greeted with:

return a.a ? a.a(b, c) : a.call(null, b, c)
│TypeError: Cannot read property 'a' of null
    at Function.Gg (/Users/Dom/Code/some-code/node_modules/testcheck/dist/testcheck.js:6699:21)

This is odd. It seems to stem from the require in the generators.js file. If I modify generators.ts to look like so:

var testcheck = require('/Users/Dom/Code/some-code/node_modules/testcheck/dist/testcheck.js');
var gen = testcheck.gen;
exports.genBoolean = gen.returnOneOf([true, false]);

I.e. use the same testcheck.js install. It seems to work. I have no idea what is going on, given we are dealing with minified clj -> js, I can't gain much insight.

Any ideas?

Is gen.any supposed to generate any kind of values or only arrays or objects?

Hi,

The documentation for gen.any says:

Generates any JS value, including Arrays and Objects (possibly nested).

I ran this code a couple of times (± 10 times) and never had any single strings, numbers or booleans:

 sample(gen.any, 100).filter(x => typeof x !== 'object');

I know the values in the list are randomly generated but I should have received one non-array non-object value at least once. (Or I might just be extremely unlucky. )

Is gen.any supposed to produce only arrays or objects? In which case I'd recommend updating the documentation. Otherwise do you think this may be a bug?

I am using testcheck 1.0.0-rc.2

Thank you.

Improve recursive Flow/TS types for gen()

The top level gen() function (#30) allows deeply nested shapes that contain generators in any leaf position. This is also the function used to convert any value expected to be a generator to a generator. The type signatures of the functions in this library should be aware of this nested behavior, however that doesn't currently seem possible in either tool.

I'm keeping this task open to track the desire to improve those types.

Please publish RC with shape generator

There are 2 issues with not publishing shape generator as RC:

  1. Documentation website says
    Try it! Open the developer console to take the API for a test run.
    At the same, shape generator is present in documentation, but library version in console doesn't support it, so attempt to do something like gen({a: '1'}) results in Uncaught TypeError: gen is not a function.
  2. There is no easy way to use master version, because dist folder is not saved in Github.

A workaround to use master version now is to fork the repo, build, commit dist folder and then put Github url into package.json. This doesn't look easy at all.

Async checks

A check should be able to run asynchronously, completing in a separate run tick. This would allow for more complete cross-compatibility with most test engines which support async tests.

Unfortunately right now, because it's based on clojure's testcheck, this feature probably needs to be added to testcheck first.

Check result should not use dashed keys

Currently a direct port from clojure, the dashes in the response object make the response slightly cumbersome to use. Replacing them with camelcase would be an improvement.

"Spec has no expectations" warnings with karma-jasmine-html-reporter 1.x

I've upgraded my test harness to jasmine 3.1.0 and karma-jasmine-html-reporter 1.1.0 and started getting tons of warnings of missing expectations in all my testcheck tests.

This is where the check is hapening
https://github.com/dfederm/karma-jasmine-html-reporter/blob/master/src/lib/html.jasmine.reporter.js#L491-L494

And the reason why passedExpectations array is empty, even though expectations were checked during testcheck property evaluation is here:
https://github.com/leebyron/testcheck-js/blob/master/integrations/jasmine-check/jasmine-check.js#L78-L84

On one hand, the warning is harmless if a bit annoying, on the other that is an useful check to have. I've prepared a workaround that is backward compatible with jasmine 1.x and 2.x that I'll post shortly

Collections generators failing

Whenever I attempt any of the Collections generators (array, object, arrayOrObject, nested), I receive the following error:

e.g.

const testcheck = require('testcheck')
const gen = testcheck.gen
console.log(testcheck.sample(gen.array))

TypeError: Cannot read property 'a' of null

I'm using node v7.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.