diff options
| author | 2023-04-28 01:36:44 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:44 +0800 | |
| commit | dd84b9d64fb98746a230cd24233ff50a562c39c9 (patch) | |
| tree | b583261ef00b3afe72ec4d6dacb31e57779a6faf /packages/turbo-workspaces/__tests__ | |
| parent | 0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff) | |
| download | HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip | |
Diffstat (limited to 'packages/turbo-workspaces/__tests__')
| -rw-r--r-- | packages/turbo-workspaces/__tests__/index.test.ts | 85 | ||||
| -rw-r--r-- | packages/turbo-workspaces/__tests__/managers.test.ts | 285 | ||||
| -rw-r--r-- | packages/turbo-workspaces/__tests__/test-utils.ts | 153 |
3 files changed, 523 insertions, 0 deletions
diff --git a/packages/turbo-workspaces/__tests__/index.test.ts b/packages/turbo-workspaces/__tests__/index.test.ts new file mode 100644 index 0000000..21753be --- /dev/null +++ b/packages/turbo-workspaces/__tests__/index.test.ts @@ -0,0 +1,85 @@ +import path from "path"; +import * as turboUtils from "@turbo/utils"; +import { setupTestFixtures } from "@turbo/test-utils"; +import { getWorkspaceDetails, convert } from "../src"; +import { generateConvertMatrix } from "./test-utils"; +import execa from "execa"; + +jest.mock("execa", () => jest.fn()); + +describe("Node entrypoint", () => { + const { useFixture } = setupTestFixtures({ + directory: path.join(__dirname, "../"), + }); + + describe("convert", () => { + test.each(generateConvertMatrix())( + "detects $fixtureType project using $fixtureManager and converts to $toManager (interactive=$interactive dry=$dry install=$install)", + async ({ + fixtureManager, + fixtureType, + toManager, + interactive, + dry, + install, + }) => { + const mockedGetAvailablePackageManagers = jest + .spyOn(turboUtils, "getAvailablePackageManagers") + .mockResolvedValue({ + npm: { + available: true, + version: "8.19.2", + }, + yarn: { + available: true, + version: "1.22.19", + }, + pnpm: { + available: true, + version: "7.29.1", + }, + }); + + const { root } = useFixture({ + fixture: `./${fixtureManager}/${fixtureType}`, + }); + + // read + const details = await getWorkspaceDetails({ root }); + expect(details.packageManager).toBe(fixtureManager); + + // convert + const convertWrapper = () => + convert({ + root, + to: toManager, + options: { interactive, dry, skipInstall: !install }, + }); + + if (fixtureManager === toManager) { + await expect(convertWrapper()).rejects.toThrowError( + "You are already using this package manager" + ); + } else { + await expect(convertWrapper()).resolves.toBeUndefined(); + // read again + const convertedDetails = await getWorkspaceDetails({ + root, + }); + expect(mockedGetAvailablePackageManagers).toHaveBeenCalled(); + + if (dry) { + expect(convertedDetails.packageManager).toBe(fixtureManager); + } else { + if (install) { + expect(execa).toHaveBeenCalled(); + } + expect(convertedDetails.packageManager).toBe(toManager); + } + } + + mockedGetAvailablePackageManagers.mockRestore(); + } + ); + }); +}); diff --git a/packages/turbo-workspaces/__tests__/managers.test.ts b/packages/turbo-workspaces/__tests__/managers.test.ts new file mode 100644 index 0000000..73c5073 --- /dev/null +++ b/packages/turbo-workspaces/__tests__/managers.test.ts @@ -0,0 +1,285 @@ +import path from "path"; +import { setupTestFixtures } from "@turbo/test-utils"; +import { Logger } from "../src/logger"; +import MANAGERS from "../src/managers"; +import { PackageJson } from "../src/types"; +import fs from "fs-extra"; +import { + generateDetectMatrix, + generateCreateMatrix, + generateRemoveMatrix, + generateReadMatrix, + generateCleanMatrix, + generateConvertLockMatrix, +} from "./test-utils"; + +jest.mock("execa", () => jest.fn()); + +describe("managers", () => { + const { useFixture } = setupTestFixtures({ + directory: path.join(__dirname, "../"), + }); + + describe("detect", () => { + test.each(generateDetectMatrix())( + "$project $type project detected by $manager manager - (expect: $result)", + async ({ project, manager, type, result }) => { + const { root } = useFixture({ fixture: `./${project}/${type}` }); + + const detectResult = await MANAGERS[manager].detect({ + workspaceRoot: root, + }); + + expect(detectResult).toEqual(result); + } + ); + }); + + describe("create", () => { + test.each(generateCreateMatrix())( + "creates $manager project from $project $type project (interactive=$interactive, dry=$dry)", + async ({ project, manager, type, interactive, dry }) => { + expect.assertions(2); + + const { root } = useFixture({ fixture: `./${project}/${type}` }); + const testProject = await MANAGERS[project].read({ + workspaceRoot: root, + }); + + expect(testProject.packageManager).toEqual(project); + + await MANAGERS[manager].create({ + project: testProject, + to: { name: manager, version: "1.2.3" }, + logger: new Logger({ interactive, dry }), + options: { + interactive, + dry, + }, + }); + + if (dry) { + expect( + await MANAGERS[project].detect({ workspaceRoot: root }) + ).toEqual(true); + } else { + expect( + await MANAGERS[manager].detect({ workspaceRoot: root }) + ).toEqual(true); + } + } + ); + }); + + describe("remove", () => { + test.each(generateRemoveMatrix())( + "removes $fixtureManager from $fixtureManager $fixtureType project when moving to $toManager (withNodeModules=$withNodeModules, interactive=$interactive, dry=$dry)", + async ({ + fixtureManager, + fixtureType, + toManager, + withNodeModules, + interactive, + dry, + }) => { + const { root, readJson, readYaml } = useFixture({ + fixture: `./${fixtureManager}/${fixtureType}`, + }); + const project = await MANAGERS[fixtureManager].read({ + workspaceRoot: root, + }); + expect(project.packageManager).toEqual(fixtureManager); + + if (withNodeModules) { + fs.ensureDirSync(project.paths.nodeModules); + } + + await MANAGERS[fixtureManager].remove({ + project, + to: { name: toManager, version: "1.2.3" }, + logger: new Logger({ interactive, dry }), + options: { + interactive, + dry, + }, + }); + + if (withNodeModules) { + expect(fs.existsSync(project.paths.nodeModules)).toEqual(dry); + } + + const packageJson = readJson<PackageJson>(project.paths.packageJson); + if (dry) { + expect(packageJson?.packageManager).toBeDefined(); + expect(packageJson?.packageManager?.split("@")[0]).toEqual( + fixtureManager + ); + if (fixtureType === "basic") { + if (fixtureManager === "pnpm") { + expect(project.paths.workspaceConfig).toBeDefined(); + if (project.paths.workspaceConfig) { + const workspaceConfig = readYaml<{ packages: Array<string> }>( + project.paths.workspaceConfig + ); + expect(workspaceConfig?.packages).toBeDefined(); + expect(workspaceConfig?.packages).toEqual( + project.workspaceData.globs + ); + } + } else { + expect(packageJson?.workspaces).toBeDefined(); + expect(packageJson?.workspaces).toEqual( + project.workspaceData.globs + ); + } + } + } else { + expect(packageJson?.packageManager).toBeUndefined(); + if (fixtureType === "basic") { + expect(packageJson?.workspaces).toBeUndefined(); + + if (fixtureManager === "pnpm") { + expect(project.paths.workspaceConfig).toBeDefined(); + if (project.paths.workspaceConfig) { + const workspaceConfig = readYaml<{ packages: Array<string> }>( + project.paths.workspaceConfig + ); + expect(workspaceConfig).toBeUndefined(); + } + } + } + } + } + ); + }); + + describe("read", () => { + test.each(generateReadMatrix())( + "reads $toManager workspaces from $fixtureManager $fixtureType project - (shouldThrow: $shouldThrow)", + async ({ fixtureManager, fixtureType, toManager, shouldThrow }) => { + const { root, directoryName } = useFixture({ + fixture: `./${fixtureManager}/${fixtureType}`, + }); + + const read = async () => + MANAGERS[toManager].read({ workspaceRoot: path.join(root) }); + if (shouldThrow) { + if (toManager === "pnpm") { + expect(read).rejects.toThrow(`Not a pnpm project`); + } else if (toManager === "yarn") { + expect(read).rejects.toThrow(`Not a yarn project`); + } else if (toManager === "npm") { + expect(read).rejects.toThrow(`Not an npm project`); + } + return; + } + const project = await MANAGERS[toManager].read({ + workspaceRoot: path.join(root), + }); + + expect(project.name).toEqual( + fixtureType === "monorepo" ? `${toManager}-workspaces` : toManager + ); + expect(project.packageManager).toEqual(toManager); + + // paths + expect(project.paths.root).toMatch( + new RegExp(`^.*\/${directoryName}$`) + ); + expect(project.paths.packageJson).toMatch( + new RegExp(`^.*\/${directoryName}\/package.json$`) + ); + + if (fixtureManager === "pnpm") { + new RegExp(`^.*\/${directoryName}\/pnpm-lock.yaml$`); + } else if (fixtureManager === "yarn") { + new RegExp(`^.*\/${directoryName}\/yarn.lock$`); + } else if (fixtureManager === "npm") { + new RegExp(`^.*\/${directoryName}\/package-lock.json$`); + } else { + throw new Error("Invalid fixtureManager"); + } + + if (fixtureType === "non-monorepo") { + expect(project.workspaceData.workspaces).toEqual([]); + expect(project.workspaceData.globs).toEqual([]); + } else { + expect(project.workspaceData.globs).toEqual(["apps/*", "packages/*"]); + project.workspaceData.workspaces.forEach((workspace) => { + const type = ["web", "docs"].includes(workspace.name) + ? "apps" + : "packages"; + expect(workspace.paths.packageJson).toMatch( + new RegExp( + `^.*${directoryName}\/${type}\/${workspace.name}\/package.json$` + ) + ); + expect(workspace.paths.root).toMatch( + new RegExp(`^.*${directoryName}\/${type}\/${workspace.name}$`) + ); + }); + } + } + ); + }); + + describe("clean", () => { + test.each(generateCleanMatrix())( + "cleans $fixtureManager $fixtureType project (interactive=$interactive, dry=$dry)", + async ({ fixtureManager, fixtureType, interactive, dry }) => { + const { root } = useFixture({ + fixture: `./${fixtureManager}/${fixtureType}`, + }); + + const project = await MANAGERS[fixtureManager].read({ + workspaceRoot: root, + }); + + expect(project.packageManager).toEqual(fixtureManager); + + await MANAGERS[fixtureManager].clean({ + project, + logger: new Logger({ interactive, dry }), + options: { + interactive, + dry, + }, + }); + + expect(fs.existsSync(project.paths.lockfile)).toEqual(dry); + } + ); + }); + + describe("convertLock", () => { + test.each(generateConvertLockMatrix())( + "converts lockfile for $fixtureManager $fixtureType project to $toManager format (interactive=$interactive, dry=$dry)", + async ({ fixtureManager, fixtureType, toManager, interactive, dry }) => { + const { root, exists } = useFixture({ + fixture: `./${fixtureManager}/${fixtureType}`, + }); + + const project = await MANAGERS[fixtureManager].read({ + workspaceRoot: root, + }); + + expect(project.packageManager).toEqual(fixtureManager); + + await MANAGERS[toManager].convertLock({ + project, + logger: new Logger(), + options: { + interactive, + dry, + }, + }); + + if (fixtureManager !== toManager) { + expect(exists(project.paths.lockfile)).toEqual(dry); + } else { + expect(exists(project.paths.lockfile)).toEqual(true); + } + } + ); + }); +}); diff --git a/packages/turbo-workspaces/__tests__/test-utils.ts b/packages/turbo-workspaces/__tests__/test-utils.ts new file mode 100644 index 0000000..4d6c7c9 --- /dev/null +++ b/packages/turbo-workspaces/__tests__/test-utils.ts @@ -0,0 +1,153 @@ +import { PackageManager } from "../src/types"; + +const PACKAGE_MANAGERS: Array<PackageManager> = ["pnpm", "npm", "yarn"]; +const REPO_TYPES = ["monorepo", "non-monorepo"]; +const BOOLEAN_OPTIONS = [true, false]; + +export function generateConvertMatrix() { + const matrix = []; + for (const fixtureManager of PACKAGE_MANAGERS) { + for (const fixtureType of REPO_TYPES) { + for (const toManager of PACKAGE_MANAGERS) { + for (const interactive of BOOLEAN_OPTIONS) { + for (const dry of BOOLEAN_OPTIONS) { + for (const install of BOOLEAN_OPTIONS) { + matrix.push({ + fixtureManager, + fixtureType, + toManager, + interactive, + dry, + install, + }); + } + } + } + } + } + } + return matrix; +} + +export function generateDetectMatrix() { + const matrix = []; + for (const project of PACKAGE_MANAGERS) { + for (const manager of PACKAGE_MANAGERS) { + for (const type of REPO_TYPES) { + matrix.push({ + project, + manager, + type, + result: project === manager, + }); + } + } + } + return matrix; +} + +export function generateCreateMatrix() { + const matrix = []; + for (const project of PACKAGE_MANAGERS) { + for (const manager of PACKAGE_MANAGERS) { + for (const type of REPO_TYPES) { + for (const interactive of BOOLEAN_OPTIONS) { + for (const dry of BOOLEAN_OPTIONS) { + matrix.push({ + project, + manager, + type, + interactive, + dry, + }); + } + } + } + } + } + return matrix; +} + +export function generateReadMatrix() { + const matrix = []; + for (const fixtureManager of PACKAGE_MANAGERS) { + for (const fixtureType of REPO_TYPES) { + for (const toManager of PACKAGE_MANAGERS) { + matrix.push({ + fixtureManager, + fixtureType, + toManager, + shouldThrow: fixtureManager !== toManager, + }); + } + } + } + + return matrix; +} + +export function generateRemoveMatrix() { + const matrix = []; + for (const fixtureManager of PACKAGE_MANAGERS) { + for (const fixtureType of REPO_TYPES) { + for (const toManager of PACKAGE_MANAGERS) { + for (const withNodeModules of BOOLEAN_OPTIONS) { + for (const interactive of BOOLEAN_OPTIONS) { + for (const dry of BOOLEAN_OPTIONS) { + matrix.push({ + fixtureManager, + fixtureType, + withNodeModules, + toManager, + interactive, + dry, + }); + } + } + } + } + } + } + return matrix; +} + +export function generateCleanMatrix() { + const matrix = []; + for (const fixtureManager of PACKAGE_MANAGERS) { + for (const fixtureType of REPO_TYPES) { + for (const interactive of BOOLEAN_OPTIONS) { + for (const dry of BOOLEAN_OPTIONS) { + matrix.push({ + fixtureManager, + fixtureType, + interactive, + dry, + }); + } + } + } + } + return matrix; +} + +export function generateConvertLockMatrix() { + const matrix = []; + for (const fixtureManager of PACKAGE_MANAGERS) { + for (const fixtureType of REPO_TYPES) { + for (const toManager of PACKAGE_MANAGERS) { + for (const interactive of BOOLEAN_OPTIONS) { + for (const dry of BOOLEAN_OPTIONS) { + matrix.push({ + fixtureManager, + fixtureType, + toManager, + interactive, + dry, + }); + } + } + } + } + } + return matrix; +} |
