Advent of PBT 2021 — Learn how to use property based testing and fast-check through examples
Our algorithm today is: hanoiTower.
It comes with the following documentation and prototype:
/**
* In hanoi tower, we consider disks having sizes ranging from 1 to
* towerHeight (included). We want to move this tower from a given
* start position to an end position.
*
* But to do so we have several rules to follow:
* - disk can only be moved on top of another one with larger size
* (or position empty)
* - one disk at a time
* - cannot move disks outside of the tower
*
* For instance the hanoi game with towerHeight=3 and startPosition=0
* at start time is:
*
* X (1) | |
* XXX (2) | |
* XXXXX (3) | |
* --+-- --+-- --+--
*
* @param towerHeight - The height of the hanoi tower
* (between 0 and 10)
* @param startPosition - The position of the hanoi tower at start
* time (one of 0, 1 or 2)
* @param endPosition - The position of the hanoi tower at the end
* @param move - Move function called each time the function wants
* to move the disk on top of "from" to the top of "to"
*/
declare function hanoiTower(
towerHeight: number,
startPosition: number,
endPosition: number,
move: (from: number, to: number) => void
): void;
We already wrote some examples based tests for it:
it("should be able to move a tower of size 3 from 0 to 2", () => {
const move = jest.fn();
hanoiTower(3, 0, 2, move);
expect(move.mock.calls).toEqual([
// state: (1/2/3) / () / ()
[0, 2],
// state: (2/3) / () / (1)
[0, 1],
// state: (3) / (2) / (1)
[2, 1],
// state: (3) / (1/2) / ()
[0, 2],
// state: () / (1/2) / (3)
[1, 0],
// state: (1) / (2) / (3)
[1, 2],
// state: (1) / () / (2/3)
[0, 2]
// state: () / () / (1/2/3)
]);
});
it("should be able to move a tower of size 3 from 2 to 1", () => {
const move = jest.fn();
hanoiTower(3, 2, 1, move);
expect(move.mock.calls).toEqual([
// state: () / () / (1/2/3)
[2, 1],
// state: () / (1) / (2/3)
[2, 0],
// state: (2) / (1) / (3)
[1, 0],
// state: (1/2) / () / (3)
[2, 1],
// state: (1/2) / (3) / ()
[0, 2],
// state: (2) / (3) / (1)
[0, 1],
// state: () / (2/3) / (1)
[2, 1]
// state: () / (1/2/3) / ()
]);
});
How would you cover it with Property Based Tests?
In order to ease your task we provide you with an already setup CodeSandbox, with examples based tests already written and a possible implementation of the algorithm: https://codesandbox.io/s/advent-of-pbt-day-11-dgrk3?file=/src/index.spec.ts&previewwindow=tests
You wanna see the solution? Here is the set of properties I came with to cover today's algorithm: https://dev.to/dubzzz/advent-of-pbt-2021-day-11-solution-1og1
Back to "Advent of PBT 2021" to see topics covered during the other days and their solutions.
More about this serie on @ndubien or with the hashtag #AdventOfPBT.
Top comments (0)