1 # frozen_string_literal: true
2
3 require "test_helper"
4
5
6 module Umu
7
8 module Test
9
10 module Grammar
11
12 module CoreLanguage
13
14 module Expression
15
16 module Atomic
17
18 module List
19 =begin
20 <square-braket-expression> ::=
21 <list-expression>
22 | <list-interval>
23 | <list-comprehension>
24 ;
25 =end
26
27 class ExpressionTest < Minitest::Test
28 =begin
29 <list-expression> ::=
30 "[" "]"
31 | "[" <expression> { "," <expression> } [ "|" <expression> ] "]"
32 ;
33 =end
34
35 def setup
36 @interp = Api.setup_interpreter
37 end
38
39
40 def test_empty_list
41 value = Api.eval_expr @interp, "[]"
42 assert_instance_of VCM::List::Nil, value
43 end
44
45
46 def test_singleton_list
47 value = Api.eval_expr @interp, "[3]"
48 assert_instance_of VCM::List::Cons, value
49 assert_instance_of VCAN::Int, value.head
50 assert_equal 3, value.head.val
51 assert_instance_of VCM::List::Nil, value.tail
52 end
53
54
55 def test_some_list
56 value = Api.eval_expr @interp, "[3, 4]"
57 assert_instance_of VCM::List::Cons, value
58 assert_instance_of VCAN::Int, value.head
59 assert_equal 3, value.head.val
60 assert_instance_of VCM::List::Cons, value.tail
61
62 tail_value = value.tail
63 assert_instance_of VCAN::Int, tail_value.head
64 assert_equal 4, tail_value.head.val
65 assert_instance_of VCM::List::Nil, tail_value.tail
66 end
67
68
69 def test_list_with_last_expression
70 value = Api.eval_expr @interp, "[3 | []]"
71 assert_instance_of VCM::List::Cons, value
72 assert_instance_of VCAN::Int, value.head
73 assert_equal 3, value.head.val
74 assert_instance_of VCM::List::Nil, value.tail
75
76 value = Api.eval_expr @interp, "[3 | [4]]"
77 assert_instance_of VCM::List::Cons, value
78 assert_instance_of VCAN::Int, value.head
79 assert_equal 3, value.head.val
80 assert_instance_of VCM::List::Cons, value.tail
81
82 tail_value = value.tail
83 assert_instance_of VCAN::Int, tail_value.head
84 assert_equal 4, tail_value.head.val
85 assert_instance_of VCM::List::Nil, tail_value.tail
86 end
87
88
89 def test_last_value_should_be_a_list_type
90 assert_raises(X::TypeError) do
91 Api.eval_expr @interp, "[3 | 4]"
92 end
93 end
94 end
95
96
97
98 class IntervalTest < Minitest::Test
99 =begin
100 <list-interval> ::=
101 "[" <expression> { "," <expression> } ".." <expression> "]" ;
102 =end
103
104 def setup
105 @interp = Api.setup_interpreter
106 end
107
108
109 def test_list_interval
110 value = Api.eval_expr @interp, "[3 .. 10]"
111 assert_instance_of VCM::Interval, value
112 assert_instance_of VCAN::Int, value.current_value
113 assert_equal 3, value.current_value.val
114 assert_instance_of VCAN::Int, value.step_value
115 assert_equal 1, value.step_value.val
116 assert_instance_of VCAN::Int, value.stop_value
117 assert_equal 10, value.stop_value.val
118
119 list_value = Api.eval_expr @interp, "[3 .. 10].to-list"
120 assert_instance_of VCM::List::Cons, list_value
121
122 expected_list = (3 .. 10).to_a
123 assert_equal expected_list.count, list_value.count
124
125 expected_list.zip(list_value).each do |expected, actual_value|
126 assert_instance_of VCAN::Int, actual_value
127 assert_equal expected, actual_value.val
128 end
129 end
130
131
132 def test_list_interval_with_second_expression
133 value = Api.eval_expr @interp, "[3, 5 .. 10]"
134 assert_instance_of VCM::Interval, value
135 assert_instance_of VCAN::Int, value.current_value
136 assert_equal 3, value.current_value.val
137 assert_instance_of VCAN::Int, value.step_value
138 assert_equal 2, value.step_value.val
139 assert_instance_of VCAN::Int, value.stop_value
140 assert_equal 10, value.stop_value.val
141
142 list_value = Api.eval_expr @interp, "[3, 5 .. 10].to-list"
143 assert_instance_of VCM::List::Cons, list_value
144
145 expected_list = [3, 5, 7, 9]
146 assert_equal expected_list.count, list_value.count
147
148 expected_list.zip(list_value).each do |expected, actual_value|
149 assert_instance_of VCAN::Int, actual_value
150 assert_equal expected, actual_value.val
151 end
152 end
153
154
155 def test_1st_value_should_be_a_integer_type
156 assert_raises(X::TypeError) do
157 Api.eval_expr @interp, "[3.0 .. 10]"
158 end
159 end
160
161
162 def test_2nd_value_should_be_a_integer_type
163 assert_raises(X::TypeError) do
164 Api.eval_expr @interp, "[3, 4.0 .. 10]"
165 end
166 end
167
168
169 def test_last_value_should_be_a_integer_type
170 assert_raises(X::TypeError) do
171 Api.eval_expr @interp, "[3 .. 10.0]"
172 end
173 end
174
175
176 def test_2nd_value_should_be_between_1st_and_last_value_1
177 assert_raises(X::ValueError) do
178 Api.eval_expr @interp, "[3, 11 .. 10]"
179 end
180 end
181
182
183 def test_2nd_value_should_be_between_1st_and_last_value_2
184 assert_raises(X::ValueError) do
185 Api.eval_expr @interp, "[10, 11 .. 3]"
186 end
187 end
188
189
190 def test_2nd_value_should_be_not_equal_to_1st_value_1
191 assert_raises(X::ValueError) do
192 Api.eval_expr @interp, "[3, 3 .. 10]"
193 end
194 end
195
196
197 def test_2nd_value_should_be_not_equal_to_1st_value_2
198 assert_raises(X::ValueError) do
199 Api.eval_expr @interp, "&[3, 3 ..]"
200 end
201 end
202 end
203
204
205
206 class ComprehensionTest < Minitest::Test
207 =begin
208 <list-comprehension> ::=
209 | "[" "|" <expression> { "," <expression> } "|"
210 { <qualifier> }
211 "]"
212 | "[" "|" <named-field> <<named-field> { <named-field> } "|"
213 { <qualifier> }
214 "]"
215 ;
216
217 <qualifier> ::= <generator> | <guard> ;
218 <generator> ::= VAL <pattern> "<-" <expression> :
219 <guard> ::= IF <expression> ;
220
221 /* <named-field> ::= ... ; See NamedTupleTest */
222 =end
223
224 def setup
225 @interp = Api.setup_interpreter
226 end
227
228
229 def test_singleton_comprehension
230 value = Api.eval_expr @interp, "[|3|]"
231 assert_instance_of VCM::List::Cons, value
232 assert_instance_of VCAN::Int, value.head
233 assert_equal 3, value.head.val
234 assert_instance_of VCM::List::Nil, value.tail
235 end
236
237
238 def test_comprehension_with_generator
239 list_value = Api.eval_expr @interp, <<-EOS
240 [|x| val x <- [1..5]]
241 EOS
242 assert_instance_of VCM::List::Cons, list_value
243
244 expected_list = (1 .. 5).to_a
245 assert_equal expected_list.count, list_value.count
246
247 expected_list.zip(list_value).each do |expected, actual_value|
248 assert_instance_of VCAN::Int, actual_value
249 assert_equal expected, actual_value.val
250 end
251 end
252
253
254 def test_comprehension_with_guard
255 list_value = Api.eval_expr @interp, <<-EOS
256 [|x| val x <- [1..5] if odd? x]
257 EOS
258 assert_instance_of VCM::List::Cons, list_value
259
260 expected_list = [1, 3, 5]
261 assert_equal expected_list.count, list_value.count
262
263 expected_list.zip(list_value).each do |expected, actual_value|
264 assert_instance_of VCAN::Int, actual_value
265 assert_equal expected, actual_value.val
266 end
267 end
268
269
270 def test_comprehension_returned_tuple
271 list_value = Api.eval_expr @interp, <<-EOS
272 [|k, v| val k <- [@Apple, @Banana] val v <- [1, 2, 3]]
273 EOS
274 assert_instance_of VCM::List::Cons, list_value
275
276 expected_list = [
277 [:Apple, 1], [:Apple, 2], [:Apple, 3],
278 [:Banana, 1], [:Banana, 2], [:Banana, 3]
279 ]
280 assert_equal expected_list.count, list_value.count
281
282 expected_list.zip(list_value).each do |expected, actual_value|
283 assert_instance_of VCP::Tuple, actual_value
284 assert_equal 2, actual_value.arity
285
286 assert_instance_of VCA::Symbol, actual_value.values[0]
287 assert_equal expected[0], actual_value.values[0].val
288
289 assert_instance_of VCAN::Int, actual_value.values[1]
290 assert_equal expected[1], actual_value.values[1].val
291 end
292 end
293
294
295 def test_comprehension_returned_named_tuple
296 list_value = Api.eval_expr @interp, <<-EOS
297 [|key:k value:v| val k <- [@Apple, @Banana] val v <- [1, 2, 3]]
298 EOS
299 assert_instance_of VCM::List::Cons, list_value
300
301 expected_list = [
302 [:Apple, 1], [:Apple, 2], [:Apple, 3],
303 [:Banana, 1], [:Banana, 2], [:Banana, 3]
304 ]
305 assert_equal expected_list.count, list_value.count
306
307 expected_list.zip(list_value).each do |expected, actual_value|
308 assert_instance_of VCP::Named, actual_value
309 assert_equal 2, actual_value.arity
310
311 assert_instance_of VCA::Symbol, actual_value.values[0]
312 assert_equal expected[0], actual_value.values[0].val
313
314 assert_instance_of VCAN::Int, actual_value.values[1]
315 assert_equal expected[1], actual_value.values[1].val
316 end
317 end
318 end
319
320 end # Umu::Test::Grammar::CoreLanguage::Expression::Atomic::SquareBracket
321
322 end # Umu::Test::Grammar::CoreLanguage::Expression::Atomic
323
324 end # Umu::Test::Grammar::CoreLanguage::Expression
325
326 end # Umu::Test::Grammar::CoreLanguage
327
328 end # Umu::Test::Grammar
329
330 end # Umu::Test
331
332 end # Umu