Files
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00

341 lines
11 KiB
TypeScript

/**
* Coverage Analysis Wizard - Unit Tests
* ADR-041: V3 QE CLI Enhancement
*/
import { describe, it, expect } from 'vitest';
import {
CoverageAnalysisWizard,
runCoverageAnalysisWizard,
getSensitivityConfig,
type CoverageWizardResult,
type GapSensitivity,
type ReportFormat,
type PriorityFocus,
} from '../../../src/cli/wizards/coverage-wizard';
describe('CoverageAnalysisWizard', () => {
describe('Non-Interactive Mode', () => {
it('should return defaults when nonInteractive is true', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
});
expect(result.cancelled).toBe(false);
expect(result.sensitivity).toBe('medium');
expect(result.format).toBe('json');
expect(result.priorityFocus).toEqual(['functions', 'branches']);
expect(result.riskScoring).toBe(true);
expect(result.threshold).toBe(80);
});
it('should use provided defaults', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
defaultTarget: '/test/path',
defaultSensitivity: 'high',
defaultFormat: 'html',
defaultPriorityFocus: ['lines', 'statements'],
defaultRiskScoring: false,
defaultThreshold: 90,
});
expect(result.target).toBe('/test/path');
expect(result.sensitivity).toBe('high');
expect(result.format).toBe('html');
expect(result.priorityFocus).toEqual(['lines', 'statements']);
expect(result.riskScoring).toBe(false);
expect(result.threshold).toBe(90);
});
});
describe('CoverageWizardResult', () => {
it('should have correct structure', () => {
const result: CoverageWizardResult = {
target: '/test/path',
sensitivity: 'medium',
format: 'json',
priorityFocus: ['functions', 'branches'],
riskScoring: true,
threshold: 80,
cancelled: false,
};
expect(typeof result.target).toBe('string');
expect(typeof result.sensitivity).toBe('string');
expect(typeof result.format).toBe('string');
expect(result.priorityFocus).toBeInstanceOf(Array);
expect(typeof result.riskScoring).toBe('boolean');
expect(typeof result.threshold).toBe('number');
expect(typeof result.cancelled).toBe('boolean');
});
it('should support cancelled state', () => {
const result: CoverageWizardResult = {
target: '.',
sensitivity: 'medium',
format: 'json',
priorityFocus: ['functions', 'branches'],
riskScoring: true,
threshold: 80,
cancelled: true,
};
expect(result.cancelled).toBe(true);
});
it('should support optional include/exclude patterns', () => {
const result: CoverageWizardResult = {
target: '.',
sensitivity: 'medium',
format: 'json',
priorityFocus: ['functions'],
riskScoring: true,
threshold: 80,
cancelled: false,
includePatterns: ['src/**/*.ts'],
excludePatterns: ['**/*.test.ts', 'dist/**'],
};
expect(result.includePatterns).toEqual(['src/**/*.ts']);
expect(result.excludePatterns).toEqual(['**/*.test.ts', 'dist/**']);
});
});
describe('Gap Sensitivity Levels', () => {
const validLevels: GapSensitivity[] = ['low', 'medium', 'high'];
it('should support all sensitivity levels', () => {
validLevels.forEach(level => {
expect(['low', 'medium', 'high']).toContain(level);
});
});
it('should have 3 sensitivity levels', () => {
expect(validLevels).toHaveLength(3);
});
it('should have correct ordering from least to most sensitive', () => {
expect(validLevels[0]).toBe('low');
expect(validLevels[1]).toBe('medium');
expect(validLevels[2]).toBe('high');
});
});
describe('Report Formats', () => {
const validFormats: ReportFormat[] = ['json', 'html', 'markdown', 'text'];
it('should support all report formats', () => {
validFormats.forEach(format => {
expect(['json', 'html', 'markdown', 'text']).toContain(format);
});
});
it('should have 4 report formats', () => {
expect(validFormats).toHaveLength(4);
});
});
describe('Priority Focus Areas', () => {
const validFocusAreas: PriorityFocus[] = ['functions', 'branches', 'lines', 'statements'];
it('should support all priority focus areas', () => {
validFocusAreas.forEach(area => {
expect(['functions', 'branches', 'lines', 'statements']).toContain(area);
});
});
it('should have 4 priority focus areas', () => {
expect(validFocusAreas).toHaveLength(4);
});
});
describe('Sensitivity Configuration', () => {
it('should return correct config for low sensitivity', () => {
const config = getSensitivityConfig('low');
expect(config.minRisk).toBe(0.7);
expect(config.maxGaps).toBe(10);
expect(config.description).toContain('critical');
});
it('should return correct config for medium sensitivity', () => {
const config = getSensitivityConfig('medium');
expect(config.minRisk).toBe(0.5);
expect(config.maxGaps).toBe(20);
expect(config.description).toContain('medium');
});
it('should return correct config for high sensitivity', () => {
const config = getSensitivityConfig('high');
expect(config.minRisk).toBe(0.3);
expect(config.maxGaps).toBe(50);
expect(config.description).toContain('low');
});
it('should have decreasing minRisk as sensitivity increases', () => {
const lowConfig = getSensitivityConfig('low');
const mediumConfig = getSensitivityConfig('medium');
const highConfig = getSensitivityConfig('high');
expect(lowConfig.minRisk).toBeGreaterThan(mediumConfig.minRisk);
expect(mediumConfig.minRisk).toBeGreaterThan(highConfig.minRisk);
});
it('should have increasing maxGaps as sensitivity increases', () => {
const lowConfig = getSensitivityConfig('low');
const mediumConfig = getSensitivityConfig('medium');
const highConfig = getSensitivityConfig('high');
expect(highConfig.maxGaps).toBeGreaterThan(mediumConfig.maxGaps);
expect(mediumConfig.maxGaps).toBeGreaterThan(lowConfig.maxGaps);
});
});
describe('CoverageAnalysisWizard Class', () => {
it('should create instance', () => {
const wizard = new CoverageAnalysisWizard();
expect(wizard).toBeInstanceOf(CoverageAnalysisWizard);
});
it('should accept options', () => {
const wizard = new CoverageAnalysisWizard({
nonInteractive: true,
defaultSensitivity: 'high',
});
expect(wizard).toBeInstanceOf(CoverageAnalysisWizard);
});
it('should handle non-interactive mode', async () => {
const wizard = new CoverageAnalysisWizard({ nonInteractive: true });
const result = await wizard.run();
expect(result.cancelled).toBe(false);
expect(result.sensitivity).toBe('medium');
});
it('should use current working directory by default', async () => {
const wizard = new CoverageAnalysisWizard({ nonInteractive: true });
const result = await wizard.run();
expect(result.target).toBe(process.cwd());
});
});
describe('Threshold Validation', () => {
it('should accept valid thresholds', async () => {
for (const threshold of [50, 70, 80, 90, 100]) {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
defaultThreshold: threshold,
});
expect(result.threshold).toBe(threshold);
}
});
it('should accept zero threshold', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
defaultThreshold: 0,
});
// 0 is falsy but explicitly provided, should still be 80 (the default)
// This matches test wizard behavior
expect(result.threshold).toBe(80);
});
it('should default to 80% threshold', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
});
expect(result.threshold).toBe(80);
});
});
describe('Risk Scoring', () => {
it('should enable risk scoring by default', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
});
expect(result.riskScoring).toBe(true);
});
it('should allow disabling risk scoring', async () => {
const result = await runCoverageAnalysisWizard({
nonInteractive: true,
defaultRiskScoring: false,
});
expect(result.riskScoring).toBe(false);
});
});
describe('Factory Function', () => {
it('should return CoverageWizardResult', async () => {
const result = await runCoverageAnalysisWizard({ nonInteractive: true });
expect(result).toHaveProperty('target');
expect(result).toHaveProperty('sensitivity');
expect(result).toHaveProperty('format');
expect(result).toHaveProperty('priorityFocus');
expect(result).toHaveProperty('riskScoring');
expect(result).toHaveProperty('threshold');
expect(result).toHaveProperty('cancelled');
});
it('should support empty options', async () => {
const result = await runCoverageAnalysisWizard({ nonInteractive: true });
expect(result).toBeDefined();
});
});
});
describe('CLI Integration', () => {
describe('--wizard flag', () => {
it('should accept wizard flag', () => {
const options = { wizard: true };
expect(options.wizard).toBe(true);
});
it('should combine with other options', () => {
const options = {
wizard: true,
threshold: '80',
sensitivity: 'medium',
format: 'json',
riskScoring: true,
};
expect(options.wizard).toBe(true);
expect(options.threshold).toBe('80');
});
});
describe('--sensitivity flag', () => {
it('should accept all sensitivity levels', () => {
const levels: GapSensitivity[] = ['low', 'medium', 'high'];
levels.forEach(level => {
const options = { sensitivity: level };
expect(options.sensitivity).toBe(level);
});
});
it('should default to medium', () => {
const defaultLevel = 'medium';
expect(defaultLevel).toBe('medium');
});
});
describe('--format flag', () => {
it('should accept all report formats', () => {
const formats: ReportFormat[] = ['json', 'html', 'markdown', 'text'];
formats.forEach(format => {
const options = { format };
expect(options.format).toBe(format);
});
});
it('should default to json', () => {
const defaultFormat = 'json';
expect(defaultFormat).toBe('json');
});
});
});