Advent of PBT 2021 - Day 3 - Solution
Tags: challenge, testing, webdev, javascript
Published: 2021-12-03 08:52:38

---
title: Advent of PBT 2021 - Day 3 - Solution
published: true
description: Advent of Property Based Testing 2021 - Day 3 - Solution
tags: challenge,testing,webdev,javascript
//cover_image: https://direct_url_to_image.jpg
---

Our algorithm was: **fizzbuzz**.
[Go to the subject itself for more details](https://dev.to/dubzzz/advent-of-pbt-2021-day-3-4mac)

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.

```ts
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.

```ts
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

```ts
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

```ts
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

```ts
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

```ts
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

```ts
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

```ts
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"](https://dev.to/dubzzz/advent-of-pbt-2021-13ee) to see topics covered during the other days and their solutions.

More about this serie on [@ndubien](https://twitter.com/ndubien) or with the hashtag [#AdventOfPBT](https://twitter.com/search?q=%23AdventOfPBT).