use asmachina::{MachineW, MachineError};
#[test]
fn test_debugger_breakpoint_functionality() {
let mut machine = MachineW::new();
let program = vec![
(0b00100 << 11) | 10, (0b00001 << 11) | 11, (0b00111 << 11) | 0, 0, 0, 0, 0, 0, 0, 0, 25, 17, ];
assert!(machine.load_program(&program).is_ok());
machine.is_running = true;
assert!(machine.add_breakpoint(1).is_ok());
assert!(machine.has_breakpoint(1));
let result = machine.run_until_halt_or_breakpoint();
assert!(matches!(result, Err(MachineError::BreakpointHit { address: 1 })));
assert_eq!(machine.l, 1); assert_eq!(machine.ak, 25);
assert!(machine.step().is_ok());
assert_eq!(machine.l, 2); assert_eq!(machine.ak, 42);
assert!(machine.run_until_halt_or_breakpoint().is_ok());
assert_eq!(machine.is_running, false); }
#[test]
fn test_debugger_state_inspection() {
let mut machine = MachineW::new();
machine.ak = 0x1234;
machine.l = 0x10;
machine.ws = 2000;
machine.memory[0x10] = 0x5678;
machine.memory[0x11] = 0x9ABC;
let state = machine.get_current_state();
assert_eq!(state.ak, 0x1234);
assert_eq!(state.l, 0x10);
assert_eq!(state.ws, 2000);
let memory_range = machine.get_memory_range(0x10, 0x11);
assert!(memory_range.is_some());
let range = memory_range.unwrap();
assert_eq!(range.len(), 2);
assert_eq!(range[0], (0x10, 0x5678)); assert_eq!(range[1], (0x11, 0x9ABC));
}
#[test]
fn test_debugger_breakpoint_management() {
let mut machine = MachineW::new();
assert!(machine.add_breakpoint(10).is_ok());
assert!(machine.add_breakpoint(20).is_ok());
assert!(machine.add_breakpoint(30).is_ok());
assert!(machine.has_breakpoint(10));
assert!(machine.has_breakpoint(20));
assert!(machine.has_breakpoint(30));
assert!(!machine.has_breakpoint(40));
let breakpoints = machine.list_breakpoints();
assert_eq!(breakpoints.len(), 3);
assert!(breakpoints.contains(&10));
assert!(breakpoints.contains(&20));
assert!(breakpoints.contains(&30));
machine.remove_breakpoint(20);
assert!(!machine.has_breakpoint(20));
assert_eq!(machine.list_breakpoints().len(), 2);
machine.clear_all_breakpoints();
assert_eq!(machine.list_breakpoints().len(), 0);
}
#[test]
fn test_debugger_step_instruction() {
let mut machine = MachineW::new();
machine.memory[0] = (0b00001 << 11) | 10; machine.memory[1] = (0b00011 << 11) | 11; machine.memory[2] = (0b00111 << 11) | 0; machine.memory[10] = 15;
machine.l = 0;
machine.ak = 5;
machine.is_running = true;
assert!(machine.step_instruction().is_ok());
assert_eq!(machine.l, 1);
assert_eq!(machine.ak, 20);
assert!(machine.step_instruction().is_ok());
assert_eq!(machine.l, 2);
assert_eq!(machine.memory[11], 20);
assert!(machine.step_instruction().is_ok());
assert_eq!(machine.l, 3);
assert_eq!(machine.is_running, false);
}
#[test]
fn test_debugger_run_until_breakpoint_with_multiple_breakpoints() {
let mut machine = MachineW::new();
machine.memory[0] = (0b00001 << 11) | 10; machine.memory[1] = (0b00101 << 11) | 3; machine.memory[2] = (0b00111 << 11) | 0; machine.memory[3] = (0b00001 << 11) | 11; machine.memory[4] = (0b00111 << 11) | 0; machine.memory[10] = 5;
machine.memory[11] = 10;
machine.l = 0;
machine.ak = 0;
machine.is_running = true;
assert!(machine.add_breakpoint(1).is_ok()); assert!(machine.add_breakpoint(3).is_ok());
let result = machine.run_until_halt_or_breakpoint();
assert!(matches!(result, Err(MachineError::BreakpointHit { address: 1 })));
assert_eq!(machine.l, 1);
assert_eq!(machine.ak, 5);
assert!(machine.step().is_ok());
assert_eq!(machine.l, 3); assert_eq!(machine.ak, 5);
let result = machine.run_until_halt_or_breakpoint();
assert!(matches!(result, Err(MachineError::BreakpointHit { address: 3 })));
assert_eq!(machine.l, 3);
assert_eq!(machine.ak, 5);
assert!(machine.step().is_ok());
assert_eq!(machine.l, 4); assert_eq!(machine.ak, 15);
let result = machine.run_until_halt_or_breakpoint();
assert!(result.is_ok());
assert_eq!(machine.is_running, false);
assert_eq!(machine.ak, 15); }
#[test]
fn test_breakpoint_hit_at_exact_address() {
let mut machine = MachineW::new();
machine.memory[0] = (0b00001 << 11) | 10; machine.memory[1] = (0b00001 << 11) | 11; machine.memory[2] = (0b00111 << 11) | 0; machine.memory[10] = 5;
machine.memory[11] = 7;
assert!(machine.add_breakpoint(1).is_ok());
machine.l = 0;
machine.ak = 0;
machine.is_running = true;
let result = machine.run_until_halt_or_breakpoint();
assert!(matches!(result, Err(MachineError::BreakpointHit { address: 1 })));
assert_eq!(machine.l, 1); }
#[test]
fn test_memory_range_retrieval() {
let mut machine = MachineW::new();
for i in 0..20 {
machine.memory[i] = (i * 2) as u16;
}
let range = machine.get_memory_range(5, 10);
assert!(range.is_some());
let range = range.unwrap();
assert_eq!(range.len(), 6); assert_eq!(range[0], (5, 10)); assert_eq!(range[1], (6, 12)); assert_eq!(range[5], (10, 20)); }
#[test]
fn test_debugger_state_snapshot() {
let mut machine = MachineW::new();
machine.ak = 0xABCD;
machine.l = 0x123;
machine.ad = 0x456;
machine.kod = 0x7;
machine.ws = 1500;
let state = machine.get_current_state();
assert_eq!(state.ak, 0xABCD);
assert_eq!(state.l, 0x123);
assert_eq!(state.ad, 0x456);
assert_eq!(state.kod, 0x7);
assert_eq!(state.ws, 1500);
assert_eq!(state.is_running, false); }