diff --git a/test/test_debugger.py b/test/test_debugger.py index a884aa1..dfbbf9d 100644 --- a/test/test_debugger.py +++ b/test/test_debugger.py @@ -18,6 +18,7 @@ def debugger(): SET(R1, 10) SET(R2, 32) ADD(R3, R1, R2) +HALT() """ ) _symtab = get_symtab(_tree) @@ -25,6 +26,15 @@ def debugger(): def test_print_breakpoints(debugger, capsys): + debugger.breakpoints[4] = "main.hera:7" + + should_continue = debugger.handle_command("break") + + assert should_continue + assert capsys.readouterr().out == "main.hera:7\n" + + +def test_print_breakpoints_with_no_breakpoints_set(debugger, capsys): should_continue = debugger.handle_command("break") assert should_continue @@ -90,6 +100,35 @@ def test_execute_next(debugger): assert debugger.vm.pc == 2 +def test_execute_next_with_halt(debugger, capsys): + # Last instruction of SAMPLE_PROGRAM is a HALT operation. + debugger.vm.pc = len(debugger.program) - 1 + + should_continue = debugger.handle_command("next") + + assert should_continue + assert debugger.vm.pc == len(debugger.program) - 1 + assert capsys.readouterr().out == "Program has finished executing.\n" + + +def test_execute_next_after_end_of_program(debugger, capsys): + debugger.vm.pc = 9000 + + should_continue = debugger.handle_command("next") + + assert should_continue + assert debugger.vm.pc == 9000 + assert capsys.readouterr().out == "Program has finished executing. Press 'r' to restart.\n" + + +def test_execute_next_with_too_many_args(debugger, capsys): + # TODO: It would actually be useful if this worked. + should_continue = debugger.handle_command("next 10") + + assert should_continue + assert capsys.readouterr().out == "next takes no arguments.\n" + + def test_execute_abbreviated_next(debugger): with patch("hera.debugger.Debugger.exec_next") as mock_exec_next: debugger.handle_command("n") @@ -108,7 +147,7 @@ def test_execute_continue_with_breakpoint(debugger): assert debugger.vm.pc == 4 -def test_execute_continue_without_breakpoint(debugger): +def test_execute_continue_without_breakpoint(debugger, capsys): should_continue = debugger.handle_command("continue") assert should_continue @@ -116,6 +155,14 @@ def test_execute_continue_without_breakpoint(debugger): assert debugger.vm.registers[2] == 32 assert debugger.vm.registers[3] == 42 assert debugger.vm.pc == 5 + assert capsys.readouterr().out == "Program has finished executing.\n" + + +def test_execute_continue_with_too_many_args(debugger, capsys): + should_continue = debugger.handle_command("continue 10") + + assert should_continue + assert capsys.readouterr().out == "continue takes no arguments.\n" def test_execute_abbreviated_continue(debugger): @@ -158,11 +205,41 @@ def test_print_memory_location(debugger, capsys): assert capsys.readouterr().out == "M[97] = 1000\n" +def test_execute_print_with_too_few_args(debugger, capsys): + # TODO: It would be useful if this printed the last printed expression again. + should_continue = debugger.handle_command("print") + + assert should_continue + assert capsys.readouterr().out == "print takes one argument.\n" + + +def test_execute_abbreviated_print(debugger): + with patch("hera.debugger.Debugger.exec_print") as mock_exec_print: + debugger.handle_command("p r7") + assert mock_exec_print.call_count == 1 + + args = mock_exec_print.call_args[0] + assert len(args) == 1 + assert args[0] == ["r7"] + + kwargs = mock_exec_print.call_args[1] + assert len(kwargs) == 0 + + def test_execute_quit(debugger): assert debugger.handle_command("quit") is False assert debugger.handle_command("q") is False +def test_execute_help(debugger, capsys): + should_continue = debugger.handle_command("help") + + assert should_continue + out = capsys.readouterr().out + assert "Available commands" in out + assert "Error:" not in out + + def test_execute_unknown_command(debugger, capsys): should_continue = debugger.handle_command("whatever")