From 1216fc9750cdc04c066e159618dd4ad9705a6172 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Fri, 17 Dec 2021 09:56:27 +0000 Subject: [PATCH] export functions from dialogs.tsx, pass tests (#125) * export functions from dialogs.tsx, pass tests As mentioned in https://github.com/cloudflare/wrangler2/pull/124#discussion_r770953444, it's possible to use regular exports from a module, but still be able to mock their implementations in jest. This PR does so, and passes tests. --- .changeset/purple-rice-fail.md | 5 ++ packages/wrangler/src/__tests__/index.test.ts | 50 +++++++++++-------- packages/wrangler/src/dialogs.tsx | 18 +------ packages/wrangler/src/index.tsx | 18 +++---- 4 files changed, 43 insertions(+), 48 deletions(-) create mode 100644 .changeset/purple-rice-fail.md diff --git a/.changeset/purple-rice-fail.md b/.changeset/purple-rice-fail.md new file mode 100644 index 000000000000..8c0dd86e59db --- /dev/null +++ b/.changeset/purple-rice-fail.md @@ -0,0 +1,5 @@ +--- +"wrangler": patch +--- + +Export regular functions from dialog.ts, pass tests (followup from https://github.com/cloudflare/wrangler2/pull/124) diff --git a/packages/wrangler/src/__tests__/index.test.ts b/packages/wrangler/src/__tests__/index.test.ts index c01496824ed3..21bc4fa98e42 100644 --- a/packages/wrangler/src/__tests__/index.test.ts +++ b/packages/wrangler/src/__tests__/index.test.ts @@ -5,10 +5,39 @@ import * as TOML from "@iarna/toml"; import { main } from "../index"; import { setMock, unsetAllMocks } from "./mock-cfetch"; import { existsSync } from "node:fs"; -import { dialogs } from "../dialogs"; +import { confirm } from "../dialogs"; jest.mock("../cfetch", () => jest.requireActual("./mock-cfetch")); +jest.mock("../dialogs", () => { + return { + // @ts-expect-error typescript doesn't know that jest.requireActual + // returns the 'object' form of the dialogs module + ...jest.requireActual("../dialogs"), + confirm: jest.fn().mockName("confirmMock"), + }; +}); + +/** + * Mock the implementation of `confirm()` that will respond with configured results + * for configured confirmation text messages. + * + * If there is a call to `confirm()` that does not match any of the expectations + * then an error is thrown. + */ +function mockConfirm(...expectations: { text: string; result: boolean }[]) { + // @ts-expect-error - we're mocking the implementation of confirm() + // but typescript doesn't know we've previously replaced confirm with a mock + confirm.mockImplementationOnce((text: string) => { + for (const { text: expectedText, result } of expectations) { + if (text === expectedText) { + return result; + } + } + throw new Error(`Unexpected confirmation message: ${text}`); + }); +} + async function w(cmd?: string) { const logSpy = jest.spyOn(console, "log").mockImplementation(); const errorSpy = jest.spyOn(console, "error").mockImplementation(); @@ -222,22 +251,3 @@ describe("wrangler", () => { }); }); }); - -/** - * Create a mock version of `confirm()` that will respond with configured results - * for configured confirmation text messages. - * - * If there is a call to `confirm()` that does not match any of the expectations - * then an error is thrown. - */ -function mockConfirm(...expectations: { text: string; result: boolean }[]) { - const mockImplementation = async (text: string) => { - for (const { text: expectedText, result } of expectations) { - if (text === expectedText) { - return result; - } - } - throw new Error(`Unexpected confirmation message: ${text}`); - }; - return jest.spyOn(dialogs, "confirm").mockImplementation(mockImplementation); -} diff --git a/packages/wrangler/src/dialogs.tsx b/packages/wrangler/src/dialogs.tsx index f3140ade9325..69a3ce074377 100644 --- a/packages/wrangler/src/dialogs.tsx +++ b/packages/wrangler/src/dialogs.tsx @@ -23,7 +23,7 @@ function Confirm(props: ConfirmProps) { ); } -function confirm(text: string): Promise { +export function confirm(text: string): Promise { return new Promise((resolve) => { const { unmount } = render( { const { unmount } = render( { - -// } - -// Export as an object so that it is easier to mock for testing -export const dialogs = { - confirm, - prompt, -}; diff --git a/packages/wrangler/src/index.tsx b/packages/wrangler/src/index.tsx index 3adaf8a7e5ce..5e118375e274 100644 --- a/packages/wrangler/src/index.tsx +++ b/packages/wrangler/src/index.tsx @@ -8,7 +8,7 @@ import type yargs from "yargs"; import { findUp } from "find-up"; import TOML from "@iarna/toml"; import type { Config } from "./config"; -import { dialogs } from "./dialogs"; +import { confirm, prompt } from "./dialogs"; import { version as wranglerVersion } from "../package.json"; import { login, @@ -202,7 +202,7 @@ export async function main(argv: string[]): Promise { const destination = path.join(process.cwd(), "wrangler.toml"); if (fs.existsSync(destination)) { console.error(`${destination} file already exists!`); - const result = await dialogs.confirm( + const result = await confirm( "Do you want to continue initializing this project?" ); if (!result) { @@ -229,9 +229,7 @@ export async function main(argv: string[]): Promise { if (!pathToPackageJson) { if ( - await dialogs.confirm( - "No package.json found. Would you like to create one?" - ) + await confirm("No package.json found. Would you like to create one?") ) { await writeFile( path.join(process.cwd(), "package.json"), @@ -256,7 +254,7 @@ export async function main(argv: string[]): Promise { // and make a tsconfig? let pathToTSConfig = await findUp("tsconfig.json"); if (!pathToTSConfig) { - if (await dialogs.confirm("Would you like to use typescript?")) { + if (await confirm("Would you like to use typescript?")) { await writeFile( path.join(process.cwd(), "tsconfig.json"), JSON.stringify( @@ -915,7 +913,7 @@ export async function main(argv: string[]): Promise { // -- snip, end -- - const secretValue = await dialogs.prompt( + const secretValue = await prompt( "Enter a secret value:", "password" ); @@ -1015,11 +1013,7 @@ export async function main(argv: string[]): Promise { // -- snip, end -- - if ( - await dialogs.confirm( - "Are you sure you want to delete this secret?" - ) - ) { + if (await confirm("Are you sure you want to delete this secret?")) { console.log( `Deleting the secret ${args.key} on script ${scriptName}.` );