1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/// Test: REPL-008-002-005 - Next with call depth tracking
///
/// RED Phase: This test will FAIL because next() method doesn't exist yet
/// Note: Simplified version - just verify call_depth() accessor exists
#[test]
fn test_REPL_008_002_call_depth_accessor() {
// ARRANGE
let script = "echo test";
let session = DebugSession::new(script);
// ACT & ASSERT: Verify call_depth() method exists
// Initial depth should be 1 (main frame)
assert_eq!(
session.call_depth(),
1,
"Initial call depth should be 1 (main frame)"
);
}
// ===== REPL-008-003: CONTINUE EXECUTION TESTS =====
/// Test: REPL-008-003-001 - Continue to breakpoint
#[test]
fn test_REPL_008_003_continue_to_breakpoint() {
let script = "echo line1\necho line2\necho line3\necho line4";
let mut session = DebugSession::new(script);
// Set breakpoint at line 3
session.set_breakpoint(3);
// Continue execution - should stop at line 3
let result = session.continue_execution();
assert_eq!(
result,
ContinueResult::BreakpointHit(3),
"Should stop at breakpoint on line 3"
);
assert_eq!(session.current_line(), 3, "Current line should be 3");
}
/// Test: REPL-008-003-002 - Continue to end (no breakpoints)
#[test]
fn test_REPL_008_003_continue_to_end() {
let script = "echo line1\necho line2\necho line3";
let mut session = DebugSession::new(script);
// No breakpoints - should run to completion
let result = session.continue_execution();
assert_eq!(
result,
ContinueResult::Finished,
"Should finish execution without breakpoints"
);
assert!(session.is_finished(), "Session should be finished");
}
/// Test: REPL-008-003-003 - Continue past first breakpoint
#[test]
fn test_REPL_008_003_continue_multiple_breakpoints() {
let script = "echo line1\necho line2\necho line3\necho line4\necho line5";
let mut session = DebugSession::new(script);
// Set breakpoints at lines 2 and 4
session.set_breakpoint(2);
session.set_breakpoint(4);
// First continue - stop at line 2
let result1 = session.continue_execution();
assert_eq!(result1, ContinueResult::BreakpointHit(2));
assert_eq!(session.current_line(), 2);
// Step over the breakpoint
session.step();
// Second continue - stop at line 4
let result2 = session.continue_execution();
assert_eq!(result2, ContinueResult::BreakpointHit(4));
assert_eq!(session.current_line(), 4);
}
/// Test: REPL-008-003-004 - Continue when already at breakpoint
#[test]
fn test_REPL_008_003_continue_at_breakpoint() {
let script = "echo line1\necho line2\necho line3";
let mut session = DebugSession::new(script);
// Set breakpoint at line 1 (starting position)
session.set_breakpoint(1);
// Continue should immediately return (already at breakpoint)
let result = session.continue_execution();
assert_eq!(
result,
ContinueResult::BreakpointHit(1),
"Should detect we're already at breakpoint"
);
assert_eq!(session.current_line(), 1);
}
/// Test: REPL-008-003-005 - Continue from middle of script
#[test]
fn test_REPL_008_003_continue_from_middle() {
let script = "echo line1\necho line2\necho line3\necho line4";
let mut session = DebugSession::new(script);
// Step to line 2
session.step();
assert_eq!(session.current_line(), 2);
// Set breakpoint at line 4
session.set_breakpoint(4);
// Continue from line 2 to line 4
let result = session.continue_execution();
assert_eq!(result, ContinueResult::BreakpointHit(4));
assert_eq!(session.current_line(), 4);
}
/// Test: REPL-008-003-006 - Continue past last breakpoint to end
#[test]
fn test_REPL_008_003_continue_past_breakpoint_to_end() {
let script = "echo line1\necho line2\necho line3";
let mut session = DebugSession::new(script);
// Set breakpoint at line 2
session.set_breakpoint(2);
// First continue - stop at breakpoint
assert_eq!(
session.continue_execution(),
ContinueResult::BreakpointHit(2)
);
// Step past breakpoint
session.step();
// Second continue - run to end
assert_eq!(session.continue_execution(), ContinueResult::Finished);
assert!(session.is_finished());
}
// ===== REPL-008-004: FINISH (EXIT CURRENT FUNCTION) TESTS =====
/// Test: REPL-008-004-001 - Finish returns from simulated function
///
/// RED phase: Test finish() with manual call stack manipulation
#[test]
fn test_REPL_008_004_finish_returns_from_function() {
// ARRANGE: Script with multiple lines
let script = "echo line1\necho line2\necho line3\necho line4";
let mut session = DebugSession::new(script);
// Simulate entering a function by pushing a frame
session.push_frame("test_function", 2);
// Current depth should be 2 (<main> + test_function)
assert_eq!(session.call_depth(), 2);
// ACT: Call finish() to exit function
let result = session.finish();
// ASSERT: Should have returned from function
// (In simplified version, this will just continue to end or breakpoint)
assert!(matches!(result, ContinueResult::Finished));
}
/// Test: REPL-008-004-002 - Finish at top level continues to end
///
/// RED phase: Test finish() when already at <main> level
#[test]
fn test_REPL_008_004_finish_at_top_level() {
// ARRANGE: Script with no functions (depth 1 - main only)
let script = "echo line1\necho line2\necho line3";
let mut session = DebugSession::new(script);
// At line 1, depth 1 (<main> only)
assert_eq!(session.call_depth(), 1);
// ACT: Call finish() at top level
let result = session.finish();
// ASSERT: Should continue to end (behaves like continue)
assert!(matches!(result, ContinueResult::Finished));
assert!(session.is_finished());
}
/// Test: REPL-008-004-003 - Finish stops at breakpoint
///
/// RED phase: Test that finish() respects breakpoints
#[test]
fn test_REPL_008_004_finish_stops_at_breakpoint() {
// ARRANGE: Script with breakpoint
let script = "echo line1\necho line2\necho line3\necho line4";
let mut session = DebugSession::new(script);
// Set breakpoint on line 3
session.set_breakpoint(3);
// Simulate entering a function
session.push_frame("test_function", 1);
// ACT: Call finish() - should stop at breakpoint before returning
let result = session.finish();
// ASSERT: Should hit breakpoint
assert!(matches!(result, ContinueResult::BreakpointHit(3)));
assert!(!session.is_finished());
}
include!("debugger_tests_extracted_cont_tests_repl_008.rs");