Basic empty program returning 0
[sandbox] / stutter_test.py
1 #!/usr/bin/env python
2
3 import stutter
4 import unittest
5
6 class IsIntegerTests(unittest.TestCase):
7     def test_returns_true_for_integers(self):
8         for i in range(10):
9             self.assertTrue(stutter.is_integer(i))
10
11     def test_returns_false_for_booleans(self):
12         self.assertFalse(stutter.is_integer(True))
13         self.assertFalse(stutter.is_integer(False))
14
15     def test_returns_false_for_other_types(self):
16         for o in [object(), '', 0.1, [], (), {}, set()]:
17             self.assertFalse(stutter.is_integer(o))
18
19 class ParseAllTests(unittest.TestCase):
20     def test_parses_integers(self):
21         expected = [0]
22         actual = stutter.parse_all('0')
23
24         self.assertEqual(expected, actual)
25
26     def test_parses_empty_s_expressions(self):
27         expected = [()]
28         actual = stutter.parse_all('()')
29
30         self.assertEqual(expected, actual)
31
32     def test_parses_s_expressions(self):
33         expected = [(0, 1, 2)]
34         actual = stutter.parse_all('(0 1 2)')
35
36         self.assertEqual(expected, actual)
37
38     def test_parses_nested_s_expressions(self):
39         expected = [(0, (1, (2,)))]
40         actual = stutter.parse_all('(0 (1 (2)))')
41
42         self.assertEqual(expected, actual)
43
44     def test_parses_multiple_expressions(self):
45         expected = [0, ()]
46         actual = stutter.parse_all('0 ()')
47
48         self.assertEqual(expected, actual)
49
50     def test_raises_exception_for_unclosed_parenthese(self):
51         self.assertRaises(Exception, stutter.parse_all, '(')
52
53     def test_raises_exception_for_unopened_parenthese(self):
54         self.assertRaises(Exception, stutter.parse_all, ')')
55
56 class EvaluateToCTests(unittest.TestCase):
57     def test_evaluates_integers(self):
58         for i in range(5):
59             result = stutter.evaluate_to_c(i)
60             self.assertIsInstance(result, stutter.CIntegerLiteralExpression)
61             self.assertEqual(result.integer, i)
62
63 class EvaluateAllToCTests(unittest.TestCase):
64     def test_returns_main(self):
65         result = stutter.evaluate_all_to_c([0])
66
67         self.assertIsInstance(result, stutter.CFunctionDeclaration)
68         self.assertEqual(result.name, 'main')
69
70     def test_main_contains_expression_statements_followed_by_return_statement(self):
71         result = stutter.evaluate_all_to_c([0,0,0])
72
73         self.assertIsInstance(result.body[0],stutter.CExpressionStatement)
74         self.assertIsInstance(result.body[1],stutter.CExpressionStatement)
75         self.assertIsInstance(result.body[2],stutter.CReturnStatement)
76
77 class IndentTests(unittest.TestCase):
78     def test_indents_single_line(self):
79         expected = '  Hello, world'
80         actual = stutter.indent('Hello, world')
81         self.assertEqual(expected, actual)
82
83     def test_indents_multiple_lines(self):
84         expected = '  Hello, world\n  Goodbye, cruel world'
85         actual = stutter.indent('Hello, world\nGoodbye, cruel world')
86         self.assertEqual(expected, actual)
87
88     def test_leaves_empty_lines_empty(self):
89         expected = '  Hello, world\n\n  Goodbye, cruel world'
90         actual = stutter.indent('Hello, world\n \nGoodbye, cruel world')
91         self.assertEqual(expected, actual)
92
93     def test_indents_already_indented_lines(self):
94         expected = '    Hello, world\n\n    Goodbye, cruel world'
95         actual = stutter.indent('  Hello, world\n \n  Goodbye, cruel world')
96         self.assertEqual(expected, actual)
97
98 class GeneratePointerTypeTests(unittest.TestCase):
99     def test_basic(self):
100         expected = 'int*'
101         actual = stutter.generate_pointer_type(stutter.CPointerType(stutter.CType('int')))
102         self.assertEqual(expected, actual)
103
104 class GenerateTypeTests(unittest.TestCase):
105     def test_basic(self):
106         expected = 'int'
107         actual = stutter.generate_type(stutter.CType('int'))
108         self.assertEqual(expected, actual)
109
110     def test_generates_pointer_types(self):
111         expected = object()
112         actual = stutter.generate_type(
113                 stutter.CPointerType(stutter.CType('int')),
114                 generate_pointer_type = lambda x : expected)
115
116         self.assertIs(expected, actual)
117
118 class GenerateArgumentDeclarationTests(unittest.TestCase):
119     def test_basic(self):
120         expected = 'int argc'
121         actual = stutter.generate_argument_declaration(
122                 stutter.CArgumentDeclaration(stutter.CType('int'), 'argc'))
123         self.assertEqual(expected, actual)
124
125 class GenerateArgumentDeclarationListTests(unittest.TestCase):
126     def test_basic(self):
127         argument_declarations = [
128                 stutter.CArgumentDeclaration(stutter.CType('int'),'argc'),
129                 stutter.CArgumentDeclaration(stutter.CPointerType(stutter.CPointerType(stutter.CType('char'))), 'argv'),
130             ]
131         expected = 'int argc, char** argv'
132         actual = stutter.generate_argument_declaration_list(argument_declarations)
133         self.assertEqual(expected, actual)
134
135 class GenerateIntegerLiteralExpressionTests(unittest.TestCase):
136     def test_basic(self):
137         expected = '0'
138         actual = stutter.generate_integer_literal_expression(
139             stutter.CIntegerLiteralExpression(0),
140         )
141         self.assertEqual(expected, actual)
142
143 class GenerateFunctionCallExpressionTests(unittest.TestCase):
144     def test_no_arguments(self):
145         expected = 'name()'
146         actual = stutter.generate_function_call_expression(
147             stutter.CFunctionCallExpression('name', []),
148         )
149         self.assertEqual(expected, actual)
150
151     def test_one_argument(self):
152         expected = 'name(0)'
153         actual = stutter.generate_function_call_expression(
154             stutter.CFunctionCallExpression(
155                 'name',
156                 [
157                     stutter.CIntegerLiteralExpression(0),
158                 ],
159             ),
160         )
161         self.assertEqual(expected, actual)
162
163     def test_many_arguments(self):
164         expected = 'name(0, 1)'
165         actual = stutter.generate_function_call_expression(
166             stutter.CFunctionCallExpression(
167                 'name',
168                 [
169                     stutter.CIntegerLiteralExpression(0),
170                     stutter.CIntegerLiteralExpression(1),
171                 ],
172             ),
173         )
174         self.assertEqual(expected, actual)
175
176 class GenerateExpressionTests(unittest.TestCase):
177     def test_generates_integer_literal_expressions(self):
178         expected = object()
179         actual = stutter.generate_expression(
180                 stutter.CIntegerLiteralExpression(0),
181                 generate_integer_literal_expression = lambda x : expected)
182
183         self.assertIs(expected, actual)
184
185     def test_generates_function_call_expression(self):
186         expected = object()
187         actual = stutter.generate_expression(
188                 stutter.CFunctionCallExpression('name',[]),
189                 generate_function_call_expression = lambda x : expected)
190
191         self.assertIs(expected, actual)
192
193 class GenerateStatement(unittest.TestCase):
194     def test_generates_expression_statement(self):
195         return_statement = stutter.CExpressionStatement('0')
196
197         expected = object()
198         actual = stutter.generate_statement(
199             return_statement,
200             generate_expression_statement = lambda _ : expected)
201
202         self.assertIs(expected, actual)
203
204     def test_generates_return_statement(self):
205         return_statement = stutter.CReturnStatement(stutter.CIntegerLiteralExpression(0))
206
207         expected = object()
208         actual = stutter.generate_statement(
209             return_statement,
210             generate_return_statement = lambda _ : expected)
211
212         self.assertIs(expected, actual)
213
214 class GenerateExpressionStatementTests(unittest.TestCase):
215     def test_generates_return_statement(self):
216         expression_statement = stutter.CExpressionStatement(stutter.CIntegerLiteralExpression(0))
217
218         expected = '0;'
219         actual = stutter.generate_expression_statement(expression_statement)
220
221         self.assertEqual(expected, actual)
222
223 class GenerateReturnStatementTests(unittest.TestCase):
224     def test_generates_return_statement(self):
225         return_statement = stutter.CReturnStatement(stutter.CIntegerLiteralExpression(0))
226
227         expected = 'return 0;'
228         actual = stutter.generate_return_statement(return_statement)
229
230         self.assertEqual(expected, actual)
231
232 class GenerateFunctionDeclarationTests(unittest.TestCase):
233     def test_basic(self):
234         return_type = stutter.CType('int')
235         argument_declarations = [
236                 stutter.CArgumentDeclaration(stutter.CType('int'),'argc'),
237                 stutter.CArgumentDeclaration(stutter.CPointerType(stutter.CPointerType(stutter.CType('char'))), 'argv'),
238             ]
239
240         function_declaration = stutter.CFunctionDeclaration(
241                 return_type,
242                 'main',
243                 argument_declarations,
244                 [stutter.CReturnStatement(stutter.CIntegerLiteralExpression(0))])
245
246         expected = 'int main(int argc, char** argv)\n{\n  return 0;\n}'
247         actual = stutter.generate_function_declaration(function_declaration)
248         self.assertEqual(expected, actual)
249
250 unittest.main()