UNPKG

4.64 kBJavaScriptView Raw
1var R = require('ramda');
2var assert = require('assert');
3var equalsInvoker = require('./utils').equalsInvoker;
4var types = require('./types')(equalsInvoker);
5var jsv = require('jsverify');
6
7var Maybe = require('..').Maybe;
8
9var MaybeGen = R.curry(function(a, n) {
10 return n % 2 === 0 ? Maybe.Just(a.generator(n)) : Maybe.Nothing();
11});
12
13var MaybeShow = R.curry(function(a, m) {
14 return (Maybe.isJust(m)) ?
15 'Just(' + a.show(m.value) + ')' :
16 'Nothing';
17});
18
19var MaybeShrink = R.curry(function(a, m) {
20 return (Maybe.isJust(m)) ?
21 [Maybe.Nothing()].concat(a.shrink(m.value).map(Maybe.Just)) :
22 [];
23});
24
25var MaybeArb = function(a) {
26 return {
27 generator: jsv.generator.bless(MaybeGen(a)),
28 show: MaybeShow(a),
29 shrink: jsv.shrink.bless(MaybeShrink(a))
30 };
31};
32
33describe('Maybe', function() {
34 var m = MaybeArb(jsv.nat);
35 var env = {Maybe: MaybeArb};
36 var appF = 'Maybe (nat -> nat)';
37 var appN = 'Maybe nat';
38
39 it('has an arbitrary', function() {
40 var arb = jsv.forall(m, function(m) {
41 return m instanceof Maybe;
42 });
43 jsv.assert(arb);
44 });
45
46 it('is a Functor', function() {
47 var fTest = types.functor;
48
49 jsv.assert(jsv.forall(m, fTest.iface));
50 jsv.assert(jsv.forall(m, fTest.id));
51 jsv.assert(jsv.forall(m, 'nat -> nat', 'nat -> nat', fTest.compose));
52 });
53
54 it('is an Apply', function() {
55 var aTest = types.apply;
56
57 jsv.assert(jsv.forall(m, aTest.iface));
58 jsv.assert(jsv.forall(appF, appF, appN, env, aTest.compose));
59 });
60
61 it('is an Applicative', function() {
62 var aTest = types.applicative;
63
64 jsv.assert(jsv.forall(m, aTest.iface));
65 jsv.assert(jsv.forall(appN, appN, env, aTest.id));
66 jsv.assert(jsv.forall(appN, 'nat -> nat', 'nat', env, aTest.homomorphic));
67 jsv.assert(jsv.forall(appN, appF, 'nat', env, aTest.interchange));
68 });
69
70 it('is a Chain', function() {
71 var cTest = types.chain;
72 var f = 'nat -> Maybe nat';
73
74 jsv.assert(jsv.forall(m, cTest.iface));
75 jsv.assert(jsv.forall(m, f, f, env, cTest.associative));
76 });
77
78 it('is a Monad', function() {
79 var mTest = types.monad;
80
81 jsv.assert(jsv.forall(m, mTest.iface));
82 });
83
84 it('is Foldable', function() {
85 var fTest = types.foldable;
86
87 jsv.assert(jsv.forall(m, fTest.iface));
88 jsv.assert(jsv.forall('nat -> nat -> nat', 'nat', 'nat', function(f, n1, n2) {
89 return Maybe.Just(n1).reduce(R.uncurryN(2, f), n2) === f(n2)(n1);
90 }));
91 jsv.assert(jsv.forall('nat -> nat -> nat', 'nat', function(f, n) {
92 return Maybe.Nothing().reduce(R.uncurryN(2, f), n) === n;
93 }));
94 });
95});
96
97describe('Maybe usage', function() {
98
99 describe('checking for Just | Nothing', function() {
100 it('should allow the user to check if the instance is a Nothing', function() {
101 assert.equal(true, Maybe(null).isNothing);
102 assert.equal(false, Maybe(42).isNothing);
103 });
104
105 it('should allow the user to check if the instance is a Just', function() {
106 assert.equal(true, Maybe(42).isJust);
107 assert.equal(false, Maybe(null).isJust);
108 });
109
110 it('can check the type statically', function() {
111 var nada = Maybe.Nothing();
112 var just1 = Maybe.Just(1);
113 assert.equal(Maybe.isJust(nada), false);
114 assert.equal(Maybe.isNothing(nada), true);
115 assert.equal(Maybe.isJust(just1), true);
116 assert.equal(Maybe.isNothing(just1), false);
117 });
118 });
119
120 describe('#getOrElse', function() {
121
122 it('should return the contained value for if the instance is a Just', function() {
123 assert.equal(42, Maybe(42).getOrElse(24));
124 });
125
126 it('should return the input value if the instance is a Nothing', function() {
127 assert.equal(24, Maybe(null).getOrElse(24));
128 });
129
130 });
131
132 describe('#toString', function() {
133
134 it('returns the string representation of a Just', function() {
135 assert.strictEqual(Maybe.Just([1, 2, 3]).toString(),
136 'Maybe.Just([1, 2, 3])');
137 });
138
139 it('returns the string representation of a Nothing', function() {
140 assert.strictEqual(Maybe.Nothing().toString(),
141 'Maybe.Nothing()');
142 });
143
144 });
145
146 describe('#maybe', function() {
147
148 it('returns the result of applying the value of a Just to the second argument', function() {
149 jsv.assert(jsv.forall('nat -> nat', 'nat', 'nat', function(f, n1, n2) {
150 return R.equals(Maybe.maybe(n2, f, Maybe.Just(n1)), f(n1));
151 }));
152 });
153
154 it('returns the first argument for a Nothing', function() {
155 jsv.assert(jsv.forall('nat -> nat', 'nat', 'nat', function(f, n) {
156 return R.equals(Maybe.maybe(n, f, Maybe.Nothing()), n);
157 }));
158 });
159 });
160});