@qlover/create-app 1.1.0 → 2.0.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/CHANGELOG.md +28 -0
- package/dist/index.cjs +9 -9
- package/dist/index.js +9 -9
- package/package.json +3 -2
- package/dist/configs/_common/.editorconfig +0 -23
- package/dist/configs/_common/.env.template +0 -13
- package/dist/configs/_common/.gitattributes +0 -2
- package/dist/configs/_common/.github/workflows/general-check.yml +0 -41
- package/dist/configs/_common/.github/workflows/release.yml +0 -81
- package/dist/configs/_common/.gitignore.template +0 -64
- package/dist/configs/_common/.husky/commit-msg +0 -3
- package/dist/configs/_common/.husky/pre-commit +0 -3
- package/dist/configs/_common/.prettierignore +0 -17
- package/dist/configs/_common/.prettierrc.js +0 -7
- package/dist/configs/_common/.vscode/extensions.json +0 -9
- package/dist/configs/_common/.vscode/react.code-snippets +0 -19
- package/dist/configs/_common/.vscode/settings.json +0 -16
- package/dist/configs/_common/commitlint.config.js +0 -10
- package/dist/configs/_common/package.json.template +0 -75
- package/dist/configs/node-lib/eslint.config.js +0 -50
- package/dist/templates/next-app/.env.template +0 -25
- package/dist/templates/next-app/.prettierignore +0 -58
- package/dist/templates/next-app/README.en.md +0 -130
- package/dist/templates/next-app/README.md +0 -130
- package/dist/templates/next-app/config/IOCIdentifier.ts +0 -74
- package/dist/templates/next-app/config/Identifier/api.ts +0 -41
- package/dist/templates/next-app/config/Identifier/common/admint.table.ts +0 -69
- package/dist/templates/next-app/config/Identifier/common/common.ts +0 -90
- package/dist/templates/next-app/config/Identifier/common/index.ts +0 -3
- package/dist/templates/next-app/config/Identifier/common/validators.ts +0 -34
- package/dist/templates/next-app/config/Identifier/index.ts +0 -3
- package/dist/templates/next-app/config/Identifier/pages/index.ts +0 -7
- package/dist/templates/next-app/config/Identifier/pages/page.about.ts +0 -20
- package/dist/templates/next-app/config/Identifier/pages/page.admin.home.ts +0 -27
- package/dist/templates/next-app/config/Identifier/pages/page.admin.locales.ts +0 -266
- package/dist/templates/next-app/config/Identifier/pages/page.admin.user.ts +0 -293
- package/dist/templates/next-app/config/Identifier/pages/page.home.ts +0 -56
- package/dist/templates/next-app/config/Identifier/pages/page.login.ts +0 -159
- package/dist/templates/next-app/config/Identifier/pages/page.register.ts +0 -177
- package/dist/templates/next-app/config/adminNavs.ts +0 -19
- package/dist/templates/next-app/config/common.ts +0 -43
- package/dist/templates/next-app/config/cookies.ts +0 -23
- package/dist/templates/next-app/config/i18n/AboutI18n.ts +0 -14
- package/dist/templates/next-app/config/i18n/HomeI18n.ts +0 -24
- package/dist/templates/next-app/config/i18n/PageI18nInterface.ts +0 -51
- package/dist/templates/next-app/config/i18n/admin18n.ts +0 -75
- package/dist/templates/next-app/config/i18n/i18nConfig.ts +0 -16
- package/dist/templates/next-app/config/i18n/i18nKeyScheam.ts +0 -36
- package/dist/templates/next-app/config/i18n/index.ts +0 -7
- package/dist/templates/next-app/config/i18n/loginI18n.ts +0 -50
- package/dist/templates/next-app/config/i18n/register18n.ts +0 -44
- package/dist/templates/next-app/config/route.ts +0 -9
- package/dist/templates/next-app/config/theme.ts +0 -28
- package/dist/templates/next-app/docs/en/api.md +0 -387
- package/dist/templates/next-app/docs/en/component.md +0 -544
- package/dist/templates/next-app/docs/en/database.md +0 -496
- package/dist/templates/next-app/docs/en/development-guide.md +0 -727
- package/dist/templates/next-app/docs/en/env.md +0 -563
- package/dist/templates/next-app/docs/en/i18n.md +0 -287
- package/dist/templates/next-app/docs/en/index.md +0 -165
- package/dist/templates/next-app/docs/en/page.md +0 -457
- package/dist/templates/next-app/docs/en/project-structure.md +0 -176
- package/dist/templates/next-app/docs/en/router.md +0 -427
- package/dist/templates/next-app/docs/en/theme.md +0 -532
- package/dist/templates/next-app/docs/en/validator.md +0 -478
- package/dist/templates/next-app/docs/zh/api.md +0 -387
- package/dist/templates/next-app/docs/zh/component.md +0 -544
- package/dist/templates/next-app/docs/zh/database.md +0 -496
- package/dist/templates/next-app/docs/zh/development-guide.md +0 -727
- package/dist/templates/next-app/docs/zh/env.md +0 -563
- package/dist/templates/next-app/docs/zh/i18n.md +0 -287
- package/dist/templates/next-app/docs/zh/index.md +0 -165
- package/dist/templates/next-app/docs/zh/page.md +0 -457
- package/dist/templates/next-app/docs/zh/project-structure.md +0 -176
- package/dist/templates/next-app/docs/zh/router.md +0 -427
- package/dist/templates/next-app/docs/zh/theme.md +0 -532
- package/dist/templates/next-app/docs/zh/validator.md +0 -476
- package/dist/templates/next-app/eslint.config.mjs +0 -285
- package/dist/templates/next-app/make/generateLocales.ts +0 -32
- package/dist/templates/next-app/migrations/schema/LocalesSchema.ts +0 -15
- package/dist/templates/next-app/migrations/schema/UserSchema.ts +0 -38
- package/dist/templates/next-app/migrations/sql/1694244000000.sql +0 -21
- package/dist/templates/next-app/next.config.ts +0 -25
- package/dist/templates/next-app/package.json +0 -87
- package/dist/templates/next-app/postcss.config.mjs +0 -5
- package/dist/templates/next-app/public/favicon.ico +0 -0
- package/dist/templates/next-app/public/file.svg +0 -1
- package/dist/templates/next-app/public/globe.svg +0 -1
- package/dist/templates/next-app/public/locales/en.json +0 -182
- package/dist/templates/next-app/public/locales/zh.json +0 -182
- package/dist/templates/next-app/public/next.svg +0 -1
- package/dist/templates/next-app/public/vercel.svg +0 -1
- package/dist/templates/next-app/public/window.svg +0 -1
- package/dist/templates/next-app/src/app/[locale]/admin/AdminI18nProvider.tsx +0 -37
- package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +0 -42
- package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +0 -153
- package/dist/templates/next-app/src/app/[locale]/admin/page.tsx +0 -20
- package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +0 -67
- package/dist/templates/next-app/src/app/[locale]/auth/layout.tsx +0 -18
- package/dist/templates/next-app/src/app/[locale]/auth/login/LoginForm.tsx +0 -126
- package/dist/templates/next-app/src/app/[locale]/auth/login/page.tsx +0 -90
- package/dist/templates/next-app/src/app/[locale]/auth/page.tsx +0 -8
- package/dist/templates/next-app/src/app/[locale]/auth/register/RegisterForm.tsx +0 -197
- package/dist/templates/next-app/src/app/[locale]/auth/register/page.tsx +0 -90
- package/dist/templates/next-app/src/app/[locale]/layout.tsx +0 -63
- package/dist/templates/next-app/src/app/[locale]/not-found.tsx +0 -24
- package/dist/templates/next-app/src/app/[locale]/page.tsx +0 -98
- package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +0 -13
- package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +0 -13
- package/dist/templates/next-app/src/app/api/admin/locales/route.ts +0 -20
- package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +0 -13
- package/dist/templates/next-app/src/app/api/admin/users/route.ts +0 -20
- package/dist/templates/next-app/src/app/api/ai/completions/route.ts +0 -32
- package/dist/templates/next-app/src/app/api/auth/callback/route.ts +0 -11
- package/dist/templates/next-app/src/app/api/callback/route.ts +0 -49
- package/dist/templates/next-app/src/app/api/locales/json/route.ts +0 -33
- package/dist/templates/next-app/src/app/api/user/login/route.ts +0 -10
- package/dist/templates/next-app/src/app/api/user/logout/route.ts +0 -8
- package/dist/templates/next-app/src/app/api/user/register/route.ts +0 -11
- package/dist/templates/next-app/src/app/manifest.ts +0 -16
- package/dist/templates/next-app/src/app/robots.txt +0 -2
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +0 -28
- package/dist/templates/next-app/src/base/cases/AppConfig.ts +0 -40
- package/dist/templates/next-app/src/base/cases/Datetime.ts +0 -18
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +0 -57
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +0 -116
- package/dist/templates/next-app/src/base/cases/InversifyContainer.ts +0 -45
- package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +0 -32
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +0 -77
- package/dist/templates/next-app/src/base/cases/ResourceState.ts +0 -17
- package/dist/templates/next-app/src/base/cases/RouterService.ts +0 -52
- package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +0 -73
- package/dist/templates/next-app/src/base/cases/TranslateI18nUtil.ts +0 -53
- package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +0 -212
- package/dist/templates/next-app/src/base/port/AdminLayoutInterface.ts +0 -26
- package/dist/templates/next-app/src/base/port/AppApiInterface.ts +0 -36
- package/dist/templates/next-app/src/base/port/AppUserApiInterface.ts +0 -27
- package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +0 -25
- package/dist/templates/next-app/src/base/port/IOCInterface.ts +0 -33
- package/dist/templates/next-app/src/base/port/RouterInterface.ts +0 -11
- package/dist/templates/next-app/src/base/port/UserServiceInterface.ts +0 -25
- package/dist/templates/next-app/src/base/port/ZodBuilderInterface.ts +0 -8
- package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +0 -26
- package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +0 -42
- package/dist/templates/next-app/src/base/services/AppApiRequester.ts +0 -67
- package/dist/templates/next-app/src/base/services/AppUserGateway.ts +0 -110
- package/dist/templates/next-app/src/base/services/I18nService.ts +0 -87
- package/dist/templates/next-app/src/base/services/ResourceService.ts +0 -139
- package/dist/templates/next-app/src/base/services/UserService.ts +0 -68
- package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +0 -106
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +0 -87
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +0 -110
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +0 -52
- package/dist/templates/next-app/src/base/types/AppPageRouter.ts +0 -12
- package/dist/templates/next-app/src/base/types/PagesRouter.ts +0 -9
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +0 -76
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +0 -125
- package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +0 -50
- package/dist/templates/next-app/src/core/bootstraps/IocIdentifierTest.ts +0 -26
- package/dist/templates/next-app/src/core/bootstraps/PrintBootstrap.ts +0 -18
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +0 -68
- package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +0 -100
- package/dist/templates/next-app/src/core/globals.ts +0 -28
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +0 -80
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +0 -66
- package/dist/templates/next-app/src/i18n/loadMessages.ts +0 -103
- package/dist/templates/next-app/src/i18n/request.ts +0 -31
- package/dist/templates/next-app/src/i18n/routing.ts +0 -35
- package/dist/templates/next-app/src/lib/supabase/client.ts +0 -8
- package/dist/templates/next-app/src/lib/supabase/conts.ts +0 -2
- package/dist/templates/next-app/src/lib/supabase/proxy.ts +0 -84
- package/dist/templates/next-app/src/lib/supabase/server.ts +0 -38
- package/dist/templates/next-app/src/pages/[locale]/about.tsx +0 -61
- package/dist/templates/next-app/src/pages/_app.tsx +0 -50
- package/dist/templates/next-app/src/pages/_document.tsx +0 -13
- package/dist/templates/next-app/src/proxy.ts +0 -33
- package/dist/templates/next-app/src/server/AppErrorApi.ts +0 -10
- package/dist/templates/next-app/src/server/AppPageRouteParams.ts +0 -110
- package/dist/templates/next-app/src/server/AppSuccessApi.ts +0 -7
- package/dist/templates/next-app/src/server/NextApiServer.ts +0 -61
- package/dist/templates/next-app/src/server/PagesRouteParams.ts +0 -145
- package/dist/templates/next-app/src/server/PasswordEncrypt.ts +0 -18
- package/dist/templates/next-app/src/server/ServerAuth.ts +0 -81
- package/dist/templates/next-app/src/server/SupabaseBridge.ts +0 -262
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +0 -53
- package/dist/templates/next-app/src/server/controllers/AdminLocalesController.ts +0 -86
- package/dist/templates/next-app/src/server/controllers/AdminUserController.ts +0 -42
- package/dist/templates/next-app/src/server/controllers/LocalesController.ts +0 -36
- package/dist/templates/next-app/src/server/controllers/UserController.ts +0 -91
- package/dist/templates/next-app/src/server/port/AIControllerInterface.ts +0 -8
- package/dist/templates/next-app/src/server/port/AdminLocalesControllerInterface.ts +0 -21
- package/dist/templates/next-app/src/server/port/AdminUserControllerInterface.ts +0 -11
- package/dist/templates/next-app/src/server/port/CrentialTokenInterface.ts +0 -5
- package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +0 -36
- package/dist/templates/next-app/src/server/port/DBTableInterface.ts +0 -12
- package/dist/templates/next-app/src/server/port/LocalesControllerInterface.ts +0 -10
- package/dist/templates/next-app/src/server/port/LocalesRepositoryInterface.ts +0 -43
- package/dist/templates/next-app/src/server/port/PaginationInterface.ts +0 -6
- package/dist/templates/next-app/src/server/port/RouteParamsnHandlerInterface.ts +0 -18
- package/dist/templates/next-app/src/server/port/ServerAuthInterface.ts +0 -15
- package/dist/templates/next-app/src/server/port/ServerInterface.ts +0 -23
- package/dist/templates/next-app/src/server/port/UserRepositoryInterface.ts +0 -15
- package/dist/templates/next-app/src/server/port/UserServiceInterface.ts +0 -14
- package/dist/templates/next-app/src/server/port/ValidatorInterface.ts +0 -23
- package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +0 -216
- package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +0 -102
- package/dist/templates/next-app/src/server/services/AIService.ts +0 -45
- package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +0 -21
- package/dist/templates/next-app/src/server/services/AdminLocalesService.ts +0 -20
- package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +0 -137
- package/dist/templates/next-app/src/server/services/ApiUserService.ts +0 -29
- package/dist/templates/next-app/src/server/services/UserService.ts +0 -134
- package/dist/templates/next-app/src/server/validators/ExtendedExecutorError.ts +0 -6
- package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +0 -145
- package/dist/templates/next-app/src/server/validators/LoginValidator.ts +0 -82
- package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +0 -70
- package/dist/templates/next-app/src/server/validators/SignupVerifyValidator.ts +0 -68
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/_default.css +0 -280
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/dark.css +0 -233
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/index.css +0 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/pink.css +0 -246
- package/dist/templates/next-app/src/styles/css/antd-themes/index.css +0 -4
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/_default.css +0 -108
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/dark.css +0 -67
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/index.css +0 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/pink.css +0 -67
- package/dist/templates/next-app/src/styles/css/antd-themes/no-context.css +0 -34
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +0 -34
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +0 -31
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/index.css +0 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +0 -36
- package/dist/templates/next-app/src/styles/css/antd-themes/table/_default.css +0 -44
- package/dist/templates/next-app/src/styles/css/antd-themes/table/dark.css +0 -43
- package/dist/templates/next-app/src/styles/css/antd-themes/table/index.css +0 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/table/pink.css +0 -43
- package/dist/templates/next-app/src/styles/css/index.css +0 -6
- package/dist/templates/next-app/src/styles/css/page.css +0 -20
- package/dist/templates/next-app/src/styles/css/scrollbar.css +0 -34
- package/dist/templates/next-app/src/styles/css/tailwind.css +0 -5
- package/dist/templates/next-app/src/styles/css/themes/_default.css +0 -30
- package/dist/templates/next-app/src/styles/css/themes/dark.css +0 -30
- package/dist/templates/next-app/src/styles/css/themes/index.css +0 -3
- package/dist/templates/next-app/src/styles/css/themes/pink.css +0 -30
- package/dist/templates/next-app/src/styles/css/zIndex.css +0 -9
- package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +0 -150
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +0 -39
- package/dist/templates/next-app/src/uikit/components/ClientRootProvider.tsx +0 -64
- package/dist/templates/next-app/src/uikit/components/ClientSeo.tsx +0 -36
- package/dist/templates/next-app/src/uikit/components/ClinetRenderProvider.tsx +0 -42
- package/dist/templates/next-app/src/uikit/components/EditableCell.tsx +0 -118
- package/dist/templates/next-app/src/uikit/components/FeatureItem.tsx +0 -13
- package/dist/templates/next-app/src/uikit/components/IOCProvider.tsx +0 -34
- package/dist/templates/next-app/src/uikit/components/LocaleLink.tsx +0 -50
- package/dist/templates/next-app/src/uikit/components/With.tsx +0 -17
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportButton.tsx +0 -62
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +0 -28
- package/dist/templates/next-app/src/uikit/components/localesImportButton/import.module.css +0 -6
- package/dist/templates/next-app/src/uikit/components-app/AdminButton.tsx +0 -29
- package/dist/templates/next-app/src/uikit/components-app/AppBridge.tsx +0 -17
- package/dist/templates/next-app/src/uikit/components-app/AppRoutePage.tsx +0 -105
- package/dist/templates/next-app/src/uikit/components-app/AuthButton.tsx +0 -20
- package/dist/templates/next-app/src/uikit/components-app/LanguageSwitcher.tsx +0 -75
- package/dist/templates/next-app/src/uikit/components-app/LogoutButton.tsx +0 -45
- package/dist/templates/next-app/src/uikit/components-app/ThemeSwitcher.tsx +0 -144
- package/dist/templates/next-app/src/uikit/components-pages/LanguageSwitcher.tsx +0 -98
- package/dist/templates/next-app/src/uikit/components-pages/PagesRoutePage.tsx +0 -93
- package/dist/templates/next-app/src/uikit/context/IOCContext.ts +0 -25
- package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +0 -22
- package/dist/templates/next-app/src/uikit/hook/useIOC.ts +0 -37
- package/dist/templates/next-app/src/uikit/hook/useStrictEffect.ts +0 -32
- package/dist/templates/next-app/src/uikit/hook/useWarnTranslations.ts +0 -11
- package/dist/templates/next-app/src/uikit/utils/getHashParams.ts +0 -8
- package/dist/templates/next-app/src/uikit/utils/getHashVerifyEmailParams.ts +0 -42
- package/dist/templates/next-app/tailwind.config.ts +0 -8
- package/dist/templates/next-app/tsconfig.json +0 -39
- package/dist/templates/node-lib/__tests__/readJson.test.ts +0 -26
- package/dist/templates/node-lib/bin/test.js +0 -30
- package/dist/templates/node-lib/package.json +0 -66
- package/dist/templates/node-lib/rollup.config.js +0 -79
- package/dist/templates/node-lib/src/index.ts +0 -7
- package/dist/templates/node-lib/src/readJson.ts +0 -12
- package/dist/templates/node-lib/tsconfig.json +0 -23
- package/dist/templates/pack-app/README.md +0 -108
- package/dist/templates/pack-app/eslint.config.js +0 -97
- package/dist/templates/pack-app/fe-config.json +0 -35
- package/dist/templates/pack-app/package.json +0 -86
- package/dist/templates/pack-app/pnpm-workspace.yaml +0 -2
- package/dist/templates/pack-app/tsconfig.json +0 -9
- package/dist/templates/pack-app/tsconfig.test.json +0 -10
- package/dist/templates/pack-app/vite.config.ts +0 -14
- package/dist/templates/react-app/.env.template +0 -22
- package/dist/templates/react-app/.prettierignore +0 -17
- package/dist/templates/react-app/README.en.md +0 -274
- package/dist/templates/react-app/README.md +0 -273
- package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +0 -16
- package/dist/templates/react-app/__tests__/__mocks__/MockAppConfig.ts +0 -48
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +0 -17
- package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +0 -14
- package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +0 -38
- package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +0 -53
- package/dist/templates/react-app/__tests__/__mocks__/components/TestRouter.tsx +0 -46
- package/dist/templates/react-app/__tests__/__mocks__/components/index.ts +0 -12
- package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +0 -96
- package/dist/templates/react-app/__tests__/__mocks__/i18nextHttpBackend.ts +0 -110
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +0 -55
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +0 -74
- package/dist/templates/react-app/__tests__/setup/index.ts +0 -1
- package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +0 -64
- package/dist/templates/react-app/__tests__/src/App.structure.test.tsx +0 -115
- package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +0 -288
- package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +0 -226
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +0 -178
- package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +0 -181
- package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +0 -61
- package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +0 -177
- package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +0 -191
- package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +0 -245
- package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +0 -240
- package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +0 -242
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +0 -135
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +0 -74
- package/dist/templates/react-app/__tests__/src/main.test.tsx +0 -46
- package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +0 -97
- package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +0 -274
- package/dist/templates/react-app/config/IOCIdentifier.ts +0 -91
- package/dist/templates/react-app/config/Identifier/common/common.error.ts +0 -34
- package/dist/templates/react-app/config/Identifier/common/common.ts +0 -62
- package/dist/templates/react-app/config/Identifier/common/index.ts +0 -2
- package/dist/templates/react-app/config/Identifier/components/component.chatMessage.ts +0 -56
- package/dist/templates/react-app/config/Identifier/components/component.messageBaseList.ts +0 -103
- package/dist/templates/react-app/config/Identifier/index.ts +0 -2
- package/dist/templates/react-app/config/Identifier/pages/index.ts +0 -9
- package/dist/templates/react-app/config/Identifier/pages/page.about.ts +0 -189
- package/dist/templates/react-app/config/Identifier/pages/page.executor.ts +0 -275
- package/dist/templates/react-app/config/Identifier/pages/page.home.ts +0 -71
- package/dist/templates/react-app/config/Identifier/pages/page.identifiter.ts +0 -102
- package/dist/templates/react-app/config/Identifier/pages/page.jsonStorage.ts +0 -77
- package/dist/templates/react-app/config/Identifier/pages/page.login.ts +0 -162
- package/dist/templates/react-app/config/Identifier/pages/page.message.ts +0 -20
- package/dist/templates/react-app/config/Identifier/pages/page.register.ts +0 -159
- package/dist/templates/react-app/config/Identifier/pages/page.request.ts +0 -169
- package/dist/templates/react-app/config/app.router.ts +0 -338
- package/dist/templates/react-app/config/common.ts +0 -85
- package/dist/templates/react-app/config/feapi.mock.json +0 -34
- package/dist/templates/react-app/config/i18n/PageI18nInterface.ts +0 -53
- package/dist/templates/react-app/config/i18n/aboutI18n.ts +0 -42
- package/dist/templates/react-app/config/i18n/chatMessageI18n.ts +0 -17
- package/dist/templates/react-app/config/i18n/executorI18n.ts +0 -51
- package/dist/templates/react-app/config/i18n/homeI18n.ts +0 -24
- package/dist/templates/react-app/config/i18n/i18nConfig.ts +0 -30
- package/dist/templates/react-app/config/i18n/identifiter18n.ts +0 -30
- package/dist/templates/react-app/config/i18n/jsonStorage18n.ts +0 -27
- package/dist/templates/react-app/config/i18n/login18n.ts +0 -42
- package/dist/templates/react-app/config/i18n/messageBaseListI18n.ts +0 -22
- package/dist/templates/react-app/config/i18n/messageI18n.ts +0 -14
- package/dist/templates/react-app/config/i18n/notFoundI18n.ts +0 -34
- package/dist/templates/react-app/config/i18n/register18n.ts +0 -40
- package/dist/templates/react-app/config/i18n/request18n.ts +0 -41
- package/dist/templates/react-app/config/theme.ts +0 -21
- package/dist/templates/react-app/docs/en/bootstrap.md +0 -1891
- package/dist/templates/react-app/docs/en/components/chat-message-component.md +0 -320
- package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +0 -283
- package/dist/templates/react-app/docs/en/components/message-base-list-component.md +0 -171
- package/dist/templates/react-app/docs/en/development-guide.md +0 -1199
- package/dist/templates/react-app/docs/en/env.md +0 -1336
- package/dist/templates/react-app/docs/en/global.md +0 -509
- package/dist/templates/react-app/docs/en/i18n.md +0 -979
- package/dist/templates/react-app/docs/en/index.md +0 -802
- package/dist/templates/react-app/docs/en/ioc.md +0 -1365
- package/dist/templates/react-app/docs/en/playwright/e2e-tests.md +0 -321
- package/dist/templates/react-app/docs/en/playwright/index.md +0 -19
- package/dist/templates/react-app/docs/en/playwright/installation-summary.md +0 -332
- package/dist/templates/react-app/docs/en/playwright/overview.md +0 -222
- package/dist/templates/react-app/docs/en/playwright/quickstart.md +0 -325
- package/dist/templates/react-app/docs/en/playwright/reorganization-notes.md +0 -340
- package/dist/templates/react-app/docs/en/playwright/setup-complete.md +0 -290
- package/dist/templates/react-app/docs/en/playwright/testing-guide.md +0 -565
- package/dist/templates/react-app/docs/en/request.md +0 -423
- package/dist/templates/react-app/docs/en/router.md +0 -404
- package/dist/templates/react-app/docs/en/store.md +0 -1331
- package/dist/templates/react-app/docs/en/test-guide.md +0 -976
- package/dist/templates/react-app/docs/en/theme.md +0 -424
- package/dist/templates/react-app/docs/en/typescript-guide.md +0 -473
- package/dist/templates/react-app/docs/en/why-no-globals.md +0 -797
- package/dist/templates/react-app/docs/zh/bootstrap.md +0 -1891
- package/dist/templates/react-app/docs/zh/components/chat-message-component.md +0 -320
- package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +0 -283
- package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +0 -171
- package/dist/templates/react-app/docs/zh/development-guide.md +0 -1199
- package/dist/templates/react-app/docs/zh/env.md +0 -1336
- package/dist/templates/react-app/docs/zh/global.md +0 -511
- package/dist/templates/react-app/docs/zh/i18n.md +0 -979
- package/dist/templates/react-app/docs/zh/index.md +0 -786
- package/dist/templates/react-app/docs/zh/ioc.md +0 -1364
- package/dist/templates/react-app/docs/zh/playwright/e2e-tests.md +0 -321
- package/dist/templates/react-app/docs/zh/playwright/index.md +0 -19
- package/dist/templates/react-app/docs/zh/playwright/installation-summary.md +0 -332
- package/dist/templates/react-app/docs/zh/playwright/overview.md +0 -222
- package/dist/templates/react-app/docs/zh/playwright/quickstart.md +0 -325
- package/dist/templates/react-app/docs/zh/playwright/reorganization-notes.md +0 -340
- package/dist/templates/react-app/docs/zh/playwright/setup-complete.md +0 -290
- package/dist/templates/react-app/docs/zh/playwright/testing-guide.md +0 -565
- package/dist/templates/react-app/docs/zh/request.md +0 -427
- package/dist/templates/react-app/docs/zh/router.md +0 -408
- package/dist/templates/react-app/docs/zh/store.md +0 -1329
- package/dist/templates/react-app/docs/zh/test-guide.md +0 -976
- package/dist/templates/react-app/docs/zh/theme.md +0 -424
- package/dist/templates/react-app/docs/zh/typescript-guide.md +0 -473
- package/dist/templates/react-app/docs/zh/why-no-globals.md +0 -797
- package/dist/templates/react-app/e2e/App.spec.ts +0 -319
- package/dist/templates/react-app/e2e/fixtures/base.fixture.ts +0 -40
- package/dist/templates/react-app/e2e/main.spec.ts +0 -20
- package/dist/templates/react-app/e2e/utils/test-helpers.ts +0 -19
- package/dist/templates/react-app/eslint.config.mjs +0 -325
- package/dist/templates/react-app/index.html +0 -13
- package/dist/templates/react-app/makes/generateTs2LocalesOptions.ts +0 -26
- package/dist/templates/react-app/package.json +0 -125
- package/dist/templates/react-app/playwright.config.ts +0 -79
- package/dist/templates/react-app/postcss.config.js +0 -5
- package/dist/templates/react-app/public/locales/en/common.json +0 -235
- package/dist/templates/react-app/public/locales/zh/common.json +0 -235
- package/dist/templates/react-app/public/logo.svg +0 -1
- package/dist/templates/react-app/public/router-root/logo.svg +0 -1
- package/dist/templates/react-app/src/App.tsx +0 -35
- package/dist/templates/react-app/src/assets/react.svg +0 -1
- package/dist/templates/react-app/src/base/apis/AiApi.ts +0 -68
- package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +0 -29
- package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +0 -14
- package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +0 -86
- package/dist/templates/react-app/src/base/apis/feApi/FeApiType.ts +0 -21
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +0 -142
- package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +0 -14
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +0 -86
- package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +0 -70
- package/dist/templates/react-app/src/base/cases/AppConfig.ts +0 -123
- package/dist/templates/react-app/src/base/cases/DialogHandler.ts +0 -115
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +0 -64
- package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +0 -45
- package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +0 -23
- package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +0 -55
- package/dist/templates/react-app/src/base/cases/RequestLogger.ts +0 -80
- package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +0 -40
- package/dist/templates/react-app/src/base/cases/ResourceState.ts +0 -23
- package/dist/templates/react-app/src/base/cases/RouterLoader.ts +0 -173
- package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +0 -26
- package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +0 -23
- package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +0 -10
- package/dist/templates/react-app/src/base/port/IOCInterface.ts +0 -38
- package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +0 -21
- package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +0 -23
- package/dist/templates/react-app/src/base/port/RequestStatusInterface.ts +0 -5
- package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +0 -29
- package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +0 -20
- package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +0 -61
- package/dist/templates/react-app/src/base/services/I18nService.ts +0 -146
- package/dist/templates/react-app/src/base/services/IdentifierService.ts +0 -162
- package/dist/templates/react-app/src/base/services/RouteService.ts +0 -115
- package/dist/templates/react-app/src/base/services/UserBootstrap.ts +0 -45
- package/dist/templates/react-app/src/base/services/UserService.ts +0 -88
- package/dist/templates/react-app/src/base/types/Page.ts +0 -47
- package/dist/templates/react-app/src/base/types/deprecated-antd.d.ts +0 -60
- package/dist/templates/react-app/src/base/types/global.d.ts +0 -8
- package/dist/templates/react-app/src/core/IOC.ts +0 -28
- package/dist/templates/react-app/src/core/bootstraps/BootstrapClient.ts +0 -108
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +0 -54
- package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +0 -26
- package/dist/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +0 -14
- package/dist/templates/react-app/src/core/bootstraps/SaveAppInfo.ts +0 -28
- package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +0 -47
- package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +0 -142
- package/dist/templates/react-app/src/core/globals.ts +0 -47
- package/dist/templates/react-app/src/main.tsx +0 -19
- package/dist/templates/react-app/src/pages/404.tsx +0 -19
- package/dist/templates/react-app/src/pages/500.tsx +0 -18
- package/dist/templates/react-app/src/pages/NoRouteFound.tsx +0 -5
- package/dist/templates/react-app/src/pages/auth/Layout.tsx +0 -27
- package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +0 -166
- package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +0 -226
- package/dist/templates/react-app/src/pages/base/AboutPage.tsx +0 -123
- package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +0 -467
- package/dist/templates/react-app/src/pages/base/HomePage.tsx +0 -81
- package/dist/templates/react-app/src/pages/base/IdentifierPage.tsx +0 -117
- package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +0 -132
- package/dist/templates/react-app/src/pages/base/Layout.tsx +0 -20
- package/dist/templates/react-app/src/pages/base/MessagePage.tsx +0 -71
- package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +0 -18
- package/dist/templates/react-app/src/pages/base/RequestPage.tsx +0 -193
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/_default.css +0 -280
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/dark.css +0 -233
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/index.css +0 -3
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/pink.css +0 -246
- package/dist/templates/react-app/src/styles/css/antd-themes/index.css +0 -4
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/_default.css +0 -108
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/dark.css +0 -67
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/index.css +0 -3
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/pink.css +0 -67
- package/dist/templates/react-app/src/styles/css/antd-themes/no-context.css +0 -34
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/_default.css +0 -34
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/dark.css +0 -31
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/index.css +0 -3
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/pink.css +0 -36
- package/dist/templates/react-app/src/styles/css/antd-themes/table/_default.css +0 -44
- package/dist/templates/react-app/src/styles/css/antd-themes/table/dark.css +0 -43
- package/dist/templates/react-app/src/styles/css/antd-themes/table/index.css +0 -3
- package/dist/templates/react-app/src/styles/css/antd-themes/table/pink.css +0 -43
- package/dist/templates/react-app/src/styles/css/index.css +0 -6
- package/dist/templates/react-app/src/styles/css/page.css +0 -20
- package/dist/templates/react-app/src/styles/css/scrollbar.css +0 -34
- package/dist/templates/react-app/src/styles/css/tailwind.css +0 -5
- package/dist/templates/react-app/src/styles/css/themes/_default.css +0 -30
- package/dist/templates/react-app/src/styles/css/themes/dark.css +0 -30
- package/dist/templates/react-app/src/styles/css/themes/index.css +0 -3
- package/dist/templates/react-app/src/styles/css/themes/pink.css +0 -30
- package/dist/templates/react-app/src/styles/css/zIndex.css +0 -9
- package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +0 -72
- package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +0 -41
- package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +0 -22
- package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +0 -136
- package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +0 -35
- package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +0 -51
- package/dist/templates/react-app/src/uikit/components/BaseLayoutProvider.tsx +0 -44
- package/dist/templates/react-app/src/uikit/components/BaseRouteProvider.tsx +0 -21
- package/dist/templates/react-app/src/uikit/components/BaseRouteSeo.tsx +0 -18
- package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +0 -11
- package/dist/templates/react-app/src/uikit/components/ClientSeo.tsx +0 -62
- package/dist/templates/react-app/src/uikit/components/ComboProvider.tsx +0 -38
- package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +0 -78
- package/dist/templates/react-app/src/uikit/components/Loading.tsx +0 -49
- package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +0 -43
- package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +0 -58
- package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +0 -258
- package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +0 -19
- package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +0 -137
- package/dist/templates/react-app/src/uikit/components/With.tsx +0 -17
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +0 -205
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatRoot.tsx +0 -21
- package/dist/templates/react-app/src/uikit/components/chatMessage/FocusBar.tsx +0 -108
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +0 -282
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageItem.tsx +0 -102
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessagesList.tsx +0 -86
- package/dist/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +0 -42
- package/dist/templates/react-app/src/uikit/contexts/IOCContext.ts +0 -13
- package/dist/templates/react-app/src/uikit/hooks/useAppTranslation.ts +0 -26
- package/dist/templates/react-app/src/uikit/hooks/useI18nInterface.ts +0 -25
- package/dist/templates/react-app/src/uikit/hooks/useIOC.ts +0 -35
- package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +0 -21
- package/dist/templates/react-app/src/uikit/hooks/useRouterI18nGuard.ts +0 -25
- package/dist/templates/react-app/src/uikit/hooks/useStrictEffect.ts +0 -31
- package/dist/templates/react-app/src/vite-env.d.ts +0 -1
- package/dist/templates/react-app/tailwind.config.js +0 -4
- package/dist/templates/react-app/tsconfig.app.json +0 -36
- package/dist/templates/react-app/tsconfig.e2e.json +0 -24
- package/dist/templates/react-app/tsconfig.json +0 -22
- package/dist/templates/react-app/tsconfig.node.json +0 -27
- package/dist/templates/react-app/tsconfig.test.json +0 -18
- package/dist/templates/react-app/vite.config.ts +0 -144
|
@@ -1,976 +0,0 @@
|
|
|
1
|
-
# Testing Guide
|
|
2
|
-
|
|
3
|
-
> This document briefly introduces the testing strategies and best practices for the **fe-base** project in a monorepo scenario, using [Vitest](https://vitest.dev/) as the unified testing framework.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Why Choose Vitest
|
|
8
|
-
|
|
9
|
-
1. **Perfect Integration with Vite Ecosystem**: Shares Vite configuration, TypeScript & ESM work out of the box.
|
|
10
|
-
2. **Modern Features**: Parallel execution, HMR, built-in coverage statistics.
|
|
11
|
-
3. **Jest Compatible API**: `describe / it / expect` APIs with no learning curve.
|
|
12
|
-
4. **Monorepo Friendly**: Can filter execution by workspace, easy to run package-level tests in parallel in CI.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Test Types
|
|
17
|
-
|
|
18
|
-
- **Unit Tests**: Verify the minimal behavior of functions, classes, or components.
|
|
19
|
-
- **Integration Tests**: Verify collaboration and boundaries between multiple modules.
|
|
20
|
-
- **End-to-End (E2E, introduce Playwright/Cypress as needed)**: Verify complete user workflows.
|
|
21
|
-
|
|
22
|
-
> ⚡️ In most cases, prioritize writing unit tests; only add integration tests when cross-module interactions are complex.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Test File Organization Standards
|
|
27
|
-
|
|
28
|
-
### File Naming and Location
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
packages/
|
|
32
|
-
├── package-name/
|
|
33
|
-
│ ├── __tests__/ # Test files directory
|
|
34
|
-
│ │ ├── Class.test.ts # Class tests
|
|
35
|
-
│ │ ├── utils/ # Utility function tests
|
|
36
|
-
│ │ │ └── helper.test.ts
|
|
37
|
-
│ │ └── integration/ # Integration tests
|
|
38
|
-
│ ├── __mocks__/ # Mock files directory
|
|
39
|
-
│ │ └── index.ts
|
|
40
|
-
│ └── src/ # Source code directory
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Test File Structure
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
// Standard test file header comment
|
|
47
|
-
/**
|
|
48
|
-
* ClassName test-suite
|
|
49
|
-
*
|
|
50
|
-
* Coverage:
|
|
51
|
-
* 1. constructor – Constructor tests
|
|
52
|
-
* 2. methodName – Method functionality tests
|
|
53
|
-
* 3. edge cases – Edge case tests
|
|
54
|
-
* 4. error handling – Error handling tests
|
|
55
|
-
*/
|
|
56
|
-
|
|
57
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
58
|
-
import { ClassName } from '../src/ClassName';
|
|
59
|
-
|
|
60
|
-
describe('ClassName', () => {
|
|
61
|
-
// Test data and mock objects
|
|
62
|
-
let instance: ClassName;
|
|
63
|
-
let mockDependency: MockType;
|
|
64
|
-
|
|
65
|
-
// Setup and cleanup
|
|
66
|
-
beforeEach(() => {
|
|
67
|
-
// Initialize test environment
|
|
68
|
-
mockDependency = createMockDependency();
|
|
69
|
-
instance = new ClassName(mockDependency);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
afterEach(() => {
|
|
73
|
-
// Clean up test environment
|
|
74
|
-
vi.clearAllMocks();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// Constructor tests
|
|
78
|
-
describe('constructor', () => {
|
|
79
|
-
it('should create instance with valid parameters', () => {
|
|
80
|
-
expect(instance).toBeInstanceOf(ClassName);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should throw error with invalid parameters', () => {
|
|
84
|
-
expect(() => new ClassName(null)).toThrow();
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Method test grouping
|
|
89
|
-
describe('methodName', () => {
|
|
90
|
-
it('should handle normal case', () => {
|
|
91
|
-
// Test normal scenarios
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should handle edge cases', () => {
|
|
95
|
-
// Test edge cases
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should handle error cases', () => {
|
|
99
|
-
// Test error scenarios
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Integration tests
|
|
104
|
-
describe('integration tests', () => {
|
|
105
|
-
it('should work with dependent modules', () => {
|
|
106
|
-
// Test module collaboration
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Vitest Global Configuration Example
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
// vitest.config.ts
|
|
118
|
-
import { defineConfig } from 'vitest/config';
|
|
119
|
-
import { resolve } from 'path';
|
|
120
|
-
|
|
121
|
-
export default defineConfig({
|
|
122
|
-
test: {
|
|
123
|
-
globals: true,
|
|
124
|
-
environment: 'jsdom',
|
|
125
|
-
setupFiles: ['./test/setup.ts'],
|
|
126
|
-
alias: {
|
|
127
|
-
// Automatically mock certain packages in test environment, pointing to __mocks__ directory
|
|
128
|
-
'@qlover/fe-corekit': resolve(__dirname, 'packages/fe-corekit/__mocks__'),
|
|
129
|
-
'@qlover/logger': resolve(__dirname, 'packages/logger/__mocks__')
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Package-level Scripts
|
|
136
|
-
|
|
137
|
-
```jsonc
|
|
138
|
-
// packages/xxx/package.json (example)
|
|
139
|
-
{
|
|
140
|
-
"scripts": {
|
|
141
|
-
"test": "vitest run",
|
|
142
|
-
"test:watch": "vitest",
|
|
143
|
-
"test:coverage": "vitest run --coverage"
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Test Strategy
|
|
151
|
-
|
|
152
|
-
### Test Grouping
|
|
153
|
-
|
|
154
|
-
The entire file is a test file, with test content organized into groups. For example, describe represents a group of tests. Typically, a test file has only one root describe.
|
|
155
|
-
|
|
156
|
-
The content is tested from "small to large." For example, if the source file contains a class, the tests are grouped by the constructor parameters, the constructor itself, and each member method.
|
|
157
|
-
|
|
158
|
-
- From covering various parameter types for each method to the overall flow affected by method calls.
|
|
159
|
-
- As well as comprehensive flow testing and boundary testing.
|
|
160
|
-
|
|
161
|
-
Source file (TestClass.ts):
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
type TestClassOptions = {
|
|
165
|
-
name: string;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
class TestClass {
|
|
169
|
-
constructor(options: TestClassOptions) {}
|
|
170
|
-
|
|
171
|
-
getName(): string {
|
|
172
|
-
return this.options.name;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
setName(name: string): void {
|
|
176
|
-
this.options.name = name;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Test file (TestClass.test.ts):
|
|
182
|
-
|
|
183
|
-
```ts
|
|
184
|
-
describe('TestClass', () => {
|
|
185
|
-
describe('TestClass.constructor', () => {
|
|
186
|
-
// ...
|
|
187
|
-
});
|
|
188
|
-
describe('TestClass.getName', () => {
|
|
189
|
-
// ...
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('Overall flow or boundary testing', () => {
|
|
193
|
-
it('should keep getName consistent after modifying the name', () => {
|
|
194
|
-
const testClass = new TestClass({ name: 'test' });
|
|
195
|
-
testClass.setName('test2');
|
|
196
|
-
expect(testClass.getName()).toBe('test2');
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Test Case Naming Conventions
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
describe('ClassName', () => {
|
|
206
|
-
describe('methodName', () => {
|
|
207
|
-
// Positive test cases
|
|
208
|
-
it('should return expected result when given valid input', () => {});
|
|
209
|
-
it('should handle multiple parameters correctly', () => {});
|
|
210
|
-
|
|
211
|
-
// Boundary test cases
|
|
212
|
-
it('should handle empty input', () => {});
|
|
213
|
-
it('should handle null/undefined input', () => {});
|
|
214
|
-
it('should handle maximum/minimum values', () => {});
|
|
215
|
-
|
|
216
|
-
// Error test cases
|
|
217
|
-
it('should throw error when given invalid input', () => {});
|
|
218
|
-
it('should handle network failure gracefully', () => {});
|
|
219
|
-
|
|
220
|
-
// Behavioral test cases
|
|
221
|
-
it('should call dependency method with correct parameters', () => {});
|
|
222
|
-
it('should not call dependency when condition is false', () => {});
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Function Testing
|
|
228
|
-
|
|
229
|
-
Function tests should cover the following aspects:
|
|
230
|
-
|
|
231
|
-
1. **Parameter Combination Testing**
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
interface TestParams {
|
|
235
|
-
key1?: string;
|
|
236
|
-
key2?: number;
|
|
237
|
-
key3?: boolean;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function testFunction({ key1, key2, key3 }: TestParams): string {
|
|
241
|
-
// Implementation...
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
describe('testFunction', () => {
|
|
245
|
-
describe('Parameter Combination Testing', () => {
|
|
246
|
-
it('should handle case with all parameters present', () => {
|
|
247
|
-
expect(testFunction({ key1: 'test', key2: 1, key3: true })).toBe(
|
|
248
|
-
'expected result'
|
|
249
|
-
);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it('should handle case with key1, key2 only', () => {
|
|
253
|
-
expect(testFunction({ key1: 'test', key2: 1 })).toBe('expected result');
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('should handle case with key1, key3 only', () => {
|
|
257
|
-
expect(testFunction({ key1: 'test', key3: true })).toBe(
|
|
258
|
-
'expected result'
|
|
259
|
-
);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it('should handle case with key2, key3 only', () => {
|
|
263
|
-
expect(testFunction({ key2: 1, key3: true })).toBe('expected result');
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it('should handle case with key1 only', () => {
|
|
267
|
-
expect(testFunction({ key1: 'test' })).toBe('expected result');
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
it('should handle case with key2 only', () => {
|
|
271
|
-
expect(testFunction({ key2: 1 })).toBe('expected result');
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it('should handle case with key3 only', () => {
|
|
275
|
-
expect(testFunction({ key3: true })).toBe('expected result');
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it('should handle empty object case', () => {
|
|
279
|
-
expect(testFunction({})).toBe('expected result');
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
describe('Boundary Value Testing', () => {
|
|
284
|
-
it('should handle extreme values', () => {
|
|
285
|
-
expect(
|
|
286
|
-
testFunction({
|
|
287
|
-
key1: '', // Empty string
|
|
288
|
-
key2: Number.MAX_SAFE_INTEGER, // Maximum safe integer
|
|
289
|
-
key3: false
|
|
290
|
-
})
|
|
291
|
-
).toBe('expected result');
|
|
292
|
-
|
|
293
|
-
expect(
|
|
294
|
-
testFunction({
|
|
295
|
-
key1: 'a'.repeat(1000), // Very long string
|
|
296
|
-
key2: Number.MIN_SAFE_INTEGER, // Minimum safe integer
|
|
297
|
-
key3: true
|
|
298
|
-
})
|
|
299
|
-
).toBe('expected result');
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('should handle special values', () => {
|
|
303
|
-
expect(
|
|
304
|
-
testFunction({
|
|
305
|
-
key1: ' ', // All spaces string
|
|
306
|
-
key2: 0, // Zero value
|
|
307
|
-
key3: false
|
|
308
|
-
})
|
|
309
|
-
).toBe('expected result');
|
|
310
|
-
|
|
311
|
-
expect(
|
|
312
|
-
testFunction({
|
|
313
|
-
key1: null as any, // null value
|
|
314
|
-
key2: NaN, // NaN value
|
|
315
|
-
key3: undefined as any // undefined value
|
|
316
|
-
})
|
|
317
|
-
).toBe('expected result');
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it('should handle invalid values', () => {
|
|
321
|
-
expect(() =>
|
|
322
|
-
testFunction({
|
|
323
|
-
key1: Symbol() as any, // Invalid type
|
|
324
|
-
key2: {} as any, // Invalid type
|
|
325
|
-
key3: 42 as any // Invalid type
|
|
326
|
-
})
|
|
327
|
-
).toThrow();
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
This test suite demonstrates:
|
|
334
|
-
|
|
335
|
-
1. **Complete Parameter Combination Coverage**:
|
|
336
|
-
- Tests all possible parameter combinations (2^n combinations, where n is the number of parameters)
|
|
337
|
-
- Includes cases with all parameters present, partial parameters, and empty object
|
|
338
|
-
|
|
339
|
-
2. **Boundary Value Testing**:
|
|
340
|
-
- Tests parameter limit values (maximum, minimum)
|
|
341
|
-
- Tests special values (empty string, null, undefined, NaN)
|
|
342
|
-
- Tests invalid values (type errors)
|
|
343
|
-
|
|
344
|
-
3. **Test Case Organization**:
|
|
345
|
-
- Uses nested describe blocks to clearly organize test scenarios
|
|
346
|
-
- Each test case has a clear description
|
|
347
|
-
- Related test cases are grouped together
|
|
348
|
-
|
|
349
|
-
### Test Data Management
|
|
350
|
-
|
|
351
|
-
```typescript
|
|
352
|
-
describe('DataProcessor', () => {
|
|
353
|
-
// Test data constants
|
|
354
|
-
const VALID_DATA = {
|
|
355
|
-
id: 1,
|
|
356
|
-
name: 'test',
|
|
357
|
-
items: ['a', 'b', 'c']
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
const INVALID_DATA = {
|
|
361
|
-
id: null,
|
|
362
|
-
name: '',
|
|
363
|
-
items: []
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
// Test data factory functions
|
|
367
|
-
const createTestUser = (overrides = {}) => ({
|
|
368
|
-
id: 1,
|
|
369
|
-
name: 'Test User',
|
|
370
|
-
email: 'test@example.com',
|
|
371
|
-
...overrides
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
// Complex data structures
|
|
375
|
-
const createComplexTestData = () => ({
|
|
376
|
-
metadata: {
|
|
377
|
-
version: '1.0.0',
|
|
378
|
-
created: Date.now(),
|
|
379
|
-
tags: ['test', 'data']
|
|
380
|
-
},
|
|
381
|
-
users: [
|
|
382
|
-
createTestUser({ id: 1 }),
|
|
383
|
-
createTestUser({ id: 2, name: 'Another User' })
|
|
384
|
-
]
|
|
385
|
-
});
|
|
386
|
-
});
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## Mock Strategy
|
|
392
|
-
|
|
393
|
-
### 1. Global Mock Directory
|
|
394
|
-
|
|
395
|
-
Each package can expose a subdirectory with the same name, providing persistent mocks for automatic use by other packages during testing.
|
|
396
|
-
|
|
397
|
-
```typescript
|
|
398
|
-
// packages/fe-corekit/__mocks__/index.ts
|
|
399
|
-
import { vi } from 'vitest';
|
|
400
|
-
|
|
401
|
-
export const MyUtility = {
|
|
402
|
-
doSomething: vi.fn(() => 'mocked'),
|
|
403
|
-
processData: vi.fn((input: string) => `processed-${input}`)
|
|
404
|
-
};
|
|
405
|
-
export default MyUtility;
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
### 2. File-level Mock
|
|
409
|
-
|
|
410
|
-
```typescript
|
|
411
|
-
// At the top of test file
|
|
412
|
-
vi.mock('../src/Util', () => ({
|
|
413
|
-
Util: {
|
|
414
|
-
ensureDir: vi.fn(),
|
|
415
|
-
readFile: vi.fn()
|
|
416
|
-
}
|
|
417
|
-
}));
|
|
418
|
-
|
|
419
|
-
vi.mock('js-cookie', () => {
|
|
420
|
-
let store: Record<string, string> = {};
|
|
421
|
-
|
|
422
|
-
const get = vi.fn((key?: string) => {
|
|
423
|
-
if (typeof key === 'string') return store[key];
|
|
424
|
-
return { ...store };
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
const set = vi.fn((key: string, value: string) => {
|
|
428
|
-
store[key] = value;
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
const remove = vi.fn((key: string) => {
|
|
432
|
-
delete store[key];
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
const __resetStore = () => {
|
|
436
|
-
store = {};
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
return {
|
|
440
|
-
default: { get, set, remove, __resetStore }
|
|
441
|
-
};
|
|
442
|
-
});
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### 3. Dynamic Mock
|
|
446
|
-
|
|
447
|
-
```typescript
|
|
448
|
-
describe('ServiceClass', () => {
|
|
449
|
-
it('should handle API failure', async () => {
|
|
450
|
-
// Temporarily mock API call failure
|
|
451
|
-
vi.spyOn(apiClient, 'request').mockRejectedValue(
|
|
452
|
-
new Error('Network error')
|
|
453
|
-
);
|
|
454
|
-
|
|
455
|
-
await expect(service.fetchData()).rejects.toThrow('Network error');
|
|
456
|
-
|
|
457
|
-
// Restore original implementation
|
|
458
|
-
vi.restoreAllMocks();
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### 4. Mock Class Instances
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
class MockStorage<Key = string> implements SyncStorageInterface<Key> {
|
|
467
|
-
public data = new Map<string, string>();
|
|
468
|
-
public calls: {
|
|
469
|
-
setItem: Array<{ key: Key; value: unknown; options?: unknown }>;
|
|
470
|
-
getItem: Array<{ key: Key; defaultValue?: unknown; options?: unknown }>;
|
|
471
|
-
removeItem: Array<{ key: Key; options?: unknown }>;
|
|
472
|
-
clear: number;
|
|
473
|
-
} = {
|
|
474
|
-
setItem: [],
|
|
475
|
-
getItem: [],
|
|
476
|
-
removeItem: [],
|
|
477
|
-
clear: 0
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
setItem<T>(key: Key, value: T, options?: unknown): void {
|
|
481
|
-
this.calls.setItem.push({ key, value, options });
|
|
482
|
-
this.data.set(String(key), String(value));
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
getItem<T>(key: Key, defaultValue?: T, options?: unknown): T | null {
|
|
486
|
-
this.calls.getItem.push({ key, defaultValue, options });
|
|
487
|
-
const value = this.data.get(String(key));
|
|
488
|
-
return (value ?? defaultValue ?? null) as T | null;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
reset(): void {
|
|
492
|
-
this.data.clear();
|
|
493
|
-
this.calls = {
|
|
494
|
-
setItem: [],
|
|
495
|
-
getItem: [],
|
|
496
|
-
removeItem: [],
|
|
497
|
-
clear: 0
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
---
|
|
504
|
-
|
|
505
|
-
## Test Environment Management
|
|
506
|
-
|
|
507
|
-
### Lifecycle Hooks
|
|
508
|
-
|
|
509
|
-
```typescript
|
|
510
|
-
describe('ComponentTest', () => {
|
|
511
|
-
let component: Component;
|
|
512
|
-
let mockDependency: MockDependency;
|
|
513
|
-
|
|
514
|
-
beforeAll(() => {
|
|
515
|
-
// One-time setup before entire test suite
|
|
516
|
-
setupGlobalTestEnvironment();
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
afterAll(() => {
|
|
520
|
-
// One-time cleanup after entire test suite
|
|
521
|
-
cleanupGlobalTestEnvironment();
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
beforeEach(() => {
|
|
525
|
-
// Setup before each test case
|
|
526
|
-
vi.useFakeTimers();
|
|
527
|
-
mockDependency = new MockDependency();
|
|
528
|
-
component = new Component(mockDependency);
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
afterEach(() => {
|
|
532
|
-
// Cleanup after each test case
|
|
533
|
-
vi.useRealTimers();
|
|
534
|
-
vi.clearAllMocks();
|
|
535
|
-
mockDependency.reset();
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### File System Testing
|
|
541
|
-
|
|
542
|
-
```typescript
|
|
543
|
-
describe('FileProcessor', () => {
|
|
544
|
-
const testDir = './test-files';
|
|
545
|
-
const testFilePath = path.join(testDir, 'test.json');
|
|
546
|
-
|
|
547
|
-
beforeAll(() => {
|
|
548
|
-
// Create test directories and files
|
|
549
|
-
if (!fs.existsSync(testDir)) {
|
|
550
|
-
fs.mkdirSync(testDir, { recursive: true });
|
|
551
|
-
}
|
|
552
|
-
fs.writeFileSync(testFilePath, JSON.stringify({ test: 'data' }));
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
afterAll(() => {
|
|
556
|
-
// Clean up test files
|
|
557
|
-
if (fs.existsSync(testDir)) {
|
|
558
|
-
fs.rmSync(testDir, { recursive: true, force: true });
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
it('should process file correctly', () => {
|
|
563
|
-
const processor = new FileProcessor();
|
|
564
|
-
const result = processor.processFile(testFilePath);
|
|
565
|
-
expect(result).toEqual({ test: 'data' });
|
|
566
|
-
});
|
|
567
|
-
});
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
---
|
|
571
|
-
|
|
572
|
-
## Boundary Testing and Error Handling
|
|
573
|
-
|
|
574
|
-
### Boundary Value Testing
|
|
575
|
-
|
|
576
|
-
```typescript
|
|
577
|
-
describe('ValidationUtils', () => {
|
|
578
|
-
describe('validateAge', () => {
|
|
579
|
-
it('should handle boundary values', () => {
|
|
580
|
-
// Boundary value testing
|
|
581
|
-
expect(validateAge(0)).toBe(true); // Minimum value
|
|
582
|
-
expect(validateAge(150)).toBe(true); // Maximum value
|
|
583
|
-
expect(validateAge(-1)).toBe(false); // Below minimum
|
|
584
|
-
expect(validateAge(151)).toBe(false); // Above maximum
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
it('should handle edge cases', () => {
|
|
588
|
-
// Edge case testing
|
|
589
|
-
expect(validateAge(null)).toBe(false);
|
|
590
|
-
expect(validateAge(undefined)).toBe(false);
|
|
591
|
-
expect(validateAge(NaN)).toBe(false);
|
|
592
|
-
expect(validateAge(Infinity)).toBe(false);
|
|
593
|
-
});
|
|
594
|
-
});
|
|
595
|
-
});
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### Async Operation Testing
|
|
599
|
-
|
|
600
|
-
```typescript
|
|
601
|
-
describe('AsyncService', () => {
|
|
602
|
-
it('should handle successful async operation', async () => {
|
|
603
|
-
const service = new AsyncService();
|
|
604
|
-
const result = await service.fetchData();
|
|
605
|
-
expect(result).toBeDefined();
|
|
606
|
-
});
|
|
607
|
-
|
|
608
|
-
it('should handle async operation failure', async () => {
|
|
609
|
-
const service = new AsyncService();
|
|
610
|
-
vi.spyOn(service, 'apiCall').mockRejectedValue(new Error('API Error'));
|
|
611
|
-
|
|
612
|
-
await expect(service.fetchData()).rejects.toThrow('API Error');
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
it('should handle timeout', async () => {
|
|
616
|
-
vi.useFakeTimers();
|
|
617
|
-
const service = new AsyncService();
|
|
618
|
-
|
|
619
|
-
const promise = service.fetchDataWithTimeout(1000);
|
|
620
|
-
vi.advanceTimersByTime(1001);
|
|
621
|
-
|
|
622
|
-
await expect(promise).rejects.toThrow('Timeout');
|
|
623
|
-
vi.useRealTimers();
|
|
624
|
-
});
|
|
625
|
-
});
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
### Type Safety Testing
|
|
629
|
-
|
|
630
|
-
TypeScript project tests should not only verify runtime behavior but also ensure the correctness of the type system. Vitest provides the `expectTypeOf` utility for compile-time type checking.
|
|
631
|
-
|
|
632
|
-
#### Why Type Testing?
|
|
633
|
-
|
|
634
|
-
1. **Type Inference Validation**: Ensure TypeScript correctly infers complex types
|
|
635
|
-
2. **Generic Constraint Checking**: Verify generic parameter constraints
|
|
636
|
-
3. **Type Compatibility**: Ensure type definitions match actual usage
|
|
637
|
-
4. **API Contract Guarantee**: Prevent breaking changes in type definitions
|
|
638
|
-
|
|
639
|
-
#### Basic Type Testing
|
|
640
|
-
|
|
641
|
-
```typescript
|
|
642
|
-
import { describe, it, expectTypeOf } from 'vitest';
|
|
643
|
-
|
|
644
|
-
describe('TypeSafetyTests', () => {
|
|
645
|
-
it('should maintain type safety', () => {
|
|
646
|
-
const processor = new DataProcessor<User>();
|
|
647
|
-
|
|
648
|
-
// Use expectTypeOf for type checking
|
|
649
|
-
expectTypeOf(processor.process).parameter(0).toEqualTypeOf<User>();
|
|
650
|
-
expectTypeOf(processor.process).returns.toEqualTypeOf<ProcessedUser>();
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
it('should infer correct return types', () => {
|
|
654
|
-
const result = getData();
|
|
655
|
-
|
|
656
|
-
// Verify return type
|
|
657
|
-
expectTypeOf(result).toEqualTypeOf<{ id: number; name: string }>();
|
|
658
|
-
expectTypeOf(result).not.toEqualTypeOf<{ id: string; name: string }>();
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
it('should validate parameter types', () => {
|
|
662
|
-
function processUser(user: User): void {
|
|
663
|
-
// implementation
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Verify parameter type
|
|
667
|
-
expectTypeOf(processUser).parameter(0).toMatchTypeOf<{ id: number }>();
|
|
668
|
-
expectTypeOf(processUser).parameter(0).toHaveProperty('id');
|
|
669
|
-
});
|
|
670
|
-
});
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
#### Generic Type Testing
|
|
674
|
-
|
|
675
|
-
```typescript
|
|
676
|
-
describe('Generic Type Tests', () => {
|
|
677
|
-
it('should work with generic constraints', () => {
|
|
678
|
-
class Storage<T extends { id: number }> {
|
|
679
|
-
store(item: T): T {
|
|
680
|
-
return item;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
const storage = new Storage<User>();
|
|
685
|
-
|
|
686
|
-
// Verify generic type
|
|
687
|
-
expectTypeOf(storage.store).parameter(0).toMatchTypeOf<User>();
|
|
688
|
-
expectTypeOf(storage.store).returns.toMatchTypeOf<User>();
|
|
689
|
-
});
|
|
690
|
-
|
|
691
|
-
it('should validate complex generic types', () => {
|
|
692
|
-
type ApiResponse<T> = {
|
|
693
|
-
data: T;
|
|
694
|
-
status: number;
|
|
695
|
-
message?: string;
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
const response: ApiResponse<User[]> = {
|
|
699
|
-
data: [],
|
|
700
|
-
status: 200
|
|
701
|
-
};
|
|
702
|
-
|
|
703
|
-
// Verify nested generic type
|
|
704
|
-
expectTypeOf(response).toMatchTypeOf<ApiResponse<User[]>>();
|
|
705
|
-
expectTypeOf(response.data).toEqualTypeOf<User[]>();
|
|
706
|
-
});
|
|
707
|
-
});
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
#### Union and Intersection Type Testing
|
|
711
|
-
|
|
712
|
-
```typescript
|
|
713
|
-
describe('Union and Intersection Types', () => {
|
|
714
|
-
it('should handle union types correctly', () => {
|
|
715
|
-
type Result = Success | Error;
|
|
716
|
-
type Success = { status: 'success'; data: string };
|
|
717
|
-
type Error = { status: 'error'; message: string };
|
|
718
|
-
|
|
719
|
-
function handleResult(result: Result): void {
|
|
720
|
-
// implementation
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// Verify union type
|
|
724
|
-
expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Success>();
|
|
725
|
-
expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Error>();
|
|
726
|
-
});
|
|
727
|
-
|
|
728
|
-
it('should handle intersection types correctly', () => {
|
|
729
|
-
type Timestamped = { createdAt: Date; updatedAt: Date };
|
|
730
|
-
type UserWithTimestamp = User & Timestamped;
|
|
731
|
-
|
|
732
|
-
const user: UserWithTimestamp = {
|
|
733
|
-
id: 1,
|
|
734
|
-
name: 'John',
|
|
735
|
-
createdAt: new Date(),
|
|
736
|
-
updatedAt: new Date()
|
|
737
|
-
};
|
|
738
|
-
|
|
739
|
-
// Verify intersection type contains all properties
|
|
740
|
-
expectTypeOf(user).toHaveProperty('id');
|
|
741
|
-
expectTypeOf(user).toHaveProperty('name');
|
|
742
|
-
expectTypeOf(user).toHaveProperty('createdAt');
|
|
743
|
-
expectTypeOf(user).toHaveProperty('updatedAt');
|
|
744
|
-
});
|
|
745
|
-
});
|
|
746
|
-
```
|
|
747
|
-
|
|
748
|
-
#### Type Narrowing Testing
|
|
749
|
-
|
|
750
|
-
```typescript
|
|
751
|
-
describe('Type Narrowing Tests', () => {
|
|
752
|
-
it('should validate type guards', () => {
|
|
753
|
-
function isString(value: unknown): value is string {
|
|
754
|
-
return typeof value === 'string';
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
const value: unknown = 'test';
|
|
758
|
-
|
|
759
|
-
if (isString(value)) {
|
|
760
|
-
// Within this scope, value should be narrowed to string type
|
|
761
|
-
expectTypeOf(value).toEqualTypeOf<string>();
|
|
762
|
-
}
|
|
763
|
-
});
|
|
764
|
-
|
|
765
|
-
it('should validate discriminated unions', () => {
|
|
766
|
-
type Shape =
|
|
767
|
-
| { kind: 'circle'; radius: number }
|
|
768
|
-
| { kind: 'rectangle'; width: number; height: number };
|
|
769
|
-
|
|
770
|
-
function getArea(shape: Shape): number {
|
|
771
|
-
if (shape.kind === 'circle') {
|
|
772
|
-
// In this branch, shape should be narrowed to circle type
|
|
773
|
-
expectTypeOf(shape).toHaveProperty('radius');
|
|
774
|
-
expectTypeOf(shape).not.toHaveProperty('width');
|
|
775
|
-
return Math.PI * shape.radius ** 2;
|
|
776
|
-
} else {
|
|
777
|
-
// In this branch, shape should be narrowed to rectangle type
|
|
778
|
-
expectTypeOf(shape).toHaveProperty('width');
|
|
779
|
-
expectTypeOf(shape).toHaveProperty('height');
|
|
780
|
-
return shape.width * shape.height;
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
|
-
});
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
#### Practical Recommendations
|
|
788
|
-
|
|
789
|
-
1. **Combine with Runtime Tests**: Type tests should complement runtime tests
|
|
790
|
-
|
|
791
|
-
```typescript
|
|
792
|
-
describe('Combined Runtime and Type Tests', () => {
|
|
793
|
-
it('should validate both runtime behavior and types', () => {
|
|
794
|
-
function add(a: number, b: number): number {
|
|
795
|
-
return a + b;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
// Type test
|
|
799
|
-
expectTypeOf(add).parameter(0).toEqualTypeOf<number>();
|
|
800
|
-
expectTypeOf(add).returns.toEqualTypeOf<number>();
|
|
801
|
-
|
|
802
|
-
// Runtime test
|
|
803
|
-
expect(add(1, 2)).toBe(3);
|
|
804
|
-
expect(add(-1, 1)).toBe(0);
|
|
805
|
-
});
|
|
806
|
-
});
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
2. **Test Type Inference**: Ensure TypeScript correctly infers types, avoid overusing `any`
|
|
810
|
-
|
|
811
|
-
```typescript
|
|
812
|
-
describe('Type Inference Tests', () => {
|
|
813
|
-
it('should infer types correctly', () => {
|
|
814
|
-
const data = { id: 1, name: 'John' };
|
|
815
|
-
|
|
816
|
-
// Verify inferred type
|
|
817
|
-
expectTypeOf(data).toEqualTypeOf<{ id: number; name: string }>();
|
|
818
|
-
expectTypeOf(data.id).toEqualTypeOf<number>();
|
|
819
|
-
expectTypeOf(data.name).toEqualTypeOf<string>();
|
|
820
|
-
});
|
|
821
|
-
});
|
|
822
|
-
```
|
|
823
|
-
|
|
824
|
-
3. **Use TypeScript Compiler Checks**: Run `tsc --noEmit` in CI to ensure no type errors
|
|
825
|
-
|
|
826
|
-
```bash
|
|
827
|
-
# Add script in package.json
|
|
828
|
-
{
|
|
829
|
-
"scripts": {
|
|
830
|
-
"type-check": "tsc --noEmit",
|
|
831
|
-
"test": "pnpm type-check && vitest run"
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
---
|
|
837
|
-
|
|
838
|
-
## Performance Testing
|
|
839
|
-
|
|
840
|
-
```typescript
|
|
841
|
-
describe('PerformanceTests', () => {
|
|
842
|
-
it('should complete operation within time limit', async () => {
|
|
843
|
-
const startTime = Date.now();
|
|
844
|
-
const processor = new DataProcessor();
|
|
845
|
-
|
|
846
|
-
await processor.processLargeDataset(largeDataset);
|
|
847
|
-
|
|
848
|
-
const endTime = Date.now();
|
|
849
|
-
const duration = endTime - startTime;
|
|
850
|
-
|
|
851
|
-
expect(duration).toBeLessThan(1000); // Should complete within 1 second
|
|
852
|
-
});
|
|
853
|
-
});
|
|
854
|
-
```
|
|
855
|
-
|
|
856
|
-
---
|
|
857
|
-
|
|
858
|
-
## Running Tests
|
|
859
|
-
|
|
860
|
-
```bash
|
|
861
|
-
# Run all package tests
|
|
862
|
-
pnpm test
|
|
863
|
-
|
|
864
|
-
# Run tests for specific package only
|
|
865
|
-
pnpm --filter @qlover/fe-corekit test
|
|
866
|
-
|
|
867
|
-
# Watch mode
|
|
868
|
-
pnpm test:watch
|
|
869
|
-
|
|
870
|
-
# Generate coverage report
|
|
871
|
-
pnpm test:coverage
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
In CI, you can leverage GitHub Actions:
|
|
875
|
-
|
|
876
|
-
```yaml
|
|
877
|
-
# .github/workflows/test.yml (truncated)
|
|
878
|
-
- run: pnpm install
|
|
879
|
-
- run: pnpm test:coverage
|
|
880
|
-
- uses: codecov/codecov-action@v3
|
|
881
|
-
```
|
|
882
|
-
|
|
883
|
-
---
|
|
884
|
-
|
|
885
|
-
## Coverage Targets
|
|
886
|
-
|
|
887
|
-
| Metric | Target |
|
|
888
|
-
| ---------- | ------ |
|
|
889
|
-
| Statements | ≥ 80% |
|
|
890
|
-
| Branches | ≥ 75% |
|
|
891
|
-
| Functions | ≥ 85% |
|
|
892
|
-
| Lines | ≥ 80% |
|
|
893
|
-
|
|
894
|
-
Coverage reports are output to the `coverage/` directory by default, with `index.html` available for local browsing.
|
|
895
|
-
|
|
896
|
-
---
|
|
897
|
-
|
|
898
|
-
## Debugging
|
|
899
|
-
|
|
900
|
-
### VS Code Launch Configuration
|
|
901
|
-
|
|
902
|
-
```jsonc
|
|
903
|
-
{
|
|
904
|
-
"version": "0.2.0",
|
|
905
|
-
"configurations": [
|
|
906
|
-
{
|
|
907
|
-
"name": "Debug Vitest",
|
|
908
|
-
"type": "node",
|
|
909
|
-
"request": "launch",
|
|
910
|
-
"program": "${workspaceFolder}/node_modules/vitest/vitest.mjs",
|
|
911
|
-
"args": ["run", "--reporter=verbose"],
|
|
912
|
-
"console": "integratedTerminal",
|
|
913
|
-
"internalConsoleOptions": "neverOpen"
|
|
914
|
-
}
|
|
915
|
-
]
|
|
916
|
-
}
|
|
917
|
-
```
|
|
918
|
-
|
|
919
|
-
> You can use `console.log` / `debugger` in test code to assist with troubleshooting.
|
|
920
|
-
|
|
921
|
-
---
|
|
922
|
-
|
|
923
|
-
## Frequently Asked Questions (FAQ)
|
|
924
|
-
|
|
925
|
-
### Q1: How to Mock Browser APIs?
|
|
926
|
-
|
|
927
|
-
Use `vi.mock()` or globally override in `setupFiles`, for example:
|
|
928
|
-
|
|
929
|
-
```typescript
|
|
930
|
-
globalThis.requestAnimationFrame = (cb) => setTimeout(cb, 16);
|
|
931
|
-
```
|
|
932
|
-
|
|
933
|
-
### Q2: What to do when tests are slow?
|
|
934
|
-
|
|
935
|
-
- Use `vi.useFakeTimers()` to accelerate time-related logic.
|
|
936
|
-
- Break down long integration processes into independent unit tests.
|
|
937
|
-
|
|
938
|
-
### Q3: How to test TypeScript types?
|
|
939
|
-
|
|
940
|
-
Use `expectTypeOf`:
|
|
941
|
-
|
|
942
|
-
```typescript
|
|
943
|
-
import { expectTypeOf } from 'vitest';
|
|
944
|
-
|
|
945
|
-
expectTypeOf(MyUtility.doSomething).returns.toEqualTypeOf<string>();
|
|
946
|
-
```
|
|
947
|
-
|
|
948
|
-
### Q4: How to test private methods?
|
|
949
|
-
|
|
950
|
-
```typescript
|
|
951
|
-
// Access private methods through type assertion
|
|
952
|
-
it('should test private method', () => {
|
|
953
|
-
const instance = new MyClass();
|
|
954
|
-
const result = (instance as any).privateMethod();
|
|
955
|
-
expect(result).toBe('expected');
|
|
956
|
-
});
|
|
957
|
-
```
|
|
958
|
-
|
|
959
|
-
### Q5: How to handle dependency injection testing?
|
|
960
|
-
|
|
961
|
-
```typescript
|
|
962
|
-
describe('ServiceWithDependencies', () => {
|
|
963
|
-
let mockRepository: MockRepository;
|
|
964
|
-
let service: UserService;
|
|
965
|
-
|
|
966
|
-
beforeEach(() => {
|
|
967
|
-
mockRepository = new MockRepository();
|
|
968
|
-
service = new UserService(mockRepository);
|
|
969
|
-
});
|
|
970
|
-
|
|
971
|
-
it('should use injected dependency', () => {
|
|
972
|
-
service.getUser(1);
|
|
973
|
-
expect(mockRepository.findById).toHaveBeenCalledWith(1);
|
|
974
|
-
});
|
|
975
|
-
});
|
|
976
|
-
```
|