From 6be68f027b7e914627df8e0382e104b8c36dc493 Mon Sep 17 00:00:00 2001 From: Varixo Date: Fri, 25 Apr 2025 10:25:58 +0200 Subject: [PATCH 1/2] fix: unit tests on Windows --- packages/qwik/src/cli/add/update-files.ts | 17 ++++++++++----- .../src/optimizer/src/plugins/plugin.unit.ts | 21 ++++++++++++------- .../qwik/src/optimizer/src/plugins/rollup.ts | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/qwik/src/cli/add/update-files.ts b/packages/qwik/src/cli/add/update-files.ts index 875c8dce0d0..2244ff67d0f 100644 --- a/packages/qwik/src/cli/add/update-files.ts +++ b/packages/qwik/src/cli/add/update-files.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import { extname, join } from 'node:path'; +import { extname, join, normalize } from 'node:path'; import type { FsUpdates, UpdateAppOptions } from '../types'; import { getPackageManager } from '../utils/utils'; @@ -22,12 +22,18 @@ export async function mergeIntegrationDir( const s = await fs.promises.stat(srcChildPath); if (s.isDirectory()) { - await mergeIntegrationDir(fileUpdates, opts, srcChildPath, destRootPath, alwaysInRoot); + await mergeIntegrationDir( + fileUpdates, + opts, + srcChildPath, + normalize(destRootPath).replace(/\\/g, '/'), + alwaysInRoot + ); } else if (s.isFile()) { const finalDestPath = getFinalDestPath(opts, destRootPath, destDir, destName, alwaysInRoot); if (destName === 'package.json') { - await mergePackageJsons(fileUpdates, srcChildPath, destRootPath); + await mergePackageJsons(fileUpdates, srcChildPath, destRootPath.replace(/\\/g, '/')); } else if (destName === 'settings.json') { await mergeJsons(fileUpdates, srcChildPath, finalDestPath); } else if (destName === 'README.md') { @@ -37,7 +43,7 @@ export async function mergeIntegrationDir( destName === '.prettierignore' || destName === '.eslintignore' ) { - await mergeIgnoresFile(fileUpdates, srcChildPath, destRootPath); + await mergeIgnoresFile(fileUpdates, srcChildPath, destRootPath.replace(/\\/g, '/')); } else if (ext === '.css') { await mergeCss(fileUpdates, srcChildPath, finalDestPath, opts); } else if (fs.existsSync(finalDestPath)) { @@ -79,7 +85,8 @@ function getFinalDestPath( ? destRootPath : destChildPath; - return finalDestPath; + // Normalize path separators to forward slashes for cross-platform compatibility + return normalize(finalDestPath).replace(/\\/g, '/'); } async function mergePackageJsons(fileUpdates: FsUpdates, srcPath: string, destPath: string) { diff --git a/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts b/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts index 67a4c8fab74..86ce44f3417 100644 --- a/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts +++ b/packages/qwik/src/optimizer/src/plugins/plugin.unit.ts @@ -1,9 +1,10 @@ import path, { resolve } from 'node:path'; import { assert, describe, expect, test } from 'vitest'; +import { normalizePath } from '../../../testing/util'; import type { QwikManifest } from '../types'; import { ExperimentalFeatures, createQwikPlugin } from './plugin'; -import { normalizePath } from '../../../testing/util'; import { qwikVite } from './vite'; +import type { ResolvedId } from 'rollup'; const cwd = process.cwd(); @@ -244,18 +245,22 @@ describe('resolveId', () => { ).toHaveProperty('id', '/root/src/routes/layout.tsx_s_7xk04rim0vu.js'); expect(await plugin.resolveId(null!, './foo', '/root/src/routes/layout.tsx')).toBeFalsy(); expect( - await plugin.resolveId( - ctx, - './layout.tsx_layout_component_usetask_1_7xk04rim0vu.js', - '/root/src/routes/layout.tsx' - ) - ).toHaveProperty('id', '/root/src/routes/layout.tsx_layout_component_usetask_1_7xk04rim0vu.js'); + ( + (await plugin.resolveId( + ctx, + './layout.tsx_layout_component_usetask_1_7xk04rim0vu.js', + '/root/src/routes/layout.tsx' + )) as ResolvedId + ).id + ).toContain('/root/src/routes/layout.tsx_layout_component_usetask_1_7xk04rim0vu.js'); // this uses the already populated id we created above expect( await plugin.resolveId( { resolve: (id: string, importer: string) => { - expect(id).toBe('/root/src/routes/foo'); + expect(id).toContain( + process.platform === 'win32' ? '\\root\\src\\routes\\foo' : '/root/src/routes/foo' + ); expect(importer).toBe('Yey'); return { id: 'hi' }; }, diff --git a/packages/qwik/src/optimizer/src/plugins/rollup.ts b/packages/qwik/src/optimizer/src/plugins/rollup.ts index ba3002f4d24..3d021aaa6ac 100644 --- a/packages/qwik/src/optimizer/src/plugins/rollup.ts +++ b/packages/qwik/src/optimizer/src/plugins/rollup.ts @@ -190,7 +190,7 @@ export function normalizeRollupOutputOptionsObject( const sanitized = relativePath .replace(/^(\.\.\/)+/, '') .replace(/^\/+/, '') - .replace(/\//g, '-'); + .replace(/[\\/]/g, '-'); return `build/${sanitized}.js`; }; } From 942bdc50b228aee86fe55089f7c51dfe965a0e9a Mon Sep 17 00:00:00 2001 From: Varixo Date: Fri, 25 Apr 2025 10:29:00 +0200 Subject: [PATCH 2/2] chore: add Windows to the unit tests CI --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5642afafcd9..ccebc7cfe96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -615,7 +615,13 @@ jobs: test-unit: name: Unit Tests if: always() && needs.changes.outputs.build-unit == 'true' - runs-on: ubuntu-latest + strategy: + matrix: + settings: + - host: ubuntu-latest + - host: windows-latest + + runs-on: ${{ matrix.settings.host }} needs: - changes - build-other-packages