Files
whetstone_DSL/editor/tests/step453_test.cpp

143 lines
6.1 KiB
C++

// Step 453: Memory Model Translation Tests (12 tests)
#include "MemoryModelTranslator.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 {}
void test_manual_c_to_rust_gains_safety() {
TEST(manual_c_to_rust_gains_safety);
auto r = MemoryModelTranslator::analyze("p = malloc(8); free(p);", "c", "rust");
CHECK(r.hasPattern("@Owner(Manual)"), "expected manual pattern");
CHECK(r.translations[0].safetyChange == SafetyDelta::Gained, "manual->rust should gain safety");
CHECK(r.translations[0].annotation.find("@Risk(lowered)") != std::string::npos,
"expected lowered risk annotation");
PASS();
}
void test_manual_c_to_java_gains_gc_safety() {
TEST(manual_c_to_java_gains_gc_safety);
auto r = MemoryModelTranslator::analyze("p = malloc(8); free(p);", "c", "java");
CHECK(r.hasPattern("@Owner(Manual)"), "expected manual pattern");
CHECK(r.translations[0].safetyChange == SafetyDelta::Gained, "manual->java should gain safety");
CHECK(r.translations[0].annotation.find("@Owner(GC)") != std::string::npos,
"expected GC owner annotation");
PASS();
}
void test_unique_cpp_to_c_loses_safety() {
TEST(unique_cpp_to_c_loses_safety);
auto r = MemoryModelTranslator::analyze("std::unique_ptr<Foo> p;", "cpp", "c");
CHECK(r.hasPattern("@Owner(Unique)"), "expected unique ownership pattern");
CHECK(r.translations[0].safetyChange == SafetyDelta::Lost, "unique->C should lose safety");
CHECK(r.translations[0].annotation.find("@Risk(high)") != std::string::npos,
"expected high risk annotation");
PASS();
}
void test_shared_cpp_to_rust_arc_mapping() {
TEST(shared_cpp_to_rust_arc_mapping);
auto r = MemoryModelTranslator::analyze("std::shared_ptr<Foo> p;", "cpp", "rust");
CHECK(r.hasPattern("@Owner(Shared_ARC)"), "expected shared ownership pattern");
CHECK(r.translations[0].targetCode.find("Arc::new") != std::string::npos,
"expected Arc mapping");
CHECK(r.translations[0].safetyChange == SafetyDelta::Neutral, "shared->shared should be neutral");
PASS();
}
void test_shared_rust_to_c_loses_safety() {
TEST(shared_rust_to_c_loses_safety);
auto r = MemoryModelTranslator::analyze("let p: Arc<Foo> = Arc::new(v);", "rust", "c");
CHECK(r.hasPattern("@Owner(Shared_ARC)"), "expected shared ownership pattern");
CHECK(r.translations[0].safetyChange == SafetyDelta::Lost, "shared->C should lose safety");
CHECK(r.translations[0].annotation.find("@Risk(high)") != std::string::npos,
"expected high risk annotation");
PASS();
}
void test_scope_lifetime_to_go_defer() {
TEST(scope_lifetime_to_go_defer);
auto r = MemoryModelTranslator::analyze("with open(path) as f: data = f.read()", "python", "go");
CHECK(r.hasPattern("@Lifetime(Scope)"), "expected scope lifetime pattern");
CHECK(r.translations[0].annotation.find("@Lifetime(deferred)") != std::string::npos,
"expected deferred lifetime annotation");
PASS();
}
void test_scope_to_c_loses_scope_guarantee() {
TEST(scope_to_c_loses_scope_guarantee);
auto r = MemoryModelTranslator::analyze("with resource_manager() as r: use(r)", "python", "c");
CHECK(r.hasPattern("@Lifetime(Scope)"), "expected scope pattern");
CHECK(r.translations[0].safetyChange == SafetyDelta::Lost, "scope->C should lose guarantee");
CHECK(r.translations[0].annotation.find("@Risk(medium)") != std::string::npos,
"expected medium risk annotation");
PASS();
}
void test_detect_source_model_rust_borrowchecked() {
TEST(detect_source_model_rust_borrowchecked);
auto r = MemoryModelTranslator::analyze("let x = Box::new(1);", "rust", "cpp");
CHECK(r.sourceModel == OwnershipModel::BorrowChecked, "rust source should be borrow-checked");
PASS();
}
void test_detect_target_model_java_gc() {
TEST(detect_target_model_java_gc);
auto r = MemoryModelTranslator::analyze("int* p = malloc(8);", "c", "java");
CHECK(r.targetModel == OwnershipModel::GC, "java target should use GC model");
PASS();
}
void test_no_pattern_on_plain_code() {
TEST(no_pattern_on_plain_code);
auto r = MemoryModelTranslator::analyze("x = a + b;", "python", "rust");
CHECK(r.translations.empty(), "plain code should not emit memory translations");
PASS();
}
void test_safety_gain_count_for_manual_migration() {
TEST(safety_gain_count_for_manual_migration);
auto r = MemoryModelTranslator::analyze("p = malloc(8); free(p);", "c", "rust");
CHECK(r.countSafetyGained() >= 1, "expected at least one safety gain");
CHECK(r.countSafetyLost() == 0, "manual->rust should not lose safety");
PASS();
}
void test_mixed_patterns_report_gain_and_loss() {
TEST(mixed_patterns_report_gain_and_loss);
auto r = MemoryModelTranslator::analyze(
"std::unique_ptr<Foo> p; q = malloc(8); free(q);",
"cpp",
"c");
CHECK(r.translations.size() >= 2, "expected unique + manual translations");
CHECK(r.countSafetyLost() >= 1, "expected at least one safety loss");
CHECK(r.countSafetyGained() == 0, "cpp->c should not gain safety here");
PASS();
}
int main() {
std::cout << "Step 453: Memory Model Translation Tests\n";
test_manual_c_to_rust_gains_safety(); // 1
test_manual_c_to_java_gains_gc_safety(); // 2
test_unique_cpp_to_c_loses_safety(); // 3
test_shared_cpp_to_rust_arc_mapping(); // 4
test_shared_rust_to_c_loses_safety(); // 5
test_scope_lifetime_to_go_defer(); // 6
test_scope_to_c_loses_scope_guarantee(); // 7
test_detect_source_model_rust_borrowchecked(); // 8
test_detect_target_model_java_gc(); // 9
test_no_pattern_on_plain_code(); // 10
test_safety_gain_count_for_manual_migration(); // 11
test_mixed_patterns_report_gain_and_loss(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed)
<< " passed\n";
return failed == 0 ? 0 : 1;
}