UNPKG

markus-diff

Version:

A tool to analyze and reconstruct project structures

158 lines (134 loc) 5.55 kB
import { expect, describe, it, beforeEach, afterEach, vi } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; import { execSync } from 'child_process'; import { analyzeWithGit } from '../commands/generate.mjs'; // Mock the scanner module vi.mock('../src/scanner.mjs', () => { return { scanProject: (projectDir) => ({ structure: { framework: 'unknown', hasTypescript: false, hasSrcDir: true, packageJson: { dependencies: {}, devDependencies: {} } }, files: [ { path: 'file1.js', type: 'javascript', size: 100, content: 'console.log("Modified content");' }, { path: 'file2.js', type: 'javascript', size: 100, content: 'console.log("Another file");' } ], dependencies: {}, devDependencies: {} }) }; }); describe('Git Analysis Tests', () => { const testDir = path.resolve(process.cwd(), 'test/__markus_tests'); const testProjectDir = path.resolve(testDir, 'test-project'); const outputDir = path.resolve(testDir, 'output'); const outputFile = path.resolve(outputDir, 'analysis.json'); console.log("@@@ testDir", testDir); console.log("@@@ testProjectDir", testProjectDir); console.log("@@@ outputDir", outputDir); console.log("@@@ outputFile", outputFile); // Setup test project and git repo before each test beforeEach(() => { // Create test project directory and output directory fs.mkdirSync(testProjectDir, { recursive: true }); fs.mkdirSync(outputDir, { recursive: true }); // Initialize git repo process.chdir(testProjectDir); execSync('git init'); execSync('git config user.name "Test User"'); execSync('git config user.email "test@example.com"'); // Create some test files fs.writeFileSync('file1.js', 'console.log("Initial content");'); fs.writeFileSync('file2.js', 'console.log("Another file");'); // Initial commit execSync('git add .'); execSync('git commit -m "Initial commit"'); // Create and switch to feature branch execSync('git checkout -b feature/test-branch'); // Make some changes fs.writeFileSync('file1.js', 'console.log("Modified content");'); fs.writeFileSync('file3.js', 'console.log("New file");'); // Commit changes execSync('git add .'); execSync('git commit -m "Feature changes"'); }); // Cleanup after each test afterEach(() => { try { // Make sure we're not in the directory we're trying to delete process.chdir(process.cwd()); fs.rmSync(testDir, { recursive: true, force: true }); } catch (error) { console.warn('Cleanup warning:', error.message); } }); it('should generate analysis with git information', async () => { const options = { dir: testProjectDir, output: outputFile, gitMaster: true }; await analyzeWithGit(options); // Verify the output file exists expect(fs.existsSync(outputFile)).toBe(true); // log the output file content console.log("@@@ outputFile content", fs.readFileSync(outputFile, 'utf-8')); // Read and parse the output file const analysis = JSON.parse(fs.readFileSync(outputFile, 'utf-8')); // Verify git information expect(analysis.git).toBeDefined(); expect(analysis.git.sourceBranch).toBe('feature/test-branch'); expect(analysis.git.targetBranch).toBe('master'); expect(analysis.git.branchStatus).toBeDefined(); expect(analysis.git.branchStatus.ahead).toBeGreaterThan(0); expect(analysis.git.lastCommit).toBeDefined(); expect(analysis.git.lastCommit.subject).toBe('Feature changes'); }); it('should handle merge conflicts gracefully', async () => { // Create conflicting changes in master execSync('git checkout master'); fs.writeFileSync('file1.js', 'console.log("Master change");'); execSync('git add .'); execSync('git commit -m "Master changes"'); execSync('git checkout feature/test-branch'); const options = { dir: testProjectDir, output: outputFile, gitMaster: true }; // The analysis should handle the conflict and exit gracefully await expect(analyzeWithGit(options)).rejects.toThrow(); }); it('should restore working directory state after analysis', async () => { // Create some uncommitted changes fs.writeFileSync('uncommitted.js', 'console.log("Uncommitted");'); const options = { dir: testProjectDir, output: outputFile, gitMaster: true }; await analyzeWithGit(options); // Verify we're back on the original branch const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim(); expect(currentBranch).toBe('feature/test-branch'); // Verify uncommitted changes are preserved expect(fs.existsSync('uncommitted.js')).toBe(true); }); });