UNPKG

@embeddable.com/sdk-core

Version:

Core Embeddable SDK module responsible for web-components bundling and publishing.

263 lines (212 loc) 8.1 kB
import * as fs from "node:fs/promises"; import { checkNodeVersion, getArgumentByKey, storeBuildSuccessFlag, checkBuildSuccess, SUCCESS_FLAG_FILE, hrtimeToISO8601, getSDKVersions, } from "./utils"; const startMock = { succeed: vi.fn(), fail: vi.fn(), stop: vi.fn(), }; const failMock = vi.fn(); // Mock for testing resolveLocalFileVersion const mockPackageJson = { version: "1.2.3", }; vi.mock("ora", () => ({ default: () => ({ start: vi.fn().mockImplementation(() => startMock), info: vi.fn(), fail: failMock, }), })); vi.mock("../package.json", () => ({ engines: { node: "14.x", }, })); vi.mock("fs/promises", () => ({ readFile: vi.fn(), writeFile: vi.fn(), access: vi.fn(), mkdir: vi.fn(), unlink: vi.fn(), })); describe("utils", () => { describe("checkNodeVersion", () => { it("should return true if the node version is greater than 14", async () => { vi.mocked(fs.readFile).mockResolvedValue( JSON.stringify({ engines: { node: "16.x", }, }), ); const result = await checkNodeVersion(); expect(result).toBe(true); }); it("should fail if the node version is less than 16", async () => { Object.defineProperty(process.versions, "node", { value: "14.0", configurable: true, }); vi.mocked(fs.readFile).mockResolvedValue( JSON.stringify({ engines: { node: "16.x", }, }), ); vi.spyOn(process, "exit").mockImplementation(() => null as never); const result = await checkNodeVersion(); expect(startMock.fail).toHaveBeenCalledWith( "Node version 16.0 or higher is required. You are running 14.0.", ); expect(result).toBe(undefined); }); it("should throw an error if the package.json file cannot be read", async () => { vi.spyOn(process, "exit").mockImplementation(() => null as never); vi.mocked(fs.readFile).mockRejectedValue( new Error("Failed to read package.json of core-sdk"), ); await expect(checkNodeVersion()).rejects.toThrow( "Failed to read package.json of core-sdk", ); }); }); describe("getArgumentByKey", () => { it("should return the value of the argument", () => { process.argv = ["--email", "test@a.com", "--password", "123456"]; const result = getArgumentByKey("--email"); expect(result).toBe("test@a.com"); process.argv = ["-e", "test@a.com", "--password", "123456"]; const result2 = getArgumentByKey(["--email", "-e"]); expect(result2).toBe("test@a.com"); }); }); describe("storeBuildSuccessFlag", () => { it("should write a success flag file", async () => { await storeBuildSuccessFlag(); expect(fs.writeFile).toHaveBeenCalledWith(SUCCESS_FLAG_FILE, "true"); }); it("should throw an error if the file write fails", async () => { vi.mocked(fs.writeFile).mockImplementation(async () => { throw new Error(); }); await expect(storeBuildSuccessFlag()).rejects.toThrow(); }); }); describe("checkBuildSuccess", () => { it("should return true if the success flag file exists", async () => { vi.mocked(fs.access).mockResolvedValue(undefined); const result = await checkBuildSuccess(); expect(result).toBe(true); }); it("should return false if the success flag file does not exist", async () => { vi.mocked(fs.access).mockRejectedValue(undefined); const result = await checkBuildSuccess(); expect(result).toBe(false); }); }); describe("getSDKVersions", () => { beforeEach(() => { process.env.NODE_ENV = "local"; vi.resetAllMocks(); process.cwd = vi.fn().mockReturnValue("/test/path"); }); afterEach(() => { process.env.NODE_ENV = "test"; }); it("should get versions from node_modules", async () => { // Mock the readFile to return a version for the first package vi.mocked(fs.readFile).mockResolvedValueOnce( JSON.stringify(mockPackageJson), ); const result = await getSDKVersions(); expect(result).toHaveProperty("@embeddable.com/core", "1.2.3"); }); it("should handle local file references", async () => { // Mock package.json with local file references const mockProjectPackageJson = { dependencies: { "@embeddable.com/core": "file:../packages/core", }, }; // First readFile calls for node_modules fail vi.mocked(fs.readFile) .mockRejectedValueOnce(new Error("Not found")) // core .mockRejectedValueOnce(new Error("Not found")) // react .mockRejectedValueOnce(new Error("Not found")) // sdk-core .mockRejectedValueOnce(new Error("Not found")) // sdk-react .mockRejectedValueOnce(new Error("Not found")) // sdk-utils // Then project package.json succeeds .mockResolvedValueOnce(JSON.stringify(mockProjectPackageJson)) // Then the referenced package.json succeeds .mockResolvedValueOnce(JSON.stringify({ version: "2.0.0" })); const result = await getSDKVersions(); expect(result).toHaveProperty("@embeddable.com/core", "2.0.0"); }); it("should handle errors when resolving local file references", async () => { // Mock console.warn to avoid test output noise const consoleWarnSpy = vi .spyOn(console, "warn") .mockImplementation(() => {}); // Mock package.json with local file references const mockProjectPackageJson = { dependencies: { "@embeddable.com/core": "file:../packages/core", }, }; // First readFile calls for node_modules fail vi.mocked(fs.readFile) .mockRejectedValueOnce(new Error("Not found")) // core .mockRejectedValueOnce(new Error("Not found")) // react .mockRejectedValueOnce(new Error("Not found")) // sdk-core .mockRejectedValueOnce(new Error("Not found")) // sdk-react .mockRejectedValueOnce(new Error("Not found")) // sdk-utils // Then project package.json succeeds .mockResolvedValueOnce(JSON.stringify(mockProjectPackageJson)) // Then the referenced package.json fails .mockRejectedValueOnce(new Error("Cannot read file")); const result = await getSDKVersions(); expect(consoleWarnSpy).toHaveBeenCalled(); expect(result).toHaveProperty("@embeddable.com/core", "local-dev"); consoleWarnSpy.mockRestore(); }); it("should use fallback values in test environment when no versions found", async () => { // Mock console.warn to avoid test output noise const consoleWarnSpy = vi .spyOn(console, "warn") .mockImplementation(() => {}); // Mock all readFile calls to fail vi.mocked(fs.readFile).mockRejectedValue(new Error("Not found")); // Mock process.cwd to return a test-sdk path process.cwd = vi.fn().mockReturnValue("/test/path/test-sdk"); const result = await getSDKVersions(); // Should have fallback values for all packages expect(Object.keys(result).length).toBeGreaterThan(0); expect(result["@embeddable.com/core"]).toBe("local-dev"); expect(result["@embeddable.com/sdk-core"]).toBe("local-dev"); consoleWarnSpy.mockRestore(); }); }); describe("hrtimeToISO8601", () => { test.each([ { input: [0, 0], expected: "PT0.000S" }, { input: [75, 0], expected: "PT1M15.000S" }, // 1 minute and 15 seconds { input: [2, 500000000], expected: "PT2.500S" }, // 2.5 seconds { input: [0, 123456789], expected: "PT0.123S" }, // 0.123 seconds { input: [0, 500000000], expected: "PT0.500S" }, // 0.5 seconds { input: [1, 0], expected: "PT1.000S" }, // 1 second { input: null, expected: "" }, { input: undefined, expected: "" }, ])("converts hrtime $input to $expected", ({ input, expected }) => { expect(hrtimeToISO8601(input)).toBe(expected); }); }); });