1 | var assert = require('assert');
|
2 | var types = require('./types');
|
3 |
|
4 | var IO = require('..').IO;
|
5 |
|
6 | function add(a) {
|
7 | return function(b) { return a + b; };
|
8 | }
|
9 |
|
10 | function always(x) {
|
11 | return function() { return x; };
|
12 | }
|
13 |
|
14 | function mult(a) {
|
15 | return function(b) { return a * b; };
|
16 | }
|
17 |
|
18 | function identity(x) { return x; }
|
19 |
|
20 | describe('IO', function() {
|
21 | var logger = (function() {
|
22 | var results = [];
|
23 | return {
|
24 | log: function(str) {results.push(str);},
|
25 | clear: function() {results = [];},
|
26 | report: function() {return results.join(' ~ ');}
|
27 | };
|
28 | }());
|
29 | var f1 = function() { logger.log('IO 1'); return '1 '; };
|
30 | var f2 = function(x) { logger.log('IO 2'); return x + '2 '; };
|
31 | var f3 = function(x) { logger.log('IO 3'); return x + '3 '; };
|
32 | var i1 = IO(f1);
|
33 | var i2 = IO(f2);
|
34 |
|
35 | beforeEach(function() {
|
36 | logger.clear();
|
37 | });
|
38 |
|
39 | it('is a Functor', function() {
|
40 | var fTest = types.functor;
|
41 | assert.equal(true, fTest.iface(i1));
|
42 | assert.equal(true, fTest.id(i1));
|
43 | assert.equal(logger.report(), 'IO 1 ~ IO 1');
|
44 | logger.clear();
|
45 | assert.equal(true, fTest.compose(i1, f2, f3));
|
46 | assert.equal(logger.report(), 'IO 1 ~ IO 3 ~ IO 2 ~ IO 1 ~ IO 3 ~ IO 2');
|
47 | });
|
48 |
|
49 | it('is an Apply', function() {
|
50 | var aTest = types.apply;
|
51 | var a = IO(function() { return add(1); });
|
52 | var b = IO(function() { return always(2); });
|
53 | var c = IO(always(4));
|
54 |
|
55 | assert.equal(true, aTest.iface(i1));
|
56 | assert.equal(true, aTest.compose(a, b, c));
|
57 | });
|
58 |
|
59 | it('is an Applicative', function() {
|
60 | var aTest = types.applicative;
|
61 |
|
62 | assert.equal(true, aTest.iface(i1));
|
63 | assert.equal(true, aTest.id(IO, i2));
|
64 | assert.equal(logger.report(), 'IO 2 ~ IO 2');
|
65 | assert.equal(true, aTest.homomorphic(i1, add(3), 46));
|
66 | assert.equal(true, aTest.interchange(
|
67 | IO(function() { return mult(20); }),
|
68 | IO(function() { return mult(0.5); }),
|
69 | 73
|
70 | ));
|
71 | });
|
72 |
|
73 | it('is a Chain', function() {
|
74 | var cTest = types.chain;
|
75 | var c = IO(function() {
|
76 | return IO(function() {
|
77 | return IO(function() {
|
78 | return 3;
|
79 | });
|
80 | });
|
81 | });
|
82 | assert.equal(true, cTest.iface(i1));
|
83 | assert.equal(true, cTest.associative(c, identity, identity));
|
84 | });
|
85 |
|
86 | it('is a Monad', function() {
|
87 | var mTest = types.monad;
|
88 | assert.equal(true, mTest.iface(i1));
|
89 | });
|
90 |
|
91 | describe('#toString', function() {
|
92 |
|
93 | it('returns the string representation of an IO', function() {
|
94 | assert.strictEqual(IO(function() {}).toString(),
|
95 | 'IO(function () {})');
|
96 | });
|
97 |
|
98 | });
|
99 |
|
100 | });
|