Example #1
0
  describe("associativity", function () {
    jsc.property("xs ++ (ys ++ zs) ≡ (xs ++ ys) ++ zs", "array nat", "array nat", "array nat", function (xs, ys, zs) {
      xs = lazyseq.fromArray(xs);
      ys = lazyseq.fromArray(ys);
      zs = lazyseq.fromArray(zs);

      var lhs = lazyseq.append(xs, lazyseq.append(ys, zs));
      var rhs = lazyseq.append(lazyseq.append(xs, ys), zs);

      return _.isEqual(lhs.toArray(), rhs.toArray());
    });

    jsc.property("xs ++ (ys ++ zs) ≡ xs ++ ys ++ zs", "array nat", "array nat", "array nat", function (xs, ys, zs) {
      xs = lazyseq.fromArray(xs);
      ys = lazyseq.fromArray(ys);
      zs = lazyseq.fromArray(zs);

      var lhs = lazyseq.append(xs, lazyseq.append(ys, zs));
      var rhs = lazyseq.append(xs, ys, zs);

      return _.isEqual(lhs.toArray(), rhs.toArray());
    });

    jsc.property("kind of flatten", "array (array nat)", function (xs) {
      var ys = xs.map(lazyseq.fromArray);
      var lhs = lazyseq.append.apply(undefined, ys).toArray();
      var rhs = _.flatten(xs);

      return _.isEqual(lhs, rhs);
    });
  });
Example #2
0
  describe('Equality', () => {
    const { A, B } = union('AB', {
      A: (value) => ({ value }),
      B: (value) => ({ value })
    }).derive(equality)
    
    property('Different simple values are NOT equal', 'json', (a) => {
      return !A(a).equals(B(a))
    });
    property('Different composite values are NOT equal', 'json', (a) => {
      return !A(B(a)).equals(A(a))
    });
    property('Similar simple values are equal', 'json', (a) => {
      return A(a).equals(A(a))
    });
    property('Similar composite values are equal', 'json', (a) => {
      return A(B(a)).equals(A(B(a)))
    });

    describe('Equality#withCustomComparison', () => {

      const { A } = union('A', {
        A: (value) => ({ value }),
      }).derive(equality.withCustomComparison((a, b) => a.id === b.id));
      
      property('Values are compared using a custom function if provided', 'json', 'json', function(a, b) {
        return A({id:1, _irrelevantValue:a}).equals(A({id:1, _irrelevantValue: b}))
      });
    });
  });
describe('arbitrary selector', function() {
  jsc.property('div(".class") ≡ React.createElement("div.class")', "nestring", function(className) {
    const selector = '.' + className;
    const hr = React.createElement('div' + selector);
    const divr = div(selector);
    return jsc.utils.isApproxEqual(hr, divr);
  });

  jsc.property('div("#id") ≡ React.createElement("div#id")', "nestring", function(id) {
    const selector = '#' + id;
    const hr = React.createElement('div' + selector);
    const divr = div(selector);
    return jsc.utils.isApproxEqual(hr, divr);
  });

  jsc.property('div("[.#]foo", children) ≡ React.createElement("div[.#]id", children)', selChars, "nestring", "array string", function(selChar, id, children) {
    const selector = selChar + id;
    const hr = React.createElement('div' + selector, children);
    const divr = div(selector, children);
    return jsc.utils.isApproxEqual(hr, divr);
  });

  jsc.property('div("[.#]foo", attrs, children) ≡ React.createElement("div[.#]id", attrs, children)', selChars, "nestring", "dict string", "array string", function(selChar, id, attrs, children) {
    const selector = selChar + id;
    const hr = React.createElement('div' + selector, attrs, children);
    const divr = div(selector, attrs, children);
    return jsc.utils.isApproxEqual(hr, divr);
  });
});
Example #4
0
  describe("right identities", function () {
    jsc.property("nil", "array nat", function (arr) {
      var lhs = lazyseq.append(arr, lazyseq.nil).toArray();
      var rhs = arr;
      return _.isEqual(lhs, rhs);
    });

    jsc.property("[]", "array nat", function (arr) {
      var lhs = lazyseq.append(arr, []).toArray();
      var rhs = arr;
      return _.isEqual(lhs, rhs);
    });

    jsc.property("() → nil", "array nat", function (arr) {
      var lhs = lazyseq.append(arr, function () { return lazyseq.nil; }).toArray();
      var rhs = arr;
      return _.isEqual(lhs, rhs);
    });

    jsc.property("() → []", "array nat", function (arr) {
      var lhs = lazyseq.append(arr, function () { return []; }).toArray();
      var rhs = arr;
      return _.isEqual(lhs, rhs);
    });
  });
