t.test('invariants', t => {
  fc.assert(
    fc.property(fc.bigIntN(N), n => {
      // -(-n) = n
      t.equal(to(mpz.negate(mpz.negate(from(n)))), n);

      // identity
      t.equal(t_add(n, 0n), n);
      t.equal(t_add(0n, n), n);
      t.equal(t_sub(n, 0n), n);
      t.equal(t_sub(0n, n), -n);
    })
  );

  fc.assert(
    fc.property(fc.bigIntN(N), fc.bigIntN(N), (n, m) => {
      // (n+m)-m = n
      t.equal(to(mpz.sub(mpz.add(from(n), from(m)), from(m))), n);

      // commutative
      t.equal(t_add(n, m), t_add(m, n));
      t.equal(t_sub(n, m), t_add(n, -m));
    })
  );

  fc.assert(
    fc.property(fc.bigIntN(N), fc.bigIntN(N), fc.bigIntN(N), (a, b, c) => {
      const A = from(a);
      const B = from(b);
      const C = from(c);

      // associative
      // (a+b)+c = a+(b+c)
      t.equal(to(mpz.add(mpz.add(A, B), C)), to(mpz.add(A, mpz.add(B, C))));
      // (a-b)-c = a-(b+c)
      t.equal(to(mpz.sub(mpz.sub(A, B), C)), to(mpz.sub(A, mpz.add(B, C))));
      // (a+b)-c = a+(b-c)
      t.equal(to(mpz.sub(mpz.add(A, B), C)), to(mpz.add(A, mpz.sub(B, C))));
    })
  );

  t.end();
})


unknown

UnitTest.test('Options.sequence: Array of numbers', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (n) => {
    const someNumbers = Arr.map(n, (x) => Option.some(x));
    Assert.eq('eq', Option.some(n), Options.sequence<number>(someNumbers), tOption());
  }));
})

Summary: `Options.sequence` constructs an `Option` from an array of `Option`-wrapped numbers, ensuring it equals an `Option` of the original array of numbers.


UnitTest.test('Options.sequence: None then some', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (n) => {
    const someNumbers = Arr.map(n, (x) => Option.some(x));
    Assert.eq('eq', Option.none(), Options.sequence<number>([ Option.none<number>(), ...someNumbers ]), tOption());
  }));
})

Summary: `Options.sequence` results in `Option.none` when the sequence starts with `Option.none`, regardless of subsequent `Option.some` values.


UnitTest.test('Options.sequence: all some', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (n) =>
    Assert.eq('eq',
      Options.traverse<number, number>(n, (x) => Option.some(x)),
      Options.sequence<number>(Arr.map(n, (x) => Option.some(x))),
      tOption()
    )
  ));
})

Summary: `Options.sequence` should produce the same result as `Options.traverse` when both operate on an array of integers with all elements wrapped in `Option.some`.


UnitTest.test('some !== none, for any predicate', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt1) => {
    Assert.eq('eq', false, opt1.equals_(Option.none(), boom));
  }));
})

Summary: `some` option is not equal to `none` option, regardless of the predicate used.


UnitTest.test('none !== some, for any predicate', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt1) => {
    Assert.eq('eq', false, Option.none().equals_(opt1, boom));
  }));
})

Summary: `Option.none()` is not equal to `Option.some()` for any integer value, confirmed by a predicate.


t.test('mul-div invariants', t => {
  fc.assert(
    fc.property(fc.bigIntN(N), fc.bigIntN(N), (a, b) => {
      const n = mpz.from(a);
      const d = mpz.from(b || 1n);

      const q = mpz.div(n, d);
      const m = mpz.rem(n, d);
      const r = mpz.add(mpz.mul(q, d), m);
      t.equal(mpz.toHex(r), mpz.toHex(n));

      // commutative
      t.equal(t_mul(a, b), t_mul(b, a));
    })
  );

  // distributive
  // a*(b+c) = a*b + a*c

  fc.assert(
    fc.property(fc.bigIntN(N), n => {
      // identity
      t.equal(t_mul(n, 1n), n);
      t.equal(t_div(n, 1n), n);

      // inverse
      if (n !== 0n) {
        t.equal(t_div(n, n), 1n);
      }
    })
  );

  t.end();
})


UnitTest.test('Checking some(x).equals_(some(y), _, _ -> false) === false', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), arbOptionSome(fc.integer()), (opt1, opt2) => {
    Assert.eq('eq', false, opt1.equals_(opt2, Fun.constant(false)));
  }));
})

Summary: Two `some` options compared with a function that always returns false should result in `equals_` returning false.


UnitTest.test('Checking some(x).equals_(some(y), _, _ -> true) === true', () => {
  fc.assert(fc.property(fc.integer(), fc.integer(), (a, b) => {
    const opt1 = Option.some(a);
    const opt2 = Option.some(b);
    Assert.eq('eq', true, opt1.equals_(opt2, Fun.constant(true)));
  }));
})

Summary: The test checks that `Option.some(x).equals_(Option.some(y), _, _ -> true)` always returns true, regardless of the integers `x` and `y`.


UnitTest.test('Checking some(x).equals_(some(y), f) iff. f(x, y)', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), arbOptionSome(fc.integer()), fc.func(fc.boolean()), (a, b, f) => {
    const opt1 = Option.some(a);
    const opt2 = Option.some(b);
    return f(a, b) === opt1.equals_(opt2, f);
  }));
})

Summary: `Option.some(x).equals_(Option.some(y), f)` is true if and only if `f(x, y)` is true for integers `x` and `y`.


UnitTest.test('Checking some(x).fold(die, id) === x', () => {
  fc.assert(fc.property(fc.integer(), (json) => {
    const opt = Option.some(json);
    const actual = opt.fold(Fun.die('Should not be none!'), Fun.identity);
    Assert.eq('eq', json, actual);
  }));
})

Summary: The property confirms that calling `fold` on `Option.some(x)` with an identity function returns `x`.


UnitTest.test('Checking some(x).is(x) === true', () => {
  fc.assert(fc.property(fc.integer(), (json) => {
    const opt = Option.some(json);
    Assert.eq('eq', true, opt.is(json));
  }));
})

Summary: `Option.some(x).is(x)` should return true for any integer `x`.


UnitTest.test('Checking some(x).isSome === true', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => opt.isSome()));
})

Summary: `some(x).isSome` should return true for any integer value wrapped in an option.


UnitTest.test('Checking some(x).isNone === false', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => !opt.isNone()));
})

Summary: `some(x).isNone` should always return false for any integer wrapped by `OptionSome`.


UnitTest.test('Checking some(x).map(f) === some(f(x))', () => {
  fc.assert(fc.property(fc.integer(), fc.func(fc.integer()), (a, f) => {
    const opt = Option.some(a);
    const actual = opt.map(f);
    Assert.eq('eq', f(a), actual.getOrDie());
  }));
})

Summary: `Option.some(x).map(f)` should produce the same result as `Option.some(f(x))`.


UnitTest.test('Checking some(x).each(f) === undefined and f gets x', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => {
    let hack: number | null = null;
    const actual = opt.each((x) => {
      hack = x;
    });
    Assert.eq('eq', undefined, actual);
    Assert.eq('hack', hack, opt.getOrDie());
  }));
})

Summary: `some(x).each(f)` should return `undefined`, and `f` should be applied to `x`.


UnitTest.test('Given f :: s -> some(b), checking some(x).bind(f) === some(b)', () => {
  fc.assert(fc.property(fc.integer(), fc.func(arbOptionSome(fc.integer())), (i, f) => {
    const actual = Option.some(i).bind(f);
    Assert.eq('eq', f(i), actual, tOption(tNumber));
  }));
})

Summary: `Option.some(i).bind(f)` should be equivalent to `f(i)` when `f` is a function mapping integers to `Option.some` of integers.


UnitTest.test('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);
    Assert.eq('eq', Option.none(), actual, tOption(tNumber));
  }));
})

Summary: The property checks if binding a function returning `none` to an `Option` with some value results in `none`.


it("should always return notice", async () => {
                const file = "foo.js";
                const root = await tempFs.create({ [file]: "" });
                const wrapper = new StandardWrapper(
                    {
                        level: Levels.INFO,
                        fix: false,
                        root,
                        files: [file],
                    },
                    {},
                );

                await fc.assert(
                    fc.asyncProperty(
                        fc.string({ unit: "binary" }),
                        async (content) => {
                            await fs.writeFile(file, content);

                            const notices = await wrapper.lint(file);
                            for (const notice of notices) {
                                assert.equal(notice.file, file);
                                assert.equal(notice.linter, "standard");
                            }
                        },
                    ),
                );
            })

Summary: Ensures that the `StandardWrapper` linting function returns notices with the specified file name and "standard" as the linter for any binary string content written to the file.


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

Summary: `OptionSome.exists` method returns true when applied with a constant true function on an option containing a value.


UnitTest.test('Checking some(x).exists(f) iff. f(x)', () => {
  fc.assert(fc.property(fc.integer(), fc.func(fc.boolean()), (i, f) => {
    const opt = Option.some(i);
    if (f(i)) {
      Assert.eq('eq', true, opt.exists(f));
    } else {
      Assert.eq('eq', false, opt.exists(f));
    }
  }));
})

Summary: `Option.some(x).exists(f)` returns true if and only if the function `f` applied to `x` is true.


