GitNexus/gitnexus/test/integration/resolvers/helpers.ts
Gergő Magyar bf09eab95b
feat: configure prettier with pre-commit hook (#563)
* 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.
2026-03-28 14:58:04 +00:00

76 lines
2.6 KiB
TypeScript

/**
* Shared test helpers for language resolution integration tests.
*/
import path from 'path';
import { runPipelineFromRepo } from '../../../src/core/ingestion/pipeline.js';
import type { PipelineOptions } from '../../../src/core/ingestion/pipeline.js';
import type { PipelineResult } from '../../../src/types/pipeline.js';
import type { GraphRelationship } from '../../../src/core/graph/types.js';
export const FIXTURES = path.resolve(__dirname, '..', '..', 'fixtures', 'lang-resolution');
export const CROSS_FILE_FIXTURES = path.resolve(
__dirname,
'..',
'..',
'fixtures',
'cross-file-binding',
);
export type RelEdge = {
source: string;
target: string;
sourceLabel: string;
targetLabel: string;
sourceFilePath: string;
targetFilePath: string;
rel: GraphRelationship;
};
export function getRelationships(result: PipelineResult, type: string): RelEdge[] {
const edges: RelEdge[] = [];
for (const rel of result.graph.iterRelationships()) {
if (rel.type === type) {
const sourceNode = result.graph.getNode(rel.sourceId);
const targetNode = result.graph.getNode(rel.targetId);
edges.push({
source: sourceNode?.properties.name ?? rel.sourceId,
target: targetNode?.properties.name ?? rel.targetId,
sourceLabel: sourceNode?.label ?? 'unknown',
targetLabel: targetNode?.label ?? 'unknown',
sourceFilePath: sourceNode?.properties.filePath ?? '',
targetFilePath: targetNode?.properties.filePath ?? '',
rel,
});
}
}
return edges;
}
export function getNodesByLabel(result: PipelineResult, label: string): string[] {
const names: string[] = [];
result.graph.forEachNode((n) => {
if (n.label === label) names.push(n.properties.name);
});
return names.sort();
}
export function edgeSet(edges: Array<{ source: string; target: string }>): string[] {
return edges.map((e) => `${e.source}${e.target}`).sort();
}
/** Get graph nodes by label with full properties (for parameterTypes assertions). */
export function getNodesByLabelFull(
result: PipelineResult,
label: string,
): Array<{ name: string; properties: Record<string, any> }> {
const nodes: Array<{ name: string; properties: Record<string, any> }> = [];
result.graph.forEachNode((n) => {
if (n.label === label) nodes.push({ name: n.properties.name, properties: n.properties });
});
return nodes.sort((a, b) => a.name.localeCompare(b.name));
}
// Tests can pass { skipGraphPhases: true } as third arg for faster runs
// (skips MRO, community detection, and process extraction).
export { runPipelineFromRepo };
export type { PipelineOptions, PipelineResult };