1 | assert = require('assert')
|
2 |
|
3 |
|
4 |
|
5 | {exprEqual, compiler} = require('./kit/core')
|
6 |
|
7 | describe '`throw` statements compiler', ->
|
8 | it 'should leave unchanged if it has pure argument', ->
|
9 | exprEqual(
|
10 | ->
|
11 | throw new Error("error")
|
12 | ->
|
13 | throw new Error("error"))
|
14 | exprEqual(
|
15 | ->
|
16 | eff(1)
|
17 | throw new Error("error")
|
18 | ->
|
19 | M(eff(1)).mbind(-> M.raise(new Error("error"))))
|
20 | it 'should convert `throw` with effectful argument into monadish value', ->
|
21 | exprEqual(
|
22 | ->
|
23 | throw eff(1)
|
24 | ->
|
25 | M(eff(1)).mbind(M.raise))
|
26 |
|
27 | it 'should ignore actions after monadish throw', ->
|
28 | exprEqual(
|
29 | ->
|
30 | throw eff(1)
|
31 | eff(2)
|
32 | """
|
33 | function () {
|
34 | return M(eff(1)).mbind(M.raise)
|
35 | .mbind(function () {
|
36 | return eff(2);
|
37 | });
|
38 | }
|
39 | """)
|
40 |
|
41 | describe '`try` statements', ->
|
42 | context 'when all blocks are pure', ->
|
43 | it 'should be left unchanged', ->
|
44 | exprEqual(
|
45 | ->
|
46 | try
|
47 | console.log("1")
|
48 | ->
|
49 | try
|
50 | console.log("1"))
|
51 | exprEqual(
|
52 | ->
|
53 | try
|
54 | console.log("1")
|
55 | catch e
|
56 | console.log("2")
|
57 | ->
|
58 | try
|
59 | console.log("1")
|
60 | catch e
|
61 | console.log("2"))
|
62 | exprEqual(
|
63 | ->
|
64 | try
|
65 | console.log("1")
|
66 | catch e
|
67 | console.log("2")
|
68 | finally
|
69 | console.log("3")
|
70 | ->
|
71 | try
|
72 | console.log("1")
|
73 | catch e
|
74 | console.log("2")
|
75 | finally
|
76 | console.log("3"))
|
77 | context "when inner block has effects", ->
|
78 | context "when inner block has some pure prefix", ->
|
79 | it 'should wrap whole `try` block', ->
|
80 | exprEqual(
|
81 | """function () {
|
82 | var e, error;
|
83 | try {
|
84 | console.log('1');
|
85 | eff(1);
|
86 | } catch (error) {
|
87 | e = error;
|
88 | console.log('2');
|
89 | }
|
90 | }"""
|
91 | """function () {
|
92 | var e, error;
|
93 | return M.coerce(function () {
|
94 | console.log('1');
|
95 | return eff(1);
|
96 | }).mhandle(function (error) {
|
97 | e = error;
|
98 | console.log('2');
|
99 | });
|
100 | }""")
|
101 | context "when `catch` block has no effects", ->
|
102 | it 'should be monadish block and `mhandle`', ->
|
103 |
|
104 | exprEqual(
|
105 | """
|
106 | function() {
|
107 | try {
|
108 | eff(1);
|
109 | } catch(e) {
|
110 | console.log(e);
|
111 | }
|
112 | }
|
113 | """
|
114 | """
|
115 | function() {
|
116 | return M.coerce(function(){ return eff(1); })
|
117 | .mhandle(function(e) { console.log(e); });
|
118 | }""")
|
119 | context "when `finally` block has no effects", ->
|
120 | it 'should be monadish block with `mhandle` and `mfinally`', ->
|
121 | exprEqual(
|
122 | """
|
123 | function() {
|
124 | try {
|
125 | eff(1);
|
126 | } catch(e) {
|
127 | console.log(e);
|
128 | } finally {
|
129 | console.log("fin");
|
130 | }
|
131 | }
|
132 | """
|
133 | """
|
134 | function() {
|
135 | return M.coerce(function() { return eff(1); })
|
136 | .mhandle(function(e) { console.log(e); })
|
137 | .mfinally(function() { console.log("fin"); });
|
138 | }""")
|
139 | context 'when catch has effects', ->
|
140 | it 'should be converted into `mhandle` with effects', ->
|
141 | exprEqual(
|
142 | """
|
143 | function() {
|
144 | try {
|
145 | eff(1);
|
146 | } catch(e) {
|
147 | console.log(e,1);
|
148 | eff(2);
|
149 | console.log(e,2);
|
150 | }
|
151 | }
|
152 | """
|
153 | """
|
154 | function() {
|
155 | return M.coerce(function() { return eff(1); })
|
156 | .mhandle(function(e) {
|
157 | console.log(e,1);
|
158 | return M(eff(2))
|
159 | .mapply(function() {
|
160 | console.log(e,2);
|
161 | });
|
162 | });
|
163 | }""")
|
164 | context 'when finally has effects', ->
|
165 | it 'should be converted into `mfinally`', ->
|
166 | exprEqual(
|
167 | """
|
168 | function() {
|
169 | try {
|
170 | eff(1);
|
171 | } finally {
|
172 | console.log(1);
|
173 | eff(2);
|
174 | console.log(2);
|
175 | }
|
176 | }
|
177 | """
|
178 | """
|
179 | function() {
|
180 | return M.coerce(function() { return eff(1); })
|
181 | .mfinally(function() {
|
182 | console.log(1);
|
183 | return M(eff(2)).mapply(function() {
|
184 | console.log(2);
|
185 | });
|
186 | });
|
187 | }""")
|
188 | context 'when there is finally block without effects', ->
|
189 | it 'should be converted into monadish block and `mfinally`', ->
|
190 | exprEqual(
|
191 | """
|
192 | function() {
|
193 | try {
|
194 | eff(1);
|
195 | } finally {
|
196 | console.log("fin");
|
197 | }
|
198 | }
|
199 | """
|
200 | """
|
201 | function() {
|
202 | return M.coerce(function() { return eff(1); })
|
203 | .mfinally(function() { console.log("fin"); });
|
204 | }""")
|