From 4d730a794888b4151699c5af82137bd01e765e2d Mon Sep 17 00:00:00 2001 From: Bruno Menezes Date: Wed, 4 Oct 2023 21:21:32 +1300 Subject: [PATCH 1/4] feat: Add Vitest configuration for the Web app. --- apps/web/package.json | 13 ++++- apps/web/tsconfig.json | 6 +- apps/web/vitest-setup.ts | 29 +++++++++ apps/web/vitest.config.mts | 11 ++++ package.json | 4 +- yarn.lock | 117 ++++++++++++++++++++++++++++++++++++- 6 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 apps/web/vitest-setup.ts create mode 100644 apps/web/vitest.config.mts diff --git a/apps/web/package.json b/apps/web/package.json index 1b14c1c11..dffede202 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -8,7 +8,10 @@ "codegen": "dotenv -e .env -c -- graphql-codegen", "dev": "next dev", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "test": "vitest run", + "test:watch": "vitest", + "test:ci": "vitest run --coverage" }, "dependencies": { "@cartesi/rollups-explorer-ui": "*", @@ -48,19 +51,25 @@ "@graphql-codegen/typescript-urql": "^4", "@graphql-typed-document-node/core": "^3", "@sunodo/wagmi-plugin-hardhat-deploy": "^0.2", + "@testing-library/jest-dom": "^6.1.3", + "@testing-library/react": "^14.0.0", "@types/node": "^20", "@types/ramda": "^0.29.3", "@types/react": "^18", "@types/react-dom": "^18", + "@vitejs/plugin-react": "^4.1.0", + "@vitest/coverage-v8": "0.34.2", "@wagmi/cli": "^1", "dotenv-cli": "7.3.0", "eslint": "^8", "eslint-config-cartesi": "*", + "jsdom": "22.1.0", "npm-run-all": "^4", "postcss": "^8", "postcss-preset-mantine": "^1.6", "postcss-simple-vars": "^7", "ts-node": "^10", - "typescript": "^5" + "typescript": "^5", + "vitest": "0.34.2" } } diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 83d09a2e8..bdb7876bc 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,14 +1,16 @@ { "extends": "@cartesi/tsconfig/nextjs.json", "compilerOptions": { - "plugins": [{ "name": "next" }] + "plugins": [{ "name": "next" }], + "types": ["vitest/globals"] }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", - "postcss.config.js" + "postcss.config.js", + "./vitest-setup.ts" ], "exclude": ["node_modules"] } diff --git a/apps/web/vitest-setup.ts b/apps/web/vitest-setup.ts new file mode 100644 index 000000000..c01f16ec7 --- /dev/null +++ b/apps/web/vitest-setup.ts @@ -0,0 +1,29 @@ +import { Globals } from "@react-spring/web"; +import "@testing-library/jest-dom/vitest"; +import { beforeAll, vi } from "vitest"; + +Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); + +global.ResizeObserver = vi.fn().mockImplementation(() => ({ + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), +})); + +beforeAll(() => { + Globals.assign({ + skipAnimation: true, + }); +}); diff --git a/apps/web/vitest.config.mts b/apps/web/vitest.config.mts new file mode 100644 index 000000000..8af23b1e4 --- /dev/null +++ b/apps/web/vitest.config.mts @@ -0,0 +1,11 @@ +import react from '@vitejs/plugin-react'; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: "jsdom", + setupFiles: "vitest-setup.ts", + }, +}); diff --git a/package.json b/package.json index 6606cdc4e..0ad45fe61 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "clean": "turbo run clean && rm -rf node_modules", "format:check": "prettier \"**/*.{ts,tsx}\" --check", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "test" : "turbo run test", - "test:ci" : "turbo run test:ci", + "test": "turbo run test", + "test:ci": "turbo run test:ci", "changeset": "changeset", "version-packages": "changeset version", "release": "turbo run build && changeset publish" diff --git a/yarn.lock b/yarn.lock index 93827c707..4242a478c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4630,7 +4630,7 @@ magic-string "^0.27.0" react-refresh "^0.14.0" -"@vitejs/plugin-react@^4.0.3": +"@vitejs/plugin-react@^4.0.3", "@vitejs/plugin-react@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz#e4f56f46fd737c5d386bb1f1ade86ba275fe09bd" integrity sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ== @@ -4641,6 +4641,23 @@ "@types/babel__core" "^7.20.2" react-refresh "^0.14.0" +"@vitest/coverage-v8@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-0.34.2.tgz#51c6d687c538e7f6f2a05595fbe4ec22325403da" + integrity sha512-3VuDZPeGGd1zWtc0Tdj9cHSbFc8IQ0ffnWp9MlhItOkziN6HEf219meZ9cZheg/hJXrXb+Fi2bMu7GeCAfL4yA== + dependencies: + "@ampproject/remapping" "^2.2.1" + "@bcoe/v8-coverage" "^0.2.3" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.1.5" + magic-string "^0.30.1" + picocolors "^1.0.0" + std-env "^3.3.3" + test-exclude "^6.0.0" + v8-to-istanbul "^9.1.0" + "@vitest/coverage-v8@^0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-0.34.5.tgz#bbef8960ee69dcd03b1da9b5f51bb40467b2fbdc" @@ -4658,6 +4675,15 @@ test-exclude "^6.0.0" v8-to-istanbul "^9.1.0" +"@vitest/expect@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.34.2.tgz#2bd09c20b828f8f9da625c203d88003a2b69e314" + integrity sha512-EZm2dMNlLyIfDMha17QHSQcg2KjeAZaXd65fpPzXY5bvnfx10Lcaz3N55uEe8PhF+w4pw+hmrlHLLlRn9vkBJg== + dependencies: + "@vitest/spy" "0.34.2" + "@vitest/utils" "0.34.2" + chai "^4.3.7" + "@vitest/expect@0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.34.5.tgz#1f58829e746311162220d6580f72d6329efb9081" @@ -4667,6 +4693,15 @@ "@vitest/utils" "0.34.5" chai "^4.3.7" +"@vitest/runner@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.34.2.tgz#3408682cd68475e733a3f151d27792be75d2f07d" + integrity sha512-8ydGPACVX5tK3Dl0SUwxfdg02h+togDNeQX3iXVFYgzF5odxvaou7HnquALFZkyVuYskoaHUOqOyOLpOEj5XTA== + dependencies: + "@vitest/utils" "0.34.2" + p-limit "^4.0.0" + pathe "^1.1.1" + "@vitest/runner@0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.34.5.tgz#2bc69a21cd1a09c9403a2a9b0cbd7c42df79f1ae" @@ -4676,6 +4711,15 @@ p-limit "^4.0.0" pathe "^1.1.1" +"@vitest/snapshot@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.34.2.tgz#fce1b89aa1e836e3fd0229c03ef4ef2f69cb1409" + integrity sha512-qhQ+xy3u4mwwLxltS4Pd4SR+XHv4EajiTPNY3jkIBLUApE6/ce72neJPSUQZ7bL3EBuKI+NhvzhGj3n5baRQUQ== + dependencies: + magic-string "^0.30.1" + pathe "^1.1.1" + pretty-format "^29.5.0" + "@vitest/snapshot@0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.34.5.tgz#1d81fce3cdc9cf6ad57e86eb5e5eecefc71d1e02" @@ -4685,6 +4729,13 @@ pathe "^1.1.1" pretty-format "^29.5.0" +"@vitest/spy@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.34.2.tgz#5c483d71e4c2d42f90bef29cdf6e5f5559c52827" + integrity sha512-yd4L9OhfH6l0Av7iK3sPb3MykhtcRN5c5K5vm1nTbuN7gYn+yvUVVsyvzpHrjqS7EWqn9WsPJb7+0c3iuY60tA== + dependencies: + tinyspy "^2.1.1" + "@vitest/spy@0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.34.5.tgz#2d32993b18eeb50f682e5dde089e390cbb387cb8" @@ -4692,6 +4743,15 @@ dependencies: tinyspy "^2.1.1" +"@vitest/utils@0.34.2": + version "0.34.2" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.2.tgz#5d291a1b0f5d01be99fd1801d212b837a610c53b" + integrity sha512-Lzw+kAsTPubhoQDp1uVAOP6DhNia1GMDsI9jgB0yMn+/nDaPieYQ88lKqz/gGjSHL4zwOItvpehec9OY+rS73w== + dependencies: + diff-sequences "^29.4.3" + loupe "^2.3.6" + pretty-format "^29.5.0" + "@vitest/utils@0.34.5": version "0.34.5" resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.5.tgz#2178fdbc36524d25b8d846b3d408962e1771e83a" @@ -9178,7 +9238,7 @@ jscodeshift@^0.14.0: temp "^0.8.4" write-file-atomic "^2.3.0" -jsdom@^22.1.0: +jsdom@22.1.0, jsdom@^22.1.0: version "22.1.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.1.0.tgz#0fca6d1a37fbeb7f4aac93d1090d782c56b611c8" integrity sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw== @@ -13263,6 +13323,18 @@ viem@^1, viem@^1.0.0: isomorphic-ws "5.0.0" ws "8.13.0" +vite-node@0.34.2: + version "0.34.2" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.2.tgz#1daa025f8cee8a141c9b4d051e979cf61adaba2c" + integrity sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA== + dependencies: + cac "^6.7.14" + debug "^4.3.4" + mlly "^1.4.0" + pathe "^1.1.1" + picocolors "^1.0.0" + vite "^3.0.0 || ^4.0.0" + vite-node@0.34.5: version "0.34.5" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.5.tgz#21d6bd637cb0c14d0edc1d7bdf832a70dc11c427" @@ -13275,6 +13347,17 @@ vite-node@0.34.5: picocolors "^1.0.0" vite "^3.0.0 || ^4.0.0 || ^5.0.0-0" +"vite@^3.0.0 || ^4.0.0": + version "4.4.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.10.tgz#3794639cc433f7cb33ad286930bf0378c86261c8" + integrity sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + "vite@^3.0.0 || ^4.0.0 || ^5.0.0-0", "vite@^3.1.0 || ^4.0.0 || ^5.0.0-0", vite@^4.4.5: version "4.4.9" resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d" @@ -13286,6 +13369,36 @@ vite-node@0.34.5: optionalDependencies: fsevents "~2.3.2" +vitest@0.34.2: + version "0.34.2" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.34.2.tgz#c90d563df18383f1749b8a4544adda1871bbc859" + integrity sha512-WgaIvBbjsSYMq/oiMlXUI7KflELmzM43BEvkdC/8b5CAod4ryAiY2z8uR6Crbi5Pjnu5oOmhKa9sy7uk6paBxQ== + dependencies: + "@types/chai" "^4.3.5" + "@types/chai-subset" "^1.3.3" + "@types/node" "*" + "@vitest/expect" "0.34.2" + "@vitest/runner" "0.34.2" + "@vitest/snapshot" "0.34.2" + "@vitest/spy" "0.34.2" + "@vitest/utils" "0.34.2" + acorn "^8.9.0" + acorn-walk "^8.2.0" + cac "^6.7.14" + chai "^4.3.7" + debug "^4.3.4" + local-pkg "^0.4.3" + magic-string "^0.30.1" + pathe "^1.1.1" + picocolors "^1.0.0" + std-env "^3.3.3" + strip-literal "^1.0.1" + tinybench "^2.5.0" + tinypool "^0.7.0" + vite "^3.0.0 || ^4.0.0" + vite-node "0.34.2" + why-is-node-running "^2.2.2" + vitest@^0.34.5: version "0.34.5" resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.34.5.tgz#c2200566d4b133588d69124bc0fbe8bf179f644f" From 91ccb7fbd688983d5cf356040b86dd37d86c8544 Mon Sep 17 00:00:00 2001 From: Bruno Menezes Date: Wed, 4 Oct 2023 21:23:06 +1300 Subject: [PATCH 2/4] test: Add test cases for the Address component and utils to support testing --- apps/web/test/components/address.test.tsx | 53 +++++++++++++++++++++++ apps/web/test/utils/WithMantineTheme.tsx | 19 ++++++++ 2 files changed, 72 insertions(+) create mode 100644 apps/web/test/components/address.test.tsx create mode 100644 apps/web/test/utils/WithMantineTheme.tsx diff --git a/apps/web/test/components/address.test.tsx b/apps/web/test/components/address.test.tsx new file mode 100644 index 000000000..ea67c7094 --- /dev/null +++ b/apps/web/test/components/address.test.tsx @@ -0,0 +1,53 @@ +import { cleanup, render, screen } from "@testing-library/react"; +import { describe, it } from "vitest"; +import Address from "../../src/components/address"; +import withMantineTheme from "../utils/WithMantineTheme"; + +const AddressE = withMantineTheme(Address); +const portalAddr = "0x9C21AEb2093C32DDbC53eEF24B873BDCd1aDa1DB"; +const unknowAddr = "0x775c80fd1DE1b466d7eB611b45067c4394247274"; + +describe("Address Component", () => { + afterEach(() => cleanup()); + + it("should display the name when address is from ERC20Portal", () => { + render(); + + expect(screen.getByText("ERC20Portal")).toBeInTheDocument(); + }); + + it("should display the full address when is not known address", () => { + render(); + + expect(screen.getByText(unknowAddr)).toBeInTheDocument(); + }); + + it("should display a shorten version of the address for not known address", () => { + render(); + + expect(screen.getByText("0x775c80...247274")).toBeInTheDocument(); + }); + + it("should display jazzicon when enabled", () => { + const { container } = render(); + + const jazzEls = container.querySelectorAll(".paper"); + expect(jazzEls.length).toEqual(1); + expect(jazzEls[0].querySelector("svg")).toBeInTheDocument(); + }); + + it("should wrap the address text with a link to the correct place", () => { + const { container } = render( + , + ); + + expect(screen.getByRole("link")).toBeInTheDocument(); + expect(screen.getByRole("link")).toHaveProperty( + "href", + `https://etherscan.io/address/${portalAddr}`, + ); + }); +}); diff --git a/apps/web/test/utils/WithMantineTheme.tsx b/apps/web/test/utils/WithMantineTheme.tsx new file mode 100644 index 000000000..f11598733 --- /dev/null +++ b/apps/web/test/utils/WithMantineTheme.tsx @@ -0,0 +1,19 @@ +import { MantineProvider, createTheme } from "@mantine/core"; +import { FC } from "react"; + +const theme = createTheme({ + fontFamily: "Open Sans, sans-serif", + primaryColor: "cyan", +}); + +export const withMantineTheme = (Component: FC): FC => { + const NewComp: FC = (props: T) => ( + {Component(props)} + ); + + NewComp.displayName = Component.displayName; + + return NewComp; +}; + +export default withMantineTheme; From 14447da715026cc5ef152c523aa976cd9f51541c Mon Sep 17 00:00:00 2001 From: Bruno Menezes Date: Wed, 4 Oct 2023 21:24:10 +1300 Subject: [PATCH 3/4] refactor!: Making rollups-wagmi entry point ESM only. CJS still generated but the focus is ESM. --- packages/rollups-wagmi/package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rollups-wagmi/package.json b/packages/rollups-wagmi/package.json index d44e952a2..06f9a4d6a 100644 --- a/packages/rollups-wagmi/package.json +++ b/packages/rollups-wagmi/package.json @@ -2,8 +2,9 @@ "name": "@cartesi/rollups-wagmi", "version": "0.0.0", "main": "./dist/index.js", - "module": "./dist/index.mjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", + "type": "module", "sideEffects": false, "license": "Apache-2.0", "files": [ @@ -13,7 +14,7 @@ "build": "tsup", "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", "codegen": "wagmi generate", - "dev": "tsup --watch" + "dev": "tsup --watch" }, "dependencies": { "wagmi": "^1" From c0382cb19ed911132c054e8aba3e70a1eeee5760 Mon Sep 17 00:00:00 2001 From: Bruno Menezes Date: Wed, 4 Oct 2023 21:28:35 +1300 Subject: [PATCH 4/4] chore: Add explicit type declarations --- packages/ui/src/InputDetails/InputDetailsContext.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/InputDetails/InputDetailsContext.tsx b/packages/ui/src/InputDetails/InputDetailsContext.tsx index fe64a32b9..d872246dc 100644 --- a/packages/ui/src/InputDetails/InputDetailsContext.tsx +++ b/packages/ui/src/InputDetails/InputDetailsContext.tsx @@ -63,6 +63,7 @@ const InputDetailsContext = createContext({ const getOnlySupportedContent = (dict: OptionalContents) => { const supportedTypes = map(prop("type"), SUPPORTED_TABS); + //@ts-ignore return pick(supportedTypes, dict); }; @@ -88,10 +89,12 @@ const useSelector: UseSelector = (predicate) => { return [result]; }; -const availableContentAsSet = pipe( +type AvailableContentAsSet = (value: State) => Set; + +const availableContentAsSet: AvailableContentAsSet = pipe( prop("availableContent"), keys, - memoizeWith(join("/"), (keys) => new Set(keys)), + memoizeWith(join("/"), (keys) => new Set(keys as SupportedContent[])), ); export const useDefinedContentSet = () => {