mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
test(web): make batch limits independently testable
Co-authored-by: Copilot <[email protected]>
This commit is contained in:
1 parent
cd3781c1cf
commit
297b0dfacf
6 files changed
+65
-36
No files matched your search
@@ -25,7 +25,8 @@ jobs:
|
||||
- name: Check browser module syntax
|
||||
run: |
|
||||
node --check demo/web/app.mjs
|
||||
node --check demo/web/batch.mjs
|
||||
node --check demo/web/output-directory.mjs
|
||||
node --check demo/web/worker.mjs
|
||||
- name: Test folder output recovery
|
||||
run: node --test demo/web/tests/output-directory.test.mjs
|
||||
- name: Test browser converter helpers
|
||||
run: node --test demo/web/tests/batch.test.mjs demo/web/tests/output-directory.test.mjs
|
||||
+2
-22
@@ -1,8 +1,9 @@
|
||||
import { BlobReader, Uint8ArrayReader, ZipReader, ZipWriter, configure } from "https://cdn.jsdelivr.net/npm/@zip.js/[email protected]/lib/zip-no-worker.js/+esm";
|
||||
import { batchMemoryEstimate, batchOutputDirectory, MEMORY_LIMIT, memoryEstimate } from "./batch.mjs";
|
||||
|
||||
configure({ useWebWorkers: false, useCompressionStream: false, chunkSize: 65536 });
|
||||
|
||||
export const MEMORY_LIMIT = 256 * 1024 * 1024;
|
||||
export { batchMemoryEstimate, batchOutputDirectory, memoryEstimate, MEMORY_LIMIT };
|
||||
export const CONVERSION_LIMIT = 256 * 1024 * 1024;
|
||||
export const ICON_LIMIT = 16 * 1024 * 1024;
|
||||
const MAX_ENTRIES = 100000;
|
||||
@@ -204,27 +205,6 @@ export class Archive {
|
||||
async close() { await this.reader.close(); }
|
||||
}
|
||||
|
||||
export function memoryEstimate(archiveBytes, selectedBytes, libraryBytes, entries) {
|
||||
return safeSize(Math.ceil(archiveBytes * 1.02) + selectedBytes * 4 + libraryBytes + entries * 1024 + 8 * 1024 * 1024);
|
||||
}
|
||||
|
||||
export function batchMemoryEstimate(summaries, target, libraryBytes) {
|
||||
if (target !== "linux" && target !== "windows") throw new Error(`Unsupported conversion target: ${target}`);
|
||||
return summaries.reduce((total, summary) => safeSize(total + memoryEstimate(
|
||||
summary.totalBytes,
|
||||
target === "windows" ? summary.windowsSelectedBytes : summary.selectedBytes,
|
||||
libraryBytes,
|
||||
summary.files
|
||||
)), 0);
|
||||
}
|
||||
|
||||
export function batchOutputDirectory(name, index) {
|
||||
if (!Number.isSafeInteger(index) || index < 0) throw new Error("Invalid app index");
|
||||
const stem = String(name).replace(/\.zip$/iu, "").normalize("NFKC")
|
||||
.replace(/[^A-Za-z0-9._-]+/gu, "-").replace(/^[.-]+/u, "").slice(0, 80).replace(/[. -]+$/u, "");
|
||||
return `${String(index + 1).padStart(2, "0")}-${stem || "app"}`;
|
||||
}
|
||||
|
||||
export function createPackageWriter(destination) {
|
||||
return new ZipWriter(destination, { level: 9, zip64: true, bufferedWrite: false, useWebWorkers: false, useCompressionStream: false, preventClose: true });
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
export const MEMORY_LIMIT = 256 * 1024 * 1024;
|
||||
|
||||
function safeSize(value) {
|
||||
if (!Number.isSafeInteger(value) || value < 0) throw new Error("ZIP contains an unsupported file size");
|
||||
return value;
|
||||
}
|
||||
|
||||
export function memoryEstimate(archiveBytes, selectedBytes, libraryBytes, entries) {
|
||||
return safeSize(Math.ceil(archiveBytes * 1.02) + selectedBytes * 4 + libraryBytes + entries * 1024 + 8 * 1024 * 1024);
|
||||
}
|
||||
|
||||
export function batchMemoryEstimate(summaries, target, libraryBytes) {
|
||||
if (target !== "linux" && target !== "windows") throw new Error(`Unsupported conversion target: ${target}`);
|
||||
return summaries.reduce((total, summary) => safeSize(total + memoryEstimate(
|
||||
summary.totalBytes,
|
||||
target === "windows" ? summary.windowsSelectedBytes : summary.selectedBytes,
|
||||
libraryBytes,
|
||||
summary.files
|
||||
)), 0);
|
||||
}
|
||||
|
||||
export function batchOutputDirectory(name, index) {
|
||||
if (!Number.isSafeInteger(index) || index < 0) throw new Error("Invalid app index");
|
||||
const stem = String(name).replace(/\.zip$/iu, "").normalize("NFKC")
|
||||
.replace(/[^A-Za-z0-9._-]+/gu, "-").replace(/^[.-]+/u, "").slice(0, 80).replace(/[. -]+$/u, "");
|
||||
return `${String(index + 1).padStart(2, "0")}-${stem || "app"}`;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { register } from "node:module";
|
||||
register("./cdn-loader.mjs", import.meta.url, { data: { url: process.env.ANYPS5_TEST_ZIP_URL, path: process.env.ANYPS5_TEST_ZIP_PATH } });
|
||||
|
||||
const site = name => pathToFileURL(path.join(process.argv[2], name)).href;
|
||||
const { Archive, batchMemoryEstimate, batchOutputDirectory, memoryEstimate, MEMORY_LIMIT, ICON_LIMIT, packageArchive } = await import(site("archive.mjs"));
|
||||
const { Archive, memoryEstimate, MEMORY_LIMIT, ICON_LIMIT, packageArchive } = await import(site("archive.mjs"));
|
||||
const { BlobReader, BlobWriter, Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter } = await import(process.env.ANYPS5_TEST_ZIP_URL);
|
||||
await import("./archive-reserved.test.mjs");
|
||||
const { default: createRelinker } = await import(site("native/relinker_wasm.mjs"));
|
||||
@@ -157,16 +157,6 @@ assert.equal(selfModuleSummary.warnings.length, 2);
|
||||
assert.match(selfModuleSummary.warnings.join(" "), /SELF container/u);
|
||||
await selfModule.close();
|
||||
assert(memoryEstimate(200 * 1024 ** 3, 1024, 1024, 100) > MEMORY_LIMIT);
|
||||
assert(batchMemoryEstimate([
|
||||
{ totalBytes: 1024, selectedBytes: 128, windowsSelectedBytes: 256, files: 2 },
|
||||
{ totalBytes: 2048, selectedBytes: 256, windowsSelectedBytes: 512, files: 3 }
|
||||
], "linux", 1024) > memoryEstimate(2048, 256, 1024, 3));
|
||||
assert.equal(batchOutputDirectory("First App.zip", 0), "01-First-App");
|
||||
assert.equal(batchOutputDirectory("First App.zip", 1), "02-First-App");
|
||||
assert.equal(batchOutputDirectory("CON.zip", 0), "01-CON");
|
||||
assert.equal(batchOutputDirectory("...zip", 0), "01-app");
|
||||
assert.throws(() => batchOutputDirectory("app.zip", -1), /Invalid app index/u);
|
||||
assert.throws(() => batchMemoryEstimate([], "macos", 0), /Unsupported conversion target/u);
|
||||
const invalid = native.Convert({ target: "unsupported" }, () => {});
|
||||
assert.equal(invalid.ok, false);
|
||||
console.log("Archive validation, missing-folder warnings and large-download budget verified");
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { batchMemoryEstimate, batchOutputDirectory, memoryEstimate, MEMORY_LIMIT } from "../batch.mjs";
|
||||
|
||||
test("estimates all ZIP outputs against one shared memory limit", () => {
|
||||
const summaries = [
|
||||
{ totalBytes: 1024, selectedBytes: 128, windowsSelectedBytes: 256, files: 2 },
|
||||
{ totalBytes: 2048, selectedBytes: 256, windowsSelectedBytes: 512, files: 3 }
|
||||
];
|
||||
|
||||
assert.equal(batchMemoryEstimate(summaries, "linux", 1024), summaries.reduce(
|
||||
(total, summary) => total + memoryEstimate(summary.totalBytes, summary.selectedBytes, 1024, summary.files),
|
||||
0
|
||||
));
|
||||
assert.equal(batchMemoryEstimate(summaries, "windows", 1024), summaries.reduce(
|
||||
(total, summary) => total + memoryEstimate(summary.totalBytes, summary.windowsSelectedBytes, 1024, summary.files),
|
||||
0
|
||||
));
|
||||
assert.throws(() => batchMemoryEstimate([], "macos", 0), /Unsupported conversion target/u);
|
||||
assert.throws(() => batchMemoryEstimate([{ totalBytes: Number.MAX_SAFE_INTEGER, selectedBytes: 0, windowsSelectedBytes: 0, files: 0 }], "linux", 0), /unsupported file size/u);
|
||||
assert.equal(MEMORY_LIMIT, 256 * 1024 * 1024);
|
||||
});
|
||||
|
||||
test("creates safe and distinct ZIP folder names for duplicate app filenames", () => {
|
||||
assert.equal(batchOutputDirectory("First App.zip", 0), "01-First-App");
|
||||
assert.equal(batchOutputDirectory("First App.zip", 1), "02-First-App");
|
||||
assert.equal(batchOutputDirectory("CON.zip", 0), "01-CON");
|
||||
assert.equal(batchOutputDirectory("...zip", 0), "01-app");
|
||||
assert.throws(() => batchOutputDirectory("app.zip", -1), /Invalid app index/u);
|
||||
});
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { Archive, batchMemoryEstimate, batchOutputDirectory, CONVERSION_LIMIT, MEMORY_LIMIT, createPackageWriter, packageArchive } from "./archive.mjs";
|
||||
import { batchMemoryEstimate, batchOutputDirectory, MEMORY_LIMIT } from "./batch.mjs";
|
||||
import { Archive, CONVERSION_LIMIT, createPackageWriter, packageArchive } from "./archive.mjs";
|
||||
|
||||
let archive;
|
||||
let inputs = [];
|
||||
|
||||
Reference in new issue
Block a user