knowledge-graph-preview / cli /analyze.test.js
mr4's picture
Upload 136 files
fd8cdf5 verified
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
// Mock the analyzer module
vi.mock('./analyzer/index.js', () => ({
analyze: vi.fn(),
}));
// Mock the logger
vi.mock('./logger.js', () => ({
log: vi.fn(),
}));
describe('runAnalyze output files', () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'analyze-test-'));
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it('should write knowledge-graph.json with full DashboardJSON schema', async () => {
const { analyze } = await import('./analyzer/index.js');
const mockedAnalyze = vi.mocked(analyze);
const mockDashboard = {
version: '1.0.0',
project: {
name: 'test-project',
description: 'A test project',
languages: ['typescript'],
frameworks: ['express'],
analyzedAt: '2024-01-01T00:00:00.000Z',
gitCommitHash: 'abc123def456',
},
nodes: [
{ id: 'file::src/index.ts', type: 'file', name: 'index.ts', summary: 'Entry point', tags: ['entry'] },
],
edges: [
{ source: 'file::src/index.ts', target: 'file::src/utils.ts', type: 'imports' },
],
layers: [
{ id: 'layer::core', name: 'Core', description: 'Core layer', nodeIds: ['file::src/index.ts'] },
],
tour: [
{ order: 1, title: 'Start here', description: 'Entry point', nodeIds: ['file::src/index.ts'] },
],
};
mockedAnalyze.mockResolvedValue({
dashboard: mockDashboard,
stats: {
filesAnalyzed: 5,
nodesByType: { file: 3, function: 2 },
edgesCreated: 4,
layersIdentified: 1,
},
files: [],
});
// Simulate what runAnalyze does (without process.exit)
const targetPath = tmpDir;
const { dashboard, stats } = await analyze(targetPath, { full: false });
const outputDir = path.join(targetPath, '.understand-anything');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const knowledgeGraphPath = path.join(outputDir, 'knowledge-graph.json');
fs.writeFileSync(knowledgeGraphPath, JSON.stringify(dashboard, null, 2));
const meta = {
lastAnalyzedAt: new Date().toISOString(),
gitCommitHash: dashboard.project.gitCommitHash || '',
version: '1.0.0',
analyzedFiles: stats.filesAnalyzed,
};
const metaPath = path.join(outputDir, 'meta.json');
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
// Verify knowledge-graph.json
const kgContent = JSON.parse(fs.readFileSync(knowledgeGraphPath, 'utf-8'));
expect(kgContent.version).toBe('1.0.0');
expect(kgContent.project.name).toBe('test-project');
expect(kgContent.project.gitCommitHash).toBe('abc123def456');
expect(kgContent.nodes).toHaveLength(1);
expect(kgContent.edges).toHaveLength(1);
expect(kgContent.layers).toHaveLength(1);
expect(kgContent.tour).toHaveLength(1);
// Verify meta.json
const metaContent = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
expect(metaContent.lastAnalyzedAt).toBeDefined();
expect(metaContent.gitCommitHash).toBe('abc123def456');
expect(metaContent.version).toBe('1.0.0');
expect(metaContent.analyzedFiles).toBe(5);
});
it('should create .understand-anything directory if it does not exist', async () => {
const { analyze } = await import('./analyzer/index.js');
const mockedAnalyze = vi.mocked(analyze);
mockedAnalyze.mockResolvedValue({
dashboard: {
version: '1.0.0',
project: {
name: 'test',
description: '',
languages: [],
frameworks: [],
analyzedAt: '2024-01-01T00:00:00.000Z',
gitCommitHash: '',
},
nodes: [],
edges: [],
layers: [],
tour: [],
},
stats: {
filesAnalyzed: 0,
nodesByType: {},
edgesCreated: 0,
layersIdentified: 0,
},
files: [],
});
const targetPath = tmpDir;
const outputDir = path.join(targetPath, '.understand-anything');
expect(fs.existsSync(outputDir)).toBe(false);
const { dashboard, stats } = await analyze(targetPath, { full: false });
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
fs.writeFileSync(path.join(outputDir, 'knowledge-graph.json'), JSON.stringify(dashboard, null, 2));
fs.writeFileSync(path.join(outputDir, 'meta.json'), JSON.stringify({
lastAnalyzedAt: new Date().toISOString(),
gitCommitHash: dashboard.project.gitCommitHash || '',
version: '1.0.0',
analyzedFiles: stats.filesAnalyzed,
}, null, 2));
expect(fs.existsSync(outputDir)).toBe(true);
expect(fs.existsSync(path.join(outputDir, 'knowledge-graph.json'))).toBe(true);
expect(fs.existsSync(path.join(outputDir, 'meta.json'))).toBe(true);
});
it('should produce output compatible with --preview command', async () => {
const { analyze } = await import('./analyzer/index.js');
const mockedAnalyze = vi.mocked(analyze);
mockedAnalyze.mockResolvedValue({
dashboard: {
version: '1.0.0',
project: {
name: 'my-project',
description: 'Test',
languages: ['typescript'],
frameworks: [],
analyzedAt: '2024-06-01T12:00:00.000Z',
gitCommitHash: 'deadbeef',
},
nodes: [
{ id: 'file::app.ts', type: 'file', name: 'app.ts', summary: 'App', tags: [] },
],
edges: [],
layers: [],
tour: [],
},
stats: {
filesAnalyzed: 1,
nodesByType: { file: 1 },
edgesCreated: 0,
layersIdentified: 0,
},
files: [],
});
const targetPath = tmpDir;
const { dashboard, stats } = await analyze(targetPath, { full: true });
const outputDir = path.join(targetPath, '.understand-anything');
fs.mkdirSync(outputDir, { recursive: true });
fs.writeFileSync(path.join(outputDir, 'knowledge-graph.json'), JSON.stringify(dashboard, null, 2));
fs.writeFileSync(path.join(outputDir, 'meta.json'), JSON.stringify({
lastAnalyzedAt: new Date().toISOString(),
gitCommitHash: dashboard.project.gitCommitHash || '',
version: '1.0.0',
analyzedFiles: stats.filesAnalyzed,
}, null, 2));
// The output should be compatible with --preview:
// knowledge-graph.json must have nodes and edges (DashboardJSON schema)
const kg = JSON.parse(fs.readFileSync(path.join(outputDir, 'knowledge-graph.json'), 'utf-8'));
expect(kg).toHaveProperty('version');
expect(kg).toHaveProperty('project');
expect(kg).toHaveProperty('nodes');
expect(kg).toHaveProperty('edges');
expect(Array.isArray(kg.nodes)).toBe(true);
expect(Array.isArray(kg.edges)).toBe(true);
// meta.json must have the expected fields
const meta = JSON.parse(fs.readFileSync(path.join(outputDir, 'meta.json'), 'utf-8'));
expect(meta).toHaveProperty('lastAnalyzedAt');
expect(meta).toHaveProperty('gitCommitHash');
expect(meta).toHaveProperty('version');
expect(meta).toHaveProperty('analyzedFiles');
expect(typeof meta.analyzedFiles).toBe('number');
});
});