(test) use nuxt environment for integrated pages testing

This commit is contained in:
Valentyne Stigloher 2024-08-11 12:22:05 +02:00
parent 60d245783f
commit 8c554a38fd
11 changed files with 129 additions and 15 deletions

5
app/router.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import type { RouteRecordRaw } from 'vue-router';
declare global {
var originalRoutes: readonly RouteRecordRaw[];
}

View File

@ -2,6 +2,11 @@ import type { RouterOptions } from '@nuxt/schema';
const routerOptions: RouterOptions = {
routes: (routes) => {
if (process.env.TEST) {
// workaround as there is no way to retrieve the original page routes
// which get overridden in the nuxt test environment by this router options
global.originalRoutes = routes;
}
const config = useConfig();
return routes.flatMap((route) => {
if (route.meta?.translatedPaths) {

View File

@ -1,7 +1,7 @@
import './src/dotenv.ts';
import { loadSuml } from './server/loader.ts';
import fs from 'fs';
import fs from 'node:fs';
import path from 'path';
import { defineNuxtConfig } from 'nuxt/config';
import { nodePolyfills } from 'vite-plugin-node-polyfills';

View File

@ -119,6 +119,7 @@
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@vitest/coverage-v8": "^2.0.3",
"@vue/test-utils": "^2.4.6",
"avris-daemonise": "^0.0.2",
"bootstrap": "^5.3.1",
"clipboard": "^2.0.6",

View File

@ -1,4 +1,4 @@
import fs from 'fs';
import fs from 'node:fs';
import Suml from 'suml';
import type { TransformResult, Plugin } from 'rollup';

View File

@ -1,4 +1,4 @@
import fs from 'fs';
import fs from 'node:fs';
import Papa from 'papaparse';
import type { TransformResult, Plugin } from 'rollup';

94
pnpm-lock.yaml generated
View File

@ -222,7 +222,7 @@ devDependencies:
version: git/gitlab.com+Avris/FontAwesomePro/f00db606f659dca78b143b7bcab5671b2cb459a8
'@nuxt/test-utils':
specifier: ^3.14.1
version: 3.14.1(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
version: 3.14.1(@vue/test-utils@2.4.6)(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
'@rollup/plugin-replace':
specifier: ^5.0.7
version: 5.0.7(rollup@4.21.0)
@ -313,6 +313,9 @@ devDependencies:
'@vitest/coverage-v8':
specifier: ^2.0.3
version: 2.0.5(vitest@2.0.5)
'@vue/test-utils':
specifier: ^2.4.6
version: 2.4.6
avris-daemonise:
specifier: ^0.0.2
version: 0.0.2
@ -3877,7 +3880,7 @@ packages:
- webpack-sources
dev: false
/@nuxt/test-utils@3.14.1(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3):
/@nuxt/test-utils@3.14.1(@vue/test-utils@2.4.6)(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3):
resolution: {integrity: sha512-D8F18hnOHQSarKnzsLORRXzFPlI9Y5fcQFRKwJgGhnejlIRX6sFvVnyl2SDgCvoV+F2x2czQsdGkwg51iWAshA==}
engines: {node: '>=18.20.4'}
peerDependencies:
@ -3920,6 +3923,7 @@ packages:
dependencies:
'@nuxt/kit': 3.13.1(magicast@0.3.4)(rollup@4.21.0)
'@nuxt/schema': 3.13.1(rollup@4.21.0)
'@vue/test-utils': 2.4.6
c12: 1.11.2(magicast@0.3.4)
consola: 3.2.3
defu: 6.1.4
@ -3945,7 +3949,7 @@ packages:
unplugin: 1.13.1
vite: 5.4.3(@types/node@20.11.5)(sass@1.32.12)
vitest: 2.0.5(@types/node@20.11.5)(jsdom@24.1.3)(sass@1.32.12)
vitest-environment-nuxt: 1.0.1(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
vitest-environment-nuxt: 1.0.1(@vue/test-utils@2.4.6)(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
vue: 3.5.3(typescript@5.5.2)
vue-router: 4.4.3(vue@3.5.3)
transitivePeerDependencies:
@ -4033,6 +4037,10 @@ packages:
- webpack-sources
dev: false
/@one-ini/wasm@0.1.1:
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
dev: true
/@parcel/watcher-android-arm64@2.4.1:
resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
engines: {node: '>= 10.0.0'}
@ -6272,6 +6280,13 @@ packages:
/@vue/shared@3.5.3:
resolution: {integrity: sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==}
/@vue/test-utils@2.4.6:
resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==}
dependencies:
js-beautify: 1.15.1
vue-component-type-helpers: 2.1.6
dev: true
/@vuepic/vue-datepicker@8.8.1(vue@3.5.3):
resolution: {integrity: sha512-8ehfUz1m69Vuc16Pm4ukgb3Mg1VT14x4EsG1ag4O/qbSNRWztTo+pUV4JnFt0FGLl5gGb6NXlxIvR7EjLgD7Gg==}
peerDependencies:
@ -6419,6 +6434,11 @@ packages:
/abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
/abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dev: true
/abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@ -7747,6 +7767,11 @@ packages:
dependencies:
delayed-stream: 1.0.0
/commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
dev: true
/commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
@ -7808,6 +7833,13 @@ packages:
/confbox@0.1.7:
resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==}
/config-chain@1.1.13:
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
dependencies:
ini: 1.3.8
proto-list: 1.2.4
dev: true
/consola@3.2.3:
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
engines: {node: ^14.18.0 || >=16.10.0}
@ -8619,6 +8651,17 @@ packages:
safe-buffer: 5.2.1
dev: false
/editorconfig@1.0.4:
resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
engines: {node: '>=14'}
hasBin: true
dependencies:
'@one-ini/wasm': 0.1.1
commander: 10.0.1
minimatch: 9.0.1
semver: 7.6.3
dev: true
/ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@ -10724,7 +10767,6 @@ packages:
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: false
/ini@4.1.1:
resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
@ -11314,6 +11356,23 @@ packages:
resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==}
dev: false
/js-beautify@1.15.1:
resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==}
engines: {node: '>=14'}
hasBin: true
dependencies:
config-chain: 1.1.13
editorconfig: 1.0.4
glob: 10.4.5
js-cookie: 3.0.5
nopt: 7.2.1
dev: true
/js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
dev: true
/js-md5@0.7.3:
resolution: {integrity: sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==}
dev: false
@ -12181,6 +12240,13 @@ packages:
brace-expansion: 2.0.1
dev: true
/minimatch@9.0.1:
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dev: true
/minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
@ -12664,6 +12730,14 @@ packages:
dependencies:
abbrev: 1.1.1
/nopt@7.2.1:
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
hasBin: true
dependencies:
abbrev: 2.0.0
dev: true
/normalize-package-data@2.5.0:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
dependencies:
@ -13908,6 +13982,10 @@ packages:
resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==}
dev: false
/proto-list@1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
dev: true
/protocols@2.0.1:
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
dev: false
@ -16695,10 +16773,10 @@ packages:
optionalDependencies:
fsevents: 2.3.3
/vitest-environment-nuxt@1.0.1(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3):
/vitest-environment-nuxt@1.0.1(@vue/test-utils@2.4.6)(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3):
resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==}
dependencies:
'@nuxt/test-utils': 3.14.1(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
'@nuxt/test-utils': 3.14.1(@vue/test-utils@2.4.6)(h3@1.12.0)(jsdom@24.1.3)(nitropack@2.9.7)(rollup@4.21.0)(vite@5.4.3)(vitest@2.0.5)(vue-router@4.4.3)(vue@3.5.3)
transitivePeerDependencies:
- '@cucumber/cucumber'
- '@jest/globals'
@ -16827,6 +16905,10 @@ packages:
ufo: 1.5.4
dev: false
/vue-component-type-helpers@2.1.6:
resolution: {integrity: sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==}
dev: true
/vue-demi@0.14.10(vue@3.5.3):
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}

View File

@ -1,4 +1,4 @@
import fs from 'fs';
import fs from 'node:fs';
import Suml from 'suml';
import { loadTsv as baseLoadTsv } from '../src/tsv.ts';

View File

@ -1,5 +1,5 @@
import Papa from 'papaparse';
import fs from 'fs';
import fs from 'node:fs';
export const tsvParseConfig = {
dynamicTyping: true,

View File

@ -1,8 +1,13 @@
import { beforeEach, describe, expect, test, vi } from 'vitest';
// @vitest-environment nuxt
import { mockNuxtImport } from '@nuxt/test-utils/runtime';
import { beforeAll, describe, expect, test, vi } from 'vitest';
import pathToRegexp from 'path-to-regexp';
import type { NuxtPage } from '@nuxt/schema';
import type { SyncExpectationResult, MatcherState } from '@vitest/expect';
import type { RouteRecordRaw } from 'vue-router';
import routerOptions from '../../app/router.options.ts';
import { loadSumlFromBase } from '../../server/loader.ts';
import allLocales from '../../locale/locales.ts';
import { deepGet, deepListKeys } from '../../src/helpers.ts';
@ -84,13 +89,22 @@ function toBeValidPath(this: MatcherState, actual: string, paths: RegExp[], key:
}
}
const { useConfigMock } = vi.hoisted(() => ({
useConfigMock: vi.fn().mockImplementation(() => null),
}));
mockNuxtImport('useConfig', () => useConfigMock);
const pathRegex = /\{(\/[^}]+?)(?:#[^}]+)?=[^}]+\}/g;
describe.each(allLocales)('translations for $code', ({ code, published }) => {
const config = loadSumlFromBase(`locale/${code}/config`);
const translations = loadSumlFromBase(`locale/${code}/translations`) as Translations;
beforeEach(() => {
beforeAll(() => {
// for router.options.ts
useConfigMock.mockImplementation(() => config);
// for pages:extend hook in nuxt.config.ts
vi.doMock('../../server/loader.ts', () => {
return {
loadSuml(name: string): unknown {
@ -117,8 +131,10 @@ describe.each(allLocales)('translations for $code', ({ code, published }) => {
vi.resetModules();
const { default: nuxtConfig } = await import('../../nuxt.config.ts');
const routes: NuxtPage[] = [];
nuxtConfig.hooks!['pages:extend']!(routes);
const baseRoutes = routerOptions.routes!(global.originalRoutes) as RouteRecordRaw[];
const extendedRoutes: NuxtPage[] = [];
nuxtConfig.hooks!['pages:extend']!(extendedRoutes);
const routes = [...baseRoutes, ...extendedRoutes];
const paths = routes.filter((route) => route.name !== 'all').map((route) => pathToRegexp(route.path));
for (const key of deepListKeys(translations)) {

View File

@ -7,5 +7,10 @@ export default defineVitestConfig({
include: ['plugins/**', 'server/**', 'src/**', 'store/**'],
reporter: ['text', 'cobertura'],
},
environmentOptions: {
nuxt: {
domEnvironment: 'jsdom',
},
},
},
});