UnitTest.test('Checking some(x).forall(_ -> false) === false', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => !opt.forall(Fun.constant(false))));
})

Summary: `some(x).forall(_ -> false)` should always be false for any integer wrapped in `OptionSome`.


it("should always return notice", async () => {
                const file = "foo.yaml";
                const root = await tempFs.create({ [file]: "" });
                const wrapper = new YAMLLintWrapper(
                    {
                        level: Levels.INFO,
                        fix: false,
                        root,
                        files: [file],
                    },
                    {},
                );

                await fc.assert(
                    fc.asyncProperty(
                        fc.string({ unit: "binary" }),
                        async (content) => {
                            await fs.writeFile(file, content);

                            const notices = await wrapper.lint(file);
                            for (const notice of notices) {
                                assert.equal(notice.file, file);
                                assert.equal(notice.linter, "yaml-lint");
                            }
                        },
                    ),
                );
            })

Summary: `YAMLLintWrapper` always produces notices tagged with the correct file and linter name when linting any binary string content in a YAML file.


UnitTest.test('Checking none.fold(_ -> x, die) === x', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    const actual = Option.none<string>().fold(Fun.constant(i), Fun.die('Should not die'));
    Assert.eq('eq', i, actual);
  }));
})

Summary: The property checks that `none.fold(_ -> x, die)` returns `x` for any integer `x`, without calling the die function.


UnitTest.test('Checking none.is === false', () => {
  fc.assert(fc.property(fc.integer(), (v) => {
    Assert.eq('none is', false, Option.none<number>().is(v));
  }));
})

Summary: `Option.none<number>().is(v)` should always be false for any integer `v`.


UnitTest.test('Checking none.getOrDie() always throws', () => {
  // Require non empty string of msg falsiness gets in the way.
  fc.assert(fc.property(fc.string(1, 40), (s) => {
    Assert.throws('getOrDie', () => {
      Option.none().getOrDie(s);
    });
  }));
})

Summary: Calling `getOrDie` on `Option.none()` always throws an error.


UnitTest.test('Checking none.or(oSomeValue) === oSomeValue', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    const output = Option.none().or(Option.some(i));
    Assert.eq('eq', true, output.is(i));
  }));
})

Summary: `Option.none().or(Option.some(i))` should equal `Option.some(i)`.


UnitTest.test('Checking none.orThunk(_ -> v) === v', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    const output = Option.none().orThunk(() => Option.some(i));
    Assert.eq('eq', true, output.is(i));
  }));
})

Summary: `Option.none().orThunk(() => Option.some(i))` should equal `Option.some(i)`.


UnitTest.test('Option.isSome: none is not some', () => {
  Assert.eq('none is not some', false, Option.none().isSome());
  fc.assert(fc.property(fc.anything(), (x) => {
    Assert.eq('some is some', true, Option.some(x).isSome());
  }));
})

Summary: `Option.none().isSome()` should return false, while `Option.some(x).isSome()` should return true for any value `x`.


UnitTest.test('Option.getOr', () => {
  fc.assert(fc.property(fc.integer(), (x) => {
    Assert.eq('none', x, Option.none().getOr(x));
    Assert.eq('none', x, Option.none().getOrThunk(() => x));
  }));
  fc.assert(fc.property(fc.integer(), fc.integer(), (x, y) => {
    Assert.eq('some', x, Option.some(x).getOr(y));
    Assert.eq('some', x, Option.some(x).getOrThunk(Fun.die('boom')));
  }));
})

Summary: `Option.getOr` returns the provided default value or thunk result if the option is `none`, while `Option.some` ignores the default value and returns its own value.


Summary: `Option.getOr` returns the provided default value for `Option.none`, and the contained value for `Option.some`.


UnitTest.test('Checking some(x).filter(_ -> false) === none', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt) => {
    Assert.eq('eq', true, tOption().eq(
      none(),
      opt.filter(Fun.constant(false))));
  }));
})

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


UnitTest.test('Checking some(x).filter(f) === some(x) iff. f(x)', () => {
  fc.assert(fc.property(fc.integer(), fc.func(fc.boolean()), (i, f) => {
    const opt = some(i);
    if (f(i)) {
      Assert.eq('filter true', Option.some(i), opt.filter(f), tOption(tNumber));
    } else {
      Assert.eq('filter false', Option.none(), opt.filter(f), tOption(tNumber));
    }
  }));
})

Summary: Applying a filter function `f` to `some(x)` should return `some(x)` if and only if `f(x)` is true; otherwise, it should return `none()`.


UnitTest.test('Obj.map: map id obj = obj', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
    const actual = Obj.map(obj, Fun.identity);
    Assert.eq('map id', obj, actual);
  }));
})

Summary: Mapping an identity function over an object with `Obj.map` should return the original object unchanged.


UnitTest.test('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 all values in an object to a constant results in every value being equal to that constant.


UnitTest.test('mapToArray is symmetric with tupleMap', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
    const array = Obj.mapToArray(obj, (x, i) => ({ k: i, v: x }));

    const aKeys = Arr.map(array, (x) => x.k);
    const aValues = Arr.map(array, (x) => x.v);

    const keys = Obj.keys(obj);
    const values = Obj.values(obj);

    Assert.eq('same keys', Arr.sort(keys), Arr.sort(aKeys));
    Assert.eq('same values', Arr.sort(values), Arr.sort(aValues));
  }));
})

Summary: Converting an object to an array using `mapToArray` should preserve the same keys and values as retrieved by `Obj.keys` and `Obj.values`.


UnitTest.test('the value found by find always passes predicate', () => {
  fc.assert(fc.property(
    fc.dictionary(fc.asciiString(), fc.json()),
    fc.func(fc.boolean()),
    function (obj, pred) {
      // It looks like the way that fc.fun works is it cares about all of its arguments, so therefore
      // we have to only pass in one if we want it to be deterministic. Just an assumption
      const value = Obj.find(obj, function (v) {
        return pred(v);
      });
      return value.fold(function () {
        const values = Obj.values(obj);
        return !Arr.exists(values, function (v) {
          return pred(v);
        });
      }, function (v) {
        return pred(v);
      });
    }
  ));
})

Summary: The value found by `Obj.find` always satisfies the given predicate function.


UnitTest.test('If predicate is always false, then find is always none', () => {
  fc.assert(fc.property(
    fc.dictionary(fc.asciiString(), fc.json()),
    function (obj) {
      const value = Obj.find(obj, Fun.constant(false));
      return value.isNone();
    }
  ));
})

Summary: When a predicate is always false, `Obj.find` consistently returns none for any dictionary.


UnitTest.test('If object is empty, find is always none', () => {
  fc.assert(fc.property(
    fc.func(fc.boolean()),
    function (pred) {
      const value = Obj.find({ }, pred);
      return value.isNone();
    }
  ));
})

Summary: `Obj.find` should return none when searching within an empty object.


UnitTest.test('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()),
    function (obj) {
      const value = Obj.find(obj, Fun.constant(true));
      // No order is specified, so we cannot know what "first" is
      return Obj.keys(obj).length === 0 ? value.isNone() : true;
    }
  ));
})

Summary: When the predicate always returns true, `Obj.find` should return the first value as `some(first)`, or `none` if the dictionary is empty, independent of order.


UnitTest.test('Each + set should equal the same object', () => {
  fc.assert(fc.property(
    fc.dictionary(fc.asciiString(), fc.json()),
    function (obj: Record<string, any>) {
      const values = { };
      const output = Obj.each(obj, function (x, i) {
        values[i] = x;
      });
      Assert.eq('eq', obj, values);
      Assert.eq('output', undefined, output);
    }
  ));
})

Summary: Verifies that iterating over an object with `Obj.each` and collecting values results in an object identical to the original, and that `Obj.each` returns `undefined`.


UnitTest.test('Merged with identity on left', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.json()), function (obj) {
    Assert.eq('eq', obj, Merger.merge({}, obj));
  }));
})

Summary: Merging an object with an empty object on the left should result in the original object unchanged.


UnitTest.test('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()), function (a, b) {
    const output = Merger.merge(a, b);
    const keys = Obj.keys(b);
    const oKeys = Obj.keys(output);
    return Arr.forall(keys, function (k) {
      return Arr.contains(oKeys, k);
    });
  }));
})

Summary: `Merger.merge(a, b)` ensures that the resulting object contains all the keys present in object `b`.


UnitTest.test('Deep-merged with identity on right', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.json()), function (obj) {
    Assert.eq('eq', obj, Merger.deepMerge(obj, {}));
  }));
})

Summary: `Merger.deepMerge` should return the original object when merged with an empty object on the right.


UnitTest.test('Deep-merged with itself is itself', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.json()), function (obj) {
    Assert.eq('eq', obj, Merger.deepMerge(obj, obj));
  }));
})

Summary: Deep-merging an object with itself should return the original object unchanged.


UnitTest.test('Deep-merge(a, Deep-merge(b, c)) === Deep-merge(Deep-merge(a, b), c)', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.json()), fc.dictionary(fc.asciiString(), fc.json()), fc.dictionary(fc.asciiString(), fc.json()), function (a, b, c) {
    const one = Merger.merge(a, Merger.merge(b, c));
    const other = Merger.merge(Merger.merge(a, b), c);
    Assert.eq('eq', one, other);
  }));
})

