Files
whetstone_DSL/editor/tests/step337_test.cpp

211 lines
7.4 KiB
C++
Raw Normal View History

// Step 337: Preprocessor AST Nodes (12 tests)
// Tests IncludeDirective, PragmaDirective, MacroDefinition construction,
// serialization roundtrip, and CompactAST output.
#include <cassert>
#include <iostream>
#include <string>
#include "ast/PreprocessorNodes.h"
#include "ast/Serialization.h"
#include "CompactAST.h"
#include "ast/Module.h"
#include "ast/Function.h"
int main() {
int passed = 0;
// Test 1: IncludeDirective construction — local include
{
auto* inc = new IncludeDirective("inc1", "ast/ASTNode.h", false);
assert(inc->conceptType == "IncludeDirective");
assert(inc->path == "ast/ASTNode.h");
assert(!inc->isSystem);
delete inc;
std::cout << "Test 1 PASSED: IncludeDirective local include\n";
passed++;
}
// Test 2: IncludeDirective — system include
{
auto* inc = new IncludeDirective("inc2", "string", true);
assert(inc->isSystem);
assert(inc->path == "string");
delete inc;
std::cout << "Test 2 PASSED: IncludeDirective system include\n";
passed++;
}
// Test 3: IncludeDirective JSON roundtrip
{
auto* inc = new IncludeDirective("inc3", "vector", true);
json j = toJson(inc);
auto* restored = fromJson(j);
assert(restored->conceptType == "IncludeDirective");
auto* ri = static_cast<IncludeDirective*>(restored);
assert(ri->path == "vector");
assert(ri->isSystem == true);
delete inc;
delete restored;
std::cout << "Test 3 PASSED: IncludeDirective JSON roundtrip\n";
passed++;
}
// Test 4: PragmaDirective construction
{
auto* prag = new PragmaDirective("prag1", "once");
assert(prag->conceptType == "PragmaDirective");
assert(prag->directive == "once");
delete prag;
std::cout << "Test 4 PASSED: PragmaDirective construction\n";
passed++;
}
// Test 5: PragmaDirective JSON roundtrip
{
auto* prag = new PragmaDirective("prag2", "pack(push, 1)");
json j = toJson(prag);
auto* restored = fromJson(j);
assert(restored->conceptType == "PragmaDirective");
auto* rp = static_cast<PragmaDirective*>(restored);
assert(rp->directive == "pack(push, 1)");
delete prag;
delete restored;
std::cout << "Test 5 PASSED: PragmaDirective JSON roundtrip\n";
passed++;
}
// Test 6: MacroDefinition — object-like macro
{
auto* mac = new MacroDefinition("mac1", "MAX_SIZE");
mac->body = "1024";
mac->isFunctionLike = false;
assert(mac->conceptType == "MacroDefinition");
assert(mac->name == "MAX_SIZE");
assert(mac->body == "1024");
assert(!mac->isFunctionLike);
assert(mac->parameters.empty());
delete mac;
std::cout << "Test 6 PASSED: MacroDefinition object-like macro\n";
passed++;
}
// Test 7: MacroDefinition — function-like macro with params
{
auto* mac = new MacroDefinition("mac2", "MIN");
mac->isFunctionLike = true;
mac->parameters = {"a", "b"};
mac->body = "((a) < (b) ? (a) : (b))";
assert(mac->isFunctionLike);
assert(mac->parameters.size() == 2);
assert(mac->parameters[0] == "a");
assert(mac->parameters[1] == "b");
delete mac;
std::cout << "Test 7 PASSED: MacroDefinition function-like macro\n";
passed++;
}
// Test 8: MacroDefinition JSON roundtrip
{
auto* mac = new MacroDefinition("mac3", "CONCAT");
mac->isFunctionLike = true;
mac->parameters = {"x", "y"};
mac->body = "x##y";
json j = toJson(mac);
auto* restored = fromJson(j);
assert(restored->conceptType == "MacroDefinition");
auto* rm = static_cast<MacroDefinition*>(restored);
assert(rm->name == "CONCAT");
assert(rm->isFunctionLike);
assert(rm->parameters.size() == 2);
assert(rm->parameters[0] == "x");
assert(rm->body == "x##y");
delete mac;
delete restored;
std::cout << "Test 8 PASSED: MacroDefinition JSON roundtrip\n";
passed++;
}
// Test 9: CompactAST names
{
auto* inc = new IncludeDirective("inc4", "iostream", true);
assert(getNodeName(inc) == "iostream");
auto* prag = new PragmaDirective("prag3", "once");
assert(getNodeName(prag) == "once");
auto* mac = new MacroDefinition("mac4", "DEBUG_LOG");
assert(getNodeName(mac) == "DEBUG_LOG");
delete inc; delete prag; delete mac;
std::cout << "Test 9 PASSED: CompactAST node names\n";
passed++;
}
// Test 10: Module with mixed preprocessor + function nodes
{
auto* mod = new Module();
mod->id = "mod1";
mod->name = "test_module";
auto* inc = new IncludeDirective("inc5", "stdio.h", true);
auto* prag = new PragmaDirective("prag4", "once");
auto* mac = new MacroDefinition("mac5", "VERSION");
mac->body = "\"1.0\"";
auto* func = new Function("fn1", "main");
mod->addChild("statements", inc);
mod->addChild("statements", prag);
mod->addChild("statements", mac);
mod->addChild("functions", func);
auto stmts = mod->getChildren("statements");
assert(stmts.size() == 3);
assert(stmts[0]->conceptType == "IncludeDirective");
assert(stmts[1]->conceptType == "PragmaDirective");
assert(stmts[2]->conceptType == "MacroDefinition");
delete mod;
std::cout << "Test 10 PASSED: Module with mixed preprocessor + function\n";
passed++;
}
// Test 11: Empty macro body
{
auto* mac = new MacroDefinition("mac6", "NDEBUG");
assert(mac->body.empty());
json j = toJson(mac);
auto* restored = fromJson(j);
auto* rm = static_cast<MacroDefinition*>(restored);
assert(rm->name == "NDEBUG");
assert(rm->body.empty());
assert(!rm->isFunctionLike);
delete mac;
delete restored;
std::cout << "Test 11 PASSED: Empty macro body\n";
passed++;
}
// Test 12: Serialization createNode dispatch for all 3 types
{
json jInc = {{"concept", "IncludeDirective"}, {"id", "test_inc"},
{"properties", {{"path", "test.h"}, {"isSystem", false}}}};
auto* rInc = fromJson(jInc);
assert(rInc != nullptr);
assert(rInc->conceptType == "IncludeDirective");
assert(static_cast<IncludeDirective*>(rInc)->path == "test.h");
json jPrag = {{"concept", "PragmaDirective"}, {"id", "test_prag"},
{"properties", {{"directive", "warning disable"}}}};
auto* rPrag = fromJson(jPrag);
assert(rPrag != nullptr);
assert(static_cast<PragmaDirective*>(rPrag)->directive == "warning disable");
json jMac = {{"concept", "MacroDefinition"}, {"id", "test_mac"},
{"properties", {{"name", "FOO"}, {"body", "bar"}}}};
auto* rMac = fromJson(jMac);
assert(rMac != nullptr);
assert(static_cast<MacroDefinition*>(rMac)->name == "FOO");
delete rInc; delete rPrag; delete rMac;
std::cout << "Test 12 PASSED: Serialization createNode dispatch\n";
passed++;
}
std::cout << "\nResults: " << passed << "/12 tests passed\n";
return (passed == 12) ? 0 : 1;
}