Skip to content

Commit

Permalink
very clever test funcationality added
Browse files Browse the repository at this point in the history
  • Loading branch information
marsninja committed Sep 16, 2023
1 parent 8d0fd4c commit 6a0f043
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 56 deletions.
26 changes: 7 additions & 19 deletions examples/manual_code/circle.jac
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This module demonstrates a simple circle class and a function to calculate the a
import:py math;

# Module-level global
global RADIUS = 5;
global RAD = 5;

"""Function to calculate the area of a circle."""
can calculate_area(radius: float) -> float {
Expand Down Expand Up @@ -50,29 +50,17 @@ object Circle:Shape {
}
}

with entry {c = Circle(RADIUS);} # Global also works here
with entry {c = Circle(RAD);} # Global also works here

with entry:__main__ { # TODO: add name == option abstract feature
# To run the program functionality
print(f"Area of a circle with radius 5: {calculate_area(RADIUS)}");
print(f"Area of a circle with radius 5: {calculate_area(RAD)}");
print(f"Area of a {c.shape_type.value} with radius 5: {c.area()}");
}

test calculate_area
"Tests for the calculate_area function." {
expected_area = 78.53981633974483;
assertAlmostEqual(calculate_area(RADIUS), expected_area);
}

test circle_area
"Tests for the area method of the Circle class." {
c = Circle(RADIUS);
expected_area = 78.53981633974483;
assertAlmostEqual(c.area(), expected_area);
}
global expected_area = 78.53981633974483;

test circle_type
"Tests for the shape_type attribute of the Circle class." {
c = Circle(RADIUS);
assertEqual(c.shape_type, ShapeType.CIRCLE);
}
test calculate_area { check.AlmostEqual(calculate_area(RAD), expected_area); }
test circle_area { c = Circle(RAD); check.AlmostEqual(c.area(), expected_area); }
test circle_type { c = Circle(RAD); check.Equal(c.shape_type, ShapeType.CIRCLE); }
18 changes: 7 additions & 11 deletions examples/manual_code/circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import unittest

# Module-level global
RADIUS = 5
RAD = 5


def calculate_area(radius: float) -> float:
Expand Down Expand Up @@ -51,16 +51,12 @@ def area(self) -> float:
return math.pi * self.radius * self.radius


c = Circle(RADIUS)
c = Circle(RAD)

if __name__ == "__main__":
# To run the program functionality
print(
f"Area of a circle with radius {RADIUS} using function: {calculate_area(RADIUS)}"
)
print(
f"Area of a {c.shape_type.value} with radius {RADIUS} using class: {c.area()}"
)
print(f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}")
print(f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}")

# Uncomment the next line if you want to run the unit tests
# run_tests()
Expand All @@ -70,13 +66,13 @@ def area(self) -> float:
class TestShapesFunctions(unittest.TestCase):
def test_calculate_area(self):
expected_area = 78.53981633974483
self.assertAlmostEqual(calculate_area(RADIUS), expected_area)
self.assertAlmostEqual(calculate_area(RAD), expected_area)

def test_circle_area(self):
c = Circle(RADIUS)
c = Circle(RAD)
expected_area = 78.53981633974483
self.assertAlmostEqual(c.area(), expected_area)

def test_circle_type(self):
c = Circle(RADIUS)
c = Circle(RAD)
self.assertEqual(c.shape_type, ShapeType.CIRCLE)
4 changes: 2 additions & 2 deletions examples/micro/module_structure.jac
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ with entry {
# module level freestyle code
}