Summary: The deep merge of dictionaries should be associative, meaning `Deep-merge(a, Deep-merge(b, c))` equals `Deep-merge(Deep-merge(a, b), c)`.


UnitTest.test('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()), function (a, b) {
    const output = Merger.deepMerge(a, b);
    const keys = Obj.keys(b);
    const oKeys = Obj.keys(output);
    return Arr.forall(keys, function (k) {
      return Arr.contains(oKeys, k);
    });
  }));
})

Summary: Deep-merge of objects `a` and `b` should result in an object that contains all keys from `b`.


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

Summary: If the filter function always returns false, all elements of the object should be in the "f" part of the output, and "t" should be empty.


UnitTest.test('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) => x % 2 === 0;
      const output = Obj.bifilter(obj, predicate);

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

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

      Assert.eq('Something in "f" passed predicate', false, Arr.exists(falseKeys, matches));
      Assert.eq('Something in "t" failed predicate', true, Arr.forall(trueKeys, matches));
    }
  ));
})

Summary: `Obj.bifilter` separates an object's entries such that all entries in `f` fail the predicate and all entries in `t` pass the predicate.


UnitTest.test('Checking struct with right number of arguments', () => {
  fc.assert(fc.property(
    fc.array(fc.string(), 1, 40),
    (rawValues: string[]) => {
      // Remove duplications.
      const values = toUnique(rawValues);

      const struct = Struct.immutable.apply(undefined, values);
      const output = struct.apply(undefined, values);

      const evaluated = Obj.mapToArray(output, (v, _k) => v());

      Assert.eq('eq', evaluated, values);
    }
  ));
})

Summary: `Struct.immutable` correctly converts an array of unique strings into a structure that, when applied, produces functions yielding the original values.


UnitTest.test('Checking struct with fewer arguments', () => {
  fc.assert(fc.property(
    fc.array(fc.string(), 1, 40),
    fc.integer(1, 10),
    (rawValues: string[], numToExclude: number) => {
      // Remove duplications.
      const values = toUnique(rawValues);

      const struct = Struct.immutable.apply(undefined, values);
      try {
        struct.apply(undefined, values.slice(numToExclude));
        return false;
      } catch (err) {
        return err.message.indexOf('Wrong number') > -1;
      }
    }
  ));
})

Summary: Verifies that invoking `Struct.immutable` with fewer arguments than it was created with throws an error containing the message "Wrong number".


UnitTest.test('Checking struct with more arguments', () => {
  fc.assert(fc.property(
    fc.array(fc.string(), 1, 40),
    fc.array(fc.string(), 1, 40),
    (rawValues: string[], extra: string[]) => {
      // Remove duplications.
      const values = toUnique(rawValues);

      const struct = Struct.immutable.apply(undefined, values);
      try {
        struct.apply(undefined, values.concat(extra));
        return false;
      } catch (err) {
        return err.message.indexOf('Wrong number') > -1;
      }
    }
  ));
})

Summary: When an immutable structure is created with a set of unique strings, applying it with additional arguments should throw an error indicating a wrong number of arguments.


UnitTest.test('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.eq('eq', matched, folded);
  }));
})

Summary: `adt.nothing.match` and `fold` produce the same result when applied to a `nothing` subject, ensuring both methods yield equivalent outputs.


UnitTest.test('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.eq('eq', 2, contents.length);
  }));
})

Summary: `adt.exact.match` produces contents with exactly two elements when matched with "exact".


it("should always return notice", async () => {
                const file = "foo.txt";
                const root = await tempFs.create({ [file]: "" });
                const wrapper = new SecretlintWrapper(
                    {
                        level: Levels.INFO,
                        fix: false,
                        root,
                        files: [file],
                    },
                    {},
                );

                await fc.assert(
                    fc.asyncProperty(
                        fc.string({ unit: "binary" }),
                        async (content) => {
                            await fs.writeFile(file, content);

                            const notices = await wrapper.lint(file);
                            for (const notice of notices) {
                                assert.equal(notice.file, file);
                                assert.equal(notice.linter, "secretlint");
                            }
                        },
                    ),
                );
            })

Summary: The test ensures that for any binary string written to "foo.txt", `SecretlintWrapper` generates notices correctly identifying the file and linter as "secretlint".


UnitTest.test('CycleBy 0 has no effect', () => {
  fc.assert(fc.property(fc.nat(), fc.nat(), (value, delta) => {
    const actual = Num.cycleBy(value, 0, value, value + delta);
    Assert.eq('eq', value, actual);
  }));
})

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


UnitTest.test('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())),
    function (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: `Results.partition` should return an empty `values` array and an `errors` array equal in length to the input when only generating error results.


UnitTest.test('Check that the total number of values and errors matches the input size', () => {
  fc.assert(fc.property(
    fc.array(arbResult(fc.integer(), fc.string())),
    function (results) {
      const actual = Results.partition(results);
      Assert.eq('Total number should match size of input', results.length, actual.errors.length + actual.values.length);
    }
  ));
})

Summary: The total number of values and errors from `Results.partition` should match the size of the input array.


UnitTest.test('Check that error, value always equal comparison.firstError', () => {
  fc.assert(fc.property(
    arbResultError(fc.integer()),
    arbResultValue(fc.string()),
    function (r1, r2) {
      const comparison = Results.compare(r1, r2);
      return comparison.match({
        bothErrors: Fun.constant(false),
        firstError: Fun.constant(true),
        secondError: Fun.constant(false),
        bothValues: Fun.constant(false)
      });
    }
  ));
})

Summary: `Results.compare` should identify the first result (`r1`) as an error, returning `firstError` as true in the comparison.


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

Summary: Calling `each(f)` on a `ResultValue` should return `undefined`.


UnitTest.test('Given f :: s -> RV, checking value.bind(f).getOrDie() === f(value.getOrDie()).getOrDie()', () => {
  fc.assert(fc.property(arbResultValue(fc.integer()), fc.func(arbResultValue(fc.integer())), (res, f) => {
    Assert.eq('eq', res.bind(f).getOrDie(), f(res.getOrDie()).getOrDie());
  }));
})

Summary: The property requires that applying a function `f` to the result of `value.bind()` and comparing it with directly applying `f` to the unwrapped value produces the same outcome using `getOrDie()`.


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

Summary: The property should hold that applying a function `f` to a result using `bind` and folding it yields the same as applying `f` directly to the result's value and then folding it.


UnitTest.test('Checking value.forall is true iff. f(value.getOrDie() === true)', () => {
  fc.assert(fc.property(arbResultValue(fc.integer()), fc.func(fc.boolean()), (res, f) => {
    Assert.eq('eq', f(res.getOrDie()), res.forall(f));
  }));
})

Summary: The test checks that `res.forall(f)` returns true if and only if `f(res.getOrDie())` is true.


UnitTest.test('Checking value.exists is true iff. f(value.getOrDie() === true)', () => {
  fc.assert(fc.property(arbResultValue(fc.integer()), fc.func(fc.boolean()), (res, f) => {
    Assert.eq('eq', f(res.getOrDie()), res.exists(f));
  }));
})

Summary: The property should ensure that `value.exists` returns true if and only if applying function `f` to `value.getOrDie()` results in true.


UnitTest.test('Checking value.toOption is always Option.some(value.getOrDie())', () => {
  fc.assert(fc.property(arbResultValue(fc.integer()), (res) => {
    Assert.eq('eq', res.getOrDie(), res.toOption().getOrDie());
  }));
})

Summary: `value.toOption` converts a `ResultValue` into an `Option` and retrieves the same result using `getOrDie()`.


UnitTest.test('Result.error: error.is === false', () => {
  fc.assert(fc.property(fc.integer(), fc.string(), (i, s) => {
    Assert.eq('eq', false, Result.error<number, string>(s).is(i));
  }));
})

Summary: `Result.error` should return an object where `is` method always evaluates to false for any integer input.


UnitTest.test('Result.error: error.isValue === false', () => {
  fc.assert(fc.property(arbResultError(fc.integer()), (res) => {
    Assert.eq('eq', false, res.isValue());
  }));
})

Summary: `Result.error` instances should return `false` for the `isValue` method.


UnitTest.test('Result.error: error.getOr(v) === v', () => {
  fc.assert(fc.property(arbResultError(fc.integer()), fc.json(), (res, json) => {
    Assert.eq('eq', json, res.getOr(json));
  }));
})

Summary: `Result.error` returns the default value when accessing a result using `getOr`.


UnitTest.test('Result.error: error.getOrDie() always throws', () => {
  fc.assert(fc.property(arbResultError(fc.integer()), (res) => {
    Assert.throws('should throw', () => {
      res.getOrDie();
    });
  }));
})

Summary: `Result.error().getOrDie()` should always throw an error when accessed.


UnitTest.test('Result.error: error.orThunk(_ -> v) === v', () => {
  fc.assert(fc.property(fc.integer(), fc.string(), (i, s) => {
    Assert.eq('eq', Result.value(i), Result.error<number, string>(s).orThunk(() => Result.value(i)), tResult());
  }));
})

Summary: `Result.error.orThunk` applied to an error returns a value equal to the provided fallback value.


UnitTest.test('Result.error: error.fold(_ -> x, die) === x', () => {
  fc.assert(fc.property(arbResultError(fc.integer()), fc.json(), (res, json) => {
    const actual = res.fold(Fun.constant(json), Fun.die('Should not die'));
    Assert.eq('eq', json, actual);
  }));
})

Summary: `Result.error` should fold to the first function provided, returning the constant value without invoking the second function.


UnitTest.test('Given f :: s -> RV, Result.error: 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.eq('eq', true, getErrorOrDie(res) === getErrorOrDie(actual));
  }));
})

