Step 373: Add Common Lisp integration tests
This commit is contained in:
@@ -2236,4 +2236,13 @@ target_link_libraries(step372_test PRIVATE
|
||||
tree_sitter_javascript tree_sitter_typescript
|
||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||
|
||||
add_executable(step373_test tests/step373_test.cpp)
|
||||
target_include_directories(step373_test PRIVATE src)
|
||||
target_link_libraries(step373_test PRIVATE
|
||||
nlohmann_json::nlohmann_json
|
||||
unofficial::tree-sitter::tree-sitter
|
||||
tree_sitter_python tree_sitter_cpp tree_sitter_elisp
|
||||
tree_sitter_javascript tree_sitter_typescript
|
||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||
|
||||
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)
|
||||
|
||||
150
editor/tests/step373_test.cpp
Normal file
150
editor/tests/step373_test.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
// Step 373: Common Lisp Integration (8 tests)
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Pipeline.h"
|
||||
#include "CrossLanguageProjector.h"
|
||||
#include "AnnotationInference.h"
|
||||
#include "CompactAST.h"
|
||||
#include "SemannoSidecar.h"
|
||||
#include "ast/CommonLispParser.h"
|
||||
#include "ast/CommonLispGenerator.h"
|
||||
|
||||
static bool contains(const std::string& text, const std::string& token) {
|
||||
return text.find(token) != std::string::npos;
|
||||
}
|
||||
|
||||
static bool hasInference(const std::vector<AnnotationInference::InferredAnnotation>& inferred,
|
||||
const std::string& annotationType,
|
||||
const std::string& value = "") {
|
||||
for (const auto& a : inferred) {
|
||||
if (a.annotationType != annotationType) continue;
|
||||
if (value.empty() || a.value == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int passed = 0;
|
||||
|
||||
// Test 1: Parse CL -> generate CL -> parse roundtrip shape
|
||||
{
|
||||
std::string src =
|
||||
"(defclass point () ((x) (y)))\n"
|
||||
"(defun add (a b) (+ a b))\n";
|
||||
auto mod1 = CommonLispParser::parseCommonLisp(src);
|
||||
CommonLispGenerator gen;
|
||||
std::string out = gen.generate(mod1.get());
|
||||
auto mod2 = CommonLispParser::parseCommonLisp(out);
|
||||
assert(mod1->getChildren("classes").size() == mod2->getChildren("classes").size());
|
||||
assert(mod1->getChildren("functions").size() == mod2->getChildren("functions").size());
|
||||
std::cout << "Test 1 PASSED: CL parse/generate/parse roundtrip\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 2: Python -> Common Lisp (class -> CLOS)
|
||||
{
|
||||
Pipeline p;
|
||||
std::string py =
|
||||
"class Point:\n"
|
||||
" def __init__(self, x, y):\n"
|
||||
" self.x = x\n"
|
||||
" self.y = y\n";
|
||||
auto res = p.run(py, "python", "common-lisp");
|
||||
assert(res.success);
|
||||
assert(contains(res.generatedCode, "(defclass"));
|
||||
std::cout << "Test 2 PASSED: Python class -> Common Lisp CLOS form\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 3: Common Lisp -> Python projection retains class structure
|
||||
{
|
||||
auto src = CommonLispParser::parseCommonLisp("(defclass point () ((x) (y)))");
|
||||
CrossLanguageProjector projector;
|
||||
auto pyMod = projector.project(src.get(), "python");
|
||||
Pipeline p;
|
||||
auto code = p.generate(pyMod.get(), "python");
|
||||
assert(pyMod != nullptr);
|
||||
assert(pyMod->getChildren("classes").size() == 1);
|
||||
assert(!code.empty());
|
||||
std::cout << "Test 3 PASSED: Common Lisp class retained in Python projection\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 4: Common Lisp -> Java projection retains class hierarchy shape
|
||||
{
|
||||
auto src = CommonLispParser::parseCommonLisp("(defclass rectangle (shape) ((w) (h)))");
|
||||
CrossLanguageProjector projector;
|
||||
auto javaMod = projector.project(src.get(), "java");
|
||||
assert(javaMod != nullptr);
|
||||
assert(javaMod->getChildren("classes").size() == 1);
|
||||
std::cout << "Test 4 PASSED: Common Lisp class retained in Java projection\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 5: CL annotation inference (macro, dynamic var, tail call)
|
||||
{
|
||||
std::string cl =
|
||||
"(defmacro m (x) x)\n"
|
||||
"(defvar *state* 1)\n"
|
||||
"(defun loopf (n) (loopf n))\n";
|
||||
auto mod = CommonLispParser::parseCommonLisp(cl);
|
||||
AnnotationInference inf;
|
||||
auto inferred = inf.inferAll(mod.get());
|
||||
assert(hasInference(inferred, "MetaAnnotation", "quoted"));
|
||||
assert(hasInference(inferred, "BindingAnnotation", "dynamic"));
|
||||
assert(hasInference(inferred, "TailCallAnnotation"));
|
||||
std::cout << "Test 5 PASSED: CL annotation inference integration\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 6: Semanno sidecar roundtrip on .lisp path
|
||||
{
|
||||
Module mod("m1", "cl_module", "common-lisp");
|
||||
auto* fn = new Function("f1", "run");
|
||||
fn->setSpan(1, 1, 1, 12);
|
||||
auto* owner = new OwnerAnnotation("a1", "Shared_GC");
|
||||
fn->addChild("annotations", owner);
|
||||
mod.addChild("functions", fn);
|
||||
|
||||
std::string root = "/tmp/whetstone_step373";
|
||||
std::string filePath = "samples/test.lisp";
|
||||
auto save = saveSemannoSidecar(root, filePath, &mod);
|
||||
auto load = loadSemannoSidecar(root, filePath);
|
||||
assert(save.success);
|
||||
assert(load.success);
|
||||
assert(load.count >= 1);
|
||||
std::cout << "Test 6 PASSED: Semanno sidecar roundtrip for CL\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 7: Pipeline.run with CL source succeeds
|
||||
{
|
||||
Pipeline p;
|
||||
std::string cl = "(defun id (x) x)";
|
||||
auto res = p.run(cl, "common-lisp", "common-lisp");
|
||||
assert(res.success);
|
||||
assert(!res.generatedCode.empty());
|
||||
std::cout << "Test 7 PASSED: Pipeline.run with CL source\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Test 8: Compact AST has meaningful Lisp node names
|
||||
{
|
||||
auto mod = CommonLispParser::parseCommonLisp("(defun id (x) x)");
|
||||
auto compact = toJsonCompactTree(mod.get());
|
||||
assert(compact.is_array());
|
||||
bool hasFunctionNode = false;
|
||||
for (const auto& n : compact) {
|
||||
if (n.contains("type") && n["type"] == "Function") hasFunctionNode = true;
|
||||
}
|
||||
assert(hasFunctionNode);
|
||||
std::cout << "Test 8 PASSED: compact AST contains Function node\n";
|
||||
passed++;
|
||||
}
|
||||
|
||||
std::cout << "\nResults: " << passed << "/8\n";
|
||||
assert(passed == 8);
|
||||
return 0;
|
||||
}
|
||||
32
progress.md
32
progress.md
@@ -2533,6 +2533,38 @@ plus Common Lisp memory-strategy defaults.
|
||||
- `editor/src/MemoryStrategyInference.h` remains within header-size limit
|
||||
(`384` lines <= `600`)
|
||||
|
||||
### Step 373: Common Lisp Integration
|
||||
**Status:** PASS (8/8 tests)
|
||||
|
||||
Added phase-level integration validation for Common Lisp parse/generate
|
||||
roundtrips, cross-language projection paths, inference integration, and CL
|
||||
artifact compatibility with Semanno and compact AST tooling.
|
||||
|
||||
**Files created:**
|
||||
- `editor/tests/step373_test.cpp` — 8 integration tests covering:
|
||||
1. Common Lisp parse -> generate -> parse roundtrip shape
|
||||
2. Python class -> Common Lisp CLOS generation path
|
||||
3. Common Lisp defclass retained through Python projection
|
||||
4. Common Lisp class hierarchy retained through Java projection
|
||||
5. Common Lisp annotation inference integration (macro/dynamic/tail-call)
|
||||
6. Semanno sidecar save/load roundtrip on `.lisp` path
|
||||
7. `Pipeline.run()` success with Common Lisp source
|
||||
8. compact AST node naming on Common Lisp module
|
||||
|
||||
**Files modified:**
|
||||
- `editor/CMakeLists.txt` — `step373_test` target
|
||||
|
||||
**Verification run:**
|
||||
- `step373_test` — PASS (8/8) new step coverage
|
||||
- `step372_test` — PASS (12/12) regression coverage
|
||||
- `step371_test` — PASS (12/12) regression coverage
|
||||
- `step370_test` — PASS (12/12) regression coverage
|
||||
- `step369_test` — PASS (8/8) regression coverage
|
||||
|
||||
**Architecture gate check:**
|
||||
- `editor/tests/step373_test.cpp` remains within project file-size guidance
|
||||
for test artifacts (`147` lines)
|
||||
|
||||
# Roadmap Planning — Sprints 12-25+
|
||||
|
||||
## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md)
|
||||
|
||||
Reference in New Issue
Block a user