it('should return false for non-controller principal from an update method', async () => {
            const actor = await getCanisterActor<Actor>('canister');

            await fc.assert(
                fc.asyncProperty(
                    fc.uint8Array({ minLength: 29, maxLength: 29 }),
                    async (bytes) => {
                        const principal = Principal.fromUint8Array(bytes);

                        const isController =
                            await actor.updateIsController(principal);

                        expect(isController).toStrictEqual(false);
                    }
                ),
                defaultPropTestParams()
            );
        })

Summary: The update method returns false when given a non-controller principal converted from a 29-byte Uint8Array.


unknown

it('after generates alphabetically "higher" values', () => {
    fc.assert(
      fc.property(
        genUnverifiedPos(),

        (pos) => {
          expect(after(pos) > pos).toBe(true);
          expect(pos < after(pos)).toBe(true);
        }
      )
    );
  })

Summary: The `after` function should generate a value that is alphabetically greater than the input position.


it("all equal scalars are shallowly equal", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.clone(scalar(), 2),

        // Unit test
        ([scalar1, scalar2]) => {
          expect(shallow(scalar1, scalar2)).toBe(true);

          // If two values are shallowly equal, then those values wrapped in an
          // array (one level) should _also_ be considered shallowly equal
          expect(shallow([scalar1], [scalar2])).toBe(true);
          expect(shallow([scalar1, scalar1], [scalar2, scalar2])).toBe(true);

          // ...but wrapping twice is _never_ going to be equal
          expect(shallow([[scalar1]], [[scalar2]])).toBe(false);

          // Ditto for objects
          expect(shallow({ a: scalar1 }, { a: scalar2 })).toBe(true);
          expect(
            shallow({ a: scalar1, b: scalar1 }, { a: scalar2, b: scalar2 })
          ).toBe(true);

          // ...but nesting twice is _never_ going to be equal
          expect(shallow({ a: { b: scalar1 } }, { a: { b: scalar2 } })).toBe(
            false
          );
        }
      )
    );
  })


it("different scalars are not shallowly equal", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.tuple(scalar(), scalar()).filter(([x, y]) => x !== y),

        // Unit test
        ([scalar1, scalar2]) => {
          expect(shallow(scalar1, scalar2)).toBe(false);

          // If two values are shallowly unequal, then wrapping those in an
          // array (one level) should also always be shallowly unequal
          expect(shallow([scalar1], [scalar2])).toBe(false);

          // Ditto for objects
          expect(shallow({ k: scalar1 }, { k: scalar2 })).toBe(false);
        }
      )
    );
  })


it("equal composite values", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.clone(complex(), 2),

        // Unit test
        ([complex1, complex2]) => {
          // Property: _if_ two complex values are considered shallowly equal,
          // then wrapping them in an array (one level) will guarantee they're
          // not shallowly equal
          if (shallow(complex1, complex2)) {
            expect(shallow([complex1], [complex2])).toBe(false);
          }

          // Ditto for objects
          if (shallow(complex1, complex2)) {
            expect(shallow({ k: complex1 }, { k: complex2 })).toBe(false);
          }
        }
      )
    );
  })


it("consistency", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.oneof(
          fc.tuple(anything(), anything()),

          // Add a few clones in the mix too, to ensure we'll have different and equal values
          fc.clone(anything(), 2)
        ),

        // Unit test
        ([value1, value2]) => {
          // _If_ sticking these values in an array makes them shallow-equal,
          // then they should also always be equal without the array wrappers
          if (shallow([value1], [value2])) {
            expect(shallow(value1, value2)).toBe(true);
          }

          if (shallow({ k: value1 }, { k: value2 })) {
            expect(shallow(value1, value2)).toBe(true);
          }
        }
      )
    );
  })


it("argument ordering does not matter", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.oneof(
          fc.tuple(anything(), anything()),

          // Add a few clones in the mix too, to ensure we'll have different and equal values
          fc.clone(anything(), 2)
        ),

        // Unit test
        ([value1, value2]) => {
          // Order doesn't matter when comparing
          expect(shallow(value1, value2)).toBe(shallow(value2, value1));
        }
      )
    );
  })


it("date (and other non-pojos) are never considered equal", () => {
    fc.assert(
      fc.property(
        // Inputs
        fc.oneof(
          fc.tuple(nonpojo(), nonpojo()),

          // Add a few clones in the mix too, to ensure we'll have different and equal values
          fc.clone(nonpojo(), 2)
        ),

        // Unit test
        ([v1, v2]) => {
          expect(shallow(v1, v2)).toBe(false);
          expect(shallow([v1], [v2])).toBe(false);
          expect(shallow({ k: v1 }, { k: v2 })).toBe(false);
        }
      )
    );
  })


test("normal usage", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback = jest.fn();
          const hub = makeEventSource();

          hub.observable.subscribe(callback);
          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback).toHaveBeenCalledTimes(3);
          for (const [arg] of callback.mock.calls) {
            expect(arg).toBe(payload);
          }
        }
      )
    );
  })


test("registering multiple callbacks", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback1 = jest.fn();
          const callback2 = jest.fn();
          const hub = makeEventSource();

          hub.observable.subscribe(callback1);
          hub.notify(payload);

          hub.observable.subscribe(callback2);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback1).toHaveBeenCalledTimes(3);
          for (const [arg] of callback1.mock.calls) {
            expect(arg).toBe(payload);
          }

          expect(callback2).toHaveBeenCalledTimes(2);
          for (const [arg] of callback2.mock.calls) {
            expect(arg).toBe(payload);
          }
        }
      )
    );
  })


test("subscribing once", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback = jest.fn();
          const hub = makeEventSource();

          const dereg1 = hub.observable.subscribeOnce(callback);
          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback).toHaveBeenCalledTimes(1); // Called only once, not three times
          for (const [arg] of callback.mock.calls) {
            expect(arg).toBe(payload);
          }

          // Deregistering has no effect
          dereg1();
          hub.notify(payload);
          expect(callback).toHaveBeenCalledTimes(1); // Called only once, not three times
        }
      )
    );
  })


test("deregisering usage", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback1 = jest.fn();
          const callback2 = jest.fn();
          const hub = makeEventSource();

          const dereg1 = hub.observable.subscribe(callback1);

          // Registering the same function instance multiple times has no
          // observable effect
          const dereg2a = hub.observable.subscribe(callback2);
          const dereg2b = hub.observable.subscribe(callback2);

          hub.notify(payload);
          hub.notify(payload);

          expect(callback1).toHaveBeenCalledTimes(2); // Both get updates
          expect(callback2).toHaveBeenCalledTimes(2);

          // Deregister callback1
          dereg1();

          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback1).toHaveBeenCalledTimes(2); // Callback1 stopped getting updates
          expect(callback2).toHaveBeenCalledTimes(5); // Callback2 still receives updates

          // Deregister callback2
          dereg2a();

          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback1).toHaveBeenCalledTimes(2); // Callback1 already stopped getting updates before
          expect(callback2).toHaveBeenCalledTimes(5); // Callback2 now also stopped getting them

          // Deregister callback2 again (has no effect)
          dereg2b();

          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback1).toHaveBeenCalledTimes(2); // Callback1 already stopped getting updates before
          expect(callback2).toHaveBeenCalledTimes(5); // Callback2 already stopped getting updates before
        }
      )
    );
  })


test("pausing/continuing event delivery", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback = jest.fn();
          const hub = makeBufferableEventSource();

          const unsub = hub.observable.subscribe(callback);

          hub.pause();
          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback).not.toHaveBeenCalled(); // No events get delivered until unpaused

          hub.unpause();
          expect(callback).toHaveBeenCalledTimes(3); // Buffered events get delivered

          // Deregister callback
          unsub();
        }
      )
    );
  })


test("[prop] whatever value you initialize it with is what comes out", () => {
  fc.assert(
    fc.property(
      fc.anything(),

      (value) => {
        const signal = new Signal(value);
        expect(signal.get()).toBe(value);
      }
    )
  );
})


test("[prop] setting works with any value", () => {
  fc.assert(
    fc.property(
      fc.anything(),
      fc.anything(),

      (init, newVal) => {
        const signal = new Signal(init);
        expect(signal.get()).toBe(init);

        signal.set(newVal);
        expect(signal.get()).toBe(newVal);
      }
    )
  );
})


test("[prop] will freeze all given values", () => {
  fc.assert(
    fc.property(
      fc.anything().filter((x) => x !== null && x !== undefined),
      fc.anything().filter((x) => x !== null && x !== undefined),

      (init, newVal) => {
        // Freezes in constructor
        const signal = new Signal(init);
        expect(signal.get()).toBe(init);

        /* eslint-disable @typescript-eslint/no-unsafe-return */
        expect(() => {
          // @ts-expect-error - deliberately set invalid prop
          signal.get().abc = 123;
        }).toThrow(TypeError);

        // @ts-expect-error - get prop
        expect(signal.get().abc).toBe(undefined);

        // Freezes in setter
        signal.set(newVal);

        expect(() => {
          // @ts-expect-error - deliberately set invalid prop
          signal.get().xyz = 456;
        }).toThrow(TypeError);

        // @ts-expect-error - get prop
        expect(signal.get().xyz).toBe(undefined);
        /* eslint-enable @typescript-eslint/no-unsafe-return */
      }
    )
  );
})


test("[prop] whatever value you initialize it with is what comes out", () => {
  fc.assert(
    fc.property(
      anyObject,

      (value) => {
        const signal = new MutableSignal(value);
        expect(signal.get()).toBe(value);
      }
    )
  );
})


test("[prop] mutating works with any value", () => {
  fc.assert(
    fc.property(
      anyObject,
      fc.anything(),

      (init, newVal) => {
        const signal = new MutableSignal(init);
        expect(signal.get()).toBe(init);

        signal.mutate((x) => {
          // @ts-expect-error deliberately mutate
          x.whatever = newVal;
        });
        expect(signal.get()).toBe(init);

        // But the mutation happened
        expect(
          // @ts-expect-error deliberately access
          signal.get().whatever
        ).toBe(newVal);
      }
    )
  );
})


it('should not hit the instruction limit with chunking', async () => {
            const actor = await getCanisterActor<Actor>('canister');

            await fc.assert(
                fc.asyncProperty(fc.nat({ max }), async (constant) => {
                    const instructions = await actor.measureSum(
                        20_000_000 + 1_000_000 * constant,
                        true
                    );

                    expect(instructions).toBeGreaterThanOrEqual(
                        updateCallInstructionLimit
                    );
                }),
                defaultPropTestParams()
            );
        })

Summary: Chunking ensures the measured instructions for a sum operation exceed or meet the update call instruction limit.


it('has no certified data if none is set', async () => {
            await fc.assert(
                fc.asyncProperty(
                    fc.uint8Array({ minLength: 0, maxLength: 32 }),
                    async (data) => {
                        const agent = await createAuthenticatedAgent(whoami());
                        const actor = await getCanisterActor<Actor>(
                            CANISTER_NAME,
                            {
                                agent
                            }
                        );
                        uninstallCanister(); // to clear any existing certified data
                        deployCanister();

                        // Check that getCertificate returns an empty array initially
                        await testCertifiedData(
                            new Uint8Array(),
                            actor,
                            agent,
                            CANISTER_NAME
                        );

                        // Set the certified data
                        await actor.setData(data);

                        // Check that getCertificate now returns the set data
                        await testCertifiedData(
                            data,
                            actor,
                            agent,
                            CANISTER_NAME
                        );
                    }
                ),
                defaultPropTestParams()
            );
        })

