Skip to content

Commit

Permalink
Implement some units for commands
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz committed Jul 31, 2018
1 parent 346862a commit c326fee
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions test/unit/check/model/commands/CommandsArbitrary.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as assert from 'assert';
import prand from 'pure-rand';
import * as fc from '../../../../../lib/fast-check';

import { Command } from '../../../../../src/check/model/command/Command';
import { Random } from '../../../../../src/random/generator/Random';
import { constant } from '../../../../../src/check/arbitrary/ConstantArbitrary';
import { commands } from '../../../../../src/check/model/commands/CommandsArbitrary';
import { modelRun } from '../../../../../src/check/model/ModelRunner';

type Model = {};
type Real = {};
type Cmd = Command<Model, Real>;

const model: Model = Object.freeze({});
const real: Real = Object.freeze({});

class SuccessCommand implements Cmd {
constructor(readonly log: { data: string[] }) {}
check = () => {
this.log.data.push(this.toString());
return true;
};
run = () => {};
toString = () => 'success';
}
class SkippedCommand implements Cmd {
constructor(readonly log: { data: string[] }) {}
check = () => {
this.log.data.push(this.toString());
return false;
};
run = () => {};
toString = () => 'skipped';
}
class FailureCommand implements Cmd {
constructor(readonly log: { data: string[] }) {}
check = () => {
this.log.data.push(this.toString());
return true;
};
run = () => {
throw 'error';
};
toString = () => 'failure';
}

describe('CommandWrapper', () => {
describe('commands', () => {
const simulateCommands = (cmds: Cmd[]) => {
for (const c of cmds) {
if (!c.check(model)) continue;
try {
c.run(model, real);
} catch (err) {
return;
}
}
};
it('Should skip skipped commands on shrink', () =>
fc.assert(
fc.property(fc.integer(), (seed: number) => {
const mrng = new Random(prand.mersenne(seed));
let logOnCheck: { data: string[] } = { data: [] };

const baseCommands = commands([
constant(new SuccessCommand(logOnCheck)),
constant(new SkippedCommand(logOnCheck)),
constant(new FailureCommand(logOnCheck))
]).generate(mrng);
simulateCommands(baseCommands.value);

for (const shrunkCmds of baseCommands.shrink()) {
logOnCheck.data = [];
shrunkCmds.value.forEach(c => c.check(model));
assert.ok(logOnCheck.data.every(e => e !== 'skipped'));
}
})
));
// TODO: revamp the arbitrary so that this test
// can be enabled
/*it('Should shrink with failure at the end', () =>
fc.assert(
fc.property(fc.integer(), (seed: number) => {
const mrng = new Random(prand.mersenne(seed));
let logOnCheck: { data: string[] } = { data: [] };
const baseCommands = commands([
constant(new SuccessCommand(logOnCheck)),
constant(new SkippedCommand(logOnCheck)),
constant(new FailureCommand(logOnCheck))
]).generate(mrng);
simulateCommands(baseCommands.value);
const lastWasFailure = logOnCheck.data[logOnCheck.data.length - 1] === 'failure';
const initialData = [...logOnCheck.data];
fc.pre(lastWasFailure);
for (const shrunkCmds of baseCommands.shrink()) {
logOnCheck.data = [];
shrunkCmds.value.forEach(c => c.check(model));
assert.ok(
logOnCheck.data.length === 0
|| logOnCheck.data[logOnCheck.data.length - 1] === 'failure',
`Shrunk initial data ${initialData.join(',')} into ${logOnCheck.data.join(',')}`
);
}
})
));*/
it('Should shrink with at most one failure and all successes', () =>
fc.assert(
fc.property(fc.integer(), (seed: number) => {
const mrng = new Random(prand.mersenne(seed));
let logOnCheck: { data: string[] } = { data: [] };

const baseCommands = commands([
constant(new SuccessCommand(logOnCheck)),
constant(new SkippedCommand(logOnCheck)),
constant(new FailureCommand(logOnCheck))
]).generate(mrng);
simulateCommands(baseCommands.value);

for (const shrunkCmds of baseCommands.shrink()) {
logOnCheck.data = [];
shrunkCmds.value.forEach(c => c.check(model));
assert.ok(logOnCheck.data.every(e => e === 'failure' || e === 'success'));
assert.ok(logOnCheck.data.filter(e => e === 'failure').length <= 1);
}
})
));
});
});

0 comments on commit c326fee

Please sign in to comment.