mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
* fix(hopper): normalize string-backed addresses and update verification * feat(native): add inspection primitives, dispatch traces and approved UI observation * test: prioritize real artifact E2E and captured golden regressions * fix(process): queue observed output before reactive rendering actions * test: prune redundant cases and strengthen boundary assertions * fix(cli): route native value tracing through shared workflows * test: replace synthetic success with real workflows and captured data * fix(catalog): separate portable metadata from native host availability
134 lines
4.4 KiB
JavaScript
134 lines
4.4 KiB
JavaScript
import { execFile } from "node:child_process";
|
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { promisify } from "node:util";
|
|
import { parseBinaryTarget } from "../dist/application/BinaryTargetResolver.js";
|
|
import { inspectAppleDispatchMetadata } from "../dist/native/AppleDispatchMetadata.js";
|
|
|
|
if (process.platform !== "darwin")
|
|
throw new Error(
|
|
"Apple dispatch verification requires macOS with a host Objective-C compiler and Foundation SDK",
|
|
);
|
|
const exec = promisify(execFile);
|
|
const root = await mkdtemp(join(tmpdir(), "rea-dispatch-"));
|
|
try {
|
|
const targetPath = join(root, "fixture");
|
|
await exec("/usr/bin/xcrun", [
|
|
"clang",
|
|
"-O2",
|
|
"-framework",
|
|
"Foundation",
|
|
"-Wl,-no_fixup_chains",
|
|
fileURLToPath(
|
|
new URL("../tests/conformance/native/dispatch.m", import.meta.url),
|
|
),
|
|
"-o",
|
|
targetPath,
|
|
]);
|
|
const results = [];
|
|
for (const variant of ["symbols", "stripped"]) {
|
|
if (variant === "stripped")
|
|
await exec("/usr/bin/strip", ["-x", targetPath]);
|
|
const target = await parseBinaryTarget(targetPath);
|
|
if (!target.ok) throw target.error;
|
|
const observation = await inspectAppleDispatchMetadata(target.value, 5000);
|
|
const metadata = observation.result;
|
|
if (
|
|
!metadata.objc_dispatch_implementations.some(
|
|
(item) =>
|
|
item.class_name === "ReaDispatchFixture" &&
|
|
item.selector === "performAction:" &&
|
|
item.implementation_address !== null,
|
|
) ||
|
|
!metadata.objc_dispatch_implementations.some(
|
|
(item) =>
|
|
item.selector === "fixtureVersion" && item.method_type === "class",
|
|
) ||
|
|
!metadata.objc_ivars.some(
|
|
(item) => item.name === "state" && item.offset !== null,
|
|
) ||
|
|
!metadata.objc_protocol_records.some(
|
|
(protocol) =>
|
|
protocol.name === "ReaDispatchProtocol" &&
|
|
protocol.methods.some(
|
|
(method) => method.selector === "performAction:",
|
|
) &&
|
|
protocol.optional_methods.some(
|
|
(method) => method.selector === "optionalFixtureValue",
|
|
),
|
|
)
|
|
)
|
|
throw new Error(
|
|
`Apple metadata fixture drifted: ${JSON.stringify(observation)}`,
|
|
);
|
|
results.push({
|
|
variant,
|
|
target_sha256: target.value.sha256,
|
|
implementations: metadata.objc_dispatch_implementations.length,
|
|
ivars: metadata.objc_ivars.length,
|
|
coverage: metadata.coverage,
|
|
});
|
|
}
|
|
const swiftPath = join(root, "libReaWitnessFixture.dylib");
|
|
await exec("/usr/bin/xcrun", [
|
|
"swiftc",
|
|
"-emit-library",
|
|
"-O",
|
|
"-Xlinker",
|
|
"-no_fixup_chains",
|
|
fileURLToPath(
|
|
new URL("../tests/conformance/native/dispatch.swift", import.meta.url),
|
|
),
|
|
"-o",
|
|
swiftPath,
|
|
]);
|
|
for (const variant of ["swift-symbols", "swift-stripped"]) {
|
|
if (variant === "swift-stripped")
|
|
await exec("/usr/bin/strip", ["-x", swiftPath]);
|
|
const target = await parseBinaryTarget(swiftPath);
|
|
if (!target.ok) throw target.error;
|
|
const observation = await inspectAppleDispatchMetadata(target.value, 5000);
|
|
const metadata = observation.result;
|
|
if (
|
|
!metadata.swift_dispatch_slots.some(
|
|
(slot) =>
|
|
slot.table_kind === "class_vtable" &&
|
|
slot.owner === "ReaVtableFixture" &&
|
|
slot.decode.status === "decoded",
|
|
)
|
|
)
|
|
throw new Error(
|
|
`Swift class vtable fixture unavailable: ${JSON.stringify(metadata.coverage)}`,
|
|
);
|
|
if (
|
|
!metadata.swift_conformances.some(
|
|
(item) =>
|
|
item.type_name === "ReaWitnessFixture" &&
|
|
item.protocol_name === "ReaWitnessFixtureProtocol",
|
|
) ||
|
|
!metadata.swift_dispatch_slots.some(
|
|
(item) =>
|
|
item.owner === "ReaWitnessFixture: ReaWitnessFixtureProtocol" &&
|
|
item.implementation_address !== null,
|
|
)
|
|
)
|
|
throw new Error(
|
|
`Swift metadata fixture drifted: ${JSON.stringify(observation)}`,
|
|
);
|
|
results.push({
|
|
variant,
|
|
target_sha256: target.value.sha256,
|
|
conformances: metadata.swift_conformances.length,
|
|
slots: metadata.swift_dispatch_slots.length,
|
|
coverage: metadata.coverage,
|
|
});
|
|
}
|
|
process.stdout.write(
|
|
`${JSON.stringify({ ok: true, target_executed: false, fixtures: results })}\n`,
|
|
);
|
|
} finally {
|
|
await rm(root, { recursive: true, force: true });
|
|
}
|