This commit is contained in:
225
.ai-context-generator-cli/tests/dependencyAnalyzer.test.ts
Normal file
225
.ai-context-generator-cli/tests/dependencyAnalyzer.test.ts
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { DependencyAnalyzer } from '../src/analyzers/dependencyAnalyzer';
|
||||||
|
|
||||||
|
describe('DependencyAnalyzer', () => {
|
||||||
|
let analyzer: DependencyAnalyzer;
|
||||||
|
let testDir: string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
analyzer = new DependencyAnalyzer();
|
||||||
|
testDir = path.join('/tmp', `ai-context-test-${Date.now()}`);
|
||||||
|
await fs.promises.mkdir(testDir, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
if (await fs.promises.stat(testDir).catch(() => null)) {
|
||||||
|
await fs.promises.rm(testDir, { recursive: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('analyze', () => {
|
||||||
|
it('should parse package.json dependencies correctly', async () => {
|
||||||
|
const packageJson = {
|
||||||
|
dependencies: {
|
||||||
|
express: '^4.18.0',
|
||||||
|
lodash: '^4.17.21',
|
||||||
|
},
|
||||||
|
devDependencies: {
|
||||||
|
jest: '^29.0.0',
|
||||||
|
typescript: '^5.0.0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBe(2);
|
||||||
|
expect(result.direct.length).toBe(2);
|
||||||
|
expect(result.direct.find(d => d.name === 'express')?.version).toBe('^4.18.0');
|
||||||
|
expect(result.dev.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include dev dependencies when requested', async () => {
|
||||||
|
const packageJson = {
|
||||||
|
dependencies: { express: '^4.18.0' },
|
||||||
|
devDependencies: { jest: '^29.0.0' },
|
||||||
|
};
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, true);
|
||||||
|
|
||||||
|
expect(result.total).toBe(2);
|
||||||
|
expect(result.dev.length).toBe(1);
|
||||||
|
expect(result.dev[0].name).toBe('jest');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse requirements.txt dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'requirements.txt'),
|
||||||
|
`django>=4.0.0
|
||||||
|
flask>=2.0.0
|
||||||
|
requests==2.28.0
|
||||||
|
numpy~=1.24.0`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBeGreaterThan(0);
|
||||||
|
const deps = result.direct.map(d => d.name);
|
||||||
|
expect(deps).toContain('django');
|
||||||
|
expect(deps).toContain('flask');
|
||||||
|
expect(deps).toContain('requests');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse go.mod dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'go.mod'),
|
||||||
|
`module example.com/mymodule
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gin-gonic/gin v1.9.0
|
||||||
|
github.com/stretchr/testify v1.8.0
|
||||||
|
)`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBeGreaterThan(0);
|
||||||
|
const deps = result.direct.map(d => d.name);
|
||||||
|
expect(deps).toContain('github.com/gin-gonic/gin');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse Cargo.toml dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'Cargo.toml'),
|
||||||
|
`[package]
|
||||||
|
name = "myproject"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assertions = "0.3"`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, true);
|
||||||
|
|
||||||
|
expect(result.total).toBe(3);
|
||||||
|
expect(result.direct.length).toBe(2);
|
||||||
|
expect(result.dev.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse pyproject.toml dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'pyproject.toml'),
|
||||||
|
`[project]
|
||||||
|
name = "myproject"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"requests>=2.28.0",
|
||||||
|
"flask>=2.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"pytest>=7.0.0",
|
||||||
|
"black>=23.0.0",
|
||||||
|
]`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBe(2);
|
||||||
|
expect(result.direct.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse composer.json dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'composer.json'),
|
||||||
|
JSON.stringify({
|
||||||
|
require: {
|
||||||
|
php: '^8.0',
|
||||||
|
'laravel/framework': '^10.0',
|
||||||
|
},
|
||||||
|
'require-dev': {
|
||||||
|
'phpunit/phpunit': '^10.0',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, true);
|
||||||
|
|
||||||
|
expect(result.total).toBe(3);
|
||||||
|
expect(result.dev.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse Gemfile dependencies', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'Gemfile'),
|
||||||
|
`source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'rails', '~> 7.0.0'
|
||||||
|
gem 'nokogiri', '>= 1.13'
|
||||||
|
|
||||||
|
group :development, :test do
|
||||||
|
gem 'rspec-rails', '~> 6.0'
|
||||||
|
end`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, true);
|
||||||
|
|
||||||
|
expect(result.total).toBe(3);
|
||||||
|
expect(result.dev.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty project gracefully', async () => {
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBe(0);
|
||||||
|
expect(result.direct).toHaveLength(0);
|
||||||
|
expect(result.dev).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle invalid JSON gracefully', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
'invalid json {'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.total).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark local dependencies correctly', async () => {
|
||||||
|
const packageJson = {
|
||||||
|
dependencies: {
|
||||||
|
'./local-module': '*',
|
||||||
|
'@local/package': '*',
|
||||||
|
express: '^4.18.0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await analyzer.analyze(testDir, false);
|
||||||
|
|
||||||
|
expect(result.direct.find(d => d.name === './local-module')?.isLocal).toBe(true);
|
||||||
|
expect(result.direct.find(d => d.name === '@local/package')?.isLocal).toBe(true);
|
||||||
|
expect(result.direct.find(d => d.name === 'express')?.isLocal).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user