Summary: Binding a function to a `Result.error` should return the same error.


UnitTest.test('Result.error: error.exists === false', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    Assert.eq('eq', false, Result.error<unknown, number>(i).exists(Fun.die('⊥')));
  }));
})

Summary: `Result.error` returns an object where the `exists` method evaluates to false, given any integer input.


it("should always return notice", async () => {
                const file = "foo.js";
                const root = await tempFs.create({ [file]: "" });
                const wrapper = new PrettierWrapper(
                    {
                        level: Levels.INFO,
                        fix: false,
                        root,
                        files: [file],
                    },
                    {},
                );

                await fc.assert(
                    fc.asyncProperty(
                        fc.string({ unit: "binary" }),
                        async (content) => {
                            await fs.writeFile(file, content);

                            const notices = await wrapper.lint(file);
                            for (const notice of notices) {
                                assert.equal(notice.file, file);
                                assert.equal(notice.linter, "prettier");
                            }
                        },
                    ),
                );
            })

Summary: The test ensures that for any binary string content written to a file, the `PrettierWrapper` returns notices identifying the file and linter as "prettier".


UnitTest.test('Result.error: error.toOption is always none', () => {
  fc.assert(fc.property(arbResultError(fc.integer()), (res) => {
    Assert.eq('eq', Option.none(), res.toOption(), tOption());
  }));
})

Summary: `Result.error` ensures that calling `toOption` always returns `Option.none`.


UnitTest.test('Id: Two ids should not be the same', () => {
  const arbId = fc.string(1, 30).map(Id.generate);
  fc.assert(fc.property(arbId, arbId, (id1, id2) => id1 !== id2));
})

Summary: Generated IDs should be unique across two distinct generations.


promiseTest('LazyValue: delayed, map', () =>
  fc.assert(fc.asyncProperty(fc.integer(), fc.func(fc.string()), (i, f) => new Promise((resolve, reject) => {
    LazyValue.nu((c) => {
      setTimeout(() => {
        c(i);
      }, 2);
    }).map(f).get((v) => {
      eqAsync('LazyValue.map', f(i), v, reject);
      resolve();
    });
  }))))

Summary: A `LazyValue` that is delayed maps an integer through a function to produce a string, and the result matches the expected transformed value.


promiseTest('LazyValue: parallel spec', () => fc.assert(fc.asyncProperty(fc.array(fc.integer(), 0, 20), (vals) => new Promise((resolve, reject) => {
  const lazyVals = Arr.map(vals, LazyValue.pure);
  LazyValues.par(lazyVals).get((actual) => {
    eqAsync('pars', vals, actual, reject);
    resolve();
  });
}))))

Summary: `LazyValues.par` processes an array of `LazyValue` instances in parallel, ensuring the output matches the input array of integers.


promiseTest('Future: pure get', () =>
  fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
    Future.pure(i).get((ii) => {
      eqAsync('pure get', i, ii, reject, tNumber);
      resolve();
    });
  }))))

Summary: `Future.pure(i).get` correctly retrieves the value `i`, ensuring type consistency and equality.


promiseTest('Future: parallel spec', () =>
  fc.assert(fc.asyncProperty(fc.array(fc.tuple(fc.integer(1, 10), fc.integer())), (tuples) => new Promise((resolve, reject) => {
    Futures.par(Arr.map(tuples, ([ timeout, value ]) => Future.nu((cb) => {
      setTimeout(() => {
        cb(value);
      }, timeout);
    }))).get((ii) => {
      eqAsync('pars', tuples.map(([ _, i ]) => i), ii, reject, tArray(tNumber));
      resolve();
    });
  })))
)

Summary: `Futures.par` processes an array of futures derived from integer tuples where each tuple contains a timeout and a value, ensuring completion in order of the tuple values.


promiseTest('FutureResult: fromFuture', () => fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
  FutureResult.fromFuture<number, unknown>(Future.pure(i)).get((ii) => {
    eqAsync('eq', Result.value(i), ii, reject, tResult());
    resolve();
  });
}))))

Summary: `FutureResult.fromFuture` successfully retrieves the expected value from a resolved future using asynchronous comparison.


promiseTest('FutureResult: error mapResult', () => fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
  FutureResult.error(i).mapResult(Fun.die('⊥')).get((ii) => {
    eqAsync('eq', Result.error(i), ii, reject, tResult());
    resolve();
  });
}))))

Summary: `FutureResult.error(i).mapResult` should return a result that matches `Result.error(i)`.


promiseTest('FutureResult: value mapError', () => fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
  FutureResult.value(i).mapError(Fun.die('⊥')).get((ii) => {
    eqAsync('eq', Result.value(i), ii, reject, tResult());
    resolve();
  });
}))))

Summary: Mapping an error on a `FutureResult` containing a value should not affect the result.


promiseTest('FutureResult: err mapError', () => {
  const f = (x) => x + 3;
  return fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
    FutureResult.error(i).mapError(f).get((ii) => {
      eqAsync('eq', Result.error(f(i)), ii, reject, tResult());
      resolve();
    });
  })));
})

Summary: The property should ensure that mapping an error function over a `FutureResult.error` transforms the error value as expected.


promiseTest('FutureResult: bindFuture: value bindFuture error', () => fc.assert(fc.asyncProperty(fc.integer(), fc.string(), (i, s) => new Promise((resolve, reject) => {
  FutureResult.value(i).bindFuture(() => FutureResult.error(s)).get((actual) => {
    eqAsync('bind result', Result.error(s), actual, reject, tResult(tNumber));
    resolve();
  });
}))))

Summary: `FutureResult.value` bound with `bindFuture` to `FutureResult.error` results in an error matching the second input.


promiseTest('FutureResult: error bindFuture', () => fc.assert(fc.asyncProperty(fc.integer(), (i) => new Promise((resolve, reject) => {
  FutureResult.error(i).bindFuture(Fun.die('⊥')).get((actual) => {
    eqAsync('bind result', Result.error(i), actual, reject, tResult(tNumber));
    resolve();
  });
}))))

Summary: `FutureResult.error` correctly binds to a future that results in an error when using `bindFuture`.


UnitTest.test('Obj.filter: filter const true is identity', () => {
  fc.assert(fc.property(fc.dictionary(fc.asciiString(), fc.integer()), (obj) => {
    Assert.eq('id', obj, Obj.filter(obj, () => true));
  }));
})

Summary: `Obj.filter` returns the original object when the filter function always returns true.


UnitTest.test('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.eq('eq', expected, actual.length);
    }
  ));
})

Summary: The length of the array returned by `Jam.intersperse` should be `2 * len(arr) - 1` if the array is not empty; otherwise, the length should be `0`.


UnitTest.test('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);
    }
  ));
})

Summary: Each odd-indexed element in the result of `Jam.intersperse` should match the delimiter.


UnitTest.test('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.eq('eq', arr, filtered);
    }
  ));
})

Summary: Filtering out the delimiter from an interspersed array should result in an array equal to the original array.


UnitTest.test('Arr.groupBy: 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;
    }
  ));
})

Summary: Adjacent groups returned by `Arr.groupBy` have different hash values, and all elements within a group have the same hash value.


UnitTest.test('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.eq('eq', xs, output);
    }
  ));
})

Summary: Flattening grouped arrays should result in an array equal to the original array.


UnitTest.test('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) => {
      const output = Arr.forall(xs, Fun.constant(false));
      Assert.eq('eq', false, output);
    }
  ));
})

Summary: `Arr.forall` applied to a non-empty integer array with a predicate that always returns false should return false.


UnitTest.test('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) => {
      const output = Arr.forall(xs, Fun.constant(true));
      Assert.eq('eq', true, output);
    }
  ));
})

Summary: `Arr.forall` returns true for non-empty arrays when the predicate always returns true.


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

Summary: Folding an array with a concatenation function should produce the same result as reversing the array.


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

Summary: The property should hold that folding an array from the right using concatenation with an empty array results in the original array.


UnitTest.test('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.eq('eq', xs.concat(ys), output);
    }
  ));
})

Summary: Concatenating two arrays using `foldr` should produce the same result as directly concatenating the arrays with `concat`.


UnitTest.test('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.eq('eq', Arr.reverse(xs).concat(ys), output);
    }
  ));
})

Summary: The function `foldl` combines two arrays by prepending the reversed first array to the second array, verifying that this operation results in the same outcome as reversing the first array and then concatenating it with the second array.


UnitTest.test('Arr.flatten: 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);
      return Assert.eq('chunking', arr, bound);
    }
  ));
})

Summary: `Arr.flatten` should produce an array identical to the original when applied to arrays that have been chunked and then flattened.


UnitTest.test('Arr.flatten: Wrap then flatten array is identity', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    Assert.eq('wrap then flatten', Arr.flatten(Arr.pure(arr)), arr);
  }));
})

Summary: Flattening an array wrapped with `Arr.pure` results in the original array.


