This repository contains a model (oracle) and a test generator for the Casper token written in Haskell.
The technique being used for tests is known as "model based testing". The tester only needs to write scenarios that predictably transform the model's state on each step, and all the assertions will be automatically extracted from the model, which is itself an abstract representation of Casper token.
As for now, the model is very simple: only three ERC20 functions (think of them as model's state transitions) and only two events are considered.
The model was written independently of the smart contract to reduce the probability of mistake transference.
This package can be installed with cabal
cabal installor examined interactively with
cabal replHaskell's do notation is utilized to form a DSL for test scenarios.
import Casper
scenario = flatten $ do
transfer me a 1
approve me a 9
transferFrom a me b 2
approve me b 100000000000000000000000
code :: String
code = show $ scenarioToJS initialState scenarioThe code will look like this:
it("\n transfer me a 1\n approve me a 9\n transferFrom a me b 2\n approve me b 100000000000000000000000", () => {
return Casper.new().then(casper => {
var utils = new TestUtils(web3, casper, [me,a,b]);
return casper.transfer(a, 1, { from: me }).then(result => {
utils.saveEvents(result);
return utils.assertState([9999999,1,0], [[0,0,0],[0,0,0],[0,0,0]]).then(() => {
return casper.approve(a, 9, { from: me }).then(result => {
utils.saveEvents(result);
return utils.assertState([9999999,1,0], [[0,9,0],[0,0,0],[0,0,0]]).then(() => {
return casper.transferFrom(me, b, 2, { from: a }).then(result => {
utils.saveEvents(result);
return utils.assertState([9999997,1,2], [[0,7,0],[0,0,0],[0,0,0]]).then(() => {
return casper.approve(b, new BigNumber('100000000000000000000000'), { from: me }).then(result => {
utils.saveEvents(result);
return utils.assertState([9999997,1,2], [[0,7,new BigNumber('100000000000000000000000')],[0,0,0],[0,0,0]]).then(() => {
utils.assertLogs([['Transfer', me, a, 1],['Approval', me, a, 9],['Transfer', me, b, 2],['Approval', me, b, new BigNumber('100000000000000000000000')]]);
});
});
});
});
});
});
});
});
});
});