@aamini/config 0.0.13 → 0.0.14

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.
Files changed (56) hide show
  1. package/dist/{playwright.shared.config.d.mts → playwright.d.mts} +2 -3
  2. package/dist/{playwright.shared.config.mjs → playwright.mjs} +2 -3
  3. package/dist/playwright.mjs.map +1 -0
  4. package/dist/setup/styles.mjs +0 -1
  5. package/dist/test/browser.d.mts +7 -2
  6. package/dist/test/browser.mjs +5 -3
  7. package/dist/test/browser.mjs.map +1 -1
  8. package/dist/test/db.d.mts +34 -7
  9. package/dist/test/db.mjs +29 -15
  10. package/dist/test/db.mjs.map +1 -1
  11. package/dist/test/server.d.mts +7 -3
  12. package/dist/test/server.mjs +3 -4
  13. package/dist/test/server.mjs.map +1 -1
  14. package/dist/vite.d.mts +81 -0
  15. package/dist/vite.mjs +211 -0
  16. package/dist/vite.mjs.map +1 -0
  17. package/package.json +38 -45
  18. package/tsconfig/tsconfig.tanstack.json +1 -1
  19. package/dist/internal-Dshd0hdM.mjs +0 -22
  20. package/dist/internal-Dshd0hdM.mjs.map +0 -1
  21. package/dist/playwright.shared.config.mjs.map +0 -1
  22. package/dist/test/database.d.mts +0 -22
  23. package/dist/test/database.mjs +0 -18
  24. package/dist/test/database.mjs.map +0 -1
  25. package/dist/test/playwright.d.mts +0 -7
  26. package/dist/test/playwright.mjs +0 -15
  27. package/dist/test/playwright.mjs.map +0 -1
  28. package/dist/test/postgres.d.mts +0 -14
  29. package/dist/test/postgres.mjs +0 -25
  30. package/dist/test/postgres.mjs.map +0 -1
  31. package/dist/test/visual-page.d.mts +0 -36
  32. package/dist/test/visual-page.mjs +0 -30
  33. package/dist/test/visual-page.mjs.map +0 -1
  34. package/dist/vite.shared.d.mts +0 -379
  35. package/dist/vite.shared.mjs +0 -302
  36. package/dist/vite.shared.mjs.map +0 -1
  37. package/dist/vitest.shared.d.mts +0 -12
  38. package/dist/vitest.shared.mjs +0 -122
  39. package/dist/vitest.shared.mjs.map +0 -1
  40. package/msw.ts +0 -5
  41. package/playwright.shared.config.ts +0 -71
  42. package/setup/styles.ts +0 -4
  43. package/test/browser.ts +0 -44
  44. package/test/database.ts +0 -38
  45. package/test/db.ts +0 -86
  46. package/test/internal.ts +0 -45
  47. package/test/playwright.ts +0 -17
  48. package/test/postgres.ts +0 -43
  49. package/test/server.ts +0 -43
  50. package/test/visual-page.ts +0 -57
  51. package/tsconfig/tsconfig.astro.json +0 -34
  52. package/tsconfig/tsconfig.react.json +0 -16
  53. package/virtual-modules.d.ts +0 -6
  54. package/vite.config.ts +0 -53
  55. package/vite.shared.ts +0 -411
  56. package/vitest.shared.ts +0 -183
