Files
whetstone_DSL/editor/tests/step569_test.cpp

157 lines
6.6 KiB
C++
Raw Normal View History

// Step 569: Disassembly + Register View Baseline (12 tests)
#include "DisassemblyRegisterViewModel.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 DisassemblyInstruction inst(std::uint64_t address, const std::string& opcode, const std::string& operands) {
return {address, opcode, operands, false};
}
void test_set_instructions_success() {
TEST(set_instructions_success);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1000, "mov", "rax, rbx"), inst(0x1004, "ret", "")}, &error), "set should succeed");
CHECK(model.instructions().size() == 2, "instruction count mismatch");
PASS();
}
void test_set_instructions_rejects_empty() {
TEST(set_instructions_rejects_empty);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(!model.setInstructions({}, &error), "empty instruction list should fail");
CHECK(error == "instruction_list_empty", "wrong error");
PASS();
}
void test_set_instructions_rejects_invalid_address() {
TEST(set_instructions_rejects_invalid_address);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(!model.setInstructions({inst(0, "mov", "rax,rbx")}, &error), "zero address should fail");
CHECK(error == "instruction_address_invalid", "wrong error");
PASS();
}
void test_set_instructions_rejects_missing_opcode() {
TEST(set_instructions_rejects_missing_opcode);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(!model.setInstructions({inst(0x1000, "", "rax,rbx")}, &error), "missing opcode should fail");
CHECK(error == "instruction_opcode_missing", "wrong error");
PASS();
}
void test_instructions_are_sorted_by_address() {
TEST(instructions_are_sorted_by_address);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1010, "ret", ""), inst(0x1000, "push", "rbp")}, &error), "set should succeed");
CHECK(model.instructions()[0].address == 0x1000, "first instruction should be lowest address");
CHECK(model.instructions()[1].address == 0x1010, "second instruction should be highest address");
PASS();
}
void test_set_current_instruction_pointer_success() {
TEST(set_current_instruction_pointer_success);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1000, "nop", ""), inst(0x1001, "ret", "")}, &error), "set should succeed");
CHECK(model.setCurrentInstructionPointer(0x1001, &error), "set ip should succeed");
CHECK(!model.instructions()[0].isCurrentInstruction, "first instruction should not be current");
CHECK(model.instructions()[1].isCurrentInstruction, "second instruction should be current");
PASS();
}
void test_set_current_instruction_pointer_rejects_unknown_address() {
TEST(set_current_instruction_pointer_rejects_unknown_address);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1000, "nop", "")}, &error), "set should succeed");
CHECK(!model.setCurrentInstructionPointer(0x2000, &error), "unknown ip should fail");
CHECK(error == "instruction_pointer_not_found", "wrong error");
PASS();
}
void test_window_around_address_returns_radius_slice() {
TEST(window_around_address_returns_radius_slice);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1000, "a", ""), inst(0x1001, "b", ""), inst(0x1002, "c", ""), inst(0x1003, "d", "")}, &error), "set should succeed");
const auto window = model.windowAroundAddress(0x1001, 1);
CHECK(window.size() == 3, "window size mismatch");
CHECK(window[0].address == 0x1000, "window start mismatch");
CHECK(window[2].address == 0x1002, "window end mismatch");
PASS();
}
void test_window_around_unknown_address_is_empty() {
TEST(window_around_unknown_address_is_empty);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setInstructions({inst(0x1000, "a", "")}, &error), "set should succeed");
const auto window = model.windowAroundAddress(0x9999, 1);
CHECK(window.empty(), "window should be empty for unknown center");
PASS();
}
void test_set_register_value_success() {
TEST(set_register_value_success);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setRegisterValue("rax", 123, &error), "set register should succeed");
CHECK(model.hasRegister("rax"), "register should exist");
CHECK(model.registerValueOrZero("rax") == 123, "register value mismatch");
PASS();
}
void test_set_register_value_rejects_empty_name() {
TEST(set_register_value_rejects_empty_name);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(!model.setRegisterValue("", 123, &error), "empty register name should fail");
CHECK(error == "register_name_missing", "wrong error");
PASS();
}
void test_sorted_registers_order_by_name() {
TEST(sorted_registers_order_by_name);
DisassemblyRegisterViewModel model;
std::string error;
CHECK(model.setRegisterValue("rbx", 2, &error), "set rbx failed");
CHECK(model.setRegisterValue("rax", 1, &error), "set rax failed");
const auto regs = model.sortedRegisters();
CHECK(regs.size() == 2, "register count mismatch");
CHECK(regs[0].name == "rax", "register order mismatch");
CHECK(regs[1].name == "rbx", "register order mismatch");
PASS();
}
int main() {
std::cout << "Step 569: Disassembly + Register View Baseline\n";
test_set_instructions_success(); // 1
test_set_instructions_rejects_empty(); // 2
test_set_instructions_rejects_invalid_address(); // 3
test_set_instructions_rejects_missing_opcode(); // 4
test_instructions_are_sorted_by_address(); // 5
test_set_current_instruction_pointer_success(); // 6
test_set_current_instruction_pointer_rejects_unknown_address();// 7
test_window_around_address_returns_radius_slice(); // 8
test_window_around_unknown_address_is_empty(); // 9
test_set_register_value_success(); // 10
test_set_register_value_rejects_empty_name(); // 11
test_sorted_registers_order_by_name(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n";
return failed == 0 ? 0 : 1;
}