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 Pattern
15
16 class ListTest < Minitest::Test
17 =begin
18 <list-pattern> ::=
19 "[" "]"
20 | "["
21 <variable-pattern> { "," <variable-pattern> }
22 [ "|" <variable-pattern> ]
23 "]"
24 ;
25 =end
26 def setup
27 @interp = Api.setup_interpreter
28 end
29
30
31 def test_value_empty
32 assert (
33 Api.eval_decls @interp, <<-EOS
34 val [] = []
35 EOS
36 )
37 end
38
39
40 def test_should_not_be_matched_list_to_empty_pattern_in_declaration
41 assert_raises(X::TypeError) do
42 Api.eval_decls @interp, <<-EOS
43 val [] = [3]
44 EOS
45 end
46 end
47
48
49 def test_value_singleton
50 interp = Api.eval_decls @interp, <<-EOS
51 val [x] = [3]
52 EOS
53
54 value = Api.eval_expr interp, "x"
55 assert_instance_of VCAN::Int, value
56 assert_equal 3, value.val
57 end
58
59
60 def test_value
61 interp = Api.eval_decls @interp, <<-EOS
62 val [x, y] = [3, 4]
63 EOS
64
65 value = Api.eval_expr interp, "x"
66 assert_instance_of VCAN::Int, value
67 assert_equal 3, value.val
68
69 value = Api.eval_expr interp, "y"
70 assert_instance_of VCAN::Int, value
71 assert_equal 4, value.val
72 end
73
74
75 def test_value_with_last_1
76 interp = Api.eval_decls @interp, <<-EOS
77 val [x|xs] = [3]
78 EOS
79
80 value = Api.eval_expr interp, "x"
81 assert_instance_of VCAN::Int, value
82 assert_equal 3, value.val
83
84 value = Api.eval_expr interp, "xs"
85 assert_instance_of VCM::List::Nil, value
86 end
87
88
89 def test_value_with_last_2
90 interp = Api.eval_decls @interp, <<-EOS
91 val [x|xs] = [3, 4]
92 EOS
93
94 value = Api.eval_expr interp, "x"
95 assert_instance_of VCAN::Int, value
96 assert_equal 3, value.val
97
98 value = Api.eval_expr interp, "xs"
99 assert_instance_of VCM::List::Cons, value
100 assert_instance_of VCAN::Int, value.head
101 assert_equal 4, value.head.val
102 assert_instance_of VCM::List::Nil, value.tail
103 end
104
105
106 def test_should_not_be_matched_list_to_shorter_pattern_in_declaration
107 assert_raises(X::TypeError) do
108 Api.eval_decls @interp, <<-EOS
109 val [x] = [3, 4]
110 EOS
111 end
112 end
113
114
115 def test_should_not_be_matched_list_to_longer_pattern_in_declaration_1
116 assert_raises(X::EmptyError) do
117 Api.eval_decls @interp, <<-EOS
118 val [x, y, z] = [3, 4]
119 EOS
120 end
121 end
122
123
124 def test_should_not_be_matched_list_to_longer_pattern_in_declaration_2
125 assert_raises(X::EmptyError) do
126 Api.eval_decls @interp, <<-EOS
127 val [x, y|xs] = [3]
128 EOS
129 end
130 end
131
132
133 def test_value_type
134 interp = Api.eval_decls @interp, <<-EOS
135 val [x : Int|xs] = [3, 4]
136 EOS
137
138 value = Api.eval_expr interp, "x"
139 assert_instance_of VCAN::Int, value
140 assert_equal 3, value.val
141
142 value = Api.eval_expr interp, "xs"
143 assert_instance_of VCM::List::Cons, value
144 end
145
146
147 def test_should_be_kind_of_specified_type_in_declaration
148 assert_raises(X::TypeError) do
149 Api.eval_decls @interp, <<-EOS
150 val [x : String|xs] = [3, 4]
151 EOS
152 end
153 end
154
155
156 def test_should_not_specify_type_to_tail_pattern_in_declaration
157 assert_raises(X::SyntaxError) do
158 Api.eval_decls @interp, <<-EOS
159 val [x|xs : List] = [3, 4]
160 EOS
161 end
162 end
163
164
165 def test_lambda
166 value = Api.eval_expr @interp, <<-EOS
167 { [x, y] -> x + y } [3, 4]
168 EOS
169 assert_instance_of VCAN::Int, value
170 assert_equal 7, value.val
171 end
172
173
174 def test_lambda_empty
175 value = Api.eval_expr @interp, <<-EOS
176 { [] -> 3 } []
177 EOS
178 assert_instance_of VCAN::Int, value
179 assert_equal 3, value.val
180 end
181
182
183 def test_should_not_be_matched_list_to_empty_pattern_in_lambda
184 assert_raises(X::TypeError) do
185 Api.eval_expr @interp, <<-EOS
186 { [] -> 4 } [3]
187 EOS
188 end
189 end
190
191
192 def test_lambda_singleton
193 value = Api.eval_expr @interp, <<-EOS
194 { [x] -> x + 4 } [3]
195 EOS
196 assert_instance_of VCAN::Int, value
197 assert_equal 7, value.val
198 end
199
200
201 def test_lambda_with_last_1
202 value = Api.eval_expr @interp, <<-EOS
203 { [x|xs] -> (x, xs) } [3]
204 EOS
205 assert_instance_of VCP::Tuple, value
206 assert_equal 2, value.arity
207
208 head_value, tail_value = value.values
209 assert_instance_of VCAN::Int, head_value
210 assert_equal 3, head_value.val
211 assert_instance_of VCM::List::Nil, tail_value
212 end
213
214
215 def test_lambda_with_last_2
216 value = Api.eval_expr @interp, <<-EOS
217 { [x|xs] -> (x, xs) } [3, 4]
218 EOS
219 assert_instance_of VCP::Tuple, value
220 assert_equal 2, value.arity
221
222 head_value, tail_value = value.values
223
224 assert_instance_of VCAN::Int, head_value
225 assert_equal 3, head_value.val
226
227 assert_instance_of VCM::List::Cons, tail_value
228 assert_instance_of VCAN::Int, tail_value.head
229 assert_equal 4, tail_value.head.val
230 assert_instance_of VCM::List::Nil, tail_value.tail
231 end
232
233
234 def test_should_not_be_matched_list_to_shorter_pattern_in_lambda
235 assert_raises(X::TypeError) do
236 Api.eval_expr @interp, <<-EOS
237 { [x] -> x } [3, 4]
238 EOS
239 end
240 end
241
242
243 def test_should_not_be_matched_list_to_longer_pattern_in_lambda_1
244 assert_raises(X::EmptyError) do
245 Api.eval_expr @interp, <<-EOS
246 { [x, y, z] -> x } [3, 4]
247 EOS
248 end
249 end
250
251
252 def test_should_not_be_matched_list_to_longer_pattern_in_lambda_2
253 assert_raises(X::EmptyError) do
254 Api.eval_expr @interp, <<-EOS
255 { [x, y|xs] -> (x, y, xs) } [3]
256 EOS
257 end
258 end
259
260
261 def test_lambda_type
262 value = Api.eval_expr @interp, <<-EOS
263 { [x : Int|xs] -> (x, xs) } [3, 4]
264 EOS
265 assert_instance_of VCP::Tuple, value
266 assert_equal 2, value.arity
267
268 head_value, tail_value = value.values
269 assert_instance_of VCAN::Int, head_value
270 assert_equal 3, head_value.val
271 assert_instance_of VCM::List::Cons, tail_value
272 end
273
274
275 def test_should_be_kind_of_specified_type_in_lambda
276 assert_raises(X::TypeError) do
277 Api.eval_expr @interp, <<-EOS
278 { [x : String|xs] -> (x, xs) } [3, 4]
279 EOS
280 end
281 end
282
283
284 def test_should_not_specify_type_to_tail_pattern_in_lambda
285 assert_raises(X::SyntaxError) do
286 Api.eval_expr @interp, <<-EOS
287 { [x|xs : List] -> (x, xs) } [3, 4]
288 EOS
289 end
290 end
291 end
292
293 end # Umu::Test::Grammar::CoreLanguage::Pattern
294
295 end # Umu::Test::Grammar::CoreLanguage
296
297 end # Umu::Test::Grammar
298
299 end # Umu::Test
300
301 end # Umu