Files
whetstone_DSL/editor/tests/step276_test.cpp

212 lines
7.9 KiB
C++
Raw Normal View History

// Step 276: Scope & Namespace Annotations (12 tests)
// Tests: BindingAnnotation, LookupAnnotation, CaptureAnnotation,
// VisibilityAnnotation, NamespaceAnnotation, ScopeAnnotation
// + JSON roundtrip + compact AST
#include <cassert>
#include <iostream>
#include <string>
#include "ast/ASTNode.h"
#include "ast/Module.h"
#include "ast/Function.h"
#include "ast/Annotation.h"
#include "ast/Serialization.h"
#include "ASTUtils.h"
#include "CompactAST.h"
static int passed = 0;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: BindingAnnotation creation ---
static void test_binding_annotation() {
BindingAnnotation ba;
check(ba.conceptType == "BindingAnnotation", "conceptType is BindingAnnotation");
ba.time = "static";
check(ba.time == "static", "time field set to static");
}
// --- Test 2: LookupAnnotation creation ---
static void test_lookup_annotation() {
LookupAnnotation la;
check(la.conceptType == "LookupAnnotation", "conceptType is LookupAnnotation");
la.mode = "lexical";
check(la.mode == "lexical", "mode field set to lexical");
}
// --- Test 3: CaptureAnnotation creation ---
static void test_capture_annotation() {
CaptureAnnotation ca;
check(ca.conceptType == "CaptureAnnotation", "conceptType is CaptureAnnotation");
ca.strategy = "move";
check(ca.strategy == "move", "strategy field set to move");
}
// --- Test 4: VisibilityAnnotation, NamespaceAnnotation, ScopeAnnotation ---
static void test_visibility_namespace_scope() {
VisibilityAnnotation va;
check(va.conceptType == "VisibilityAnnotation", "VisibilityAnnotation conceptType");
va.level = "friend";
check(va.level == "friend", "level set to friend");
NamespaceAnnotation na;
check(na.conceptType == "NamespaceAnnotation", "NamespaceAnnotation conceptType");
na.style = "qualified";
check(na.style == "qualified", "style set to qualified");
ScopeAnnotation sa;
check(sa.conceptType == "ScopeAnnotation", "ScopeAnnotation conceptType");
sa.kind = "singleton";
check(sa.kind == "singleton", "kind set to singleton");
}
// --- Test 5: CaptureAnnotation JSON roundtrip ---
static void test_capture_json_roundtrip() {
auto* ca = new CaptureAnnotation();
ca->id = "c1";
ca->strategy = "ref";
json j = toJson(ca);
check(j["properties"]["strategy"] == "ref", "JSON strategy correct");
ASTNode* restored = fromJson(j);
auto* rca = dynamic_cast<CaptureAnnotation*>(restored);
check(rca != nullptr, "fromJson creates CaptureAnnotation");
check(rca->strategy == "ref", "roundtrip strategy preserved");
delete ca;
delete restored;
}
// --- Test 6: VisibilityAnnotation JSON roundtrip ---
static void test_visibility_json_roundtrip() {
auto* va = new VisibilityAnnotation();
va->id = "v1";
va->level = "internal";
json j = toJson(va);
ASTNode* restored = fromJson(j);
auto* rva = dynamic_cast<VisibilityAnnotation*>(restored);
check(rva != nullptr, "fromJson creates VisibilityAnnotation");
check(rva->level == "internal", "roundtrip level preserved");
delete va;
delete restored;
}
// --- Test 7: ScopeAnnotation JSON roundtrip ---
static void test_scope_json_roundtrip() {
auto* sa = new ScopeAnnotation();
sa->id = "s1";
sa->kind = "global_leaked";
json j = toJson(sa);
ASTNode* restored = fromJson(j);
auto* rsa = dynamic_cast<ScopeAnnotation*>(restored);
check(rsa != nullptr, "fromJson creates ScopeAnnotation");
check(rsa->kind == "global_leaked", "roundtrip kind preserved");
delete sa;
delete restored;
}
// --- Test 8: createNode factory for Step 276 types ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"BindingAnnotation", "LookupAnnotation", "CaptureAnnotation",
"VisibilityAnnotation", "NamespaceAnnotation", "ScopeAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 9: Compact AST shows binding and lookup ---
static void test_compact_ast_binding_lookup() {
auto* func = new Function();
func->id = "f1";
func->name = "resolve";
auto* ba = new BindingAnnotation(); ba->time = "dynamic";
auto* la = new LookupAnnotation(); la->mode = "hoisted";
func->addChild("annotations", ba);
func->addChild("annotations", la);
json sem = extractSemanticSummary(func);
check(sem["binding"] == "dynamic", "binding in semantic summary");
check(sem["lookup"] == "hoisted", "lookup in semantic summary");
delete func;
}
// --- Test 10: Compact AST shows capture and visibility ---
static void test_compact_ast_capture_visibility() {
auto* func = new Function();
func->id = "f2";
func->name = "closureFactory";
auto* ca = new CaptureAnnotation(); ca->strategy = "value";
auto* va = new VisibilityAnnotation(); va->level = "private";
func->addChild("annotations", ca);
func->addChild("annotations", va);
json sem = extractSemanticSummary(func);
check(sem["capture"] == "value", "capture in semantic summary");
check(sem["visibility"] == "private", "visibility in semantic summary");
delete func;
}
// --- Test 11: All 6 scope annotations on one function ---
static void test_all_scope_annotations() {
auto* func = new Function();
func->id = "f3";
func->name = "fullScope";
func->addChild("annotations", [&]{ auto* a = new BindingAnnotation(); a->time = "static"; return a; }());
func->addChild("annotations", [&]{ auto* a = new LookupAnnotation(); a->mode = "lexical"; return a; }());
func->addChild("annotations", [&]{ auto* a = new CaptureAnnotation(); a->strategy = "move"; return a; }());
func->addChild("annotations", [&]{ auto* a = new VisibilityAnnotation(); a->level = "public"; return a; }());
func->addChild("annotations", [&]{ auto* a = new NamespaceAnnotation(); a->style = "flat"; return a; }());
func->addChild("annotations", [&]{ auto* a = new ScopeAnnotation(); a->kind = "local"; return a; }());
json sem = extractSemanticSummary(func);
check(sem.contains("binding") && sem.contains("lookup") &&
sem.contains("capture") && sem.contains("visibility") &&
sem.contains("namespace") && sem.contains("scope"),
"all 6 scope annotations in semantic summary");
delete func;
}
// --- Test 12: BindingAnnotation and NamespaceAnnotation JSON roundtrip ---
static void test_binding_namespace_roundtrip() {
auto* ba = new BindingAnnotation();
ba->id = "b1";
ba->time = "dynamic";
json jb = toJson(ba);
ASTNode* rb = fromJson(jb);
auto* rba = dynamic_cast<BindingAnnotation*>(rb);
check(rba != nullptr && rba->time == "dynamic", "BindingAnnotation roundtrip");
auto* na = new NamespaceAnnotation();
na->id = "n1";
na->style = "qualified";
json jn = toJson(na);
ASTNode* rn = fromJson(jn);
auto* rna = dynamic_cast<NamespaceAnnotation*>(rn);
check(rna != nullptr && rna->style == "qualified", "NamespaceAnnotation roundtrip");
delete ba; delete rb; delete na; delete rn;
}
int main() {
std::cout << "=== Step 276: Scope & Namespace Annotations ===\n";
test_binding_annotation();
test_lookup_annotation();
test_capture_annotation();
test_visibility_namespace_scope();
test_capture_json_roundtrip();
test_visibility_json_roundtrip();
test_scope_json_roundtrip();
test_create_node_factory();
test_compact_ast_binding_lookup();
test_compact_ast_capture_visibility();
test_all_scope_annotations();
test_binding_namespace_roundtrip();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}