Example #5
0
  describe('Serialization', () => {
    const AB = union('folktale:AB', {
      A: (value) => ({ value }),
      B: (value) => ({ value })
    }).derive(serialization, equality);
    
    const CD = union('folktale:CD', {
      C: (value) => ({value}),
      D: (value) => ({value})
    }).derive(serialization, equality);

    const {A, B} = AB;
    const {C, D} = CD;

    property('Serializing a value and deserializing it yields a similar value', 'json', (a) => {
      return AB.fromJSON(A(a).toJSON()).equals(A(a))
    })
    property('Serializing a *recursive* value and deserializing it yields a similar value', 'json', (a) => {
      return AB.fromJSON(A(B(a)).toJSON()).equals(A(B(a)))
    })

    property('Serializing a *composite* value and deserializing it yields a similar value (when the proper parsers are provided).', 'json', (a) => {
      return AB.fromJSON(A(B(C(a))).toJSON(), {AB, CD}).equals(A(B(C(a))))
    })
  });
Example #6
0
describe('curry properties', function() {
  jsv.property('curries multiple values', funcN(4), jsv.json, jsv.json, jsv.json, jsv.json, function(f, a, b, c, d) {
    var g = R.curry(f);

    return R.all(R.equals(f(a, b, c, d)), [
      g(a, b, c, d),
      g(a)(b)(c)(d),
      g(a)(b, c, d),
      g(a, b)(c, d),
      g(a, b, c)(d)
    ]);
  });

  jsv.property('curries with placeholder', funcN(3), jsv.json, jsv.json, jsv.json, function(f, a, b, c) {
    var _ = {'@@functional/placeholder': true, x: Math.random()};
    var g = R.curry(f);

    return R.all(R.equals(f(a, b, c)), [
      g(_, _, c)(a, b),
      g(a, _, c)(b),
      g(_, b, c)(a),
      g(a, _, _)(_, c)(b),
      g(a, b, _)(c)
    ]);
  });
});
Example #7
0
 describe('Conversions', () => {
   property('Just#fromResult', 'json', (a) => {
     return Maybe.fromResult(Just(a).toResult()).equals(Just(a));
   });
   property('Nothing#fromResult', 'json', (a) => {
     return Maybe.fromResult(Nothing().toResult()).equals(Nothing());
   });
 });
Example #8
0
  describe('minimumOf', () => {
    jsv.property('minimumOf empty',
      () => R.equals(Fold.minimumOf(Traversal.traversed, []), RF.Maybe.Nothing()));

    jsv.property('minimumOf non-empty',
      jsv.nearray(jsv.nat),
      xs => R.equals(Fold.minimumOf(Traversal.traversed, xs), RF.Maybe.Just(R.reduce(R.min, Infinity, xs))));
  });
Example #9
0
  describe('lastOf', () => {
    jsv.property('lastOf empty',
                 () => R.equals(Fold.lastOf(Traversal.traversed, []), RF.Maybe.Nothing()));

    jsv.property('lastOf non-empty',
      jsv.nearray(jsv.nat),
      xs => R.equals(Fold.lastOf(Traversal.traversed, xs), RF.Maybe.Just(R.last(xs))));
  });
Example #10
0
describe("partitions", function () {
  it("example 1", function () {
    var result = utils.partitions(3, 1);
    chai.expect(result).to.deep.equal([[3]]);
  });

  it("example 2", function () {
    var result = utils.partitions(3, 2);
    chai.expect(normalize(result)).to.deep.equal(normalize([
      [3, 0],
      [2, 1],
      [1, 2],
      [0, 3],
    ]));
  });

  it("example 3", function () {
    var result = utils.partitions(3, 3);
    chai.expect(normalize(result)).to.deep.equal(normalize([
      [0, 0, 3],
      [0, 1, 2],
      [0, 2, 1],
      [0, 3, 0],
      [1, 0, 2],
      [1, 1, 1],
      [1, 2, 0],
      [2, 0, 1],
      [2, 1, 0],
      [3, 0, 0],
    ]));
  });

  var genN = "nat 7";
  var genM = "nat 6";

  jsc.property("partitions are of right size", genN, genM, function (n, m) {
    m += 1;
    var result = utils.partitions(n, m);
    return result.every(function (p) {
      return p.length === m;
    });
  });

  jsc.property("partitions add to size", genN, genM, function (n, m) {
    m += 1;
    var result = utils.partitions(n, m);
    return result.every(function (p) {
      return n === p.reduce(function (a, b) { return a + b; }, 0);
    });
  });

  jsc.property("there are all partitions", genN, genM, function (n, m) {
    m += 1;
    // console.log(n, m, binomialCoefficient(m + n - 1, n));
    var result = utils.partitions(n, m);
    return result.length === binomialCoefficient(m + n - 1, n);
  });
});
Example #11
0
  describe('notElemOf', () => {
    jsv.property('notElemOf',
                 jsv.json, jsv.array(jsv.json),
                 (x, xs) => R.equals(Fold.notElemOf(Traversal.traversed, x, xs), !R.contains(x, xs)));

    jsv.property('notElemOf does not exist',
                 jsv.json, jsv.nearray(jsv.json),
                 (x, xs) => Fold.notElemOf(Traversal.traversed, x, R.without([x], xs)));
  });
