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