This commit is contained in:
205
tests/projectTypeDetector.test.ts
Normal file
205
tests/projectTypeDetector.test.ts
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { ProjectTypeDetector } from '../src/analyzers/projectTypeDetector';
|
||||||
|
|
||||||
|
describe('ProjectTypeDetector', () => {
|
||||||
|
let detector: ProjectTypeDetector;
|
||||||
|
let testDir: string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
detector = new ProjectTypeDetector();
|
||||||
|
testDir = path.join(__dirname, 'test-projects', `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('detect', () => {
|
||||||
|
it('should detect TypeScript project with tsconfig.json', async () => {
|
||||||
|
const tsconfig = { compilerOptions: { target: 'ES2020' } };
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'tsconfig.json'),
|
||||||
|
JSON.stringify(tsconfig)
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'index.ts'),
|
||||||
|
'const x: string = "hello";'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('TypeScript');
|
||||||
|
expect(result.primaryLanguage).toBe('TypeScript');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect JavaScript project with package.json', async () => {
|
||||||
|
const packageJson = { dependencies: { express: '^4.0.0' } };
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'index.js'),
|
||||||
|
'const express = require("express");'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('JavaScript');
|
||||||
|
expect(result.primaryLanguage).toBe('JavaScript');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect Python project with requirements.txt', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'requirements.txt'),
|
||||||
|
'django>=3.0.0\nflask>=1.0.0'
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'main.py'),
|
||||||
|
'import django\nfrom flask import Flask'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('Python');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect Go project with go.mod', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'go.mod'),
|
||||||
|
'module example.com/mymodule\n\ngo 1.21\n\nrequire github.com/gin-gonic/gin v1.9.0'
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'main.go'),
|
||||||
|
'package main\nimport "fmt"'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('Go');
|
||||||
|
expect(result.frameworks).toContain('Gin');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect Rust project with Cargo.toml', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'Cargo.toml'),
|
||||||
|
'[package]\nname = "myproject"\nversion = "0.1.0"\n\n[dependencies]\nserde = { version = "1.0", features = ["derive"] }'
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'main.rs'),
|
||||||
|
'fn main() { println!("Hello"); }'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('Rust');
|
||||||
|
expect(result.buildTools).toContain('cargo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect React framework from package.json', async () => {
|
||||||
|
const packageJson = {
|
||||||
|
dependencies: { react: '^18.0.0', 'react-dom': '^18.0.0' },
|
||||||
|
devDependencies: { '@types/react': '^18.0.0' }
|
||||||
|
};
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'App.tsx'),
|
||||||
|
'import React from "react";'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages).toContain('TypeScript');
|
||||||
|
expect(result.frameworks).toContain('React');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect Next.js framework', async () => {
|
||||||
|
const packageJson = {
|
||||||
|
dependencies: {
|
||||||
|
next: '^14.0.0',
|
||||||
|
react: '^18.0.0',
|
||||||
|
'react-dom': '^18.0.0'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson)
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'next.config.js'),
|
||||||
|
'module.exports = {}'
|
||||||
|
);
|
||||||
|
await fs.promises.mkdir(path.join(testDir, 'pages'), { recursive: true });
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'pages', 'index.tsx'),
|
||||||
|
'export default function() { return null; }'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.frameworks).toContain('Next.js');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect Django framework', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'requirements.txt'),
|
||||||
|
'django>=4.0.0\ndjangorestframework>=3.0.0'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.frameworks).toContain('Django');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect FastAPI framework', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'requirements.txt'),
|
||||||
|
'fastapi>=0.100.0\nuvicorn>=0.23.0'
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.frameworks).toContain('FastAPI');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect build tools from config files', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify({ dependencies: {} })
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'Makefile'), 'all:\n\techo "build"');
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.buildTools).toContain('npm');
|
||||||
|
expect(result.buildTools).toContain('make');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect multiple languages in same project', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'package.json'),
|
||||||
|
JSON.stringify({ dependencies: {} })
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'index.js'), 'console.log("js");');
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'main.py'), 'print("python")');
|
||||||
|
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.languages.length).toBeGreaterThan(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return Unknown for empty directory', async () => {
|
||||||
|
const result = await detector.detect(testDir);
|
||||||
|
|
||||||
|
expect(result.primaryLanguage).toBe('Unknown');
|
||||||
|
expect(result.languages).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user