Summary: The function verifies that initially, a canister has no certified data, and after setting certified data, it returns the correct data.


it('should return the caller principal for query and update', async () => {
            await fc.assert(
                fc.asyncProperty(
                    fc.uint8Array({ minLength: 32, maxLength: 32 }),
                    async (bytes) => {
                        const identity = Ed25519KeyIdentity.generate(bytes);
                        const identityPrincipalText = identity
                            .getPrincipal()
                            .toText();

                        const actor = await getCanisterActor<Actor>(
                            'canister',
                            {
                                identity
                            }
                        );

                        const queryCaller = await actor.getQueryCaller();
                        const updateCaller = await actor.getUpdateCaller();

                        expect(queryCaller.toText()).toBe(
                            identityPrincipalText
                        );
                        expect(updateCaller.toText()).toBe(
                            identityPrincipalText
                        );
                    }
                ),
                defaultPropTestParams()
            );
        })

Summary: The function should return the caller's principal for both query and update calls, verifying that it matches the identity created from a generated byte array.


UnitTest.test('ShadowDom - SelectorFind.descendant', () => {
  if (SugarShadowDom.isSupported()) {
    fc.assert(fc.property(htmlBlockTagName(), htmlInlineTagName(), fc.hexaString(), (block, inline, text) => {
      withShadowElement((ss) => {
        const id = 'theid';
        const inner = SugarElement.fromHtml(`<${block}><p>hello<${inline} id="${id}">${text}</${inline}></p></${block}>`);
        Insert.append(ss, inner);

        const frog: SugarElement<Element> = SelectorFind.descendant(ss, `#${id}`).getOrDie('Element not found');
        Assert.eq('textcontent', text, frog.dom.textContent);
      });
    }));
  }
})


UnitTest.test('All valid floats are valid', () => {
  fc.assert(fc.property(fc.oneof(
    // small to medium floats
    fc.float(),
    // big floats
    fc.tuple(fc.float(), fc.integer(-20, 20)).map(([ mantissa, exponent ]) => mantissa * Math.pow(10, exponent))
  ), (num) => {
    const parsed = Dimension.parse(num.toString(), [ 'empty' ]).getOrDie();
    Assert.eq('Number is unchanged by stringifying and parsing', num, parsed.value);
    Assert.eq('Unit is empty', '', parsed.unit);
    return true;
  }));
})


UnitTest.test('All valid integers are valid', () => {
  fc.assert(fc.property(fc.integer(), (num) => {
    const parsed = Dimension.parse(num.toString(), [ 'empty' ]).getOrDie();
    Assert.eq('Number is unchanged by stringifying and parsing', num, parsed.value);
    Assert.eq('Unit is empty', '', parsed.unit);
    return true;
  }));
})


it('cell(x).get() === x', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      const cell = Cell(i);
      assert.equal(cell.get(), i);
    }));
  })


roundtrip = <const S extends Schema>(s: S) =>
  fc.assert(fc.property(decoded(s), x => roundtripWith(s, x)))

Summary: The property ensures that encoding and then decoding a value, twice in succession, yields consistent and identical intermediate encoded and decoded results for a given schema.


it('cell.get() === last set call', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), fc.integer(), (a, b, c) => {
      const cell = Cell(a);
      assert.equal(cell.get(), a);
      cell.set(b);
      assert.equal(cell.get(), b);
      cell.set(c);
      assert.equal(cell.get(), c);
    }));
  })


it('Error is thrown if not all arguments are supplied', () => {
    fc.assert(fc.property(arbAdt, fc.array(arbKeys, 1, 40), (subject, exclusions) => {
      const original = Arr.filter(allKeys, (k) => !Arr.contains(exclusions, k));

      try {
        const branches = Arr.mapToObject(original, () => Fun.identity);
        subject.match(branches);
        return false;
      } catch (err: any) {
        return err.message.indexOf('nothing') > -1;
      }
    }));
  })


it('adt.nothing.match should pass [ ]', () => {
    fc.assert(fc.property(arbNothing, (subject) => {
      const contents = subject.match({
        nothing: record,
        unknown: Fun.die('should not be unknown'),
        exact: Fun.die('should not be exact')
      });
      assert.deepEqual(contents, []);
    }));
  })


it('adt.nothing.match should be same as fold', () => {
    fc.assert(fc.property(arbNothing, (subject) => {
      const matched = subject.match({
        nothing: record,
        unknown: Fun.die('should not be unknown'),
        exact: Fun.die('should not be exact')
      });

      const folded = subject.fold(record, Fun.die('should not be unknown'), Fun.die('should not be exact'));
      assert.deepEqual(folded, matched);
    }));
  })


it('adt.unknown.match should pass 1 parameter: [ guesses ]', () => {
    fc.assert(fc.property(arbUnknown, (subject) => {
      const contents = subject.match({
        nothing: Fun.die('should not be nothing'),
        unknown: record,
        exact: Fun.die('should not be exact')
      });
      assert.deepEqual(contents.length, 1);
    }));
  })


it('adt.unknown.match should be same as fold', () => {
    fc.assert(fc.property(arbUnknown, (subject) => {
      const matched = subject.match({
        nothing: Fun.die('should not be nothing'),
        unknown: record,
        exact: Fun.die('should not be exact')
      });

      const folded = subject.fold(Fun.die('should not be nothing'), record, Fun.die('should not be exact'));
      assert.deepEqual(folded, matched);
    }));
  })


it('adt.exact.match should pass 2 parameters [ value, precision ]', () => {
    fc.assert(fc.property(arbExact, (subject) => {
      const contents = subject.match({
        nothing: Fun.die('should not be nothing'),
        unknown: Fun.die('should not be unknown'),
        exact: record
      });
      assert.deepEqual(contents.length, 2);
    }));
  })


it('adt.exact.match should be same as fold', () => {
    fc.assert(fc.property(arbExact, (subject) => {
      const matched = subject.match({
        nothing: Fun.die('should not be nothing'),
        unknown: Fun.die('should not be unknown'),
        exact: record
      });

      const folded = subject.fold(Fun.die('should not be nothing'), Fun.die('should not be unknown'), record);
      assert.deepEqual(folded, matched);
    }));
  })


it('adt.match must have the right arguments, not just the right number', () => {
    fc.assert(fc.property(arbAdt, (subject) => {
      try {
        subject.match({
          not: Fun.identity,
          the: Fun.identity,
          right: Fun.identity
        });
        return false;
      } catch (err: any) {
        return err.message.indexOf('nothing') > -1;
      }
    }));
  })


it('leftTrim(whitespace + s) === leftTrim(s)', () => {
    fc.assert(fc.property(
      fc.string(),
      (s) => {
        assert.equal(Strings.lTrim(s), Strings.lTrim(' ' + s));
      }
    ));
  })


it('rightTrim(s + whitespace) === rightTrim(s)', () => {
    fc.assert(fc.property(
      fc.string(),
      (s) => {
        assert.equal(Strings.rTrim(s), Strings.rTrim(s + ' '));
      }
    ));
  })


it('trim(whitespace + s) === trim(s)', () => {
    fc.assert(fc.property(
      fc.string(),
      (s) => {
        assert.equal(Strings.trim(s), Strings.trim(' ' + s));
      }
    ));
  })


it('trim(s + whitespace) === trim(s)', () => {
    fc.assert(fc.property(
      fc.string(),
      (s) => {
        assert.equal(Strings.trim(s), Strings.trim(s + ' '));
      }
    ));
  })


it('trim(whitespace + s + whitespace) === trim(s)', () => {
    fc.assert(fc.property(
      fc.string(),
      (s) => {
        assert.equal(Strings.trim(s), Strings.trim(' ' + s + ' '));
      }
    ));
  })


it('Optionals.cat of only nones should be an empty array', () => {
    fc.assert(fc.property(
      fc.array(ArbDataTypes.arbOptionalNone()),
      (options) => {
        const output = Optionals.cat(options);
        assert.deepEqual(output, []);
      }
    ));
  })


it('Optionals.cat of only somes should have the same length', () => {
    fc.assert(fc.property(
      fc.array(ArbDataTypes.arbOptionalSome(fc.integer())),
      (options) => {
        const output = Optionals.cat(options);
        assert.lengthOf(output, options.length);
      }
    ));
  })


it('Optionals.cat of Arr.map(xs, Optional.some) should be xs', () => {
    fc.assert(fc.property(
      fc.array(fc.json()),
      (arr) => {
        const options = Arr.map(arr, Optional.some);
        const output = Optionals.cat(options);
        assert.deepEqual(output, arr);
      }
    ));
  })


it('Optionals.cat of somes and nones should have length <= original', () => {
    fc.assert(fc.property(
      fc.array(ArbDataTypes.arbOptional(fc.integer())),
      (arr) => {
        const output = Optionals.cat(arr);
        assert.isAtMost(output.length, arr.length);
      }
    ));
  })


it('Optionals.cat of nones.concat(somes).concat(nones) should be somes', () => {
    fc.assert(fc.property(
      fc.array(fc.json()),
      fc.array(fc.json()),
      fc.array(fc.json()),
      (before, on, after) => {
        const beforeNones: Optional<string>[] = Arr.map(before, Optional.none);
        const afterNones = Arr.map(after, Optional.none);
        const onSomes = Arr.map(on, Optional.some);
        const output = Optionals.cat(beforeNones.concat(onSomes).concat(afterNones));
        assert.deepEqual(output, on);
      }
    ));
  })


it('value(x) = value(x)', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      assertResult(Result.value<number, string>(i), Result.value<number, string>(i));
    }));
  })


it('error(x) = error(x)', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      assertResult(Result.error<string, number>(i), Result.error<string, number>(i));
    }));
  })


it('value(a) != error(e)', () => {
    fc.assert(fc.property(fc.integer(), fc.string(), (a, e) => {
      assert.isFalse(tResult(tNumber, tString).eq(
        Result.value<number, string>(a),
        Result.error<number, string>(e)
      ));

      assert.isFalse(tResult(tNumber, tString).eq(
        Result.error<number, string>(e),
        Result.value<number, string>(a)
      ));
    }));
  })


it('(a = b) = (value(a) = value(b))', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), (a, b) => {
      assert.equal(tResult(tNumber, tString).eq(
        Result.value<number, string>(a),
        Result.value<number, string>(b)
      ), a === b);
    }));
  })


it('(a = b) = (error(a) = error(b))', () => {
    fc.assert(fc.property(fc.string(), fc.string(), (a, b) => {
      assert.equal(tResult(tNumber, tString).eq(
        Result.error<number, string>(a),
        Result.error<number, string>(b)
      ), a === b);
    }));
  })


it('ResultInstances.pprint', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      assert.equal(Pprint.render(Result.value(i), tResult(tNumber, tString)), `Result.value(
  ${i}
)`);

      assert.equal(Pprint.render(Result.error(i), tResult(tString, tNumber)), `Result.error(
  ${i}
)`);
    }));
  })


it('Single some value', () => {
    fc.assert(fc.property(fc.integer(), (n) => {
      assertOptional(Optionals.sequence([ Optional.some(n) ]), Optional.some([ n ]));
    }));
  })


it('Two some values', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), (n, m) => {
      assertOptional(Optionals.sequence<number>([ Optional.some(n), Optional.some(m) ]), Optional.some([ n, m ]));
    }));
  })


it('Array of numbers', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (n) => {
      const someNumbers = Arr.map(n, (x) => Optional.some(x));
      assertOptional(Optionals.sequence<number>(someNumbers), Optional.some(n));
    }));
  })


