Files
whetstone_DSL/editor/tests/step476_test.cpp

149 lines
6.2 KiB
C++

// Step 476: Phase 23a Integration Tests (8 tests)
#include "ArchitectReviewInterface.h"
#include <iostream>
#include <vector>
struct WorkflowTask {
std::string moduleName;
std::string functionName;
};
static std::vector<WorkflowTask> createWorkflow(const SkeletonProjectSpec& sk) {
std::vector<WorkflowTask> tasks;
for (const auto& m : sk.modules) {
for (const auto& f : m.functions) {
tasks.push_back({m.moduleName, f.name});
}
}
return tasks;
}
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 ArchitectReviewState runFlow(const std::string& prompt) {
auto req = ArchitectProblemParser::parse(prompt);
auto graph = ArchitectModuleDecomposer::decompose(req, DecompositionStrategy::Layered);
auto stack = ArchitectTechStackSelector::select(req, graph);
auto sk = ArchitectSkeletonGenerator::generate(req, graph, stack);
return ArchitectReviewInterface::initialize(sk, stack, graph);
}
void test_full_flow_extracts_structured_requirements() {
TEST(full_flow_extracts_structured_requirements);
auto req = ArchitectProblemParser::parse(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
CHECK(!req.functionalRequirements.empty(), "missing functional requirements");
CHECK(!req.integrationRequirements.empty(), "missing integration requirements");
CHECK(!req.platformConstraints.empty(), "missing platform requirements");
PASS();
}
void test_full_flow_decomposes_expected_modules() {
TEST(full_flow_decomposes_expected_modules);
auto req = ArchitectProblemParser::parse(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
auto g = ArchitectModuleDecomposer::decompose(req, DecompositionStrategy::Layered);
CHECK(g.hasModule("api"), "missing api module");
CHECK(g.hasModule("auth"), "missing auth module");
CHECK(g.hasModule("data"), "missing data module");
CHECK(g.hasModule("ui"), "missing ui module");
PASS();
}
void test_full_flow_stack_selects_frontend_and_database() {
TEST(full_flow_stack_selects_frontend_and_database);
auto req = ArchitectProblemParser::parse(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
auto g = ArchitectModuleDecomposer::decompose(req, DecompositionStrategy::Layered);
auto stack = ArchitectTechStackSelector::select(req, g);
auto ui = stack.getChoice("ui");
auto data = stack.getChoice("data");
CHECK(ui.language == "typescript", "expected typescript frontend");
CHECK(ui.framework == "react", "expected react framework");
CHECK(data.database == "postgresql", "expected postgresql");
PASS();
}
void test_full_flow_generates_skeleton_modules_and_annotations() {
TEST(full_flow_generates_skeleton_modules_and_annotations);
auto st = runFlow(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
CHECK(st.skeleton.hasModule("api"), "missing api skeleton module");
auto api = st.skeleton.getModule("api");
CHECK(!api.functions.empty(), "missing api functions");
bool hasIntent = false, hasContract = false;
for (const auto& a : api.functions[0].annotations) {
if (a.key == "@Intent") hasIntent = true;
if (a.key == "@Contract") hasContract = true;
}
CHECK(hasIntent && hasContract, "missing key annotations");
PASS();
}
void test_architect_review_can_modify_and_approve() {
TEST(architect_review_can_modify_and_approve);
auto st = runFlow(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
bool changed = ArchitectReviewInterface::changeModuleLanguage(st, "api", "go");
CHECK(changed, "expected language change");
ArchitectReviewInterface::approve(st);
CHECK(st.approved, "expected approved state");
PASS();
}
void test_workflow_created_after_approval() {
TEST(workflow_created_after_approval);
auto st = runFlow(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
ArchitectReviewInterface::approve(st);
auto tasks = createWorkflow(st.skeleton);
CHECK(st.approved, "expected approved state");
CHECK(!tasks.empty(), "expected workflow tasks");
PASS();
}
void test_dependency_graph_available_in_review_snapshot() {
TEST(dependency_graph_available_in_review_snapshot);
auto st = runFlow(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
auto snap = ArchitectReviewInterface::snapshot(st);
CHECK(!snap.dependencyGraph.empty(), "expected dependency graph");
CHECK(!snap.modules.empty(), "expected module summaries");
PASS();
}
void test_end_to_end_flow_keeps_review_structured_for_mcp() {
TEST(end_to_end_flow_keeps_review_structured_for_mcp);
auto st = runFlow(
"Build a REST API for a bookstore with user auth, PostgreSQL, and a React web frontend.");
auto snap = ArchitectReviewInterface::snapshot(st);
bool hasStackRationale = !snap.stackRationales.empty();
bool hasModuleSummary = !snap.modules.empty();
CHECK(hasStackRationale, "expected stack rationale entries");
CHECK(hasModuleSummary, "expected module summary entries");
PASS();
}
int main() {
std::cout << "Step 476: Phase 23a Integration Tests\n";
test_full_flow_extracts_structured_requirements(); // 1
test_full_flow_decomposes_expected_modules(); // 2
test_full_flow_stack_selects_frontend_and_database(); // 3
test_full_flow_generates_skeleton_modules_and_annotations();// 4
test_architect_review_can_modify_and_approve(); // 5
test_workflow_created_after_approval(); // 6
test_dependency_graph_available_in_review_snapshot(); // 7
test_end_to_end_flow_keeps_review_structured_for_mcp(); // 8
std::cout << "\nResults: " << passed << "/" << (passed + failed)
<< " passed\n";
return failed == 0 ? 0 : 1;
}