Skip to content
Javascript property-based testing tool wrapping Erlang's PropEr and QuickCheck application
JavaScript Erlang Shell
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
priv
src
.gitignore
.travis.yml
Makefile
README.md
properjs
properjs.escript
rebar
rebar.config

README.md

Property testing in Javascript

Build Status

Make

make

Test

Runs the tests in priv/*.js

make test

Running

Then you can try running the properjs command in the properjs repository:

./properjs PATH/TO/file.js Object
./properjs PATH/TO/file.js Object PATH/TO/include.js 0 PATH/TO/otherfile.js OtherObject

where PATH/TO/file.js is a source file for your code, Object.props is how properjs discovers its properties, and 0 denotes a source file without any properties defined

By default running properjs with no arguments runs the Proper.prop properties.

Example

Given that reversing a reversed string should always be the same, we can write a test that asserts this behaviour.

// string.js
String.prototype.reverse = function() {
    return this.split("").reverse().join("");
};
String.props = {
    reverse: function() {
        return FORALL(string(),
            function(s) {
                assert.equal(s, s.reverse().reverse());
            }
        );
    }
};

Then run it with:

./properjs string.js String

Compiling to use QuviQ QuickCheck

By default PropEr is used, but to compile to use your system's QuviQ QuickCheck installation compile with:

make cleanebin compile_eqc

Supported Types/Generators/Properties

FORALL(type(), type(), ..., function(v1, v2, ...) { return $boolean() | undefined })

Each argument to FORALL before the last function argument is a generator for a type that will then be passed to your function. Needs to return true or undefined on success and false on test failure.

var myprop = FORALL(integer(), integer(), integer(),
    function(one, two, three) {
        assert.equal(typeof one, 'number');
        assert.equal(typeof two, 'number');
        assert.equal(typeof three, 'number');
        return true; // optional due to being synonymous with undefined
    }
);

LET(type(), type(), ..., function(v1, v2, ...) { return new_value })

Allows you to define a custom type based on others. The function needs to return the generated value for your new type.

An even number generator would required an integer and multiple it by 2.

function even_number() {
    return LET(integer(),
        function(i) {
            return i * 2;
        }
    );
}

SUCHTHAT(type(), function(v) { return $boolean() })

Returns the value generated by type() if the condition function returns true. Otherwise the value will be skipped and a new one generated. There is a hard limit on the number of suchthat attempts that is not yet configurable via javascript.

function even_number() {
    return SUCHTHAT(integer(),
        function(i) {
            return i % 2 == 0;
        }
    );
}

The example of even_number() using a LET is prefered over this example since it does not throw away any generated values.

oneof(type(), type(), ...) oneof(array(type()))

Returns a randomly selection member of its arguments or the first element if there is only one and it is a list.

function board_size() {
    return oneof(9, 13, 19);
}
// equivalent to the above
function board_size() {
    return oneof([9, 13, 19]);
}

Basic Types

  • integer()
  • integer(integer(), integer()) generates an integer between its two arguments (inclusive)
  • pos_integer() positive integer
  • neg_integer() negative integer
  • non_neg_integer() positive integer or 0
  • $float()
  • $float($float(), $float()) generates a float between its two arguments (inclusive)
  • string()
  • $boolean() true or false
  • string()
  • array(type()) generates an array of its argument
  • char_code()
You can’t perform that action at this time.