it('Some then none', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (n) => {
      const someNumbers = Arr.map(n, (x) => Optional.some(x));
      assertNone(Optionals.sequence<number>([ ...someNumbers, Optional.none<number>() ]));
    }));
  })


it('None then some', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (n) => {
      const someNumbers = Arr.map(n, (x) => Optional.some(x));
      assertNone(Optionals.sequence<number>([ Optional.none<number>(), ...someNumbers ]));
    }));
  })

Summary: `Optionals.sequence` returns none when the sequence starts with an optional none element.


it('flattens some(some(x)) to some(x)', () => {
    fc.assert(fc.property(fc.integer(), (n) => {
      assertOptional(Optionals.flatten(Optional.some(Optional.some<number>(n))), Optional.some(n));
    }));
  })

Summary: Flattening a nested `some(some(x))` should result in `some(x)`.


it('Optional.some(x) !== Optional.none()', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      assert.isFalse((Optionals.equals(Optional.some(i), Optional.none())));
    }));
  })

Summary: `Optionals.equals` returns false when comparing `Optional.some(x)` with `Optional.none()`.


it('Optional.some(x) === Optional.some(x)', () => {
    fc.assert(fc.property(fc.integer(), (i) => assert.isTrue(Optionals.equals(Optional.some(i), Optional.some(i)))));
  })

Summary: `Optional.some(x)` is equal to `Optional.some(x)` using `Optionals.equals` for any integer `x`.


it('Optional.some(x) !== Optional.some(x + y) where y is not identity', () => {
    fc.assert(fc.property(fc.string(), fc.string(1, 40), (a, b) => {
      assert.isFalse(Optionals.equals(Optional.some(a), Optional.some(a + b)));
    }));
  })

Summary: `Optional.some(x)` is not equal to `Optional.some(x + y)` where `y` is a non-identity value.


it('Checking Optionals.equals(some(x), some(y), _, _ -> true) === true', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), (a, b) => {
      const opt1 = Optional.some(a);
      const opt2 = Optional.some(b);
      assert.isTrue(Optionals.equals(opt1, opt2, Fun.always));
    }));
  })

Summary: `Optionals.equals` should return true when both are `Optional.some` regardless of differing integer values, using a function that always returns true.


it('Checking some(x).is(x) === true', () => {
    fc.assert(fc.property(fc.integer(), (json) => {
      const opt = Optional.some(json);
      assert.isTrue(Optionals.is(opt, json));
    }));
  })

Summary: `Optional.some(x)` should return true when checked with `Optionals.is(opt, x)`.


it('Checking some(x).getOrThunk(_ -> v) === x', () => {
    fc.assert(fc.property(fc.integer(), fc.func(fc.integer()), (a, thunk) => {
      assert.equal(Optional.some(a).getOrThunk(thunk), a);
    }));
  })

Summary: `Optional.some(a).getOrThunk(thunk)` should return `a`.


it('Checking some.getOrDie() never throws', () => {
    fc.assert(fc.property(fc.integer(), fc.string(1, 40), (i, s) => {
      const opt = Optional.some(i);
      opt.getOrDie(s);
    }));
  })

Summary: `Optional.some().getOrDie()` does not throw an exception regardless of the integer value or string message provided.


it('Given f :: s -> none, checking some(x).bind(f) === none', () => {
    fc.assert(fc.property(arbOptionSome(fc.integer()), fc.func(arbOptionNone()), (opt, f) => {
      const actual = opt.bind(f);
      assertNone(actual);
    }));
  })

Summary: Ensures that binding a function returning `none` to `some(x)` results in `none`.


it('Checking some(x).exists(_ -> false) === false', () => {
    fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => !opt.exists(Fun.never)));
  })

Summary: The `exists` method on a `Some` instance with a function that always returns false should itself return false.


it('Checking some(x).exists(_ -> true) === true', () => {
    fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => opt.exists(Fun.always)));
  })

Summary: The `exists` function should return true when applied with a function that always returns true on a `some(x)` optional.


it('Checking none.fold(_ -> x, die) === x', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      const actual = Optional.none<string>().fold(Fun.constant(i), Fun.die('Should not be called'));
      assert.equal(actual, i);
    }));
  })

Summary: `Optional.none` with `fold` using a constant function for the first argument returns the constant value.


it('Checking none.is === false', () => {
    fc.assert(fc.property(fc.integer(), (v) => {
      assert.isFalse(Optionals.is(Optional.none(), v));
    }));
  })

Summary: `Optionals.is` returns false when comparing `Optional.none()` with any integer.


it('Checking none.getOr(v) === v', () => {
    fc.assert(fc.property(fc.integer(), (i) => {
      assert.equal(Optional.none<number>().getOr(i), i);
    }));
  })

Summary: `Optional.none<number>().getOr(i)` should return the integer `i`.


it('none is not some', () => {
    assert.isFalse(Optional.none().isSome());
    fc.assert(fc.property(fc.anything(), (x) => {
      assert.isTrue(Optional.some(x).isSome());
    }));
  })

Summary: `Optional.none()` returns false for `isSome()`, while `Optional.some(x)` returns true for `isSome()` for any `x`.


it('Optional.isNone', () => {
    assert.isTrue(Optional.none().isNone());
    fc.assert(fc.property(fc.anything(), (x) => {
      assert.isFalse(Optional.some(x).isNone());
    }));
  })

Summary: `Optional.isNone` returns true for `Optional.none()` and false for `Optional.some(x)`.


it('Optional.getOr', () => {
    fc.assert(fc.property(fc.integer(), (x) => {
      assert.equal(Optional.none().getOr(x), x);
      assert.equal(Optional.none().getOrThunk(() => x), x);
    }));
    fc.assert(fc.property(fc.integer(), fc.integer(), (x, y) => {
      assert.equal(Optional.some(x).getOr(y), x);
      assert.equal(Optional.some(x).getOrThunk(Fun.die('boom')), x);
    }));
  })

Summary: `Optional.getOr` returns the provided fallback value for `Optional.none()`; `Optional.some(x).getOr` returns the contained value `x`, bypassing the fallback.


it('Checking some(x).filter(_ -> false) === none', () => {
    fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => {
      assertNone(opt.filter(Fun.never));
    }));
  })

Summary: Filtering an `Option` with a function that always returns false results in `none`.


it('Checking some(x).filter(_ -> true) === some(x)', () => {
    fc.assert(fc.property(fc.integer(), (x) => {
      assertSome(some(x).filter(Fun.always), x);
    }));
  })

Summary: `some(x).filter(Fun.always)` should yield `some(x)`.


it('Checking some(x).filter(f) === some(x) iff. f(x)', () => {
    fc.assert(fc.property(fc.integer(), fc.func(fc.boolean()), (i, f) => {
      if (f(i)) {
        assertSome(some(i).filter(f), i);
      } else {
        assertNone(some(i).filter(f));
      }
    }));
  })

Summary: The property checks that `some(x).filter(f)` returns `some(x)` if `f(x)` is true, and `none` otherwise.


it('fails for some vs none', () => {
    fc.assert(fc.property(fc.nat(), (n) => {
      assert.throw(() => {
        assertOptional(Optional.some(n), Optional.none());
      });
    }));
  })

Summary: The test checks that `assertOptional` throws an error when comparing `Optional.some(n)` with `Optional.none()`.


it('passes for identical somes', () => {
    fc.assert(fc.property(fc.nat(), (n) => {
      assertOptional(Optional.some(n), Optional.some(n));
    }));
  })

Summary: `assertOptional` should pass when comparing identical `Optional.some` instances containing the same value.


it('StringMatch.matches(StringMatch.exact(s), s1 + s) === false', () => {
    fc.assert(fc.property(
      fc.string(1, 40),
      fc.string(1, 40),
      (s, s1) => {
        assert.isFalse(StringMatch.matches(
          StringMatch.exact(s, StringMatch.caseInsensitive),
          s1 + s
        ));
      }
    ));
  })

Summary: `StringMatch.matches` should return false when checking if a concatenated string (`s1 + s`) exactly matches a given string `s`, even with case insensitivity.


it('StringMatch.matches(StringMatch.exact(s), s) === false when different case and case-insensitive', () => {
    fc.assert(fc.property(
      fc.asciiString(1, 40),
      (s) => s.toUpperCase() === s.toLowerCase() || StringMatch.matches(
        StringMatch.exact(s.toLowerCase(), StringMatch.caseInsensitive),
        s.toUpperCase()
      )
    ));
  })

Summary: `StringMatch.matches` should return true for exact matches when case-insensitive and the strings differ only in case.


it('StringMatch.matches(StringMatch.exact(s), s) === false when different case and case-sensitive', () => {
    fc.assert(fc.property(
      fc.asciiString(1, 40),
      (s) => s.toUpperCase() === s.toLowerCase() || !StringMatch.matches(
        StringMatch.exact(s.toLowerCase(), StringMatch.caseSensitive),
        s.toUpperCase()
      )
    ));
  })

Summary: `StringMatch.matches` should return false when comparing a string to its differently cased version using `exact` and case sensitivity.


it('StringMatch.matches(StringMatch.all(s1), *) === true', () => {
    fc.assert(fc.property(
      fc.string(),
      fc.string(),
      (s) => {
        assert.isTrue(StringMatch.matches(
          StringMatch.all(),
          s
        ));
      }
    ));
  })

Summary: `StringMatch.matches` always returns true when using `StringMatch.all` as the matcher, regardless of the input string.


it('positive range', () => {
    fc.assert(fc.property(fc.char(), fc.integer(1, 100), (c, count) => {
      const actual = Strings.repeat(c, count);
      assert.equal(actual.length, count);
      assert.equal(actual.charAt(0), c);
      assert.equal(actual.charAt(actual.length - 1), c);
    }));

    fc.assert(fc.property(fc.asciiString(5), fc.integer(1, 100), (s, count) => {
      const actual = Strings.repeat(s, count);
      assert.equal(actual.length, count * s.length);
      assert.equal(actual.indexOf(s), 0);
      assert.equal(actual.lastIndexOf(s), actual.length - s.length);
    }));
  })


it('An empty string should contain nothing', () => {
    fc.assert(fc.property(
      fc.string(1, 40),
      (value) => !Strings.contains('', value)
    ));
  })

Summary: An empty string should not contain any other string.


it('tail of the string is unchanged', () => {
    fc.assert(fc.property(fc.ascii(), fc.asciiString(30), (h, t) => {
      assert.equal(Strings.capitalize(h + t).substring(1), t);
    }));
  })

Summary: The test ensures that capitalizing a string changes only the first character, leaving the rest of the string unchanged.


it('should have an adjustment of delta, or be the min or max', () => {
    fc.assert(fc.property(
      fc.nat(),
      fc.integer(),
      fc.nat(),
      fc.nat(),
      (value, delta, min, range) => {
        const max = min + range;
        const actual = Num.cycleBy(value, delta, min, max);
        return (actual - value) === delta || actual === min || actual === max;
      }
    ));
  })

Summary: The `Num.cycleBy` function should return a value adjusted by delta or equal to the specified minimum or maximum.


it('0 has no effect', () => {
    fc.assert(fc.property(fc.nat(), fc.nat(), (value, delta) => {
      const actual = Num.cycleBy(value, 0, value, value + delta);
      assert.equal(actual, value);
    }));
  })

Summary: Calling `Num.cycleBy` with a cycle argument of `0` returns the original value unchanged.


