Skip to main content
Glama

OneTech MCP Server

by jordnlvr
test-comprehensive.jsโ€ข9.2 kB
/** * Comprehensive test suite for OneTech MCP Server * Tests all functionality before NPM publish */ import { execFile } from "child_process"; import { promisify } from "util"; import { readFile, access, mkdir, rm } from "fs/promises"; import { join } from "path"; import { constants } from "fs"; const execFileAsync = promisify(execFile); // Test configuration const DEFAULT_MX_PATH = "D:\\Program Files\\Mendix\\11.3.0.80734\\modeler\\mx.exe"; const TEST_MPR = "d:\\kelly.seale\\CodeBase\\OneTech-main\\OneTech.mpr"; const TEST_MODULE = "RequestHub"; const TEST_OUTPUT = "D:\\kelly.seale\\CodeBase\\onetech-mcp-server\\test-validation"; // Test results const results = { passed: 0, failed: 0, tests: [], }; function test(name, fn) { return async () => { try { console.log(`\n๐Ÿงช ${name}...`); await fn(); results.passed++; results.tests.push({ name, status: "PASS" }); console.log(`โœ… PASS: ${name}`); } catch (error) { results.failed++; results.tests.push({ name, status: "FAIL", error: error.message }); console.log(`โŒ FAIL: ${name}`); console.log(` Error: ${error.message}`); } }; } // Test 1: mx.exe exists const testMxExeExists = test("mx.exe exists and is accessible", async () => { await access(DEFAULT_MX_PATH, constants.X_OK); }); // Test 2: .mpr file exists const testMprExists = test("OneTech.mpr file exists", async () => { await access(TEST_MPR, constants.R_OK); }); // Test 3: Create output directory const testOutputDir = test("Can create output directory", async () => { await rm(TEST_OUTPUT, { recursive: true, force: true }); await mkdir(TEST_OUTPUT, { recursive: true }); await access(TEST_OUTPUT, constants.W_OK); }); // Test 4: Extract DomainModel const testDomainModel = test("Extract DomainModel successfully", async () => { const outputFile = join(TEST_OUTPUT, `${TEST_MODULE}-DomainModel.json`); const args = ["dump-mpr", "--unit-type", "DomainModels$DomainModel", "--module-names", TEST_MODULE, "--output-file", outputFile, TEST_MPR]; await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 60000 }); let content = await readFile(outputFile, "utf-8"); // Remove UTF-8 BOM if present if (content.charCodeAt(0) === 0xfeff) { content = content.substring(1); } const size = Buffer.byteLength(content, "utf-8"); if (size < 1000) throw new Error(`File too small: ${size} bytes`); // Validate JSON const json = JSON.parse(content); if (!json || typeof json !== "object") throw new Error("Invalid JSON structure"); console.log(` Size: ${(size / 1024).toFixed(1)}KB`); }); // Test 5: Extract Pages const testPages = test("Extract Pages successfully", async () => { const outputFile = join(TEST_OUTPUT, `${TEST_MODULE}-Pages.json`); const args = ["dump-mpr", "--unit-type", "Pages$Page", "--module-names", TEST_MODULE, "--output-file", outputFile, TEST_MPR]; await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 60000 }); let content = await readFile(outputFile, "utf-8"); // Remove UTF-8 BOM if present if (content.charCodeAt(0) === 0xfeff) { content = content.substring(1); } const size = Buffer.byteLength(content, "utf-8"); if (size < 1000) throw new Error(`File too small: ${size} bytes`); const json = JSON.parse(content); if (!json || typeof json !== "object") throw new Error("Invalid JSON structure"); console.log(` Size: ${(size / 1024).toFixed(1)}KB`); }); // Test 6: Extract Microflows (may be empty) const testMicroflows = test("Extract Microflows (may be empty)", async () => { const outputFile = join(TEST_OUTPUT, `${TEST_MODULE}-Microflows.json`); const args = ["dump-mpr", "--unit-type", "Microflows$Microflow", "--module-names", TEST_MODULE, "--output-file", outputFile, TEST_MPR]; await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 60000 }); let content = await readFile(outputFile, "utf-8"); // Remove UTF-8 BOM if present if (content.charCodeAt(0) === 0xfeff) { content = content.substring(1); } const size = Buffer.byteLength(content, "utf-8"); const json = JSON.parse(content); if (!json || typeof json !== "object") throw new Error("Invalid JSON structure"); const sizeKB = (size / 1024).toFixed(1); const sizeMsg = size < 100 ? " (empty, expected)" : ""; console.log(` Size: ${sizeKB}KB${sizeMsg}`); }); // Test 7: Extract Enumerations const testEnumerations = test("Extract Enumerations successfully", async () => { const outputFile = join(TEST_OUTPUT, `${TEST_MODULE}-Enumerations.json`); const args = ["dump-mpr", "--unit-type", "Enumerations$Enumeration", "--module-names", TEST_MODULE, "--output-file", outputFile, TEST_MPR]; await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 60000 }); let content = await readFile(outputFile, "utf-8"); // Remove UTF-8 BOM if present if (content.charCodeAt(0) === 0xfeff) { content = content.substring(1); } const size = Buffer.byteLength(content, "utf-8"); if (size < 100) throw new Error(`File too small: ${size} bytes`); const json = JSON.parse(content); if (!json || typeof json !== "object") throw new Error("Invalid JSON structure"); console.log(` Size: ${(size / 1024).toFixed(1)}KB`); }); // Test 8: Error handling - invalid .mpr path const testInvalidMpr = test("Handle invalid .mpr path gracefully", async () => { const outputFile = join(TEST_OUTPUT, "test-invalid.json"); const args = ["dump-mpr", "--unit-type", "DomainModels$DomainModel", "--module-names", TEST_MODULE, "--output-file", outputFile, "D:\\NonExistent\\Invalid.mpr"]; try { await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 10000 }); throw new Error("Should have failed with invalid .mpr path"); } catch (error) { // Expected to fail if (error.message.includes("Should have failed")) throw error; console.log(` Expected error: ${error.message.substring(0, 50)}...`); } }); // Test 9: Error handling - invalid module name const testInvalidModule = test("Handle invalid module name gracefully", async () => { const outputFile = join(TEST_OUTPUT, "test-invalid-module.json"); const args = ["dump-mpr", "--unit-type", "DomainModels$DomainModel", "--module-names", "NonExistentModule", "--output-file", outputFile, TEST_MPR]; // This may succeed but return empty results - both are acceptable await execFileAsync(DEFAULT_MX_PATH, args, { maxBuffer: 50 * 1024 * 1024, timeout: 60000 }); let content = await readFile(outputFile, "utf-8"); // Remove UTF-8 BOM if present if (content.charCodeAt(0) === 0xfeff) { content = content.substring(1); } const json = JSON.parse(content); console.log(` Result: ${JSON.stringify(json).length < 50 ? "Empty (expected)" : "Has data"}`); }); // Test 10: Verify compiled TypeScript const testCompiled = test("TypeScript compiled successfully", async () => { await access("dist/index.js", constants.R_OK); await access("dist/index.d.ts", constants.R_OK); const code = await readFile("dist/index.js", "utf-8"); if (!code.includes("OneTech MCP Server")) throw new Error("Compiled code missing header"); if (!code.includes("onetech_extract_module")) throw new Error("Tool not found in compiled code"); console.log(` Size: ${(Buffer.byteLength(code, "utf-8") / 1024).toFixed(1)}KB`); }); // Run all tests async function runAllTests() { console.log("\nโ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"); console.log("โ•‘ OneTech MCP Server - Test Suite โ•‘"); console.log("โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"); const startTime = Date.now(); await testMxExeExists(); await testMprExists(); await testOutputDir(); await testDomainModel(); await testPages(); await testMicroflows(); await testEnumerations(); await testInvalidMpr(); await testInvalidModule(); await testCompiled(); const duration = Date.now() - startTime; console.log("\nโ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"); console.log("โ•‘ Test Results โ•‘"); console.log("โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"); console.log(`\nPassed: ${results.passed}`); console.log(`Failed: ${results.failed}`); console.log(`Total: ${results.passed + results.failed}`); console.log(`Time: ${(duration / 1000).toFixed(1)}s`); if (results.failed > 0) { console.log("\nโŒ FAILED TESTS:"); results.tests .filter((t) => t.status === "FAIL") .forEach((t) => { console.log(` - ${t.name}: ${t.error}`); }); } console.log("\n" + (results.failed === 0 ? "โœ… ALL TESTS PASSED!" : "โŒ SOME TESTS FAILED")); console.log(results.failed === 0 ? "\n๐Ÿš€ Ready to publish to NPM!\n" : "\nโš ๏ธ Fix errors before publishing\n"); return results.failed === 0; } runAllTests() .then((success) => process.exit(success ? 0 : 1)) .catch((error) => { console.error("Fatal error:", error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jordnlvr/onetech-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server