1+ from s2e2 .error import ExpressionError
12from s2e2 .converter import Converter
23from s2e2 .token_type import TokenType
34from s2e2 .token import Token
45
6+ import pytest
7+
58
69class TestConverter :
710
@@ -29,7 +32,7 @@ def test_positive_one_binary_operator_result_value(self):
2932 assert actual_tokens == expected_tokens
3033
3134
32- def test_positive_two_binary_operators_result_value (self ):
35+ def test_positive_two_binary_operators_same_priority_result_value (self ):
3336 self .converter .add_operator ('+' , 1 )
3437 self .converter .add_operator ('-' , 1 )
3538
@@ -48,3 +51,269 @@ def test_positive_two_binary_operators_result_value(self):
4851 Token (TokenType .OPERATOR , '-' )]
4952
5053 assert actual_tokens == expected_tokens
54+
55+
56+ def test_positive_two_binary_operators_different_priority_result_value (self ):
57+ self .converter .add_operator ('+' , 1 )
58+ self .converter .add_operator ('*' , 2 )
59+
60+ input_tokens = [Token (TokenType .ATOM , 'A' ),
61+ Token (TokenType .OPERATOR , '+' ),
62+ Token (TokenType .ATOM , 'B' ),
63+ Token (TokenType .OPERATOR , '*' ),
64+ Token (TokenType .ATOM , 'C' )]
65+
66+ actual_tokens = self .converter .convert (input_tokens )
67+
68+ expected_tokens = [Token (TokenType .ATOM , 'A' ),
69+ Token (TokenType .ATOM , 'B' ),
70+ Token (TokenType .ATOM , 'C' ),
71+ Token (TokenType .OPERATOR , '*' ),
72+ Token (TokenType .OPERATOR , '+' )]
73+
74+ assert actual_tokens == expected_tokens
75+
76+
77+ def test_positive_unary_operator_and_binary_operator_result_value (self ):
78+ self .converter .add_operator ('!=' , 1 )
79+ self .converter .add_operator ('!' , 2 )
80+
81+ input_tokens = [Token (TokenType .OPERATOR , '!' ),
82+ Token (TokenType .ATOM , 'A' ),
83+ Token (TokenType .OPERATOR , '!=' ),
84+ Token (TokenType .ATOM , 'B' )]
85+
86+ actual_tokens = self .converter .convert (input_tokens )
87+
88+ expected_tokens = [Token (TokenType .ATOM , 'A' ),
89+ Token (TokenType .OPERATOR , '!' ),
90+ Token (TokenType .ATOM , 'B' ),
91+ Token (TokenType .OPERATOR , '!=' )]
92+
93+ assert actual_tokens == expected_tokens
94+
95+
96+ def test_positive_one_function_without_arguments_result_value (self ):
97+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
98+ Token (TokenType .LEFT_BRACKET , '(' ),
99+ Token (TokenType .RIGHT_BRACKET , ')' )]
100+
101+ actual_tokens = self .converter .convert (input_tokens )
102+
103+ expected_tokens = [Token (TokenType .FUNCTION , 'FUN' )]
104+
105+ assert actual_tokens == expected_tokens
106+
107+
108+ def test_positive_one_function_one_argument_result_value (self ):
109+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
110+ Token (TokenType .LEFT_BRACKET , '(' ),
111+ Token (TokenType .ATOM , 'Arg' ),
112+ Token (TokenType .RIGHT_BRACKET , ')' )]
113+
114+ actual_tokens = self .converter .convert (input_tokens )
115+
116+ expected_tokens = [Token (TokenType .ATOM , 'Arg' ),
117+ Token (TokenType .FUNCTION , 'FUN' )]
118+
119+ assert actual_tokens == expected_tokens
120+
121+
122+ def test_positive_one_function_three_arguments_result_value (self ):
123+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
124+ Token (TokenType .LEFT_BRACKET , '(' ),
125+ Token (TokenType .ATOM , 'Arg1' ),
126+ Token (TokenType .ATOM , 'Arg2' ),
127+ Token (TokenType .ATOM , 'Arg3' ),
128+ Token (TokenType .RIGHT_BRACKET , ')' )]
129+
130+ actual_tokens = self .converter .convert (input_tokens )
131+
132+ expected_tokens = [Token (TokenType .ATOM , 'Arg1' ),
133+ Token (TokenType .ATOM , 'Arg2' ),
134+ Token (TokenType .ATOM , 'Arg3' ),
135+ Token (TokenType .FUNCTION , 'FUN' )]
136+
137+ assert actual_tokens == expected_tokens
138+
139+
140+ def test_positive_function_and_exernal_operator_result_value (self ):
141+ self .converter .add_operator ('+' , 1 )
142+
143+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
144+ Token (TokenType .LEFT_BRACKET , '(' ),
145+ Token (TokenType .ATOM , 'Arg1' ),
146+ Token (TokenType .RIGHT_BRACKET , ')' ),
147+ Token (TokenType .OPERATOR , '+' ),
148+ Token (TokenType .FUNCTION , 'FUN' ),
149+ Token (TokenType .LEFT_BRACKET , '(' ),
150+ Token (TokenType .ATOM , 'Arg2' ),
151+ Token (TokenType .RIGHT_BRACKET , ')' )]
152+
153+ actual_tokens = self .converter .convert (input_tokens )
154+
155+ expected_tokens = [Token (TokenType .ATOM , 'Arg1' ),
156+ Token (TokenType .FUNCTION , 'FUN' ),
157+ Token (TokenType .ATOM , 'Arg2' ),
158+ Token (TokenType .FUNCTION , 'FUN' ),
159+ Token (TokenType .OPERATOR , '+' )]
160+
161+ assert actual_tokens == expected_tokens
162+
163+
164+ def test_positive_function_and_internal_operator_result_value (self ):
165+ self .converter .add_operator ('+' , 1 )
166+
167+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
168+ Token (TokenType .LEFT_BRACKET , '(' ),
169+ Token (TokenType .ATOM , 'Arg1' ),
170+ Token (TokenType .OPERATOR , '+' ),
171+ Token (TokenType .ATOM , 'Arg2' ),
172+ Token (TokenType .COMMA , ',' ),
173+ Token (TokenType .ATOM , 'Arg3' ),
174+ Token (TokenType .OPERATOR , '+' ),
175+ Token (TokenType .ATOM , 'Arg4' ),
176+ Token (TokenType .RIGHT_BRACKET , ')' )]
177+
178+ actual_tokens = self .converter .convert (input_tokens )
179+
180+ expected_tokens = [Token (TokenType .ATOM , 'Arg1' ),
181+ Token (TokenType .ATOM , 'Arg2' ),
182+ Token (TokenType .OPERATOR , '+' ),
183+ Token (TokenType .ATOM , 'Arg3' ),
184+ Token (TokenType .ATOM , 'Arg4' ),
185+ Token (TokenType .OPERATOR , '+' ),
186+ Token (TokenType .FUNCTION , 'FUN' )]
187+
188+ assert actual_tokens == expected_tokens
189+
190+
191+ def test_positive_nested_functions_result_value (self ):
192+ self .converter .add_operator ('+' , 1 )
193+
194+ input_tokens = [Token (TokenType .FUNCTION , 'FUN1' ),
195+ Token (TokenType .LEFT_BRACKET , '(' ),
196+ Token (TokenType .FUNCTION , 'FUN2' ),
197+ Token (TokenType .LEFT_BRACKET , '(' ),
198+ Token (TokenType .RIGHT_BRACKET , ')' ),
199+ Token (TokenType .COMMA , ',' ),
200+ Token (TokenType .FUNCTION , 'FUN3' ),
201+ Token (TokenType .LEFT_BRACKET , '(' ),
202+ Token (TokenType .ATOM , 'Arg1' ),
203+ Token (TokenType .COMMA , ',' ),
204+ Token (TokenType .ATOM , 'Arg2' ),
205+ Token (TokenType .RIGHT_BRACKET , ')' ),
206+ Token (TokenType .RIGHT_BRACKET , ')' )]
207+
208+ actual_tokens = self .converter .convert (input_tokens )
209+
210+ expected_tokens = [Token (TokenType .FUNCTION , 'FUN2' ),
211+ Token (TokenType .ATOM , 'Arg1' ),
212+ Token (TokenType .ATOM , 'Arg2' ),
213+ Token (TokenType .FUNCTION , 'FUN3' ),
214+ Token (TokenType .FUNCTION , 'FUN1' )]
215+
216+ assert actual_tokens == expected_tokens
217+
218+
219+ def test_positive_operators_without_arguments_result_value (self ):
220+ self .converter .add_operator ('+' , 1 )
221+
222+ input_tokens = [Token (TokenType .OPERATOR , '+' ),
223+ Token (TokenType .OPERATOR , '+' ),
224+ Token (TokenType .OPERATOR , '+' )]
225+
226+ actual_tokens = self .converter .convert (input_tokens )
227+
228+ expected_tokens = [Token (TokenType .OPERATOR , '+' ),
229+ Token (TokenType .OPERATOR , '+' ),
230+ Token (TokenType .OPERATOR , '+' )]
231+
232+ assert actual_tokens == expected_tokens
233+
234+
235+ def test_positive_function_without_commas_result_value (self ):
236+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
237+ Token (TokenType .LEFT_BRACKET , '(' ),
238+ Token (TokenType .ATOM , 'Arg1' ),
239+ Token (TokenType .ATOM , 'Arg2' ),
240+ Token (TokenType .RIGHT_BRACKET , ')' )]
241+
242+ actual_tokens = self .converter .convert (input_tokens )
243+
244+ expected_tokens = [Token (TokenType .ATOM , 'Arg1' ),
245+ Token (TokenType .ATOM , 'Arg2' ),
246+ Token (TokenType .FUNCTION , 'FUN' )]
247+
248+ assert actual_tokens == expected_tokens
249+
250+
251+ def test_positive_function_of_operators_result_value (self ):
252+ self .converter .add_operator ('+' , 1 )
253+
254+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
255+ Token (TokenType .LEFT_BRACKET , '(' ),
256+ Token (TokenType .OPERATOR , '+' ),
257+ Token (TokenType .OPERATOR , '+' ),
258+ Token (TokenType .RIGHT_BRACKET , ')' )]
259+
260+ actual_tokens = self .converter .convert (input_tokens )
261+
262+ expected_tokens = [Token (TokenType .OPERATOR , '+' ),
263+ Token (TokenType .OPERATOR , '+' ),
264+ Token (TokenType .FUNCTION , 'FUN' )]
265+
266+ assert actual_tokens == expected_tokens
267+
268+
269+ def test_negative_unpaired_left_bracket (self ):
270+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
271+ Token (TokenType .LEFT_BRACKET , '(' ),
272+ Token (TokenType .ATOM , 'Arg1' )]
273+
274+ with pytest .raises (ExpressionError ) as ex :
275+ self .converter .convert (input_tokens )
276+
277+ assert 'Unpaired bracket' in str (ex .value )
278+
279+
280+ def test_negative_unpaired_right_bracket (self ):
281+ input_tokens = [Token (TokenType .FUNCTION , 'FUN' ),
282+ Token (TokenType .ATOM , 'Arg1' ),
283+ Token (TokenType .RIGHT_BRACKET , ')' )]
284+
285+ with pytest .raises (ExpressionError ) as ex :
286+ self .converter .convert (input_tokens )
287+
288+ assert 'Unpaired bracket' in str (ex .value )
289+
290+
291+ def test_negative_empty_operator (self ):
292+ with pytest .raises (TypeError ) as ex :
293+ self .converter .add_operator (None , 1 )
294+
295+ assert 'Attempt to add None' in str (ex .value )
296+
297+
298+ def test_negative_two_operators_with_the_same_name (self ):
299+ self .converter .add_operator ('+' , 1 )
300+
301+ with pytest .raises (ExpressionError ) as ex :
302+ self .converter .add_operator ('+' , 1 )
303+
304+ assert 'is alredy added' in str (ex .value )
305+
306+
307+ def test_negative_unknown_operator (self ):
308+ self .converter .add_operator ('+' , 1 )
309+
310+ input_tokens = [Token (TokenType .ATOM , 'Arg1' ),
311+ Token (TokenType .OPERATOR , '+' ),
312+ Token (TokenType .ATOM , 'Arg2' ),
313+ Token (TokenType .OPERATOR , '*' ),
314+ Token (TokenType .ATOM , 'Arg3' )]
315+
316+ with pytest .raises (ExpressionError ) as ex :
317+ self .converter .convert (input_tokens )
318+
319+ assert 'Unknown operator' in str (ex .value )
0 commit comments