@pasosdejesus/m 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blockchain/deployments.d.ts +40 -0
- package/dist/blockchain/deployments.d.ts.map +1 -0
- package/dist/blockchain/deployments.js +64 -0
- package/dist/debug/DebugConsole.d.ts +22 -0
- package/dist/debug/DebugConsole.d.ts.map +1 -0
- package/dist/debug/DebugConsole.js +79 -0
- package/dist/debug/Logger.d.ts +38 -0
- package/dist/debug/Logger.d.ts.map +1 -0
- package/dist/debug/Logger.js +94 -0
- package/dist/debug/index.d.ts +6 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +4 -0
- package/dist/debug/useLogger.d.ts +14 -0
- package/dist/debug/useLogger.d.ts.map +1 -0
- package/dist/debug/useLogger.js +23 -0
- package/dist/debug/utils.d.ts +10 -0
- package/dist/debug/utils.d.ts.map +1 -0
- package/dist/debug/utils.js +53 -0
- package/dist/e2e/assertions.d.ts +5 -0
- package/dist/e2e/assertions.d.ts.map +1 -0
- package/dist/e2e/assertions.js +18 -0
- package/dist/e2e/browser.d.ts +37 -0
- package/dist/e2e/browser.d.ts.map +1 -0
- package/dist/e2e/browser.js +97 -0
- package/dist/e2e/env.d.ts +18 -0
- package/dist/e2e/env.d.ts.map +1 -0
- package/dist/e2e/env.js +57 -0
- package/dist/e2e/index.d.ts +11 -0
- package/dist/e2e/index.d.ts.map +1 -0
- package/dist/e2e/index.js +8 -0
- package/dist/e2e/navigation.d.ts +4 -0
- package/dist/e2e/navigation.d.ts.map +1 -0
- package/dist/e2e/navigation.js +32 -0
- package/dist/e2e/siwe-mock.d.ts +11 -0
- package/dist/e2e/siwe-mock.d.ts.map +1 -0
- package/dist/e2e/siwe-mock.js +112 -0
- package/dist/e2e/siwe.d.ts +15 -0
- package/dist/e2e/siwe.d.ts.map +1 -0
- package/dist/e2e/siwe.js +85 -0
- package/dist/e2e/wallet-mock.d.ts +13 -0
- package/dist/e2e/wallet-mock.d.ts.map +1 -0
- package/dist/e2e/wallet-mock.js +91 -0
- package/dist/i18n/common-cli.d.ts +11 -0
- package/dist/i18n/common-cli.d.ts.map +1 -0
- package/dist/i18n/common-cli.js +22 -0
- package/dist/i18n/createTranslator.d.ts +28 -0
- package/dist/i18n/createTranslator.d.ts.map +1 -0
- package/dist/i18n/createTranslator.js +48 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/locales/cli.d.ts +3 -0
- package/dist/i18n/locales/cli.d.ts.map +1 -0
- package/dist/i18n/locales/cli.js +180 -0
- package/dist/i18n/types.d.ts +3 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +10 -0
- package/dist/m.d.ts +2 -0
- package/dist/m.d.ts.map +1 -0
- package/dist/m.js +334 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +7 -0
- package/dist/shadcn_components/cn.d.ts +13 -0
- package/dist/shadcn_components/cn.d.ts.map +1 -0
- package/dist/shadcn_components/cn.js +15 -0
- package/dist/shadcn_components/ui/accordion.d.ts +8 -0
- package/dist/shadcn_components/ui/accordion.d.ts.map +1 -0
- package/dist/shadcn_components/ui/accordion.js +14 -0
- package/dist/shadcn_components/ui/alert-dialog.d.ts +21 -0
- package/dist/shadcn_components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/shadcn_components/ui/alert-dialog.js +27 -0
- package/dist/shadcn_components/ui/alert.d.ts +9 -0
- package/dist/shadcn_components/ui/alert.d.ts.map +1 -0
- package/dist/shadcn_components/ui/alert.js +22 -0
- package/dist/shadcn_components/ui/avatar.d.ts +7 -0
- package/dist/shadcn_components/ui/avatar.d.ts.map +1 -0
- package/dist/shadcn_components/ui/avatar.js +12 -0
- package/dist/shadcn_components/ui/badge.d.ts +10 -0
- package/dist/shadcn_components/ui/badge.d.ts.map +1 -0
- package/dist/shadcn_components/ui/badge.js +22 -0
- package/dist/shadcn_components/ui/button.d.ts +11 -0
- package/dist/shadcn_components/ui/button.d.ts.map +1 -0
- package/dist/shadcn_components/ui/button.js +31 -0
- package/dist/shadcn_components/ui/card.d.ts +10 -0
- package/dist/shadcn_components/ui/card.d.ts.map +1 -0
- package/dist/shadcn_components/ui/card.js +24 -0
- package/dist/shadcn_components/ui/checkbox.d.ts +5 -0
- package/dist/shadcn_components/ui/checkbox.d.ts.map +1 -0
- package/dist/shadcn_components/ui/checkbox.js +9 -0
- package/dist/shadcn_components/ui/dialog.d.ts +20 -0
- package/dist/shadcn_components/ui/dialog.d.ts.map +1 -0
- package/dist/shadcn_components/ui/dialog.js +23 -0
- package/dist/shadcn_components/ui/dropdown-menu.d.ts +28 -0
- package/dist/shadcn_components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/shadcn_components/ui/dropdown-menu.js +36 -0
- package/dist/shadcn_components/ui/form.d.ts +24 -0
- package/dist/shadcn_components/ui/form.d.ts.map +1 -0
- package/dist/shadcn_components/ui/form.js +63 -0
- package/dist/shadcn_components/ui/input.d.ts +4 -0
- package/dist/shadcn_components/ui/input.d.ts.map +1 -0
- package/dist/shadcn_components/ui/input.js +6 -0
- package/dist/shadcn_components/ui/label.d.ts +6 -0
- package/dist/shadcn_components/ui/label.d.ts.map +1 -0
- package/dist/shadcn_components/ui/label.js +10 -0
- package/dist/shadcn_components/ui/menubar.d.ts +29 -0
- package/dist/shadcn_components/ui/menubar.d.ts.map +1 -0
- package/dist/shadcn_components/ui/menubar.js +46 -0
- package/dist/shadcn_components/ui/popover.d.ts +7 -0
- package/dist/shadcn_components/ui/popover.d.ts.map +1 -0
- package/dist/shadcn_components/ui/popover.js +10 -0
- package/dist/shadcn_components/ui/progress.d.ts +5 -0
- package/dist/shadcn_components/ui/progress.d.ts.map +1 -0
- package/dist/shadcn_components/ui/progress.js +8 -0
- package/dist/shadcn_components/ui/radio-group.d.ts +6 -0
- package/dist/shadcn_components/ui/radio-group.d.ts.map +1 -0
- package/dist/shadcn_components/ui/radio-group.js +15 -0
- package/dist/shadcn_components/ui/scroll-area.d.ts +6 -0
- package/dist/shadcn_components/ui/scroll-area.d.ts.map +1 -0
- package/dist/shadcn_components/ui/scroll-area.js +12 -0
- package/dist/shadcn_components/ui/select.d.ts +14 -0
- package/dist/shadcn_components/ui/select.d.ts.map +1 -0
- package/dist/shadcn_components/ui/select.js +27 -0
- package/dist/shadcn_components/ui/separator.d.ts +5 -0
- package/dist/shadcn_components/ui/separator.d.ts.map +1 -0
- package/dist/shadcn_components/ui/separator.js +8 -0
- package/dist/shadcn_components/ui/sheet.d.ts +26 -0
- package/dist/shadcn_components/ui/sheet.d.ts.map +1 -0
- package/dist/shadcn_components/ui/sheet.js +37 -0
- package/dist/shadcn_components/ui/skeleton.d.ts +3 -0
- package/dist/shadcn_components/ui/skeleton.d.ts.map +1 -0
- package/dist/shadcn_components/ui/skeleton.js +6 -0
- package/dist/shadcn_components/ui/slider.d.ts +5 -0
- package/dist/shadcn_components/ui/slider.d.ts.map +1 -0
- package/dist/shadcn_components/ui/slider.js +8 -0
- package/dist/shadcn_components/ui/switch.d.ts +5 -0
- package/dist/shadcn_components/ui/switch.d.ts.map +1 -0
- package/dist/shadcn_components/ui/switch.js +8 -0
- package/dist/shadcn_components/ui/table.d.ts +11 -0
- package/dist/shadcn_components/ui/table.d.ts.map +1 -0
- package/dist/shadcn_components/ui/table.js +20 -0
- package/dist/shadcn_components/ui/tabs.d.ts +8 -0
- package/dist/shadcn_components/ui/tabs.d.ts.map +1 -0
- package/dist/shadcn_components/ui/tabs.js +13 -0
- package/dist/shadcn_components/ui/textarea.d.ts +4 -0
- package/dist/shadcn_components/ui/textarea.d.ts.map +1 -0
- package/dist/shadcn_components/ui/textarea.js +8 -0
- package/dist/shadcn_components/ui/toast.d.ts +16 -0
- package/dist/shadcn_components/ui/toast.d.ts.map +1 -0
- package/dist/shadcn_components/ui/toast.js +34 -0
- package/dist/shadcn_components/ui/toaster.d.ts +2 -0
- package/dist/shadcn_components/ui/toaster.d.ts.map +1 -0
- package/dist/shadcn_components/ui/toaster.js +10 -0
- package/dist/shadcn_components/ui/tooltip.d.ts +8 -0
- package/dist/shadcn_components/ui/tooltip.d.ts.map +1 -0
- package/dist/shadcn_components/ui/tooltip.js +11 -0
- package/dist/shadcn_components/ui/use-toast.d.ts +45 -0
- package/dist/shadcn_components/ui/use-toast.d.ts.map +1 -0
- package/dist/shadcn_components/ui/use-toast.js +126 -0
- package/dist/tasks/context.d.ts +13 -0
- package/dist/tasks/context.d.ts.map +1 -0
- package/dist/tasks/context.js +310 -0
- package/dist/tasks/create.d.ts +2 -0
- package/dist/tasks/create.d.ts.map +1 -0
- package/dist/tasks/create.js +91 -0
- package/dist/tasks/db.d.ts +19 -0
- package/dist/tasks/db.d.ts.map +1 -0
- package/dist/tasks/db.js +791 -0
- package/dist/tasks/e2e.d.ts +2 -0
- package/dist/tasks/e2e.d.ts.map +1 -0
- package/dist/tasks/e2e.js +124 -0
- package/dist/tasks/edit.d.ts +7 -0
- package/dist/tasks/edit.d.ts.map +1 -0
- package/dist/tasks/edit.js +471 -0
- package/dist/tasks/engine.d.ts +2 -0
- package/dist/tasks/engine.d.ts.map +1 -0
- package/dist/tasks/engine.js +149 -0
- package/dist/tasks/env-diff.d.ts +2 -0
- package/dist/tasks/env-diff.d.ts.map +1 -0
- package/dist/tasks/env-diff.js +140 -0
- package/dist/tasks/fuzzy.d.ts +9 -0
- package/dist/tasks/fuzzy.d.ts.map +1 -0
- package/dist/tasks/fuzzy.js +153 -0
- package/dist/tasks/glob.d.ts +5 -0
- package/dist/tasks/glob.d.ts.map +1 -0
- package/dist/tasks/glob.js +57 -0
- package/dist/tasks/grep.d.ts +9 -0
- package/dist/tasks/grep.d.ts.map +1 -0
- package/dist/tasks/grep.js +93 -0
- package/dist/tasks/readfile.d.ts +2 -0
- package/dist/tasks/readfile.d.ts.map +1 -0
- package/dist/tasks/readfile.js +177 -0
- package/dist/tasks/update.d.ts +5 -0
- package/dist/tasks/update.d.ts.map +1 -0
- package/dist/tasks/update.js +200 -0
- package/dist/tasks/util.d.ts +12 -0
- package/dist/tasks/util.d.ts.map +1 -0
- package/dist/tasks/util.js +42 -0
- package/dist/tasks/wallet.d.ts +2 -0
- package/dist/tasks/wallet.d.ts.map +1 -0
- package/dist/tasks/wallet.js +697 -0
- package/dist/tasks/writefile.d.ts +2 -0
- package/dist/tasks/writefile.d.ts.map +1 -0
- package/dist/tasks/writefile.js +66 -0
- package/dist/templates/AGENTS.md.hbs +81 -0
- package/dist/templates/ARCHITECTURE.md.hbs +146 -0
- package/dist/templates/CONTRIBUTING.md.hbs +83 -0
- package/dist/templates/LICENCIA.md +21 -0
- package/dist/templates/LICENSE.md +15 -0
- package/dist/templates/Makefile +16 -0
- package/dist/templates/README.md.hbs +111 -0
- package/dist/templates/apps/.env.example.hbs +75 -0
- package/dist/templates/apps/hardhat/.prettierrc +16 -0
- package/dist/templates/apps/hardhat/MOCK_USDT_README.md +20 -0
- package/dist/templates/apps/hardhat/Makefile +13 -0
- package/dist/templates/apps/hardhat/README.md +129 -0
- package/dist/templates/apps/hardhat/bin/MusdtVerification +4 -0
- package/dist/templates/apps/hardhat/bin/approveDepositOwner +7 -0
- package/dist/templates/apps/hardhat/bin/contractVerification +9 -0
- package/dist/templates/apps/hardhat/bin/deployMockUSDT +7 -0
- package/dist/templates/apps/hardhat/bin/prepadJ.sh +14 -0
- package/dist/templates/apps/hardhat/bin/verifyMockUSDT +7 -0
- package/dist/templates/apps/hardhat/contracts/MockUSDT.sol +47 -0
- package/dist/templates/apps/hardhat/hardhat.config.ts +102 -0
- package/dist/templates/apps/hardhat/package.json +55 -0
- package/dist/templates/apps/hardhat/scripts/approveDepositOwner.ts +22 -0
- package/dist/templates/apps/hardhat/scripts/deployMockUSDT.ts +49 -0
- package/dist/templates/apps/hardhat/scripts/verifyDeployment.ts +93 -0
- package/dist/templates/apps/hardhat/scripts/verifyMockUSDT.ts +52 -0
- package/dist/templates/apps/hardhat/sync-abis.mjs +58 -0
- package/dist/templates/apps/hardhat/test/MockUSDT.test.ts +40 -0
- package/dist/templates/apps/hardhat/tsconfig.json +27 -0
- package/dist/templates/apps/nextjs/.config/kysely.config.ts +36 -0
- package/dist/templates/apps/nextjs/Makefile +24 -0
- package/dist/templates/apps/nextjs/README.md.hbs +76 -0
- package/dist/templates/apps/nextjs/abis/IERC20.json +74 -0
- package/dist/templates/apps/nextjs/abis/MockUSDT.json +242 -0
- package/dist/templates/apps/nextjs/abis/ReentrancyGuard.json +1 -0
- package/dist/templates/apps/nextjs/app/globals.css +3 -0
- package/dist/templates/apps/nextjs/app/layout.tsx.hbs +26 -0
- package/dist/templates/apps/nextjs/app/page.tsx.hbs +225 -0
- package/dist/templates/apps/nextjs/app/testui/page.tsx +371 -0
- package/dist/templates/apps/nextjs/bin/m +8 -0
- package/dist/templates/apps/nextjs/components.json +21 -0
- package/dist/templates/apps/nextjs/next-env.d.ts +5 -0
- package/dist/templates/apps/nextjs/next.config.ts +10 -0
- package/dist/templates/apps/nextjs/package.json.hbs +48 -0
- package/dist/templates/apps/nextjs/pnpm-workspace.yaml +13 -0
- package/dist/templates/apps/nextjs/postcss.config.mjs +6 -0
- package/dist/templates/apps/nextjs/tailwind.config.js +11 -0
- package/dist/templates/apps/nextjs/tests/helpers.ts +31 -0
- package/dist/templates/apps/nextjs/tests/index.test.ts +7 -0
- package/dist/templates/apps/nextjs/tests/setup-env.ts.hbs +8 -0
- package/dist/templates/apps/nextjs/tests/test-utils.example.test.ts +168 -0
- package/dist/templates/apps/nextjs/tsconfig.json +44 -0
- package/dist/templates/apps/nextjs/tsconfig.test.json +38 -0
- package/dist/templates/apps/nextjs/vitest.config.ts +13 -0
- package/dist/test-utils/fs-mocks.d.ts +32 -0
- package/dist/test-utils/fs-mocks.d.ts.map +1 -0
- package/dist/test-utils/fs-mocks.js +63 -0
- package/dist/test-utils/i18n-mock.d.ts +21 -0
- package/dist/test-utils/i18n-mock.d.ts.map +1 -0
- package/dist/test-utils/i18n-mock.js +29 -0
- package/dist/test-utils/index.d.ts +12 -0
- package/dist/test-utils/index.d.ts.map +1 -0
- package/dist/test-utils/index.js +11 -0
- package/dist/test-utils/kysely-mocks.d.ts +298 -0
- package/dist/test-utils/kysely-mocks.d.ts.map +1 -0
- package/dist/test-utils/kysely-mocks.js +173 -0
- package/dist/test-utils/radix-mocks.d.ts +134 -0
- package/dist/test-utils/radix-mocks.d.ts.map +1 -0
- package/dist/test-utils/radix-mocks.js +175 -0
- package/dist/test-utils/rainbowkit-mocks.d.ts +80 -0
- package/dist/test-utils/rainbowkit-mocks.d.ts.map +1 -0
- package/dist/test-utils/rainbowkit-mocks.js +247 -0
- package/dist/test-utils/viem-mocks.d.ts +86 -0
- package/dist/test-utils/viem-mocks.d.ts.map +1 -0
- package/dist/test-utils/viem-mocks.js +54 -0
- package/dist/util/cli-parser.d.ts +20 -0
- package/dist/util/cli-parser.d.ts.map +1 -0
- package/dist/util/cli-parser.js +38 -0
- package/dist/util/colors.d.ts +5 -0
- package/dist/util/colors.d.ts.map +1 -0
- package/dist/util/colors.js +5 -0
- package/dist/util/locale.d.ts +3 -0
- package/dist/util/locale.d.ts.map +1 -0
- package/dist/util/locale.js +10 -0
- package/dist/wba/client.d.ts +19 -0
- package/dist/wba/client.d.ts.map +1 -0
- package/dist/wba/client.js +31 -0
- package/dist/wba/index.d.ts +4 -0
- package/dist/wba/index.d.ts.map +1 -0
- package/dist/wba/index.js +2 -0
- package/dist/wba/routes/event.d.ts +32 -0
- package/dist/wba/routes/event.d.ts.map +1 -0
- package/dist/wba/routes/event.js +42 -0
- package/dist/wba/routes/index.d.ts +3 -0
- package/dist/wba/routes/index.d.ts.map +1 -0
- package/dist/wba/routes/index.js +2 -0
- package/dist/wba/routes/summary.d.ts +44 -0
- package/dist/wba/routes/summary.d.ts.map +1 -0
- package/dist/wba/routes/summary.js +146 -0
- package/dist/wba/server.d.ts +18 -0
- package/dist/wba/server.d.ts.map +1 -0
- package/dist/wba/server.js +29 -0
- package/dist/wba/types.d.ts +68 -0
- package/dist/wba/types.d.ts.map +1 -0
- package/dist/wba/types.js +6 -0
- package/package.json +223 -0
- package/src/blockchain/README.md +80 -0
- package/src/debug/README.md +94 -0
- package/src/e2e/README.md +105 -0
- package/src/i18n/README.md +143 -0
- package/src/shadcn_components/README.md +125 -0
- package/src/tasks/README.md +69 -0
- package/src/test-utils/README.md +638 -0
- package/src/util/README.md +18 -0
- package/src/wba/README.md +175 -0
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
# Test Utilities Commons (@pasosdeJesus/m)
|
|
2
|
+
|
|
3
|
+
**"Y todo lo que hagáis, hacedlo de corazón, como para el Señor y no para los hombres" (Colosenses 3:23)**
|
|
4
|
+
|
|
5
|
+
This directory contains generic mocking utilities for tests, designed to be reusable across multiple projects using similar stacks. These utilities have been extracted and adapted from the `learn.tg` project to become part of the `@pasosdeJesus/m` library.
|
|
6
|
+
|
|
7
|
+
### 🕊️ Christian Framework
|
|
8
|
+
|
|
9
|
+
As part of "Pasos de Jesús" projects, we recognize that our work serves a higher purpose: to bring the Good News to the world through technology. The Word of God is our supreme compass (brújula suprema). We strive to act with faithful diligence, excellence, and love, remembering that our technical work ultimately serves God's kingdom.
|
|
10
|
+
|
|
11
|
+
"Whatever you do, work at it with all your heart, as working for the Lord, not for human masters" (Colossians 3:23). This includes writing tests and creating tools that help others build reliable, truthful software.
|
|
12
|
+
|
|
13
|
+
## 🚀 For users of projects generated by `m`
|
|
14
|
+
|
|
15
|
+
If you're developing a project generated with `m`, you can use these test utilities by importing them directly from the `@pasosdejesus/m` package.
|
|
16
|
+
|
|
17
|
+
> ⚠️ **Vitest compatibility**: These mocks are designed for **Vitest 2.1.x**.
|
|
18
|
+
> They use `vi.hoisted()` and `vi.mock()`. For vitest 1.x, use version `0.14.x`
|
|
19
|
+
> of `@pasosdejesus/m`.
|
|
20
|
+
|
|
21
|
+
### Installation
|
|
22
|
+
|
|
23
|
+
Projects generated by `m` already include the necessary dependencies as `devDependencies`. If you need to install optional dependencies for using specific mocks:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Install optional dependencies as needed
|
|
27
|
+
pnpm add -D @testing-library/react viem next-auth wagmi siwe kysely pg react react-dom
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Quick start
|
|
31
|
+
|
|
32
|
+
`apiAuthMocks` provee mocks para wagmi, rainbowkit, next-auth, siwe y axios.
|
|
33
|
+
Úsalos directamente en `vitest.setup.ts`:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// vitest.setup.ts
|
|
37
|
+
import { apiAuthMocks } from '@pasosdejesus/m/test-utils/rainbowkit-mocks'
|
|
38
|
+
|
|
39
|
+
const { mocks, setupDefaultImplementations } = apiAuthMocks
|
|
40
|
+
setupDefaultImplementations()
|
|
41
|
+
|
|
42
|
+
// vi.mock() para cada módulo — DEBE estar a module scope
|
|
43
|
+
vi.mock('axios', () => ({
|
|
44
|
+
default: {
|
|
45
|
+
get: (...args: any[]) => mocks.mockAxiosGet(...args),
|
|
46
|
+
post: (...args: any[]) => mocks.mockAxiosPost(...args),
|
|
47
|
+
},
|
|
48
|
+
}))
|
|
49
|
+
vi.mock('siwe', () => ({ SiweMessage: mocks.mockSiweMessage }))
|
|
50
|
+
vi.mock('next-auth/react', () => ({
|
|
51
|
+
useSession: () => mocks.mockUseSession(),
|
|
52
|
+
getCsrfToken: () => mocks.mockGetCsrfToken(),
|
|
53
|
+
SessionProvider: ({ children }: { children: React.ReactNode }) => children,
|
|
54
|
+
}))
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Esto configura automáticamente:
|
|
58
|
+
- **wagmi**: `useAccount`, `useConnect`, `useDisconnect`, `useSwitchChain`, `createConfig`, `http`, `WagmiProvider`
|
|
59
|
+
- **next-auth/react**: `useSession`, `getCsrfToken`, `SessionProvider`
|
|
60
|
+
- **@rainbow-me/rainbowkit**: `RainbowKitProvider`, `ConnectButton`
|
|
61
|
+
- **axios**: delegación a `mocks.mockAxiosGet/Post/Put/Delete/Request`
|
|
62
|
+
- **siwe**: `SiweMessage`
|
|
63
|
+
|
|
64
|
+
> ⚠️ **CRÍTICO**: `vi.mock()` debe estar a **module scope** del archivo que vitest transforma.
|
|
65
|
+
> No funciona desde funciones dentro de módulos importados (como `setupMocks()`).
|
|
66
|
+
> Si usas `apiDbMocks.setupMocks()`, el `vi.mock('kysely')` interno **no se aplica**.
|
|
67
|
+
> Agrega los `vi.mock()` directamente en tu `vitest.setup.ts` o en el test file.
|
|
68
|
+
|
|
69
|
+
### Basic usage
|
|
70
|
+
|
|
71
|
+
Import mocks from `@pasosdejesus/m/test-utils`:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// Import individual mocks
|
|
75
|
+
import { createFsMocks } from '@pasosdejesus/m/test-utils/fs-mocks'
|
|
76
|
+
import { createMockKysely } from '@pasosdejesus/m/test-utils/kysely-mocks'
|
|
77
|
+
import { createAuthMocks } from '@pasosdejesus/m/test-utils/rainbowkit-mocks'
|
|
78
|
+
import { viemMocks } from '@pasosdejesus/m/test-utils/viem-mocks'
|
|
79
|
+
|
|
80
|
+
// radix-mocks is a side-effect import
|
|
81
|
+
import '@pasosdejesus/m/test-utils/radix-mocks'
|
|
82
|
+
|
|
83
|
+
// Or import everything from the index
|
|
84
|
+
import { createFsMocks, createMockKysely, createAuthMocks } from '@pasosdejesus/m/test-utils'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Quick example
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { describe, it, expect, beforeAll, beforeEach } from 'vitest'
|
|
91
|
+
import { createFsMocks, createMockKysely, createAuthMocks } from '@pasosdejesus/m/test-utils'
|
|
92
|
+
|
|
93
|
+
describe('My test', () => {
|
|
94
|
+
const fsMocks = createFsMocks()
|
|
95
|
+
const dbMocks = createMockKysely()
|
|
96
|
+
const authMocks = createAuthMocks()
|
|
97
|
+
|
|
98
|
+
beforeAll(() => {
|
|
99
|
+
fsMocks.setupFsMocks()
|
|
100
|
+
dbMocks.setupMocks()
|
|
101
|
+
authMocks.setupMocks()
|
|
102
|
+
authMocks.setupDefaultImplementations()
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
fsMocks.resetFsMocks()
|
|
107
|
+
dbMocks.resetMocks()
|
|
108
|
+
authMocks.resetMocks()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('should use the mocks', () => {
|
|
112
|
+
// Configure custom responses
|
|
113
|
+
fsMocks.mockReadFile.mockResolvedValue('test content')
|
|
114
|
+
dbMocks.mockExecuteTakeFirst.mockResolvedValue({ id: 1, name: 'User' })
|
|
115
|
+
|
|
116
|
+
// Your test code here
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Complete example
|
|
122
|
+
|
|
123
|
+
Check the example file included in your project: `templates/tests/test-utils.example.test.ts`.
|
|
124
|
+
|
|
125
|
+
## 📁 Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
test-utils/
|
|
129
|
+
├── index.ts # Re-exports all generic mocks
|
|
130
|
+
├── fs-mocks.ts # Mocks for filesystem (fs/promises)
|
|
131
|
+
├── kysely-mocks.ts # Mocks for Kysely ORM and PostgreSQL
|
|
132
|
+
├── radix-mocks.tsx # Mocks for Radix UI components
|
|
133
|
+
├── rainbowkit-mocks.ts # Mocks for authentication (RainbowKit, Wagmi, NextAuth, SIWE)
|
|
134
|
+
├── viem-mocks.ts # Mocks for blockchain client Viem
|
|
135
|
+
└── i18n-mock.ts # Mocks for i18n module
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> **mpdj test-utils**: Mocks para los módulos blockchain de `@pasosdejesus/mpdj`
|
|
139
|
+
> (credenciales, deployments, ecosystem-addresses, slearn-info) están en
|
|
140
|
+
> `@pasosdejesus/mpdj/test-utils`. Ver [`packages/mpdj/src/test-utils/README.md`](../../mpdj/src/test-utils/README.md).
|
|
141
|
+
|
|
142
|
+
## 🧪 Available Modules
|
|
143
|
+
|
|
144
|
+
### 1. `fs-mocks.ts` – Filesystem
|
|
145
|
+
|
|
146
|
+
**Purpose:** Mock `fs/promises` and `node:fs/promises` modules for tests that read files.
|
|
147
|
+
|
|
148
|
+
**Functions:**
|
|
149
|
+
- `createFsMocks(options?)`: Creates configurable mocks with custom content or errors.
|
|
150
|
+
|
|
151
|
+
**Usage:**
|
|
152
|
+
```typescript
|
|
153
|
+
import { createFsMocks } from '@pasosdejesus/m/test-utils/fs-mocks'
|
|
154
|
+
|
|
155
|
+
const fsMocks = createFsMocks({
|
|
156
|
+
readFileContent: '# Mock content',
|
|
157
|
+
readFileError: new Error('File not found')
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
beforeAll(() => {
|
|
161
|
+
fsMocks.setupFsMocks()
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
beforeEach(() => {
|
|
165
|
+
fsMocks.resetFsMocks()
|
|
166
|
+
fsMocks.setupCommonResponses()
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Important points:**
|
|
171
|
+
- Uses `vi.hoisted()` to avoid initialization issues
|
|
172
|
+
- Mocks both `fs/promises` and `node:fs/promises`
|
|
173
|
+
- Includes `setupFsMocks()`, `resetFsMocks()`, `setupCommonResponses()` functions
|
|
174
|
+
|
|
175
|
+
### 2. `kysely-mocks.ts` – Database ORM
|
|
176
|
+
|
|
177
|
+
**Purpose:** Mock Kysely and PostgreSQL for database access tests.
|
|
178
|
+
|
|
179
|
+
**Functions:**
|
|
180
|
+
- `createMockKysely(options?)`: Creates configurable mock Kysely instance with `MockKysely` class and mock functions
|
|
181
|
+
- `createMockDb()`: Flat mock DB object with chainable methods — simple, no class needed
|
|
182
|
+
- `apiDbMocks` / `libDbMocks`: Pre-configured instances for API routes and libraries
|
|
183
|
+
|
|
184
|
+
> ⚠️ **CRÍTICO**: `vi.mock()` debe estar a **module scope**. El método `setupMocks()`
|
|
185
|
+
> llama `vi.mock()` internamente pero vitest **no lo hoistea** porque está dentro de
|
|
186
|
+
> una factory en un módulo importado. Agrega los `vi.mock()` directamente:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// vitest.setup.ts — module scope
|
|
190
|
+
import { apiDbMocks } from '@pasosdejesus/m/test-utils/kysely-mocks'
|
|
191
|
+
const { mockExecuteTakeFirst, mockExecute, mockSqlExecute, mockSql, mockPgPool } = apiDbMocks
|
|
192
|
+
|
|
193
|
+
class GlobalMockKysely {
|
|
194
|
+
selectFrom() { return this }
|
|
195
|
+
where() { return this }
|
|
196
|
+
selectAll() { return this }
|
|
197
|
+
select(..._args: any[]) { return this }
|
|
198
|
+
orderBy() { return this }
|
|
199
|
+
limit() { return this }
|
|
200
|
+
groupBy() { return this }
|
|
201
|
+
having() { return this }
|
|
202
|
+
leftJoin() { return this }
|
|
203
|
+
innerJoin() { return this }
|
|
204
|
+
insertInto() { return this }
|
|
205
|
+
values() { return this }
|
|
206
|
+
returningAll() { return this }
|
|
207
|
+
updateTable() { return this }
|
|
208
|
+
set() { return this }
|
|
209
|
+
deleteFrom() { return this }
|
|
210
|
+
with() { return this }
|
|
211
|
+
onConflict() { return this }
|
|
212
|
+
doNothing() { return this }
|
|
213
|
+
executeTakeFirst() { return mockExecuteTakeFirst() }
|
|
214
|
+
executeTakeFirstOrThrow() { return mockExecuteTakeFirst() }
|
|
215
|
+
execute() { return mockExecute() }
|
|
216
|
+
transaction() {
|
|
217
|
+
return {
|
|
218
|
+
execute: async (callback: any) => {
|
|
219
|
+
return callback(new GlobalMockKysely())
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
getExecutor() {
|
|
224
|
+
return {
|
|
225
|
+
executeQuery: (query: any) => mockSqlExecute(query),
|
|
226
|
+
provideConnection: async (callback: any) => callback({}),
|
|
227
|
+
releaseConnection: () => {},
|
|
228
|
+
transformQuery: (query: any, transformer: any) => query,
|
|
229
|
+
compileQuery: (query: any, ctx: any) => ({ sql: '', parameters: [] }),
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
fn = {
|
|
233
|
+
countAll: vi.fn(() => ({ as: vi.fn(() => ({})) })),
|
|
234
|
+
sum: vi.fn(() => ({ as: vi.fn(() => ({})) })),
|
|
235
|
+
avg: vi.fn(() => ({ as: vi.fn(() => ({})) })),
|
|
236
|
+
max: vi.fn(() => ({ as: vi.fn(() => ({})) })),
|
|
237
|
+
min: vi.fn(() => ({ as: vi.fn(() => ({})) })),
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
vi.mock('kysely', () => ({
|
|
241
|
+
Kysely: GlobalMockKysely,
|
|
242
|
+
PostgresDialect: vi.fn(),
|
|
243
|
+
sql: mockSql,
|
|
244
|
+
}))
|
|
245
|
+
vi.mock('pg', () => ({ Pool: mockPgPool }))
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**`createMockDb()` — alternativa simple:**
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import { createMockDb } from '@pasosdejesus/m/test-utils'
|
|
252
|
+
|
|
253
|
+
let mockDb: ReturnType<typeof createMockDb>
|
|
254
|
+
beforeEach(() => { mockDb = createMockDb() })
|
|
255
|
+
|
|
256
|
+
vi.mock('@/.config/kysely-db', () => ({
|
|
257
|
+
newKyselyPostgresql: vi.fn(() => mockDb),
|
|
258
|
+
}))
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Configurable options (para `createMockKysely`):**
|
|
262
|
+
- `executeTakeFirst`, `execute`, `sqlExecute`: Custom implementations
|
|
263
|
+
- `configPath`: **Deprecated.** No funciona por hoisting de `vi.mock()`.
|
|
264
|
+
- `skipConfigMock`: Si `true`, no mockea el módulo de config.
|
|
265
|
+
|
|
266
|
+
**Usage:**
|
|
267
|
+
```typescript
|
|
268
|
+
import { createMockKysely } from '@pasosdejesus/m/test-utils/kysely-mocks'
|
|
269
|
+
|
|
270
|
+
const dbMocks = createMockKysely()
|
|
271
|
+
|
|
272
|
+
beforeEach(() => {
|
|
273
|
+
dbMocks.resetMocks()
|
|
274
|
+
dbMocks.setupCommonResponses()
|
|
275
|
+
// Configure specific responses
|
|
276
|
+
dbMocks.mockExecuteTakeFirst.mockResolvedValue({ id: 1 })
|
|
277
|
+
})
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Important points:**
|
|
281
|
+
- Complete Kysely mock with fluent query builder (`selectFrom().where().execute()`)
|
|
282
|
+
- Includes mock for `sql` with `val()` method for template tags, `execute()` for
|
|
283
|
+
execution, and `as()` for aliases: `mockSql().as('alias')` returns `{}`
|
|
284
|
+
- Mock for `pg.Pool` of PostgreSQL
|
|
285
|
+
- **Lesson learned:** The `sql.val()` method is crucial for queries using template tags
|
|
286
|
+
|
|
287
|
+
### 3. `radix-mocks.tsx` – UI Components
|
|
288
|
+
|
|
289
|
+
**Purpose:** Mock Radix UI components for React component tests.
|
|
290
|
+
|
|
291
|
+
**Included mocks:**
|
|
292
|
+
- `portalMock`, `popoverMock`, `menubarMock`, `dropdownMenuMock`
|
|
293
|
+
- `dialogMock`, `toastMock`, `tooltipMock`, `accordionMock`
|
|
294
|
+
- `scrollAreaMock`, `tabsMock`, and common components (`Slot`, `Label`, `Separator`)
|
|
295
|
+
|
|
296
|
+
**Usage:**
|
|
297
|
+
```typescript
|
|
298
|
+
// Import at the beginning of test files (before importing components)
|
|
299
|
+
import '@pasosdejesus/m/test-utils/radix-mocks'
|
|
300
|
+
|
|
301
|
+
// Radix components are now mocked with simplified versions
|
|
302
|
+
// that include data-testid for test selection
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Important points:**
|
|
306
|
+
- All mocks use `React.forwardRef` for compatibility
|
|
307
|
+
- Include `data-testid` for easy test selection
|
|
308
|
+
- **Lesson learned:** Some components like `ScrollArea` render multiple elements with the same `data-testid`; use `getAllByTestId` and select the appropriate element
|
|
309
|
+
- **Lesson learned:** Components using `Portal` must be mocked to render children directly
|
|
310
|
+
|
|
311
|
+
### 4. `rainbowkit-mocks.ts` – Web3 Authentication
|
|
312
|
+
|
|
313
|
+
**Purpose:** Mock authentication with RainbowKit, Wagmi, NextAuth and Sign-In With Ethereum (SIWE).
|
|
314
|
+
|
|
315
|
+
**Functions:**
|
|
316
|
+
- `createAuthMocks(config?)`: Creates configurable mocks
|
|
317
|
+
- `apiAuthMocks`: Pre-configured instance for API routes
|
|
318
|
+
|
|
319
|
+
**Configuration (`AuthMockConfig`):**
|
|
320
|
+
- `address`, `isConnected`, `sessionData`, `csrfToken`, `siweVerificationSuccess`
|
|
321
|
+
- `chainId`: Chain ID (default: 1)
|
|
322
|
+
- `mockAxios`, `mockWagmi`, `mockSiwe`, `mockNextAuth`: Enable/disable specific mocks
|
|
323
|
+
- `axiosMock`: Custom implementations for axios methods
|
|
324
|
+
|
|
325
|
+
**Usage:**
|
|
326
|
+
```typescript
|
|
327
|
+
import { createAuthMocks } from '@pasosdejesus/m/test-utils/rainbowkit-mocks'
|
|
328
|
+
|
|
329
|
+
const authMocks = createAuthMocks({
|
|
330
|
+
address: '0x123...',
|
|
331
|
+
chainId: 8453, // Base chain
|
|
332
|
+
mockAxios: true,
|
|
333
|
+
axiosMock: {
|
|
334
|
+
post: vi.fn().mockResolvedValue({ data: { success: true } })
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
beforeAll(() => {
|
|
339
|
+
authMocks.setupMocks()
|
|
340
|
+
authMocks.setupDefaultImplementations()
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
beforeEach(() => {
|
|
344
|
+
authMocks.resetMocks()
|
|
345
|
+
// Update dynamic configuration
|
|
346
|
+
authMocks.updateConfig({ isConnected: false })
|
|
347
|
+
})
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Important points:**
|
|
351
|
+
- **Lesson learned:** Some components use `axios.post` while others use `fetch`; mock both appropriately
|
|
352
|
+
- **Lesson learned:** User scores come from APIs, not from `useSession().data.user`; mock `fetch` responses correctly
|
|
353
|
+
- **Lesson learned:** Configure `chainId` correctly for multi-chain tests
|
|
354
|
+
- Includes `updateConfig()` function for dynamic changes during tests
|
|
355
|
+
|
|
356
|
+
### 5. `viem-mocks.ts` – Blockchain Client
|
|
357
|
+
|
|
358
|
+
**Purpose:** Mock Viem for blockchain interactions.
|
|
359
|
+
|
|
360
|
+
**Mocks:**
|
|
361
|
+
- `viemMocks`: `createPublicClient`, `createWalletClient`, `getContract`, `encodeFunctionData`, etc.
|
|
362
|
+
- `viemChainsMocks`: Object with mock chains (`celo`, `celoSepolia` by default)
|
|
363
|
+
|
|
364
|
+
**Usage:**
|
|
365
|
+
```typescript
|
|
366
|
+
import { viemMocks, viemChainsMocks } from '@pasosdejesus/m/test-utils/viem-mocks'
|
|
367
|
+
|
|
368
|
+
// Extend available chains
|
|
369
|
+
viemChainsMocks.ethereum = {}
|
|
370
|
+
viemChainsMocks.base = {}
|
|
371
|
+
|
|
372
|
+
// Use in tests
|
|
373
|
+
viemMocks.createPublicClient.mockReturnValue({ ... })
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Important points:**
|
|
377
|
+
- Mock chains are extensible; add new chains as needed
|
|
378
|
+
- **Lesson learned:** Some functions like `privateKeyToAccount` and `formatUnits` are necessary for transaction tests
|
|
379
|
+
|
|
380
|
+
## 🚀 Complete Usage Examples
|
|
381
|
+
|
|
382
|
+
### Configuration for API Route Tests
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
import { createMockKysely, createAuthMocks } from '@pasosdejesus/m/test-utils'
|
|
386
|
+
|
|
387
|
+
// Global setup
|
|
388
|
+
const dbMocks = createMockKysely({ skipConfigMock: true })
|
|
389
|
+
const authMocks = createAuthMocks({ mockAxios: false })
|
|
390
|
+
|
|
391
|
+
beforeAll(() => {
|
|
392
|
+
dbMocks.setupMocks()
|
|
393
|
+
authMocks.setupMocks()
|
|
394
|
+
authMocks.setupDefaultImplementations()
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
beforeEach(() => {
|
|
398
|
+
dbMocks.resetMocks()
|
|
399
|
+
authMocks.resetMocks()
|
|
400
|
+
// Test-specific configurations
|
|
401
|
+
dbMocks.mockExecuteTakeFirst.mockResolvedValue({ id: 1 })
|
|
402
|
+
authMocks.updateConfig({ address: '0xtest...' })
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
afterAll(() => {
|
|
406
|
+
vi.clearAllMocks()
|
|
407
|
+
})
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Configuration for Component Tests
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
import '@pasosdejesus/m/test-utils/radix-mocks'
|
|
414
|
+
import { createAuthMocks } from '@pasosdejesus/m/test-utils/rainbowkit-mocks'
|
|
415
|
+
import { render, screen } from '@testing-library/react'
|
|
416
|
+
|
|
417
|
+
const authMocks = createAuthMocks({
|
|
418
|
+
mockAxios: false,
|
|
419
|
+
mockSiwe: false,
|
|
420
|
+
mockNextAuth: true
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
beforeAll(() => {
|
|
424
|
+
authMocks.setupMocks()
|
|
425
|
+
authMocks.setupDefaultImplementations()
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
test('renders component with wallet connection', () => {
|
|
429
|
+
authMocks.updateConfig({ isConnected: true })
|
|
430
|
+
render(<MyComponent />)
|
|
431
|
+
expect(screen.getByText('Connected')).toBeInTheDocument()
|
|
432
|
+
})
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## 📝 Important Lessons Learned
|
|
436
|
+
|
|
437
|
+
### 1. **Import order**
|
|
438
|
+
Radix UI mocks must be imported **before** importing any components that use them. Place `import '@pasosdejesus/m/test-utils/radix-mocks'` at the beginning of test files.
|
|
439
|
+
|
|
440
|
+
### 2. **Multiple elements with same testid**
|
|
441
|
+
Components like `ScrollArea` render multiple elements with the same `data-testid`. Use `getAllByTestId` and select the appropriate element.
|
|
442
|
+
|
|
443
|
+
### 3. **axios vs fetch**
|
|
444
|
+
Some components use `axios` while others use native `fetch`. Mock both as appropriate:
|
|
445
|
+
- Components: generally use `fetch` for initial data
|
|
446
|
+
- Handlers: may use `axios.post` for updates
|
|
447
|
+
|
|
448
|
+
### 4. **User scores**
|
|
449
|
+
User scores (`learningscore`, `profilescore`) come from APIs (`fetch` responses), not from `useSession().data.user`. Mock `fetch` responses correctly.
|
|
450
|
+
|
|
451
|
+
### 5. **Dynamic configuration**
|
|
452
|
+
Use `updateConfig()` to change authentication state during tests (e.g., simulate disconnection).
|
|
453
|
+
|
|
454
|
+
### 6. **SQL template tags**
|
|
455
|
+
The Kysely mock must include `sql.val()` for queries using template tags like ```sql`SELECT * FROM table` ``.
|
|
456
|
+
|
|
457
|
+
### 7. **Error handling**
|
|
458
|
+
Configure mocks to simulate errors (e.g., `mockRejectedValue`) to test error flows.
|
|
459
|
+
|
|
460
|
+
### 8. **`vi.mock` hoisting in Vitest (CRÍTICO)**
|
|
461
|
+
`vi.mock` calls are hoisted to the top of the **file being transformed by vitest**. NO se hoistean desde funciones dentro de módulos importados. Ejemplo:
|
|
462
|
+
```typescript
|
|
463
|
+
// ❌ NO FUNCIONA — el vi.mock está dentro de setupMocks() en un módulo importado
|
|
464
|
+
import { apiDbMocks } from '@pasosdejesus/m/test-utils'
|
|
465
|
+
apiDbMocks.setupMocks() // vi.mock('kysely') interno NO se aplica
|
|
466
|
+
|
|
467
|
+
// ✅ FUNCIONA — vi.mock() a module scope del archivo que vitest transforma
|
|
468
|
+
vi.mock('kysely', () => ({ Kysely: MockKysely, PostgresDialect: vi.fn(), sql: mockSql }))
|
|
469
|
+
```
|
|
470
|
+
Esto aplica a TODOS los `setupMocks()` de los test-utils. Para usar `apiDbMocks` correctamente, agrega el `vi.mock()` a module scope en tu `vitest.setup.ts` (ver ejemplo en §2).
|
|
471
|
+
|
|
472
|
+
### 9. **Variables captured in closures**
|
|
473
|
+
When using `vi.hoisted`, external variables must be captured before the hoisted function. Example:
|
|
474
|
+
```typescript
|
|
475
|
+
// CORRECT: capture before vi.hoisted
|
|
476
|
+
const capturedVar = externalVar
|
|
477
|
+
const mocks = vi.hoisted(() => {
|
|
478
|
+
// Use capturedVar, not externalVar
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
// INCORRECT: external variable not accessible
|
|
482
|
+
const mocks = vi.hoisted(() => {
|
|
483
|
+
// ReferenceError: externalVar is not defined
|
|
484
|
+
})
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### 10. **Mocking modules with dynamic paths**
|
|
488
|
+
`vi.mock` doesn't accept dynamic paths (variables) due to hoisting. To mock modules with configurable paths:
|
|
489
|
+
1. Use string literal and configure alias in `vite.config.ts`
|
|
490
|
+
2. Or create multiple mocks for different paths
|
|
491
|
+
3. Or disable the mock (`skipConfigMock: true`) and mock manually
|
|
492
|
+
|
|
493
|
+
### 11. **Recent common errors and solutions**
|
|
494
|
+
- **`ReferenceError: configPath is not defined`**: Caused by using variable in `vi.mock`. Solution: use string literal `'@/.config/kysely.config'`.
|
|
495
|
+
- **`ReferenceError: axiosMock is not defined`**: Variable not captured in closure. Solution: capture `axiosMock` before `vi.hoisted`.
|
|
496
|
+
- **`ReferenceError: path is not defined`**: Similar to `configPath`, variable not accessible in `vi.mock` scope.
|
|
497
|
+
|
|
498
|
+
### 12. **Import order for module under test**
|
|
499
|
+
When testing modules that depend on mocked dependencies, import the module **after** setting up mocks. This ensures that the module receives the mocked versions. Example from `queries.test.ts`:
|
|
500
|
+
```typescript
|
|
501
|
+
// 1. Setup mocks first
|
|
502
|
+
vi.mock('kysely', () => ({ Kysely: libDbMocks.MockKysely, ... }))
|
|
503
|
+
// 2. Then import the module
|
|
504
|
+
import * as metricsQueries from '../queries'
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 13. **Pre-configured mock instances**
|
|
508
|
+
The library provides pre-configured instances for common use cases:
|
|
509
|
+
- `libDbMocks` and `apiDbMocks` for Kysely (configured for library vs API route contexts)
|
|
510
|
+
- `apiAuthMocks` for authentication in API routes
|
|
511
|
+
Use these to avoid repetitive configuration. Example:
|
|
512
|
+
```typescript
|
|
513
|
+
import { apiDbMocks } from '@pasosdejesus/m/test-utils/kysely-mocks'
|
|
514
|
+
const { mockExecuteTakeFirst, setupMocks, resetMocks } = apiDbMocks
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### 14. **React version alignment**
|
|
518
|
+
Ensure that React versions are consistent between the test utilities package and the consuming project. The `@pasosdejesus/m` package uses React 19 as a peer dependency. If your project uses a different version, you may encounter errors like "A React Element from an older version of React was rendered".
|
|
519
|
+
|
|
520
|
+
### 15. **Global React setup for mocks**
|
|
521
|
+
When using Radix UI mocks or other React-based mocks in Vitest setup files, set `global.React = React` before importing the mocks to ensure proper React instance sharing. This is especially important when mocks are used in `vitest.setup.ts`.
|
|
522
|
+
|
|
523
|
+
## 🔧 Configuration for Other Projects
|
|
524
|
+
|
|
525
|
+
These utilities can be used in other projects with the following adaptations:
|
|
526
|
+
|
|
527
|
+
### 1. **Kysely Configuration**
|
|
528
|
+
If the project uses a different path for Kysely configuration:
|
|
529
|
+
```typescript
|
|
530
|
+
// ⚠️ configPath currently non-functional due to vi.mock hoisting
|
|
531
|
+
// For different paths, configure aliases in Vite or mock manually
|
|
532
|
+
createMockKysely({ skipConfigMock: true }) // And mock the module manually
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### 2. **Blockchain Chains**
|
|
536
|
+
Extend available chains in `viemChainsMocks`:
|
|
537
|
+
```typescript
|
|
538
|
+
import { viemChainsMocks } from '@pasosdejesus/m/test-utils/viem-mocks'
|
|
539
|
+
viemChainsMocks.ethereum = {}
|
|
540
|
+
viemChainsMocks.polygon = {}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### 3. **Radix UI Components**
|
|
544
|
+
If using Radix components not included, extend `radix-mocks.tsx`:
|
|
545
|
+
```typescript
|
|
546
|
+
// In test setup
|
|
547
|
+
vi.mock('@radix-ui/react-slider', () => ({
|
|
548
|
+
Root: /* mock implementation */
|
|
549
|
+
}))
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### 4. **Environment variables**
|
|
553
|
+
Ensure required environment variables are defined in tests:
|
|
554
|
+
```typescript
|
|
555
|
+
process.env.NEXT_PUBLIC_API_URL = 'http://test.example.com'
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### 5. **Project-specific modules**
|
|
559
|
+
For mocking project‑specific internal modules, follow the pattern used in `learn.tg`'s `learn‑tg‑mocks.ts`:
|
|
560
|
+
1. Use `vi.hoisted()` to create mock objects that can be referenced in `vi.mock()` calls.
|
|
561
|
+
2. Export factory functions that return those mocks for test‑time configuration.
|
|
562
|
+
3. Provide a `setup*Mocks()` function that calls `vi.mock` for all related modules.
|
|
563
|
+
|
|
564
|
+
Example:
|
|
565
|
+
```typescript
|
|
566
|
+
// my‑project‑mocks.ts
|
|
567
|
+
import { vi } from 'vitest'
|
|
568
|
+
|
|
569
|
+
const myModuleMocks = vi.hoisted(() => ({
|
|
570
|
+
myFunction: vi.fn(),
|
|
571
|
+
myConstant: 'test',
|
|
572
|
+
}))
|
|
573
|
+
|
|
574
|
+
export function setupMyMocks() {
|
|
575
|
+
vi.mock('@/lib/my‑module', () => myModuleMocks)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export function getMyMocks() {
|
|
579
|
+
return myModuleMocks
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## 🤝 Contribution
|
|
584
|
+
|
|
585
|
+
The utilities are designed to be part of `@pasosdeJesus/m`. To contribute:
|
|
586
|
+
|
|
587
|
+
1. **Maintain compatibility**: Breaking changes must be versioned
|
|
588
|
+
2. **Document**: Update this documentation with new features
|
|
589
|
+
3. **Test**: Ensure utilities work across multiple projects
|
|
590
|
+
4. **Christian principles**: Work with diligence, humility, and love (Colossians 3:23)
|
|
591
|
+
|
|
592
|
+
## 🚀 Integration with Existing Projects
|
|
593
|
+
|
|
594
|
+
These utilities are now part of the `@pasosdeJesus/m` package and ready to use. They have been successfully integrated into the `learn.tg` project, serving as a reference implementation.
|
|
595
|
+
|
|
596
|
+
### Using with Project-Specific Mocks
|
|
597
|
+
|
|
598
|
+
In real projects, you'll often combine generic mocks with project-specific mocks. Here's how `learn.tg` structures this:
|
|
599
|
+
|
|
600
|
+
1. **Generic mocks** (from `@pasosdejesus/m/test-utils`): Mock cross-cutting concerns (database, authentication, UI components, blockchain).
|
|
601
|
+
2. **Project-specific mocks** (in `@/test-utils/`): Mock internal modules unique to the project.
|
|
602
|
+
|
|
603
|
+
**Example: `vitest.setup.ts` in learn.tg**
|
|
604
|
+
```typescript
|
|
605
|
+
import '@pasosdejesus/m/test-utils/radix-mocks';
|
|
606
|
+
import { apiAuthMocks } from '@pasosdejesus/m/test-utils/rainbowkit-mocks';
|
|
607
|
+
|
|
608
|
+
// Extract mocks from apiAuthMocks for direct use
|
|
609
|
+
const { mocks, setupDefaultImplementations } = apiAuthMocks;
|
|
610
|
+
setupDefaultImplementations();
|
|
611
|
+
|
|
612
|
+
// Setup vi.mock for various modules using the provided mocks
|
|
613
|
+
vi.mock('@rainbow-me/rainbowkit', () => ({ ... }));
|
|
614
|
+
vi.mock('wagmi', async (importOriginal) => ({ ... }));
|
|
615
|
+
vi.mock('next-auth/react', () => ({
|
|
616
|
+
useSession: () => mocks.mockUseSession(),
|
|
617
|
+
getCsrfToken: () => mocks.mockGetCsrfToken(),
|
|
618
|
+
}));
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
**Example: Test file combining generic and project mocks**
|
|
622
|
+
```typescript
|
|
623
|
+
import { apiDbMocks } from '@pasosdejesus/m/test-utils/kysely-mocks';
|
|
624
|
+
import { setupApiMocks } from '@/test-utils/learn-tg-mocks';
|
|
625
|
+
|
|
626
|
+
beforeAll(() => {
|
|
627
|
+
apiDbMocks.setupMocks();
|
|
628
|
+
setupApiMocks(); // Sets up project-specific mocks
|
|
629
|
+
});
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
## 📄 License
|
|
633
|
+
|
|
634
|
+
Part of `@pasosdeJesus/m` – Utilities for "Pasos de Jesús" projects.
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
*"For God has not given us a spirit of timidity, but of power, love, and self-discipline" (2 Timothy 1:7)*
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Util — Shared CLI Utilities
|
|
2
|
+
|
|
3
|
+
Shared helpers used across all `../tasks/` command implementations.
|
|
4
|
+
|
|
5
|
+
## Exports
|
|
6
|
+
|
|
7
|
+
| File | Export | Purpose |
|
|
8
|
+
|------|--------|---------|
|
|
9
|
+
| `cli-parser.ts` | `parseArgv()`, `parseFlags()` | Minimal CLI argument parser (replaced Commander.js); `parseFlags` handles --flag parsing for multi-command CLI |
|
|
10
|
+
| `colors.ts` | `problem()`, `info()`, `success()`, `warn()` | Colored console output with consistent formatting |
|
|
11
|
+
| `locale.ts` | `detectLocale()`, `setLocale()` | System locale detection via `LANG` env var + override setter |
|
|
12
|
+
| `i18n.ts` | *(removed)* | Former `getCliT()` wrapper. Replaced by `createTranslator` in `../i18n/` — translations are now inline per-file in each `../tasks/*.ts` |
|
|
13
|
+
|
|
14
|
+
## Why a custom CLI parser
|
|
15
|
+
|
|
16
|
+
Commander.js interfered with `stdin`/`stdout` handling for interactive commands
|
|
17
|
+
(`db:console`, `m:update`). The custom parser gives full control over the
|
|
18
|
+
process lifecycle. See `ARCHITECTURE.md` §2.1 for details.
|