def test_do_width_with_bad_arg_shows_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_width('bad') out = stdout.getvalue() expected = "Illegal width: bad\nTerminal width is 78\n" self.assertEqual(expected, out)
def test_do_tilde(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_tilde('$10') out = stdout.getvalue() expected = "+16\n$10\n0020\n00010000\n" self.assertTrue(out.startswith(expected))
def test_do_assemble_shows_bad_syntax_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('c000 foo') out = stdout.getvalue() self.assertEqual("Syntax error: foo\n", out)
def test_goto_without_breakpoints_stops_execution_at_brk(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._breakpoints = [] mon._mpu.memory = [ 0xEA, 0xEA, 0x00, 0xEA ] mon.do_goto('0') self.assertEqual(0x02, mon._mpu.pc)
def test_help_assemble(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.help_assemble() out = stdout.getvalue() self.assertTrue("assemble <address>" in out)
def test_do_assemble_passes_addr_for_relative_branch_calc(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('4000 bvs $4005') out = stdout.getvalue() self.assertEqual("$4000 70 03 BVS $4005\n", out)
def test_help_cycles(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.help_cycles() out = stdout.getvalue() self.assertTrue(out.startswith("Display the total number of cycles"))
def test_do_cd_with_no_dir_shows_help(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_cd("") out = stdout.getvalue() self.assertTrue(out.startswith("cd <directory>"))
def test_shortcut_for_add_label(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_help('al') out = stdout.getvalue() self.assertTrue(out.startswith('add_label'))
def test_shortcut_for_disassemble(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_help('d') out = stdout.getvalue() self.assertTrue(out.startswith('disassemble'))
def test_registers_a_overflow(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_registers('a=100') out = stdout.getvalue() expected = "Overflow: '100' too wide for register 'a'" self.assertTrue(out.startswith(expected))
def test_registers_updates_single_register(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_registers('x=42') out = stdout.getvalue() self.assertEqual("", out) self.assertEqual(0x42, mon._mpu.x)
def test_do_add_label_syntax_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_add_label('should be label space value') out = stdout.getvalue() err = "Syntax error: should be label space value\n" self.assertTrue(out.startswith(err))
def test_shortcut_for_step(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_help('z') out = stdout.getvalue() self.assertTrue(out.startswith('step'))
def test_tilde_shortcut_without_space_for_vice_compatibility(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.onecmd('~$10') out = stdout.getvalue() expected = "+16\n$10\n0020\n00010000\n" self.assertTrue(out.startswith(expected))
def test_do_assemble_shows_bad_label_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('nonexistant rts') out = stdout.getvalue() self.assertEqual("Bad label: nonexistant rts\n", out)
def test_shortcut_for_registers(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_help('r') out = stdout.getvalue() self.assertTrue(out.startswith('registers'))
def test_help_fill(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.help_fill() out = stdout.getvalue() self.assertTrue(out.startswith('fill <address_range>'))
def test_pwd_shows_os_getcwd(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_pwd() out = stdout.getvalue() self.assertEqual("%s\n" % os.getcwd(), out)
def test_do_cycles_shows_zero_initially(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_cycles("") out = stdout.getvalue() self.assertEqual(out, "0\n")
def test_do_add_breakpoint_adds_number(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_add_breakpoint('ffd2') out = stdout.getvalue() self.assertTrue(out.startswith("Breakpoint 0 added at $FFD2")) self.assertTrue(0xffd2 in mon._breakpoints)
def test_do_cd_with_bad_dir_shows_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_cd("/path/to/a/nonexistant/directory") out = stdout.getvalue() self.assertTrue(out.startswith("Cannot change directory"))
def test_do_mem_shows_help_when_given_extra_args(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_mem('c000 c001') out = stdout.getvalue() self.assertTrue(out.startswith('mem <address_range>'))
def test_help_cd(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.help_cd() out = stdout.getvalue() self.assertTrue(out.startswith("cd <directory>"))
def test_shortcut_for_mem(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_help('m') out = stdout.getvalue() self.assertTrue(out.startswith('mem <address_range>'))
def test_do_assemble_constrains_address_to_valid_range(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble("-1 lda #$ab") out = stdout.getvalue() self.assertEqual("Overflow error: -1 lda #$ab\n", out)
def test_show_breakpoints_ignores_deleted_breakpoints(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._breakpoints = [None, 0xffd2] mon.do_show_breakpoints('') out = stdout.getvalue() self.assertTrue(out.startswith("Breakpoint 1: $FFD2"))
def test_do_assemble_shows_overflow_error(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('c000 lda #$fff') out = stdout.getvalue() self.assertEqual("Overflow error: c000 lda #$fff\n", out)
def test_do_fill_with_no_args_shows_help(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_fill('') out = stdout.getvalue() self.assertTrue(out.startswith('fill <address_range>'))
def test_do_assemble_outputs_disassembly(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('c000 lda #$ab') out = stdout.getvalue() self.assertEqual("$c000 a9 ab LDA #$ab\n", out)
def test_do_mem_shows_memory_for_a_single_address(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xC000] = 0xAA mon.do_mem('c000') out = stdout.getvalue() self.assertEqual('c000: aa\n', out)
def test_do_delete_label_with_delete_label(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._address_parser.labels['foo'] = 0xc000 mon.do_delete_label('foo') self.assertFalse('foo' in mon._address_parser.labels) out = stdout.getvalue() self.assertEqual('', out)
def test_do_assemble_assembles_valid_statement(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_assemble('c000 lda #$ab') mpu = mon._mpu self.assertEqual(0xA9, mpu.memory[0xC000]) self.assertEqual(0xAB, mpu.memory[0xC001])
def test_show_breakpoints_shows_breakpoints(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._breakpoints = [0xffd2] mon._address_parser.labels = {'chrout': 0xffd2} mon.do_show_breakpoints('') out = stdout.getvalue() self.assertTrue(out.startswith("Breakpoint 0: $FFD2 chrout"))
def test_mpu_with_bad_arg_gives_error_lists_available_mpus(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_mpu('z80') lines = stdout.getvalue().splitlines() self.assertEqual(2, len(lines)) self.assertEqual('Unknown MPU: z80', lines[0]) self.assertTrue(lines[1].startswith('Available MPUs:'))
def test_mpu_selects_65C02(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_mpu('65C02') lines = stdout.getvalue().splitlines() self.assertEqual(1, len(lines)) self.assertEqual('Reset with new MPU 65C02', lines[0]) self.assertEqual('65C02', mon._mpu.name)
def test_mpu_with_no_args_prints_current_lists_available_mpus(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_mpu('') lines = stdout.getvalue().splitlines() self.assertEqual(2, len(lines)) self.assertTrue(lines[0].startswith('Current MPU is ')) self.assertTrue(lines[1].startswith('Available MPUs:'))
def test_do_cycles_shows_count_after_step(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0x0000] = 0xEA # => NOP (2 cycles) mon._mpu.step() mon.do_cycles("") out = stdout.getvalue() self.assertEqual(out, "2\n")
def test_do_fill_will_fill_one_address(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xc000] = 0x00 mon.do_fill('c000 aa') self.assertEqual(0xAA, mon._mpu.memory[0xc000]) out = stdout.getvalue() self.assertTrue(out.startswith('Wrote +1 bytes from $c000 to $c000'))
def test_do_mem_wraps_at_terminal_width(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._width = 14 mon.do_mem('c000:c003') out = stdout.getvalue() self.assertEqual('c000: 00 00\n' 'c002: 00 00\n', out)
def test_do_cd_changes_cwd(self): stdout = StringIO() mon = Monitor(stdout=stdout) here = os.path.abspath(os.path.dirname(__file__)) mon.do_cd(here) out = stdout.getvalue() self.assertTrue(out.startswith(here)) self.assertEqual(here, os.getcwd())
def test_goto_with_breakpoints_stops_execution_at_breakpoint(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._breakpoints = [ 0x03 ] mon._mpu.memory = [ 0xEA, 0xEA, 0xEA, 0xEA ] mon.do_goto('0') out = stdout.getvalue() self.assertTrue(out.startswith("Breakpoint 0 reached")) self.assertEqual(0x03, mon._mpu.pc)
def test_do_add_breakpoint_adds_label(self): stdout = StringIO() mon = Monitor(stdout=stdout) address_parser = mon._address_parser address_parser.labels['chrout'] = 0xffd2 mon.do_add_breakpoint('chrout') out = stdout.getvalue() self.assertTrue(out.startswith("Breakpoint 0 added at $FFD2")) self.assertTrue(0xffd2 in mon._breakpoints)
def test_do_mem_shows_memory_for_an_address_range(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xC000] = 0xAA mon._mpu.memory[0xC001] = 0xBB mon._mpu.memory[0xC002] = 0xCC mon.do_mem('c000:c002') out = stdout.getvalue() self.assertEqual('c000: aa bb cc\n', out)
def test_help_mpu(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.help_mpu() lines = stdout.getvalue().splitlines() self.assertEqual("mpu\t\tPrint available microprocessors.", lines[0]) self.assertEqual("mpu <type>\tSelect a new microprocessor.", lines[1])
def test_disassemble_will_disassemble_one_address(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xc000] = 0xEA # => NOP mon._mpu.step() mon.do_disassemble("c000") out = stdout.getvalue() disasm = "$c000 ea NOP\n" self.assertEqual(out, disasm)
def test_disassemble_wraps_an_instruction_around_memory(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xffff] = 0x20 # => JSR mon._mpu.memory[0x0000] = 0xD2 # mon._mpu.memory[0x0001] = 0xFF # => $FFD2 mon.do_disassemble("ffff") out = stdout.getvalue() disasm = "$ffff 20 d2 ff JSR $ffd2\n" self.assertEqual(out, disasm)
def test_registers_updates_all_registers(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon.do_registers('a=42,x=43,y=44,p=45, sp=46, pc=4600') out = stdout.getvalue() self.assertEqual("", out) self.assertEqual(0x42, mon._mpu.a) self.assertEqual(0x43, mon._mpu.x) self.assertEqual(0x44, mon._mpu.y) self.assertEqual(0x45, mon._mpu.p) self.assertEqual(0x46, mon._mpu.sp) self.assertEqual(0x4600, mon._mpu.pc)
def test_load(self): stdout = StringIO() mon = Monitor(stdout=stdout) f = tempfile.NamedTemporaryFile() f.write(b'\xaa\xbb\xcc') f.flush() mon.do_load("'%s' a600" % f.name) self.assertEqual([0xAA, 0xBB, 0xCC], mon._mpu.memory[0xA600:0xA603]) self.assertEqual('Wrote +3 bytes from $a600 to $a602\n', stdout.getvalue()) f.close()
def test_save(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0:3] = [0xAA, 0xBB, 0xCC] f = tempfile.NamedTemporaryFile() mon.do_save("'%s' 0 2" % f.name) f.seek(0) self.assertEqual(b'\xaa\xbb\xcc', f.read()) self.assertEqual('Saved +3 bytes to %s\n' % f.name, stdout.getvalue()) f.close()
def test_do_fill_will_fill_an_address_range_with_a_single_byte(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xc000] = 0x00 mon._mpu.memory[0xc001] = 0x00 mon._mpu.memory[0xc002] = 0x00 mon.do_fill('c000:c001 aa') self.assertEqual(0xAA, mon._mpu.memory[0xc000]) self.assertEqual(0xAA, mon._mpu.memory[0xc001]) self.assertEqual(0x00, mon._mpu.memory[0xc002]) out = stdout.getvalue() self.assertTrue(out.startswith('Wrote +2 bytes from $c000 to $c001'))
def test_do_fill_will_fill_an_address_range_with_byte_sequence(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xc000] = 0x00 mon._mpu.memory[0xc001] = 0x00 mon._mpu.memory[0xc002] = 0x00 mon._mpu.memory[0xc003] = 0x00 mon.do_fill('c000:c003 aa bb') self.assertEqual(0xAA, mon._mpu.memory[0xc000]) self.assertEqual(0xBB, mon._mpu.memory[0xc001]) self.assertEqual(0xAA, mon._mpu.memory[0xc002]) self.assertEqual(0xBB, mon._mpu.memory[0xc003]) out = stdout.getvalue() self.assertTrue(out.startswith('Wrote +4 bytes from $c000 to $c003'))
def test_argv_input(self): argv = ['py65mon', '--input', 'abcd'] stdout = StringIO() mon = Monitor(argv=argv, stdout=stdout) read_subscribers = mon._mpu.memory._read_subscribers self.assertEqual(1, len(read_subscribers)) self.assertTrue('getc' in repr(read_subscribers[0xabcd]))
def test_argv_output(self): argv = ['py65mon', '--output', 'dcba'] stdout = StringIO() mon = Monitor(argv=argv, stdout=stdout) write_subscribers = mon._mpu.memory._write_subscribers self.assertEqual(1, len(write_subscribers)) self.assertTrue('putc' in repr(write_subscribers[0xdcba]))
def test_disassemble_wraps_disassembly_list_around_memory(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0xffff] = 0x20 # => JSR mon._mpu.memory[0x0000] = 0xD2 mon._mpu.memory[0x0001] = 0xFF # => $FFD2 mon._mpu.memory[0x0002] = 0x20 # => JSR mon._mpu.memory[0x0003] = 0xE4 mon._mpu.memory[0x0004] = 0xFF # => $FFE4 mon._mpu.memory[0x0005] = 0xEA # => NOP mon.do_disassemble("ffff:5") out = stdout.getvalue() disasm = ("$ffff 20 d2 ff JSR $ffd2\n" "$0002 20 e4 ff JSR $ffe4\n" "$0005 ea NOP\n") self.assertEqual(out, disasm)
def test_argv_mpu_invalid(self): argv = ['py65mon', '--mpu', 'bad'] stdout = StringIO() try: Monitor(argv=argv, stdout=stdout) except SystemExit as exc: self.assertEqual(1, exc.code) self.assertTrue("Fatal: no such MPU." in stdout.getvalue())
def test_load(self): stdout = StringIO() mon = Monitor(stdout=stdout) filename = tempfile.mktemp() try: f = open(filename, 'wb') f.write(chr(0xAA) + chr(0xBB) + chr(0xCC)) f.close() mon.do_load("'%s' a600" % filename) self.assertEqual('Wrote +3 bytes from $a600 to $a602\n', stdout.getvalue()) self.assertEqual([0xAA, 0xBB, 0xCC], mon._mpu.memory[0xA600:0xA603]) finally: os.unlink(filename)
def test_save(self): stdout = StringIO() mon = Monitor(stdout=stdout) mon._mpu.memory[0:3] = [0xAA, 0xBB, 0xCC] filename = tempfile.mktemp() try: mon.do_save("'%s' 0 2" % filename) self.assertEqual('Saved +3 bytes to %s\n' % filename, stdout.getvalue()) f = open(filename, 'rb') contents = f.read() f.close() self.assertEqual(b'\xaa\xbb\xcc', contents) finally: os.unlink(filename)
def test_argv_goto(self): argv = ['py65mon', '--goto', 'c000'] stdout = StringIO() memory = bytearray(0x10000) memory[0xc000] = 0xea # c000 nop memory[0xc001] = 0xea # c001 nop memory[0xc002] = 0x00 # c002 brk mon = Monitor(argv=argv, stdout=stdout, memory=memory) self.assertEqual(0xc002, mon._mpu.pc)
def test_argv_load(self): with tempfile.NamedTemporaryFile('wb+') as f: data = bytearray([0xab, 0xcd]) f.write(data) f.flush() argv = ['py65mon', '--load', f.name] stdout = StringIO() mon = Monitor(argv=argv, stdout=stdout) self.assertEqual(list(data), mon._mpu.memory[:len(data)])