💄 format
This commit is contained in:
6
bin/builders/MacBuilder.ts
vendored
6
bin/builders/MacBuilder.ts
vendored
@@ -40,11 +40,7 @@ export default class MacBuilder extends BaseBuilder {
|
|||||||
: 'npm run tauri build --';
|
: 'npm run tauri build --';
|
||||||
|
|
||||||
// Use temporary config directory to avoid modifying source files
|
// Use temporary config directory to avoid modifying source files
|
||||||
const configPath = path.join(
|
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
||||||
'src-tauri',
|
|
||||||
'.pake',
|
|
||||||
'tauri.conf.json',
|
|
||||||
);
|
|
||||||
let fullCommand = `${baseCommand} --target universal-apple-darwin -c "${configPath}"`;
|
let fullCommand = `${baseCommand} --target universal-apple-darwin -c "${configPath}"`;
|
||||||
|
|
||||||
// Add features
|
// Add features
|
||||||
|
|||||||
16
bin/helpers/tauriConfig.ts
vendored
16
bin/helpers/tauriConfig.ts
vendored
@@ -5,10 +5,18 @@ import { npmDirectory } from '@/utils/dir';
|
|||||||
// Load configs from npm package directory, not from project source
|
// Load configs from npm package directory, not from project source
|
||||||
const tauriSrcDir = path.join(npmDirectory, 'src-tauri');
|
const tauriSrcDir = path.join(npmDirectory, 'src-tauri');
|
||||||
const pakeConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'pake.json'));
|
const pakeConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'pake.json'));
|
||||||
const CommonConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.conf.json'));
|
const CommonConf = fsExtra.readJSONSync(
|
||||||
const WinConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.windows.conf.json'));
|
path.join(tauriSrcDir, 'tauri.conf.json'),
|
||||||
const MacConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.macos.conf.json'));
|
);
|
||||||
const LinuxConf = fsExtra.readJSONSync(path.join(tauriSrcDir, 'tauri.linux.conf.json'));
|
const WinConf = fsExtra.readJSONSync(
|
||||||
|
path.join(tauriSrcDir, 'tauri.windows.conf.json'),
|
||||||
|
);
|
||||||
|
const MacConf = fsExtra.readJSONSync(
|
||||||
|
path.join(tauriSrcDir, 'tauri.macos.conf.json'),
|
||||||
|
);
|
||||||
|
const LinuxConf = fsExtra.readJSONSync(
|
||||||
|
path.join(tauriSrcDir, 'tauri.linux.conf.json'),
|
||||||
|
);
|
||||||
|
|
||||||
const platformConfigs = {
|
const platformConfigs = {
|
||||||
win32: WinConf,
|
win32: WinConf,
|
||||||
|
|||||||
3
rollup.config.js
vendored
3
rollup.config.js
vendored
@@ -11,7 +11,8 @@ import { spawn, exec } from "child_process";
|
|||||||
|
|
||||||
// Set macOS SDK environment variables for compatibility
|
// Set macOS SDK environment variables for compatibility
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
process.env.MACOSX_DEPLOYMENT_TARGET = process.env.MACOSX_DEPLOYMENT_TARGET || "14.0";
|
process.env.MACOSX_DEPLOYMENT_TARGET =
|
||||||
|
process.env.MACOSX_DEPLOYMENT_TARGET || "14.0";
|
||||||
process.env.CFLAGS = process.env.CFLAGS || "-fno-modules";
|
process.env.CFLAGS = process.env.CFLAGS || "-fno-modules";
|
||||||
process.env.CXXFLAGS = process.env.CXXFLAGS || "-fno-modules";
|
process.env.CXXFLAGS = process.env.CXXFLAGS || "-fno-modules";
|
||||||
}
|
}
|
||||||
|
|||||||
4
script/build_with_pake_cli.js
vendored
4
script/build_with_pake_cli.js
vendored
@@ -52,10 +52,10 @@ const main = async () => {
|
|||||||
"src-tauri/target",
|
"src-tauri/target",
|
||||||
"src-tauri/target/debug",
|
"src-tauri/target/debug",
|
||||||
"src-tauri/target/release",
|
"src-tauri/target/release",
|
||||||
"src-tauri/target/universal-apple-darwin"
|
"src-tauri/target/universal-apple-darwin",
|
||||||
];
|
];
|
||||||
|
|
||||||
targetDirs.forEach(dir => {
|
targetDirs.forEach((dir) => {
|
||||||
if (fs.existsSync(dir)) {
|
if (fs.existsSync(dir)) {
|
||||||
// Only remove .pake subdirectories, not the entire target directory
|
// Only remove .pake subdirectories, not the entire target directory
|
||||||
const targetPakeDir = path.join(dir, ".pake");
|
const targetPakeDir = path.join(dir, ".pake");
|
||||||
|
|||||||
@@ -85,14 +85,14 @@ GitHub.com 专用快速构建验证:
|
|||||||
|
|
||||||
## 测试命令
|
## 测试命令
|
||||||
|
|
||||||
| 命令 | 描述 | 覆盖范围 | 持续时间 |
|
| 命令 | 描述 | 覆盖范围 | 持续时间 |
|
||||||
| --------------------------- | -------------------- | ------------------------------- | ----------- |
|
| ---------------------------------- | -------------------- | ----------------------------- | ----------- |
|
||||||
| `npm test` | **真实完整构建测试** | 完整 GitHub.com 应用打包 | **~8 分钟** |
|
| `npm test` | **真实完整构建测试** | 完整 GitHub.com 应用打包 | **~8 分钟** |
|
||||||
| `node tests/index.js` | 基础测试套件 | Unit + Integration + Builder | ~30 秒 |
|
| `node tests/index.js` | 基础测试套件 | Unit + Integration + Builder | ~30 秒 |
|
||||||
| `node tests/index.js --real-build` | 真实构建测试 | 完整 GitHub.com 应用打包 | ~8 分钟 |
|
| `node tests/index.js --real-build` | 真实构建测试 | 完整 GitHub.com 应用打包 | ~8 分钟 |
|
||||||
| `node tests/github.js` | GitHub Actions 测试 | 12 个 GitHub Actions 专项测试 | ~2 分钟 |
|
| `node tests/github.js` | GitHub Actions 测试 | 12 个 GitHub Actions 专项测试 | ~2 分钟 |
|
||||||
| `node tests/build.js` | 快速构建测试 | GitHub.com 构建验证 | ~3 分钟 |
|
| `node tests/build.js` | 快速构建测试 | GitHub.com 构建验证 | ~3 分钟 |
|
||||||
| `node tests/complete.js` | 完整构建测试 | 端到端完整构建流程 | ~10 分钟 |
|
| `node tests/complete.js` | 完整构建测试 | 端到端完整构建流程 | ~10 分钟 |
|
||||||
|
|
||||||
## 高级用法
|
## 高级用法
|
||||||
|
|
||||||
|
|||||||
@@ -47,16 +47,18 @@ const cleanup = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handle cleanup on exit
|
// Handle cleanup on exit
|
||||||
process.on('exit', cleanup);
|
process.on("exit", cleanup);
|
||||||
process.on('SIGINT', () => {
|
process.on("SIGINT", () => {
|
||||||
console.log("\n🛑 Build interrupted by user");
|
console.log("\n🛑 Build interrupted by user");
|
||||||
cleanup();
|
cleanup();
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
process.on('SIGTERM', cleanup);
|
process.on("SIGTERM", cleanup);
|
||||||
|
|
||||||
console.log("🔧 Testing GitHub.com packaging with CLI...");
|
console.log("🔧 Testing GitHub.com packaging with CLI...");
|
||||||
console.log(`Command: node ${config.CLI_PATH} https://github.com --name ${testName} --debug --width 1200 --height 780\n`);
|
console.log(
|
||||||
|
`Command: node ${config.CLI_PATH} https://github.com --name ${testName} --debug --width 1200 --height 780\n`,
|
||||||
|
);
|
||||||
|
|
||||||
const command = `node "${config.CLI_PATH}" "https://github.com" --name "${testName}" --debug --width 1200 --height 780`;
|
const command = `node "${config.CLI_PATH}" "https://github.com" --name "${testName}" --debug --width 1200 --height 780`;
|
||||||
|
|
||||||
@@ -129,18 +131,20 @@ child.stderr.on("data", (data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only show actual errors, filter out build progress
|
// Only show actual errors, filter out build progress
|
||||||
if (!output.includes("warning:") &&
|
if (
|
||||||
!output.includes("verbose") &&
|
!output.includes("warning:") &&
|
||||||
!output.includes("npm info") &&
|
!output.includes("verbose") &&
|
||||||
!output.includes("Installing package") &&
|
!output.includes("npm info") &&
|
||||||
!output.includes("Package installed") &&
|
!output.includes("Installing package") &&
|
||||||
!output.includes("Building app") &&
|
!output.includes("Package installed") &&
|
||||||
!output.includes("Compiling") &&
|
!output.includes("Building app") &&
|
||||||
!output.includes("Finished") &&
|
!output.includes("Compiling") &&
|
||||||
!output.includes("Built application at:") &&
|
!output.includes("Finished") &&
|
||||||
!output.includes("Bundling") &&
|
!output.includes("Built application at:") &&
|
||||||
!output.includes("npm http") &&
|
!output.includes("Bundling") &&
|
||||||
output.trim().length > 0) {
|
!output.includes("npm http") &&
|
||||||
|
output.trim().length > 0
|
||||||
|
) {
|
||||||
console.log("❌ Build error:", output.trim());
|
console.log("❌ Build error:", output.trim());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -157,7 +161,9 @@ const timeout = setTimeout(() => {
|
|||||||
console.log(" - Configuration generated for GitHub.com ✓");
|
console.log(" - Configuration generated for GitHub.com ✓");
|
||||||
console.log("\n🎯 Test Result: PASS");
|
console.log("\n🎯 Test Result: PASS");
|
||||||
console.log(" The GitHub.com app build is working correctly.");
|
console.log(" The GitHub.com app build is working correctly.");
|
||||||
console.log(" Build was terminated early to save time, but core functionality verified.");
|
console.log(
|
||||||
|
" Build was terminated early to save time, but core functionality verified.",
|
||||||
|
);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} else if (buildStarted) {
|
} else if (buildStarted) {
|
||||||
console.log("⚠️ PARTIAL: Build started but compilation not detected");
|
console.log("⚠️ PARTIAL: Build started but compilation not detected");
|
||||||
@@ -190,7 +196,9 @@ child.on("close", (code) => {
|
|||||||
console.log(" All critical build stages detected.");
|
console.log(" All critical build stages detected.");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} else if (buildStarted) {
|
} else if (buildStarted) {
|
||||||
console.log("\n⚠️ PARTIAL SUCCESS: Build started but may not have completed");
|
console.log(
|
||||||
|
"\n⚠️ PARTIAL SUCCESS: Build started but may not have completed",
|
||||||
|
);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} else {
|
} else {
|
||||||
console.log("\n❌ FAILED: Build did not start properly");
|
console.log("\n❌ FAILED: Build did not start properly");
|
||||||
|
|||||||
@@ -47,16 +47,18 @@ const cleanup = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handle cleanup on exit
|
// Handle cleanup on exit
|
||||||
process.on('exit', cleanup);
|
process.on("exit", cleanup);
|
||||||
process.on('SIGINT', () => {
|
process.on("SIGINT", () => {
|
||||||
console.log("\n🛑 Build interrupted by user");
|
console.log("\n🛑 Build interrupted by user");
|
||||||
cleanup();
|
cleanup();
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
process.on('SIGTERM', cleanup);
|
process.on("SIGTERM", cleanup);
|
||||||
|
|
||||||
console.log("🔧 Testing GitHub app packaging with optimal settings...");
|
console.log("🔧 Testing GitHub app packaging with optimal settings...");
|
||||||
console.log(`Command: pake https://github.com --name ${testName} --width 1200 --height 800 --hide-title-bar\n`);
|
console.log(
|
||||||
|
`Command: pake https://github.com --name ${testName} --width 1200 --height 800 --hide-title-bar\n`,
|
||||||
|
);
|
||||||
|
|
||||||
const command = `node "${config.CLI_PATH}" "https://github.com" --name "${testName}" --width 1200 --height 800 --hide-title-bar`;
|
const command = `node "${config.CLI_PATH}" "https://github.com" --name "${testName}" --width 1200 --height 800 --hide-title-bar`;
|
||||||
|
|
||||||
@@ -137,19 +139,21 @@ child.stderr.on("data", (data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only show actual errors, filter out build progress
|
// Only show actual errors, filter out build progress
|
||||||
if (!output.includes("warning:") &&
|
if (
|
||||||
!output.includes("verbose") &&
|
!output.includes("warning:") &&
|
||||||
!output.includes("npm info") &&
|
!output.includes("verbose") &&
|
||||||
!output.includes("Installing package") &&
|
!output.includes("npm info") &&
|
||||||
!output.includes("Package installed") &&
|
!output.includes("Installing package") &&
|
||||||
!output.includes("Building app") &&
|
!output.includes("Package installed") &&
|
||||||
!output.includes("Compiling") &&
|
!output.includes("Building app") &&
|
||||||
!output.includes("Finished") &&
|
!output.includes("Compiling") &&
|
||||||
!output.includes("Built application at:") &&
|
!output.includes("Finished") &&
|
||||||
!output.includes("Bundling") &&
|
!output.includes("Built application at:") &&
|
||||||
!output.includes("npm http") &&
|
!output.includes("Bundling") &&
|
||||||
!output.includes("Info Looking up installed") &&
|
!output.includes("npm http") &&
|
||||||
output.trim().length > 0) {
|
!output.includes("Info Looking up installed") &&
|
||||||
|
output.trim().length > 0
|
||||||
|
) {
|
||||||
console.log("❌ Build error:", output.trim());
|
console.log("❌ Build error:", output.trim());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -201,8 +205,12 @@ child.on("close", (code) => {
|
|||||||
|
|
||||||
console.log(`App Bundle Structure:`);
|
console.log(`App Bundle Structure:`);
|
||||||
console.log(` Contents/: ${fs.existsSync(contentsPath) ? "✅" : "❌"}`);
|
console.log(` Contents/: ${fs.existsSync(contentsPath) ? "✅" : "❌"}`);
|
||||||
console.log(` Contents/MacOS/: ${fs.existsSync(macOSPath) ? "✅" : "❌"}`);
|
console.log(
|
||||||
console.log(` Contents/Resources/: ${fs.existsSync(resourcesPath) ? "✅" : "❌"}`);
|
` Contents/MacOS/: ${fs.existsSync(macOSPath) ? "✅" : "❌"}`,
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
` Contents/Resources/: ${fs.existsSync(resourcesPath) ? "✅" : "❌"}`,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`App Bundle Check: ❌ (${error.message})`);
|
console.log(`App Bundle Check: ❌ (${error.message})`);
|
||||||
}
|
}
|
||||||
@@ -221,7 +229,9 @@ child.on("close", (code) => {
|
|||||||
console.log(" 🎯 Build process successful");
|
console.log(" 🎯 Build process successful");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} else if (code === 0 && buildStarted && compilationStarted) {
|
} else if (code === 0 && buildStarted && compilationStarted) {
|
||||||
console.log("\n⚠️ PARTIAL SUCCESS: Build process completed but no app file found");
|
console.log(
|
||||||
|
"\n⚠️ PARTIAL SUCCESS: Build process completed but no app file found",
|
||||||
|
);
|
||||||
console.log(" 🐙 GitHub.com build process executed successfully");
|
console.log(" 🐙 GitHub.com build process executed successfully");
|
||||||
console.log(" ⚠️ App file may be in a different location");
|
console.log(" ⚠️ App file may be in a different location");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
|||||||
@@ -161,8 +161,12 @@ class PakeCliTestRunner {
|
|||||||
console.log("🚀 GitHub Actions Usage Guide:");
|
console.log("🚀 GitHub Actions Usage Guide:");
|
||||||
console.log("==============================\n");
|
console.log("==============================\n");
|
||||||
|
|
||||||
console.log("This test suite validates that pake-cli works correctly in GitHub Actions.");
|
console.log(
|
||||||
console.log("The following workflow file (.github/workflows/pake-cli.yaml) is ready to use:\n");
|
"This test suite validates that pake-cli works correctly in GitHub Actions.",
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"The following workflow file (.github/workflows/pake-cli.yaml) is ready to use:\n",
|
||||||
|
);
|
||||||
|
|
||||||
console.log("Key features tested:");
|
console.log("Key features tested:");
|
||||||
console.log(" ✅ npm package installation and caching");
|
console.log(" ✅ npm package installation and caching");
|
||||||
@@ -327,7 +331,9 @@ process.exit(cleanedDirs > 0 ? 0 : 1);
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Verify .pake directory was cleaned
|
// Verify .pake directory was cleaned
|
||||||
return !fs.existsSync(pakeDir) && result.includes("Cleaned directories: 1");
|
return (
|
||||||
|
!fs.existsSync(pakeDir) && result.includes("Cleaned directories: 1")
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Cleanup test failed:", error.message);
|
console.error("Cleanup test failed:", error.message);
|
||||||
return false;
|
return false;
|
||||||
@@ -384,8 +390,10 @@ process.exit(validResults && invalidResults ? 0 : 1);
|
|||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.includes("Valid URLs passed: true") &&
|
return (
|
||||||
result.includes("Invalid URLs rejected: true");
|
result.includes("Valid URLs passed: true") &&
|
||||||
|
result.includes("Invalid URLs rejected: true")
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -432,7 +440,9 @@ process.exit(isSupported ? 0 : 1);
|
|||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.includes("Platform:") && result.includes("Expected extension:");
|
return (
|
||||||
|
result.includes("Platform:") && result.includes("Expected extension:")
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -513,7 +523,10 @@ runner.addTest(
|
|||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
// Check if the workflow file exists and has correct structure
|
// Check if the workflow file exists and has correct structure
|
||||||
const workflowPath = path.join(config.PROJECT_ROOT, ".github/workflows/pake-cli.yaml");
|
const workflowPath = path.join(
|
||||||
|
config.PROJECT_ROOT,
|
||||||
|
".github/workflows/pake-cli.yaml",
|
||||||
|
);
|
||||||
|
|
||||||
if (!fs.existsSync(workflowPath)) {
|
if (!fs.existsSync(workflowPath)) {
|
||||||
console.error("Workflow file not found:", workflowPath);
|
console.error("Workflow file not found:", workflowPath);
|
||||||
@@ -529,17 +542,17 @@ runner.addTest(
|
|||||||
"node ./script/build_with_pake_cli.js", // Build script execution
|
"node ./script/build_with_pake_cli.js", // Build script execution
|
||||||
"ubuntu-24.04", // Linux support
|
"ubuntu-24.04", // Linux support
|
||||||
"macos-latest", // macOS support
|
"macos-latest", // macOS support
|
||||||
"windows-latest" // Windows support
|
"windows-latest", // Windows support
|
||||||
];
|
];
|
||||||
|
|
||||||
const hasAllElements = requiredElements.every(element =>
|
const hasAllElements = requiredElements.every((element) =>
|
||||||
workflowContent.includes(element)
|
workflowContent.includes(element),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasAllElements) {
|
if (!hasAllElements) {
|
||||||
console.error("Workflow missing required elements");
|
console.error("Workflow missing required elements");
|
||||||
const missing = requiredElements.filter(element =>
|
const missing = requiredElements.filter(
|
||||||
!workflowContent.includes(element)
|
(element) => !workflowContent.includes(element),
|
||||||
);
|
);
|
||||||
console.error("Missing elements:", missing);
|
console.error("Missing elements:", missing);
|
||||||
}
|
}
|
||||||
@@ -761,10 +774,12 @@ process.exit(validBuild ? 0 : 1);
|
|||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.includes("GitHub Actions GitHub.com build simulation started") &&
|
return (
|
||||||
result.includes("URL: https://github.com") &&
|
result.includes("GitHub Actions GitHub.com build simulation started") &&
|
||||||
result.includes("NAME: github") &&
|
result.includes("URL: https://github.com") &&
|
||||||
result.includes("Build configuration valid: true");
|
result.includes("NAME: github") &&
|
||||||
|
result.includes("Build configuration valid: true")
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("GitHub Actions simulation failed:", error.message);
|
console.error("GitHub Actions simulation failed:", error.message);
|
||||||
return false;
|
return false;
|
||||||
@@ -833,9 +848,11 @@ process.exit(validParams ? 0 : 1);
|
|||||||
timeout: 8000,
|
timeout: 8000,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.includes("GitHub.com build parameters validated: true") &&
|
return (
|
||||||
result.includes("URL: https://github.com") &&
|
result.includes("GitHub.com build parameters validated: true") &&
|
||||||
result.includes("App name: github");
|
result.includes("URL: https://github.com") &&
|
||||||
|
result.includes("App name: github")
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Build script test failed:", error.message);
|
console.error("Build script test failed:", error.message);
|
||||||
return false;
|
return false;
|
||||||
@@ -847,7 +864,8 @@ process.exit(validParams ? 0 : 1);
|
|||||||
|
|
||||||
// Run the test suite
|
// Run the test suite
|
||||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
runner.runAll()
|
runner
|
||||||
|
.runAll()
|
||||||
.then((success) => {
|
.then((success) => {
|
||||||
process.exit(success ? 0 : 1);
|
process.exit(success ? 0 : 1);
|
||||||
})
|
})
|
||||||
|
|||||||
530
tests/index.js
530
tests/index.js
@@ -28,7 +28,7 @@ class PakeTestRunner {
|
|||||||
pakeCliTests = false,
|
pakeCliTests = false,
|
||||||
e2e = false,
|
e2e = false,
|
||||||
quick = false,
|
quick = false,
|
||||||
realBuild = false // Add option for real build test
|
realBuild = false, // Add option for real build test
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
console.log("🚀 Pake CLI Test Suite");
|
console.log("🚀 Pake CLI Test Suite");
|
||||||
@@ -74,7 +74,7 @@ class PakeTestRunner {
|
|||||||
testCount++;
|
testCount++;
|
||||||
|
|
||||||
// Add multi-arch test on macOS
|
// Add multi-arch test on macOS
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === "darwin") {
|
||||||
console.log("\n🔧 Running Multi-Arch Build Test...");
|
console.log("\n🔧 Running Multi-Arch Build Test...");
|
||||||
await this.runMultiArchBuildTest();
|
await this.runMultiArchBuildTest();
|
||||||
testCount++;
|
testCount++;
|
||||||
@@ -89,7 +89,7 @@ class PakeTestRunner {
|
|||||||
this.cleanup();
|
this.cleanup();
|
||||||
this.displayFinalResults();
|
this.displayFinalResults();
|
||||||
|
|
||||||
const passed = this.results.filter(r => r.passed).length;
|
const passed = this.results.filter((r) => r.passed).length;
|
||||||
const total = this.results.length;
|
const total = this.results.length;
|
||||||
|
|
||||||
return passed === total;
|
return passed === total;
|
||||||
@@ -135,7 +135,7 @@ class PakeTestRunner {
|
|||||||
const result = await Promise.race([
|
const result = await Promise.race([
|
||||||
testFn(),
|
testFn(),
|
||||||
new Promise((_, reject) =>
|
new Promise((_, reject) =>
|
||||||
setTimeout(() => reject(new Error("Test timeout")), timeout)
|
setTimeout(() => reject(new Error("Test timeout")), timeout),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ class PakeTestRunner {
|
|||||||
this.results.push({
|
this.results.push({
|
||||||
name,
|
name,
|
||||||
passed: false,
|
passed: false,
|
||||||
error: error.message
|
error: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ class PakeTestRunner {
|
|||||||
});
|
});
|
||||||
return /^\d+\.\d+\.\d+/.test(output.trim());
|
return /^\d+\.\d+\.\d+/.test(output.trim());
|
||||||
},
|
},
|
||||||
TIMEOUTS.QUICK
|
TIMEOUTS.QUICK,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Help command test
|
// Help command test
|
||||||
@@ -180,174 +180,151 @@ class PakeTestRunner {
|
|||||||
});
|
});
|
||||||
return output.includes("Usage: cli [url] [options]");
|
return output.includes("Usage: cli [url] [options]");
|
||||||
},
|
},
|
||||||
TIMEOUTS.QUICK
|
TIMEOUTS.QUICK,
|
||||||
);
|
);
|
||||||
|
|
||||||
// URL validation test
|
// URL validation test
|
||||||
await this.runTest(
|
await this.runTest("URL Validation", () => {
|
||||||
"URL Validation",
|
try {
|
||||||
() => {
|
execSync(`node "${config.CLI_PATH}" "invalid-url" --name TestApp`, {
|
||||||
try {
|
|
||||||
execSync(`node "${config.CLI_PATH}" "invalid-url" --name TestApp`, {
|
|
||||||
encoding: "utf8",
|
|
||||||
timeout: 3000,
|
|
||||||
});
|
|
||||||
return false; // Should have failed
|
|
||||||
} catch (error) {
|
|
||||||
return error.status !== 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Number validation test
|
|
||||||
await this.runTest(
|
|
||||||
"Number Validation",
|
|
||||||
() => {
|
|
||||||
try {
|
|
||||||
execSync(`node "${config.CLI_PATH}" https://example.com --width abc`, {
|
|
||||||
encoding: "utf8",
|
|
||||||
timeout: 3000,
|
|
||||||
});
|
|
||||||
return false; // Should throw error
|
|
||||||
} catch (error) {
|
|
||||||
return error.message.includes("Not a number");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// CLI response time test
|
|
||||||
await this.runTest(
|
|
||||||
"CLI Response Time",
|
|
||||||
() => {
|
|
||||||
const start = Date.now();
|
|
||||||
execSync(`node "${config.CLI_PATH}" --version`, {
|
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
timeout: 3000,
|
timeout: 3000,
|
||||||
});
|
});
|
||||||
const elapsed = Date.now() - start;
|
return false; // Should have failed
|
||||||
return elapsed < 2000;
|
} catch (error) {
|
||||||
|
return error.status !== 0;
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
|
// Number validation test
|
||||||
|
await this.runTest("Number Validation", () => {
|
||||||
|
try {
|
||||||
|
execSync(`node "${config.CLI_PATH}" https://example.com --width abc`, {
|
||||||
|
encoding: "utf8",
|
||||||
|
timeout: 3000,
|
||||||
|
});
|
||||||
|
return false; // Should throw error
|
||||||
|
} catch (error) {
|
||||||
|
return error.message.includes("Not a number");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// CLI response time test
|
||||||
|
await this.runTest("CLI Response Time", () => {
|
||||||
|
const start = Date.now();
|
||||||
|
execSync(`node "${config.CLI_PATH}" --version`, {
|
||||||
|
encoding: "utf8",
|
||||||
|
timeout: 3000,
|
||||||
|
});
|
||||||
|
const elapsed = Date.now() - start;
|
||||||
|
return elapsed < 2000;
|
||||||
|
});
|
||||||
|
|
||||||
// Weekly URL accessibility test
|
// Weekly URL accessibility test
|
||||||
await this.runTest(
|
await this.runTest("Weekly URL Accessibility", () => {
|
||||||
"Weekly URL Accessibility",
|
try {
|
||||||
() => {
|
const testCommand = `node "${config.CLI_PATH}" ${TEST_URLS.WEEKLY} --name "URLTest" --debug`;
|
||||||
try {
|
execSync(`echo "n" | timeout 5s ${testCommand} || true`, {
|
||||||
const testCommand = `node "${config.CLI_PATH}" ${TEST_URLS.WEEKLY} --name "URLTest" --debug`;
|
encoding: "utf8",
|
||||||
execSync(`echo "n" | timeout 5s ${testCommand} || true`, {
|
timeout: 8000,
|
||||||
encoding: "utf8",
|
});
|
||||||
timeout: 8000,
|
return true; // If we get here, URL was parsed successfully
|
||||||
});
|
} catch (error) {
|
||||||
return true; // If we get here, URL was parsed successfully
|
return (
|
||||||
} catch (error) {
|
!error.message.includes("Invalid URL") &&
|
||||||
return !error.message.includes("Invalid URL") && !error.message.includes("invalid");
|
!error.message.includes("invalid")
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async runIntegrationTests() {
|
async runIntegrationTests() {
|
||||||
// Process spawning test
|
// Process spawning test
|
||||||
await this.runTest(
|
await this.runTest("CLI Process Spawning", () => {
|
||||||
"CLI Process Spawning",
|
return new Promise((resolve) => {
|
||||||
() => {
|
const child = spawn("node", [config.CLI_PATH, "--version"], {
|
||||||
return new Promise((resolve) => {
|
stdio: ["pipe", "pipe", "pipe"],
|
||||||
const child = spawn("node", [config.CLI_PATH, "--version"], {
|
|
||||||
stdio: ["pipe", "pipe", "pipe"],
|
|
||||||
});
|
|
||||||
|
|
||||||
let output = "";
|
|
||||||
child.stdout.on("data", (data) => {
|
|
||||||
output += data.toString();
|
|
||||||
});
|
|
||||||
|
|
||||||
child.on("close", (code) => {
|
|
||||||
resolve(code === 0 && /\d+\.\d+\.\d+/.test(output));
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
child.kill();
|
|
||||||
resolve(false);
|
|
||||||
}, 3000);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
let output = "";
|
||||||
|
child.stdout.on("data", (data) => {
|
||||||
|
output += data.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on("close", (code) => {
|
||||||
|
resolve(code === 0 && /\d+\.\d+\.\d+/.test(output));
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
child.kill();
|
||||||
|
resolve(false);
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// File system permissions test
|
// File system permissions test
|
||||||
await this.runTest(
|
await this.runTest("File System Permissions", () => {
|
||||||
"File System Permissions",
|
try {
|
||||||
() => {
|
const testFile = "test-write-permission.tmp";
|
||||||
try {
|
fs.writeFileSync(testFile, "test");
|
||||||
const testFile = "test-write-permission.tmp";
|
this.trackTempFile(testFile);
|
||||||
fs.writeFileSync(testFile, "test");
|
|
||||||
this.trackTempFile(testFile);
|
|
||||||
|
|
||||||
const cliStats = fs.statSync(config.CLI_PATH);
|
const cliStats = fs.statSync(config.CLI_PATH);
|
||||||
return cliStats.isFile();
|
return cliStats.isFile();
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
// Dependency resolution test
|
// Dependency resolution test
|
||||||
await this.runTest(
|
await this.runTest("Dependency Resolution", () => {
|
||||||
"Dependency Resolution",
|
try {
|
||||||
() => {
|
const packageJsonPath = path.join(config.PROJECT_ROOT, "package.json");
|
||||||
try {
|
const packageJson = JSON.parse(
|
||||||
const packageJsonPath = path.join(config.PROJECT_ROOT, "package.json");
|
fs.readFileSync(packageJsonPath, "utf8"),
|
||||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
);
|
||||||
|
|
||||||
const essentialDeps = ["commander", "chalk", "fs-extra", "execa"];
|
const essentialDeps = ["commander", "chalk", "fs-extra", "execa"];
|
||||||
return essentialDeps.every(dep => packageJson.dependencies && packageJson.dependencies[dep]);
|
return essentialDeps.every(
|
||||||
} catch {
|
(dep) => packageJson.dependencies && packageJson.dependencies[dep],
|
||||||
return false;
|
);
|
||||||
}
|
} catch {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async runBuilderTests() {
|
async runBuilderTests() {
|
||||||
// Platform detection test
|
// Platform detection test
|
||||||
await this.runTest(
|
await this.runTest("Platform Detection", () => {
|
||||||
"Platform Detection",
|
const platform = process.platform;
|
||||||
() => {
|
const platformConfigs = {
|
||||||
const platform = process.platform;
|
darwin: { ext: ".dmg", multiArch: true },
|
||||||
const platformConfigs = {
|
win32: { ext: ".msi", multiArch: false },
|
||||||
darwin: { ext: '.dmg', multiArch: true },
|
linux: { ext: ".deb", multiArch: false },
|
||||||
win32: { ext: '.msi', multiArch: false },
|
};
|
||||||
linux: { ext: '.deb', multiArch: false }
|
|
||||||
};
|
|
||||||
|
|
||||||
const config = platformConfigs[platform];
|
const config = platformConfigs[platform];
|
||||||
return config && typeof config.ext === 'string';
|
return config && typeof config.ext === "string";
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// Architecture detection test
|
// Architecture detection test
|
||||||
await this.runTest(
|
await this.runTest("Architecture Detection", () => {
|
||||||
"Architecture Detection",
|
const currentArch = process.arch;
|
||||||
() => {
|
const macArch = currentArch === "arm64" ? "aarch64" : currentArch;
|
||||||
const currentArch = process.arch;
|
const linuxArch = currentArch === "x64" ? "amd64" : currentArch;
|
||||||
const macArch = currentArch === "arm64" ? "aarch64" : currentArch;
|
|
||||||
const linuxArch = currentArch === "x64" ? "amd64" : currentArch;
|
|
||||||
|
|
||||||
return typeof macArch === "string" && typeof linuxArch === "string";
|
return typeof macArch === "string" && typeof linuxArch === "string";
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// File naming pattern test
|
// File naming pattern test
|
||||||
await this.runTest(
|
await this.runTest("File Naming Patterns", () => {
|
||||||
"File Naming Patterns",
|
const testNames = ["Simple App", "App-With_Symbols", "CamelCaseApp"];
|
||||||
() => {
|
return testNames.every((name) => {
|
||||||
const testNames = ["Simple App", "App-With_Symbols", "CamelCaseApp"];
|
const processed = name.toLowerCase().replace(/\s+/g, "");
|
||||||
return testNames.every(name => {
|
return processed.length > 0;
|
||||||
const processed = name.toLowerCase().replace(/\s+/g, "");
|
});
|
||||||
return processed.length > 0;
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async runPakeCliTests() {
|
async runPakeCliTests() {
|
||||||
@@ -369,63 +346,59 @@ class PakeTestRunner {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TIMEOUTS.LONG
|
TIMEOUTS.LONG,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Version command test
|
// Version command test
|
||||||
await this.runTest(
|
await this.runTest("pake-cli Version Command", async () => {
|
||||||
"pake-cli Version Command",
|
try {
|
||||||
async () => {
|
const version = execSync("npx pake --version", {
|
||||||
try {
|
encoding: "utf8",
|
||||||
const version = execSync("npx pake --version", {
|
timeout: 10000,
|
||||||
encoding: "utf8",
|
});
|
||||||
timeout: 10000,
|
return /^\d+\.\d+\.\d+/.test(version.trim());
|
||||||
});
|
} catch {
|
||||||
return /^\d+\.\d+\.\d+/.test(version.trim());
|
return false;
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
// Configuration validation test
|
// Configuration validation test
|
||||||
await this.runTest(
|
await this.runTest("Configuration Validation", async () => {
|
||||||
"Configuration Validation",
|
try {
|
||||||
async () => {
|
const validateConfig = (config) => {
|
||||||
try {
|
const required = ["url", "name", "width", "height"];
|
||||||
const validateConfig = (config) => {
|
const hasRequired = required.every((field) =>
|
||||||
const required = ['url', 'name', 'width', 'height'];
|
config.hasOwnProperty(field),
|
||||||
const hasRequired = required.every(field => config.hasOwnProperty(field));
|
);
|
||||||
|
|
||||||
const validTypes =
|
const validTypes =
|
||||||
typeof config.url === 'string' &&
|
typeof config.url === "string" &&
|
||||||
typeof config.name === 'string' &&
|
typeof config.name === "string" &&
|
||||||
typeof config.width === 'number' &&
|
typeof config.width === "number" &&
|
||||||
typeof config.height === 'number';
|
typeof config.height === "number";
|
||||||
|
|
||||||
let validUrl = false;
|
let validUrl = false;
|
||||||
try {
|
try {
|
||||||
new URL(config.url);
|
new URL(config.url);
|
||||||
validUrl = true;
|
validUrl = true;
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
const validName = config.name.length > 0;
|
const validName = config.name.length > 0;
|
||||||
return hasRequired && validTypes && validUrl && validName;
|
return hasRequired && validTypes && validUrl && validName;
|
||||||
};
|
};
|
||||||
|
|
||||||
const testConfig = {
|
const testConfig = {
|
||||||
url: 'https://github.com',
|
url: "https://github.com",
|
||||||
name: 'github',
|
name: "github",
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 780
|
height: 780,
|
||||||
};
|
};
|
||||||
|
|
||||||
return validateConfig(testConfig);
|
return validateConfig(testConfig);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async runE2ETests() {
|
async runE2ETests() {
|
||||||
@@ -453,20 +426,32 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
child.stdout.on("data", (data) => {
|
child.stdout.on("data", (data) => {
|
||||||
const output = data.toString();
|
const output = data.toString();
|
||||||
if (output.includes("Building app") || output.includes("Compiling") ||
|
if (
|
||||||
output.includes("Installing package") || output.includes("Bundling")) {
|
output.includes("Building app") ||
|
||||||
|
output.includes("Compiling") ||
|
||||||
|
output.includes("Installing package") ||
|
||||||
|
output.includes("Bundling")
|
||||||
|
) {
|
||||||
buildStarted = true;
|
buildStarted = true;
|
||||||
}
|
}
|
||||||
if (output.includes("GitHub") && (output.includes("config") || output.includes("name"))) {
|
if (
|
||||||
|
output.includes("GitHub") &&
|
||||||
|
(output.includes("config") || output.includes("name"))
|
||||||
|
) {
|
||||||
configGenerated = true;
|
configGenerated = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stderr.on("data", (data) => {
|
child.stderr.on("data", (data) => {
|
||||||
const output = data.toString();
|
const output = data.toString();
|
||||||
if (output.includes("Building app") || output.includes("Compiling") ||
|
if (
|
||||||
output.includes("Installing package") || output.includes("Bundling") ||
|
output.includes("Building app") ||
|
||||||
output.includes("Finished") || output.includes("Built application at:")) {
|
output.includes("Compiling") ||
|
||||||
|
output.includes("Installing package") ||
|
||||||
|
output.includes("Bundling") ||
|
||||||
|
output.includes("Finished") ||
|
||||||
|
output.includes("Built application at:")
|
||||||
|
) {
|
||||||
buildStarted = true;
|
buildStarted = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -481,10 +466,14 @@ class PakeTestRunner {
|
|||||||
this.trackTempFile(dmgFile);
|
this.trackTempFile(dmgFile);
|
||||||
|
|
||||||
if (buildStarted) {
|
if (buildStarted) {
|
||||||
console.log(`✓ GitHub.com CLI build started successfully (${testName})`);
|
console.log(
|
||||||
|
`✓ GitHub.com CLI build started successfully (${testName})`,
|
||||||
|
);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error("GitHub.com CLI build did not start within timeout"));
|
reject(
|
||||||
|
new Error("GitHub.com CLI build did not start within timeout"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
@@ -498,18 +487,22 @@ class PakeTestRunner {
|
|||||||
if (buildStarted) {
|
if (buildStarted) {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error("GitHub.com CLI build process ended before starting"));
|
reject(
|
||||||
|
new Error("GitHub.com CLI build process ended before starting"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
child.on("error", (error) => {
|
child.on("error", (error) => {
|
||||||
reject(new Error(`GitHub.com CLI build process error: ${error.message}`));
|
reject(
|
||||||
|
new Error(`GitHub.com CLI build process error: ${error.message}`),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stdin.end();
|
child.stdin.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
70000 // 70 seconds timeout
|
70000, // 70 seconds timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
// Configuration verification test
|
// Configuration verification test
|
||||||
@@ -540,14 +533,22 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
if (fs.existsSync(configFile) && fs.existsSync(pakeConfigFile)) {
|
if (fs.existsSync(configFile) && fs.existsSync(pakeConfigFile)) {
|
||||||
try {
|
try {
|
||||||
const config = JSON.parse(fs.readFileSync(configFile, "utf8"));
|
const config = JSON.parse(
|
||||||
const pakeConfig = JSON.parse(fs.readFileSync(pakeConfigFile, "utf8"));
|
fs.readFileSync(configFile, "utf8"),
|
||||||
|
);
|
||||||
|
const pakeConfig = JSON.parse(
|
||||||
|
fs.readFileSync(pakeConfigFile, "utf8"),
|
||||||
|
);
|
||||||
|
|
||||||
if (config.productName === testName &&
|
if (
|
||||||
pakeConfig.windows[0].url === "https://github.com/") {
|
config.productName === testName &&
|
||||||
|
pakeConfig.windows[0].url === "https://github.com/"
|
||||||
|
) {
|
||||||
child.kill("SIGTERM");
|
child.kill("SIGTERM");
|
||||||
this.trackTempDir(pakeDir);
|
this.trackTempDir(pakeDir);
|
||||||
console.log("✓ GitHub.com configuration files verified correctly");
|
console.log(
|
||||||
|
"✓ GitHub.com configuration files verified correctly",
|
||||||
|
);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -561,15 +562,21 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
child.stdout.on("data", (data) => {
|
child.stdout.on("data", (data) => {
|
||||||
const output = data.toString();
|
const output = data.toString();
|
||||||
if (output.includes("Installing package") || output.includes("Building app")) {
|
if (
|
||||||
|
output.includes("Installing package") ||
|
||||||
|
output.includes("Building app")
|
||||||
|
) {
|
||||||
setTimeout(checkConfigFiles, 1000);
|
setTimeout(checkConfigFiles, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stderr.on("data", (data) => {
|
child.stderr.on("data", (data) => {
|
||||||
const output = data.toString();
|
const output = data.toString();
|
||||||
if (output.includes("Installing package") || output.includes("Building app") ||
|
if (
|
||||||
output.includes("Package installed")) {
|
output.includes("Installing package") ||
|
||||||
|
output.includes("Building app") ||
|
||||||
|
output.includes("Package installed")
|
||||||
|
) {
|
||||||
setTimeout(checkConfigFiles, 1000);
|
setTimeout(checkConfigFiles, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -582,13 +589,17 @@ class PakeTestRunner {
|
|||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
child.on("error", (error) => {
|
child.on("error", (error) => {
|
||||||
reject(new Error(`GitHub.com config verification error: ${error.message}`));
|
reject(
|
||||||
|
new Error(
|
||||||
|
`GitHub.com config verification error: ${error.message}`,
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stdin.end();
|
child.stdin.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
25000
|
25000,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,7 +662,8 @@ class PakeTestRunner {
|
|||||||
if (output.includes("Building app")) buildStarted = true;
|
if (output.includes("Building app")) buildStarted = true;
|
||||||
if (output.includes("Compiling")) compilationStarted = true;
|
if (output.includes("Compiling")) compilationStarted = true;
|
||||||
if (output.includes("Bundling")) bundlingStarted = true;
|
if (output.includes("Bundling")) bundlingStarted = true;
|
||||||
if (output.includes("Finished")) console.log(" ✅ Compilation finished!");
|
if (output.includes("Finished"))
|
||||||
|
console.log(" ✅ Compilation finished!");
|
||||||
if (output.includes("Built application at:")) buildCompleted = true;
|
if (output.includes("Built application at:")) buildCompleted = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -661,7 +673,9 @@ class PakeTestRunner {
|
|||||||
const dmgExists = fs.existsSync(dmgFile);
|
const dmgExists = fs.existsSync(dmgFile);
|
||||||
|
|
||||||
if (appExists) {
|
if (appExists) {
|
||||||
console.log(" 🎉 Build completed successfully (app file exists)!");
|
console.log(
|
||||||
|
" 🎉 Build completed successfully (app file exists)!",
|
||||||
|
);
|
||||||
console.log(` 📱 App location: ${appFile}`);
|
console.log(` 📱 App location: ${appFile}`);
|
||||||
if (dmgExists) {
|
if (dmgExists) {
|
||||||
console.log(` 💿 DMG location: ${dmgFile}`);
|
console.log(` 💿 DMG location: ${dmgFile}`);
|
||||||
@@ -696,7 +710,9 @@ class PakeTestRunner {
|
|||||||
console.log(" ✨ Build artifacts preserved for inspection");
|
console.log(" ✨ Build artifacts preserved for inspection");
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else if (code === 0 && buildStarted && compilationStarted) {
|
} else if (code === 0 && buildStarted && compilationStarted) {
|
||||||
console.log(" ⚠️ Build process completed but no app file found");
|
console.log(
|
||||||
|
" ⚠️ Build process completed but no app file found",
|
||||||
|
);
|
||||||
console.log(` 📍 Expected location: ${appFile}`);
|
console.log(` 📍 Expected location: ${appFile}`);
|
||||||
resolve(false);
|
resolve(false);
|
||||||
} else {
|
} else {
|
||||||
@@ -706,13 +722,15 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
child.on("error", (error) => {
|
child.on("error", (error) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
reject(new Error(`Real build test process error: ${error.message}`));
|
reject(
|
||||||
|
new Error(`Real build test process error: ${error.message}`),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stdin.end();
|
child.stdin.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
500000 // 8+ minutes timeout
|
500000, // 8+ minutes timeout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +780,10 @@ class PakeTestRunner {
|
|||||||
compilationStarted = true;
|
compilationStarted = true;
|
||||||
console.log(" ⚙️ Compiling for multiple architectures...");
|
console.log(" ⚙️ Compiling for multiple architectures...");
|
||||||
}
|
}
|
||||||
if (output.includes("universal-apple-darwin") || output.includes("Universal")) {
|
if (
|
||||||
|
output.includes("universal-apple-darwin") ||
|
||||||
|
output.includes("Universal")
|
||||||
|
) {
|
||||||
multiArchDetected = true;
|
multiArchDetected = true;
|
||||||
console.log(" 🔀 Universal binary target detected");
|
console.log(" 🔀 Universal binary target detected");
|
||||||
}
|
}
|
||||||
@@ -780,9 +801,11 @@ class PakeTestRunner {
|
|||||||
const output = data.toString();
|
const output = data.toString();
|
||||||
if (output.includes("Building app")) buildStarted = true;
|
if (output.includes("Building app")) buildStarted = true;
|
||||||
if (output.includes("Compiling")) compilationStarted = true;
|
if (output.includes("Compiling")) compilationStarted = true;
|
||||||
if (output.includes("universal-apple-darwin")) multiArchDetected = true;
|
if (output.includes("universal-apple-darwin"))
|
||||||
|
multiArchDetected = true;
|
||||||
if (output.includes("Bundling")) bundlingStarted = true;
|
if (output.includes("Bundling")) bundlingStarted = true;
|
||||||
if (output.includes("Finished")) console.log(" ✅ Multi-arch compilation finished!");
|
if (output.includes("Finished"))
|
||||||
|
console.log(" ✅ Multi-arch compilation finished!");
|
||||||
if (output.includes("Built application at:")) buildCompleted = true;
|
if (output.includes("Built application at:")) buildCompleted = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -801,7 +824,9 @@ class PakeTestRunner {
|
|||||||
child.kill("SIGTERM");
|
child.kill("SIGTERM");
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
console.log(" ❌ Multi-arch build timeout - no app file generated");
|
console.log(
|
||||||
|
" ❌ Multi-arch build timeout - no app file generated",
|
||||||
|
);
|
||||||
console.log(` 📍 Expected location: ${appFile}`);
|
console.log(` 📍 Expected location: ${appFile}`);
|
||||||
child.kill("SIGTERM");
|
child.kill("SIGTERM");
|
||||||
reject(new Error("Multi-arch build test timeout"));
|
reject(new Error("Multi-arch build test timeout"));
|
||||||
@@ -815,7 +840,9 @@ class PakeTestRunner {
|
|||||||
const dmgExists = fs.existsSync(dmgFile);
|
const dmgExists = fs.existsSync(dmgFile);
|
||||||
|
|
||||||
if (appExists) {
|
if (appExists) {
|
||||||
console.log(" 🎉 Multi-arch build test SUCCESS: Universal binary generated!");
|
console.log(
|
||||||
|
" 🎉 Multi-arch build test SUCCESS: Universal binary generated!",
|
||||||
|
);
|
||||||
console.log(` 📱 App location: ${appFile}`);
|
console.log(` 📱 App location: ${appFile}`);
|
||||||
if (dmgExists) {
|
if (dmgExists) {
|
||||||
console.log(` 💿 DMG location: ${dmgFile}`);
|
console.log(` 💿 DMG location: ${dmgFile}`);
|
||||||
@@ -824,11 +851,19 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
// Verify it's actually a universal binary
|
// Verify it's actually a universal binary
|
||||||
try {
|
try {
|
||||||
const fileOutput = execSync(`file "${appFile}/Contents/MacOS/pake"`, { encoding: 'utf8' });
|
const fileOutput = execSync(
|
||||||
if (fileOutput.includes('universal binary')) {
|
`file "${appFile}/Contents/MacOS/pake"`,
|
||||||
console.log(" ✅ Verified: Universal binary created successfully");
|
{ encoding: "utf8" },
|
||||||
|
);
|
||||||
|
if (fileOutput.includes("universal binary")) {
|
||||||
|
console.log(
|
||||||
|
" ✅ Verified: Universal binary created successfully",
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log(" ⚠️ Note: Binary architecture:", fileOutput.trim());
|
console.log(
|
||||||
|
" ⚠️ Note: Binary architecture:",
|
||||||
|
fileOutput.trim(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(" ⚠️ Could not verify binary architecture");
|
console.log(" ⚠️ Could not verify binary architecture");
|
||||||
@@ -836,23 +871,31 @@ class PakeTestRunner {
|
|||||||
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else if (code === 0 && buildStarted && compilationStarted) {
|
} else if (code === 0 && buildStarted && compilationStarted) {
|
||||||
console.log(" ⚠️ Multi-arch build process completed but no app file found");
|
console.log(
|
||||||
|
" ⚠️ Multi-arch build process completed but no app file found",
|
||||||
|
);
|
||||||
console.log(` 📍 Expected location: ${appFile}`);
|
console.log(` 📍 Expected location: ${appFile}`);
|
||||||
resolve(false);
|
resolve(false);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error(`Multi-arch build test failed with code ${code}`));
|
reject(
|
||||||
|
new Error(`Multi-arch build test failed with code ${code}`),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
child.on("error", (error) => {
|
child.on("error", (error) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
reject(new Error(`Multi-arch build test process error: ${error.message}`));
|
reject(
|
||||||
|
new Error(
|
||||||
|
`Multi-arch build test process error: ${error.message}`,
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stdin.end();
|
child.stdin.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
750000 // 12+ minutes timeout
|
750000, // 12+ minutes timeout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,7 +910,7 @@ class PakeTestRunner {
|
|||||||
});
|
});
|
||||||
return /^\d+\.\d+\.\d+/.test(output.trim());
|
return /^\d+\.\d+\.\d+/.test(output.trim());
|
||||||
},
|
},
|
||||||
TIMEOUTS.QUICK
|
TIMEOUTS.QUICK,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.runTest(
|
await this.runTest(
|
||||||
@@ -879,7 +922,7 @@ class PakeTestRunner {
|
|||||||
});
|
});
|
||||||
return output.includes("Usage: cli [url] [options]");
|
return output.includes("Usage: cli [url] [options]");
|
||||||
},
|
},
|
||||||
TIMEOUTS.QUICK
|
TIMEOUTS.QUICK,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.runTest(
|
await this.runTest(
|
||||||
@@ -889,11 +932,13 @@ class PakeTestRunner {
|
|||||||
const arch = process.arch;
|
const arch = process.arch;
|
||||||
const nodeVersion = process.version;
|
const nodeVersion = process.version;
|
||||||
|
|
||||||
return typeof platform === 'string' &&
|
return (
|
||||||
typeof arch === 'string' &&
|
typeof platform === "string" &&
|
||||||
nodeVersion.startsWith('v');
|
typeof arch === "string" &&
|
||||||
|
nodeVersion.startsWith("v")
|
||||||
|
);
|
||||||
},
|
},
|
||||||
TIMEOUTS.QUICK
|
TIMEOUTS.QUICK,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,7 +988,9 @@ class PakeTestRunner {
|
|||||||
if (passed === total) {
|
if (passed === total) {
|
||||||
console.log("🎉 All tests passed! CLI is ready for use.\n");
|
console.log("🎉 All tests passed! CLI is ready for use.\n");
|
||||||
} else {
|
} else {
|
||||||
console.log(`❌ ${total - passed} test(s) failed. Please check the issues above.\n`);
|
console.log(
|
||||||
|
`❌ ${total - passed} test(s) failed. Please check the issues above.\n`,
|
||||||
|
);
|
||||||
|
|
||||||
// Show failed tests
|
// Show failed tests
|
||||||
const failed = this.results.filter((r) => !r.passed);
|
const failed = this.results.filter((r) => !r.passed);
|
||||||
@@ -964,17 +1011,17 @@ const args = process.argv.slice(2);
|
|||||||
|
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
const options = {
|
const options = {
|
||||||
unit: args.includes('--unit') || args.length === 0,
|
unit: args.includes("--unit") || args.length === 0,
|
||||||
integration: args.includes('--integration') || args.length === 0,
|
integration: args.includes("--integration") || args.length === 0,
|
||||||
builder: args.includes('--builder') || args.length === 0,
|
builder: args.includes("--builder") || args.length === 0,
|
||||||
pakeCliTests: args.includes('--pake-cli'),
|
pakeCliTests: args.includes("--pake-cli"),
|
||||||
e2e: args.includes('--e2e') || args.includes('--full'),
|
e2e: args.includes("--e2e") || args.includes("--full"),
|
||||||
realBuild: args.includes('--real-build') || args.length === 0, // Include real build in default tests
|
realBuild: args.includes("--real-build") || args.length === 0, // Include real build in default tests
|
||||||
quick: args.includes('--quick')
|
quick: args.includes("--quick"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Help message
|
// Help message
|
||||||
if (args.includes('--help') || args.includes('-h')) {
|
if (args.includes("--help") || args.includes("-h")) {
|
||||||
console.log(`
|
console.log(`
|
||||||
🚀 Pake CLI Test Suite
|
🚀 Pake CLI Test Suite
|
||||||
|
|
||||||
@@ -1009,7 +1056,8 @@ Environment:
|
|||||||
|
|
||||||
// Run tests
|
// Run tests
|
||||||
const runner = new PakeTestRunner();
|
const runner = new PakeTestRunner();
|
||||||
runner.runAll(options)
|
runner
|
||||||
|
.runAll(options)
|
||||||
.then((success) => {
|
.then((success) => {
|
||||||
process.exit(success ? 0 : 1);
|
process.exit(success ? 0 : 1);
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user