Files
whetstone_DSL/editor/tests/step556_test.cpp

155 lines
5.6 KiB
C++
Raw Normal View History

// Step 556: Step Engine (12 tests)
#include "StepEngine.h"
#include <iostream>
static int passed = 0, failed = 0;
#define TEST(name) { std::cout << " " << #name << "... "; }
#define PASS() { std::cout << "PASS\n"; ++passed; }
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
static bool hasDiag(const StepResult& r, const std::string& d) {
for (const auto& x : r.diagnostics) if (x == d) return true;
return false;
}
void test_step_over_advances_instruction_pointer() {
TEST(step_over_advances_instruction_pointer);
StepEngine e;
auto before = e.state().instructionPointer;
auto r = e.execute("step_over");
CHECK(r.ok, "step_over should succeed");
CHECK(r.state.instructionPointer == before + 1, "ip should advance by one");
PASS();
}
void test_step_into_advances_ip_and_stack_depth() {
TEST(step_into_advances_ip_and_stack_depth);
StepEngine e;
auto r = e.execute("step_into");
CHECK(r.ok, "step_into should succeed");
CHECK(r.state.instructionPointer == 1, "ip should advance");
CHECK(r.state.stackDepth == 2, "stack depth should increase");
PASS();
}
void test_step_out_reduces_stack_depth_when_nested() {
TEST(step_out_reduces_stack_depth_when_nested);
StepEngine e;
CHECK(e.execute("step_into").ok, "step_into should nest");
auto r = e.execute("step_out");
CHECK(r.ok, "step_out should succeed");
CHECK(r.state.stackDepth == 1, "stack should reduce");
PASS();
}
void test_step_out_from_root_completes_session() {
TEST(step_out_from_root_completes_session);
StepEngine e;
auto r = e.execute("step_out");
CHECK(r.ok, "step_out root should succeed");
CHECK(r.state.runState == DebugRunState::Completed, "session should complete");
CHECK(hasDiag(r, "session_completed"), "completion diag expected");
PASS();
}
void test_continue_runs_and_pauses_deterministically() {
TEST(continue_runs_and_pauses_deterministically);
StepEngine e;
auto before = e.state().instructionPointer;
auto r = e.execute("continue");
CHECK(r.ok, "continue should succeed");
CHECK(r.state.runState == DebugRunState::Paused, "engine should return to paused state");
CHECK(r.state.instructionPointer == before + 5, "continue should advance by deterministic burst");
PASS();
}
void test_unknown_command_fails() {
TEST(unknown_command_fails);
StepEngine e;
auto r = e.execute("teleport");
CHECK(!r.ok, "unknown command should fail");
CHECK(hasDiag(r, "unknown_command"), "unknown command diag expected");
PASS();
}
void test_pause_keeps_engine_paused() {
TEST(pause_keeps_engine_paused);
StepEngine e;
CHECK(e.pause(), "pause should succeed");
CHECK(e.state().runState == DebugRunState::Paused, "engine should remain paused");
PASS();
}
void test_commands_fail_after_completion() {
TEST(commands_fail_after_completion);
StepEngine e;
CHECK(e.execute("step_out").ok, "root step_out completes session");
auto r = e.execute("step_over");
CHECK(!r.ok, "commands should fail after completion");
CHECK(hasDiag(r, "session_completed"), "completion diag expected");
PASS();
}
void test_last_command_tracks_step_actions() {
TEST(last_command_tracks_step_actions);
StepEngine e;
CHECK(e.execute("step_into").ok, "step_into should succeed");
CHECK(e.state().lastCommand == "step_into", "last command mismatch");
CHECK(e.execute("step_over").ok, "step_over should succeed");
CHECK(e.state().lastCommand == "step_over", "last command mismatch");
PASS();
}
void test_continue_updates_last_command() {
TEST(continue_updates_last_command);
StepEngine e;
CHECK(e.execute("continue").ok, "continue should succeed");
CHECK(e.state().lastCommand == "continue", "last command should be continue");
PASS();
}
void test_multiple_step_into_accumulates_stack_depth() {
TEST(multiple_step_into_accumulates_stack_depth);
StepEngine e;
CHECK(e.execute("step_into").ok, "step_into #1");
CHECK(e.execute("step_into").ok, "step_into #2");
CHECK(e.state().stackDepth == 3, "stack depth should accumulate");
PASS();
}
void test_instruction_pointer_progression_is_monotonic() {
TEST(instruction_pointer_progression_is_monotonic);
StepEngine e;
CHECK(e.execute("step_over").ok, "step_over");
int a = e.state().instructionPointer;
CHECK(e.execute("step_into").ok, "step_into");
int b = e.state().instructionPointer;
CHECK(e.execute("continue").ok, "continue");
int c = e.state().instructionPointer;
CHECK(a < b && b < c, "ip progression should be monotonic");
PASS();
}
int main() {
std::cout << "Step 556: Step Engine\n";
test_step_over_advances_instruction_pointer(); // 1
test_step_into_advances_ip_and_stack_depth(); // 2
test_step_out_reduces_stack_depth_when_nested(); // 3
test_step_out_from_root_completes_session(); // 4
test_continue_runs_and_pauses_deterministically(); // 5
test_unknown_command_fails(); // 6
test_pause_keeps_engine_paused(); // 7
test_commands_fail_after_completion(); // 8
test_last_command_tracks_step_actions(); // 9
test_continue_updates_last_command(); // 10
test_multiple_step_into_accumulates_stack_depth(); // 11
test_instruction_pointer_progression_is_monotonic(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n";
return failed == 0 ? 0 : 1;
}