From b809f1c0956a3d29596d0499b1cdb1793786db80 Mon Sep 17 00:00:00 2001 From: Xevion Date: Tue, 30 Dec 2025 12:28:14 -0600 Subject: [PATCH] fix: address ESLint warnings and add Vitest configuration - Add ESLint flat config with Svelte and TypeScript support - Fix unused variables and component prop naming - Add Vitest browser testing setup with Playwright - Configure separate test projects for client and server code --- pacman-server/src/auth/mod.rs | 5 ++ pacman-server/src/data/pool.rs | 2 +- web/eslint.config.js | 33 ++++++++++++++ web/src/demo.spec.ts | 7 +++ web/src/lib/components/NavLink.svelte | 4 +- web/src/routes/+layout.svelte | 4 +- web/src/routes/+page.svelte | 2 +- web/src/routes/page.svelte.spec.ts | 13 ++++++ web/vite-plugin-font-subset.ts | 13 +----- web/vite.config.ts | 66 ++++++++++++++++++++++----- 10 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 web/eslint.config.js create mode 100644 web/src/demo.spec.ts create mode 100644 web/src/routes/page.svelte.spec.ts diff --git a/pacman-server/src/auth/mod.rs b/pacman-server/src/auth/mod.rs index 6e524d5..460f8ea 100644 --- a/pacman-server/src/auth/mod.rs +++ b/pacman-server/src/auth/mod.rs @@ -84,4 +84,9 @@ impl AuthRegistry { pub fn len(&self) -> usize { self.providers.len() } + + #[allow(dead_code)] + pub fn is_empty(&self) -> bool { + self.providers.is_empty() + } } diff --git a/pacman-server/src/data/pool.rs b/pacman-server/src/data/pool.rs index 0c1d1b4..6bd068c 100644 --- a/pacman-server/src/data/pool.rs +++ b/pacman-server/src/data/pool.rs @@ -6,7 +6,7 @@ pub type PgPool = Pool; /// Create a PostgreSQL database pool. /// /// - `immediate`: If true, establishes connection immediately (panics on failure). -/// If false, uses lazy connection (for tests or when database may not be needed). +/// If false, uses lazy connection (for tests or when database may not be needed). /// - `database_url`: The database connection URL. /// - `max_connections`: Maximum number of connections in the pool. pub async fn create_pool(immediate: bool, database_url: &str, max_connections: u32) -> PgPool { diff --git a/web/eslint.config.js b/web/eslint.config.js new file mode 100644 index 0000000..cb9d2f5 --- /dev/null +++ b/web/eslint.config.js @@ -0,0 +1,33 @@ +import prettier from 'eslint-config-prettier'; +import svelte from 'eslint-plugin-svelte'; +import globals from 'globals'; +import ts from 'typescript-eslint'; + +export default [ + ...ts.configs.recommended, + ...svelte.configs['flat/recommended'], + prettier, + ...svelte.configs['flat/prettier'], + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node + } + } + }, + { + files: ['**/*.svelte'], + languageOptions: { + parserOptions: { + parser: ts.parser + } + }, + rules: { + 'svelte/no-navigation-without-resolve': 'off' + } + }, + { + ignores: ['build/', '.svelte-kit/', 'dist/', '**/*.cjs', 'static/**'] + } +]; diff --git a/web/src/demo.spec.ts b/web/src/demo.spec.ts new file mode 100644 index 0000000..e07cbbd --- /dev/null +++ b/web/src/demo.spec.ts @@ -0,0 +1,7 @@ +import { describe, it, expect } from 'vitest'; + +describe('sum test', () => { + it('adds 1 + 2 to equal 3', () => { + expect(1 + 2).toBe(3); + }); +}); diff --git a/web/src/lib/components/NavLink.svelte b/web/src/lib/components/NavLink.svelte index 85b10c5..2545a62 100644 --- a/web/src/lib/components/NavLink.svelte +++ b/web/src/lib/components/NavLink.svelte @@ -3,7 +3,7 @@ let { href, - icon, + icon: Icon, label, active = false, size = 18 @@ -23,6 +23,6 @@ - + {label} diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index e5dfb15..05c6ed1 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -202,7 +202,7 @@
- {#each links as link} + {#each links as link (link.href)} { + it('should render h1', async () => { + render(Page); + + const heading = page.getByRole('heading', { level: 1 }); + await expect.element(heading).toBeInTheDocument(); + }); +}); diff --git a/web/vite-plugin-font-subset.ts b/web/vite-plugin-font-subset.ts index bd6cdfd..bccbfd1 100644 --- a/web/vite-plugin-font-subset.ts +++ b/web/vite-plugin-font-subset.ts @@ -8,7 +8,7 @@ import { createHash } from 'node:crypto'; function isFont(font: Font | FontCollection): font is Font { return 'glyphForCodePoint' in font; } -import { readFile, writeFile, mkdir, copyFile, stat } from 'node:fs/promises'; +import { readFile, writeFile, mkdir, copyFile } from 'node:fs/promises'; import { existsSync } from 'node:fs'; import path from 'node:path'; import { normalizePath } from 'vite'; @@ -75,16 +75,6 @@ function logWarning(message: string): void { console.warn(`[vite-plugin-font-subset] WARNING: ${message}`); } -function logError(context: string, error: Error, isProduction: boolean): void { - console.error(`\n[vite-plugin-font-subset] ERROR: ${context}`); - console.error(error.message); - - if (!isProduction && error.stack) { - console.error('\nStack trace:'); - console.error(error.stack); - } -} - // ============================================================================ // Path Resolution // ============================================================================ @@ -231,6 +221,7 @@ async function extractFontMetadata( // OpenType name table IDs: // ID 16 = Typographic/Preferred Family (base family without weight/style) // ID 1 = Font Family (may include weight/style for compatibility) + // eslint-disable-next-line @typescript-eslint/no-explicit-any const nameTable = (font as any).name; const preferredFamily = nameTable?.records?.preferredFamily?.en; const fontFamily = nameTable?.records?.fontFamily?.en; diff --git a/web/vite.config.ts b/web/vite.config.ts index 95eaa89..4614c47 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,13 +1,16 @@ +import devtoolsJson from 'vite-plugin-devtools-json'; +import { defineConfig } from 'vitest/config'; +import { playwright } from '@vitest/browser-playwright'; import { sveltekit } from '@sveltejs/kit/vite'; import tailwindcss from '@tailwindcss/vite'; -import { defineConfig, type Plugin } from 'vite'; +import { type Plugin } from 'vite'; import { execSync } from 'child_process'; import { fontSubsetPlugin, type FontSubsetConfig } from './vite-plugin-font-subset'; // Character sets for font subsetting const TITLE_CHARS = 'PACMN-'; -const COMMON_CHARS = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,!?':;-_()\/@#&*+=%<>"; + +const COMMON_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,!?':;-_()/@#&*+=%<>"; const fontConfig: FontSubsetConfig = { fonts: [ @@ -15,11 +18,13 @@ const fontConfig: FontSubsetConfig = { source: '@fontsource/russo-one/files/russo-one-latin-400-normal.woff2', whitelist: TITLE_CHARS }, + { source: '@fontsource/outfit/files/outfit-latin-400-normal.woff2', whitelist: COMMON_CHARS, family: 'Outfit' }, + { source: '@fontsource/outfit/files/outfit-latin-500-normal.woff2', whitelist: COMMON_CHARS, @@ -39,10 +44,7 @@ function pacmanVersionPlugin(): Plugin { } try { - const hash = execSync('git rev-parse --short HEAD', { - encoding: 'utf8', - stdio: ['pipe', 'pipe', 'pipe'] - }).trim(); + const hash = execSync('git rev-parse --short HEAD', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim(); if (hash) { return hash; @@ -56,8 +58,10 @@ function pacmanVersionPlugin(): Plugin { return { name: 'pacman-version', + config(_, { mode }) { const version = getVersion(mode); + console.log(`[pacman-version] Using version: ${version}`); return { @@ -70,10 +74,16 @@ function pacmanVersionPlugin(): Plugin { } export default defineConfig({ - plugins: [fontSubsetPlugin(fontConfig), pacmanVersionPlugin(), sveltekit(), tailwindcss()], - build: { - target: 'es2022' - }, + plugins: [ + fontSubsetPlugin(fontConfig), + pacmanVersionPlugin(), + sveltekit(), + tailwindcss(), + devtoolsJson() + ], + + build: { target: 'es2022' }, + server: { proxy: { '/api': { @@ -81,5 +91,39 @@ export default defineConfig({ changeOrigin: true } } + }, + + test: { + expect: { requireAssertions: true }, + + projects: [ + { + extends: './vite.config.ts', + + test: { + name: 'client', + + browser: { + enabled: true, + provider: playwright(), + instances: [{ browser: 'chromium', headless: true }] + }, + + include: ['src/**/*.svelte.{test,spec}.{js,ts}'], + exclude: ['src/lib/server/**'] + } + }, + + { + extends: './vite.config.ts', + + test: { + name: 'server', + environment: 'node', + include: ['src/**/*.{test,spec}.{js,ts}'], + exclude: ['src/**/*.svelte.{test,spec}.{js,ts}'] + } + } + ] } });