diff --git a/tests/boundary/filesystem/interfaceBuilderBundle.test.ts b/tests/boundary/filesystem/interfaceBuilderBundle.test.ts index c30908794..4446c80dc 100644 --- a/tests/boundary/filesystem/interfaceBuilderBundle.test.ts +++ b/tests/boundary/filesystem/interfaceBuilderBundle.test.ts @@ -1,4 +1,3 @@ -import { existsSync } from "node:fs"; import { execFile } from "node:child_process"; import { mkdir, writeFile } from "node:fs/promises"; import { join } from "node:path"; @@ -10,6 +9,7 @@ import { describe, expect, it } from "vitest"; import { analyzeInterfaceBuilderBundle } from "../../../src/artifacts/apple/InterfaceBuilderAnalysis.js"; import { encodeNibArchiveFixture } from "../../../src/artifacts/apple/NibArchive.fixture.js"; import { thinMach } from "../../../src/domain/binaryTarget.fixture.js"; +import { xcodeIbtoolAvailable } from "../../fixtures/ibtool.js"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; import { interfaceBuilderAnalysisSchema } from "../../../src/domain/apple/interfaceBuilderGraph.js"; @@ -913,7 +913,7 @@ describe("bounded Interface Builder archive decoding", () => { ); }); - it.skipIf(process.platform !== "darwin" || !existsSync("/usr/bin/ibtool"))( + it.skipIf(!xcodeIbtoolAvailable)( "decodes an Xcode-compiled storyboard NIB and recovers its UI routes", async () => { const root = await createTestTempDirectory("rea-ib-compiled-test-"); diff --git a/tests/boundary/filesystem/nibNativeHierarchy.test.ts b/tests/boundary/filesystem/nibNativeHierarchy.test.ts index 2d956246a..e2b948f57 100644 --- a/tests/boundary/filesystem/nibNativeHierarchy.test.ts +++ b/tests/boundary/filesystem/nibNativeHierarchy.test.ts @@ -5,6 +5,7 @@ import { promisify } from "node:util"; import { describe, expect, it } from "vitest"; +import { xcodeIbtoolAvailable } from "../../fixtures/ibtool.js"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; import { decodeNibArchive } from "../../../src/artifacts/apple/NibArchive.js"; import { analyzeInterfaceBuilderBundle } from "../../../src/artifacts/apple/InterfaceBuilderAnalysis.js"; @@ -57,7 +58,7 @@ const compileNestedViews = async (depth: number, withWindow = false) => { return { bundle, archive: decodeNibArchive(await readFile(nib)) }; }; -describe.skipIf(process.platform !== "darwin")( +describe.skipIf(!xcodeIbtoolAvailable)( "native compiled NIB view hierarchy", () => { it.each([4, 40])( diff --git a/tests/fixtures/ibtool.ts b/tests/fixtures/ibtool.ts new file mode 100644 index 000000000..c7aef773f --- /dev/null +++ b/tests/fixtures/ibtool.ts @@ -0,0 +1,11 @@ +import { spawnSync } from "node:child_process"; + +/** + * Whether Xcode's ibtool can compile Interface Builder sources on this host. + * Command Line Tools install the /usr/bin/ibtool and xcrun shims without the + * tool itself, so probe resolution instead of checking the shim path. + */ +export const xcodeIbtoolAvailable = + process.platform === "darwin" && + spawnSync("/usr/bin/xcrun", ["--find", "ibtool"], { stdio: "ignore" }) + .status === 0;