UnitTest.test('Mapping pure then flattening array is identity', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    Assert.eq('map pure then flatten', Arr.flatten(Arr.map(arr, Arr.pure)), arr);
  }));
})

Summary: Mapping an array with `Arr.pure` and then flattening it should result in the original array.


UnitTest.test('Arr.findIndex: find 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);
    Assert.eq(
      'Element should be found immediately after the prefix array',
      Option.some(prefix.length),
      Arr.findIndex(arr, (x) => x === element),
      tOption(tNumber)
    );
  }));
})

Summary: `Arr.findIndex` returns the index of a specified element placed immediately after a prefix array within a concatenated array.


UnitTest.test('Arr.findIndex: Element found passes predicate', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    const pred = (x) => x % 3 === 0;
    return Arr.findIndex(arr, pred).forall((x) => pred(arr[x]));
  }));
})

Summary: `Arr.findIndex` returns an index where the element in the array satisfies the given predicate.


UnitTest.test('Arr.findIndex: If predicate is always false, then index is always none', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    Assert.eq('should be none', Option.none(), Arr.findIndex(arr, () => false), tOption(tNumber));
  }));
})

Summary: `Arr.findIndex` should return `Option.none()` when the predicate function always evaluates to false for any array of integers.


UnitTest.test('Arr.findIndex: consistent with find', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    const pred = (x) => x % 5 === 0;
    Assert.eq('findIndex vs find', Arr.find(arr, pred), Arr.findIndex(arr, pred).map((x) => arr[x]), tOption(tNumber));
  }));
})

Summary: `Arr.findIndex` and `Arr.find` should both locate elements satisfying a predicate for divisibility by 5, ensuring consistent results between the found element and its index.


UnitTest.test('Arr.findIndex: consistent with exists', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    const pred = (x) => x % 6 === 0;
    Assert.eq('findIndex vs find', Arr.exists(arr, pred), Arr.findIndex(arr, pred).isSome());
  }));
})

Summary: `Arr.findIndex` should return a result consistent with `Arr.exists`, where finding an index means the predicate is satisfied.


UnitTest.test('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.eq('in array', true, Arr.exists(arr2, eqc(element)));
  }));
})

Summary: An element placed in the middle of a flattened array should be detected as existing within that array.


UnitTest.test('Element exists in singleton array of itself', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (i) => {
    Assert.eq('in array', true, Arr.exists([ i ], eqc(i)));
  }));
})

Summary: `Arr.exists` should return true when checking if an integer exists in a singleton array containing that integer.


it("should always return notice", async () => {
                const file = "foo.coffee";
                const root = await tempFs.create({ [file]: "" });
                const wrapper = new CoffeeLintCliWrapper(
                    {
                        level: Levels.INFO,
                        fix: false,
                        root,
                        files: [file],
                    },
                    {
                        /* eslint-disable camelcase */
                        no_tabs: { level: "error" },
                        prefer_english_operator: { level: "warn" },
                        /* eslint-enable camelcase */
                    },
                );

                await fc.assert(
                    fc.asyncProperty(
                        fc.string({ unit: "binary" }),
                        async (content) => {
                            await fs.writeFile(file, content);

                            const notices = await wrapper.lint(file);
                            for (const notice of notices) {
                                assert.equal(notice.file, file);
                                assert.equal(notice.linter, "coffeelint__cli");
                            }
                        },
                    ),
                );
            })

Summary: `CoffeeLintCliWrapper` should always return notices with the correct file and linter name when linting a file with any binary string content.


UnitTest.test('Element does not exist in empty array', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (i) => {
    Assert.eq('not in empty array', false, Arr.exists([], eqc(i)));
  }));
})

Summary: Verifies that searching for any element in an empty array results in `Arr.exists` returning false.


UnitTest.test('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 ]]);
    return Arr.exists(arr, always);
  }));
})

Summary: An element exists in a non-empty array if the predicate always returns true.


UnitTest.test('difference: ∀ xs ys. x ∈ (ys - xs) -> x ∉ 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));
  }));
})

Summary: `Arr.difference` results in elements that are present in the first array but not in the second, ensuring every element in the result exists in the first array.


UnitTest.test('Chunking should create 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 hasRightSize = (part) => part.length === chunkSize;

      const numChunks = chunks.length;
      const firstParts = chunks.slice(0, numChunks - 1);
      Assert.eq('Incorrect chunk size', true, Arr.forall(firstParts, hasRightSize));
      if (arr.length === 0) {
        Assert.eq('empty', [], chunks, tArray(tArray(tNumber)));
      } else {
        Assert.eq('nonEmpty', true, chunks[chunks.length - 1].length <= chunkSize);
      }
    }
  ));
})

Summary: Chunking an array should result in all chunks, except possibly the last one, having the specified length, and the last chunk should not exceed this length.


UnitTest.test('Cell: cell(x).get() === x', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    const cell = Cell(i);
    Assert.eq('eq', i, cell.get());
  }));
})

Summary: A `Cell` initialized with an integer returns that integer when `get()` is called.


UnitTest.test('Cell: cell.get() === last set call', () => {
  fc.assert(fc.property(fc.integer(), fc.integer(), fc.integer(), (a, b, c) => {
    const cell = Cell(a);
    Assert.eq('a', a, cell.get());
    cell.set(b);
    Assert.eq('b', b, cell.get());
    cell.set(c);
    Assert.eq('c', c, cell.get());
  }));
})

Summary: A `Cell` should return the value set by the most recent `set` call.


UnitTest.test('Arr.last: nonEmpty', () => {
  fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (init, last) => {
    const arr = init.concat([ last ]);
    Assert.eq('nonEmpty', Option.some(last), Arr.last(arr), tOption(tNumber));
  }));
})

Summary: `Arr.last` retrieves the last element of a non-empty integer array, matching it with the expected value.


UnitTest.test('Arr.head: nonEmpty', () => {
  fc.assert(fc.property(fc.array(fc.integer()), fc.integer(), (t, h) => {
    const arr = [ h ].concat(t);
    Assert.eq('nonEmpty', Option.some(h), Arr.head(arr), tOption(tNumber));
  }));
})

Summary: `Arr.head` returns the first element of a non-empty array when a head element is prepended to an integer array.


UnitTest.test('Arr.find: 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) => x === i;
    const result = Arr.find(arr, pred);
    Assert.eq('Element found in array', Option.some(i), result, tOption(tNumber));
  }));
})

Summary: `Arr.find` locates a specified integer within a concatenated array of integers, confirming the element is found.


UnitTest.test('Arr.find: value not found', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    const result = Arr.find(arr, () => false);
    Assert.eq('Element not found in array', Option.none(), result, tOption(tNumber));
  }));
})

Summary: `Arr.find` should return `Option.none()` when no element satisfies the condition in the array.


UnitTest.test('Arr.findMap of non-empty is first if f is Option.some', () => {
  fc.assert(fc.property(
    fc.integer(),
    fc.array(fc.integer()),
    (head, tail) => {
      const arr = [ head, ...tail ];
      Assert.eq('eq', Option.some(head), Arr.findMap(arr, Option.some), tOption());
    }
  ));
})

Summary: `Arr.findMap` applied to a non-empty array should return the first element as `Option.some` if `f` consistently returns `Option.some`.


UnitTest.test('Arr.findMap of non-empty is none if f is Option.none', () => {
  fc.assert(fc.property(
    fc.array(fc.integer()),
    (arr) => {
      Assert.eq('eq', Option.none(), Arr.findMap(arr, () => Option.none()), tOption());
    }
  ));
})

Summary: `Arr.findMap` returns `Option.none` when applied to a non-empty array with a function that always returns `Option.none`.


UnitTest.test('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 ];
      Assert.eq('eq', Option.some(ret), Arr.findMap(arr, (x) => Options.someIf(x === element, ret)), tOption());
    }
  ));
})

Summary: `Arr.findMap` should return `Some(ret)` when it finds an element matching the condition in the array.


UnitTest.test('Arr.findMap does not find an element', () => {
  fc.assert(fc.property(
    fc.array(fc.nat()),
    fc.nat(),
    (arr, ret) => {
      Assert.eq('eq', Option.none(), Arr.findMap(arr, (x) => Options.someIf(x === -1, ret)), tOption());
    }
  ));
})

Summary: `Arr.findMap` returns `Option.none()` when it does not find an element matching a condition in an array of natural numbers.


UnitTest.test('Arr.bind: Monad Law: right identity', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
    Assert.eq('right id', arr, Arr.bind(arr, Arr.pure), tArray(tNumber));
  }));
})

Summary: `Arr.bind` satisfies the right identity monad law when binding an array with `Arr.pure` returns the original array.


UnitTest.test('Arr.bind: Monad Law: associativity', () => {
  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.eq('assoc', Arr.bind(arr, (x) => Arr.bind(f(x), g)), Arr.bind(Arr.bind(arr, f), g), tArray(tNumber));
  }));
})

Summary: Associativity for `Arr.bind` ensures that applying nested bindings with functions `f` and `g` to an array is equivalent to sequentially applying `f` and then `g`.


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(MAC(), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.true;
          })
        ))

Summary: The property should ensure that when the input value is transformed to uppercase, the `input` element remains valid.


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(invertedRegex(regExp.MAC), async testValue => {
            input!.value = testValue;
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))

