Semver check tests: the first-release probe's cwd and blob size are pinned, and assembly-less packages read no tags' trees
Also defines the PE fixture before the tests that use it, so a filtered run no longer reaches it before initialization. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
98eb42af60
commit
8c9faf06c6
1 changed files with 49 additions and 24 deletions
|
|
@ -411,6 +411,30 @@ function tagWithFiles(dir, tag, files) {
|
|||
commitAndTag(dir, tag);
|
||||
}
|
||||
|
||||
// A PE image written byte by byte. A managed assembly's CLI header is data directory 14; a
|
||||
// native DLL has none.
|
||||
function peImage({ plus = true, directories = 16, cli = null } = {}) {
|
||||
const pe = 0x40;
|
||||
const optionalSize = (plus ? 112 : 96) + directories * 8;
|
||||
const bytes = Buffer.alloc(pe + 24 + optionalSize);
|
||||
bytes.writeUInt16LE(0x5a4d, 0);
|
||||
bytes.writeUInt32LE(pe, 0x3c);
|
||||
bytes.writeUInt32LE(0x00004550, pe);
|
||||
bytes.writeUInt16LE(plus ? 0x8664 : 0x14c, pe + 4);
|
||||
bytes.writeUInt16LE(optionalSize, pe + 20);
|
||||
const optional = pe + 24;
|
||||
bytes.writeUInt16LE(plus ? 0x20b : 0x10b, optional);
|
||||
const dirs = optional + (plus ? 112 : 96);
|
||||
bytes.writeUInt32LE(directories, dirs - 4);
|
||||
if (cli) {
|
||||
bytes.writeUInt32LE(cli.rva, dirs + 14 * 8);
|
||||
bytes.writeUInt32LE(cli.size, dirs + 14 * 8 + 4);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const CLI = { rva: 0x2000, size: 0x48 };
|
||||
|
||||
test("CLI: a mistyped declared prefix of a Unity package is refused, because a tag under another prefix tracks its managed assembly", () => {
|
||||
// The real entries of CultMath and cultlib, each released once under its real prefix, then
|
||||
// the declaration misspelled. Nothing is measured: the refusal comes from git.
|
||||
|
|
@ -465,6 +489,31 @@ test("CLI: only a managed assembly under the declared assemblies directory prove
|
|||
});
|
||||
});
|
||||
|
||||
test("CLI: the first-release probe reads the repository of --cwd and a blob of any size, and reads no tree for a package without assemblies", () => {
|
||||
const elsewhere = mkdtempSync(join(tmpdir(), "cultlib-semver-elsewhere-"));
|
||||
try {
|
||||
withTempGitRepo((dir) => {
|
||||
declare(dir, { widget: { ...WIDGET, assemblies: PLUGINS } });
|
||||
// a managed assembly larger than the default 1 MiB buffer of a child process
|
||||
tagWithFiles(dir, "other-v1.0.0", { [`${PLUGINS}/Big.dll`]: Buffer.concat([peImage({ cli: CLI }), Buffer.alloc(2 << 20)]) });
|
||||
writeChangelog(dir, "1.0.0");
|
||||
const junk = join(dir, "junk.dll");
|
||||
writeFileSync(junk, "junk");
|
||||
const refused = runCheckerExpectFailure(dir, [...widgetArgs("1.0.0"), "--api-built", junk], { processCwd: elsewhere });
|
||||
assert.ok(refused.includes(`other-v1.0.0 tracks the managed assembly ${PLUGINS}/Big.dll`), refused);
|
||||
});
|
||||
withTempGitRepo((dir) => {
|
||||
commitAndTag(dir, "other-v1.0.0");
|
||||
writeFileSync(join(dir, ".git", "refs", "tags", "other-v2.0.0"), "1".repeat(40) + "\n");
|
||||
writeChangelog(dir, "1.0.0");
|
||||
// an unreadable tag matters only to a package whose assemblies it could have shipped
|
||||
assert.match(runChecker(dir, widgetArgs("1.0.0")), /first release \(1\.0\.0\)/);
|
||||
});
|
||||
} finally {
|
||||
rmSync(elsewhere, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("CLI: a package with no assemblies is a first release when no tag of its own prefix exists, whatever other tags track", () => {
|
||||
withTempGitRepo((dir) => {
|
||||
declare(dir, { widget: { ...WIDGET, changelog: "pkg/CHANGELOG.md" } });
|
||||
|
|
@ -816,30 +865,6 @@ test("measured: an assembly tracked in a subdirectory is measured, and is a brea
|
|||
});
|
||||
});
|
||||
|
||||
// A PE image written byte by byte. A managed assembly's CLI header is data directory 14; a
|
||||
// native DLL has none.
|
||||
function peImage({ plus = true, directories = 16, cli = null } = {}) {
|
||||
const pe = 0x40;
|
||||
const optionalSize = (plus ? 112 : 96) + directories * 8;
|
||||
const bytes = Buffer.alloc(pe + 24 + optionalSize);
|
||||
bytes.writeUInt16LE(0x5a4d, 0);
|
||||
bytes.writeUInt32LE(pe, 0x3c);
|
||||
bytes.writeUInt32LE(0x00004550, pe);
|
||||
bytes.writeUInt16LE(plus ? 0x8664 : 0x14c, pe + 4);
|
||||
bytes.writeUInt16LE(optionalSize, pe + 20);
|
||||
const optional = pe + 24;
|
||||
bytes.writeUInt16LE(plus ? 0x20b : 0x10b, optional);
|
||||
const dirs = optional + (plus ? 112 : 96);
|
||||
bytes.writeUInt32LE(directories, dirs - 4);
|
||||
if (cli) {
|
||||
bytes.writeUInt32LE(cli.rva, dirs + 14 * 8);
|
||||
bytes.writeUInt32LE(cli.size, dirs + 14 * 8 + 4);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const CLI = { rva: 0x2000, size: 0x48 };
|
||||
|
||||
test("isManagedAssembly: a non-empty CLI header makes an assembly managed, nothing else does", () => {
|
||||
assert.equal(isManagedAssembly(peImage({ cli: CLI })), true);
|
||||
assert.equal(isManagedAssembly(peImage({ plus: false, cli: CLI })), true);
|
||||
|
|
|
|||
Loading…
Reference in a new issue