it('mirrors bind', () => {
      const arbInner = fc.tuple(fc.boolean(), fc.string()).map(([ isJust, value ]) => {
        if (isJust) {
          return Maybes.just(value);
        } else {
          return Maybes.nothing<string>();
        }
      });
      const arbNested = fc.tuple(fc.boolean(), arbInner).map(([ isJust, value ]) => {
        if (isJust) {
          return Maybes.just(value);
        } else {
          return Maybes.nothing<Maybe<string>>();
        }
      });
      fc.assert(fc.property(arbNested, (maybe) => {
        const flattened = Maybes.flatten(maybe);
        const bound = Maybes.bind<Maybe<string>, string>(Fun.identity)(maybe);
        assert.deepEqual(flattened, bound);
      }));
    })

Summary: Flattening a nested `Maybe` structure should yield the same result as binding with the identity function.


it('is always false for "Nothing"', () => {
      fc.assert(fc.property(fc.anything(), (thing) => {
        const matches = Fun.pipe(
          Maybes.nothing(),
          Maybes.is(thing)
        );

        assert.isFalse(matches);
      }));
    })

Summary: `Maybes.is` returns false when comparing "Nothing" to any value.


it('is always false for "Nothing" with explicit comparator', () => {
      fc.assert(fc.property(fc.anything(), (thing) => {
        const matches = Fun.pipe(
          Maybes.nothing(),
          Maybes.is(thing, Fun.die('should not be called'))
        );

        assert.isFalse(matches);
      }));
    })

Summary: `Maybes.is` returns false when comparing "Nothing" with any value using an explicit comparator.


it('is correct for "Just"', () => {
      fc.assert(fc.property(fc.string(), (thing) => {
        const matches = Fun.pipe(
          Maybes.just(thing),
          Maybes.is(thing)
        );

        assert.isTrue(matches);
      }));

      fc.assert(fc.property(fc.string(), (thing) => {
        const matches = Fun.pipe(
          Maybes.just(thing),
          Maybes.is(thing + 'foo')
        );

        assert.isFalse(matches);
      }));
    })

Summary: The property checks that `Maybes.is` returns true for a "Just" value containing the same string and false for a "Just" value with a different string.


it('is correct for "Just" with an explicit comparator', () => {

      // Just an example data type that doesn't have a simple equality
      const thunkEq = (a: () => string, b: () => string): boolean => a() === b();

      fc.assert(fc.property(fc.string(), (thing) => {
        const matches = Fun.pipe(
          Maybes.just(Fun.constant(thing)),
          Maybes.is(Fun.constant(thing), thunkEq)
        );

        assert.isTrue(matches);
      }));

      fc.assert(fc.property(fc.string(), (thing) => {
        const matches = Fun.pipe(
          Maybes.just(Fun.constant(thing)),
          Maybes.is(() => thing + 'foo', thunkEq)
        );

        assert.isFalse(matches);
      }));
    })

Summary: The comparison of "Just" values using an explicit comparator should return true if the provided comparator confirms equality and false if it does not.


Summary: Verification that a "Just" value with an explicit comparator matches the expected value when the thunk evaluates to the same result, and does not match when it evaluates to a different result.


it('is false for one "Nothing"', () => {
      fc.assert(fc.property(fc.anything(), (thing) => {
        assert.isFalse(Maybes.equals(Maybes.nothing(), Maybes.just(thing)));
        assert.isFalse(Maybes.equals(Maybes.just(thing), Maybes.nothing()));
      }));
    })

Summary: `Maybes.equals` returns false when comparing `Maybes.nothing()` with `Maybes.just(thing)`.


it('Check constant :: constant(a)() === a', () => {
    fc.assert(fc.property(fc.json(), (json) => {
      assert.deepEqual(Fun.constant(json)(), json);
    }));
  })

Summary: `Fun.constant(json)()` should always return the original `json` value.


it('Check identity :: identity(a) === a', () => {
    fc.assert(fc.property(fc.json(), (json) => {
      assert.deepEqual(Fun.identity(json), json);
    }));
  })

Summary: The function `Fun.identity` should return the input `json` exactly as it is.


it('Check curry', () => {
    fc.assert(fc.property(fc.json(), fc.json(), fc.json(), fc.json(), (a, b, c, d) => {
      const f = (a: string, b: string, c: string, d: string) => [ a, b, c, d ];

      assert.deepEqual([ a, b, c, d ], Fun.curry(f, a)(b, c, d));
      assert.deepEqual([ a, b, c, d ], Fun.curry(f, a, b)(c, d));
      assert.deepEqual([ a, b, c, d ], Fun.curry(f, a, b, c)(d));
      assert.deepEqual([ a, b, c, d ], Fun.curry(f, a, b, c, d)());
    }));
  })

Summary: The test verifies that the `Fun.curry` function correctly applies partial application to a four-argument function, preserving the order and values of arguments.


it('Check apply :: apply(constant(a)) === a', () => {
    fc.assert(fc.property(fc.json(), (x) => {
      assert.deepEqual(Fun.apply(Fun.constant(x)), x);
    }));
  })

Summary: Applying `Fun.constant(x)` should return `x`.


it('Check that values should be empty and  errors should be all if we only generate errors', () => {
    fc.assert(fc.property(
      fc.array(arbResultError(fc.integer())),
      (resErrors) => {
        const actual = Results.partition(resErrors);
        if (actual.values.length !== 0) {
          assert.fail('Values length should be 0');
        } else if (resErrors.length !== actual.errors.length) {
          assert.fail('Errors length should be ' + resErrors.length);
        }
        return true;
      }
    ));
  })

Summary: The result of partitioning an array of error results should have no values and all the errors.


it('Checking value.fold(die, id) === value.getOrDie()', () => {
    fc.assert(fc.property(arbResultValue(fc.integer()), (res) => {
      const actual = res.getOrDie();
      assert.equal(res.fold(Fun.die('should not get here'), Fun.identity), actual);
    }));
  })

Summary: `value.fold(die, id)` should be equal to `value.getOrDie()`.


it('Checking value.map(f) === f(value.getOrDie())', () => {
    fc.assert(fc.property(arbResultValue(fc.integer()), fc.func(fc.json()), (res, f) => {
      assert.equal(f(res.getOrDie()), res.map(f).getOrDie());
    }));
  })

Summary: The property ensures that mapping a function over a `ResultValue` yields the same result as directly applying the function to the value obtained from `getOrDie()`.


it('Checking value.each(f) === undefined', () => {
    fc.assert(fc.property(arbResultValue(fc.integer()), fc.func(fc.json()), (res, f) => {
      const actual = res.each(f);
      assert.isUndefined(actual);
    }));
  })

Summary: `ResultValue.each(f)` should always return `undefined` when applied to any function `f`.


test('no picking lower bound 0 for upper alarm', () => {
    fc.assert(fc.property(
      arbitrary_complete_intervals(),
      (intervals) => {
        const alarms = findAlarmThresholds(intervals);
        fc.pre(alarms.upperAlarmIntervalIndex !== undefined);

        return intervals[alarms.upperAlarmIntervalIndex!].lower !== 0;
      },
    ));
  })

Summary: The test ensures that when determining alarm thresholds, the lower bound of the interval for an upper alarm is never 0.


it('Given f :: s -> RE, checking value.bind(f).fold(id, die) === f(value.getOrDie()).fold(id, die)', () => {
    fc.assert(fc.property(arbResultValue<number, number>(fc.integer()), fc.func(arbResultError<number, number>(fc.integer())), (res, f) => {
      const toErrString = (r: Result<number, number>) => r.fold(Fun.identity, Fun.die('Not a Result.error'));
      assert.equal(toErrString(f(res.getOrDie())), toErrString(res.bind(f)));
    }));
  })

Summary: For a function `f`, applying `bind(f)` to a `Result` value and folding it should equal applying `f` directly to the resolved value and folding that result.


it('error.each returns undefined', () => {
    fc.assert(fc.property(arbResultError(fc.integer()), (res) => {
      const actual = res.each(Fun.die('should not be called'));
      assert.isUndefined(actual);
    }));
  })

Summary: `res.each` returns undefined when executed with `Fun.die('should not be called')` on `arbResultError`.


it('Given f :: s -> RV, error.bind(f) === error', () => {
    fc.assert(fc.property(arbResultError<number, number>(fc.integer()), fc.func(arbResultValue<number, number>(fc.integer())), (res, f) => {
      const actual = res.bind(f);
      assert.deepEqual(getErrorOrDie(actual), getErrorOrDie(res));
    }));
  })

Summary: Binding a function to a `ResultError` should yield the same `ResultError`.


it('pure', () =>
    fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
      LazyValue.pure(i).get((v) => {
        eqAsync('LazyValue.pure', i, v, reject);
        resolve();
      });
    }))))

Summary: `LazyValue.pure` should produce a value retrieved asynchronously that matches the original integer input.


it('map constant obj means that values(obj) are all the constant', () => {
    fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), fc.integer(), (obj, x) => {
      const output = Obj.map(obj, Fun.constant(x));
      const values = Obj.values(output);
      return Arr.forall(values, (v) => v === x);
    }));
  })

Summary: Mapping a dictionary with a constant function results in all values being the constant.


it('tupleMap obj (x, i) -> { k: i, v: x }', () => {
    fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
      const output = Obj.tupleMap(obj, (x, i) => ({ k: i, v: x }));
      assert.deepEqual(output, obj);
    }));
  })

Summary: `Obj.tupleMap` transforms an object by mapping each entry to an object with keys `k` and `v`, maintaining equivalent structure to the original.


it('If predicate is always true, then value is always the some(first), or none if dict is empty', () => {
    fc.assert(fc.property(
      fc.dictionary(fc.asciiString(), fc.json()),
      (obj) => {
        const value = Obj.find(obj, Fun.always);
        // No order is specified, so we cannot know what "first" is
        return Obj.keys(obj).length === 0 ? value.isNone() : true;
      }
    ));
  })

Summary: `Obj.find` returns some(first element) if any exists when the predicate is always true; otherwise, it returns none for an empty dictionary.


it('Deep-merge(a, b) contains all the keys of b', () => {
    fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.json()), fc.dictionary(fc.asciiString(), fc.json()), (a, b) => {
      const output = Merger.deepMerge(a, b);
      const keys = Obj.keys(b);
      const oKeys = Obj.keys(output);
      return Arr.forall(keys, (k) => {
        return Arr.contains(oKeys, k);
      });
    }));
  })

Summary: Deep-merge of two dictionaries `a` and `b` results in an output containing all the keys of `b`.


it('Check that if the filter always returns true, then everything is in "t"', () => {
    fc.assert(fc.property(
      fc.dictionary(fc.asciiString(), fc.string(1, 40)),
      (obj) => {
        const output = Obj.bifilter(obj, Fun.always);
        assert.lengthOf(Obj.keys(output.f), 0);
        assert.lengthOf(Obj.keys(output.t), Obj.keys(obj).length);
        return true;
      }
    ));
  })

Summary: If the filter always returns true, all elements should be in "t" and none in "f".


it('Check that everything in f fails predicate and everything in t passes predicate', () => {
    fc.assert(fc.property(
      fc.dictionary(fc.asciiString(1, 30), fc.integer()),
      (obj) => {
        const predicate = (x: number) => x % 2 === 0;
        const output = Obj.bifilter(obj, predicate);

        const matches = (k: string) => predicate(obj[k]);

        const falseKeys = Obj.keys(output.f);
        const trueKeys = Obj.keys(output.t);

        assert.isFalse(Arr.exists(falseKeys, matches));
        assert.isTrue(Arr.forall(trueKeys, matches));
      }
    ));
  })

