Skip to content

Commit

Permalink
Added some unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Fernandez committed Dec 16, 2024
1 parent 6bda973 commit 376d58e
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 3 deletions.
1 change: 0 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ pylint==3.2.4
coverage>=7.2
sphinx>=7.0
build>=1.2.0
bmw-lobster
128 changes: 126 additions & 2 deletions tests-unit/test_ast_bysection.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import unittest
from unittest.mock import patch, MagicMock
from trlc.ast import Symbol_Table
from unittest.mock import MagicMock, patch
from trlc.ast import (Record_Object, Implicit_Null, Literal, Record_Type,
Package, Composite_Type, Composite_Component, Symbol_Table)
from trlc.errors import Location

class TestRecordObject:
def __init__(self, location, section):
Expand Down Expand Up @@ -38,3 +40,125 @@ def test_iter_record_objects_by_section(self, mock_iter_record_objects):

if __name__ == '__main__':
unittest.main()

"""
class TestCompositeType(Composite_Type):
def __init__(self):
super().__init__(name="mock_composite_type",
location=Location(file_name="mock_file", line_no=1, col_no=1),
description="mock description")
self.components = {}
class TestCompositeComponent(Composite_Component):
def __init__(self, name):
member_of = TestCompositeType()
super().__init__(name=name,
description="test_description",
location=Location(file_name="mock_file", line_no=1, col_no=1),
member_of=member_of,
n_typ=None,
optional=False)
class TestLiteral(Literal):
def __init__(self):
location = Location(file_name="test_file", line_no=1, col_no=1)
super().__init__(location=location, typ=None)
def can_be_null(self):
return False
def dump(self, indent=0):
pass
def to_python_object(self):
return "test_literal_value"
def to_string(self):
return "test_literal"
class TestRecordObjectMethods(unittest.TestCase):
def setUp(self):
name = "mock_name"
location = Location(file_name="mock_file", line_no=1, col_no=1)
builtin_stab = Symbol_Table()
declared_late = False
package = Package(
name="mock_package",
location=location,
builtin_stab=builtin_stab,
declared_late=declared_late,
)
description = "mock_description"
n_parent = None
is_abstract = False
n_typ = Record_Type(
name=name,
description=description,
location=location,
package=package,
n_parent=n_parent,
is_abstract=is_abstract,
)
section = None
n_package = package
self.record = Record_Object(
name=name,
location=location,
n_typ=n_typ,
section=section,
n_package=n_package,
)
self.record.field = {}
def test_is_component_implicit_null_uninitialized(self):
# Intention is to check if it correctly identifies an uninitialized component like a
# component with an Implicit_Null value in the field dictionary.
component = TestCompositeComponent("test_component")
self.record.field[component.name] = Implicit_Null(self.record, component)
self.assertTrue(self.record.is_component_implicit_null(component))
def test_is_component_implicit_null_initialized(self):
# Intention is to verify that it returns False for initialized components
# like when a valid value has been assigned already.
component = TestCompositeComponent("test_component")
self.record.field[component.name] = TestLiteral()
self.assertFalse(self.record.is_component_implicit_null(component))
def test_assign_uninitialized_component(self):
# Intention is to test whether the assign method correctly assigns a value
# to a component that is currently uninitialized (set to Implicit_Null).
component = TestCompositeComponent("new_component")
value = TestLiteral()
self.record.field[component.name] = Implicit_Null(self.record, component)
self.record.assign(component, value)
self.assertEqual(self.record.field[component.name], value)
def test_assign_duplicate_component(self):
# Intention is to confirm that the assign method raises an error
# when attempting to assign a value to a component that has already been assigned a value.
component = TestCompositeComponent("duplicate_component")
initial_value = TestLiteral()
self.record.field[component.name] = initial_value
new_value = TestLiteral()
with self.assertRaises(KeyError):
self.record.assign(component, new_value)
if __name__ == '__main__':
unittest.main()
The testing by using mocking requires instantiating many classes of the AST the because of how the assertions at runtime check and verify certain conditions about the arguments. If those conditions aren't satisfied perfectly, the code fails immediately, even if the behavior being tested is unrelated to the failed assertion.
Assertions in methods like `assign` in `ast.py` (arround line 3000) check for specific types and states of dependencies (e.g., ensuring arguments are instances of Composite_Component, Record_Object, or Implicit_Null). This means one must carefully construct the exact objects expected by the assertions everytime, which involves setting up a chain of related objects and probbably mocking again even more dependencies. The `assert` statements enforce all dependencies perfectly to be configured.
In order to achieve this 'perfectness' within the assertions some test classes like TestLiteral, TestCompositeComponent, and TestCompositeType were created purely as 'dummy' classes, allowing to bypass the complex setups required for the actual classes (Literal, Composite_Component, Composite_Type).
Propposed solution for testing: Adopt System-Level Testing
- Instead of testing individual methods in isolation, test the system's behavior as a whole using realistic input files or configurations and comparing against a expected output of the system given specific inputs, rather than low-level internal states.
"""

0 comments on commit 376d58e

Please sign in to comment.