From 638bcf1fc7f4908f18cfb21b9ea2f2d3e3c1c116 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 14 Jul 2023 10:56:42 -0400 Subject: [PATCH 1/4] Reorganize tests in to multiple files so the tests are less overwhelming to work with --- tests/cli.test.ts | 536 ------------------ tests/smoke-tests/--addon-location.test.ts | 45 ++ tests/smoke-tests/--addon-only.test.ts | 49 ++ tests/smoke-tests/--test-app-location.test.ts | 45 ++ tests/smoke-tests/--typescript.test.ts | 75 +++ tests/smoke-tests/defaults.test.ts | 107 ++++ .../custom-locations.test.ts | 107 ++++ .../within-existing-monorepo/defaults.test.ts | 137 +++++ tests/utils.ts | 38 +- 9 files changed, 602 insertions(+), 537 deletions(-) delete mode 100644 tests/cli.test.ts create mode 100644 tests/smoke-tests/--addon-location.test.ts create mode 100644 tests/smoke-tests/--addon-only.test.ts create mode 100644 tests/smoke-tests/--test-app-location.test.ts create mode 100644 tests/smoke-tests/--typescript.test.ts create mode 100644 tests/smoke-tests/defaults.test.ts create mode 100644 tests/smoke-tests/within-existing-monorepo/custom-locations.test.ts create mode 100644 tests/smoke-tests/within-existing-monorepo/defaults.test.ts diff --git a/tests/cli.test.ts b/tests/cli.test.ts deleted file mode 100644 index bcda9e58..00000000 --- a/tests/cli.test.ts +++ /dev/null @@ -1,536 +0,0 @@ -import { type Options, execa } from 'execa'; -import fixturify from 'fixturify'; -import fse from 'fs-extra'; -import fs from 'node:fs/promises'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { afterAll, beforeAll, describe, expect, it } from 'vitest'; - -import { assertGeneratedCorrectly } from './assertions.js'; -import { createTmp, dirContents, install, runScript } from './utils.js'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -const blueprintPath = path.join(__dirname, '..'); - -describe('ember addon -b ', () => { - async function createAddon({ - name = 'my-addon', - args = [], - options = {}, - }: { - name?: string; - args?: string[]; - options?: Options; - }) { - let result = await execa( - 'ember', - ['addon', name, '-b', blueprintPath, '--skip-npm', '--skip-git', ...args], - { ...options, env: { ...options.env, EMBER_CLI_PNPM: 'true' }, preferLocal: true } - ); - - // Light work-around for an upstream `@babel/core` peer issue - if (typeof options.cwd === 'string') { - await fs.writeFile( - fse.existsSync(path.join(options.cwd, name)) - ? path.join(options.cwd, name, '.npmrc') - : path.join(options.cwd, '.npmrc'), - 'auto-install-peers=true' - ); - } - - return { result, name }; - } - - ['npm', 'yarn', 'pnpm'].map((packageManager) => { - describe(`defaults with ${packageManager}`, () => { - let cwd = ''; - let tmpDir = ''; - let distDir = ''; - - beforeAll(async () => { - tmpDir = await createTmp(); - - console.debug(`Debug test repo at ${tmpDir}`); - - let { name } = await createAddon({ - args: [`--${packageManager}=true`], - options: { cwd: tmpDir }, - }); - - cwd = path.join(tmpDir, name); - distDir = path.join(cwd, name, 'dist'); - - await install({ cwd, packageManager }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('is using the correct packager', async () => { - let npm = path.join(cwd, 'package-lock.json'); - let yarn = path.join(cwd, 'yarn.lock'); - let pnpm = path.join(cwd, 'pnpm-lock.yaml'); - - switch (packageManager) { - case 'npm': { - expect(await fse.pathExists(npm), 'for NPM: package-lock.json exists').toBe(true); - expect(await fse.pathExists(yarn), 'yarn.lock does not exist').toBe(false); - expect(await fse.pathExists(pnpm), 'pnpm-lock.yaml does not exist').toBe(false); - - break; - } - case 'yarn': { - expect(await fse.pathExists(yarn), 'for Yarn: yarn.lock exists').toBe(true); - expect(await fse.pathExists(npm), 'package-lock.json does not exist').toBe(false); - expect(await fse.pathExists(pnpm), 'pnpm-lock.yaml does not exist').toBe(false); - - break; - } - case 'pnpm': { - expect(await fse.pathExists(pnpm), 'for pnpm: pnpm-lock.yaml exists').toBe(true); - expect(await fse.pathExists(npm), 'package-lock.json does not exist').toBe(false); - expect(await fse.pathExists(yarn), 'yarn.lock does not exist').toBe(false); - - break; - } - - default: - throw new Error(`unknown packageManager: ${packageManager}`); - } - }); - - it('"prepare" built the addon', async () => { - let contents = await dirContents(distDir); - - expect(contents).to.deep.equal(['index.js', 'index.js.map']); - }); - - it('was generated correctly', async () => { - assertGeneratedCorrectly({ projectRoot: cwd }); - }); - - it('builds the addon', async () => { - let { exitCode } = await runScript({ cwd, script: 'build', packageManager }); - - expect(exitCode).toEqual(0); - - let contents = await dirContents(distDir); - - expect(contents).to.deep.equal(['index.js', 'index.js.map']); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ cwd, script: 'test', packageManager }); - - expect(exitCode).toEqual(0); - }); - - it('lints all pass', async () => { - let { exitCode } = await runScript({ cwd, script: 'lint', packageManager }); - - expect(exitCode).toEqual(0); - }); - }); - - describe('--typescript', () => { - let cwd = ''; - let tmpDir = ''; - let distDir = ''; - - beforeAll(async () => { - tmpDir = await createTmp(); - - let { name } = await createAddon({ - args: ['--typescript', `--${packageManager}=true`, '--skip-npm'], - options: { cwd: tmpDir }, - }); - - cwd = path.join(tmpDir, name); - distDir = path.join(cwd, name, 'dist'); - - await install({ cwd, packageManager, skipPrepare: true }); - }); - - afterAll(async () => { - await fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('was generated correctly', async () => { - await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); - - assertGeneratedCorrectly({ projectRoot: cwd }); - }); - - it('builds the addon', async () => { - let { exitCode } = await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - - let contents = await dirContents(distDir); - - expect(contents).to.deep.equal([ - 'index.d.ts', - 'index.d.ts.map', - 'index.js', - 'index.js.map', - 'template-registry.d.ts', - 'template-registry.js', - 'template-registry.js.map', - ]); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - - it('lints all pass', async () => { - let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - }); - }); - - describe('--addon-location', () => { - let cwd = ''; - let tmpDir = ''; - let addonLocation = 'packages/my-custom-location'; - - beforeAll(async () => { - tmpDir = await createTmp(); - - let { name } = await createAddon({ - args: [`--addon-location=${addonLocation}`, '--pnpm=true'], - options: { cwd: tmpDir }, - }); - - cwd = path.join(tmpDir, name); - - await install({ cwd, packageManager: 'pnpm' }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('was generated correctly', async () => { - assertGeneratedCorrectly({ projectRoot: cwd, addonLocation }); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - - it('lints all pass', async () => { - let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - }); - - describe('--test-app-location', () => { - let cwd = ''; - let tmpDir = ''; - let testAppLocation = 'packages/my-custom-location'; - - beforeAll(async () => { - tmpDir = await createTmp(); - - let { name } = await createAddon({ - args: [`--test-app-location=${testAppLocation}`, '--pnpm=true'], - options: { cwd: tmpDir }, - }); - - cwd = path.join(tmpDir, name); - - await install({ cwd, packageManager: 'pnpm' }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('was generated correctly', async () => { - assertGeneratedCorrectly({ projectRoot: cwd, testAppLocation }); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - - it('lints all pass', async () => { - let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - }); - - describe('existing monorepo', () => { - let commonFixtures = { - '.prettierrc.js': - // prettier-ignore - 'module.exports = {' + - ' singleQuote: true,' + - '};', - }; - - ['npm', 'yarn', 'pnpm'].map((packageManager) => - describe(`monorepo with ${packageManager}`, () => { - let cwd = ''; - let tmpDir = ''; - let addonLocation = 'my-addon'; - let testAppLocation = 'test-app'; - let rootPackageJson; - let rootFiles = {}; - let lockFile = - packageManager === 'yarn' - ? 'yarn.lock' - : packageManager === 'pnpm' - ? 'pnpm-lock.yaml' - : 'package-lock.json'; - - beforeAll(async () => { - tmpDir = await createTmp(); - - switch (packageManager) { - case 'npm': - case 'yarn': - rootPackageJson = { - name: 'existing-monorepo', - private: true, - workspaces: ['*'], - devDependencies: { - prettier: '^2.5.0', - }, - }; - rootFiles = { - ...commonFixtures, - 'package.json': JSON.stringify(rootPackageJson), - }; - fixturify.writeSync(tmpDir, rootFiles); - - break; - case 'pnpm': - rootPackageJson = { - name: 'existing-monorepo', - private: true, - devDependencies: { - prettier: '^2.5.0', - }, - }; - rootFiles = { - ...commonFixtures, - 'package.json': JSON.stringify(rootPackageJson), - 'pnpm-workspace.yaml': "packages:\n - '*'", - }; - fixturify.writeSync(tmpDir, rootFiles); - - break; - } - - await createAddon({ - args: [`--${packageManager}=true`], - options: { cwd: tmpDir }, - }); - - cwd = tmpDir; - - await install({ cwd, packageManager }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('ignores root files', async () => { - expect( - fixturify.readSync(cwd, { - ignore: ['my-addon', 'test-app', 'node_modules', lockFile, '.npmrc'], - }), - 'root files have not been touched' - ).toEqual(rootFiles); - }); - - it('was generated correctly', async () => { - await assertGeneratedCorrectly({ - projectRoot: cwd, - expectedStaticFiles: ['README.md', 'CONTRIBUTING.md'], - }); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, testAppLocation), - script: 'test', - packageManager, - }); - - expect(exitCode).toEqual(0); - }); - - it('addon lints all pass', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, addonLocation), - script: 'lint', - packageManager, - }); - - expect(exitCode).toEqual(0); - }); - - it('test-app lints all pass', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, testAppLocation), - script: 'lint', - packageManager, - }); - - expect(exitCode).toEqual(0); - }); - }) - ); - - describe('custom locations', () => { - let cwd = ''; - let tmpDir = ''; - let addonLocation = 'addons/my-fancy-addon'; - let testAppLocation = 'tests/my-fancy-addon'; - let rootFiles = {}; - - beforeAll(async () => { - tmpDir = await createTmp(); - - let rootPackageJson = { - name: 'existing-monorepo', - private: true, - devDependencies: { - prettier: '^2.5.0', - }, - }; - - rootFiles = { - ...commonFixtures, - 'package.json': JSON.stringify(rootPackageJson), - 'pnpm-workspace.yaml': "packages:\n - 'addons/*'\n - 'tests/*'", - }; - fixturify.writeSync(tmpDir, rootFiles); - - await createAddon({ - args: [ - `--addon-location=${addonLocation}`, - `--test-app-location=${testAppLocation}`, - '--pnpm=true', - ], - options: { cwd: tmpDir }, - }); - - cwd = tmpDir; - - await install({ cwd, packageManager: 'pnpm' }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('ignores root files', async () => { - expect( - fixturify.readSync(cwd, { - ignore: ['addons', 'tests', 'node_modules', 'pnpm-lock.yaml', '.npmrc'], - }), - 'root files have not been touched' - ).toEqual(rootFiles); - }); - - it('was generated correctly', async () => { - assertGeneratedCorrectly({ - projectRoot: cwd, - addonLocation, - testAppLocation, - expectedStaticFiles: ['README.md', 'CONTRIBUTING.md'], - }); - }); - - it('runs tests', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, testAppLocation), - script: 'test', - packageManager: 'pnpm', - }); - - expect(exitCode).toEqual(0); - }); - - it('addon lints all pass', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, addonLocation), - script: 'lint', - packageManager: 'pnpm', - }); - - expect(exitCode).toEqual(0); - }); - - it('test-app lints all pass', async () => { - let { exitCode } = await runScript({ - cwd: path.join(cwd, testAppLocation), - script: 'lint', - packageManager: 'pnpm', - }); - - expect(exitCode).toEqual(0); - }); - }); - }); - - describe('--addon-only', () => { - let cwd = ''; - let tmpDir = ''; - - beforeAll(async () => { - tmpDir = await createTmp(); - - let { name } = await createAddon({ - args: ['--addon-only', '--pnpm=true'], - options: { cwd: tmpDir }, - }); - - cwd = path.join(tmpDir, name); - - await install({ cwd, packageManager: 'pnpm' }); - }); - - afterAll(async () => { - fs.rm(tmpDir, { recursive: true, force: true }); - }); - - it('is not a monorepo', async () => { - let hasPnpmWorkspace = await fse.pathExists(path.join(cwd, 'pnpm-workspace.yaml')); - let packageJson = await fse.readJson(path.join(cwd, 'package.json')); - - expect(hasPnpmWorkspace).toBe(false); - // Pnpm doesn't use this field, but it's good that it doesn't exist. - expect(packageJson.workspaces).toBeFalsy(); - }); - - it('can build', async () => { - let { exitCode } = await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - - it('has passing lints', async () => { - let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); - - expect(exitCode).toEqual(0); - }); - }); -}); diff --git a/tests/smoke-tests/--addon-location.test.ts b/tests/smoke-tests/--addon-location.test.ts new file mode 100644 index 00000000..fc181738 --- /dev/null +++ b/tests/smoke-tests/--addon-location.test.ts @@ -0,0 +1,45 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../assertions.js'; +import { createAddon, createTmp, install, runScript } from '../utils.js'; + +describe('--addon-location', () => { + let cwd = ''; + let tmpDir = ''; + let addonLocation = 'packages/my-custom-location'; + + beforeAll(async () => { + tmpDir = await createTmp(); + + let { name } = await createAddon({ + args: [`--addon-location=${addonLocation}`, '--pnpm=true'], + options: { cwd: tmpDir }, + }); + + cwd = path.join(tmpDir, name); + + await install({ cwd, packageManager: 'pnpm' }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('was generated correctly', async () => { + assertGeneratedCorrectly({ projectRoot: cwd, addonLocation }); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); + + it('lints all pass', async () => { + let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); +}); diff --git a/tests/smoke-tests/--addon-only.test.ts b/tests/smoke-tests/--addon-only.test.ts new file mode 100644 index 00000000..5605f17a --- /dev/null +++ b/tests/smoke-tests/--addon-only.test.ts @@ -0,0 +1,49 @@ +import fse from 'fs-extra'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { createAddon, createTmp, install, runScript } from '../utils.js'; + +describe('--addon-only', () => { + let cwd = ''; + let tmpDir = ''; + + beforeAll(async () => { + tmpDir = await createTmp(); + + let { name } = await createAddon({ + args: ['--addon-only', '--pnpm=true'], + options: { cwd: tmpDir }, + }); + + cwd = path.join(tmpDir, name); + + await install({ cwd, packageManager: 'pnpm' }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('is not a monorepo', async () => { + let hasPnpmWorkspace = await fse.pathExists(path.join(cwd, 'pnpm-workspace.yaml')); + let packageJson = await fse.readJson(path.join(cwd, 'package.json')); + + expect(hasPnpmWorkspace).toBe(false); + // Pnpm doesn't use this field, but it's good that it doesn't exist. + expect(packageJson.workspaces).toBeFalsy(); + }); + + it('can build', async () => { + let { exitCode } = await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); + + it('has passing lints', async () => { + let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); +}); diff --git a/tests/smoke-tests/--test-app-location.test.ts b/tests/smoke-tests/--test-app-location.test.ts new file mode 100644 index 00000000..e5bd1d0e --- /dev/null +++ b/tests/smoke-tests/--test-app-location.test.ts @@ -0,0 +1,45 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../assertions.js'; +import { createAddon, createTmp, install, runScript } from '../utils.js'; + +describe('--test-app-location', () => { + let cwd = ''; + let tmpDir = ''; + let testAppLocation = 'packages/my-custom-location'; + + beforeAll(async () => { + tmpDir = await createTmp(); + + let { name } = await createAddon({ + args: [`--test-app-location=${testAppLocation}`, '--pnpm=true'], + options: { cwd: tmpDir }, + }); + + cwd = path.join(tmpDir, name); + + await install({ cwd, packageManager: 'pnpm' }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('was generated correctly', async () => { + assertGeneratedCorrectly({ projectRoot: cwd, testAppLocation }); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); + + it('lints all pass', async () => { + let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); +}); diff --git a/tests/smoke-tests/--typescript.test.ts b/tests/smoke-tests/--typescript.test.ts new file mode 100644 index 00000000..8b9784fe --- /dev/null +++ b/tests/smoke-tests/--typescript.test.ts @@ -0,0 +1,75 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../assertions.js'; +import { + createAddon, + createTmp, + dirContents, + install, + runScript, + SUPPORTED_PACKAGE_MANAGERS, +} from '../utils.js'; + +for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { + describe(`--typescript with ${packageManager}`, () => { + let cwd = ''; + let tmpDir = ''; + let distDir = ''; + + beforeAll(async () => { + tmpDir = await createTmp(); + + let { name } = await createAddon({ + args: ['--typescript', `--${packageManager}=true`, '--skip-npm'], + options: { cwd: tmpDir }, + }); + + cwd = path.join(tmpDir, name); + distDir = path.join(cwd, name, 'dist'); + + await install({ cwd, packageManager, skipPrepare: true }); + }); + + afterAll(async () => { + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('was generated correctly', async () => { + await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); + + assertGeneratedCorrectly({ projectRoot: cwd }); + }); + + it('builds the addon', async () => { + let { exitCode } = await runScript({ cwd, script: 'build', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + + let contents = await dirContents(distDir); + + expect(contents).to.deep.equal([ + 'index.d.ts', + 'index.d.ts.map', + 'index.js', + 'index.js.map', + 'template-registry.d.ts', + 'template-registry.js', + 'template-registry.js.map', + ]); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ cwd, script: 'test', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); + + it('lints all pass', async () => { + let { exitCode } = await runScript({ cwd, script: 'lint', packageManager: 'pnpm' }); + + expect(exitCode).toEqual(0); + }); + }); +} diff --git a/tests/smoke-tests/defaults.test.ts b/tests/smoke-tests/defaults.test.ts new file mode 100644 index 00000000..063fc9ba --- /dev/null +++ b/tests/smoke-tests/defaults.test.ts @@ -0,0 +1,107 @@ +import fse from 'fs-extra'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../assertions.js'; +import { + createAddon, + createTmp, + dirContents, + install, + runScript, + SUPPORTED_PACKAGE_MANAGERS, +} from '../utils.js'; + +for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { + describe(`defaults with ${packageManager}`, () => { + let cwd = ''; + let tmpDir = ''; + let distDir = ''; + + beforeAll(async () => { + tmpDir = await createTmp(); + + console.debug(`Debug test repo at ${tmpDir}`); + + let { name } = await createAddon({ + args: [`--${packageManager}=true`], + options: { cwd: tmpDir }, + }); + + cwd = path.join(tmpDir, name); + distDir = path.join(cwd, name, 'dist'); + + await install({ cwd, packageManager }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('is using the correct packager', async () => { + let npm = path.join(cwd, 'package-lock.json'); + let yarn = path.join(cwd, 'yarn.lock'); + let pnpm = path.join(cwd, 'pnpm-lock.yaml'); + + switch (packageManager) { + case 'npm': { + expect(await fse.pathExists(npm), 'for NPM: package-lock.json exists').toBe(true); + expect(await fse.pathExists(yarn), 'yarn.lock does not exist').toBe(false); + expect(await fse.pathExists(pnpm), 'pnpm-lock.yaml does not exist').toBe(false); + + break; + } + case 'yarn': { + expect(await fse.pathExists(yarn), 'for Yarn: yarn.lock exists').toBe(true); + expect(await fse.pathExists(npm), 'package-lock.json does not exist').toBe(false); + expect(await fse.pathExists(pnpm), 'pnpm-lock.yaml does not exist').toBe(false); + + break; + } + case 'pnpm': { + expect(await fse.pathExists(pnpm), 'for pnpm: pnpm-lock.yaml exists').toBe(true); + expect(await fse.pathExists(npm), 'package-lock.json does not exist').toBe(false); + expect(await fse.pathExists(yarn), 'yarn.lock does not exist').toBe(false); + + break; + } + + default: + throw new Error(`unknown packageManager: ${packageManager}`); + } + }); + + it('"prepare" built the addon', async () => { + let contents = await dirContents(distDir); + + expect(contents).to.deep.equal(['index.js', 'index.js.map']); + }); + + it('was generated correctly', async () => { + assertGeneratedCorrectly({ projectRoot: cwd }); + }); + + it('builds the addon', async () => { + let { exitCode } = await runScript({ cwd, script: 'build', packageManager }); + + expect(exitCode).toEqual(0); + + let contents = await dirContents(distDir); + + expect(contents).to.deep.equal(['index.js', 'index.js.map']); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ cwd, script: 'test', packageManager }); + + expect(exitCode).toEqual(0); + }); + + it('lints all pass', async () => { + let { exitCode } = await runScript({ cwd, script: 'lint', packageManager }); + + expect(exitCode).toEqual(0); + }); + }); +} diff --git a/tests/smoke-tests/within-existing-monorepo/custom-locations.test.ts b/tests/smoke-tests/within-existing-monorepo/custom-locations.test.ts new file mode 100644 index 00000000..786616c9 --- /dev/null +++ b/tests/smoke-tests/within-existing-monorepo/custom-locations.test.ts @@ -0,0 +1,107 @@ +import fixturify from 'fixturify'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../../assertions.js'; +import { createAddon, createTmp, install, runScript } from '../../utils.js'; + +let commonFixtures = { + '.prettierrc.js': + // prettier-ignore + 'module.exports = {' + + ' singleQuote: true,' + + '};', +}; + +describe('custom locations', () => { + let cwd = ''; + let tmpDir = ''; + let addonLocation = 'addons/my-fancy-addon'; + let testAppLocation = 'tests/my-fancy-addon'; + let rootFiles = {}; + + beforeAll(async () => { + tmpDir = await createTmp(); + + let rootPackageJson = { + name: 'existing-monorepo', + private: true, + devDependencies: { + prettier: '^2.5.0', + }, + }; + + rootFiles = { + ...commonFixtures, + 'package.json': JSON.stringify(rootPackageJson), + 'pnpm-workspace.yaml': "packages:\n - 'addons/*'\n - 'tests/*'", + }; + fixturify.writeSync(tmpDir, rootFiles); + + await createAddon({ + args: [ + `--addon-location=${addonLocation}`, + `--test-app-location=${testAppLocation}`, + '--pnpm=true', + ], + options: { cwd: tmpDir }, + }); + + cwd = tmpDir; + + await install({ cwd, packageManager: 'pnpm' }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('ignores root files', async () => { + expect( + fixturify.readSync(cwd, { + ignore: ['addons', 'tests', 'node_modules', 'pnpm-lock.yaml', '.npmrc'], + }), + 'root files have not been touched' + ).toEqual(rootFiles); + }); + + it('was generated correctly', async () => { + assertGeneratedCorrectly({ + projectRoot: cwd, + addonLocation, + testAppLocation, + expectedStaticFiles: ['README.md', 'CONTRIBUTING.md'], + }); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, testAppLocation), + script: 'test', + packageManager: 'pnpm', + }); + + expect(exitCode).toEqual(0); + }); + + it('addon lints all pass', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, addonLocation), + script: 'lint', + packageManager: 'pnpm', + }); + + expect(exitCode).toEqual(0); + }); + + it('test-app lints all pass', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, testAppLocation), + script: 'lint', + packageManager: 'pnpm', + }); + + expect(exitCode).toEqual(0); + }); +}); diff --git a/tests/smoke-tests/within-existing-monorepo/defaults.test.ts b/tests/smoke-tests/within-existing-monorepo/defaults.test.ts new file mode 100644 index 00000000..ee894988 --- /dev/null +++ b/tests/smoke-tests/within-existing-monorepo/defaults.test.ts @@ -0,0 +1,137 @@ +import fixturify from 'fixturify'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +import { assertGeneratedCorrectly } from '../../assertions.js'; +import { + createAddon, + createTmp, + install, + runScript, + SUPPORTED_PACKAGE_MANAGERS, +} from '../../utils.js'; + +let commonFixtures = { + '.prettierrc.js': + // prettier-ignore + 'module.exports = {' + + ' singleQuote: true,' + + '};', +}; + +for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { + describe(`monorepo with ${packageManager}`, () => { + let cwd = ''; + let tmpDir = ''; + let addonLocation = 'my-addon'; + let testAppLocation = 'test-app'; + let rootPackageJson; + let rootFiles = {}; + let lockFile = + packageManager === 'yarn' + ? 'yarn.lock' + : packageManager === 'pnpm' + ? 'pnpm-lock.yaml' + : 'package-lock.json'; + + beforeAll(async () => { + tmpDir = await createTmp(); + + switch (packageManager) { + case 'npm': + case 'yarn': + rootPackageJson = { + name: 'existing-monorepo', + private: true, + workspaces: ['*'], + devDependencies: { + prettier: '^2.5.0', + }, + }; + rootFiles = { + ...commonFixtures, + 'package.json': JSON.stringify(rootPackageJson), + }; + fixturify.writeSync(tmpDir, rootFiles); + + break; + case 'pnpm': + rootPackageJson = { + name: 'existing-monorepo', + private: true, + devDependencies: { + prettier: '^2.5.0', + }, + }; + rootFiles = { + ...commonFixtures, + 'package.json': JSON.stringify(rootPackageJson), + 'pnpm-workspace.yaml': "packages:\n - '*'", + }; + fixturify.writeSync(tmpDir, rootFiles); + + break; + } + + await createAddon({ + args: [`--${packageManager}=true`], + options: { cwd: tmpDir }, + }); + + cwd = tmpDir; + + await install({ cwd, packageManager }); + }); + + afterAll(async () => { + fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('ignores root files', async () => { + expect( + fixturify.readSync(cwd, { + ignore: ['my-addon', 'test-app', 'node_modules', lockFile, '.npmrc'], + }), + 'root files have not been touched' + ).toEqual(rootFiles); + }); + + it('was generated correctly', async () => { + await assertGeneratedCorrectly({ + projectRoot: cwd, + expectedStaticFiles: ['README.md', 'CONTRIBUTING.md'], + }); + }); + + it('runs tests', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, testAppLocation), + script: 'test', + packageManager, + }); + + expect(exitCode).toEqual(0); + }); + + it('addon lints all pass', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, addonLocation), + script: 'lint', + packageManager, + }); + + expect(exitCode).toEqual(0); + }); + + it('test-app lints all pass', async () => { + let { exitCode } = await runScript({ + cwd: path.join(cwd, testAppLocation), + script: 'lint', + packageManager, + }); + + expect(exitCode).toEqual(0); + }); + }); +} diff --git a/tests/utils.ts b/tests/utils.ts index f7191a5f..488a76b0 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,7 +1,15 @@ -import { execa } from 'execa'; +import { type Options, execa } from 'execa'; +import fse from 'fs-extra'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const blueprintPath = path.join(__dirname, '..'); + +export const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'] as const; export async function createTmp() { let prefix = 'v2-addon-blueprint--'; @@ -103,3 +111,31 @@ export async function packageJsonAt(dirPath: string) { return JSON.parse(str); } + +export async function createAddon({ + name = 'my-addon', + args = [], + options = {}, +}: { + name?: string; + args?: string[]; + options?: Options; +}) { + let result = await execa( + 'ember', + ['addon', name, '-b', blueprintPath, '--skip-npm', '--skip-git', ...args], + { ...options, env: { ...options.env, EMBER_CLI_PNPM: 'true' }, preferLocal: true } + ); + + // Light work-around for an upstream `@babel/core` peer issue + if (typeof options.cwd === 'string') { + await fs.writeFile( + fse.existsSync(path.join(options.cwd, name)) + ? path.join(options.cwd, name, '.npmrc') + : path.join(options.cwd, '.npmrc'), + 'auto-install-peers=true' + ); + } + + return { result, name }; +} From 77806ea097979173400f34b996366e0b6cd72ddd Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:22:19 -0400 Subject: [PATCH 2/4] Looks like the typescript tests potentially weren't running before, but they are now? --- tests/smoke-tests/--typescript.test.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/smoke-tests/--typescript.test.ts b/tests/smoke-tests/--typescript.test.ts index 8b9784fe..6b03a375 100644 --- a/tests/smoke-tests/--typescript.test.ts +++ b/tests/smoke-tests/--typescript.test.ts @@ -17,6 +17,7 @@ for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { let cwd = ''; let tmpDir = ''; let distDir = ''; + let declarationsDir = ''; beforeAll(async () => { tmpDir = await createTmp(); @@ -28,12 +29,13 @@ for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { cwd = path.join(tmpDir, name); distDir = path.join(cwd, name, 'dist'); + declarationsDir = path.join(cwd, name, 'declarations'); await install({ cwd, packageManager, skipPrepare: true }); }); afterAll(async () => { - await fs.rm(tmpDir, { recursive: true, force: true }); + // await fs.rm(tmpDir, { recursive: true, force: true }); }); it('was generated correctly', async () => { @@ -47,17 +49,22 @@ for (let packageManager of SUPPORTED_PACKAGE_MANAGERS) { expect(exitCode).toEqual(0); - let contents = await dirContents(distDir); + let distContents = await dirContents(distDir); + let declarationsContents = await dirContents(declarationsDir); - expect(contents).to.deep.equal([ - 'index.d.ts', - 'index.d.ts.map', + expect(distContents).to.deep.equal([ 'index.js', 'index.js.map', - 'template-registry.d.ts', 'template-registry.js', 'template-registry.js.map', ]); + + expect(declarationsContents).to.deep.equal([ + 'index.d.ts', + 'index.d.ts.map', + 'template-registry.d.ts', + 'template-registry.d.ts.map', + ]); }); it('runs tests', async () => { From 42cf171a374946db8de6a47f6cd04ac205c78c23 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:24:08 -0400 Subject: [PATCH 3/4] lint:fix --- tests/smoke-tests/--typescript.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/smoke-tests/--typescript.test.ts b/tests/smoke-tests/--typescript.test.ts index 6b03a375..b0c07c60 100644 --- a/tests/smoke-tests/--typescript.test.ts +++ b/tests/smoke-tests/--typescript.test.ts @@ -1,4 +1,3 @@ -import fs from 'node:fs/promises'; import path from 'node:path'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; From ac317f87158738746e97985421bf93cc93ab8307 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:45:36 -0400 Subject: [PATCH 4/4] Add @types/ember__owner to the --typescript output --- files/__addonLocation__/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/files/__addonLocation__/package.json b/files/__addonLocation__/package.json index c816cd6a..8133b290 100644 --- a/files/__addonLocation__/package.json +++ b/files/__addonLocation__/package.json @@ -48,6 +48,7 @@ "@tsconfig/ember": "^2.0.0", "@types/ember": "^4.0.0", "@types/ember__object": "^4.0.0", + "@types/ember__owner": "^4.0.0", "@types/ember__service": "^4.0.0", "@types/ember__controller": "^4.0.0", "@types/ember__string": "^3.16.0",