mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-22 00:31:17 +00:00
* feat: configure prettier with pre-commit hook integration Add prettier, lint-staged, and prettier-plugin-tailwindcss at the repo root with husky pre-commit hook integration. Moves husky from gitnexus/ to root package.json for reliable hook installation. - Root package.json with prepare/format/format:check scripts - .prettierrc with endOfLine:lf and tailwindStylesheet for TW v4 - .prettierignore excluding fixtures, vendor, generated, *.d.ts, *.md - .gitattributes enforcing LF line endings for Windows consistency - Pre-commit hook uses direct node_modules/.bin/ paths (no npx) * style: apply prettier formatting to entire codebase One-time bulk format. No logic changes. Use .git-blame-ignore-revs to skip this commit in git blame. * chore: add .git-blame-ignore-revs for prettier format commit * perf: pre-commit hook runs only tests related to staged files Use vitest --related to scope test execution to tests that import the changed files, instead of running the full suite on every commit. * perf: remove vitest from pre-commit hook, keep in CI only Pre-commit now runs lint-staged + tsc only. Tests run in CI (ci-tests.yml) where they belong — keeps commits fast. * ci: add prettier format check to quality workflow PRs will now fail if code isn't formatted with prettier.
119 lines
4.3 KiB
TypeScript
119 lines
4.3 KiB
TypeScript
/**
|
|
* Unit Tests: Fetch reason field parsing
|
|
*
|
|
* Tests the reason field format used by processNextjsFetchRoutes and
|
|
* parsed by fetchRoutesWithConsumers. Verifies that multi-fetch count
|
|
* encoding and keys extraction work correctly with the updated regex.
|
|
*/
|
|
import { describe, it, expect } from 'vitest';
|
|
|
|
/**
|
|
* Extracted parsing logic matching fetchRoutesWithConsumers in local-backend.ts.
|
|
* This mirrors the regex patterns used at runtime.
|
|
*/
|
|
function parseReasonField(fetchReason: string | null): {
|
|
accessedKeys?: string[];
|
|
fetchCount?: number;
|
|
} {
|
|
let accessedKeys: string[] | undefined;
|
|
let fetchCount: number | undefined;
|
|
if (fetchReason) {
|
|
const keysMatch = fetchReason.match(/\|keys:([^|]+)/);
|
|
if (keysMatch) {
|
|
accessedKeys = keysMatch[1].split(',').filter((k) => k.length > 0);
|
|
}
|
|
const fetchesMatch = fetchReason.match(/\|fetches:(\d+)/);
|
|
if (fetchesMatch) {
|
|
fetchCount = parseInt(fetchesMatch[1], 10);
|
|
}
|
|
}
|
|
return {
|
|
...(accessedKeys ? { accessedKeys } : {}),
|
|
...(fetchCount && fetchCount > 1 ? { fetchCount } : {}),
|
|
};
|
|
}
|
|
|
|
describe('fetch reason field parsing', () => {
|
|
it('parses basic reason with no keys or fetches', () => {
|
|
const result = parseReasonField('fetch-url-match');
|
|
expect(result.accessedKeys).toBeUndefined();
|
|
expect(result.fetchCount).toBeUndefined();
|
|
});
|
|
|
|
it('parses keys without fetches suffix', () => {
|
|
const result = parseReasonField('fetch-url-match|keys:data,pagination');
|
|
expect(result.accessedKeys).toEqual(['data', 'pagination']);
|
|
expect(result.fetchCount).toBeUndefined();
|
|
});
|
|
|
|
it('parses keys with fetches suffix', () => {
|
|
const result = parseReasonField('fetch-url-match|keys:data,pagination|fetches:3');
|
|
expect(result.accessedKeys).toEqual(['data', 'pagination']);
|
|
expect(result.fetchCount).toBe(3);
|
|
});
|
|
|
|
it('parses fetches without keys', () => {
|
|
const result = parseReasonField('fetch-url-match|fetches:2');
|
|
expect(result.accessedKeys).toBeUndefined();
|
|
expect(result.fetchCount).toBe(2);
|
|
});
|
|
|
|
it('does not set fetchCount when value is 1', () => {
|
|
// fetchCount=1 means single route, no need to flag
|
|
const result = parseReasonField('fetch-url-match|keys:data|fetches:1');
|
|
expect(result.accessedKeys).toEqual(['data']);
|
|
expect(result.fetchCount).toBeUndefined();
|
|
});
|
|
|
|
it('handles null reason', () => {
|
|
const result = parseReasonField(null);
|
|
expect(result.accessedKeys).toBeUndefined();
|
|
expect(result.fetchCount).toBeUndefined();
|
|
});
|
|
|
|
it('old greedy regex would have included |fetches: in keys — new regex does not', () => {
|
|
// This is the regression test: the old regex /\|keys:(.+)$/ would match
|
|
// "data,pagination|fetches:3" as keys, including the fetches suffix
|
|
const reason = 'fetch-url-match|keys:data,pagination|fetches:3';
|
|
const result = parseReasonField(reason);
|
|
// Keys should NOT contain "fetches:3" or "pagination|fetches:3"
|
|
expect(result.accessedKeys).not.toContain('pagination|fetches:3');
|
|
expect(result.accessedKeys).toEqual(['data', 'pagination']);
|
|
});
|
|
});
|
|
|
|
describe('confidence derivation from fetchCount', () => {
|
|
it('high confidence when fetchCount is undefined (single fetch)', () => {
|
|
const isMultiFetch = (undefined ?? 1) > 1;
|
|
expect(isMultiFetch).toBe(false);
|
|
});
|
|
|
|
it('low confidence when fetchCount > 1', () => {
|
|
const fetchCount = 3;
|
|
const isMultiFetch = (fetchCount ?? 1) > 1;
|
|
expect(isMultiFetch).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('middlewareDetection partial flag', () => {
|
|
it('flags partial when middleware exists and handler has multiple routes', () => {
|
|
const middleware = ['withAuth'];
|
|
const handlerRouteCount = 2;
|
|
const middlewarePartial = middleware.length > 0 && handlerRouteCount > 1;
|
|
expect(middlewarePartial).toBe(true);
|
|
});
|
|
|
|
it('does not flag partial when middleware exists but handler has single route', () => {
|
|
const middleware = ['withAuth'];
|
|
const handlerRouteCount = 1;
|
|
const middlewarePartial = middleware.length > 0 && handlerRouteCount > 1;
|
|
expect(middlewarePartial).toBe(false);
|
|
});
|
|
|
|
it('does not flag partial when no middleware even with multiple routes', () => {
|
|
const middleware: string[] = [];
|
|
const handlerRouteCount = 3;
|
|
const middlewarePartial = middleware.length > 0 && handlerRouteCount > 1;
|
|
expect(middlewarePartial).toBe(false);
|
|
});
|
|
});
|