Summary: Editing is disallowed if the input value does not match the `regExp.MAC` pattern, resulting in `checkValidity()` returning false.


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 4, maxLength: 4 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            }
          )
        ))

Summary: Editing is allowed when the input value is a valid uppercase hexadecimal string of length 4.


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(hexaString({ minLength: 5 }), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))

Summary: The test ensures that input fields with invalid hexadecimal values do not pass validity checks after updating.


it('does not allow to edit characters < 4', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 0, maxLength: 3 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))

Summary: Editing is disallowed for hexadecimal strings with fewer than 4 characters, ensuring `checkValidity()` returns false for such inputs.


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(hexaString({ minLength: 4 }), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))

Summary: Editing is disallowed if the input value is an invalid uppercase hexadecimal string with a minimum length of four characters.


it('does not allow to edit characters < 3', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 0, maxLength: 2 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))

Summary: Input values with fewer than 3 characters are considered invalid.


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            integer({ min: 8 }).map(num => `${num}`),
            async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))

Summary: Editing is disallowed for input values that are invalid, as determined by the `checkValidity` method.


it('edits name attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => {
            inputs[0].value = name;
            await (<WizardTextField>inputs[0]).requestUpdate();
            expect(inputs[0].checkValidity()).to.be.true;
          })
        );
      })

Summary: Checks that the name attribute is only edited for inputs matching a valid ASCII name pattern.


it('rejects name attribute starting with decimals', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => {
            inputs[0].value = name;
            await (<WizardTextField>inputs[0]).requestUpdate();
            expect(inputs[0].checkValidity()).to.be.false;
          })
        );
      })

Summary: The name attribute is invalid if it starts with a decimal.


it('rejects smpRate attribute in case input is not unsigned int', async () => {
        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async smpRate => {
              inputs[4].value = smpRate;
              await (<WizardTextField>inputs[4]).requestUpdate();
              expect(inputs[4].checkValidity()).to.be.false;
            }
          )
        );
      })

Summary: Rejects `smpRate` attribute if input is not an unsigned integer.


it('edits nofASDU attribute only for valid inputs', async () => {
        const input = <WizardTextField>inputs[5];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async nofASDU => {
              input.value = nofASDU;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.true;
            }
          )
        );
      })

Summary: Editing the `nofASDU` attribute maintains validity for non-negative integer inputs.


it('rejects nofASDU attribute in case input is not unsigned int', async () => {
        const input = <WizardTextField>inputs[5];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async nofASDU => {
              input.value = nofASDU;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.false;
            }
          )
        );
      })

Summary: The test ensures that the `nofASDU` attribute is invalid when the input value is not an unsigned integer.


Summary: Edits to the name attribute are allowed only when the inputs meet the valid format specified by the `tAsciName` regular expression.


Summary: The property ensures that a name attribute starting with a decimal value is considered invalid.


it('rejects bufTime attribute starting with not being a unsigned int', async () => {
        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async bufTime => {
              inputs[6].value = bufTime;
              await (<WizardTextField>inputs[6]).requestUpdate();
              expect(inputs[6].checkValidity()).to.be.false;
            }
          )
        );
      })

Summary: Checks that a `bufTime` attribute starting with a non-unsigned integer is invalid.


it('edits intgPd attribute only for valid inputs', async () => {
        const input = <WizardTextField>inputs[7];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async intgPd => {
              input.value = intgPd;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.true;
            }
          )
        );
      })

Summary: Edits the `intgPd` attribute only when the input is a valid non-negative integer string.


it('rejects intgPd attribute starting with not being a unsigned int', async () => {
        const input = <WizardTextField>inputs[7];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(regexString(inverseRegExp.uint, 1), async intgPd => {
            input.value = intgPd;
            await input.requestUpdate();
            expect(input.checkValidity()).to.be.false;
          })
        );
      })

Summary: The `intgPd` attribute should be rejected if it starts as a non-unsigned integer.


it('edits prefix attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.tAsciName, 1, 11), async name => {
            inputs[2].value = name;
            await (<WizardTextField>inputs[2]).requestUpdate();
            expect(inputs[2].checkValidity()).to.be.true;
          })
        );
      })

Summary: Editing the prefix attribute is valid only for inputs that match the specified regex pattern.


it('rejects name attribute starting with decimals', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => {
            inputs[2].value = name;
            await (<WizardTextField>inputs[2]).requestUpdate();
            expect(inputs[2].checkValidity()).to.be.false;
          })
        );
      })

Summary: Name attributes starting with decimals are rejected as invalid.


it('edits name attribute only for valid inputs', async () => {
      await fc.assert(
        fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => {
          nameTextField.value = name;
          await nameTextField.requestUpdate();
          expect(nameTextField.checkValidity()).to.be.true;
        })
      );
    })

Summary: Editing the name attribute should only be successful for inputs that match the `regExp.tAsciName` pattern with lengths between 1 and 32 characters.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSI, 1, 8), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))

Summary: An input value matching the specified regex pattern should be valid when edited.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSI, 1, 16),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))

Summary: The input value based on a specific regex pattern should always be valid for editing, ensuring `checkValidity` returns true.


Summary: Editing is allowed when the input value matches the regex pattern `regExp.OSI` and is of valid length (1 to 16 characters), ensuring `input.checkValidity()` returns true.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSIAPi, 1), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))

Summary: Editing is allowed when the input matches a specified OSIAP pattern.


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.OSIAPi), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))

Summary: Editing is disallowed for invalid input when `input.checkValidity()` returns false.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSIid, 1, 5),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))

Summary: Valid input strings matching `regExp.OSIid` pattern enable editing by passing a validity check.


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.OSIid), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))

Summary: Invalid input based on `OSIid` regex should not be editable as determined by `checkValidity` returning false.


Summary: Editing should be allowed for inputs that match the valid OSI identifier pattern.


Summary: Editing is disallowed for inputs that do not match the `OSIid` regular expression, ensuring `checkValidity` returns false.


Summary: Editing is allowed for inputs matching the `OSIid` regular expression, when the input's validity is checked.


Summary: Editing is disallowed for inputs that do not match a valid `OSIid` pattern.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSI, 1, 40),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))

Summary: The test ensures that input values matching the `regExp.OSI` regex pattern are considered valid when edited, verifying `checkValidity` returns true.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSI, 3, 3), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))

Summary: Editing is allowed if the input value matches a specific OSI regex pattern.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(/^[0-7]$/), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))

Summary: Editing should be allowed for inputs consisting of single characters between '0' and '7'.


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              nat({ max: 65535 }).map(num => `${num}`),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))

Summary: Input values between 0 and 65535 should be valid for editing, with `checkValidity()` returning true.


UnitTest.test('DialogChanges.init - no initial data', () => {
  const dialogChange = DialogChanges.init({ title: '', text: '' } as LinkDialogData, { } as LinkDialogCatalog);

  fc.assert(fc.property(fc.webUrl(), fc.asciiString(), fc.asciiString(), (url, title, text) => {
    const data = Fun.constant({ url: {
      value: url,
      meta: { title, text }
    }} as LinkDialogData);
    const dataNoMeta = Fun.constant({ url: {
      value: url,
      meta: { }
    }} as LinkDialogData);

    Assert.eq('on url change should include url title and text',
      Optional.some<Partial<LinkDialogData>>({ title, text }),
      dialogChange.onChange(data, { name: 'url' }),
      tOptional()
    );

    Assert.eq('on url change should fallback to url for text',
      Optional.some<Partial<LinkDialogData>>({ title: '', text: url }),
      dialogChange.onChange(dataNoMeta, { name: 'url' }),
      tOptional()
    );
  }));
})

Summary: `DialogChanges.init` processes `url` changes, updating with `title` and `text` from metadata or defaulting text to `url` if metadata is absent.


UnitTest.test('DialogChanges.init - with original data', () => {
  const dialogChange = DialogChanges.init({ title: 'orig title', text: 'orig text' } as LinkDialogData, { } as LinkDialogCatalog);
  const dialogChangeNoTitle = DialogChanges.init({ title: '', text: 'orig text' } as LinkDialogData, { } as LinkDialogCatalog);
  const dialogChangeNoText = DialogChanges.init({ title: 'orig title', text: '' } as LinkDialogData, { } as LinkDialogCatalog);

  fc.assert(fc.property(fc.webUrl(), fc.asciiString(), fc.asciiString(), (url, title, text) => {
    const data = Fun.constant({ url: {
      value: url,
      meta: { title, text }
    }} as LinkDialogData);

    Assert.eq('on url change should not try to change title and text',
      Optional.none(),
      dialogChange.onChange(data, { name: 'url' }),
      tOptional()
    );

    Assert.eq('No Title - on url change should only try to change title',
      Optional.some<Partial<LinkDialogData>>({ title }),
      dialogChangeNoTitle.onChange(data, { name: 'url' }),
      tOptional()
    );

    Assert.eq('No Text - on url change should only try to change text',
      Optional.some<Partial<LinkDialogData>>({ text }),
      dialogChangeNoText.onChange(data, { name: 'url' }),
      tOptional()
    );
  }));
})

Summary: The `DialogChanges.init` function should handle original data such that changing the URL does not modify title or text if both are present, modifies only the title if the title is absent, and modifies only the text if the text is absent.


UnitTest.test('leftTrim(whitespace + s) === leftTrim(s)', () => {
  fc.assert(fc.property(
    fc.string(),
    (s) => {
      Assert.eq('leftTrim', Strings.lTrim(' ' + s), Strings.lTrim(s), tString);
    }
  ));
})

