def test_prologue_evaluate(mocker): """ Test evaluation of a Prologue instance """ # Patch Context mock_ctx_cls = mocker.patch("prologue.Context", autospec=True) mock_ctx_inst = [] def create_context(*args, **kwargs): mock_ctx = MagicMock() def fake_sub(line): print(f"Called fake_sub with {type(line)} {line}") return line.encase("start sub " + str(line) + " end sub") mock_ctx.substitute.side_effect = fake_sub mock_ctx_inst.append(mock_ctx) return mock_ctx mock_ctx_cls.side_effect = create_context # Create a Prologue instance, and patch 'evaluate_inner' pro = Prologue() mocker.patch.object(pro, "evaluate_inner", autospec=True) # Setup some fake lines to be produced by 'evaluate_inner' l_file = random_str(20, 30) lines = [ Line(random_str(30, 50, spaces=True), l_file, idx + 1) for idx in range(randint(20, 30)) ] def gen_lines(file, ctx, callback=None): for line in lines: yield line pro.evaluate_inner.side_effect = gen_lines # Create a dummy callback routine def dummy_cb(): print(f"Hit the dummy callback routine") # Call evaluate initial = {random_str(5, 10): random_str(5, 10) for _ in range(5)} lookup = [] result = [ x for x in pro.evaluate( l_file, defines=initial, callback=dummy_cb, lookup=lookup, ) ] # Check that the initial state reached the context mock_ctx_cls.assert_has_calls([ call( pro, implicit_sub=True, explicit_style=("$(", ")"), allow_redefine=False, initial_state=initial, ) ]) # Check that only 'str' objects were yielded assert len([x for x in result if not isinstance(x, str)]) == 0 # Check that every line contains substitutions assert result == [f"start sub {str(x)} end sub" for x in lines] # Check that the lookup has been populated correctly assert lookup == [(x.file, x.number) for x in lines] # Check calls to 'evaluate_inner' pro.evaluate_inner.assert_has_calls( [call( l_file, mock_ctx_inst[0], callback=dummy_cb, )]) # Check calls to 'substitute' mock_ctx_inst[0].substitute.assert_has_calls([call(x) for x in lines])
import sys from prologue import Prologue # Check for right number of arguments, then extract them if len(sys.argv) != 4: print("SYNTAX: python3 verilog.py <INPUTDIR> <TOPFILE> <OUTPUT>") sys.exit(1) in_dir = Path(sys.argv[1]) top = Path(sys.argv[2]) output = Path(sys.argv[3]) # Setup preprocessor instance pro = Prologue( comment ="//", delimiter ="`", shared_delimiter=True, # Verilog uses "`" to signal a defined variable implicit_sub =False, # Every substitution must be prefixed with "`" explicit_style =("`", ""), ) # Find all files within the input directory and add them to the registry for f_path in in_dir.glob("*.*"): pro.add_file(f_path) # Kick off evaluate using the top-level file with open(output, "w") as fh: for line in pro.evaluate(top.parts[-1]): fh.write(line + "\n")