test mytest
"A test of my functionality" {
"""A test of my functionality"""
test mytest {
# test code here
}
4 changes: 1 addition & 3 deletions jaclang/jac/absyntree.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,8 @@ class Test(AstNode):

def __init__(
self,
name: Name,
name: Optional[Name],
doc: Optional[Token],
description: Token,
body: CodeBlock,
parent: Optional[AstNode],
mod_link: Optional[Module],
Expand All @@ -163,7 +162,6 @@ def __init__(
"""Initialize test node."""
self.doc = doc
self.name = name
self.description = description
self.body = body
super().__init__(
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
Expand Down
5 changes: 4 additions & 1 deletion jaclang/jac/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ def access_tag(self, p: YaccProduction) -> YaccProduction:
"""Permission tag rule."""
return p

@_("doc_tag KW_TEST NAME multistring code_block")
@_(
"doc_tag KW_TEST NAME code_block",
"doc_tag KW_TEST code_block",
)
def test(self, p: YaccProduction) -> YaccProduction:
"""Test rule."""
return p
Expand Down
42 changes: 28 additions & 14 deletions jaclang/jac/passes/blue/ast_build_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,36 @@ def exit_access_tag(self, node: ast.AstNode) -> None:
def exit_test(self, node: ast.AstNode) -> None:
"""Grammar rule.
test -> doc_tag KW_TEST NAME multistring code_block
test -> doc_tag KW_TEST code_block
test -> doc_tag KW_TEST NAME code_block
"""
del node.kid[1]
replace_node(
node,
ast.Test(
doc=node.kid[0],
name=node.kid[1],
description=node.kid[2],
body=node.kid[3],
parent=node.parent,
mod_link=self.mod_link,
kid=node.kid,
line=node.line,
),
)
if len(node.kid) == 3:
replace_node(
node,
ast.Test(
doc=node.kid[0],
name=node.kid[1],
body=node.kid[2],
parent=node.parent,
mod_link=self.mod_link,
kid=node.kid,
line=node.line,
),
)
else:
replace_node(
node,
ast.Test(
doc=node.kid[0],
name=None,
body=node.kid[1],
parent=node.parent,
mod_link=self.mod_link,
kid=node.kid,
line=node.line,
),
)

def exit_mod_code(self, node: ast.AstNode) -> None:
"""Grammar rule.
Expand Down
34 changes: 28 additions & 6 deletions jaclang/jac/passes/blue/blue_pygen_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
class BluePygenPass(Pass):
"""Jac blue transpilation to python pass."""

TEST_COUNT = 0

def before_pass(self) -> None:
"""Initialize pass."""
self.indent_size = 4
Expand Down Expand Up @@ -179,16 +181,36 @@ def exit_global_vars(self, node: ast.GlobalVars) -> None:
self.emit_ln(node, node.doc.value)
self.emit(node, node.assignments.meta["py_code"])

# NOTE: Incomplete for Jac Purple and Red
def exit_test(self, node: ast.Test) -> None:
"""Sub objects.
name: Token,
doc: Optional["Token"],
description: Token,
body: "CodeBlock",
name: Optional[Name],
doc: Optional[Token],
body: CodeBlock,
"""
self.warning("Test feature not supported in bootstrap Jac.")
if node.name:
test_name = node.name.value
else:
test_name = f"_jac_t{self.TEST_COUNT}"
self.TEST_COUNT += 1
test_code = "import unittest as __jac_unittest__\n"
test_code += "__jac_tc__ = __jac_unittest__.TestCase()\n"
test_code += "__jac_suite__ = __jac_unittest__.TestSuite()\n"
test_code += "class __jac_check:\n"
test_code += " def __getattr__(self, name):\n"
test_code += " return getattr(__jac_tc__, 'assert'+name)"
self.emit_ln_unique(self.preamble, test_code)
self.emit_ln(node, f"def test_{test_name}():")
self.indent_level += 1
if node.doc:
self.emit_ln(node, node.doc.value)
self.emit_ln(node, "check = __jac_check()")
self.emit_ln(node, node.body.meta["py_code"])
self.indent_level -= 1
self.emit_ln(
node,
f"__jac_suite__.addTest(__jac_unittest__.FunctionTestCase(test_{test_name}))",
)

def exit_module_code(self, node: ast.ModuleCode) -> None:
"""Sub objects.
Expand Down

0 comments on commit 6a0f043

Please sign in to comment.