diff --git a/build-system/build-system.gyp b/build-system/build-system.gyp index 0962a0bee..fd3f9189c 100644 --- a/build-system/build-system.gyp +++ b/build-system/build-system.gyp @@ -91,6 +91,7 @@ # generators/vcvrack 'erbb/generators/vcvrack/project_template.gyp', 'erbb/generators/vcvrack/project.py', + 'erbb/generators/vcvrack/test_unit_template.gyp', # generators/daisy 'erbb/generators/daisy/Makefile_template', diff --git a/build-system/erbb/ast.py b/build-system/erbb/ast.py index 489e2077a..efcda6ac0 100755 --- a/build-system/erbb/ast.py +++ b/build-system/erbb/ast.py @@ -69,6 +69,9 @@ def is_data (self): return isinstance (self, Data) @property def is_stream (self): return isinstance (self, Stream) + @property + def is_test (self): return isinstance (self, Test) + @property def is_faust_address (self): return isinstance (self, FaustAddress) @@ -207,6 +210,11 @@ def resources (self): entities = [e for e in self.entities if e.is_resources] return entities + @property + def tests (self): + entities = [e for e in self.entities if e.is_test] + return entities + @property def bases (self): entities = [e for e in self.entities if e.is_base] @@ -492,6 +500,37 @@ def source_context_part (self, part): +# -- Test -------------------------------------------------------------------- + +class Test (Scope): + def __init__ (self, name_identifier): + assert isinstance (name_identifier, adapter.Identifier) + super (Test, self).__init__ () + self.name_identifier = name_identifier + + @staticmethod + def typename (): return 'test' + + @property + def name (self): return self.name_identifier.name + + @property + def source_context (self): + return self.source_context_part ('name') + + def source_context_part (self, part): + if part == 'name': + return adapter.SourceContext.from_token (self.name_identifier) + + return super (Test, self).source_context_part (part) # pragma: no cover + + @property + def files (self): + entities = [e for e in self.entities if e.is_file] + return entities + + + # -- Faust ------------------------------------------------------------------- class Faust (Scope): diff --git a/build-system/erbb/generators/vcvrack/project.py b/build-system/erbb/generators/vcvrack/project.py index acb761e41..d51d3555a 100755 --- a/build-system/erbb/generators/vcvrack/project.py +++ b/build-system/erbb/generators/vcvrack/project.py @@ -50,6 +50,7 @@ def generate_module (self, path, module, strict): template = self.replace_bases (template, module, module.bases, path); template = self.replace_sources (template, module, module.sources, path) template = self.replace_actions (template, module, path) + template = self.replace_tests (template, module, path) with open (path_cpp, 'w', encoding='utf-8') as file: file.write (template) @@ -400,3 +401,41 @@ def replace_actions_data (self, module, path): lines += ' },\n' return lines + + + #-------------------------------------------------------------------------- + + def replace_tests (self, template, module, path): + + lines = '' + for test in module.tests: + lines += self.replace_test (module, test, path) + + return template.replace ('% tests%', lines) + + + #-------------------------------------------------------------------------- + + def replace_test (self, module, test, path): + path_template = os.path.join (PATH_THIS, 'test_unit_template.gyp') + with open (path_template, 'r', encoding='utf-8') as file: + template = file.read () + + template = template.replace ('%test.name%', test.name) + template = self.replace_includes (template, module, path); + template = self.replace_defines (template, module.defines) + template = self.replace_bases (template, module, module.bases, path); + template = self.replace_test_sources (template, test, path) + return template + + + #-------------------------------------------------------------------------- + + def replace_test_sources (self, template, test, path): + lines = '' + + for file in test.files: + file_path = os.path.relpath (file.path, path) + lines += ' \'%s\',\n' % file_path + + return template.replace ('% test.sources%', lines) diff --git a/build-system/erbb/generators/vcvrack/project_template.gyp b/build-system/erbb/generators/vcvrack/project_template.gyp index a67e3f279..c8dc23415 100644 --- a/build-system/erbb/generators/vcvrack/project_template.gyp +++ b/build-system/erbb/generators/vcvrack/project_template.gyp @@ -65,5 +65,6 @@ }, ], }, +% tests% ], } diff --git a/build-system/erbb/generators/vcvrack/test_unit_template.gyp b/build-system/erbb/generators/vcvrack/test_unit_template.gyp new file mode 100644 index 000000000..5edab44d9 --- /dev/null +++ b/build-system/erbb/generators/vcvrack/test_unit_template.gyp @@ -0,0 +1,17 @@ + { + 'target_name': '%test.name%', + 'type': 'executable', + + 'defines': [ +% defines.entities% + ], + + 'include_dirs': [ + '.', +% bases.entities% + ], + + 'sources': [ +% test.sources% + ], + }, diff --git a/build-system/erbb/grammar.py b/build-system/erbb/grammar.py index 9a92ee56a..f63b96d4f 100755 --- a/build-system/erbb/grammar.py +++ b/build-system/erbb/grammar.py @@ -13,7 +13,7 @@ KEYWORDS = ( 'module', 'import', 'define', 'sources', 'resources', 'section', - 'file', 'data', 'flash', 'qspi', 'sram', 'stream', 'mono', 'interleaved', 'planar' + 'file', 'data', 'test', 'flash', 'qspi', 'sram', 'stream', 'mono', 'interleaved', 'planar' ) SYMBOLS = (',', '{', '}', '=') @@ -71,6 +71,12 @@ def resources_entities (): return ZeroOrMore (data_declaration) def resources_body (): return '{', resources_entities, '}' def resources_declaration (): return 'resources', resources_body +# Tests +def test_entities (): return ZeroOrMore (file_declaration) +def test_body (): return '{', test_entities, '}' +def test_name (): return name +def test_declaration (): return 'test', test_name, test_body + # Base def base_declaration (): return 'base', string_literal @@ -79,7 +85,7 @@ def section_name (): return ['flash', 'qspi', 'sram'] def section_declaration (): return 'section', section_name # Module -def module_entities (): return ZeroOrMore ([section_declaration, import_declaration, define_declaration, sources_declaration, resources_declaration, base_declaration]) +def module_entities (): return ZeroOrMore ([section_declaration, import_declaration, define_declaration, sources_declaration, resources_declaration, test_declaration, base_declaration]) def module_body (): return '{', module_entities, '}' def module_name (): return name def module_declaration (): return 'module', module_name, module_body diff --git a/build-system/erbb/visitor.py b/build-system/erbb/visitor.py index 4251684da..203a30964 100755 --- a/build-system/erbb/visitor.py +++ b/build-system/erbb/visitor.py @@ -286,6 +286,29 @@ def visit_resources_entities (self, node, children): return list (children) + #-- Test ------------------------------------------------------------------ + + def visit_test_declaration (self, node, children): + test_name_identifier = children.test_name [0] + + test = ast.Test (test_name_identifier) + + if children.test_body: + entities = children.test_body [0] + test.add (entities) + + return test + + def visit_test_name (self, node, children): + return self.visit_identifier (node, children) + + def visit_test_body (self, node, children): + return children [0] if children else [] + + def visit_test_entities (self, node, children): + return list (children) + + #-- Base ------------------------------------------------------------------ def visit_base_declaration (self, node, children):