CAUTION
This project is under development now.
Sorry to keep you waiting.
Please see GitHub Milestones
What's "Macchiato.js" ?
Inspired by QuickCheck
Macchiato is a testing framework for JavaScript, inspired by QuickCheck, a similar library for Haskell programs.
QuickCheck is a library for random testing of program properties.
The programmer provides a specification of the program, in the form of properties which functions should satisfy, and QuickCheck then tests that the properties hold in a large number of randomly generated cases.
Specifications are expressed in Haskell, using combinators defined in the QuickCheck library. QuickCheck provides combinators to define properties, observe the distribution of test data, and define test data generators.
Demo
macchiato.stock({
'number x, y => x + y == y + x':
arbitrary( 'number', 'number' ).property( function( x, y ){
return x + y === y + x;
}),
'string str => str can be regarded as boolean that is empty or not':
arbitrary( 'string' ).property( function( str ){
if ( str.length === 0 ){
return false === !!str;
}
return true === !!str;
}),
'integer x, y (x !== y) => x - y !== y - x' :
arbitrary( 'integer', 'integer' ).property( function( x, y ){
return where( [ x !== y ], function(){
return x - y !== y - x;
});
})
});
Usage
Register Test Suites
macchiato.stock( labeled_properties )
macchiato.stock({ // stock test properties as object
'number x, y => x + y === y + x' : // <label>:<callback>
arbitrary( 'number', 'number' ).property( function( x, y ){
return x + y === y + x, // boolean
})
});
Run Test Suites
macchiato.taste()
macchiato.taste(); // check all stocked test suites
in default, macchiato.js generate 100 pattern arguments per test-property.
See sample Generator works
arbitrary( type ).sample( [ opt_count ] )
arbitrary( 'boolean' ).sample() // [ true, false, false, true, true ]
arbitrary( 'boolean' ).sample( 5 ); // [ false, false, true, false, true ]
// in default, return array has 10 elements
arbitrary( 'integer' ).sample(); // [ 0, 1, 1, 0, -1, 6, 6, -12, -2, 16 ]
Use adhoc new type generator
arbitrary( type ).fmap( modifier )
// Non Negative Integer Generator
var nonNegativeNumberProperty = arbitrary( 'integer' ).fmap( Math.abs ).property( function( x ){
return x > -1;
});
Register User generator
arbitrary( new_type ).recipe( generator )
arbitrary.( 'hoge' ).recipe(
combinator.elements( [ 'hoge', 'huga', 'piyo', 'foo', 'bar', 'baz' ] )
arbitrary.sample(); // "foo", "bar", "bar", "hoge", "piyo", "baz", "hoge", "foo", "huga", "foo"
);
arbitrary( type ).fmap( modifier ).recipeAs( new_type )
arbitrary( 'integer' ).fmap( function( n ){
var x = Math.max( Math.abs( n ), 1 );
return tuple( x, x % 15 ? x % 5 ? x % 3 ? '' + x : 'Fizz' : 'Buzz' : 'FizzBuzz' );
}).recipeAs( 'fizzbuzz' );
arbitrary( 'fizzbuzz' ).sample(); // (1,"1"), (2,"2"), (1,"1"), (2,"2"), (3,"Fizz"), (4,"4"), (5,"Buzz"), (15,"FizzBuzz"), (7,"7"), (27,"Fizz")