From 66c90b403e8c53ca341491537eebb0b0720d1770 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 4 Dec 2023 11:48:46 -0700 Subject: [PATCH] Replace outdent with our own implementation (#117) Currently we use the `outdent` package so that tests that involve writing multi-line strings to files look a bit nicer. This package doesn't play nice in an ESM context, and we actually already have equivalents in `normalizeWhitespaceString` and `buildChangelog` that we can use instead. So this commit removes `outdent` in favor of these helpers. --- package.json | 1 - src/functional.test.ts | 30 ++++++------ src/package.test.ts | 63 +++++++++++--------------- tests/functional/helpers/local-repo.ts | 2 +- tests/functional/helpers/utils.ts | 43 ------------------ tests/helpers.ts | 46 ++++++++++++++++++- yarn.lock | 8 ---- 7 files changed, 87 insertions(+), 106 deletions(-) diff --git a/package.json b/package.json index 570a672..2f42081 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "jest-it-up": "^2.0.2", "jest-when": "^3.5.2", "nanoid": "^3.3.4", - "outdent": "^0.8.0", "prettier": "^2.2.1", "prettier-plugin-packagejson": "^2.3.0", "rimraf": "^4.0.5", diff --git a/src/functional.test.ts b/src/functional.test.ts index 8d26354..b6bcabb 100644 --- a/src/functional.test.ts +++ b/src/functional.test.ts @@ -1,5 +1,5 @@ import { withMonorepoProjectEnvironment } from '../tests/functional/helpers/with'; -import { buildChangelog } from '../tests/functional/helpers/utils'; +import { buildChangelog } from '../tests/helpers'; jest.setTimeout(10_000); @@ -474,23 +474,23 @@ describe('create-release-branch (functional)', () => { 'a', 'CHANGELOG.md', buildChangelog(` - ## [Unreleased] + ## [Unreleased] - [Unreleased]: https://github.com/example-org/example-repo + [Unreleased]: https://github.com/example-org/example-repo `), ); await environment.writeFileWithinPackage( 'b', 'CHANGELOG.md', buildChangelog(` - ## [Unreleased] + ## [Unreleased] - ## [1.0.0] - ### Added - - Initial release + ## [1.0.0] + ### Added + - Initial release - [Unreleased]: https://github.com/example-org/example-repo/compare/@scope/b@1.0.0...HEAD - [1.0.0]: https://github.com/example-org/example-repo/releases/tag/@scope/b@1.0.0 + [Unreleased]: https://github.com/example-org/example-repo/compare/@scope/b@1.0.0...HEAD + [1.0.0]: https://github.com/example-org/example-repo/releases/tag/@scope/b@1.0.0 `), ); await environment.createCommit('Initial commit'); @@ -533,14 +533,14 @@ describe('create-release-branch (functional)', () => { await environment.readFileWithinPackage('b', 'CHANGELOG.md'), ).toStrictEqual( buildChangelog(` - ## [Unreleased] + ## [Unreleased] - ## [1.0.0] - ### Added - - Initial release + ## [1.0.0] + ### Added + - Initial release - [Unreleased]: https://github.com/example-org/example-repo/compare/@scope/b@1.0.0...HEAD - [1.0.0]: https://github.com/example-org/example-repo/releases/tag/@scope/b@1.0.0 + [Unreleased]: https://github.com/example-org/example-repo/compare/@scope/b@1.0.0...HEAD + [1.0.0]: https://github.com/example-org/example-repo/releases/tag/@scope/b@1.0.0 `), ); }, diff --git a/src/package.test.ts b/src/package.test.ts index ad10dec..bc0f7e1 100644 --- a/src/package.test.ts +++ b/src/package.test.ts @@ -4,8 +4,7 @@ import { when } from 'jest-when'; import * as autoChangelog from '@metamask/auto-changelog'; import { SemVer } from 'semver'; import { MockWritable } from 'stdio-mock'; -import _outdent from 'outdent'; -import { withSandbox } from '../tests/helpers'; +import { buildChangelog, withSandbox } from '../tests/helpers'; import { buildMockPackage, buildMockProject, @@ -22,8 +21,6 @@ import * as fsModule from './fs'; import * as packageManifestModule from './package-manifest'; import * as repoModule from './repo'; -const outdent = _outdent({ trimTrailingNewline: false }); - jest.mock('./package-manifest'); jest.mock('./repo'); @@ -471,20 +468,18 @@ describe('package', () => { await fs.promises.writeFile( changelogPath, - outdent` - # Changelog - All notable changes to this project will be documented in this file. - The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## [Unreleased] - ### Uncategorized - - Add \`isNewFunction\` ([#2](https://repo.url/compare/package/pull/2)) - ## [1.0.0] - 2020-01-01 - ### Changed - - Something else - [Unreleased]: https://repo.url/compare/package@2.0.0...HEAD - [1.0.0]: https://repo.url/releases/tag/package@1.0.0 - `, + buildChangelog(` + ## [Unreleased] + ### Uncategorized + - Add isNewFunction ([#2](https://repo.url/compare/package/pull/2)) + + ## [1.0.0] - 2020-01-01 + ### Changed + - Something else + + [Unreleased]: https://repo.url/compare/package@2.0.0...HEAD + [1.0.0]: https://repo.url/releases/tag/package@1.0.0 + `), ); await updatePackage({ project, packageReleasePlan }); @@ -494,27 +489,23 @@ describe('package', () => { 'utf8', ); - expect(newChangelogContent).toBe(outdent` - # Changelog - All notable changes to this project will be documented in this file. - - The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + expect(newChangelogContent).toBe( + buildChangelog(` + ## [Unreleased] - ## [Unreleased] + ## [2.0.0] + ### Uncategorized + - Add isNewFunction ([#2](https://repo.url/compare/package/pull/2)) - ## [2.0.0] - ### Uncategorized - - Add \`isNewFunction\` ([#2](https://repo.url/compare/package/pull/2)) + ## [1.0.0] - 2020-01-01 + ### Changed + - Something else - ## [1.0.0] - 2020-01-01 - ### Changed - - Something else - - [Unreleased]: https://repo.url/compare/package@2.0.0...HEAD - [2.0.0]: https://repo.url/compare/package@1.0.0...package@2.0.0 - [1.0.0]: https://repo.url/releases/tag/package@1.0.0 - `); + [Unreleased]: https://repo.url/compare/package@2.0.0...HEAD + [2.0.0]: https://repo.url/compare/package@1.0.0...package@2.0.0 + [1.0.0]: https://repo.url/releases/tag/package@1.0.0 + `), + ); }); }); diff --git a/tests/functional/helpers/local-repo.ts b/tests/functional/helpers/local-repo.ts index 39227e2..cbbd2a5 100644 --- a/tests/functional/helpers/local-repo.ts +++ b/tests/functional/helpers/local-repo.ts @@ -1,6 +1,6 @@ import path from 'path'; +import { buildChangelog } from '../../helpers'; import Repo, { RepoOptions } from './repo'; -import { buildChangelog } from './utils'; /** * A set of configuration options for a {@link LocalRepo}. In addition to the diff --git a/tests/functional/helpers/utils.ts b/tests/functional/helpers/utils.ts index e9481f6..065fc42 100644 --- a/tests/functional/helpers/utils.ts +++ b/tests/functional/helpers/utils.ts @@ -2,28 +2,6 @@ import createDebug from 'debug'; export const debug = createDebug('create-release-branch:tests'); -/** - * Given a string, resets its indentation and removes leading and trailing - * whitespace (except for a trailing newline). - * - * @param string - The string. - * @returns The normalized string. - */ -function normalizeMultilineString(string: string): string { - const lines = string - .replace(/^[\n\r]+/u, '') - .replace(/[\n\r]+$/u, '') - .split('\n'); - const indentation = lines[0].match(/^([ ]+)/u)?.[1] ?? ''; - const normalizedString = lines - .map((line) => { - return line.replace(new RegExp(`^${indentation}`, 'u'), ''); - }) - .join('\n') - .trim(); - return `${normalizedString}\n`; -} - /** * `Object.keys()` is intentionally generic: it returns the keys of an object, * but it cannot make guarantees about the contents of that object, so the type @@ -61,24 +39,3 @@ export function isErrorWithCode(error: unknown): error is { code: string } { export async function sleepFor(duration: number): Promise { await new Promise((resolve) => setTimeout(resolve, duration)); } - -/** - * Builds a changelog by filling in the first part automatically, which never - * changes. - * - * @param variantContent - The part of the changelog that can change depending - * on what is expected or what sort of changes have been made to the repo so - * far. - * @returns The full changelog. - */ -export function buildChangelog(variantContent: string): string { - const invariantContent = normalizeMultilineString(` - # Changelog - All notable changes to this project will be documented in this file. - - The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `); - - return `${invariantContent}\n${normalizeMultilineString(variantContent)}`; -} diff --git a/tests/helpers.ts b/tests/helpers.ts index 57b888c..006725e 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -2,7 +2,6 @@ import fs from 'fs'; import os from 'os'; import path from 'path'; import { nanoid } from 'nanoid'; -import { rimraf } from 'rimraf'; import type { ExecaError } from 'execa'; import { hasProperty, isObject } from '@metamask/utils'; @@ -60,7 +59,7 @@ export async function withSandbox(fn: (sandbox: Sandbox) => any) { try { await fn({ directoryPath }); } finally { - await rimraf(directoryPath); + await fs.promises.rm(directoryPath, { force: true, recursive: true }); } } @@ -92,3 +91,46 @@ export function isExecaError(error: unknown): error is ExecaError { hasProperty(error, 'exitCode') ); } + +/** + * Given a string, resets its indentation and removes leading and trailing + * whitespace (except for a trailing newline). + * + * @param string - The string. + * @returns The normalized string. + */ +export function normalizeMultilineString(string: string): string { + const lines = string + .replace(/^[\n\r]+/u, '') + .replace(/[\n\r]+$/u, '') + .split('\n'); + const indentation = lines[0].match(/^([ ]+)/u)?.[1] ?? ''; + const normalizedString = lines + .map((line) => { + return line.replace(new RegExp(`^${indentation}`, 'u'), ''); + }) + .join('\n') + .trim(); + return `${normalizedString}\n`; +} + +/** + * Builds a changelog by filling in the first part automatically, which never + * changes. + * + * @param variantContent - The part of the changelog that can change depending + * on what is expected or what sort of changes have been made to the repo so + * far. + * @returns The full changelog. + */ +export function buildChangelog(variantContent: string): string { + const invariantContent = normalizeMultilineString(` + # Changelog + All notable changes to this project will be documented in this file. + + The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), + and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + `); + + return `${invariantContent}\n${normalizeMultilineString(variantContent)}`; +} diff --git a/yarn.lock b/yarn.lock index 15d6330..c6f9631 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1016,7 +1016,6 @@ __metadata: jest-it-up: ^2.0.2 jest-when: ^3.5.2 nanoid: ^3.3.4 - outdent: ^0.8.0 pony-cause: ^2.1.9 prettier: ^2.2.1 prettier-plugin-packagejson: ^2.3.0 @@ -4837,13 +4836,6 @@ __metadata: languageName: node linkType: hard -"outdent@npm:^0.8.0": - version: 0.8.0 - resolution: "outdent@npm:0.8.0" - checksum: 72b7c1a287674317ea477999ec24e73a9eda21de35eb9429218f4a5bab899e964afaee7508265898118fee5cbee1d79397916b66dd8aeee285cd948ea5b1f562 - languageName: node - linkType: hard - "p-limit@npm:^1.1.0": version: 1.3.0 resolution: "p-limit@npm:1.3.0"