@@ -1 +0,0 @@
1
- {"version":3,"file":"vite.shared.mjs","names":["defineVitestConfig","defineConfig"],"sources":["../vite.shared.ts"],"sourcesContent":["import { nitro } from 'nitro/vite'\nimport { devtools } from '@tanstack/devtools-vite'\nimport { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport viteReact, { reactCompilerPreset } from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'\nimport babel from '@rolldown/plugin-babel'\nimport svgr from 'vite-plugin-svgr'\nimport { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Plugin } from 'vite'\nimport {\n\tdefineConfig as defineVitestConfig,\n\tmergeConfig,\n\ttype TestProjectConfiguration,\n\ttype TestProjectInlineConfiguration,\n} from 'vitest/config'\nimport { defineConfig } from 'vite'\nimport { playwright } from 'vite-plus/test/browser-playwright'\n\nconst HANDLER_LOCATIONS = [\n\t'__mocks__/handlers.ts',\n\t'__mocks__/handlers.js',\n\t'src/mocks/handlers.ts',\n\t'src/mocks/handlers.js',\n]\n\nconst STYLES_LOCATIONS = ['src/styles.css', 'src/index.css', 'src/app.css']\n\nfunction mswHandlersPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/handlers'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'msw-handlers-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of HANDLER_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `export { default } from '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No MSW handlers found. Expected one of:\\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nfunction stylesPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/styles'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'styles-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of STYLES_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `import '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No styles file found. Expected one of:\\n${STYLES_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nconst stylesSetup = '@aamini/config/setup/styles'\n\nfunction mergeProjectConfig(\n\tbase: TestProjectConfiguration,\n\toverrides: TestProjectConfiguration = {},\n): TestProjectConfiguration {\n\treturn mergeConfig(\n\t\tbase as Record<string, any>,\n\t\toverrides as Record<string, any>,\n\t) as TestProjectConfiguration\n}\n\ninterface ProjectOverrides {\n\tserver?: TestProjectConfiguration\n\tbrowser?: TestProjectConfiguration\n}\n\nfunction createBaseConfig(\n\troot: string,\n\toverrides: TestProjectInlineConfiguration = {},\n\tprojectOverrides: ProjectOverrides = {},\n) {\n\tconst localSetup = resolve(root, 'vitest.setup.ts')\n\tconst hasLocalSetup = existsSync(localSetup)\n\n\treturn mergeConfig(\n\t\tdefineVitestConfig({\n\t\t\troot,\n\t\t\tresolve: {\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\t\talias: [\n\t\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t\t],\n\t\t\t},\n\t\t\tplugins: [\n\t\t\t\ttailwindcss(),\n\t\t\t\tsvgr({\n\t\t\t\t\tinclude: '**/*.svg',\n\t\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t\t}),\n\t\t\t],\n\t\t\ttest: {\n\t\t\t\tpassWithNoTests: true,\n\t\t\t\texclude: [\n\t\t\t\t\t'**/node_modules/**',\n\t\t\t\t\t'**/dist/**',\n\t\t\t\t\t'**/.output/**',\n\t\t\t\t\t'**/.vercel/**',\n\t\t\t\t\t'**/cypress/**',\n\t\t\t\t\t'**/.{idea,git,cache,output,temp}/**',\n\t\t\t\t\t'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',\n\t\t\t\t\t'**/e2e/**',\n\t\t\t\t],\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\textends: true,\n\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\tname: 'unit',\n\t\t\t\t\t\t\tinclude: ['src/**/*.test.unit.ts'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'server',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.ts'],\n\t\t\t\t\t\t\t\texclude: ['src/**/*.test.unit.ts', 'src/**/*.test.tsx'],\n\t\t\t\t\t\t\t\ttestTimeout: 30_000,\n\t\t\t\t\t\t\t\tfileParallelism: false,\n\t\t\t\t\t\t\t\tsetupFiles: hasLocalSetup ? [localSetup] : [],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.server ?? {},\n\t\t\t\t\t),\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root), stylesPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'browser',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.tsx', 'tests/**/*.test.tsx'],\n\t\t\t\t\t\t\t\tsetupFiles: [stylesSetup],\n\t\t\t\t\t\t\t\tbrowser: {\n\t\t\t\t\t\t\t\t\tinstances: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tbrowser: 'chromium',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tprovider: playwright(),\n\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\theadless: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.browser ?? {},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t},\n\t\t}),\n\t\toverrides,\n\t)\n}\n\nconst isVitest = process.env.VITEST === 'true'\n\nfunction createFrameworkConfig(root: string) {\n\treturn defineConfig({\n\t\troot,\n\t\tresolve: {\n\t\t\ttsconfigPaths: true,\n\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\talias: [\n\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t],\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: ['recharts'],\n\t\t},\n\t\tplugins: [\n\t\t\t...(isVitest ? [] : [devtools(), nitro(), tanstackStart()]),\n\t\t\ttailwindcss(),\n\t\t\tviteReact(),\n\t\t\tbabel({ presets: [reactCompilerPreset()] }),\n\t\t\tsvgr({\n\t\t\t\tinclude: '**/*.svg',\n\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t}),\n\t\t],\n\t})\n}\n\n// Creates a full app config with customized test project overrides\nexport function createAppConfig(\n\troot: string,\n\tprojectOverrides: ProjectOverrides = {},\n\toverrides: TestProjectInlineConfiguration = {},\n) {\n\treturn {\n\t\t...workspaceConfig,\n\t\t...mergeConfig(\n\t\t\tcreateFrameworkConfig(root),\n\t\t\tcreateBaseConfig(root, overrides, projectOverrides),\n\t\t),\n\t}\n}\n\n// Helper to create config from import.meta.url\nexport function baseConfigFor(configUrl: string | URL) {\n\tconst root = dirname(fileURLToPath(configUrl))\n\treturn createAppConfig(root)\n}\n\n// Workspace-level Vite+ config shared by monorepo roots.\nexport const workspaceConfig = {\n\tfmt: {\n\t\tsingleQuote: true,\n\t\tsemi: false,\n\t\tuseTabs: true,\n\t\texperimentalTailwindcss: {},\n\t\tprintWidth: 80,\n\t\texperimentalSortPackageJson: false,\n\t\tproseWrap: 'always',\n\t\tignorePatterns: [\n\t\t\t'**/.vercel',\n\t\t\t'**/.output',\n\t\t\t'**/dist/**',\n\t\t\t'**/env.d.ts',\n\t\t\t'pnpm-lock.yaml',\n\t\t\t'**/routeTree.gen.ts',\n\t\t\t'infra/manifests/gitops/flux-system/gotk-components.yaml',\n\t\t\t'infra/charts/**/templates/**/*.{yml,yaml}',\n\t\t\t'**/charts/**',\n\t\t\t'**/*.yaml',\n\t\t\t'**/*.yml',\n\t\t],\n\t\toverrides: [\n\t\t\t{\n\t\t\t\tfiles: ['*.{yaml,yml}'],\n\t\t\t\toptions: {\n\t\t\t\t\tuseTabs: false,\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n\tlint: {\n\t\tplugins: [\n\t\t\t'eslint',\n\t\t\t'unicorn',\n\t\t\t'typescript',\n\t\t\t'oxc',\n\t\t\t'react',\n\t\t\t'react-perf',\n\t\t\t'import',\n\t\t\t'jsdoc',\n\t\t\t'jsx-a11y',\n\t\t\t'node',\n\t\t\t'promise',\n\t\t],\n\t\tcategories: {},\n\t\toptions: {\n\t\t\ttypeAware: true,\n\t\t\ttypeCheck: true,\n\t\t},\n\t\trules: {\n\t\t\t'no-empty-pattern': 'off',\n\t\t\t'no-console': ['error', { allow: ['warn', 'error'] }],\n\t\t},\n\t\tsettings: {\n\t\t\t'jsx-a11y': {\n\t\t\t\tcomponents: {},\n\t\t\t\tattributes: {},\n\t\t\t},\n\t\t\treact: {\n\t\t\t\tformComponents: [],\n\t\t\t\tlinkComponents: [],\n\t\t\t},\n\t\t\tjsdoc: {\n\t\t\t\tignorePrivate: false,\n\t\t\t\tignoreInternal: false,\n\t\t\t\tignoreReplacesDocs: true,\n\t\t\t\toverrideReplacesDocs: true,\n\t\t\t\taugmentsExtendsReplacesDocs: false,\n\t\t\t\timplementsReplacesDocs: false,\n\t\t\t\texemptDestructuredRootsFromChecks: false,\n\t\t\t\ttagNamePreference: {},\n\t\t\t},\n\t\t},\n\t\tenv: {\n\t\t\tbuiltin: true,\n\t\t},\n\t\tglobals: {},\n\t\tignorePatterns: ['**/dist/**'],\n\t\toverrides: [\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.unit.ts'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpatterns: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tgroup: ['@aamini/config-testing/test/*'],\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Unit tests should not import test fixtures. Use plain vitest imports instead.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.tsx'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpaths: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/server',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Browser tests (*.test.tsx) should use test/browser, not test/server.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/db',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Browser tests (*.test.tsx) should use test/browser, not test/db.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.ts'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpaths: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/browser',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Server tests (*.test.ts) should use test/server or test/db, not test/browser.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['apps/**'],\n\t\t\t\tplugins: ['typescript', 'react'],\n\t\t\t\trules: {\n\t\t\t\t\t'react/self-closing-comp': 'error',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.ts', '**/*.test.tsx'],\n\t\t\t\tplugins: ['typescript', 'vitest'],\n\t\t\t\trules: {\n\t\t\t\t\t'@typescript-eslint/no-explicit-any': 'off',\n\t\t\t\t\t'vitest/no-standalone-expect': [\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t{ additionalTestBlockFunctions: ['test', 'test.skip'] },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/scripts/**', '**/src/lib/imdb/**'],\n\t\t\t\trules: {\n\t\t\t\t\t'no-console': 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n\tstaged: {\n\t\t'*.{js,ts,tsx}': 'vp check --fix',\n\t},\n}\n"],"mappings":"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AAgB;IACxB,OAAO,EACN,gCAAgC,CAC/B,SACA,EACC,OAAO,CACN;KACC,MAAM;KACN,SACC;KACD,EACD;KACC,MAAM;KACN,SACC;KACD,CACD,EACD,CACD,EACD;IACD;GACD;IACC,OAAO,CAAC,eAAe;IACvB,OAAO,EACN,gCAAgC,CAC/B,SACA,EACC,OAAO,CACN;KACC,MAAM;KACN,SACC;KACD,CACD,EACD,CACD,EACD;IACD;GACD;IACC,OAAO,CAAC,UAAU;IAClB,SAAS,CAAC,cAAc,QAAQ;IAChC,OAAO,EACN,2BAA2B,SAC3B;IACD;GACD;IACC,OAAO,CAAC,gBAAgB,gBAAgB;IACxC,SAAS,CAAC,cAAc,SAAS;IACjC,OAAO;KACN,sCAAsC;KACtC,+BAA+B,CAC9B,QACA,EAAE,8BAA8B,CAAC,QAAQ,YAAY,EAAE,CACvD;KACD;IACD;GACD;IACC,OAAO,CAAC,iBAAiB,qBAAqB;IAC9C,OAAO,EACN,cAAc,OACd;IACD;GACD;EACD;CACD,QAAQ,EACP,iBAAiB,kBACjB;CACD"}
@@ -1,12 +0,0 @@
1
- import { TestProjectConfiguration, TestProjectInlineConfiguration } from "vitest/config";
2
-
3
- //#region vitest.shared.d.ts
4
- interface ProjectOverrides {
5
- server?: TestProjectConfiguration;
6
- browser?: TestProjectConfiguration;
7
- }
8
- declare const createBaseConfig: (overrides: TestProjectInlineConfiguration, projectOverrides?: ProjectOverrides) => Record<string, any>;
9
- declare const baseConfig: Record<string, any>;
10
- //#endregion
11
- export { baseConfig, createBaseConfig };
12
- //# sourceMappingURL=vitest.shared.d.mts.map
@@ -1,122 +0,0 @@
1
- import viteReact from "@vitejs/plugin-react";
2
- import tailwindcss from "@tailwindcss/vite";
3
- import svgr from "vite-plugin-svgr";
4
- import { existsSync } from "node:fs";
5
- import { resolve } from "node:path";
6
- import { defineConfig, mergeConfig } from "vitest/config";
7
- import { playwright } from "@vitest/browser-playwright";
8
- //#region vitest.shared.ts
9
- const HANDLER_LOCATIONS = [
10
- "__mocks__/handlers.ts",
11
- "__mocks__/handlers.js",
12
- "src/mocks/handlers.ts",
13
- "src/mocks/handlers.js"
14
- ];
15
- const STYLES_LOCATIONS = [
16
- "src/styles.css",
17
- "src/index.css",
18
- "src/app.css"
19
- ];
20
- function mswHandlersPlugin() {
21
- const virtualModuleId = "@test/handlers";
22
- const resolvedVirtualModuleId = "\0" + virtualModuleId;
23
- return {
24
- name: "msw-handlers-resolver",
25
- resolveId(id) {
26
- if (id === virtualModuleId) return resolvedVirtualModuleId;
27
- },
28
- load(id) {
29
- if (id === resolvedVirtualModuleId) {
30
- const cwd = process.cwd();
31
- for (const location of HANDLER_LOCATIONS) {
32
- const fullPath = resolve(cwd, location);
33
- if (existsSync(fullPath)) return `export { default } from '${fullPath}'`;
34
- }
35
- throw new Error(`No MSW handlers found. Expected one of:\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join("\n")}`);
36
- }
37
- }
38
- };
39
- }
40
- function stylesPlugin() {
41
- const virtualModuleId = "@test/styles";
42
- const resolvedVirtualModuleId = "\0" + virtualModuleId;
43
- return {
44
- name: "styles-resolver",
45
- resolveId(id) {
46
- if (id === virtualModuleId) return resolvedVirtualModuleId;
47
- },
48
- load(id) {
49
- if (id === resolvedVirtualModuleId) {
50
- const cwd = process.cwd();
51
- for (const location of STYLES_LOCATIONS) {
52
- const fullPath = resolve(cwd, location);
53
- if (existsSync(fullPath)) return `import '${fullPath}'`;
54
- }
55
- throw new Error(`No styles file found. Expected one of:\n${STYLES_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join("\n")}`);
56
- }
57
- }
58
- };
59
- }
60
- const stylesSetup = "@aamini/config/setup/styles";
61
- function asPlugins(plugins) {
62
- return plugins;
63
- }
64
- function mergeProjectConfig(base, overrides = {}) {
65
- return mergeConfig(base, overrides);
66
- }
67
- const localSetup = resolve(process.cwd(), "vitest.setup.ts");
68
- const hasLocalSetup = existsSync(localSetup);
69
- const createBaseConfig = (overrides, projectOverrides = {}) => mergeConfig(defineConfig({
70
- resolve: { tsconfigPaths: true },
71
- plugins: asPlugins([
72
- tailwindcss(),
73
- viteReact({ babel: { plugins: ["babel-plugin-react-compiler"] } }),
74
- svgr({
75
- include: "**/*.svg",
76
- svgrOptions: { exportType: "default" }
77
- })
78
- ]),
79
- test: {
80
- passWithNoTests: true,
81
- projects: [
82
- {
83
- extends: true,
84
- test: {
85
- name: "unit",
86
- include: ["src/**/*.test.unit.ts"]
87
- }
88
- },
89
- mergeProjectConfig({
90
- extends: true,
91
- plugins: [mswHandlersPlugin()],
92
- test: {
93
- name: "server",
94
- include: ["src/**/*.test.ts"],
95
- testTimeout: 3e4,
96
- fileParallelism: false,
97
- setupFiles: hasLocalSetup ? [localSetup] : []
98
- }
99
- }, projectOverrides.server ?? {}),
100
- mergeProjectConfig({
101
- extends: true,
102
- plugins: [mswHandlersPlugin(), stylesPlugin()],
103
- test: {
104
- name: "browser",
105
- include: ["src/**/*.test.tsx", "tests/**/*.test.tsx"],
106
- setupFiles: [stylesSetup],
107
- browser: {
108
- instances: [{ browser: "chromium" }],
109
- provider: playwright(),
110
- enabled: true,
111
- headless: true
112
- }
113
- }
114
- }, projectOverrides.browser ?? {})
115
- ]
116
- }
117
- }), overrides);
118
- const baseConfig = createBaseConfig({});
119
- //#endregion
120
- export { baseConfig, createBaseConfig };
121
-
122
- //# sourceMappingURL=vitest.shared.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest.shared.mjs","names":[],"sources":["../vitest.shared.ts"],"sourcesContent":["import tailwindcss from '@tailwindcss/vite'\nimport viteReact from '@vitejs/plugin-react'\nimport { playwright } from '@vitest/browser-playwright'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { Plugin } from 'vite'\nimport svgr from 'vite-plugin-svgr'\nimport {\n\tdefineConfig,\n\tmergeConfig,\n\ttype TestProjectConfiguration,\n\ttype TestProjectInlineConfiguration,\n\ttype ViteUserConfig,\n} from 'vitest/config'\n\nconst HANDLER_LOCATIONS = [\n\t'__mocks__/handlers.ts',\n\t'__mocks__/handlers.js',\n\t'src/mocks/handlers.ts',\n\t'src/mocks/handlers.js',\n]\n\nconst STYLES_LOCATIONS = ['src/styles.css', 'src/index.css', 'src/app.css']\n\nfunction mswHandlersPlugin(): Plugin {\n\tconst virtualModuleId = '@test/handlers'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'msw-handlers-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tconst cwd = process.cwd()\n\t\t\t\tfor (const location of HANDLER_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(cwd, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `export { default } from '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No MSW handlers found. Expected one of:\\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nfunction stylesPlugin(): Plugin {\n\tconst virtualModuleId = '@test/styles'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'styles-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tconst cwd = process.cwd()\n\t\t\t\tfor (const location of STYLES_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(cwd, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `import '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No styles file found. Expected one of:\\n${STYLES_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nconst stylesSetup = '@aamini/config/setup/styles'\n\nfunction asPlugins(plugins: unknown[]): NonNullable<ViteUserConfig['plugins']> {\n\treturn plugins as NonNullable<ViteUserConfig['plugins']>\n}\n\nfunction mergeProjectConfig(\n\tbase: TestProjectConfiguration,\n\toverrides: TestProjectConfiguration = {},\n): TestProjectConfiguration {\n\treturn mergeConfig(\n\t\tbase as Record<string, any>,\n\t\toverrides as Record<string, any>,\n\t) as TestProjectConfiguration\n}\n\n// Auto-detect app-level vitest.setup.ts for custom setup (e.g., MSW server)\nconst localSetup = resolve(process.cwd(), 'vitest.setup.ts')\nconst hasLocalSetup = existsSync(localSetup)\n\ninterface ProjectOverrides {\n\tserver?: TestProjectConfiguration\n\tbrowser?: TestProjectConfiguration\n}\n\nexport const createBaseConfig = (\n\toverrides: TestProjectInlineConfiguration,\n\tprojectOverrides: ProjectOverrides = {},\n) =>\n\tmergeConfig(\n\t\tdefineConfig({\n\t\t\tresolve: {\n\t\t\t\ttsconfigPaths: true,\n\t\t\t},\n\t\t\tplugins: asPlugins([\n\t\t\t\ttailwindcss(),\n\t\t\t\tviteReact({\n\t\t\t\t\tbabel: {\n\t\t\t\t\t\tplugins: ['babel-plugin-react-compiler'],\n\t\t\t\t\t},\n\t\t\t\t} as Parameters<typeof viteReact>[0]),\n\t\t\t\tsvgr({\n\t\t\t\t\tinclude: '**/*.svg',\n\t\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t\t}),\n\t\t\t]),\n\t\t\ttest: {\n\t\t\t\tpassWithNoTests: true,\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\textends: true,\n\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\tname: 'unit',\n\t\t\t\t\t\t\tinclude: ['src/**/*.test.unit.ts'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin()],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'server',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.ts'],\n\t\t\t\t\t\t\t\ttestTimeout: 30_000,\n\t\t\t\t\t\t\t\tfileParallelism: false,\n\t\t\t\t\t\t\t\tsetupFiles: hasLocalSetup ? [localSetup] : [],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.server ?? {},\n\t\t\t\t\t),\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(), stylesPlugin()],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'browser',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.tsx', 'tests/**/*.test.tsx'],\n\t\t\t\t\t\t\t\tsetupFiles: [stylesSetup],\n\t\t\t\t\t\t\t\tbrowser: {\n\t\t\t\t\t\t\t\t\tinstances: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tbrowser: 'chromium',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tprovider: playwright(),\n\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\theadless: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.browser ?? {},\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t},\n\t\t}),\n\t\toverrides,\n\t)\n\nexport const baseConfig = createBaseConfig({})\n"],"mappings":";;;;;;;;AAeA,MAAM,oBAAoB;CACzB;CACA;CACA;CACA;CACA;AAED,MAAM,mBAAmB;CAAC;CAAkB;CAAiB;CAAc;AAE3E,SAAS,oBAA4B;CACpC,MAAM,kBAAkB;CACxB,MAAM,0BAA0B,OAAO;CAEvC,OAAO;EACN,MAAM;EACN,UAAU,IAAI;GACb,IAAI,OAAO,iBACV,OAAO;;EAIT,KAAK,IAAI;GACR,IAAI,OAAO,yBAAyB;IACnC,MAAM,MAAM,QAAQ,KAAK;IACzB,KAAK,MAAM,YAAY,mBAAmB;KACzC,MAAM,WAAW,QAAQ,KAAK,SAAS;KACvC,IAAI,WAAW,SAAS,EACvB,OAAO,4BAA4B,SAAS;;IAG9C,MAAM,IAAI,MACT,4CAA4C,kBAAkB,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,GAC7G;;;EAIH;;AAGF,SAAS,eAAuB;CAC/B,MAAM,kBAAkB;CACxB,MAAM,0BAA0B,OAAO;CAEvC,OAAO;EACN,MAAM;EACN,UAAU,IAAI;GACb,IAAI,OAAO,iBACV,OAAO;;EAIT,KAAK,IAAI;GACR,IAAI,OAAO,yBAAyB;IACnC,MAAM,MAAM,QAAQ,KAAK;IACzB,KAAK,MAAM,YAAY,kBAAkB;KACxC,MAAM,WAAW,QAAQ,KAAK,SAAS;KACvC,IAAI,WAAW,SAAS,EACvB,OAAO,WAAW,SAAS;;IAG7B,MAAM,IAAI,MACT,2CAA2C,iBAAiB,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,GAC3G;;;EAIH;;AAGF,MAAM,cAAc;AAEpB,SAAS,UAAU,SAA4D;CAC9E,OAAO;;AAGR,SAAS,mBACR,MACA,YAAsC,EAAE,EACb;CAC3B,OAAO,YACN,MACA,UACA;;AAIF,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,kBAAkB;AAC5D,MAAM,gBAAgB,WAAW,WAAW;AAO5C,MAAa,oBACZ,WACA,mBAAqC,EAAE,KAEvC,YACC,aAAa;CACZ,SAAS,EACR,eAAe,MACf;CACD,SAAS,UAAU;EAClB,aAAa;EACb,UAAU,EACT,OAAO,EACN,SAAS,CAAC,8BAA8B,EACxC,EACD,CAAoC;EACrC,KAAK;GACJ,SAAS;GACT,aAAa,EAAE,YAAY,WAAW;GACtC,CAAC;EACF,CAAC;CACF,MAAM;EACL,iBAAiB;EACjB,UAAU;GACT;IACC,SAAS;IACT,MAAM;KACL,MAAM;KACN,SAAS,CAAC,wBAAwB;KAClC;IACD;GACD,mBACC;IACC,SAAS;IACT,SAAS,CAAC,mBAAmB,CAAC;IAC9B,MAAM;KACL,MAAM;KACN,SAAS,CAAC,mBAAmB;KAC7B,aAAa;KACb,iBAAiB;KACjB,YAAY,gBAAgB,CAAC,WAAW,GAAG,EAAE;KAC7C;IACD,EACD,iBAAiB,UAAU,EAAE,CAC7B;GACD,mBACC;IACC,SAAS;IACT,SAAS,CAAC,mBAAmB,EAAE,cAAc,CAAC;IAC9C,MAAM;KACL,MAAM;KACN,SAAS,CAAC,qBAAqB,sBAAsB;KACrD,YAAY,CAAC,YAAY;KACzB,SAAS;MACR,WAAW,CACV,EACC,SAAS,YACT,CACD;MACD,UAAU,YAAY;MACtB,SAAS;MACT,UAAU;MACV;KACD;IACD,EACD,iBAAiB,WAAW,EAAE,CAC9B;GACD;EACD;CACD,CAAC,EACF,UACA;AAEF,MAAa,aAAa,iBAAiB,EAAE,CAAC"}
package/msw.ts DELETED
@@ -1,5 +0,0 @@
1
- // Re-export msw to ensure all packages use the same instance
2
- export { http, HttpResponse, graphql } from 'msw'
3
- export { setupWorker } from 'msw/browser'
4
- export type { RequestHandler } from 'msw'
5
- export type { SetupWorker } from 'msw/browser'
@@ -1,71 +0,0 @@
1
- import {
2
- defineConfig,
3
- devices,
4
- type PlaywrightTestConfig,
5
- } from '@playwright/test'
6
-
7
- /** See https://playwright.dev/docs/test-configuration. */
8
- export const baseConfig = async (overrides?: PlaywrightTestConfig) => {
9
- return defineConfig(
10
- {
11
- testDir: './e2e',
12
- outputDir: '.playwright/test-results',
13
- /* Run tests in files in parallel */
14
- fullyParallel: true,
15
- // Opt out of parallel tests on CI.
16
- workers: process.env.CI ? 1 : '50%',
17
- /* Fail the build on CI if you accidentally left test.only in the source code. */
18
- forbidOnly: !!process.env.CI,
19
- retries: process.env.CI ? 3 : 0,
20
- /* Reporter to use. See https://playwright.dev/docs/test-reporters */
21
- reporter: [
22
- ['html', { open: 'never', outputFolder: '.playwright/report' }],
23
- ],
24
-
25
- /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
26
- use: {
27
- colorScheme: 'dark',
28
-
29
- /* Base URL to use in actions like `await page.goto('/')`. */
30
- baseURL: process.env.BASE_URL,
31
-
32
- /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
33
- trace: 'retain-on-first-failure',
34
- screenshot: 'on',
35
- video: 'retain-on-failure',
36
- },
37
-
38
- timeout: 15_000,
39
- expect: {
40
- timeout: 5_000,
41
- },
42
-
43
- /* Configure projects for major browsers */
44
- projects: [
45
- {
46
- name: 'chromium',
47
- use: {
48
- ...devices['Desktop Chrome'],
49
- launchOptions: {
50
- args: ['--disable-lcd-text'],
51
- },
52
- },
53
- },
54
- {
55
- name: 'mobile',
56
- use: {
57
- ...devices['Desktop Chrome'],
58
- viewport: {
59
- width: 320,
60
- height: 800,
61
- },
62
- launchOptions: {
63
- args: ['--disable-lcd-text'],
64
- },
65
- },
66
- },
67
- ],
68
- },
69
- overrides ?? {},
70
- )
71
- }
package/setup/styles.ts DELETED
@@ -1,4 +0,0 @@
1
- // oxlint-disable typescript-eslint/triple-slash-reference
2
- /// <reference path="../virtual-modules.d.ts" />
3
- import '@testing-library/jest-dom/vitest'
4
- import '@test/styles'
package/test/browser.ts DELETED
@@ -1,44 +0,0 @@
1
- // oxlint-disable typescript-eslint/triple-slash-reference
2
- /// <reference path="../virtual-modules.d.ts" />
3
- // oxlint-disable no-empty-pattern
4
- import { setupWorker, type SetupWorker } from 'msw/browser'
5
- import { test as baseTest } from 'vitest'
6
- import type { TestAPI } from 'vitest'
7
-
8
- export interface MswBrowserFixture {
9
- worker: SetupWorker
10
- _cleanup: void
11
- }
12
-
13
- let workerSingleton: SetupWorker | undefined
14
-
15
- async function ensureWorker(): Promise<SetupWorker> {
16
- if (!workerSingleton) {
17
- const { default: handlers } = await import('@test/handlers')
18
- workerSingleton = setupWorker(...handlers)
19
- }
20
- return workerSingleton
21
- }
22
-
23
- const extended = baseTest.extend<MswBrowserFixture>({
24
- worker: [
25
- async ({}, use) => {
26
- const worker = await ensureWorker()
27
- await worker.start({ quiet: true, onUnhandledRequest: 'bypass' })
28
- await use(worker)
29
- worker.stop()
30
- },
31
- { auto: true, scope: 'worker' },
32
- ],
33
- _cleanup: [
34
- async ({ worker }, use) => {
35
- await use()
36
- worker.resetHandlers()
37
- },
38
- { auto: true },
39
- ],
40
- })
41
-
42
- export { afterEach, beforeEach, describe, expect, vi } from 'vitest'
43
-
44
- export const test = extended as TestAPI<MswBrowserFixture>
package/test/database.ts DELETED
@@ -1,38 +0,0 @@
1
- import type { NodePgDatabase } from 'drizzle-orm/node-postgres'
2
- import type { Pool } from 'pg'
3
-
4
- // Convention: schema at src/db/tables.ts, migrations at src/db/migrations/
5
- const DEFAULT_EXTENSIONS = ['pg_trgm']
6
-
7
- export type Database = NodePgDatabase & {
8
- $client: Pool
9
- }
10
-
11
- export interface SeedDatabaseOptions {
12
- schemaPath: string
13
- migrationsFolder: string
14
- seedFunction?: (db: Database) => Promise<void>
15
- extensions?: string[]
16
- }
17
-
18
- export async function seedDatabase(
19
- db: Database,
20
- {
21
- schemaPath,
22
- migrationsFolder,
23
- seedFunction,
24
- extensions = DEFAULT_EXTENSIONS,
25
- }: SeedDatabaseOptions,
26
- ) {
27
- const { migrate } = await import('drizzle-orm/node-postgres/migrator')
28
- const { reset } = await import('drizzle-seed')
29
-
30
- const schema = await import(/* @vite-ignore */ schemaPath)
31
-
32
- for (const ext of extensions) {
33
- await db.execute(`CREATE EXTENSION IF NOT EXISTS "${ext}"`)
34
- }
35
- await migrate(db, { migrationsFolder })
36
- await reset(db, schema)
37
- if (seedFunction) await seedFunction(db)
38
- }
package/test/db.ts DELETED
@@ -1,86 +0,0 @@
1
- // oxlint-disable no-empty-pattern
2
- import { setupServer, SetupServer } from 'msw/node'
3
- import { resolve } from 'node:path'
4
- import { test as baseTest } from 'vitest'
5
- import type { TestAPI } from 'vitest'
6
- import type { Database } from './database'
7
- import { seedDatabase } from './database'
8
- import { findHandlerPath } from './internal'
9
-
10
- const DEFAULT_SCHEMA_PATH = 'src/db/tables.ts'
11
- const DEFAULT_MIGRATIONS_PATH = 'src/db/migrations'
12
- const DEFAULT_IMAGE = 'postgres:17'
13
-
14
- export interface DbFixture {
15
- server: SetupServer
16
- _cleanup: void
17
- db: Database
18
- seedFunction: (db: Database) => Promise<void>
19
- }
20
-
21
- let mswServer: SetupServer | undefined
22
-
23
- async function ensureMswServer(): Promise<SetupServer> {
24
- if (!mswServer) {
25
- const { default: handlers } = await import(findHandlerPath())
26
- mswServer = setupServer(...handlers)
27
- }
28
- return mswServer
29
- }
30
-
31
- let extended = baseTest.extend<DbFixture>({
32
- server: [
33
- async ({}, use) => {
34
- const server = await ensureMswServer()
35
- server.listen({ onUnhandledRequest: 'bypass' })
36
- await use(server)
37
- server.close()
38
- },
39
- { auto: true, scope: 'worker' },
40
- ],
41
- _cleanup: [
42
- async ({ server }, use) => {
43
- await use()
44
- server.resetHandlers()
45
- },
46
- { auto: true },
47
- ],
48
- seedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],
49
- db: [
50
- async ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {
51
- const { PostgreSqlContainer } = await import('@testcontainers/postgresql')
52
- const { drizzle } = await import('drizzle-orm/node-postgres')
53
- const { Wait } = await import('testcontainers')
54
- const { Pool } = await import('pg')
55
-
56
- const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)
57
- const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)
58
-
59
- const container = await new PostgreSqlContainer(DEFAULT_IMAGE)
60
- .withWaitStrategy(Wait.forHealthCheck())
61
- .start()
62
- const db = drizzle({
63
- client: new Pool({ connectionString: container.getConnectionUri() }),
64
- }) as Database
65
-
66
- try {
67
- await seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })
68
- await use(db)
69
- } finally {
70
- await db.$client.end()
71
- await container.stop()
72
- }
73
- },
74
- { scope: 'file' },
75
- ],
76
- })
77
-
78
- export { afterEach, beforeEach, describe, expect, vi } from 'vitest'
79
-
80
- export const test = extended as TestAPI<DbFixture>
81
-
82
- export function initDb(seedFunction: (db: Database) => Promise<void>) {
83
- extended = extended.override({
84
- seedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],
85
- }) as typeof extended
86
- }
package/test/internal.ts DELETED
@@ -1,45 +0,0 @@
1
- import { existsSync } from 'node:fs'
2
- import { resolve } from 'node:path'
3
-
4
- export const HANDLER_LOCATIONS = [
5
- '__mocks__/handlers.ts',
6
- '__mocks__/handlers.js',
7
- 'src/mocks/handlers.ts',
8
- 'src/mocks/handlers.js',
9
- ]
10
-
11
- export function findHandlerPath(): string {
12
- if (typeof process === 'undefined') {
13
- return ''
14
- }
15
- const cwd = process.cwd()
16
- for (const location of HANDLER_LOCATIONS) {
17
- const fullPath = resolve(cwd, location)
18
- if (existsSync(fullPath)) return fullPath
19
- }
20
- throw new Error(
21
- `No MSW handlers found. Expected one of:\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join('\n')}`,
22
- )
23
- }
24
-
25
- export function createProxy<T extends object>(getTarget: () => T): T {
26
- const handlers: ProxyHandler<object> = {
27
- get(_, prop) {
28
- return Reflect.get(getTarget(), prop, getTarget())
29
- },
30
- apply(target, thisArg, args) {
31
- return Reflect.apply(getTarget() as any, thisArg, args)
32
- },
33
- has(_, prop) {
34
- return prop in getTarget()
35
- },
36
- ownKeys() {
37
- return Reflect.ownKeys(getTarget())
38
- },
39
- getOwnPropertyDescriptor(_, prop) {
40
- return Reflect.getOwnPropertyDescriptor(getTarget(), prop)
41
- },
42
- }
43
- const proxyTarget = () => {}
44
- return new Proxy(proxyTarget, handlers) as T
45
- }
@@ -1,17 +0,0 @@
1
- import { readFile } from 'node:fs/promises'
2
- import type { Page } from '@playwright/test'
3
-
4
- export async function mockJsonRoute(
5
- page: Page,
6
- url: string | RegExp,
7
- fixtureUrl: URL,
8
- ) {
9
- await page.route(url, async (route) => {
10
- const body = await readFile(fixtureUrl, 'utf8')
11
-
12
- await route.fulfill({
13
- contentType: 'application/json',
14
- body,
15
- })
16
- })
17
- }
package/test/postgres.ts DELETED
@@ -1,43 +0,0 @@
1
- import {
2
- PostgreSqlContainer,
3
- type StartedPostgreSqlContainer,
4
- } from '@testcontainers/postgresql'
5
- import { Wait } from 'testcontainers'
6
-
7
- type State = {
8
- container: StartedPostgreSqlContainer
9
- databaseUrl: string
10
- }
11
-
12
- let state: State | undefined
13
-
14
- export async function ensurePostgresContainer() {
15
- const databaseUrl = process.env.DATABASE_URL
16
- if (databaseUrl) {
17
- return {
18
- databaseUrl,
19
- }
20
- }
21
-
22
- if (!state) {
23
- const container = await new PostgreSqlContainer('postgres:17')
24
- .withDatabase('imdbgraph')
25
- .withUsername('imdbgraph')
26
- .withPassword('imdbgraph')
27
- .withWaitStrategy(Wait.forHealthCheck())
28
- .start()
29
-
30
- state = {
31
- container,
32
- databaseUrl: container.getConnectionUri(),
33
- }
34
- }
35
-
36
- return state
37
- }
38
-
39
- export async function stopPostgresContainer() {
40
- if (!state) return
41
- await state.container.stop()
42
- state = undefined
43
- }
package/test/server.ts DELETED
@@ -1,43 +0,0 @@
1
- // oxlint-disable no-empty-pattern
2
- import { setupServer, type SetupServer } from 'msw/node'
3
- import { test as baseTest } from 'vitest'
4
- import type { TestAPI } from 'vitest'
5
- import { findHandlerPath } from './internal'
6
-
7
- export interface MswServerFixture {
8
- server: SetupServer
9
- _cleanup: void
10
- }
11
-
12
- let mswServer: SetupServer | undefined
13
-
14
- async function ensureMswServer(): Promise<SetupServer> {
15
- if (!mswServer) {
16
- const { default: handlers } = await import(findHandlerPath())
17
- mswServer = setupServer(...handlers)
18
- }
19
- return mswServer
20
- }
21
-
22
- const extended = baseTest.extend<MswServerFixture>({
23
- server: [
24
- async ({}, use) => {
25
- const server = await ensureMswServer()
26
- server.listen({ onUnhandledRequest: 'bypass' })
27
- await use(server)
28
- server.close()
29
- },
30
- { auto: true, scope: 'worker' },
31
- ],
32
- _cleanup: [
33
- async ({ server }, use) => {
34
- await use()
35
- server.resetHandlers()
36
- },
37
- { auto: true },
38
- ],
39
- })
40
-
41
- export { afterEach, beforeEach, describe, expect, vi } from 'vitest'
42
-
43
- export const test = extended as TestAPI<MswServerFixture>
@@ -1,57 +0,0 @@
1
- import { createElement, type ComponentType, type ReactNode } from 'react'
2
- import { expect } from 'vitest'
3
- import { page, type Locator } from 'vitest/browser'
4
- import { render, type RenderResult } from 'vitest-browser-react'
5
-
6
- interface Viewport {
7
- width: number
8
- height: number
9
- }
10
-
11
- interface ExpectComponentScreenshotOptions {
12
- component: ComponentType
13
- name: string
14
- waitFor: (screen: RenderResult) => Locator
15
- prepare?: ((screen: RenderResult) => void | Promise<void>) | undefined
16
- target?: ((screen: RenderResult) => Locator) | undefined
17
- setup?: (() => void | Promise<void>) | undefined
18
- wrapper?: ComponentType<{ children: ReactNode }> | undefined
19
- viewport?: Viewport | undefined
20
- fullPage?: boolean | undefined
21
- }
22
-
23
- export async function expectComponentScreenshot({
24
- component,
25
- name,
26
- waitFor,
27
- prepare,
28
- target = (screen) => screen.locator,
29
- setup,
30
- wrapper,
31
- viewport = { width: 1280, height: 720 },
32
- fullPage = true,
33
- }: ExpectComponentScreenshotOptions) {
34
- localStorage.clear()
35
- document.body.replaceChildren()
36
- await setup?.()
37
- await page.viewport(viewport.width, viewport.height)
38
-
39
- const container = document.body.appendChild(document.createElement('div'))
40
- container.style.width = '100vw'
41
- container.style.minHeight = '100vh'
42
-
43
- const screen = await render(
44
- createElement(component),
45
- wrapper ? { container, wrapper } : { container },
46
- )
47
-
48
- await prepare?.(screen)
49
- await expect.element(waitFor(screen)).toBeVisible()
50
- await document.fonts.ready
51
- if (fullPage) {
52
- await page.viewport(viewport.width, Math.ceil(container.scrollHeight))
53
- }
54
- await expect.element(target(screen)).toMatchScreenshot(`${name}.png`, {
55
- screenshotOptions: { scale: 'css' },
56
- })
57
- }