Summary: Everything in the `output.f` object fails the predicate, and everything in the `output.t` object passes the predicate.


it('matches corresponding tuples', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.array(fc.integer()),
      (keys, values) => {
        if (keys.length !== values.length) {
          assert.throws(() => Zip.zipToTuples(keys, values));
        } else {
          const output = Zip.zipToTuples(keys, values);
          assert.equal(output.length, keys.length);
          assert.isTrue(Arr.forall(output, (x, i) => x.k === keys[i] && x.v === values[i]));
        }
      }
    ));
  })

Summary: `Zip.zipToTuples` creates tuples where each key corresponds correctly to its value when both arrays have the same length; otherwise, it throws an error.


it('Reversing twice is identity', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      assert.deepEqual(Arr.reverse(Arr.reverse(arr)), arr);
    }));
  })

Summary: Reversing an array twice should return the original array.


it('reverses 2 elements', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), (a, b) => {
      assert.deepEqual(Arr.reverse([ a, b ]), [ b, a ]);
    }));
  })

Summary: `Arr.reverse` reverses arrays containing exactly two elements.


it('reverses 3 elements', () => {
    fc.assert(fc.property(fc.integer(), fc.integer(), fc.integer(), (a, b, c) => {
      assert.deepEqual(Arr.reverse([ a, b, c ]), [ c, b, a ]);
    }));
  })


it('every element in the input is in the output, and vice-versa', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (xs) => {
      const rxs = Arr.reverse(xs);
      assert.isTrue(Arr.forall(rxs, (x) => Arr.contains(xs, x)));
      assert.isTrue(Arr.forall(xs, (x) => Arr.contains(rxs, x)));
    }));
  })


it('Check that if the filter always returns false, then everything is in "fail"', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        const output = Arr.partition(arr, Fun.never);
        assert.deepEqual(output.pass.length, 0);
        assert.deepEqual(output.fail, arr);
      }
    ));
  })


it('Check that if the filter always returns true, then everything is in "pass"', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        const output = Arr.partition(arr, Fun.always);
        assert.deepEqual(output.fail.length, 0);
        assert.deepEqual(output.pass, arr);
      }
    ));
  })


it('Check that everything in fail fails predicate and everything in pass passes predicate', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        const predicate = (x: number) => x % 3 === 0;
        const output = Arr.partition(arr, predicate);
        return Arr.forall(output.fail, (x) => !predicate(x)) && Arr.forall(output.pass, predicate);
      }
    ));
  })


it('inductive case', () => {
    fc.assert(fc.property(
      fc.dictionary(fc.asciiString(1, 30), fc.integer()),
      fc.asciiString(1, 30),
      fc.integer(),
      (obj, k, v) => {
        const objWithoutK = Obj.filter(obj, (x, i) => i !== k);
        assert.deepEqual(Obj.size({ [k]: v, ...objWithoutK }), Obj.size(objWithoutK) + 1);
      }), {
      numRuns: 5000
    });
  })


it('only returns elements that are in the input', () => {
    fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
      const keys = Obj.keys(obj);
      return Arr.forall(keys, (k) => obj.hasOwnProperty(k));
    }));
  })


it('filter const true is identity', () => {
    fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
      assert.deepEqual(Obj.filter(obj, Fun.always), obj);
    }));
  })


it('Length of interspersed = len(arr) + len(arr)-1', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.integer(),
      (arr, delimiter) => {
        const actual = Jam.intersperse(arr, delimiter);
        const expected = arr.length === 0 ? 0 : arr.length * 2 - 1;
        assert.deepEqual(actual.length, expected);
      }
    ));
  })


it('Every odd element matches delimiter', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.integer(),
      (arr, delimiter) => {
        const actual = Jam.intersperse(arr, delimiter);
        return Arr.forall(actual, (x, i) => i % 2 === 1 ? x === delimiter : true);
      }
    ));
  })


it('Filtering out delimiters (assuming different type to array to avoid removing original array) should equal original', () => {
    fc.assert(fc.property(
      fc.array(fc.nat()),
      arbNegativeInteger(),
      (arr, delimiter) => {
        const actual = Jam.intersperse(arr, delimiter);
        const filtered = Arr.filter(actual, (a) => a !== delimiter);
        assert.deepEqual(filtered, arr);
      }
    ));
  })


it('finds element in middle of array', () => {
    fc.assert(fc.property(fc.array(fc.nat()), arbNegativeInteger(), fc.array(fc.nat()), (prefix, element, suffix) => {
      const arr = prefix.concat([ element ]).concat(suffix);
      assertSome(Arr.indexOf(arr, element), prefix.length);
    }));
  })


it('Adjacent groups have different hashes, and everything in a group has the same hash', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.func(fc.asciiString()),
      (xs, f) => {
        const groups = Arr.groupBy(xs, (x) => f(x));

        /* Properties about groups
         * 1. No two adjacent groups can have the same g(..) value
         * 2. Each group must have the same g(..) value
         */

        const hasEmptyGroups = Arr.exists(groups, (g) => g.length === 0);

        if (hasEmptyGroups) {
          assert.fail('Should not have empty groups');
        }
        // No consecutive groups should have the same result of g.
        const values = Arr.map(groups, (group) => {
          const first = f(group[0]);
          const mapped = Arr.map(group, (g) => f(g));

          const isSame = Arr.forall(mapped, (m) => m === first);
          if (!isSame) {
            assert.fail('Not everything in a group has the same g(..) value');
          }
          return first;
        });

        const hasSameGroup = Arr.exists(values, (v, i) => i > 0 ? values[i - 1] === values[i] : false);

        if (hasSameGroup) {
          assert.fail('A group is next to another group with the same g(..) value');
        }
        return true;
      }
    ));
  })


it('Flattening groups equals the original array', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.func(fc.string()),
      (xs, f) => {
        const groups = Arr.groupBy(xs, (x) => f(x));

        const output = Arr.flatten(groups);
        assert.deepEqual(output, xs);
      }
    ));
  })


it('forall of a non-empty array with a predicate that always returns false is false', () => {
    fc.assert(fc.property(
      fc.array(fc.integer(), 1, 30),
      (xs) => {
        assert.isFalse(Arr.forall(xs, Fun.never));
      }
    ));
  })


it('forall of a non-empty array with a predicate that always returns true is true', () => {
    fc.assert(fc.property(
      fc.array(fc.integer(), 1, 30),
      (xs) => {
        assert.isTrue(Arr.forall(xs, Fun.always));
      }
    ));
  })


it('foldl concat [ ] xs === reverse(xs)', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        const output = Arr.foldl(arr, (b: number[], a: number) => [ a ].concat(b), []);
        assert.deepEqual(output, Arr.reverse(arr));
      }
    ));
  })


it('foldr concat [ ] xs === xs', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        const output = Arr.foldr(arr, (b: number[], a: number) => [ a ].concat(b), []);
        assert.deepEqual(output, arr);
      }
    ));
  })


it('foldr concat ys xs === xs ++ ys', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.array(fc.integer()),
      (xs, ys) => {
        const output = Arr.foldr(xs, (b, a) => [ a ].concat(b), ys);
        assert.deepEqual(output, xs.concat(ys));
      }
    ));
  })


it('foldl concat ys xs === reverse(xs) ++ ys', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.array(fc.integer()),
      (xs, ys) => {
        const output = Arr.foldl(xs, (b, a) => [ a ].concat(b), ys);
        assert.deepEqual(output, Arr.reverse(xs).concat(ys));
      }
    ));
  })


it('is consistent with chunking', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.integer(1, 5),
      (arr, chunkSize) => {
        const chunks = Arr.chunk(arr, chunkSize);
        const bound = Arr.flatten(chunks);
        assert.deepEqual(bound, arr);
      }
    ));
  })


it('wrap then flatten array is identity', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      assert.deepEqual(arr, Arr.flatten(Arr.pure(arr)));
    }));
  })


it('mapping pure then flattening array is identity', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      assert.deepEqual(arr, Arr.flatten(Arr.map(arr, Arr.pure)));
    }));
  })


it('flattening two lists === concat', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.array(fc.integer()), (xs, ys) => {
      assert.deepEqual(xs.concat(ys), Arr.flatten([ xs, ys ]));
    }));
  })


describe('finds element in middle of array', () => {
    fc.assert(fc.property(fc.array(fc.nat()), arbNegativeInteger(), fc.array(fc.nat()), (prefix, element, suffix) => {
      const arr = [ ...prefix, element, ...suffix ];
      assertSome(
        Arr.findIndex(arr, (x) => x === element),
        prefix.length
      );
    }));
  })


it('finds elements that pass the predicate', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      const pred = (x: number) => x % 3 === 0;
      assert.isTrue(Arr.findIndex(arr, pred).forall((x) => pred(arr[x])));
    }));
  })


it('returns none if predicate always returns false', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      assertNone(Arr.findIndex(arr, Fun.never));
    }));
  })


it('is consistent with find', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      const pred = (x: number) => x % 5 === 0;
      assertOptional(Arr.findIndex(arr, pred).map((x) => arr[x]), Arr.find(arr, pred));
    }));
  })


it('is consistent with exists', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      const pred = (x: number) => x % 6 === 0;
      assert.equal(Arr.findIndex(arr, pred).isSome(), Arr.exists(arr, pred));
    }));
  })


it('Element exists in middle of array', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), fc.array(fc.integer()), (prefix, element, suffix) => {
      const arr2 = Arr.flatten([ prefix, [ element ], suffix ]);
      assert.isTrue(Arr.exists(arr2, eqc(element)));
    }));
  })


it('Element exists in singleton array of itself', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (i) => {
      assert.isTrue(Arr.exists([ i ], eqc(i)));
    }));
  })


it('Element does not exist in empty array', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (i) => {
      assert.isFalse(Arr.exists([], eqc(i)));
    }));
  })


it('Element not found when predicate always returns false', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => !Arr.exists(arr, never)));
  })


it('Element exists in non-empty array when predicate always returns true', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (xs, x) => {
      const arr = Arr.flatten([ xs, [ x ]]);
      assert.isTrue(Arr.exists(arr, always));
    }));
  })


it('ys-xs contains no elements from xs', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.array(fc.integer()), (xs, ys) => {
      const diff = Arr.difference(ys, xs);
      return Arr.forall(xs, (x) => !Arr.contains(diff, x));
    }));
  })


it('every member of ys-xs is in ys', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.array(fc.integer()), (xs, ys) => {
      const diff = Arr.difference(ys, xs);
      return Arr.forall(diff, (d) => Arr.contains(ys, d));
    }));
  })


it('returns true when element is in array', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), fc.array(fc.integer()), (prefix, element, suffix) => {
      const arr2 = [ ...prefix, element, ...suffix ];
      assert.isTrue(Arr.contains(arr2, element));
    }));
  })


it('creates an array of the appropriate length except for the last one', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.nat(),
      (arr, rawChunkSize) => {
        // ensure chunkSize is at least one
        const chunkSize = rawChunkSize + 1;
        const chunks = Arr.chunk(arr, chunkSize);

        const numChunks = chunks.length;
        const firstParts = chunks.slice(0, numChunks - 1);

        for (const firstPart of firstParts) {
          assert.lengthOf(firstPart, chunkSize);
        }

        if (arr.length === 0) {
          assert.deepEqual(chunks, []);
        } else {
          assert.isAtMost(chunks[chunks.length - 1].length, chunkSize);
        }
      }
    ));
  })


it('is idempotent', () => {
    fc.assert(fc.property(
      fc.array(fc.nat()), (arr) => {
        assert.deepEqual(Arr.sort(Arr.sort(arr)), Arr.sort(arr));
      }
    ));
  })


