296 lines · 9.2 KB · TypeScript
RawDownload
import { assert, it } from "@effect/vitest";import { PNG } from "pngjs"; import showcaseConfig, {  resolveShowcaseAndroidAbi,  type ShowcaseConfig,  type ShowcaseStoreAssetSpec,} from "./mobile-showcase.config.ts";import {  SHOWCASE_ENVIRONMENTS,  SHOWCASE_PROJECTS,  SHOWCASE_THREADS,} from "./mobile-showcase-environment.ts";import {  encodeAndroidPairingUrls,  normalizeStorePng,  parseShowcaseCliArgs,  parsePairingCredentialOutput,  planShowcaseCaptures,  readPngDimensions,  readPngMetadata,  resolveAndroidSdkRoot,  selectLanIpv4Address,  showcaseCaptureDirectory,  showcaseSceneUrl,  validateStoreAsset,  validateStoreAssetCount,} from "./mobile-showcase.ts"; const appleSpec: ShowcaseStoreAssetSpec = {  store: "apple",  directory: "apple/iphone-test",  width: 1284,  height: 2778,  minimumUploadCount: 1,  maximumUploadCount: 10,}; const googleSpec: ShowcaseStoreAssetSpec = {  store: "google-play",  directory: "google-play/phone",  width: 1080,  height: 1920,  minimumUploadCount: 2,  maximumUploadCount: 8,  maximumFileSizeBytes: 8 * 1024 * 1024,}; const config: ShowcaseConfig = {  outputDirectory: "artifacts",  metroPort: 8199,  settleDelayMs: 1,  devices: [    {      id: "phone",      platform: "ios",      simulator: "iPhone Test",      appearance: "dark",      scenes: ["thread", "review"],      storeAsset: appleSpec,    },    {      id: "pixel",      platform: "android",      avd: "Pixel_Test",      appearance: "light",      scenes: ["thread", "terminal"],      storeAsset: googleSpec,    },  ],}; it("parses repeatable capture filters", () => {  const options = parseShowcaseCliArgs([    "--platform",    "ios",    "--device",    "phone",    "--scene",    "review",    "--appearance",    "both",    "--skip-build",  ]);  assert.deepStrictEqual([...options.platforms], ["ios"]);  assert.deepStrictEqual([...options.deviceIds], ["phone"]);  assert.deepStrictEqual([...options.scenes], ["review"]);  assert.deepStrictEqual([...options.appearances], ["light", "dark"]);  assert.equal(options.skipBuild, true);}); it("rejects unsupported system appearances", () => {  assert.throws(    () => parseShowcaseCliArgs(["--appearance", "sepia"]),    /Unsupported appearance 'sepia'/u,  );}); it("parses validation-only mode", () => {  assert.equal(parseShowcaseCliArgs(["--validate-only"]).validateOnly, true);}); it("selects an explicit CI Android ABI without changing the local default", () => {  assert.equal(resolveShowcaseAndroidAbi(undefined), "arm64-v8a");  assert.equal(resolveShowcaseAndroidAbi("x86_64"), "x86_64");  assert.throws(() => resolveShowcaseAndroidAbi("mips"), /Unsupported T3_SHOWCASE_ANDROID_ABI/u);}); it("uses platform-correct default Android SDK roots", () => {  assert.equal(    resolveAndroidSdkRoot({ HOME: "/Users/showcase" }, "darwin"),    "/Users/showcase/Library/Android/sdk",  );  assert.equal(    resolveAndroidSdkRoot({ HOME: "/home/showcase" }, "linux"),    "/home/showcase/Android/Sdk",  );  assert.equal(    resolveAndroidSdkRoot(      { HOME: "/home/showcase", ANDROID_SDK_ROOT: "/opt/android-sdk" },      "linux",    ),    "/opt/android-sdk",  );}); it("plans only scenes supported by each selected device", () => {  const options = parseShowcaseCliArgs(["--platform", "all", "--scene", "terminal"]);  const captures = planShowcaseCaptures(config, options);  assert.deepStrictEqual(    captures.map((capture) => ({      id: capture.device.id,      appearance: capture.appearance,      scenes: capture.scenes,    })),    [{ id: "pixel", appearance: "light", scenes: ["terminal"] }],  );}); it("expands both appearances into independent upload-ready directories", () => {  const options = parseShowcaseCliArgs(["--device", "phone", "--appearance", "both"]);  const captures = planShowcaseCaptures(config, options);   assert.deepStrictEqual(    captures.map((capture) => ({      appearance: capture.appearance,      directory: showcaseCaptureDirectory("/captures", capture),    })),    [      { appearance: "light", directory: "/captures/apple/iphone-test/light" },      { appearance: "dark", directory: "/captures/apple/iphone-test/dark" },    ],  );}); it("rejects unknown devices instead of silently capturing another target", () => {  const options = parseShowcaseCliArgs(["--device", "missing"]);  assert.throws(() => planShowcaseCaptures(config, options), /Unknown device 'missing'/u);}); it("reads captured PNG dimensions from the IHDR header", () => {  const bytes = new Uint8Array(26);  bytes.set([137, 80, 78, 71, 13, 10, 26, 10]);  const view = new DataView(bytes.buffer);  view.setUint32(16, 1320);  view.setUint32(20, 2868);  view.setUint8(24, 8);  view.setUint8(25, 2);  assert.deepStrictEqual(readPngDimensions(bytes), { width: 1320, height: 2868 });  assert.deepStrictEqual(readPngMetadata(bytes), {    width: 1320,    height: 2868,    bitDepth: 8,    colorType: 2,    hasAlpha: false,  });}); function rgbaPng(width: number, height: number): Buffer {  const png = new PNG({ width, height });  png.data.fill(255);  return PNG.sync.write(png);} it("converts simulator RGBA captures to upload-safe 24-bit RGB PNGs", () => {  const normalized = normalizeStorePng(rgbaPng(2, 3));  assert.deepStrictEqual(readPngMetadata(normalized), {    width: 2,    height: 3,    bitDepth: 8,    colorType: 2,    hasAlpha: false,  });}); it("validates exact Apple and Google Play upload assets", () => {  const apple = normalizeStorePng(rgbaPng(appleSpec.width, appleSpec.height));  const google = normalizeStorePng(rgbaPng(googleSpec.width, googleSpec.height));  assert.equal(validateStoreAsset(appleSpec, apple).width, 1284);  assert.equal(validateStoreAsset(googleSpec, google).height, 1920);}); it("rejects wrong dimensions and alpha-bearing PNGs", () => {  const wrongSize = normalizeStorePng(rgbaPng(1242, 2688));  assert.throws(() => validateStoreAsset(appleSpec, wrongSize), /requires 1284×2778/u);  assert.throws(() => validateStoreAsset(appleSpec, rgbaPng(1284, 2778)), /without alpha/u);}); it("enforces store screenshot count limits", () => {  assert.doesNotThrow(() => validateStoreAssetCount(googleSpec, 5, true));  assert.throws(() => validateStoreAssetCount(googleSpec, 1, true), /requires at least 2/u);  assert.throws(() => validateStoreAssetCount(googleSpec, 9, false), /allows at most 8/u);}); it("configures every default device with an exact upload-ready store target", () => {  assert.deepStrictEqual(    showcaseConfig.devices.map((device) => [      device.id,      device.storeAsset.directory,      device.storeAsset.width,      device.storeAsset.height,    ]),    [      ["iphone-6.9", "apple/iphone-6.9", 1320, 2868],      ["iphone-6.5", "apple/iphone-6.5", 1284, 2778],      ["ipad-13", "apple/ipad-13", 2064, 2752],      ["pixel", "google-play/phone", 1080, 1920],      ["android-tablet-7", "google-play/tablet-7", 1080, 1920],      ["android-tablet-10", "google-play/tablet-10", 1440, 2560],    ],  );}); it("selects a reachable LAN IPv4 address", () => {  assert.equal(    selectLanIpv4Address([      { address: "127.0.0.1", family: "IPv4", internal: true },      { address: "fe80::1", family: "IPv6", internal: false },      { address: "169.254.2.4", family: "IPv4", internal: false },      { address: "192.168.1.80", family: "IPv4", internal: false },    ]),    "192.168.1.80",  );}); it("maps capture scenes to the real application routes", () => {  assert.equal(showcaseSceneUrl("threads", "environment-1"), "t3code-dev://");  assert.equal(    showcaseSceneUrl("environments", "environment-1"),    "t3code-dev://settings/environments",  );  assert.equal(    showcaseSceneUrl("thread", "environment-1"),    "t3code-dev://threads/environment-1/remote-command-center",  );  assert.equal(    showcaseSceneUrl("terminal", "environment-1"),    "t3code-dev://threads/environment-1/remote-command-center/terminal?terminalId=term-1",  );  assert.equal(    showcaseSceneUrl("review", "environment-1"),    "t3code-dev://threads/environment-1/remote-command-center/review",  );}); it("seeds a playful multi-environment project spectrum", () => {  assert.deepStrictEqual(    SHOWCASE_PROJECTS.map((project) => project.title),    ["T3 Code", "React", "Linux"],  );  assert.deepStrictEqual(    SHOWCASE_ENVIRONMENTS.map((environment) => environment.label),    ["Moonbase Terminal", "Suspense Station", "Kernel Cabin"],  );  assert.equal(SHOWCASE_THREADS.length, 6);  assert.equal(new Set(SHOWCASE_THREADS.map((thread) => thread.projectId)).size, 3);  assert.equal(    SHOWCASE_PROJECTS.every((project) => project.favicon.includes("<svg")),    true,  );}); it("reads multiline JSON from the pairing CLI", () => {  assert.equal(    parsePairingCredentialOutput('server log\n{\n  "credential": "PAIR-ME"\n}\n'),    "PAIR-ME",  );}); it("encodes Android pairing URLs without shell-sensitive JSON quotes", () => {  const urls = ["http://10.0.2.2:65164/#token=ONE", "http://10.0.2.2:65198/#token=TWO"];  const encoded = encodeAndroidPairingUrls(urls);  assert.equal(encoded.startsWith("json-uri:"), true);  assert.deepStrictEqual(JSON.parse(decodeURIComponent(encoded.slice("json-uri:".length))), urls);  assert.equal(encoded.includes('"'), false);});