diff --git a/docs/hexascript/html/algorithm.html b/docs/hexascript/html/algorithm.html new file mode 100644 index 0000000..0c914a0 --- /dev/null +++ b/docs/hexascript/html/algorithm.html @@ -0,0 +1,234 @@ +

Pipeline Algorithm

+ diff --git a/docs/hexascript/html/testing_plans.html b/docs/hexascript/html/testing_plans.html index 3e920bf..d81871e 100644 --- a/docs/hexascript/html/testing_plans.html +++ b/docs/hexascript/html/testing_plans.html @@ -1,181 +1,68 @@ -

Testing Plan

- +Testing Plan: 1. C++ Pybindings Validation (GTest & Pytest): Test Cases:: +test_safe_assign_binding_integrity: Pass Boolean, Integer, and Enum +string types from Python dictionaries into C++ hexa::RunConfig via +Pybind11. TestManifestBridge: Validate C++ +hexa::CompilationResult properties correctly reflect into Python +ManifestModel schema. +ConfigSafetyTest.HandlesMalformedJSONInjection: Inject deeply +nested or malformed JSON payloads into RunConfig::from_json. +Expected Outcomes:: C++ layer extracts Python variables without segmentation +faults. Type mismatches or overflows trigger controlled fallbacks or raise +caught std::invalid_argument exceptions passed back to Python. +Manifest generation strictly enforces mandatory fields. +Verification Methods:: Pytest assertions on data type mapping +(isinstance). GTest EXPECT_NO_THROW and +EXPECT_EQ ensuring safe fallback values (e.g., +SEEDLESS_VALUE). 2. Class Object Integrity (C++, Python, +TypeScript): Test Cases:: C++ Core:: OptimizerLogicTest for dead +code elimination and constant folding; LinearizerTest for nested +math AST translation; VMTest for memory bound checks +(HighRegisterPressure), loop termination, and stack underflow +logic. Python Backend:: TestOracle and +HexaASTSerializer for validating accurate translation of native +Python ast nodes to JSON. TypeScript Frontend:: +BaseCRUD memento pattern tests (isDirty flag logic). +BaseLibrary collection hydration. Expected Outcomes:: Optimizer +reduces AST complexity without altering deterministic output. VM halts +predictably on stack underflow or type mismatch +(ThrowsOnTypeMismatch). TS models track local state mutations and +revert cleanly. Verification Methods:: GTest executing bytecode and validating +literal extraction (get_double). Pytest validating dictionary +structure of serialized AST. Vitest verifying Svelte +$state reactivity and dirty flags. 3. Backend Endpoint & +Pydantic Structure Validation: Test Cases:: +TestCompilerConfigDynamicOrchestration: Verify FastAPI endpoint +schema matches the dynamically generated C++ SchemaBuilder payload. +test_dispatch_pipeline_success: Post CommandPayload to +/api/dispatch triggering database entry and background worker +queue. TestCompileJobOrchestration: Validate DB integrity and +cascading foreign keys across AST, CompilerConfig, and +CompileJob. Expected Outcomes:: API endpoints correctly enforce +BatchConfig and CommandPayload Pydantic contracts. +Missing required fields yield 422 Unprocessable Entity. Authorized +requests insert SQLite records and spawn multiprocessing tasks successfully. +Verification Methods:: Pytest TestClient executing HTTP requests. +SQLAlchemy inspect(CompilerConfig) asserting exact column parity +with C++ configuration definitions. 4. Frontend Data Dispatch Accuracy: Test +Cases:: BaseCRUD.Validation: Pass invalid/incomplete forms into TS +model before dispatch. getValidPayload: Verify stripping of UI-only +properties (e.g., isEditing) before network transmission. Expected +Outcomes:: Zod schemas intercept malformed data client-side, throwing +ValidationError and halting fetch. Generated payloads +strictly match the backend's expected JSON format. Verification Methods:: Vitest +expect(() => getValidPayload(true)).toThrow(). Spying on +internal apiFetch calls to assert the shape of the intercepted HTTP +body. 5. End-to-End API Integration & Telemetry Synchronization: Test +Cases:: runIntegrationSuite: Execute chained sequence creating +ResearchTier -> LLMServer -> +Prompt -> LLMModel -> PromptConfig. +FullChainTest: Inject Python AST payload, execute compiler pass, +and await trace result. Expected Outcomes:: System maintains state +synchronization across the network boundary. C++ execution yields physical +.hex and .meta.json files. Database accurately links +execution Manifest to the original CompileJob. +WebSocket/Polling loops hydrate the UI RegisterGrid and +ASTViewer with zero data mutation. Verification Methods: Vitest +polling tests resolving simulated backend responses. GTest +fs::exists verifying absolute file paths of generated artifacts in +the scoped temporary workspace. diff --git a/docs/hexascript/src/controller.js b/docs/hexascript/src/controller.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/hexascript/src/controller.js diff --git a/docs/hexascript/src/router.js b/docs/hexascript/src/router.js new file mode 100644 index 0000000..83bf985 --- /dev/null +++ b/docs/hexascript/src/router.js @@ -0,0 +1,76 @@ +const navLinks = require("./navLinks.json"); +const fs = require('node:fs'); +const express = require("express") +const router = express.Router() + +export function htmlController(req, res) {} +export function mermaidController(req, res) {} +export function frameController(req, res) {} + +export function getContext(type, path) { + let filePath = null; + let controllor; + let route; + switch (type) { + case "html": + /** + * Injects html directly into the content area + *
+ */ + filePath = path.join("html", path + ".html"); + controllor = htmlController; + route = `${path}` + break; + case: "mermaid": + /** + * Injects a mermaid file directly into the content area + *

+       */
+      filePath= path.join("diagrams", path + ".mmd");
+      controllor = mermaidController;
+    case "frame":
+      /**
+       * Injects an iframe into the content area
+       * 
+       */
+      controllor = frameController;
+      break;
+    default:
+      throw new Error(`Invalid option: ${type}`)
+  }
+  if ( filePath != null) {
+   fileContent = await fs.readFile(filePath, 'utf8');
+  }
+  return {
+    path, controller
+    ,route: `diagram/${path}`,
+    content: fileContent
+
+  }
+}
+function router() {
+navLinks.forEach((navLink) => {
+  const keys = Object.keys(navLink);
+  keys.forEach( key => {
+
+  // -- Html Injection
+  if (keys.indexOf("html") != -1) {
+    context = getContext("html", path)
+  }
+  // -- Mermaid Diagram Injection
+  if (keys.indexOf("mermaid") != -1) {
+    context = getContext("mermaid", path)
+    const fileContent
+  }
+  // -- Frame Injection
+  if (keys.indexOf("frame") != -1) {
+    context = getContext("frame", path)
+  }
+    router.get(context.path, context.controller)
+
+  })
+});
+
+  return router
+}
+module.exports = router()
diff --git a/docs/hexascript/src/router.test.js b/docs/hexascript/src/router.test.js
new file mode 100644
index 0000000..246db1f
--- /dev/null
+++ b/docs/hexascript/src/router.test.js
@@ -0,0 +1,75 @@
+/**
+ * UNIT TESTS (TDD)
+ */
+const runTests = () => {
+  const assert = (condition, message) => {
+    if (!condition) throw new Error(`Test Failed: ${message}`);
+  };
+
+  const mockRouter = {
+    routes: [],
+    get(path, handler) {
+      this.routes.push({ path, handler });
+    },
+  };
+
+  const mockLogger = {
+    info: () => {},
+    error: (msg, data) => {
+      console.error(msg, data);
+    },
+  };
+
+  const mockPath = {
+    join: (...args) => args.filter(Boolean).join("/").replace(/\/+/g, "/"),
+  };
+
+  const mockContextProvider = (type, value, prefix) => ({
+    route: value,
+    controller: type === "submenu" ? null : () => `handler for ${value}`,
+  });
+
+  const factory = new RouterFactory(
+    mockRouter,
+    mockLogger,
+    mockContextProvider,
+    mockPath,
+  );
+
+  // Test Case 1: Standard Route Registration
+  factory.generateRouter([{ html: "test", label: "Test" }]);
+  assert(
+    mockRouter.routes.some((r) => r.path === "test"),
+    "Standard route registration failed",
+  );
+
+  // Test Case 2: Recursion (Submenus)
+  const nestedData = [
+    {
+      label: "Parent",
+      submenu: [{ html: "child", label: "Child" }],
+    },
+  ];
+  factory.generateRouter(nestedData, "/api");
+  assert(
+    mockRouter.routes.some((r) => r.path === "/api/child"),
+    "Recursive submenu registration failed",
+  );
+
+  // Test Case 3: Boundary - Empty Links
+  factory.generateRouter([]);
+  assert(true, "Empty links should not throw");
+
+  // Test Case 4: Malformed Input - Missing Controller (Fail-Fast)
+  const brokenProvider = () => ({ route: "error" }); // No controller
+  const brokenFactory = new RouterFactory(
+    mockRouter,
+    mockLogger,
+    brokenProvider,
+    mockPath,
+  );
+  brokenFactory.generateRouter([{ html: "broken" }]);
+  // Should catch error internally and log via mockLogger.error
+
+  console.log("All tests passed.");
+};
diff --git a/docs/hexascript/src/script.test.js b/docs/hexascript/src/script.test.js
new file mode 100644
index 0000000..63a436d
--- /dev/null
+++ b/docs/hexascript/src/script.test.js
@@ -0,0 +1,137 @@
+/**
+ * Comprehensive Test Suite with Fuzzing for getContext.
+ */
+const { getContext, validateType, getFilePath } = require("./router.js");
+const fs = require("node:fs/promises");
+
+jest.mock("node:fs/promises");
+
+describe("Router Logic TDD", () => {
+  test("validateType throws on invalid input (Fail-Fast)", () => {
+    expect(() => validateType("invalid")).toThrow("Invalid option: invalid");
+  });
+
+  test("getFilePath returns correct structure for html", () => {
+    const path = getFilePath("html", "test");
+    expect(path).toBe("html/test.html");
+  });
+
+  test("getContext returns frozen object with expected keys", async () => {
+    fs.readFile.mockResolvedValue("

Test

"); + const context = await getContext("html", "about"); + + expect(context).toHaveProperty("controller"); + expect(context.content).toBe("

Test

"); + expect(Object.isFrozen(context)).toBe(true); + }); + + test("Memory Overflow / Long Input Boundary Check", async () => { + const hugeInput = "a".repeat(10 ** 6); + expect(() => getFilePath("html", hugeInput)).not.toThrow(); + }); + + test("Automated Fuzzing for malformed inputs", async () => { + const iterations = 100; + const getRandomString = () => Math.random().toString(36).substring(7); + + for (let i = 0; i < iterations; i++) { + const randomType = getRandomString(); + const randomPath = getRandomString(); + + // Should either resolve or throw defined Error, never crash process + try { + await getContext(randomType, randomPath); + } catch (e) { + expect(e.message).toMatch(/Invalid option/); + } + } + }); +}); + +/** + * NEW: Unit and Integration tests for Menu Adaptation. + */ +const { adaptConfigToMenu, resolveModuleHref } = require("./menuAdapter.js"); + +describe("Menu Module Compatibility", () => { + const mockConfig = [ + { html: "algorithm", label: "Algorithm" }, + { mermaid: "frontend_logic.html", label: "Logic" }, + ]; + + test("resolveModuleHref correctly prefixes html keys", () => { + const link = { html: "test" }; + expect(resolveModuleHref(link)).toBe("/content/html/test"); + }); + + test("adaptConfigToMenu maintains immutability", () => { + const input = [{ html: "a" }]; + const output = adaptConfigToMenu(input); + expect(output[0]).not.toBe(input[0]); + expect(output[0].href).toBe("/content/html/a"); + }); + + test("Recursion depth boundary check (Stack Overflow prevention)", () => { + const createDeepMenu = (depth) => { + if (depth === 0) return { html: "end" }; + return { label: "level", submenu: [createDeepMenu(depth - 1)] }; + }; + const deepInput = [createDeepMenu(100)]; + expect(() => adaptConfigToMenu(deepInput)).not.toThrow(); + }); + + test("Automated Fuzzing: Malformed Object Keys", () => { + const iterations = 50; + for (let i = 0; i < iterations; i++) { + const junkKey = Math.random().toString(36); + const junkVal = Math.random().toString(36); + const malformed = [{ [junkKey]: junkVal }]; + + const result = adaptConfigToMenu(malformed); + // Fail-fast / POLA: If no specialized key exists, href should be null/undefined + expect(result[0].href).toBeNull(); + } + }); +}); + +const { qualifyNavLinks, adaptConfigToMenu } = require("./menuUtils.js"); + +describe("Menu Logic Unification", () => { + test("qualifyNavLinks preserves existing behavior", () => { + const input = [{ href: "test", label: "T" }]; + const result = qualifyNavLinks(input, "/api"); + expect(result[0].href).toBe("/apitest"); + }); + + test("adaptConfigToMenu translates specialty keys to href", () => { + const input = [{ html: "algo", label: "A" }]; + const result = adaptConfigToMenu(input); + expect(result[0].href).toBe("/content/html/algo"); + }); + + test("Integration: adaptConfigToMenu followed by qualifyNavLinks", () => { + const raw = [{ html: "algo" }]; + const adapted = adaptConfigToMenu(raw); + const qualified = qualifyNavLinks(adapted, "https://jasonpoage.com"); + expect(qualified[0].href).toBe("https://jasonpoage.com/content/html/algo"); + }); + + test("Boundary: Stack Overflow protection on deep nesting", () => { + const deepLink = (n) => + n === 0 ? { href: "x" } : { submenu: [deepLink(n - 1)] }; + const input = [deepLink(100)]; + expect(() => qualifyNavLinks(input, "")).not.toThrow(); + }); + + test("Fuzzing: Malformed object structures", () => { + for (let i = 0; i < 50; i++) { + const malformed = [{ [Math.random()]: null, submenu: "not-an-array" }]; + // Should fail-fast or return input based on POLA + try { + qualifyNavLinks(malformed, ""); + } catch (e) { + expect(e).toBeDefined(); // Expecting error on non-array submenu + } + } + }); +});