it('returns last element when non-empty', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (init, last) => {
      const arr = init.concat([ last ]);
      assertSome(Arr.last(arr), last);
    }));
  })


it('returns first element when nonEmpty', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (t, h) => {
      const arr = [ h, ...t ];
      assertSome(Arr.head(arr), h);
    }));
  })


it('returns none for element of empty list', () => {
    fc.assert(fc.property(fc.integer(), (n) => {
      assertNone(Arr.get<number>([], n));
    }));
  })


it('returns some for valid index (property test)', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), fc.integer(), (array, h, t) => {
      const arr = [ h ].concat(array);
      const length = arr.push(t);
      const midIndex = Math.round(arr.length / 2);

      assertSome(Arr.get(arr, 0), h);
      assertSome(Arr.get(arr, midIndex), arr[midIndex]);
      assertSome(Arr.get(arr, length - 1), t);
    }));
  })


it('finds a value in the array', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), fc.array(fc.integer()), (prefix, i, suffix) => {
      const arr = prefix.concat([ i ]).concat(suffix);
      const pred = (x: number) => x === i;
      const result = Arr.find(arr, pred);
      assertSome(result, i);
    }));
  })


it('cannot find a nonexistent value', () => {
    fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
      const result = Arr.find(arr, Fun.never);
      assertNone(result);
    }));
  })


it('Arr.findMap of non-empty is first if f is Optional.some', () => {
    fc.assert(fc.property(
      fc.integer(),
      fc.array(fc.integer()),
      (head, tail) => {
        const arr = [ head, ...tail ];
        assertSome(Arr.findMap(arr, Optional.some), head);
      }
    ));
  })


it('Arr.findMap of non-empty is none if f is Optional.none', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      (arr) => {
        assertNone(Arr.findMap(arr, Optional.none));
      }
    ));
  })


it('Arr.findMap finds an element', () => {
    fc.assert(fc.property(
      fc.array(fc.integer()),
      fc.integer(),
      fc.integer(),
      fc.array(fc.integer()),
      (prefix, element, ret, suffix) => {
        const arr = [ ...prefix, element, ...suffix ];
        assertSome(Arr.findMap(arr, (x) => Optionals.someIf(x === element, ret)), ret);
      }
    ));
  })


it('Arr.findMap does not find an element', () => {
    fc.assert(fc.property(
      fc.array(fc.nat()),
      fc.nat(),
      (arr, ret) => {
        assertNone(Arr.findMap(arr, (x) => Optionals.someIf(x === -1, ret)));
      }
    ));
  })


it('binding an array of empty arrays with identity equals an empty array', () => {
    fc.assert(fc.property(fc.array(fc.constant<number[]>([])), (arr) => {
      assert.deepEqual(Arr.bind(arr, Fun.identity), []);
    }));
  })


it('bind (pure .) is map', () => {
    fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (arr, j) => {
      const f = (x: number) => x + j;
      assert.deepEqual(Arr.bind(arr, Fun.compose(Arr.pure, f)), Arr.map(arr, f));
    }));
  })


it('obeys left identity law', () => {
      fc.assert(fc.property(fc.integer(), fc.integer(), (i, j) => {
        const f = (x: number) => [ x, j, x + j ];
        assert.deepEqual(Arr.bind(Arr.pure(i), f), f(i));
      }));
    })


it('obeys right identity law', () => {
      fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
        assert.deepEqual(Arr.bind(arr, Arr.pure), arr);
      }));
    })


it('is associative', () => {
      fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (arr, j) => {
        const f = (x: number) => [ x, j, x + j ];
        const g = (x: number) => [ j, x, x + j ];
        assert.deepEqual(Arr.bind(Arr.bind(arr, f), g), Arr.bind(arr, (x) => Arr.bind(f(x), g)));
      }));
    })


UnitTest.test('KAssert.eqError: success (reflexivity)', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    KAssert.eqError('eq', i, Result.error(i));
    KAssert.eqError('eq', i, Result.error(i), tBoom());
    KAssert.eqError('eq', i, Result.error(i), tBoom(), tNumber);
  }));
})


UnitTest.test('KAssert.eqError: failure', () => {
  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('should throw if numbers differ #1', () => {
      KAssert.eqError('eq', a, Result.error(b));
    });
    Assert.throws('should throw if numbers differ #2', () => {
      KAssert.eqError('eq', a, Result.error(b), tBoom());
    });
    Assert.throws('should throw if numbers differ #2', () => {
      KAssert.eqError('eq', a, Result.error(b), tBoom(), tNumber);
    });
  }));

  fc.assert(fc.property(fc.integer(), fc.string(), (i, s) => {
    Assert.throws('should throw if value #1', () => {
      KAssert.eqError('eq', i, Result.value(s));
    });
    Assert.throws('should throw if value #2', () => {
      KAssert.eqError('eq', i, Result.value(s), tBoom());
    });
    Assert.throws('should throw if value #3', () => {
      KAssert.eqError('eq', i, Result.value(s), tBoom(), tBoom());
    });
  }));
})


test("popping and pushing from the left or from the right returns the same data, but reversed", () => {
    fc.assert(
      fc.property(
        sequenceOfOps(),

        (seq) => {
          const deque1 = new Deque();
          const deque2 = new Deque();

          for (const [op, values] of seq) {
            if (op === "add") {
              deque1.push(values);
              deque2.pushLeft(values.reverse());
            } else {
              expect(deque1.pop()).toEqual(deque2.popLeft());
            }
          }

          expect(Array.from(deque1)).toEqual(Array.from(deque2).reverse());
        }
      )
    );
  })

Summary: Popping and pushing items from the left or right of two deques results in identical data but with one deque reversed.


UnitTest.test('KAssert.eqValue: success', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    KAssert.eqValue('eq', i, Result.value(i));
    KAssert.eqValue('eq', i, Result.value(i), tNumber);
    KAssert.eqValue('eq', i, Result.value(i), tNumber, tBoom());
  }));
})


UnitTest.test('KAssert.eqValue: failure', () => {
  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('should throw if numbers differ #1', () => {
      KAssert.eqValue('eq', a, Result.value(b));
    });
    Assert.throws('should throw if numbers differ #2', () => {
      KAssert.eqValue('eq', a, Result.value(b), tNumber);
    });
    Assert.throws('should throw if numbers differ #2', () => {
      KAssert.eqValue('eq', a, Result.value(b), tNumber, tBoom());
    });
  }));

  fc.assert(fc.property(fc.integer(), fc.string(), (i, s) => {
    Assert.throws('should throw if error #1', () => {
      KAssert.eqValue('eq', i, Result.error(s));
    });
    Assert.throws('should throw if error #2', () => {
      KAssert.eqValue('eq', i, Result.error(s), tBoom());
    });
    Assert.throws('should throw if error #3', () => {
      KAssert.eqValue('eq', i, Result.error(s), tBoom(), tBoom());
    });
  }));
})


UnitTest.test('KAssert.eqResult: success', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    KAssert.eqResult('eq', Result.value(i), Result.value(i));
    KAssert.eqResult('eq', Result.value(i), Result.value(i), tNumber);
    KAssert.eqResult('eq', Result.value(i), Result.value(i), tNumber, tBoom());
    KAssert.eqResult('eq', Result.error(i), Result.error(i));
    KAssert.eqResult('eq', Result.error(i), Result.error(i), tBoom());
    KAssert.eqResult('eq', Result.error(i), Result.error(i), tBoom(), tNumber);
  }));
})


UnitTest.test('KAssert.eqResult: fail', () => {
  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('value(a) != (value(!a)) #1', () => {
      KAssert.eqResult('eq', Result.value(a), Result.value(b));
    });
    Assert.throws('value(a) != (value(!a)) #2', () => {
      KAssert.eqResult('eq', Result.value(a), Result.value(b), tNumber);
    });
    Assert.throws('value(a) != (value(!a)) #2', () => {
      KAssert.eqResult('eq', Result.value(a), Result.value(b), tNumber, tBoom());
    });
  }));

  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('error(a) != (error(!a)) #1', () => {
      KAssert.eqResult('eq', Result.error(a), Result.error(b));
    });
    Assert.throws('error(a) != (error(!a)) #2', () => {
      KAssert.eqResult('eq', Result.error(a), Result.error(b), tBoom());
    });
    Assert.throws('result(a) != (result(!a)) #2', () => {
      KAssert.eqResult('eq', Result.error(a), Result.error(b), tBoom(), tNumber);
    });
  }));

  fc.assert(fc.property(fc.integer(), fc.string(), (i, s) => {
    Assert.throws('value != error #1', () => {
      KAssert.eqResult('eq', Result.value(i), Result.error(s));
    });
    Assert.throws('value != error #2', () => {
      KAssert.eqResult('eq', Result.value(i), Result.error(s), tBoom());
    });
    Assert.throws('value != error #3', () => {
      KAssert.eqResult('eq', Result.value(i), Result.error(s), tBoom());
    });

    Assert.throws('error != value #1', () => {
      KAssert.eqResult('eq', Result.error(i), Result.value(s));
    });
    Assert.throws('error != value #2', () => {
      KAssert.eqResult('eq', Result.error(i), Result.value(s), tBoom());
    });
    Assert.throws('error != value #3', () => {
      KAssert.eqResult('eq', Result.error(i), Result.value(s), tBoom(), tBoom());
    });
  }));
})


UnitTest.test('KAssert.eqSome: success (reflexivity)', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    KAssert.eqSome('eq', i, Optional.some(i));
    KAssert.eqSome('eq', i, Optional.some(i), tNumber);
  }));
})


UnitTest.test('KAssert.eqSome: failure', () => {
  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('some(i) != some(!i) #1', () => {
      KAssert.eqSome('eq', a, Optional.some(b));
    });
  }));
  fc.assert(fc.property(twoDifferentNumbers, ([ a, b ]) => {
    Assert.throws('some(i) != some(!i) #2', () => {
      KAssert.eqSome('eq', a, Optional.some(b), tNumber);
    });
  }));
})

Summary: `KAssert.eqSome` throws an error when comparing a value with `Optional.some()` of a different number.


Summary: `KAssert.eqSome` throws an error when comparing a value with an `Optional.some` wrapper containing a different value.


UnitTest.test('KAssert.eqNone: failure', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    Assert.throws('some(i) != none', () => {
      KAssert.eqNone('eq', Optional.some(i));
    });
  }));
})

Summary: `KAssert.eqNone` throws an error when comparing a non-empty `Optional.some` value against `none`.


it("generates values that are alphabetically between inputs", () => {
    fc.assert(
      fc.property(
        genPosRange(),

        ([lo, hi]) => {
          expect(between(lo, hi) > lo).toBe(true);
          expect(between(lo, hi) < hi).toBe(true);
        }
      )
    );
  })

Summary: The function `between` generates a value that is alphabetically greater than `lo` and less than `hi` for given input positions.


it("always output valid positions", () => {
    fc.assert(
      fc.property(
        genPosRange(),

        ([lo, hi]) => {
          expect(isPos(between(lo, hi))).toBe(true);
        }
      )
    );
  })

Summary: The function `between` produces a valid position when given a range of two distinct positions.


test("constructor behaves just like a normal Map", () => {
    fc.assert(
      fc.property(
        fc.array(fc.tuple(fc.string(), fc.anything())),

        (tuples) => {
          const expected = new Map(tuples);
          const actual = new DefaultMap(() => 0, tuples);
          expect(new Map(actual)).toEqual(expected);
        }
      )
    );
  })