Example #12
0
  describe('elemOf', () => {
    jsv.property('elemOf',
                 jsv.json, jsv.array(jsv.json),
                 (x, xs) => R.equals(Fold.elemOf(Traversal.traversed, x, xs), R.contains(x, xs)));

    jsv.property('elemOf does exist',
                 jsv.nearray(jsv.json),
                 xs => Fold.elemOf(Traversal.traversed, xs[0], xs));
  });
  describe('Monoid instance', _ => {
    property('right identity', 'string', (a) =>
      equals(type(a)[concat](type()[empty]()), type(a))
    );

    property('left identity', 'string', (a) =>
      equals(type()[empty]()[concat](type(a)), type(a))
    );
  });
Example #14
0
describe("tail", function () {
  jsc.property("nil.tail() === nil", function () {
    return lazyseq.nil.tail() === lazyseq.nil;
  });

  jsc.property("cons(n, nil).tail() === nil", "nat", function (n) {
    return lazyseq.cons(n, lazyseq.nil).tail() === lazyseq.nil;
  });
});
Example #15
0
describe('converge', () => {
  jsc.property('converges results of individual functions', 'fun', 'array fun', 'nearray',
    (fn, fns, args) => converge(fn, fns, ...args) === fn(...fns.map(f => f(...args)))
  )

  jsc.property('curry', 'fun', 'array fun', 'nearray',
    (fn, fns, args) => converge(fn)(fns)(...args) === converge(fn, fns, ...args)
  )
})
Example #16
0
  describe('#getOrElse(b)', () => {
    property('Just(a).getOrElse(b) = a', 'json', 'json', (a, b) => {
      return Just(a).getOrElse(b) === a;
    });

    property('Nothing().getOrElse(b) = b', 'json', (a) => {
      return Nothing().getOrElse(a) === a;
    });
  });
Example #17
0
  describe('#empty()', () => {
    property('empty().equals(Nothing()) = true', () => {
      return Maybe.empty().equals(Nothing());
    });

    property('!(empty().equals(Just(a))) = false', 'nat', (a) => {
      return !(Maybe.empty().equals(Just(a)));
    });
  });
Example #18
0
  describe('#chain(f)', () => {
    property('Just(a).chain(f) = f(a)', 'json', 'json -> json', (a, f) => {
      return Just(a).chain(x => Just(f(x))).equals(Just(f(a)));
    });

    property('Nothing().chain(f) = Nothing()', 'json -> json', (f) => {
      return Nothing().chain(x => Just(f(x))).equals(Nothing());
    });
  });
Example #19
0
  describe('#orElse(f)', () => {
    property('Just(a).orElse(f) = Just(a)', 'json', 'json -> json', (a, f) => {
      return Just(a).orElse(x => Just(f(x))).equals(Just(a));
    });

    property('Nothing().orElse(f) = f()', 'json', 'json -> json', (a, f) => {
      return Nothing().orElse(x => Just(f(a))).equals(Just(f(a)));
    });
  });
Example #20
0
  describe('#alt(f)', () => {
    property('Nothing().alt(Just(a)).alt(Just(b)) = Nothing().alt(Just(a).alt(Just(b)))', 'nat', 'nat', (a, b) => {
      return Nothing().alt(Just(a)).alt(Just(b)).equals(Nothing().alt(Just(a).alt(Just(b))));
    });

    property('Just(a).alt(Just(b)).map(f) = Just(a).map(f).alt(Just(b).map(f))', 'nat', 'nat', (a, b) => {
      const f = x => x + 1;
      return Just(a).alt(Just(b)).map(f).equals(Just(a).map(f).alt(Just(b).map(f)));
    });
  });
Example #21
0
  describe('Profunctor laws', () => {
    jsv.property('identity',
                 p,
                 p => eq(p.dimap(R.identity, R.identity), p));

    jsv.property('composition',
                 natFn, natFn, natFn, natFn, p,
                 (f,    f_,    h,     h_,    p) =>
                   eq(p.dimap(R.compose(h, h_), R.compose(f_, f)),
                      p.dimap(h, f).dimap(h_, f_)));
  });