Summary: `Strings.lTrim` should produce the same result whether or not the input string is preceded by a whitespace character.


it("tanh forward pass property: tanh(a).data === Math.tanh(a.data)", () => {
    // Avoid large inputs to tanh where output is exactly +/-1, might cause gradient issues if not handled carefully later
    const boundedValueArbitrary = fc
      .float({ min: -10, max: 10, noNaN: true })
      .map((n) => eng.value(n));
    fc.assert(
      fc.property(boundedValueArbitrary, (a) => {
        const result = eng.tanh(a);
        return closeTo(result.data, Math.tanh(a.data));
      }),
    );
  })

Summary: The `tanh` forward pass should return a value close to `Math.tanh` for the same input data within a specified tolerance.


UnitTest.test('rightTrim(s + whitespace) === rightTrim(s)', () => {
  fc.assert(fc.property(
    fc.string(),
    (s) => {
      Assert.eq('rightTrim', Strings.rTrim(s + ' '), Strings.rTrim(s), tString);
    }
  ));
})

Summary: `Strings.rTrim` should produce the same result whether whitespace is appended to the input string or not.


it("add backward pass gradient property", () => {
    fc.assert(
      fc.property(valueArbitrary, valueArbitrary, (a, b) => {
        // Need fresh values for each run to avoid grad accumulation across properties
        const fresh_a = eng.value(a.data);
        const fresh_b = eng.value(b.data);
        const result = eng.add(fresh_a, fresh_b);
        eng.backward(result);
        // Check gradients are approximately 1.0 (scaled by result.grad which is 1.0)
        return closeTo(fresh_a.grad, 1.0) && closeTo(fresh_b.grad, 1.0);
      }),
    );
  })

Summary: The gradients computed during the backward pass after adding two values should be approximately 1.0 for each value.


UnitTest.test('trim(whitespace + s) === trim(s)', () => {
  fc.assert(fc.property(
    fc.string(),
    (s) => {
      Assert.eq('trim', Strings.trim(' ' + s), Strings.trim(s), tString);
    }
  ));
})

Summary: Trimming a string with leading whitespace should yield the same result as trimming the string without the whitespace.


UnitTest.test('trim(s + whitespace) === trim(s)', () => {
  fc.assert(fc.property(
    fc.string(),
    (s) => {
      Assert.eq('trim', Strings.trim(s + ' '), Strings.trim(s), tString);
    }
  ));
})

Summary: The `trim` function should remove trailing whitespace from a string, resulting in the same output whether the string ends with whitespace or not.


UnitTest.test('trim(whitespace + s + whitespace) === trim(s)', () => {
  fc.assert(fc.property(
    fc.string(),
    (s) => {
      Assert.eq('trim', Strings.trim(' ' + s + ' '), Strings.trim(s), tString);
    }
  ));
})

Summary: Trimming whitespace from the beginning and end of a string should produce the same result as trimming the string alone.


UnitTest.test('Strings.repeat: positive range', () => {
  fc.assert(fc.property(fc.char(), fc.integer(1, 100), (c, count) => {
    const actual = Strings.repeat(c, count);
    Assert.eq('length should be the same as count', count, actual.length);
    Assert.eq('first char should be the same', c, actual.charAt(0));
    Assert.eq('last char should be the same', c, actual.charAt(actual.length - 1));
  }));

  fc.assert(fc.property(fc.asciiString(5), fc.integer(1, 100), (s, count) => {
    const actual = Strings.repeat(s, count);
    Assert.eq('length should be count * original length', count * s.length, actual.length);
    Assert.eq('should start with string', 0, actual.indexOf(s));
    Assert.eq('should end with string', actual.length - s.length, actual.lastIndexOf(s));
  }));
})

Summary: The `Strings.repeat` function should produce a string with the correct length and identical start and end characters or substring, when repeating a single character or a string respectively.


it("mul commutativity property (data only)", () => {
    fc.assert(
      fc.property(valueArbitrary, valueArbitrary, (a, b) => {
        const res1 = eng.mul(a, b);
        const res2 = eng.mul(b, a);
        return closeTo(res1.data, res2.data);
      }),
    );
  })

Summary: Multiplication is commutative, ensuring `eng.mul(a, b)` equals `eng.mul(b, a)` for their data properties within a specified tolerance.


Summary: `Strings.repeat` function correctly replicates characters or strings a specified number of times, maintaining expected length and preserving sequences at the start and end.


UnitTest.test('Strings.repeat: negative range', () => {
  fc.assert(fc.property(fc.char(), fc.integer(-100, 0), (c, count) => {
    const actual = Strings.repeat(c, count);
    Assert.eq('length should be 0', 0, actual.length);
    Assert.eq('should be an empty string', '', actual);
  }));
})

Summary: `Strings.repeat` with a negative or zero count produces an empty string with length 0.


it('rejects usernames shorter than 4 characters', () => {
		fc.assert(
			fc.property(fc.string({ maxLength: 3 }), (username) => {
				expect(verifyUsernameInput(username)).toBe(false);
			}),
			{ numRuns: 200 } // fast-check default runs is 100
		);
	})

Summary: Usernames shorter than 4 characters are rejected by `verifyUsernameInput`.


it('rejects usernames longer than 31 characters', () => {
		fc.assert(
			fc.property(fc.string({ minLength: 32 }), (username) => {
				expect(verifyUsernameInput(username)).toBe(false);
			}),
			{ numRuns: 200 }
		);
	})

Summary: `verifyUsernameInput` returns false for usernames longer than 31 characters.


UnitTest.test('removeTrailing property', () => {
  fc.assert(fc.property(
    fc.asciiString(),
    fc.asciiString(),
    (prefix, suffix) => {
      Assert.eq('removeTrailing', prefix, Strings.removeTrailing(prefix + suffix, suffix));
    }
  ));
})

Summary: `removeTrailing` should return the original prefix when it is concatenated with a suffix and the suffix is removed.


UnitTest.test('ensureTrailing endsWith', () => {
  fc.assert(fc.property(
    fc.string(),
    fc.string(),
    (s, suffix) => Strings.endsWith(Strings.ensureTrailing(s, suffix), suffix)
  ));
})

Summary: `Strings.ensureTrailing` appends a suffix to a string if it's not already present, ensuring the result ends with the suffix.


UnitTest.test('endsWith: A string added to a string (at the end) must have endsWith as true', () => {
  fc.assert(fc.property(
    fc.asciiString(),
    fc.asciiString(),
    (str, contents) => Strings.endsWith(str + contents, contents)
  ));
})

Summary: A string concatenated with another string at the end should have `endsWith` return true for the added string.


UnitTest.test('A string with length 1 or larger should never be empty', () => {
  fc.assert(fc.property(fc.string(1, 40), (str) => {
    Assert.eq('isEmpty', false, Strings.isEmpty(str));
    Assert.eq('isNotEmpty', true, Strings.isNotEmpty(str));
  }));
})

Summary: A string with a length of 1 or more should not be identified as empty by both `Strings.isEmpty` and `Strings.isNotEmpty`.


UnitTest.test('A string added to a string (at the end) must be contained within it', () => {
  fc.assert(fc.property(
    fc.string(),
    fc.string(1, 40),
    (str, contents) => {
      const r = str + contents;
      Assert.eq('eq', true, Strings.contains(r, contents));
    }
  ));
})

Summary: Appending a string to another should result in the appended string being contained within the final string.


test('should always include required headers', () => {
      fc.assert(
        fc.property(
          fc.webUrl(),
          fc.option(fc.dictionary(fc.string(), fc.string())),
          fc.option(fc.json()),
          async (url, headers, body) => {
            fetch.mockResolvedValue({
              ok: true,
              json: async () => ({})
            });

            await apiClient.request(url, {
              headers,
              body: body ? JSON.stringify(body) : undefined
            });

            const [, options] = fetch.mock.calls[0];

            // Should always have Content-Type
            expect(options.headers).toHaveProperty('Content-Type');

            // Should preserve custom headers
            if (headers) {
              Object.keys(headers).forEach(key => {
                expect(options.headers[key]).toBeDefined();
              });
            }
          }
        ),
        { numRuns: 100 }
      );
    })

Summary: The API client always includes the 'Content-Type' header and preserves any custom headers in requests.


UnitTest.test('A string added to a string (at the start) must be contained within it', () => {
  fc.assert(fc.property(
    fc.string(),
    fc.string(1, 40),
    (str, contents) => {
      const r = contents = str;
      Assert.eq('eq', true, Strings.contains(r, contents));
    }
  ));
})

Summary: A string added at the start of another string should be contained within it.