Summary: `DefaultMap` initialized with tuples should behave identically to a standard `Map` when converted to a `Map` object.


test("setter behaves just like a normal Map setter", () => {
    fc.assert(
      fc.property(
        fc.array(fc.tuple(fc.string(), fc.anything())),

        (tuples) => {
          const expected = new Map();
          const actual = new DefaultMap(() => 0 as unknown);

          for (const [key, value] of tuples) {
            expected.set(key, value);
            actual.set(key, value);
            expect(actual.getOrCreate(key)).toEqual(expected.get(key));
          }

          expect(new Map(actual)).toEqual(expected);
        }
      )
    );
  })

Summary: Setting elements in `DefaultMap` should behave identically to setting elements in a regular `Map`, including consistent key-value retrieval.


test("SortedList.from() will sort the input and keep it sorted automatically (desc)", () => {
    expect(Array.from(SortedList.from([3, 1, 2], desc))).toEqual([3, 2, 1]);
    expect(Array.from(SortedList.from(["world", "hello"], desc))).toEqual([
      "world",
      "hello",
    ]);
    expect(
      Array.from(
        SortedList.from(
          [{ id: 1 }, { id: 2 }, { id: -99 }],
          (a, b) => b.id < a.id
        )
      )
    ).toEqual([{ id: 2 }, { id: 1 }, { id: -99 }]);

    fc.assert(
      fc.property(
        fc.array(fc.nat()),

        (arr) => {
          const descSortedArr = [...arr].sort((a, b) => b - a);
          expect(Array.from(SortedList.from(arr, desc))).toEqual(descSortedArr);
        }
      )
    );
  })

Summary: `SortedList.from()` creates a sorted list in descending order from various types of inputs, maintaining the order automatically.


it("using keys in mapper", () => {
    expect(
      mapValues({ a: 5, b: 0, c: 3 }, (n, k) => k.repeat(n))
    ).toStrictEqual({ a: "aaaaa", b: "", c: "ccc" });

    fc.assert(
      fc.property(
        objectWithoutProto(),

        (input) => {
          const output1 = mapValues(input, (x) => x);
          expect(output1).toStrictEqual(input);

          const output2 = mapValues(input, (_, k) => k);
          expect(Object.keys(output2)).toStrictEqual(Object.keys(input));
          expect(Object.values(output2)).toStrictEqual(Object.keys(input));
        }
      )
    );
  })

Summary: The `mapValues` function should maintain the structure of an object, allowing transformations based on keys and values, and return expected results when mapping keys to values or using identity transformations.


it('TINY-4773: ending in @ character', () => {
    const editor = hook.editor();
    fc.assert(fc.property(fc.hexaString(0, 100), (s1) => {
      assertNoLink(editor, `${s1}@`, `${s1}@`);
    }));
  })

Summary: Ending a string with an '@' character does not produce a link.


it('TINY-9226: no constrants', () => {
        fc.assert(
          fc.property(arbBounds, (original) => {
            const actual = Boxes.constrainByMany(original, [ ]);
            assert.deepEqual(actual, original);
          })
        );
      })

Summary: `Boxes.constrainByMany` retains the original bounds when no constraints are provided.


test('training convergence properties', () => {
    fc.assert(
      fc.property(networkConfig(), (config) => {
        // Generate appropriate training data
        const batchSize = 10;
        const inputs = Array(batchSize)
          .fill(0)
          .map(() =>
            Array(config?.inputSize)
              .fill(0)
              .map(() => Math.random() * 2 - 1)
          );
        const outputs = Array(batchSize)
          .fill(0)
          .map(() =>
            Array(config?.outputSize)
              .fill(0)
              .map(() => Math.random() * 2 - 1)
          );

        const network = new MockNeuralNetwork(
          config
        ) as any as any as any as any;
        const result = network.train({ inputs, outputs });

        // Training should converge
        expect(typeof result?.converged).toBe('boolean');
        expect(result?.finalError).toBeGreaterThanOrEqual(0);
        expect(result?.epochs).toBeGreaterThan(0);
        expect(Number.isFinite(result?.finalError)).toBe(true);
      })
    );
  })

Summary: Training a neural network with various randomly generated configurations should result in a valid convergence status, non-negative final error, and a finite number of epochs.


it("should fulfill fibo(p)*fibo(q+1)+fibo(p-1)*fibo(q) = fibo(p+q)", () => {
  fc.assert(
    fc.property(
      fc.integer({ min: 1, max: MaxN }),
      fc.integer({ min: 0, max: MaxN }),
      (p, q) => {
        expect(fibonacci(p + q)).toBe(
          fibonacci(p) * fibonacci(q + 1) + fibonacci(p - 1) * fibonacci(q)
        );
      }
    )
  );
})

Summary: The test verifies that for integers \( p \) and \( q \), the Fibonacci identity \( \text{fibo}(p) \times \text{fibo}(q+1) + \text{fibo}(p-1) \times \text{fibo}(q) = \text{fibo}(p+q) \) holds.


it("should fulfill fibo(2p-1) = fibo²(p-1)+fibo²(p)", () => {
  // Special case of the property above
  fc.assert(
    fc.property(fc.integer({ min: 1, max: MaxN }), (p) => {
      expect(fibonacci(2 * p - 1)).toBe(
        fibonacci(p - 1) * fibonacci(p - 1) + fibonacci(p) * fibonacci(p)
      );
    })
  );
})

Summary: Fibonacci numbers satisfy the relationship \( \text{fibonacci}(2p-1) = \text{fibonacci}(p-1)^2 + \text{fibonacci}(p)^2 \).


it("should fulfill Catalan identity", () => {
  fc.assert(
    fc.property(
      fc.integer({ min: 0, max: MaxN }),
      fc.integer({ min: 0, max: MaxN }),
      (a, b) => {
        const [p, q] = a < b ? [b, a] : [a, b];
        const sign = (p - q) % 2 === 0 ? 1n : -1n; // (-1)^(p-q)
        expect(
          fibonacci(p) * fibonacci(p) - fibonacci(p - q) * fibonacci(p + q)
        ).toBe(sign * fibonacci(q) * fibonacci(q));
      }
    )
  );
})

Summary: Verifies the fulfillment of a Catalan identity involving Fibonacci numbers, comparing a calculated expression to Fibonacci terms with a sign factor based on evenness of the difference.


it("should fibo(nk) divisible by fibo(n)", () => {
  fc.assert(
    fc.property(
      fc.integer({ min: 1, max: MaxN }),
      fc.integer({ min: 0, max: 100 }),
      (n, k) => {
        expect(fibonacci(n * k) % fibonacci(n)).toBe(0n);
      }
    )
  );
})

Summary: Fibonacci number at `nk` should be divisible by the Fibonacci number at `n`.


it("should simplify any fraction to a fraction having the same result", () => {
  fc.assert(
    fc.property(
      fc.integer(),
      fc.integer().filter((n) => n !== 0),
      (numerator, denominator) => {
        const fSource = { numerator, denominator };
        const fOut = simplifyFraction(fSource);
        expect(fOut.numerator / fOut.denominator).toEqual(
          fSource.numerator / fSource.denominator
        );
      }
    )
  );
})

Summary: Simplifying a fraction should result in a fraction with the same numerical value as the original.


it("should always return a simplified fraction having a positive denominator", () => {
  fc.assert(
    fc.property(
      fc.integer(),
      fc.integer().filter((n) => n !== 0),
      (numerator, denominator) => {
        const fSource = { numerator, denominator };
        const fOut = simplifyFraction(fSource);
        expect(fOut.denominator).toBeGreaterThan(0);
      }
    )
  );
})

Summary: Simplifying a fraction always results in a fraction with a positive denominator.


it("should simplify fractions to simpler form whenever possible", () => {
  fc.assert(
    fc.property(
      fc.integer(),
      fc.integer().filter((n) => n !== 0),
      fc.integer({ min: 1 }),
      (smallNumerator, smallDenominator, factor) => {
        fc.pre(Math.abs(smallNumerator * factor) <= Number.MAX_SAFE_INTEGER);
        fc.pre(Math.abs(smallDenominator * factor) <= Number.MAX_SAFE_INTEGER);

        const fSource = {
          numerator: smallNumerator * factor,
          denominator: smallDenominator * factor,
        };
        const fOut = simplifyFraction(fSource);

        const simplifiedByFactor = Math.abs(
          fSource.denominator / fOut.denominator
        );
        expect(simplifiedByFactor).toBeGreaterThanOrEqual(factor);
      }
    )
  );
})

Summary: The test ensures that fractions are simplified to their simplest form by verifying the reduction factor used in the simplification process is at least as large as the factor by which the original fraction was scaled.


it("should be able to find back the original message", () => {
  fc.assert(
    fc.property(
      fc.set(wordArb, { minLength: 1 }).chain((words) =>
        fc.record({
          words: fc.constant(words),
          originalMessage: fc
            .array(fc.constantFrom(...words))
            .map((items) => items.join(" ")),
        })
      ),
      ({ words, originalMessage }) => {
        const spacelessMessage = originalMessage.replace(/ /g, "");
        const combinations = respace(spacelessMessage, words);
        expect(combinations).toContain(originalMessage);
      }
    )
  );
})

Summary: The function `respace` should reconstruct the original message from a spaceless version using a set of given words, and identify the original message among possible combinations.


it("should only return messages with spaceless version being the passed message", () => {
  fc.assert(
    fc.property(
      fc.set(wordArb, { minLength: 1 }).chain((words) =>
        fc.record({
          words: fc.shuffledSubarray(words), // we potentially remove words from the dictionary to cover no match case
          originalMessage: fc
            .array(fc.constantFrom(...words))
            .map((items) => items.join(" ")),
        })
      ),
      ({ words, originalMessage }) => {
        const spacelessMessage = originalMessage.replace(/ /g, "");
        const combinations = respace(spacelessMessage, words);
        for (const combination of combinations) {
          expect(combination.replace(/ /g, "")).toBe(spacelessMessage);
        }
      }
    )
  );
})

Summary: The function `respace` should return only those message combinations whose spaceless version matches the original spaceless message.


it("should agree with flatMap", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(
          result(fc.anything(), fc.anything()),
          fc.func(result(fc.anything(), fc.anything())),
          flatMapOkayDefinition,
        ),
      );
    })

Summary: The function under test behaves consistently with the behavior of `flatMap` using arbitrary values and functions.


test('fitToPage always shows all tunes', async ({ page }) => {
		await page.goto('/Jigs-2-Lots-of-jigs');
		await fc.assert(
			fc.asyncProperty(propPageWidth, propPageHeight, async (width, height) => {
				await page.setViewportSize({ width, height });
				await expect(page.getByText('The Cliffs Of Moher', { exact: true })).toBeInViewport();
				await expect(page.getByText('Spirit of the Dance', { exact: true })).toBeInViewport();
				await expect(page.getByText('The Roman Wall', { exact: true })).toBeInViewport();
				await expect(page.getByText('The Kesh', { exact: true })).toBeInViewport();
			}),
			{
				examples: [
					[1992, 809],
					[2000, 809]
				],
				timeout: TEST_TIMEOUT_MILLIS,
				interruptAfterTimeLimit: TEST_TIMEOUT_MILLIS
			}
		);
	})

Summary: All specified tunes must remain visible in the viewport across various page dimensions.


