diff --git a/.betterer.results b/.betterer.results index b01315c8f..33eaa70bd 100644 --- a/.betterer.results +++ b/.betterer.results @@ -4,7 +4,7 @@ exports[`no hack comments`] = { "packages/cli/src/cli.ts:1074837834": [ [13, 0, 7, "RegExp match", "645651780"] ], - "packages/cli/src/init/update-package-json.ts:2842907794": [ + "packages/cli/src/init/update-package-json.ts:887451963": [ [34, 4, 7, "RegExp match", "645651780"] ] }` diff --git a/README.md b/README.md index 80da50049..077729849 100644 --- a/README.md +++ b/README.md @@ -183,16 +183,16 @@ betterer -c ./path/to/config -r ./path/to/results -w #### Start options -| Name | Description | Default | -| ------------------------------ | --------------------------------------------------------------------------- | --------------------- | -| `-c`, `--config` [value] | Path to test definition file relative to CWD. Takes multiple values | `./.betterer.ts` | -| `-r`, `--results` [value] | Path to test results file relative to CWD | `./.betterer.results` | -| `-t`, `--tsconfig` [value] | Path to TypeScript config file relative to CWD | `null` | -| `-f`, `--filter` [value] | Select tests to run by RegExp. Takes multiple values | `[]` | -| `-s`, `--silent [true\|false]` | Disable all default reporters. Custom reporters still work normally | `false` | -| `-u`, `--update [true\|false]` | Force update the results file, even if things get worse | `false` | -| `--allow-update [true\|false]` | Allow updating via the `--update` flag | `true` | -| `-R`, `--reporter` [value] | npm package name or file path to a Betterer reporter. Takes multiple values | Default reporter | +| Name | Description | Default | +| -------------------------- | -------------------------------------------------------------------------------------------------- | --------------------- | +| `-c`, `--config` [value] | Path to test definition file relative to CWD. Takes multiple values | `./.betterer.ts` | +| `-r`, `--results` [value] | Path to test results file relative to CWD | `./.betterer.results` | +| `-t`, `--tsconfig` [value] | Path to TypeScript config file relative to CWD | `null` | +| `-f`, `--filter` [value] | Select tests to run by RegExp. Takes multiple values | `[]` | +| `-s`, `--silent` | When present, all default reporters will be disabled. Custom reporters will still work normally. | `false` | +| `-u`, `--update` | When present, the results file will be updated, even if things get worse | `false` | +| `--allow-update` | When set to false, the update message will not be shown and the `--update` option will be ignored. | `true` | +| `-R`, `--reporter` [value] | npm package name or file path to a Betterer reporter. Takes multiple values | Default reporter | ### CI diff --git a/packages/cli/README.md b/packages/cli/README.md index d4618278e..e7329f26e 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -32,16 +32,16 @@ betterer -c ./path/to/config -r ./path/to/results -w #### Start options -| Name | Description | Default | -| ------------------------------ | --------------------------------------------------------------------------- | --------------------- | -| `-c`, `--config` [value] | Path to test definition file relative to CWD. Takes multiple values | `./.betterer.ts` | -| `-r`, `--results` [value] | Path to test results file relative to CWD | `./.betterer.results` | -| `-t`, `--tsconfig` [value] | Path to TypeScript config file relative to CWD | `null` | -| `-f`, `--filter` [value] | Select tests to run by RegExp. Takes multiple values | `[]` | -| `-s`, `--silent [true\|false]` | Disable all default reporters. Custom reporters still work normally | `false` | -| `-u`, `--update [true\|false]` | Force update the results file, even if things get worse | `false` | -| `--allow-update [true\|false]` | Allow updating via the `--update` flag | `true` | -| `-R`, `--reporter` [value] | npm package name or file path to a Betterer reporter. Takes multiple values | Default reporter | +| Name | Description | Default | +| -------------------------- | -------------------------------------------------------------------------------------------------- | --------------------- | +| `-c`, `--config` [value] | Path to test definition file relative to CWD. Takes multiple values | `./.betterer.ts` | +| `-r`, `--results` [value] | Path to test results file relative to CWD | `./.betterer.results` | +| `-t`, `--tsconfig` [value] | Path to TypeScript config file relative to CWD | `null` | +| `-f`, `--filter` [value] | Select tests to run by RegExp. Takes multiple values | `[]` | +| `-s`, `--silent` | When present, all default reporters will be disabled. Custom reporters will still work normally. | `false` | +| `-u`, `--update` | When present, the results file will be updated, even if things get worse | `false` | +| `--allow-update [false]` | When set to false, the update message will not be shown and the `--update` option will be ignored. | `true` | +| `-R`, `--reporter` [value] | npm package name or file path to a Betterer reporter. Takes multiple values | Default reporter | ### CI diff --git a/packages/cli/src/init.tsx b/packages/cli/src/init.tsx index 3bf35eb57..eb11b4829 100644 --- a/packages/cli/src/init.tsx +++ b/packages/cli/src/init.tsx @@ -1,14 +1,23 @@ -import { render } from 'ink'; import React from 'react'; +import { render } from 'ink'; +import path from 'path'; + import { Init } from './init/init'; import { initOptions } from './options'; import { BettererCLIArguments } from './types'; +const BETTERER_TS = './.betterer.ts'; +const TS_EXTENSION = '.ts'; + /** @internal Definitely not stable! Please don't use! */ export async function initΔ(cwd: string, argv: BettererCLIArguments): Promise { const { config } = initOptions(argv); - const app = render(); + const finalConfig = config || BETTERER_TS; + const ext = path.extname(finalConfig); + const ts = ext === TS_EXTENSION; + + const app = render(); await app.waitUntilExit(); } diff --git a/packages/cli/src/init/create-test-file.ts b/packages/cli/src/init/create-test-file.ts index a6fea6a67..a33028dc5 100644 --- a/packages/cli/src/init/create-test-file.ts +++ b/packages/cli/src/init/create-test-file.ts @@ -2,11 +2,16 @@ import { BettererError } from '@betterer/errors'; import { BettererLogger } from '@betterer/logger'; import { promises as fs } from 'fs'; -const TEMPLATE = `export default { +const TEMPLATE_JS = `module.exports = { // Add tests here ☀️ -};`; +}; +`; +const TEMPLATE_TS = `export default { + // Add tests here ☀️ +}; +`; -export async function run(logger: BettererLogger, configPath: string): Promise { +export async function run(logger: BettererLogger, configPath: string, ts: boolean): Promise { await logger.progress(`creating "${configPath}" file...`); let exists = false; @@ -22,7 +27,8 @@ export async function run(logger: BettererLogger, configPath: string): Promise = function Init({ cwd, config }) { +export const Init: FC = function Init({ cwd, config, ts }) { return ( = function Init({ cwd, config }) { { name: 'Create test file', run: async (logger) => { - await createTestFile.run(logger, path.resolve(cwd, config)); + await createTestFile.run(logger, path.resolve(cwd, config), ts); createTestFile.destroy(); } }, { name: 'Update package.json', run: async (logger) => { - await updatePackageJSON.run(logger, cwd); + await updatePackageJSON.run(logger, cwd, ts); updatePackageJSON.destroy(); } } diff --git a/packages/cli/src/init/update-package-json.ts b/packages/cli/src/init/update-package-json.ts index 78814d258..9a3ca1ad4 100644 --- a/packages/cli/src/init/update-package-json.ts +++ b/packages/cli/src/init/update-package-json.ts @@ -5,7 +5,7 @@ import { promises as fs } from 'fs'; import { BettererPackageJSON } from '../types'; -export async function run(logger: BettererLogger, cwd: string): Promise { +export async function run(logger: BettererLogger, cwd: string, ts: boolean): Promise { await logger.progress('adding "betterer" to package.json file...'); let packageJSON; @@ -41,6 +41,15 @@ export async function run(logger: BettererLogger, cwd: string): Promise { await logger.info('added "@betterer/cli" dependency to package.json file'); } + if (ts) { + if (packageJSON.devDependencies['typescript']) { + await logger.warn('"typescript" dependency already exists, moving on...'); + } else { + packageJSON.devDependencies['typescript'] = `^4`; + await logger.info('added "typescript" dependency to package.json file'); + } + } + try { await fs.writeFile(packageJSONPath, `${JSON.stringify(packageJSON, null, 2)}\n`, 'utf-8'); } catch { diff --git a/packages/cli/src/options.ts b/packages/cli/src/options.ts index 7708cfbc4..7999e0ad4 100644 --- a/packages/cli/src/options.ts +++ b/packages/cli/src/options.ts @@ -63,7 +63,7 @@ function setEnv(argv: BettererCLIArguments): T { } function configPathOption(): void { - commander.option('-c, --config [value]', 'Path to test definition file relative to CWD', './.betterer.ts'); + commander.option('-c, --config [value]', 'Path to test definition file relative to CWD'); } function configPathsOption(): void { @@ -98,20 +98,27 @@ function reportersOption(): void { ); } -function handleBool(val: string) { - return val !== 'false'; +function silentOption(): void { + commander.option( + '-s, --silent', + 'When present, all default reporters will be disabled. Custom reporters will still work normally.' + ); } -function silentOption(): void { - commander.option('-s, --silent [true|false]', 'Disable all default reporters. Custom reporters still work normally.'); +function defaultToTrue(val: string) { + return val !== 'false'; } function allowUpdateOption(): void { - commander.option('--allow-update [true|false]', 'Whether to allow the `--update` option or not.', handleBool); + commander.option( + '--allow-update [true|false]', + 'When set to false, the update message will not be shown and the `--update` option will be ignored.', + defaultToTrue + ); } function updateOption(): void { - commander.option('-u, --update [true|false]', 'Force update the results file, even if things get worse', handleBool); + commander.option('-u, --update', 'When present, the results file will be updated, even if things get worse'); } function argsToArray(value: string, previous: BettererCLIArguments = []): BettererCLIArguments { diff --git a/test/cli/__snapshots__/betterer-init.spec.ts.snap b/test/cli/__snapshots__/betterer-init.spec.ts.snap index ee34f6e3d..b20b6eb1a 100644 --- a/test/cli/__snapshots__/betterer-init.spec.ts.snap +++ b/test/cli/__snapshots__/betterer-init.spec.ts.snap @@ -8,6 +8,19 @@ Array [ ✅ Update package.json: done! ・ added \\"betterer\\" script to package.json file. ・ added \\"@betterer/cli\\" dependency to package.json file +・ added \\"typescript\\" dependency to package.json file +", +] +`; + +exports[`betterer cli should initialise betterer in a repo with JS 1`] = ` +Array [ + "🎉 Initialising Betterer (0ms): 2 tasks done! +✅ Create test file: done! +・ created \\"/fixtures/test-betterer-init-js/.betterer.js\\"! +✅ Update package.json: done! +・ added \\"betterer\\" script to package.json file. +・ added \\"@betterer/cli\\" dependency to package.json file ", ] `; @@ -20,6 +33,7 @@ Array [ ✅ Update package.json: done! ・ added \\"betterer\\" script to package.json file. ・ added \\"@betterer/cli\\" dependency to package.json file +・ added \\"typescript\\" dependency to package.json file ", "🎉 Initialising Betterer (0ms): 2 tasks done! ✅ Create test file: done! @@ -27,6 +41,7 @@ Array [ ✅ Update package.json: done! ・ \\"betterer\\" script already exists, moving on... ・ \\"@betterer/cli\\" dependency already exists, moving on... +・ \\"typescript\\" dependency already exists, moving on... ", ] `; diff --git a/test/cli/betterer-init.spec.ts b/test/cli/betterer-init.spec.ts index 76bc0fc92..b67fe2b42 100644 --- a/test/cli/betterer-init.spec.ts +++ b/test/cli/betterer-init.spec.ts @@ -2,11 +2,11 @@ import { BettererPackageJSON, initΔ } from '@betterer/cli'; import { createFixture } from '../fixture'; -const ARGV = ['node', './bin/betterer']; +const ARGV = ['node', './bin/betterer', 'init']; describe('betterer cli', () => { it('should initialise betterer in a repo', async () => { - const { logs, paths, readFile, cleanup, resolve } = await createFixture( + const { cleanup, logs, paths, readFile, resolve } = await createFixture( 'test-betterer-init', { 'package.json': ` @@ -31,10 +31,11 @@ describe('betterer cli', () => { expect(packageJSON.scripts.betterer).toEqual('betterer'); expect(packageJSON.devDependencies['@betterer/cli']).toBeDefined(); + expect(packageJSON.devDependencies['typescript']).toBeDefined(); const config = await readFile(configPath); - expect(config).toEqual('export default {\n // Add tests here ☀️\n};'); + expect(config).toEqual('export default {\n // Add tests here ☀️\n};\n'); expect(logs).toMatchSnapshot(); @@ -42,7 +43,7 @@ describe('betterer cli', () => { }); it('should work multiple times', async () => { - const { logs, paths, cleanup } = await createFixture( + const { cleanup, logs, paths } = await createFixture( 'test-betterer-init-multiple', { 'package.json': ` @@ -72,4 +73,41 @@ describe('betterer cli', () => { expect(logs).toMatchSnapshot(); }); + + it('should initialise betterer in a repo with JS', async () => { + const { cleanup, logs, paths, readFile, resolve } = await createFixture( + 'test-betterer-init-js', + { + 'package.json': ` + { + "name": "betterer-test-betterer-init-js", + "version": "0.0.1" + } + ` + }, + { + logFilters: [/🌟 Initialising Betterer/] + } + ); + + const configPath = `${paths.config}.js`; + const fixturePath = paths.cwd; + const packageJSONPath = resolve('./package.json'); + + await initΔ(fixturePath, [...ARGV, '--config', configPath]); + + const packageJSON = JSON.parse(await readFile(packageJSONPath)) as BettererPackageJSON; + + expect(packageJSON.scripts.betterer).toEqual('betterer'); + expect(packageJSON.devDependencies['@betterer/cli']).toBeDefined(); + expect(packageJSON.devDependencies['typescript']).not.toBeDefined(); + + const config = await readFile(configPath); + + expect(config).toEqual('module.exports = {\n // Add tests here ☀️\n};\n'); + + expect(logs).toMatchSnapshot(); + + await cleanup(); + }); });