UNPKG

4.45 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 Tuple = require('..').Tuple;
8var constructor = Tuple('', '').constructor;
9
10var TupleGen = R.curry(function(a, b, n) {
11 return Tuple(a.generator(n), b.generator(n));
12});
13
14var TupleShow = R.curry(function(a, m) {
15 return 'Tuple(' + a.show(m[0]) + ', ' + a.show(m[1]) + ')';
16});
17
18var TupleShrink = R.curry(function(a, m) {
19 return [Tuple(a.shrink(m[0]), a.shrink(m[1]))];
20});
21
22var TupleArb = function(a, b) {
23 return {
24 generator: jsv.generator.bless(TupleGen(a, b)),
25 show: TupleShow(a),
26 shrink: jsv.shrink.bless(TupleShrink(a))
27 };
28};
29
30var stringArb = jsv.generator.bless({
31 generator: function() {
32 switch (jsv.random(0, 2)) {
33 case 0: return 'foo';
34 case 1: return 'bar';
35 case 2: return 'quux';
36 }
37 },
38 show: function(a) { return a; },
39 shrink: jsv.shrink.bless(function(m) { return [m.slice(1)]; })
40});
41
42function mult(a) {
43 return function(b) { return a * b; };
44}
45
46function add(a) {
47 return function(b) { return a + b; };
48}
49
50
51describe('Tuple', function() {
52 var m = TupleArb(stringArb, jsv.nat);
53
54 it('has an arbitrary', function() {
55 var arb = jsv.forall(m, function(m) {
56 return m instanceof constructor;
57 });
58 jsv.assert(arb);
59 });
60
61 it('is a Semigroup', function() {
62 var t = TupleArb(stringArb, stringArb);
63 var t1 = TupleArb(stringArb, stringArb);
64 var t2 = TupleArb(stringArb, stringArb);
65 var sTest = types.semigroup;
66
67 jsv.assert(jsv.forall(t, sTest.iface));
68 jsv.assert(jsv.forall(t, t1, t2, sTest.associative));
69 });
70
71 it('is a Functor', function() {
72 var fTest = types.functor;
73
74 jsv.assert(jsv.forall(m, fTest.iface));
75 jsv.assert(jsv.forall(m, fTest.id));
76 jsv.assert(jsv.forall(m, 'nat -> nat', 'nat -> nat', fTest.compose));
77 });
78
79 it('is an Apply', function() {
80 var aTest = types.apply;
81 var appA = Tuple('', mult(10));
82 var appU = Tuple('', add(7));
83 var appV = Tuple('', 10);
84
85 jsv.assert(jsv.forall(m, aTest.iface));
86 assert.equal(true, aTest.compose(appA, appU, appV));
87 });
88});
89
90describe('Tuple usage', function() {
91
92 describe('creation', function() {
93 it('should be curried', function() {
94 var tpl = Tuple('dr')(true);
95 assert.equal('dr', tpl[0]);
96 assert.equal(true, tpl[1]);
97 });
98 });
99
100 describe('element access', function() {
101 var tuple = Tuple('nacho', 'cheese');
102
103 it('should work with indexes', function() {
104 assert.equal('nacho', tuple[0]);
105 assert.equal('cheese', tuple[1]);
106 });
107
108 it('should return the value in the first position', function() {
109 assert.equal('nacho', Tuple.fst(tuple));
110 assert.equal('cheese', Tuple.snd(tuple));
111 });
112
113 it('should work with head', function() {
114 assert.equal('nacho', R.head(tuple));
115 });
116
117 it('should work with nth', function() {
118 assert.equal('cheese', R.nth(1, tuple));
119 });
120
121 it('should work with tail', function() {
122 assert.equal('cheese', R.tail(tuple));
123 });
124
125 it('should work with take', function() {
126 assert.equal('nacho', R.take(1, tuple)[0]);
127 }
128 );
129 it('should work with drop', function() {
130 assert.equal('cheese', R.drop(1, tuple)[0]);
131 });
132
133 it('will tell us the length', function() {
134 assert.equal(2, tuple.length);
135 });
136 });
137
138 describe('interface sanity check', function() {
139 var tuple = Tuple('mixed', 'nuts');
140
141 it('only maps the snd', function() {
142 var t = tuple.map(add('coco'));
143 assert.equal('mixed', t[0]);
144 assert.equal('coconuts', t[1]);
145 });
146
147 it('will combine two tuples', function() {
148 var t = tuple.concat(Tuple(' chocolate', ' bars'));
149 assert.equal('mixed chocolate', t[0]);
150 assert.equal('nuts bars', t[1]);
151 });
152
153 it('will apply and concat', function() {
154 var t = Tuple('Re', 'dough').map(add).ap(tuple);
155 assert.equal('Remixed', t[0]);
156 assert.equal('doughnuts', t[1]);
157 });
158 });
159
160 describe('#toString', function() {
161
162 it('returns the string representation of a Tuple', function() {
163 assert.strictEqual(Tuple('abc', [1, 2, 3]).toString(),
164 'Tuple("abc", [1, 2, 3])');
165 assert.strictEqual(Tuple('abc', Tuple(1, 2)).toString(),
166 'Tuple("abc", Tuple(1, 2))');
167 });
168
169 });
170
171});