|
| 1 | +import console from "node:console"; |
| 2 | +import { mkdtemp, mkdir, writeFile } from "node:fs/promises"; |
| 3 | +import { tmpdir } from "node:os"; |
| 4 | +import path from "node:path"; |
| 5 | + |
| 6 | +import { afterEach, describe, expect, it, vi } from "vitest"; |
| 7 | + |
| 8 | +import { findBundleInfoFile, followsXcResultNaming, isMostProbablyXcResultBundle } from "../src/xcresult/bundle.js"; |
| 9 | +import { createAttachmentFileFactory, mapWellKnownAttachmentName } from "../src/xcresult/xcresulttool/utils.js"; |
| 10 | + |
| 11 | +describe("xcresult bundle helpers", () => { |
| 12 | + const tempDirs: string[] = []; |
| 13 | + |
| 14 | + afterEach(async () => { |
| 15 | + await Promise.all( |
| 16 | + tempDirs.map(async (directory) => { |
| 17 | + await import("node:fs/promises").then(({ rm }) => rm(directory, { recursive: true, force: true })); |
| 18 | + }), |
| 19 | + ); |
| 20 | + tempDirs.length = 0; |
| 21 | + }); |
| 22 | + |
| 23 | + const createTempDir = async (name: string) => { |
| 24 | + const parent = await mkdtemp(path.join(tmpdir(), "allure-reader-bundle-")); |
| 25 | + const directory = path.join(parent, name); |
| 26 | + await mkdir(directory, { recursive: true }); |
| 27 | + tempDirs.push(directory); |
| 28 | + return directory; |
| 29 | + }; |
| 30 | + |
| 31 | + it("should detect xcresult bundles by naming convention and bundle metadata", async () => { |
| 32 | + const namedBundle = await createTempDir("named.xcresult"); |
| 33 | + const bundleWithInfo = await createTempDir("bundle"); |
| 34 | + const plainDirectory = await createTempDir("plain"); |
| 35 | + |
| 36 | + await mkdir(path.join(bundleWithInfo, "Contents"), { recursive: true }); |
| 37 | + await writeFile(path.join(bundleWithInfo, "Contents", "Info.plist"), "plist", "utf-8"); |
| 38 | + |
| 39 | + expect(followsXcResultNaming(namedBundle)).toBe(true); |
| 40 | + expect(await findBundleInfoFile(bundleWithInfo)).toBe(path.join(bundleWithInfo, "Contents", "Info.plist")); |
| 41 | + expect(await isMostProbablyXcResultBundle(namedBundle)).toBe(true); |
| 42 | + expect(await isMostProbablyXcResultBundle(bundleWithInfo)).toBe(true); |
| 43 | + expect(await isMostProbablyXcResultBundle(plainDirectory)).toBe(false); |
| 44 | + }); |
| 45 | +}); |
| 46 | + |
| 47 | +describe("xcresult attachment helpers", () => { |
| 48 | + const tempDirs: string[] = []; |
| 49 | + |
| 50 | + afterEach(async () => { |
| 51 | + await Promise.all( |
| 52 | + tempDirs.map(async (directory) => { |
| 53 | + await import("node:fs/promises").then(({ rm }) => rm(directory, { recursive: true, force: true })); |
| 54 | + }), |
| 55 | + ); |
| 56 | + tempDirs.length = 0; |
| 57 | + vi.restoreAllMocks(); |
| 58 | + }); |
| 59 | + |
| 60 | + const createTempDir = async () => { |
| 61 | + const directory = await mkdtemp(path.join(tmpdir(), "allure-reader-attachments-")); |
| 62 | + tempDirs.push(directory); |
| 63 | + return directory; |
| 64 | + }; |
| 65 | + |
| 66 | + it("should read exported attachments by exact file path and extension fallback", async () => { |
| 67 | + const attachmentsDir = await createTempDir(); |
| 68 | + const factory = createAttachmentFileFactory(attachmentsDir); |
| 69 | + |
| 70 | + await writeFile(path.join(attachmentsDir, "uuid-plain"), "plain text", "utf-8"); |
| 71 | + await writeFile(path.join(attachmentsDir, "uuid-image.png"), "png data", "utf-8"); |
| 72 | + |
| 73 | + const plain = await factory("uuid-plain", "plain.txt"); |
| 74 | + const image = await factory("uuid-image", "image.png"); |
| 75 | + |
| 76 | + expect(plain?.getOriginalFileName()).toBe("plain.txt"); |
| 77 | + expect(await plain?.asUtf8String()).toBe("plain text"); |
| 78 | + expect(image?.getOriginalFileName()).toBe("image.png"); |
| 79 | + expect(await image?.asUtf8String()).toBe("png data"); |
| 80 | + }); |
| 81 | + |
| 82 | + it("should return undefined and log an actionable error when an attachment cannot be read", async () => { |
| 83 | + const attachmentsDir = await createTempDir(); |
| 84 | + const factory = createAttachmentFileFactory(attachmentsDir); |
| 85 | + const consoleError = vi.spyOn(console, "error").mockImplementation(() => {}); |
| 86 | + |
| 87 | + await expect(factory("missing-uuid", "missing.txt")).resolves.toBeUndefined(); |
| 88 | + expect(consoleError).toHaveBeenCalledWith( |
| 89 | + "Can't read attachment", |
| 90 | + "missing-uuid", |
| 91 | + "in", |
| 92 | + attachmentsDir, |
| 93 | + ":", |
| 94 | + expect.anything(), |
| 95 | + expect.anything(), |
| 96 | + ); |
| 97 | + }); |
| 98 | + |
| 99 | + it("should map well-known automatic attachment names to readable titles", () => { |
| 100 | + expect(mapWellKnownAttachmentName("kXCTAttachmentScreenRecording", undefined)).toBe("Screen Recording"); |
| 101 | + expect(mapWellKnownAttachmentName("kXCTAttachmentLegacyScreenImageData", undefined)).toBe("Screenshot"); |
| 102 | + expect(mapWellKnownAttachmentName("kXCTAttachmentLegacyScreenImageData", 1_717_171_717_171)).toContain( |
| 103 | + "Screenshot at", |
| 104 | + ); |
| 105 | + expect(mapWellKnownAttachmentName("Custom Attachment", undefined)).toBe("Custom Attachment"); |
| 106 | + }); |
| 107 | +}); |
0 commit comments