Skip to content

Commit 1c77783

Browse files
Add Harmony AST tests
1 parent f8281f6 commit 1c77783

File tree

4 files changed

+117
-3
lines changed

4 files changed

+117
-3
lines changed

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ upload-test: dist
4242
upload: dist
4343
twine upload dist/*
4444

45+
test-unit:
46+
coverage run -m unittest discover tests/harmony
47+
4548
test-e2e:
4649
coverage run -m unittest discover tests/e2e
4750

48-
test: test-e2e
51+
test: test-unit test-e2e
4952

5053
clean:
5154
# Harmony outputs in `code` directory

tests/e2e/test_compilation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_compilation_error(self):
3939
for param in params:
4040
f = str(param.filename)
4141
self.run_before_tests()
42-
with self.subTest(f"Success compilation test: {f}"):
42+
with self.subTest(f"Failure compilation test: {f}"):
4343
start_time = time.perf_counter_ns()
4444
self.assertRaises(
4545
(HarmonyCompilerErrorCollection, HarmonyCompilerError),

tests/e2e/test_gen_html.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ def test_gen_html(self):
6262
self.assertEqual(r.returncode, 0)
6363
except subprocess.TimeoutExpired:
6464
logger.warning("TimeoutExpired for file %s.", str(param.filename))
65-
return
65+
continue
6666
handle_hco(mock_ns, output_files)

tests/harmony/test_ast.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
from unittest import TestCase
2+
import unittest
3+
4+
from harmony_model_checker.harmony.ast import *
5+
from harmony_model_checker.harmony.code import Labeled_Op
6+
7+
def create_token(value, file='test.hny', line=0, col=0):
8+
return value, file, line, col
9+
10+
class TestConstantAST(TestCase):
11+
def create_constant_ast(self):
12+
return [
13+
ConstantAST(
14+
endtoken=create_token(const),
15+
const=create_token(const),
16+
) for const in [12, True, "str"]
17+
]
18+
19+
def test_is_constant(self):
20+
for c in self.create_constant_ast():
21+
scope = Scope(None)
22+
self.assertTrue(c.isConstant(scope))
23+
24+
def test_compile(self):
25+
for c in self.create_constant_ast():
26+
scope = Scope(None)
27+
code = Code()
28+
c.compile(scope, code)
29+
self.assertEqual(len(code.labeled_ops), 1)
30+
31+
lbled_op: Labeled_Op = code.labeled_ops[0]
32+
self.assertIsInstance(lbled_op, Labeled_Op)
33+
34+
op: PushOp = lbled_op.op
35+
self.assertIsInstance(op, PushOp)
36+
self.assertEqual(op.constant, c.const)
37+
38+
39+
class TestNameAST(TestCase):
40+
def create_name_ast(self):
41+
return [
42+
NameAST(
43+
endtoken=create_token(name),
44+
name=create_token(name),
45+
) for name in ['abc', 'foo', 'bar', 'harmony']
46+
]
47+
48+
def test_is_constant(self):
49+
for n in self.create_name_ast():
50+
# default scope is global
51+
scope = Scope(None)
52+
self.assertFalse(n.isConstant(scope))
53+
54+
scope = Scope(None)
55+
lexeme = n.name[0]
56+
scope.names[lexeme] = ("constant", n.name)
57+
self.assertTrue(n.isConstant(scope))
58+
59+
def test_compile(self):
60+
for n in self.create_name_ast():
61+
lexeme = n.name[0]
62+
63+
# test with global scope
64+
scope = Scope(None)
65+
code = Code()
66+
n.compile(scope, code)
67+
self.assertEqual(len(code.labeled_ops), 1)
68+
lbled_op: Labeled_Op = code.labeled_ops[0]
69+
self.assertIsInstance(lbled_op, Labeled_Op)
70+
op: LoadOp = lbled_op.op
71+
self.assertIsInstance(op, LoadOp)
72+
self.assertEqual(op.name, n.name)
73+
74+
# test as a local variable
75+
scope = Scope(None)
76+
scope.names[lexeme] = ("local-var", n.name)
77+
code = Code()
78+
n.compile(scope, code)
79+
self.assertEqual(len(code.labeled_ops), 1)
80+
lbled_op: Labeled_Op = code.labeled_ops[0]
81+
self.assertIsInstance(lbled_op, Labeled_Op)
82+
op: LoadVarOp = lbled_op.op
83+
self.assertIsInstance(op, LoadVarOp)
84+
self.assertEqual(op.v, n.name)
85+
86+
# test as a constant
87+
scope = Scope(None)
88+
scope.names[lexeme] = ("constant", n.name)
89+
code = Code()
90+
n.compile(scope, code)
91+
self.assertEqual(len(code.labeled_ops), 1)
92+
lbled_op: Labeled_Op = code.labeled_ops[0]
93+
self.assertIsInstance(lbled_op, Labeled_Op)
94+
op: PushOp = lbled_op.op
95+
self.assertIsInstance(op, PushOp)
96+
self.assertEqual(op.constant, n.name)
97+
98+
99+
class TestHarmonyAST(TestCase):
100+
"""Tests the creation and modification of Harmony AST classes
101+
"""
102+
def test_create(self):
103+
pass
104+
105+
def test_simple(self):
106+
self.assertTrue(True)
107+
pass
108+
109+
110+
if __name__ == "__main__":
111+
unittest.main()

0 commit comments

Comments
 (0)