UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

355 lines (354 loc) 12.2 kB
import fs from "fs"; import os from "os"; import path from "path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { generateBundlerConfig, isCiEnvironment, maybeGenerateBundlerConfigOnInstall, ONE_GENERATED_MARKER } from "./generateBundlerConfig.native.js"; describe("generateBundlerConfig", function () { var tmpDir; beforeEach(function () { tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "one-gen-bundler-test-")); }); afterEach(function () { fs.rmSync(tmpDir, { recursive: true, force: true }); }); it("writes both files when missing", function () { var { ok, results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); expect(ok).toBe(true); expect(results.map(function (r) { return r.action; })).toEqual(["wrote", "wrote"]); var babel = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(babel).toContain(ONE_GENERATED_MARKER); expect(babel).toContain("require('one/babel-preset')"); expect(babel).toContain("oneBundlerOptions"); var metro = fs.readFileSync(path.join(tmpDir, "metro.config.cjs"), "utf8"); expect(metro).toContain(ONE_GENERATED_MARKER); expect(metro).toContain("require('one/metro-config')"); expect(metro).toContain("withOne"); }); it("is idempotent on second run", function () { generateBundlerConfig({ cwd: tmpDir, quiet: true }); var before = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); var { results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); expect(results.map(function (r) { return r.action; })).toEqual(["kept", "kept"]); var after = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(after).toBe(before); }); it("refuses to overwrite a customized file without --force", function () { fs.writeFileSync(path.join(tmpDir, "babel.config.cjs"), "// hand-written\nmodule.exports = { presets: [] }\n"); var { ok, results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); var babelResult = results.find(function (r) { return r.filePath.endsWith("babel.config.cjs"); }); expect(babelResult.action).toBe("skipped-customized"); expect(ok).toBe(true); var after = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(after).toContain("hand-written"); }); it("overwrites a customized file when --force is set", function () { fs.writeFileSync(path.join(tmpDir, "babel.config.cjs"), "// hand-written\nmodule.exports = { presets: [] }\n"); var { results } = generateBundlerConfig({ cwd: tmpDir, force: true, quiet: true }); var babelResult = results.find(function (r) { return r.filePath.endsWith("babel.config.cjs"); }); expect(babelResult.action).toBe("wrote"); var after = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(after).toContain(ONE_GENERATED_MARKER); expect(after).not.toContain("hand-written"); }); it("rewrites a stale marked file", function () { fs.writeFileSync(path.join(tmpDir, "babel.config.cjs"), `// ${ONE_GENERATED_MARKER} // old content from previous version module.exports = {} `); var { results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); var babelResult = results.find(function (r) { return r.filePath.endsWith("babel.config.cjs"); }); expect(babelResult.action).toBe("wrote"); var after = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(after).toContain("require('one/babel-preset')"); expect(after).not.toContain("old content from previous version"); }); describe("--check mode", function () { it("exits ok when files exist and match", function () { generateBundlerConfig({ cwd: tmpDir, quiet: true }); var { ok, results } = generateBundlerConfig({ cwd: tmpDir, check: true, quiet: true }); expect(ok).toBe(true); expect(results.every(function (r) { return r.action === "kept"; })).toBe(true); }); it("exits not-ok when files are missing", function () { var { ok, results } = generateBundlerConfig({ cwd: tmpDir, check: true, quiet: true }); expect(ok).toBe(false); expect(results.every(function (r) { return r.action === "would-write"; })).toBe(true); expect(fs.existsSync(path.join(tmpDir, "babel.config.cjs"))).toBe(false); }); it("exits not-ok when a marked file is stale", function () { fs.writeFileSync(path.join(tmpDir, "babel.config.cjs"), `// ${ONE_GENERATED_MARKER} module.exports = {} `); fs.writeFileSync(path.join(tmpDir, "metro.config.cjs"), `// ${ONE_GENERATED_MARKER} module.exports = {} `); var { ok, results } = generateBundlerConfig({ cwd: tmpDir, check: true, quiet: true }); expect(ok).toBe(false); expect(results.every(function (r) { return r.action === "would-overwrite"; })).toBe(true); }); }); describe("--eject mode", function () { it("writes files WITHOUT the @one/generated marker", function () { var { results } = generateBundlerConfig({ cwd: tmpDir, eject: true, quiet: true }); expect(results.map(function (r) { return r.action; })).toEqual(["wrote", "wrote"]); var babel = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(babel).not.toContain(ONE_GENERATED_MARKER); expect(babel).toContain("you own this file"); expect(babel).toContain("require('one/babel-preset')"); var metro = fs.readFileSync(path.join(tmpDir, "metro.config.cjs"), "utf8"); expect(metro).not.toContain(ONE_GENERATED_MARKER); expect(metro).toContain("withOne"); }); it("subsequent auto-gen run (no --eject) treats ejected files as customized", function () { generateBundlerConfig({ cwd: tmpDir, eject: true, quiet: true }); var before = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); var { results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); expect(results.every(function (r) { return r.action === "skipped-customized"; })).toBe(true); var after = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); expect(after).toBe(before); }); }); it("does not clobber a non-.cjs config in the same family", function () { fs.writeFileSync(path.join(tmpDir, "babel.config.js"), "module.exports = { presets: [] }\n"); var { results } = generateBundlerConfig({ cwd: tmpDir, quiet: true }); var babelResult = results.find(function (r) { return r.filePath.endsWith("babel.config.js") || r.filePath.endsWith("babel.config.cjs"); }); expect(babelResult.action).toBe("skipped-other-format"); expect(fs.existsSync(path.join(tmpDir, "babel.config.cjs"))).toBe(false); }); it("embeds loaded One router/setup options into both config files", function () { generateBundlerConfig({ cwd: tmpDir, quiet: true, oneOptions: { router: { root: "src/routes", ignoredRouteFiles: ["**/*.native-test.*"], linking: { scheme: "myapp", prefixes: ["https://example.com/app"] } }, setupFile: { native: "src/setup.native.ts" } } }); var babel = fs.readFileSync(path.join(tmpDir, "babel.config.cjs"), "utf8"); var metro = fs.readFileSync(path.join(tmpDir, "metro.config.cjs"), "utf8"); for (var _i = 0, _iter = [babel, metro]; _i < _iter.length; _i++) { var file = _iter[_i]; expect(file).toContain('"routerRoot": "src/routes"'); expect(file).toContain('"ignoredRouteFiles"'); expect(file).toContain('"**/*.native-test.*"'); expect(file).toContain('"scheme": "myapp"'); expect(file).toContain('"native": "src/setup.native.ts"'); } }); it("refuses to silently drop non-serializable options", function () { expect(function () { return generateBundlerConfig({ cwd: tmpDir, quiet: true, oneOptions: { router: { linking: { // the plugin API only accepts serializable router.linking fields filter: function () { return true; } } } } }); }).toThrow(/JSON-serializable/); }); }); describe("isCiEnvironment", function () { var originalCi = process.env.CI; var originalEasBuild = process.env.EAS_BUILD; afterEach(function () { if (originalCi === void 0) delete process.env.CI;else process.env.CI = originalCi; if (originalEasBuild === void 0) delete process.env.EAS_BUILD;else process.env.EAS_BUILD = originalEasBuild; }); it("is true when CI=true", function () { process.env.CI = "true"; delete process.env.EAS_BUILD; expect(isCiEnvironment()).toBe(true); }); it("is true when CI=1", function () { process.env.CI = "1"; delete process.env.EAS_BUILD; expect(isCiEnvironment()).toBe(true); }); it("is true when EAS_BUILD=true", function () { delete process.env.CI; process.env.EAS_BUILD = "true"; expect(isCiEnvironment()).toBe(true); }); it("is false when neither is set", function () { delete process.env.CI; delete process.env.EAS_BUILD; expect(isCiEnvironment()).toBe(false); }); it("is false when CI=false or CI=0", function () { delete process.env.EAS_BUILD; process.env.CI = "false"; expect(isCiEnvironment()).toBe(false); process.env.CI = "0"; expect(isCiEnvironment()).toBe(false); }); }); describe("maybeGenerateBundlerConfigOnInstall", function () { var tmpDir; var originalCi = process.env.CI; beforeEach(function () { tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "one-gen-bundler-ci-test-")); }); afterEach(function () { fs.rmSync(tmpDir, { recursive: true, force: true }); if (originalCi === void 0) delete process.env.CI;else process.env.CI = originalCi; delete process.env.EAS_BUILD; }); it("does NOT generate files when not in CI even if expo-updates is present", function () { delete process.env.CI; delete process.env.EAS_BUILD; var fakeUpdates = path.join(tmpDir, "node_modules/expo-updates"); fs.mkdirSync(fakeUpdates, { recursive: true }); fs.writeFileSync(path.join(fakeUpdates, "package.json"), JSON.stringify({ name: "expo-updates" })); maybeGenerateBundlerConfigOnInstall(tmpDir); expect(fs.existsSync(path.join(tmpDir, "babel.config.cjs"))).toBe(false); expect(fs.existsSync(path.join(tmpDir, "metro.config.cjs"))).toBe(false); }); it("does NOT generate files in CI when expo-updates is absent", function () { process.env.CI = "true"; maybeGenerateBundlerConfigOnInstall(tmpDir); expect(fs.existsSync(path.join(tmpDir, "babel.config.cjs"))).toBe(false); expect(fs.existsSync(path.join(tmpDir, "metro.config.cjs"))).toBe(false); }); it("generates files in CI when expo-updates is present", function () { process.env.CI = "true"; var fakeUpdates = path.join(tmpDir, "node_modules/expo-updates"); fs.mkdirSync(fakeUpdates, { recursive: true }); fs.writeFileSync(path.join(fakeUpdates, "package.json"), JSON.stringify({ name: "expo-updates" })); var consoleInfo = vi.spyOn(console, "info").mockImplementation(function () {}); try { maybeGenerateBundlerConfigOnInstall(tmpDir); } finally { consoleInfo.mockRestore(); } expect(fs.existsSync(path.join(tmpDir, "babel.config.cjs"))).toBe(true); expect(fs.existsSync(path.join(tmpDir, "metro.config.cjs"))).toBe(true); }); }); //# sourceMappingURL=generateBundlerConfig.test.native.js.map