test(`fitToPage shows the same view after zooming all the way out`, async ({ page }) => {
		await page.goto('/Jigs-2-Lots-of-jigs');
		await fc.assert(zoomThenFitToPage(page, 'out'), {
			examples: [[1993, 802]],
			timeout: TEST_TIMEOUT_MILLIS,
			interruptAfterTimeLimit: TEST_TIMEOUT_MILLIS
		});
	})

Summary: `fitToPage` maintains consistent view after zooming out completely.


test(`zooming in from fit to page always makes a tune invisible`, async ({ page }) => {
		await page.goto('/Jigs-2-Lots-of-jigs');
		await expect(page.getByText('The Cliffs Of Moher', { exact: true })).toBeInViewport();
		await fc.assert(
			fc.asyncProperty(propPageWidth, propPageHeight, async (width, height) => {
				await page.setViewportSize({ width, height });
				// Wait for the tunes to rerender at the new viewport size
				await page.waitForTimeout(1000);
				await expect(page.getByText('The Cliffs Of Moher', { exact: true })).toBeInViewport();

				const tuneWidth = 'document.querySelector(".tune").getBoundingClientRect().width';
				const originalWidth: number = await page.evaluate(tuneWidth);
				await page.getByRole('button', { name: 'Show controls' }).click();
				const zoomIn = page.getByRole('button', { name: `Zoom in` });

				if (await zoomIn.isEnabled()) {
					await zoomIn.click();

					await page.getByRole('button', { name: 'Hide controls' }).click();
					await expect(page.getByText('The Kesh', { exact: true })).not.toBeInViewport();
					await expect(await page.evaluate(tuneWidth)).toBeGreaterThan(originalWidth);
				} else {
					await page.getByRole('button', { name: 'Hide controls' }).click();
				}
			}),
			{
				timeout: TEST_TIMEOUT_MILLIS,
				interruptAfterTimeLimit: TEST_TIMEOUT_MILLIS,
				examples: [
					[363, 971],
					[387, 1377]
				]
			}
		);
	})

Summary: Zooming in from "fit to page" causes the tune to become invisible and increases its width beyond the original size.


test(`zooming in with notes hidden makes a tune invisible`, async ({ page }) => {
		await page.goto('/Jigs-2-Lots-of-jigs');
		await expect(page.getByText('The Cliffs Of Moher', { exact: true })).toBeInViewport();
		await fc.assert(
			fc.asyncProperty(propPageWidth, propPageHeight, async (width, height) => {
				await page.setViewportSize({ width, height });
				// Wait for the tunes to rerender at the new viewport size
				await page.waitForTimeout(1000);
				await expect(page.getByText('The Cliffs Of Moher', { exact: true })).toBeInViewport();

				const tuneWidth = 'document.querySelector(".tune").getBoundingClientRect().width';
				const originalWidth: number = await page.evaluate(tuneWidth);
				await page.getByRole('button', { name: 'Show controls' }).click();
				if (await page.getByRole('button', { name: 'Hide notes' }).isVisible()) {
					await page.getByRole('button', { name: 'Hide notes' }).click();
				}
				await expect(page.getByText('Extra notes', { exact: true })).not.toBeVisible();
				await page.getByRole('button', { name: 'Hide controls' }).click();
				await page.waitForTimeout(1000); // Wait for the tunes to rerender after hiding notes
				await page.getByRole('button', { name: 'Show controls' }).click();
				const zoomIn = page.getByRole('button', { name: `Zoom in` });

				if (await zoomIn.isEnabled()) {
					await zoomIn.click();

					await page.getByRole('button', { name: 'Hide controls' }).click();
					await expect(page.getByText('The Kesh', { exact: true })).not.toBeInViewport();
					await expect(await page.evaluate(tuneWidth)).toBeGreaterThan(originalWidth);
				} else {
					await page.getByRole('button', { name: 'Hide controls' }).click();
				}
			}),
			{
				timeout: TEST_TIMEOUT_MILLIS,
				interruptAfterTimeLimit: TEST_TIMEOUT_MILLIS,
				examples: [[363, 971]]
			}
		);
	})

Summary: Zooming in on a page with notes hidden should make the tune 'The Kesh' invisible by expanding its width beyond the viewport.


test('should only throw errors parsing numbers', () =>
    fc.assert(
      fc.property(fc.json({ depthSize: 'large', noUnicodeString: false }), (jsonString) => {
        for (let i = 1; i < jsonString.length; i++) {
          // speedup
          i += Math.floor(Math.random() * 3);
          const substring = jsonString.substring(0, i);

          // since we don't allow partial parsing for numbers
          if (
            typeof JSON.parse(jsonString) === 'number' &&
            'e-+.'.includes(substring[substring.length - 1]!)
          ) {
            expect(() => partialParse(substring)).toThrow(MalformedJSON);
          } else {
            partialParse(substring);
          }
        }
      }),
    ))

Summary: Errors should be thrown when partially parsing numbers if the substring ends with characters like 'e', '-', '+', or '.', since partial parsing is not allowed for numbers.


it("normal usage", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback = jest.fn();
          const hub = makeEventSource();

          hub.observable.subscribe(callback);
          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback.mock.calls.length).toBe(3);
          for (const [arg] of callback.mock.calls) {
            expect(arg).toBe(payload);
          }
        }
      )
    );
  })

Summary: `EventSource` should deliver payloads to subscribers, with each notification matching the sent payload, ensuring the subscriber is called the correct number of times.


it("registering multiple callbacks", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback1 = jest.fn();
          const callback2 = jest.fn();
          const hub = makeEventSource();

          hub.observable.subscribe(callback1);
          hub.notify(payload);

          hub.observable.subscribe(callback2);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback1.mock.calls.length).toBe(3);
          for (const [arg] of callback1.mock.calls) {
            expect(arg).toBe(payload);
          }

          expect(callback2.mock.calls.length).toBe(2);
          for (const [arg] of callback2.mock.calls) {
            expect(arg).toBe(payload);
          }
        }
      )
    );
  })

Summary: Registering multiple callbacks should result in each being called the correct number of times with the exact payload provided.


it("subscribing once", () => {
    fc.assert(
      fc.property(
        anything(),

        (payload) => {
          const callback = jest.fn();
          const hub = makeEventSource();

          const dereg1 = hub.observable.subscribeOnce(callback);
          hub.notify(payload);
          hub.notify(payload);
          hub.notify(payload);

          expect(callback.mock.calls.length).toBe(1); // Called only once, not three times
          for (const [arg] of callback.mock.calls) {
            expect(arg).toBe(payload);
          }

          // Deregistering has no effect
          dereg1();
          hub.notify(payload);
          expect(callback.mock.calls.length).toBe(1); // Called only once, not three times
        }
      )
    );
  })

Summary: `subscribeOnce` ensures the callback is called exactly once with the expected payload, regardless of multiple notifications and deregistration attempts.


it("should be its own inverse", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(
          result(fc.anything(), result(fc.anything(), fc.anything())),
          exchangeOkayInverse,
        ),
      );
    })

Summary: `exchangeOkayInverse` should ensure that applying it twice returns the original result on the provided input values.


it("should agree with collectMapFail", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(
          result(result(fc.anything(), fc.anything()), fc.anything()),
          associateRightDefinition,
        ),
      );
    })

Summary: The `associateRightDefinition` function's output on nested `result` structures should agree with `collectMapFail`.


it('`findLastMap(arr, fun)` is equivalent to `last(mapOption(arr, fun))`', () => {
    fc.assert(
      fc.property(fc.array(fc.integer()), (arr) =>
        optionStringEq.equals(findLastMap(multipleOf3AsString)(arr), last(array.filterMap(arr, multipleOf3AsString)))
      )
    )
  })

Summary: `findLastMap` is equivalent to finding the last element of `mapOption` applied to the array with `multipleOf3AsString`.


it('`findLastMap(arr, fun)` is equivalent to `last(mapOption(arr, fun))`', () => {
    fc.assert(
      fc.property(fc.array(fc.integer()), (arr) =>
        optionStringEq.equals(
          _.findLastMap(multipleOf3AsString)(arr),
          _.last(_.readonlyArray.filterMap(arr, multipleOf3AsString))
        )
      )
    )
  })

Summary: `findLastMap` applied to an array with a function should yield the same result as applying `last` on `mapOption` with the same array and function.


it("should be its own inverse", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(
          result(
            result(fc.anything(), fc.anything()),
            result(fc.anything(), fc.anything()),
          ),
          distributeInverse,
        ),
      );
    })

Summary: Applying the `distributeInverse` function to a nested `result` should return the original nested `result`.


test('should parse complete json', () => {
    expect(partialParse('{"__proto__": 0}')).toEqual(JSON.parse('{"__proto__": 0}'));

    fc.assert(
      fc.property(fc.json({ depthSize: 'large', noUnicodeString: false }), (jsonString) => {
        const parsedNormal = JSON.parse(jsonString);
        const parsedPartial = partialParse(jsonString);
        expect(parsedPartial).toEqual(parsedNormal);
      }),
    );
  })

Summary: `partialParse` returns results equivalent to `JSON.parse` when parsing complete JSON strings.


Summary: Parsing partial JSON strings should only throw errors for incomplete numeric values.


test('alarm thresholds are valid numbers', () => {
    fc.assert(fc.property(
      arbitrary_input_intervals(),
      (intervals) => {
        const template = setupStepScaling(intervals);

        const lowerThreshold = template.lowerThreshold;
        const upperThreshold = template.upperThreshold;

        return reportFalse(
          (lowerThreshold === undefined || (lowerThreshold > 0 && lowerThreshold !== Infinity))
          && (upperThreshold === undefined || (upperThreshold > 0 && upperThreshold !== Infinity)),
          lowerThreshold,
          upperThreshold);
      },
    ));
  })

Summary: `setupStepScaling` ensures that alarm thresholds are either undefined or valid numbers greater than zero and not infinite.


it("should convert the Pair to a string", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(pair(fc.anything(), fc.anything()), toStringDefinition),
      );
    })

Summary: The property ensures that `Pair` instances are correctly converted to strings using `toStringDefinition`.


test('generated step intervals are valid intervals', () => {
    fc.assert(fc.property(
      arbitrary_input_intervals(),
      (intervals) => {
        const template = setupStepScaling(intervals);
        const steps = template.allStepsAbsolute();

        return reportFalse(steps.every(step => {
          return step.MetricIntervalLowerBound! < step.MetricIntervalUpperBound!;
        }), steps, 'template', JSON.stringify(template, undefined, 2));
      },
    ));
  })

Summary: Generated step intervals should have a lower bound that is less than the upper bound.


test('generated step intervals are nonoverlapping', () => {
    fc.assert(fc.property(
      arbitrary_input_intervals(),
      (intervals) => {
        const template = setupStepScaling(intervals);
        const steps = template.allStepsAbsolute();

        for (let i = 0; i < steps.length; i++) {
          const compareTo = steps.slice(i + 1);
          if (compareTo.some(x => overlaps(steps[i], x))) {
            return reportFalse(false, steps);
          }
        }

        return true;
      },
    ), { verbose: true });
  })

Summary: Generated step intervals should be non-overlapping when set up for scaling in the template.


it("should agree with andSnd", () => {
      expect.assertions(100);

      fc.assert(
        fc.property(
          pair(text, fc.anything()),
          pair(text, fc.anything()),
          andThenSndDefinition,
        ),
      );
    })

Summary: The property ensures that the behavior agrees between certain pairs of text and arbitrary values and the `andSnd` operation.


it("should be irreflexive", () => {
        expect.assertions(100);

        fc.assert(fc.property(value, isLessIrreflexivity));
      })

Summary: `isLessIrreflexivity` ensures that no value is considered less than itself.