Example #22
0
  describe('sequenceOf_', () => {
    jsv.property('sequenceOf_ all Just',
                 jsv.array(JustArb(jsv.json)),
                 xs => R.equals(Fold.sequenceOf_(RF.Maybe, Traversal.traversed, xs),
                                RF.Maybe.Just({})));

    jsv.property('sequenceOf_ with Nothing',
                 jsv.array(MaybeArb(jsv.json)),
                 xs => R.equals(Fold.sequenceOf_(RF.Maybe, Traversal.traversed, R.prepend(RF.Maybe.Nothing(), xs)),
                                RF.Maybe.Nothing()));
  });
Example #23
0
  describe('#toValidation(b)', () => {
    const { Success, Failure } = require('folktale/validation');

    property('Just(a).toValidation(b) = Succcess(a)', 'json', 'json', (a, b) => {
      return Just(a).toValidation(b).equals(Success(a));
    });

    property('Nothing().toValidation(b) = Failure(b)', 'json', 'json', (a, b) => {
      return Nothing().toValidation(b).equals(Failure(b));
    });
  });
Example #24
0
  describe('#toResult(b)', () => {
    const { Error, Ok } = require('folktale/result');

    property('Just(a).toResult(b) = Right(a)', 'json', 'json', (a, b) => {
      return Just(a).toResult(b).equals(Ok(a));
    });

    property('Nothing().toResult(b) = Error(b)', 'json', 'json', (a, b) => {
      return Nothing().toResult(b).equals(Error(b));
    });
  });
  describe('Functor instance', _ => {
    property('identity', 'nat', (a) =>
      equals(type(a)[map](a => a), type(a))
    );

    property('composition', 'nat', 'nat -> nat', 'nat -> nat', (a, f, g) =>
      equals(
        type(a)[map](x => f(g(x))),
        type(a)[map](g)[map](f)
      )
    );
  });
Example #26
0
  describe('toListOf', () => {
    jsv.property('toListOf list',
                 jsv.array(jsv.json),
                 xs => R.equals(Fold.toListOf(Traversal.traversed, xs), xs));

    jsv.property('toListOf Just',
                 jsv.json,
                 a => R.equals(Fold.toListOf(Prism._Just, RF.Maybe.Just(a)), [a]));

    jsv.property('toListOf Nothing',
                 () => R.equals(Fold.toListOf(Prism._Just, RF.Maybe.Nothing()), []));
  });
Example #27
0
  describe('#map', () => {
    jsv.property('identity law', 'array unit', xs =>
      R.equals(xs, map(x => x, xs))
    );

    jsv.property('composition law', 'array nat', 'nat', (xs, x) => {
      const f = R.curry((a, b) => a + b);
      const left = map(y => f(x)(y), xs);
      const right = map(g => g(x), map(f, xs));

      return R.equals(left, right);
    });
  });
Example #28
0
  describe('#apply(a)', () => {
    property('Just(f).apply(a) = Just(f(a))', 'nat', 'nat -> nat', (a, f) => {
      return Just(f).apply(Just(a)).equals(Just(f(a)));
    });

    property('Just(f).apply(Nothing()) = Nothing()', 'nat -> nat', (f) => {
      return Just(f).apply(Nothing()).equals(Nothing());
    })

    property('Nothing().apply(a) = Nothing()', 'nat', (a) => {
      return Nothing().apply(Just(a)).equals(Nothing());
    });
  });
Example #29
0
  describe('#concat(a)', () => {
    property('Just(a).concat(Nothing()) = Just(a)', 'string', (a) => {
      return Just(a).concat(Maybe.empty()).equals(Just(a));
    });

    property('Nothing().concat(Just(a)) = Nothing()', 'string', (a) => {
      return Maybe.empty().concat(Just(a)).equals(Just(a));
    });

    property('Just(a).concat(Just(b)) = Just(c)', 'string', 'string', (a, b) => {
      return Just(a).concat(Just(b)).equals(Just(a.concat(b)));
    });
  });
Example #30
0
  describe('#map', () => {
    jsv.property('identity law', 'ZipArray unit', env, xs =>
      R.equals(xs.runZipArray, xs.map(x => x).runZipArray)
    );

    jsv.property('composition law', 'ZipArray nat', 'nat', env, (xs, x) => {
      const f = R.curry((a, b) => a + b);
      const left = xs.map(y => f(x)(y)).runZipArray;
      const right = xs.map(f).map(f => f(x)).runZipArray;

      return R.equals(left, right);
    });
  });