## DEV Community

Nicolas DUBIEN

Posted on • Updated on

# Advent of PBT 2021 - Day 3 - Solution

Our algorithm was: fizzbuzz.
Go to the subject itself for more details

CodeSandbox with a possible set of properties you may have come with: https://codesandbox.io/s/advent-of-pbt-day-3-solution-q7x2v?file=/src/index.spec.ts&previewwindow=tests

Before we start with the properties, there is one main pitfall with fizzbuzz: it is easy to rewrite the implementation in the test itself. So if your tests are using modulo, you are probably rewriting the implementation of fizzbuzz directly inside your tests.

Except that trap, properties are quite straight-word for fizzbuzz, so we will just show the code.

## Property 1: should print Fizz whenever divisible by 3

Instead of checking if the number is divisible by 3, we create one divisible by 3.

``````it("should print Fizz whenever divisible by 3", () => {
fc.assert(
fc.property(
fc.nat().map((n) => n * 3),
(n) => {
expect(fizzbuzz(n)).toContain("Fizz");
}
)
);
});
``````

## Property 2: should not print Fizz when not divisible by 3

Instead of checking if the number is not divisible by 3, we create one not divisible by 3.

``````it("should not print Fizz when not divisible by 3", () => {
fc.assert(
fc.property(
fc.oneof(
fc.nat().map((n) => n * 3 + 1),
fc.nat().map((n) => n * 3 + 2)
),
(n) => {
expect(fizzbuzz(n)).not.toContain("Fizz");
}
)
);
});
``````

## Property 3: should only print Fizz when divisible by 3 but not by 5

``````it("should only print Fizz when divisible by 3 but not by 5", () => {
fc.assert(
fc.property(
fc.oneof(
fc
.nat()
.map((n) => n * 5 + 1)
.map((n) => n * 3),
fc
.nat()
.map((n) => n * 5 + 2)
.map((n) => n * 3),
fc
.nat()
.map((n) => n * 5 + 3)
.map((n) => n * 3),
fc
.nat()
.map((n) => n * 5 + 4)
.map((n) => n * 3)
),
(n) => {
expect(fizzbuzz(n)).toBe("Fizz");
}
)
);
});
``````

## Property 4: should print Buzz whenever divisible by 5

``````it("should print Buzz whenever divisible by 5", () => {
fc.assert(
fc.property(
fc.nat().map((n) => n * 5),
(n) => {
expect(fizzbuzz(n)).toContain("Buzz");
}
)
);
});
``````

## Property 5: should not print Buzz when not divisible by 5

``````it("should not print Buzz when not divisible by 5", () => {
fc.assert(
fc.property(
fc.oneof(
fc.nat().map((n) => n * 5 + 1),
fc.nat().map((n) => n * 5 + 2),
fc.nat().map((n) => n * 5 + 3),
fc.nat().map((n) => n * 5 + 4)
),
(n) => {
expect(fizzbuzz(n)).not.toContain("Buzz");
}
)
);
});
``````

## Property 6: should only print Buzz when divisible by 5 but not by 3

``````it("should only print Buzz when divisible by 5 but not by 3", () => {
fc.assert(
fc.property(
fc.oneof(
fc
.nat()
.map((n) => n * 3 + 1)
.map((n) => n * 5),
fc
.nat()
.map((n) => n * 3 + 2)
.map((n) => n * 5)
),
(n) => {
expect(fizzbuzz(n)).toBe("Buzz");
}
)
);
});
``````

## Property 7: should print Fizz Buzz whenever divisible by 3 and 5

``````it("should print Fizz Buzz whenever divisible by 3 and 5", () => {
fc.assert(
fc.property(
fc
.nat()
.map((n) => n * 3)
.map((n) => n * 5),
(n) => {
expect(fizzbuzz(n)).toBe("Fizz Buzz");
}
)
);
});
``````

## Property 8: should print the value itself when not divisible by 3 and not divisible by 5

``````it("should print the value itself when not divisible by 3 and not divisible by 5", () => {
fc.assert(
fc.property(
fc.oneof(
fc.nat().map((n) => n * 15 + 1),
fc.nat().map((n) => n * 15 + 2),
fc.nat().map((n) => n * 15 + 4), // +3 would be divisible by 3
fc.nat().map((n) => n * 15 + 7), // +5 would be divisible by 5, +6 would be divisible by 3
fc.nat().map((n) => n * 15 + 8), // +9 would be divisible by 3, +10 would be divisible by 5
fc.nat().map((n) => n * 15 + 11),
fc.nat().map((n) => n * 15 + 13), // +12 would be divisible by 3
fc.nat().map((n) => n * 15 + 14)
),
(n) => {
expect(fizzbuzz(n)).toBe(String(n));
}
)
);
});
``````

Back to "Advent of PBT 2021" to see topics covered during the other days and their solutions.