UnitTest.test('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 non-empty substring.


UnitTest.test('capitalize: tail of the string is unchanged', () => {
  fc.assert(fc.property(fc.ascii(), fc.asciiString(30), (h, t) => {
    Assert.eq('tail', t, Strings.capitalize(h + t).substring(1), tString);
  }));
})

Summary: The test verifies that after capitalizing a string, the tail (all characters except the first one) remains unchanged.


UnitTest.test('StringMatch.matches(StringMatch.starts(s1), s1 + s) === true', () => {
  fc.assert(fc.property(
    fc.string(),
    fc.string(),
    (s, s1) => {
      Assert.eq('eq', true, StringMatch.matches(
        StringMatch.starts(s1, StringMatch.caseInsensitive),
        s1 + s
      ));
    }
  ));
})

Summary: `StringMatch.matches` should return true when a string starting with `s1` is concatenated with another string, ensuring a case-insensitive prefix match.


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

Summary: `StringMatch.matches` returns false when checking if a string concatenated with another string matches exactly the original string.


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

Summary: `StringMatch.matches` should return false when checking for an exact match of a string `s` at the end of another string `s1 + s`, indicating that `s` must be an exact match without any preceding characters.


UnitTest.test('StringMatch.matches(StringMatch.exact(s), s) === true', () => {
  fc.assert(fc.property(
    fc.string(1, 40),
    (s) => {
      Assert.eq('eq', true, StringMatch.matches(
        StringMatch.exact(s, StringMatch.caseInsensitive),
        s
      ));
    }
  ));
})

Summary: Verifies that the `StringMatch.matches` function returns true when matching a string against itself using the `StringMatch.exact` method with case insensitivity.


UnitTest.test('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: Verifies that `StringMatch.matches` returns false for exact matches when the strings have different cases, even with case-insensitivity enabled, unless the strings are identical when both are transformed to upper or lower case.


UnitTest.test('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` returns false when comparing a lowercase string with its uppercase version if case-sensitive matching is specified.


UnitTest.test('StringMatch.matches(StringMatch.all(s1), *) === true', () => {
  fc.assert(fc.property(
    fc.string(),
    fc.string(),
    (s) => {
      Assert.eq('eq', true, StringMatch.matches(
        StringMatch.all(),
        s
      ));
    }
  ));
})

Summary: `StringMatch.matches` should always return true when using `StringMatch.all()` with any string.


UnitTest.test('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.eq('eq', 0, output.length);
    }
  ));
})

Summary: `Optionals.cat` returns an empty array when provided with an array of only `none` elements.


UnitTest.test('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.eq('eq', options.length, output.length);
    }
  ));
})

Summary: `Optionals.cat` should output an array with the same length as the input array when composed only of `some` optional values.


UnitTest.test('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.eq('eq', arr, output);
    }
  ));
})

Summary: `Optionals.cat` applied to an array mapped with `Optional.some` should return the original array.


UnitTest.test('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.eq('eq', output.length <= arr.length, true);
    }
  ));
})

Summary: `Optionals.cat` outputs an array whose length is less than or equal to the input array's length when composed of optional integers.


UnitTest.test('Optionals.someIf: false -> none', () => {
  fc.assert(fc.property(fc.integer(), (n) => {
    Assert.eq('eq', Optional.none(), Optionals.someIf<number>(false, n), tOptional());
  }));
})

Summary: `Optionals.someIf` should return `none` when the condition is false, regardless of the integer value provided.


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

Summary: `Optionals.sequence` results in `Optional.none` when appending `Optional.none` to an array of `Optional.some` integers.


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

Summary: `Optionals.sequence` returns `Optional.none()` when the input array starts with `Optional.none()` followed by some `Optional.some()` values.


UnitTest.test('Optionals.sequence: all some', () => {
  fc.assert(fc.property(fc.array(fc.integer()), (n) =>
    Assert.eq('eq',
      Optionals.traverse<number, number>(n, (x) => Optional.some(x)),
      Optionals.sequence<number>(Arr.map(n, (x) => Optional.some(x))),
      tOptional()
    )
  ));
})

Summary: Calling `Optionals.traverse` with a function returning `Optional.some` should be equivalent to calling `Optionals.sequence` with an array of `Optional.some` values.


UnitTest.test('Optionals.flatten: some(some(x))', () => {
  fc.assert(fc.property(fc.integer(), function (n) {
    Assert.eq('eq', Optional.some(n), Optionals.flatten(Optional.some(Optional.some<number>(n))), tOptional());
  }));
})

Summary: Flattening a nested `Optional` object containing an integer should result in a non-nested `Optional` with the same integer.


UnitTest.test('Optional.none() !== Optional.some(x)', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    Assert.eq('eq', false, Optional.none().equals(Optional.some(i)));
  }));
})

Summary: `Optional.none()` is not equal to `Optional.some(x)` for any integer `x`.


test('should safely handle any error response', () => {
      fc.assert(
        fc.property(
          fc.oneof(
            fc.constant(null),
            fc.constant(undefined),
            fc.string(),
            fc.object(),
            fc.array(fc.anything())
          ),
          fc.integer({ min: 400, max: 599 }),
          async (errorBody, statusCode) => {
            fetch.mockResolvedValue({
              ok: false,
              status: statusCode,
              json: async () => {
                if (errorBody === null || errorBody === undefined) {
                  throw new Error('Invalid JSON');
                }
                return errorBody;
              }
            });

            await expect(apiClient.request('/test')).rejects.toThrow();

            // Should not crash on any input
            expect(true).toBe(true);
          }
        ),
        { numRuns: 100 }
      );
    })

Summary: `apiClient.request` should throw an error for any non-OK HTTP status code and varied error responses without crashing.


UnitTest.test('Optional.some(x) !== Optional.none()', () => {
  fc.assert(fc.property(fc.integer(), (i) => {
    Assert.eq('eq', false, (Optional.some(i).equals(Optional.none())));
  }));
})

Summary: `Optional.some(x)` should not be equal to `Optional.none()`.


UnitTest.test('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.eq('eq', false, Optional.some(a).equals(Optional.some(a + b)));
  }));
})

Summary: `Optional.some(x)` is not equal to `Optional.some(x + y)` when `y` is not an identity value.


test('should handle network errors gracefully', () => {
      fc.assert(
        fc.property(
          fc.oneof(
            fc.constant(new Error('Network error')),
            fc.constant(new TypeError('Failed to fetch')),
            fc.constant(new Error('ECONNREFUSED')),
            fc.constant(new Error('ETIMEDOUT'))
          ),
          async (error) => {
            fetch.mockRejectedValue(error);

            await expect(apiClient.request('/test')).rejects.toThrow();

            // Should handle any network error type
            expect(true).toBe(true);
          }
        ),
        { numRuns: 50 }
      );
    })

Summary: `apiClient.request` should throw an error when any network error type occurs, ensuring it handles network errors gracefully.


UnitTest.test('none !== some, for any predicate', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), (opt1) => {
    Assert.eq('eq', false, Optional.none().equals_(opt1, boom));
  }));
})

Summary: `Optional.none()` is not equal to any `Some` value for any predicate.


UnitTest.test('Checking some(x).equals_(some(y), _, _ -> false) === false', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), arbOptionSome(fc.integer()), (opt1, opt2) => {
    Assert.eq('eq', false, opt1.equals_(opt2, Fun.never));
  }));
})

Summary: Verifies that two distinct `Some` options, when compared using a function that always returns `false`, are considered unequal.


UnitTest.test('Checking some(x).fold(die, id) === x', () => {
  fc.assert(fc.property(fc.integer(), (json) => {
    const opt = Optional.some(json);
    const actual = opt.fold(Fun.die('Should not be none!'), Fun.identity);
    Assert.eq('eq', json, actual);
  }));
})

Summary: For an `Optional` instance created with a value, `fold` with a function that returns the value should yield that original value.


test('should handle any sequence of stream chunks', () => {
      fc.assert(
        fc.property(
          fc.array(
            fc.oneof(
              fc.string(),
              fc.constant(''),
              fc.constant('[DONE]')
            ),
            { minLength: 0, maxLength: 100 }
          ),
          async (chunks) => {
            const streamChunks = chunks.map((content, index) =>
              content === '[DONE]'
                ? 'data: [DONE]\n\n'
                : `data: ${JSON.stringify(createMockStreamChunk(content, index === chunks.length - 1))}\n\n`
            );

            fetch.mockResolvedValue({
              ok: true,
              headers: new Headers({ 'content-type': 'text/event-stream' }),
              body: createMockStream(streamChunks)
            });

            const messages = [];
            await apiClient.streamRequest('/chat', {}, (message) => {
              messages.push(message);
            });

            // Should process all non-[DONE] chunks
            const expectedCount = chunks.filter(c => c !== '[DONE]').length;
            expect(messages.length).toBeLessThanOrEqual(expectedCount);
          }
        ),
        { numRuns: 50 }
      );
    })

Summary: `apiClient.streamRequest` should correctly process sequences of stream chunks, handling both standard and '[DONE]' markers in the input, and ensure that the number of processed messages does not exceed the count of non-'[DONE]' chunks.


UnitTest.test('Checking some(x).is(x) === true', () => {
  fc.assert(fc.property(fc.integer(), (json) => {
    const opt = Optional.some(json);
    Assert.eq('eq', true, opt.is(json));
  }));
})

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


UnitTest.test('Checking some(x).getOr(v) === x', () => {
  fc.assert(fc.property(arbOptionSome(fc.integer()), arbOptionSome(fc.integer()), (a, b) => {
    Assert.eq('eq', a, Optional.some(a).getOr(b));
  }));
})

Summary: `Optional.some(x).getOr(v)` should return `x`.


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

Summary: `Optional.some(a).getOrThunk(thunk)` should equal `a` for any integer `a` and any thunk function.


UnitTest.test('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(i).getOrDie(s)` does not throw an exception for any integer `i` and string `s`.