From 410757e32019c96141c9dd3afd04ff7effa45ab4 Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 01:43:24 +0200 Subject: [PATCH 1/7] Add constants --- packages/cli/constants/constants.ts | 7 +++++++ packages/cli/e2e/create.test.ts | 12 +++++++----- packages/cli/src/create/command.ts | 13 +++++++------ 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 packages/cli/constants/constants.ts diff --git a/packages/cli/constants/constants.ts b/packages/cli/constants/constants.ts new file mode 100644 index 00000000000..d014eccb2ef --- /dev/null +++ b/packages/cli/constants/constants.ts @@ -0,0 +1,7 @@ +export const CREATE_MESSAGES = { + typeOfProject: "What type of project do you want to create?", + projectName: "What is your project named?", + framework: "What framework do you want to use?", + language: "What language do you want to use?", + contract: "What contract do you want to start from?", +}; diff --git a/packages/cli/e2e/create.test.ts b/packages/cli/e2e/create.test.ts index 527ec0e6430..5aefa1b3563 100644 --- a/packages/cli/e2e/create.test.ts +++ b/packages/cli/e2e/create.test.ts @@ -1,10 +1,11 @@ import { prepareEnvironment } from "@gmrchk/cli-testing-library"; +import { CREATE_MESSAGES } from "../constants/constants"; // this creates an app, can take some time that's fine jest.setTimeout(120_000); describe("npx thirdweb create", () => { - it("should create app successfully", async () => { + it("should create app (CRA) successfully", async () => { const { spawn, cleanup, exists } = await prepareEnvironment(); const { // wait, @@ -17,14 +18,15 @@ describe("npx thirdweb create", () => { pressKey, } = await spawn("node", "./dist/cli/index.js create"); - await waitForText("What type of project do you want to create?"); + await waitForText(CREATE_MESSAGES.typeOfProject); await pressKey("enter"); - await waitForText("What is your project named?"); + await waitForText(CREATE_MESSAGES.projectName); await pressKey("enter"); - await waitForText("What framework do you want to use?"); + await waitForText(CREATE_MESSAGES.framework); + // Select CRA await pressKey("arrowDown"); await pressKey("enter"); - await waitForText("What language do you want to use?"); + await waitForText(CREATE_MESSAGES.language); await pressKey("enter"); // wait for program to finish diff --git a/packages/cli/src/create/command.ts b/packages/cli/src/create/command.ts index 975d6882a90..94bc881b187 100644 --- a/packages/cli/src/create/command.ts +++ b/packages/cli/src/create/command.ts @@ -8,6 +8,7 @@ import { validateNpmName } from "./helpers/validate-pkg"; import chalk from "chalk"; import path from "path"; import prompts from "prompts"; +import { CREATE_MESSAGES } from "../../constants/constants"; let projectType: string = ""; let projectPath: string = ""; @@ -65,7 +66,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "select", name: "projectType", - message: "What type of project do you want to create?", + message: CREATE_MESSAGES.typeOfProject, choices: [ { title: "App", value: "app" }, { title: "Contract", value: "contract" }, @@ -87,7 +88,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "text", name: "path", - message: "What is your project named?", + message: CREATE_MESSAGES.projectName, initial: options.template || defaultName, validate: (name) => { const validation = validateNpmName(path.basename(path.resolve(name))); @@ -123,7 +124,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "select", name: "framework", - message: "What framework do you want to use?", + message: CREATE_MESSAGES.framework, choices: [ { title: "Next.js", value: "next" }, { title: "Create React App", value: "cra" }, @@ -140,7 +141,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "select", name: "language", - message: "What language do you want to use?", + message: CREATE_MESSAGES.language, choices: [ { title: "JavaScript", value: "javascript" }, { title: "TypeScript", value: "typescript" }, @@ -160,7 +161,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "select", name: "framework", - message: "What framework do you want to use?", + message: CREATE_MESSAGES.framework, choices: [ { title: "Hardhat", value: "hardhat" }, { title: "Forge", value: "forge" }, @@ -177,7 +178,7 @@ export async function twCreate(options: any) { const res = await prompts({ type: "select", name: "baseContract", - message: "What contract do you want to start from?", + message: CREATE_MESSAGES.contract, choices: [ { title: "Empty Contract", value: "" }, { title: "ERC721 Base", value: "ERC721Base" }, From d736d65b0e0d47f79baa3d6ea08eee307cfc8fab Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 02:36:26 +0200 Subject: [PATCH 2/7] Add tests for release and deploy --- packages/cli/constants/constants.ts | 2 +- packages/cli/e2e/create.test.ts | 4 --- packages/cli/e2e/deploy.test.ts | 37 ++++++++++++++++++++++++ packages/cli/e2e/files/BasicContract.sol | 6 ++++ packages/cli/e2e/release.test.ts | 37 ++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/cli/e2e/deploy.test.ts create mode 100644 packages/cli/e2e/files/BasicContract.sol create mode 100644 packages/cli/e2e/release.test.ts diff --git a/packages/cli/constants/constants.ts b/packages/cli/constants/constants.ts index d014eccb2ef..5582b288623 100644 --- a/packages/cli/constants/constants.ts +++ b/packages/cli/constants/constants.ts @@ -4,4 +4,4 @@ export const CREATE_MESSAGES = { framework: "What framework do you want to use?", language: "What language do you want to use?", contract: "What contract do you want to start from?", -}; +} as const; diff --git a/packages/cli/e2e/create.test.ts b/packages/cli/e2e/create.test.ts index 5aefa1b3563..3ec8688b572 100644 --- a/packages/cli/e2e/create.test.ts +++ b/packages/cli/e2e/create.test.ts @@ -8,13 +8,9 @@ describe("npx thirdweb create", () => { it("should create app (CRA) successfully", async () => { const { spawn, cleanup, exists } = await prepareEnvironment(); const { - // wait, waitForText, waitForFinish, - // getStdout, - // getStderr, getExitCode, - // debug, pressKey, } = await spawn("node", "./dist/cli/index.js create"); diff --git a/packages/cli/e2e/deploy.test.ts b/packages/cli/e2e/deploy.test.ts new file mode 100644 index 00000000000..c2b0a8adbf0 --- /dev/null +++ b/packages/cli/e2e/deploy.test.ts @@ -0,0 +1,37 @@ +import { prepareEnvironment } from "@gmrchk/cli-testing-library"; +import { copyFile } from "fs/promises"; +import { resolve } from "path"; + +// this creates an app, can take some time that's fine +jest.setTimeout(120_000); + +describe("npx thirdweb deploy", () => { + it("should return deploy page url", async () => { + const { spawn, cleanup, exists, path } = await prepareEnvironment(); + + await copyFile(resolve("./e2e/files/BasicContract.sol"), `${path}/BasicContract.sol`); + + const { + waitForText, + waitForFinish, + getExitCode, + writeText, + getStdout, + } = await spawn("node", "./dist/cli/index.js deploy"); + + expect(await exists("BasicContract.sol")).toEqual(true); + + await waitForText("Failed to find a supported project configuration"); + await writeText("y") + + // wait for program to finish + await waitForFinish(); + + expect(getStdout().at(-1)).toEqual("https://thirdweb.com/contracts/deploy/QmTzUx1eZ1RAeEwsL85umbJFYMTwwu1UsAM3f3tWHSrHKF"); + + // the process should exit with code 0 + expect(getExitCode()).toEqual(0); + + await cleanup(); // cleanup after test + }); +}); diff --git a/packages/cli/e2e/files/BasicContract.sol b/packages/cli/e2e/files/BasicContract.sol new file mode 100644 index 00000000000..156bd16eb3a --- /dev/null +++ b/packages/cli/e2e/files/BasicContract.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract BasicContract { + constructor() {} +} \ No newline at end of file diff --git a/packages/cli/e2e/release.test.ts b/packages/cli/e2e/release.test.ts new file mode 100644 index 00000000000..06df333aee3 --- /dev/null +++ b/packages/cli/e2e/release.test.ts @@ -0,0 +1,37 @@ +import { prepareEnvironment } from "@gmrchk/cli-testing-library"; +import { copyFile } from "fs/promises"; +import { resolve } from "path"; + +// this creates an app, can take some time that's fine +jest.setTimeout(120_000); + +describe("npx thirdweb release", () => { + it("should return release page url", async () => { + const { spawn, cleanup, exists, path } = await prepareEnvironment(); + + await copyFile(resolve("./e2e/files/BasicContract.sol"), `${path}/BasicContract.sol`); + + const { + waitForText, + waitForFinish, + getExitCode, + writeText, + getStdout, + } = await spawn("node", "./dist/cli/index.js release"); + + expect(await exists("BasicContract.sol")).toEqual(true); + + await waitForText("Failed to find a supported project configuration"); + await writeText("y") + + // wait for program to finish + await waitForFinish(); + + expect(getStdout().at(-1)).toEqual("https://thirdweb.com/contracts/release/QmXENbPLE5wkAhyUr7y2YShsUHLTtgaG1CvQffUaek6pNN"); + + // the process should exit with code 0 + expect(getExitCode()).toEqual(0); + + await cleanup(); // cleanup after test + }); +}); From d90cba17f27024bcc8c1be022bc67c089529bf49 Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 03:42:03 +0200 Subject: [PATCH 3/7] Add test for detect --- packages/cli/e2e/detect.test.ts | 78 +++++++++++++++++++++ packages/cli/src/common/feature-detector.ts | 2 +- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 packages/cli/e2e/detect.test.ts diff --git a/packages/cli/e2e/detect.test.ts b/packages/cli/e2e/detect.test.ts new file mode 100644 index 00000000000..c9b4ff75498 --- /dev/null +++ b/packages/cli/e2e/detect.test.ts @@ -0,0 +1,78 @@ +import { CREATE_MESSAGES } from "../constants/constants"; +import { prepareEnvironment } from "@gmrchk/cli-testing-library"; + +// this creates an app, can take some time that's fine +jest.setTimeout(120_000); + +describe("npx thirdweb detect", () => { + it("should detect ERC721Base extensions", async () => { + const { spawn, cleanup, exists, path } = await prepareEnvironment(); + const create = await spawn("node", "./dist/cli/index.js create"); + + await create.waitForText(CREATE_MESSAGES.typeOfProject); + await create.pressKey("arrowDown"); + await create.pressKey("enter"); + await create.waitForText(CREATE_MESSAGES.projectName); + await create.pressKey("enter"); + await create.waitForText(CREATE_MESSAGES.framework); + await create.pressKey("enter"); + await create.waitForText(CREATE_MESSAGES.contract); + await create.pressKey("arrowDown"); + await create.pressKey("enter"); + + // wait for program to finish + await create.waitForFinish(); + + // the process should exit with code 0 + expect(create.getExitCode()).toEqual(0); + + //check if the contract was created + expect(await exists("thirdweb-contracts/contracts/Contract.sol")).toEqual( + true, + ); + + //check that hardhat config exists + expect(await exists("thirdweb-contracts/hardhat.config.js")).toEqual( + true, + ); + + await create.writeText("cd thirdweb-contracts"); + await create.pressKey("enter"); + await create.writeText("npm install"); + await create.pressKey("enter"); + + const detect = await spawn("node", "./dist/cli/index.js detect", "./thirdweb-contracts"); + + // wait for program to finish + await detect.waitForFinish(); + + const lines = detect.getStdout(); + + // Detected extensions + expect(lines.findIndex((line) => line.includes("ERC721"))).toBeGreaterThan( + -1, + ); + expect(lines.findIndex((line) => line.includes("ERC721Burnable"))).toBeGreaterThan( + -1, + ); + expect(lines.findIndex((line) => line.includes("ERC721Mintable"))).toBeGreaterThan( + -1, + ); + + // Suggested extensions + expect(lines.findIndex((line) => line.includes("- ERC721Enumerable"))).toBeGreaterThan( + -1, + ); + expect(lines.findIndex((line) => line.includes("- ERC721Droppable"))).toBeGreaterThan( + -1, + ); + expect(lines.findIndex((line) => line.includes("- ERC721SignatureMint"))).toBeGreaterThan( + -1, + ); + + // the process should exit with code 0 + expect(detect.getExitCode()).toEqual(0); + + await cleanup(); // cleanup after test + }); +}); diff --git a/packages/cli/src/common/feature-detector.ts b/packages/cli/src/common/feature-detector.ts index 499a6f85d96..1178a637a0f 100644 --- a/packages/cli/src/common/feature-detector.ts +++ b/packages/cli/src/common/feature-detector.ts @@ -101,7 +101,7 @@ export async function detectExtensions(options: any) { `Detected extension on ${chalk.blueBright(contractWithFeatures.name)}`, ).stopAndPersist({ symbol: "🔎" }); contractWithFeatures.enabledFeatures.map((feature) => { - info(`${chalk.green(feature.name)}`); + logger.info(`✔️ ${chalk.green(feature.name)}`); }); } logger.info(``); From 38c537a1aeffe74f7060c2d265f2ed79812e3525 Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 03:45:06 +0200 Subject: [PATCH 4/7] Cleanup --- packages/cli/e2e/create.test.ts | 4 ++-- packages/cli/e2e/detect.test.ts | 8 ++++++-- packages/cli/src/cli/index.ts | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/cli/e2e/create.test.ts b/packages/cli/e2e/create.test.ts index 3ec8688b572..3dff7139d59 100644 --- a/packages/cli/e2e/create.test.ts +++ b/packages/cli/e2e/create.test.ts @@ -19,7 +19,7 @@ describe("npx thirdweb create", () => { await waitForText(CREATE_MESSAGES.projectName); await pressKey("enter"); await waitForText(CREATE_MESSAGES.framework); - // Select CRA + // select CRA await pressKey("arrowDown"); await pressKey("enter"); await waitForText(CREATE_MESSAGES.language); @@ -28,7 +28,7 @@ describe("npx thirdweb create", () => { // wait for program to finish await waitForFinish(); - //check if the app was created + // check if the app was created expect(await exists("thirdweb-app/package.json")).toEqual(true); // the process should exit with code 0 diff --git a/packages/cli/e2e/detect.test.ts b/packages/cli/e2e/detect.test.ts index c9b4ff75498..019aa98b3bb 100644 --- a/packages/cli/e2e/detect.test.ts +++ b/packages/cli/e2e/detect.test.ts @@ -10,13 +10,17 @@ describe("npx thirdweb detect", () => { const create = await spawn("node", "./dist/cli/index.js create"); await create.waitForText(CREATE_MESSAGES.typeOfProject); + // select contract await create.pressKey("arrowDown"); await create.pressKey("enter"); await create.waitForText(CREATE_MESSAGES.projectName); + // use default name await create.pressKey("enter"); await create.waitForText(CREATE_MESSAGES.framework); + // select hardhat await create.pressKey("enter"); await create.waitForText(CREATE_MESSAGES.contract); + // select ERC721Base await create.pressKey("arrowDown"); await create.pressKey("enter"); @@ -26,12 +30,12 @@ describe("npx thirdweb detect", () => { // the process should exit with code 0 expect(create.getExitCode()).toEqual(0); - //check if the contract was created + // check if the contract was created expect(await exists("thirdweb-contracts/contracts/Contract.sol")).toEqual( true, ); - //check that hardhat config exists + // check that hardhat config exists expect(await exists("thirdweb-contracts/hardhat.config.js")).toEqual( true, ); diff --git a/packages/cli/src/cli/index.ts b/packages/cli/src/cli/index.ts index f18b1a62223..c7b7f58fd81 100644 --- a/packages/cli/src/cli/index.ts +++ b/packages/cli/src/cli/index.ts @@ -28,7 +28,7 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$ updateNotifier({ pkg, shouldNotifyInNpmScript: true, - //check every time while we're still building the CLI + // check every time while we're still building the CLI updateCheckInterval: 0, }).notify(); }); From 65b538a1a10be4bc7cb7bfae5a21d24e16fa604a Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 03:48:51 +0200 Subject: [PATCH 5/7] Add changeset --- .changeset/nervous-beers-fix.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nervous-beers-fix.md diff --git a/.changeset/nervous-beers-fix.md b/.changeset/nervous-beers-fix.md new file mode 100644 index 00000000000..6bc0bfbccda --- /dev/null +++ b/.changeset/nervous-beers-fix.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Add basic tests From 92b379a01af3be97818e94dcfe0b9b3c53ce4c74 Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 03:58:51 +0200 Subject: [PATCH 6/7] Maybe they are not deterministic, weird --- packages/cli/e2e/deploy.test.ts | 2 +- packages/cli/e2e/release.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/e2e/deploy.test.ts b/packages/cli/e2e/deploy.test.ts index c2b0a8adbf0..9f57babfa02 100644 --- a/packages/cli/e2e/deploy.test.ts +++ b/packages/cli/e2e/deploy.test.ts @@ -27,7 +27,7 @@ describe("npx thirdweb deploy", () => { // wait for program to finish await waitForFinish(); - expect(getStdout().at(-1)).toEqual("https://thirdweb.com/contracts/deploy/QmTzUx1eZ1RAeEwsL85umbJFYMTwwu1UsAM3f3tWHSrHKF"); + expect(getStdout().at(-1)).toContain("https://thirdweb.com/contracts/deploy/"); // the process should exit with code 0 expect(getExitCode()).toEqual(0); diff --git a/packages/cli/e2e/release.test.ts b/packages/cli/e2e/release.test.ts index 06df333aee3..105e38de9f9 100644 --- a/packages/cli/e2e/release.test.ts +++ b/packages/cli/e2e/release.test.ts @@ -27,7 +27,7 @@ describe("npx thirdweb release", () => { // wait for program to finish await waitForFinish(); - expect(getStdout().at(-1)).toEqual("https://thirdweb.com/contracts/release/QmXENbPLE5wkAhyUr7y2YShsUHLTtgaG1CvQffUaek6pNN"); + expect(getStdout().at(-1)).toContain("https://thirdweb.com/contracts/release/"); // the process should exit with code 0 expect(getExitCode()).toEqual(0); From b17d2cdee6e348012427174a3885f18c9bf0d288 Mon Sep 17 00:00:00 2001 From: Nacho Iacovino Date: Fri, 2 Sep 2022 21:09:06 +0200 Subject: [PATCH 7/7] Move warning to constant --- packages/cli/constants/constants.ts | 4 ++++ packages/cli/e2e/deploy.test.ts | 3 ++- packages/cli/e2e/release.test.ts | 3 ++- packages/cli/src/core/detection/detect.ts | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/cli/constants/constants.ts b/packages/cli/constants/constants.ts index 5582b288623..d6648bcf79b 100644 --- a/packages/cli/constants/constants.ts +++ b/packages/cli/constants/constants.ts @@ -5,3 +5,7 @@ export const CREATE_MESSAGES = { language: "What language do you want to use?", contract: "What contract do you want to start from?", } as const; + +export const ERROR_MESSAGES = { + noConfiguration: "Failed to find a supported project configuration file in current directory" +} \ No newline at end of file diff --git a/packages/cli/e2e/deploy.test.ts b/packages/cli/e2e/deploy.test.ts index 9f57babfa02..2fb2d779698 100644 --- a/packages/cli/e2e/deploy.test.ts +++ b/packages/cli/e2e/deploy.test.ts @@ -1,6 +1,7 @@ import { prepareEnvironment } from "@gmrchk/cli-testing-library"; import { copyFile } from "fs/promises"; import { resolve } from "path"; +import { ERROR_MESSAGES } from "../constants/constants"; // this creates an app, can take some time that's fine jest.setTimeout(120_000); @@ -21,7 +22,7 @@ describe("npx thirdweb deploy", () => { expect(await exists("BasicContract.sol")).toEqual(true); - await waitForText("Failed to find a supported project configuration"); + await waitForText(ERROR_MESSAGES.noConfiguration); await writeText("y") // wait for program to finish diff --git a/packages/cli/e2e/release.test.ts b/packages/cli/e2e/release.test.ts index 105e38de9f9..f6e5a8232c3 100644 --- a/packages/cli/e2e/release.test.ts +++ b/packages/cli/e2e/release.test.ts @@ -1,6 +1,7 @@ import { prepareEnvironment } from "@gmrchk/cli-testing-library"; import { copyFile } from "fs/promises"; import { resolve } from "path"; +import { ERROR_MESSAGES } from "../constants/constants"; // this creates an app, can take some time that's fine jest.setTimeout(120_000); @@ -21,7 +22,7 @@ describe("npx thirdweb release", () => { expect(await exists("BasicContract.sol")).toEqual(true); - await waitForText("Failed to find a supported project configuration"); + await waitForText(ERROR_MESSAGES.noConfiguration); await writeText("y") // wait for program to finish diff --git a/packages/cli/src/core/detection/detect.ts b/packages/cli/src/core/detection/detect.ts index bbef62c8838..d3c5d41e098 100644 --- a/packages/cli/src/core/detection/detect.ts +++ b/packages/cli/src/core/detection/detect.ts @@ -5,6 +5,7 @@ import FoundryDetector from "./foundry"; import HardhatDetector from "./hardhat"; import TruffleDetector from "./truffle"; import inquirer from "inquirer"; +import { ERROR_MESSAGES } from "../../../constants/constants"; const { Confirm } = require("enquirer"); @@ -25,7 +26,7 @@ export default async function detect( //if there is no project returned at all then just return unknown} if (!possibleProjectTypes.length) { - warn("Failed to find a supported project configuration file in current directory " + path); + warn(`${ERROR_MESSAGES.noConfiguration} ${path}`); const prompt = new Confirm({ name: "continue", message: "Do you want to continue and compile this project with solc instead?",