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 ProductOperator
17 =begin
18 <product-expression> ::=
19 <atomic-expression> { <product-operation> } ;
20
21 <product-operation> ::=
22 <number-selector>
23 | <label-selector>
24 | <named-tuple-modifier>
25 ;
26 =end
27
28 class NumberSelectorTest < Minitest::Test
29 =begin
30 <number-selector> ::= "$" INT ;
31 =end
32 def setup
33 @interp = Api.setup_interpreter
34 end
35
36
37 def test_tuple
38 interp = Api.eval_decls @interp, "val t = (@Apple, 300)"
39
40 value = Api.eval_expr interp, "t$1"
41 assert_instance_of VCA::Symbol, value
42 assert_equal :Apple, value.val
43
44 value = Api.eval_expr interp, "t$2"
45 assert_instance_of VCAN::Int, value
46 assert_equal 300, value.val
47 end
48
49
50 def test_named_tuple
51 interp = Api.eval_decls @interp, "val n = (name:@Apple price:300)"
52
53 value = Api.eval_expr interp, "n$1"
54 assert_instance_of VCA::Symbol, value
55 assert_equal :Apple, value.val
56
57 value = Api.eval_expr interp, "n$2"
58 assert_instance_of VCAN::Int, value
59 assert_equal 300, value.val
60 end
61
62
63 def test_left_hand_should_be_a_product_type
64 assert_raises(X::TypeError) do
65 Api.eval_expr @interp, "@foo$1"
66 end
67 end
68
69
70 def test_selection_number_should_be_in_the_range_of_1_to_arity
71 interp_t = Api.eval_decls @interp, "val t = (@Apple, 300)"
72 interp_n = Api.eval_decls @interp, "val n = (name:@Apple price:300)"
73
74 assert_raises(X::SelectionError) do
75 Api.eval_expr interp_t, "t$0"
76 end
77
78 assert_raises(X::SelectionError) do
79 Api.eval_expr interp_t, "t$3"
80 end
81
82 assert_raises(X::SelectionError) do
83 Api.eval_expr interp_n, "n$0"
84 end
85
86 assert_raises(X::SelectionError) do
87 Api.eval_expr interp_n, "n$3"
88 end
89 end
90 end
91
92
93
94 class LabelSelectorTest < Minitest::Test
95 =begin
96 <label-selector> ::= SEL ;
97 =end
98 def setup
99 @interp = Api.setup_interpreter
100 end
101
102
103 def test_named_tuple
104 interp = Api.eval_decls @interp, "val t = (name:@Apple price:300)"
105
106 value_1 = Api.eval_expr interp, "t$name"
107 assert_instance_of VCA::Symbol, value_1
108 assert_equal :Apple, value_1.val
109
110 value_2 = Api.eval_expr interp, "t$price"
111 assert_instance_of VCAN::Int, value_2
112 assert_equal 300, value_2.val
113 end
114
115
116 def test_left_hand_should_be_a_named_tuple_type
117 assert_raises(X::TypeError) do
118 Api.eval_expr @interp, "@foo$name"
119 end
120 end
121
122
123 def test_selection_label_should_be_known
124 interp = Api.eval_decls @interp, "val n = (name:@Apple price:300)"
125
126 assert_raises(X::SelectionError) do
127 Api.eval_expr interp, "n$foo"
128 end
129 end
130 end
131
132
133
134 class NamedTupleModifierTest < Minitest::Test
135 =begin
136 <named-tuple-modifier> ::= "$(" <named-field> { <named-field> } ")" ;
137
138 /* <named-field> ::= ... ; See NamedTupleExpressionTest */
139 =end
140 def setup
141 @interp = Api.setup_interpreter
142 end
143
144
145 def test_named_tuple
146 interp = Api.eval_decls @interp, "val t = (name:@Apple price:300)"
147
148 n1_value = Api.eval_expr interp, "t$(name:@Banana)"
149 assert_instance_of VCP::Named, n1_value
150 assert_equal 2, n1_value.arity
151 assert_instance_of VCA::Symbol, n1_value.values[0]
152 assert_equal :Banana, n1_value.values[0].val
153 assert_instance_of VCAN::Int, n1_value.values[1]
154 assert_equal 300, n1_value.values[1].val
155
156 n1_value = Api.eval_expr interp, "t$(price:250)"
157 assert_instance_of VCP::Named, n1_value
158 assert_equal 2, n1_value.arity
159 assert_instance_of VCA::Symbol, n1_value.values[0]
160 assert_equal :Apple, n1_value.values[0].val
161 assert_instance_of VCAN::Int, n1_value.values[1]
162 assert_equal 250, n1_value.values[1].val
163
164 n1_value = Api.eval_expr interp, "t$(name:@Banana price:250)"
165 assert_instance_of VCP::Named, n1_value
166 assert_equal 2, n1_value.arity
167 assert_instance_of VCA::Symbol, n1_value.values[0]
168 assert_equal :Banana, n1_value.values[0].val
169 assert_instance_of VCAN::Int, n1_value.values[1]
170 assert_equal 250, n1_value.values[1].val
171 end
172
173
174 def test_left_hand_should_be_a_named_tuple_type
175 assert_raises(X::TypeError) do
176 Api.eval_expr @interp, "@foo$(name:@Banana)"
177 end
178 end
179
180
181 def test_selection_label_should_be_known
182 interp = Api.eval_decls @interp, "val n = (name:@Apple price:300)"
183
184 assert_raises(X::SelectionError) do
185 Api.eval_expr interp, "n$(foo:@Bar)"
186 end
187 end
188
189
190 def test_modifier_labels_should_not_be_duplicated
191 interp = Api.eval_decls @interp, "val t = (name:@Apple price:300)"
192
193 assert_raises(X::SyntaxError) do
194 Api.eval_expr interp, "t$(name:@Banana name:@Orange)"
195 end
196 end
197 end
198
199 end # Umu::Test::Grammar::CoreLanguage::Expression::ProductOperator
200
201 end # Umu::Test::Grammar::CoreLanguage::Expression
202
203 end # Umu::Test::Grammar::CoreLanguage
204
205 end # Umu::Test::Grammar
206
207 end # Umu::Test
208
209 end # Umu