@oalacea/daemon 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +268 -58
- package/bin/Dockerfile +158 -16
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +22 -2
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/commands/command.types.d.ts +216 -0
- package/dist/cli/commands/command.types.d.ts.map +1 -0
- package/dist/cli/commands/command.types.js +64 -0
- package/dist/cli/commands/command.types.js.map +1 -0
- package/dist/cli/commands/history.command.d.ts +91 -0
- package/dist/cli/commands/history.command.d.ts.map +1 -0
- package/dist/cli/commands/history.command.js +336 -0
- package/dist/cli/commands/history.command.js.map +1 -0
- package/dist/cli/commands/index.d.ts +14 -3
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +7 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.command.d.ts +12 -14
- package/dist/cli/commands/init.command.d.ts.map +1 -1
- package/dist/cli/commands/init.command.js +278 -144
- package/dist/cli/commands/init.command.js.map +1 -1
- package/dist/cli/commands/optimize.command.d.ts +110 -0
- package/dist/cli/commands/optimize.command.d.ts.map +1 -0
- package/dist/cli/commands/optimize.command.js +497 -0
- package/dist/cli/commands/optimize.command.js.map +1 -0
- package/dist/cli/commands/report.command.d.ts +110 -0
- package/dist/cli/commands/report.command.d.ts.map +1 -0
- package/dist/cli/commands/report.command.js +532 -0
- package/dist/cli/commands/report.command.js.map +1 -0
- package/dist/cli/commands/review.command.d.ts +110 -0
- package/dist/cli/commands/review.command.d.ts.map +1 -0
- package/dist/cli/commands/review.command.js +520 -0
- package/dist/cli/commands/review.command.js.map +1 -0
- package/dist/cli/commands/score.command.d.ts +47 -0
- package/dist/cli/commands/score.command.d.ts.map +1 -0
- package/dist/cli/commands/score.command.js +261 -0
- package/dist/cli/commands/score.command.js.map +1 -0
- package/dist/cli/utils/index.d.ts +10 -0
- package/dist/cli/utils/index.d.ts.map +1 -0
- package/dist/cli/utils/index.js +10 -0
- package/dist/cli/utils/index.js.map +1 -0
- package/dist/cli/utils/output.d.ts +192 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +411 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/cli/utils/progress.d.ts +204 -0
- package/dist/cli/utils/progress.d.ts.map +1 -0
- package/dist/cli/utils/progress.js +396 -0
- package/dist/cli/utils/progress.js.map +1 -0
- package/dist/core/types/index.d.ts +1 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/project.types.d.ts +3 -3
- package/dist/core/types/project.types.d.ts.map +1 -1
- package/dist/core/types/scoring.types.d.ts +301 -0
- package/dist/core/types/scoring.types.d.ts.map +1 -0
- package/dist/core/types/scoring.types.js +8 -0
- package/dist/core/types/scoring.types.js.map +1 -0
- package/dist/services/detection/framework-detector.d.ts.map +1 -1
- package/dist/services/detection/framework-detector.js +74 -5
- package/dist/services/detection/framework-detector.js.map +1 -1
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +14 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/optimization/detectors/bug-detector.d.ts +82 -0
- package/dist/services/optimization/detectors/bug-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/bug-detector.js +443 -0
- package/dist/services/optimization/detectors/bug-detector.js.map +1 -0
- package/dist/services/optimization/detectors/code-smell-detector.d.ts +108 -0
- package/dist/services/optimization/detectors/code-smell-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/code-smell-detector.js +569 -0
- package/dist/services/optimization/detectors/code-smell-detector.js.map +1 -0
- package/dist/services/optimization/detectors/index.d.ts +7 -0
- package/dist/services/optimization/detectors/index.d.ts.map +1 -0
- package/dist/services/optimization/detectors/index.js +7 -0
- package/dist/services/optimization/detectors/index.js.map +1 -0
- package/dist/services/optimization/detectors/perf-detector.d.ts +80 -0
- package/dist/services/optimization/detectors/perf-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/perf-detector.js +451 -0
- package/dist/services/optimization/detectors/perf-detector.js.map +1 -0
- package/dist/services/optimization/index.d.ts +61 -0
- package/dist/services/optimization/index.d.ts.map +1 -0
- package/dist/services/optimization/index.js +69 -0
- package/dist/services/optimization/index.js.map +1 -0
- package/dist/services/optimization/optimization.service.d.ts +65 -0
- package/dist/services/optimization/optimization.service.d.ts.map +1 -0
- package/dist/services/optimization/optimization.service.js +511 -0
- package/dist/services/optimization/optimization.service.js.map +1 -0
- package/dist/services/optimization/optimization.types.d.ts +343 -0
- package/dist/services/optimization/optimization.types.d.ts.map +1 -0
- package/dist/services/optimization/optimization.types.js +8 -0
- package/dist/services/optimization/optimization.types.js.map +1 -0
- package/dist/services/optimization/optimizers/code-optimizer.d.ts +87 -0
- package/dist/services/optimization/optimizers/code-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/code-optimizer.js +436 -0
- package/dist/services/optimization/optimizers/code-optimizer.js.map +1 -0
- package/dist/services/optimization/optimizers/index.d.ts +7 -0
- package/dist/services/optimization/optimizers/index.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/index.js +7 -0
- package/dist/services/optimization/optimizers/index.js.map +1 -0
- package/dist/services/optimization/optimizers/perf-optimizer.d.ts +64 -0
- package/dist/services/optimization/optimizers/perf-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/perf-optimizer.js +330 -0
- package/dist/services/optimization/optimizers/perf-optimizer.js.map +1 -0
- package/dist/services/optimization/optimizers/refact-optimizer.d.ts +82 -0
- package/dist/services/optimization/optimizers/refact-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/refact-optimizer.js +354 -0
- package/dist/services/optimization/optimizers/refact-optimizer.js.map +1 -0
- package/dist/services/optimization/patterns/anti-patterns.d.ts +31 -0
- package/dist/services/optimization/patterns/anti-patterns.d.ts.map +1 -0
- package/dist/services/optimization/patterns/anti-patterns.js +501 -0
- package/dist/services/optimization/patterns/anti-patterns.js.map +1 -0
- package/dist/services/optimization/patterns/index.d.ts +5 -0
- package/dist/services/optimization/patterns/index.d.ts.map +1 -0
- package/dist/services/optimization/patterns/index.js +5 -0
- package/dist/services/optimization/patterns/index.js.map +1 -0
- package/dist/services/reporting/export/chart.exporter.d.ts +59 -0
- package/dist/services/reporting/export/chart.exporter.d.ts.map +1 -0
- package/dist/services/reporting/export/chart.exporter.js +350 -0
- package/dist/services/reporting/export/chart.exporter.js.map +1 -0
- package/dist/services/reporting/export/index.d.ts +9 -0
- package/dist/services/reporting/export/index.d.ts.map +1 -0
- package/dist/services/reporting/export/index.js +10 -0
- package/dist/services/reporting/export/index.js.map +1 -0
- package/dist/services/reporting/export/pdf.exporter.d.ts +133 -0
- package/dist/services/reporting/export/pdf.exporter.d.ts.map +1 -0
- package/dist/services/reporting/export/pdf.exporter.js +270 -0
- package/dist/services/reporting/export/pdf.exporter.js.map +1 -0
- package/dist/services/reporting/history.service.d.ts +93 -0
- package/dist/services/reporting/history.service.d.ts.map +1 -0
- package/dist/services/reporting/history.service.js +285 -0
- package/dist/services/reporting/history.service.js.map +1 -0
- package/dist/services/reporting/index.d.ts +15 -0
- package/dist/services/reporting/index.d.ts.map +1 -0
- package/dist/services/reporting/index.js +16 -0
- package/dist/services/reporting/index.js.map +1 -0
- package/dist/services/reporting/report.service.d.ts +102 -0
- package/dist/services/reporting/report.service.d.ts.map +1 -0
- package/dist/services/reporting/report.service.js +240 -0
- package/dist/services/reporting/report.service.js.map +1 -0
- package/dist/services/reporting/reporting.types.d.ts +329 -0
- package/dist/services/reporting/reporting.types.d.ts.map +1 -0
- package/dist/services/reporting/reporting.types.js +8 -0
- package/dist/services/reporting/reporting.types.js.map +1 -0
- package/dist/services/reporting/templates/html.template.d.ts +81 -0
- package/dist/services/reporting/templates/html.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/html.template.js +741 -0
- package/dist/services/reporting/templates/html.template.js.map +1 -0
- package/dist/services/reporting/templates/json.template.d.ts +85 -0
- package/dist/services/reporting/templates/json.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/json.template.js +308 -0
- package/dist/services/reporting/templates/json.template.js.map +1 -0
- package/dist/services/reporting/templates/markdown.template.d.ts +69 -0
- package/dist/services/reporting/templates/markdown.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/markdown.template.js +311 -0
- package/dist/services/reporting/templates/markdown.template.js.map +1 -0
- package/dist/services/reporting/trend-analyzer.d.ts +73 -0
- package/dist/services/reporting/trend-analyzer.d.ts.map +1 -0
- package/dist/services/reporting/trend-analyzer.js +291 -0
- package/dist/services/reporting/trend-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/dependency-analyzer.d.ts +87 -0
- package/dist/services/review/analyzers/dependency-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/dependency-analyzer.js +458 -0
- package/dist/services/review/analyzers/dependency-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/index.d.ts +13 -0
- package/dist/services/review/analyzers/index.d.ts.map +1 -0
- package/dist/services/review/analyzers/index.js +13 -0
- package/dist/services/review/analyzers/index.js.map +1 -0
- package/dist/services/review/analyzers/nestjs-analyzer.d.ts +210 -0
- package/dist/services/review/analyzers/nestjs-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/nestjs-analyzer.js +571 -0
- package/dist/services/review/analyzers/nestjs-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/performance-analyzer.d.ts +91 -0
- package/dist/services/review/analyzers/performance-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/performance-analyzer.js +589 -0
- package/dist/services/review/analyzers/performance-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/security-analyzer.d.ts +96 -0
- package/dist/services/review/analyzers/security-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/security-analyzer.js +512 -0
- package/dist/services/review/analyzers/security-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/static-analyzer.d.ts +90 -0
- package/dist/services/review/analyzers/static-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/static-analyzer.js +423 -0
- package/dist/services/review/analyzers/static-analyzer.js.map +1 -0
- package/dist/services/review/fixers/auto-fixer.d.ts +94 -0
- package/dist/services/review/fixers/auto-fixer.d.ts.map +1 -0
- package/dist/services/review/fixers/auto-fixer.js +404 -0
- package/dist/services/review/fixers/auto-fixer.js.map +1 -0
- package/dist/services/review/fixers/index.d.ts +11 -0
- package/dist/services/review/fixers/index.d.ts.map +1 -0
- package/dist/services/review/fixers/index.js +11 -0
- package/dist/services/review/fixers/index.js.map +1 -0
- package/dist/services/review/fixers/refactor-suggester.d.ts +100 -0
- package/dist/services/review/fixers/refactor-suggester.d.ts.map +1 -0
- package/dist/services/review/fixers/refactor-suggester.js +555 -0
- package/dist/services/review/fixers/refactor-suggester.js.map +1 -0
- package/dist/services/review/fixers/test-generator.d.ts +99 -0
- package/dist/services/review/fixers/test-generator.d.ts.map +1 -0
- package/dist/services/review/fixers/test-generator.js +458 -0
- package/dist/services/review/fixers/test-generator.js.map +1 -0
- package/dist/services/review/index.d.ts +14 -0
- package/dist/services/review/index.d.ts.map +1 -0
- package/dist/services/review/index.js +14 -0
- package/dist/services/review/index.js.map +1 -0
- package/dist/services/review/reporters/fix-reporter.d.ts +67 -0
- package/dist/services/review/reporters/fix-reporter.d.ts.map +1 -0
- package/dist/services/review/reporters/fix-reporter.js +437 -0
- package/dist/services/review/reporters/fix-reporter.js.map +1 -0
- package/dist/services/review/reporters/index.d.ts +10 -0
- package/dist/services/review/reporters/index.d.ts.map +1 -0
- package/dist/services/review/reporters/index.js +10 -0
- package/dist/services/review/reporters/index.js.map +1 -0
- package/dist/services/review/reporters/score-reporter.d.ts +84 -0
- package/dist/services/review/reporters/score-reporter.d.ts.map +1 -0
- package/dist/services/review/reporters/score-reporter.js +560 -0
- package/dist/services/review/reporters/score-reporter.js.map +1 -0
- package/dist/services/review/review.service.d.ts +129 -0
- package/dist/services/review/review.service.d.ts.map +1 -0
- package/dist/services/review/review.service.js +396 -0
- package/dist/services/review/review.service.js.map +1 -0
- package/dist/services/review/review.types.d.ts +443 -0
- package/dist/services/review/review.types.d.ts.map +1 -0
- package/dist/services/review/review.types.js +11 -0
- package/dist/services/review/review.types.js.map +1 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.d.ts +53 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.js +260 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.d.ts +138 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.js +713 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.d.ts +142 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.js +747 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.d.ts +142 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.js +685 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/index.d.ts +18 -0
- package/dist/services/scoring/dimensions/index.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/index.js +27 -0
- package/dist/services/scoring/dimensions/index.js.map +1 -0
- package/dist/services/scoring/dimensions/performance.analyzer.d.ts +125 -0
- package/dist/services/scoring/dimensions/performance.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/performance.analyzer.js +615 -0
- package/dist/services/scoring/dimensions/performance.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/security.analyzer.d.ts +53 -0
- package/dist/services/scoring/dimensions/security.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/security.analyzer.js +327 -0
- package/dist/services/scoring/dimensions/security.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/seo.analyzer.d.ts +77 -0
- package/dist/services/scoring/dimensions/seo.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/seo.analyzer.js +502 -0
- package/dist/services/scoring/dimensions/seo.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.d.ts +106 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.js +496 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.d.ts +126 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.js +665 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.js.map +1 -0
- package/dist/services/scoring/index.d.ts +10 -0
- package/dist/services/scoring/index.d.ts.map +1 -0
- package/dist/services/scoring/index.js +10 -0
- package/dist/services/scoring/index.js.map +1 -0
- package/dist/services/scoring/scoring-service.d.ts +222 -0
- package/dist/services/scoring/scoring-service.d.ts.map +1 -0
- package/dist/services/scoring/scoring-service.js +636 -0
- package/dist/services/scoring/scoring-service.js.map +1 -0
- package/package.json +11 -3
- package/templates/README.md +183 -0
- package/templates/nestjs/controller.spec.ts +203 -0
- package/templates/nestjs/e2e/api.e2e-spec.ts +451 -0
- package/templates/nestjs/e2e/auth.e2e-spec.ts +533 -0
- package/templates/nestjs/fixtures/test-module.ts +311 -0
- package/templates/nestjs/guard.spec.ts +314 -0
- package/templates/nestjs/interceptor.spec.ts +458 -0
- package/templates/nestjs/module.spec.ts +173 -0
- package/templates/nestjs/pipe.spec.ts +474 -0
- package/templates/nestjs/service.spec.ts +296 -0
- package/templates/rust/Cargo.toml +72 -0
- package/templates/rust/actix-controller.test.rs +114 -0
- package/templates/rust/axum-handler.test.rs +117 -0
- package/templates/rust/integration.test.rs +63 -0
- package/templates/rust/rocket-route.test.rs +106 -0
- package/templates/rust/unit.test.rs +38 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Coverage Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes test coverage for a project by parsing Vitest/Jest coverage reports.
|
|
5
|
+
* Evaluates lines, branches, functions, and statements coverage.
|
|
6
|
+
*
|
|
7
|
+
* @module services/scoring/dimensions/test-coverage
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, readdir, access } from 'node:fs/promises';
|
|
10
|
+
import { join, extname } from 'node:path';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { CommandExecutor } from '../../../shared/utils/command-executor.js';
|
|
13
|
+
import { createLogger } from '../../../shared/utils/logger.js';
|
|
14
|
+
/**
|
|
15
|
+
* Test Coverage Analyzer
|
|
16
|
+
*
|
|
17
|
+
* Evaluates test coverage across multiple metrics:
|
|
18
|
+
* - Line coverage
|
|
19
|
+
* - Branch coverage
|
|
20
|
+
* - Function coverage
|
|
21
|
+
* - Statement coverage
|
|
22
|
+
*/
|
|
23
|
+
export class TestCoverageAnalyzer {
|
|
24
|
+
/** Analyzer configuration */
|
|
25
|
+
config = {
|
|
26
|
+
dimension: 'test-coverage',
|
|
27
|
+
defaultWeight: 0.15,
|
|
28
|
+
estimatedDuration: 30000,
|
|
29
|
+
supportedFrameworks: ['Next.js', 'React', 'Vue', 'Nuxt', 'Svelte', 'NestJS', 'Angular', 'Remix', 'SvelteKit', 'Astro', 'Gatsby'],
|
|
30
|
+
};
|
|
31
|
+
logger;
|
|
32
|
+
executor;
|
|
33
|
+
targetCoverage;
|
|
34
|
+
minCoverage;
|
|
35
|
+
coveragePaths;
|
|
36
|
+
testCommand;
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
this.logger = createLogger('TestCoverageAnalyzer');
|
|
39
|
+
this.executor = new CommandExecutor();
|
|
40
|
+
this.targetCoverage = options.targetCoverage ?? 80;
|
|
41
|
+
this.minCoverage = options.minCoverage ?? 50;
|
|
42
|
+
this.coveragePaths = options.coveragePaths ?? this.getDefaultCoveragePaths();
|
|
43
|
+
this.testCommand = options.testCommand ?? 'npm test -- --coverage';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get default coverage file paths
|
|
47
|
+
*/
|
|
48
|
+
getDefaultCoveragePaths() {
|
|
49
|
+
return [
|
|
50
|
+
'coverage/coverage-summary.json',
|
|
51
|
+
'coverage/coverage-final.json',
|
|
52
|
+
'coverage/lcov.info',
|
|
53
|
+
'.nyc_output/out.json',
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the dimension this analyzer handles
|
|
58
|
+
*/
|
|
59
|
+
getDimension() {
|
|
60
|
+
return 'test-coverage';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the default weight for this dimension
|
|
64
|
+
*/
|
|
65
|
+
getWeight() {
|
|
66
|
+
return 0.15; // 15% weight in overall score
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Analyze test coverage for a project
|
|
70
|
+
*
|
|
71
|
+
* @param projectPath - Path to the project root
|
|
72
|
+
* @returns Dimension score with coverage metrics
|
|
73
|
+
*/
|
|
74
|
+
async analyze(projectPath) {
|
|
75
|
+
const startTime = performance.now();
|
|
76
|
+
this.logger.info(`Analyzing test coverage for: ${projectPath}`);
|
|
77
|
+
const issues = [];
|
|
78
|
+
const improvements = [];
|
|
79
|
+
try {
|
|
80
|
+
// Try to read existing coverage report
|
|
81
|
+
const coverageReport = await this.readCoverageReport(projectPath);
|
|
82
|
+
if (!coverageReport) {
|
|
83
|
+
// No coverage report found - try to generate one
|
|
84
|
+
this.logger.info('No coverage report found, attempting to generate...');
|
|
85
|
+
const generated = await this.generateCoverageReport(projectPath);
|
|
86
|
+
if (!generated) {
|
|
87
|
+
return this.createNoCoverageResult(issues, improvements);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Read coverage data
|
|
91
|
+
const coverage = await this.readCoverageReport(projectPath);
|
|
92
|
+
if (!coverage) {
|
|
93
|
+
return this.createNoCoverageResult(issues, improvements);
|
|
94
|
+
}
|
|
95
|
+
// Calculate scores
|
|
96
|
+
const metrics = this.extractCoverageMetrics(coverage);
|
|
97
|
+
// Find uncovered files
|
|
98
|
+
const uncoveredFiles = await this.findUncoveredFiles(projectPath, coverage);
|
|
99
|
+
// Build issues list
|
|
100
|
+
issues.push(...this.identifyCoverageIssues(metrics, uncoveredFiles));
|
|
101
|
+
// Build improvements list
|
|
102
|
+
improvements.push(...this.generateCoverageImprovements(metrics, uncoveredFiles));
|
|
103
|
+
// Calculate final score
|
|
104
|
+
const score = this.calculateCoverageScore(metrics);
|
|
105
|
+
const duration = Math.round(performance.now() - startTime);
|
|
106
|
+
return {
|
|
107
|
+
dimension: this.getDimension(),
|
|
108
|
+
score,
|
|
109
|
+
weight: this.getWeight(),
|
|
110
|
+
weightedScore: score * this.getWeight(),
|
|
111
|
+
issues,
|
|
112
|
+
improvements,
|
|
113
|
+
metadata: {
|
|
114
|
+
itemsChecked: metrics.totalFiles,
|
|
115
|
+
itemsPassed: metrics.fullyCoveredFiles,
|
|
116
|
+
metrics: {
|
|
117
|
+
lineCoverage: metrics.lines.pct,
|
|
118
|
+
branchCoverage: metrics.branches.pct,
|
|
119
|
+
functionCoverage: metrics.functions.pct,
|
|
120
|
+
statementCoverage: metrics.statements.pct,
|
|
121
|
+
totalFiles: metrics.totalFiles,
|
|
122
|
+
uncoveredFiles: uncoveredFiles.length,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
this.logger.error('Error analyzing test coverage', error);
|
|
129
|
+
issues.push({
|
|
130
|
+
severity: 'high',
|
|
131
|
+
category: 'testing',
|
|
132
|
+
description: `Failed to analyze test coverage: ${error instanceof Error ? error.message : String(error)}`,
|
|
133
|
+
fixable: false,
|
|
134
|
+
});
|
|
135
|
+
const duration = Math.round(performance.now() - startTime);
|
|
136
|
+
return {
|
|
137
|
+
dimension: this.getDimension(),
|
|
138
|
+
score: 0,
|
|
139
|
+
weight: this.getWeight(),
|
|
140
|
+
weightedScore: 0,
|
|
141
|
+
issues,
|
|
142
|
+
improvements,
|
|
143
|
+
metadata: { error: String(error) },
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Read coverage report from standard locations
|
|
149
|
+
*/
|
|
150
|
+
async readCoverageReport(projectPath) {
|
|
151
|
+
for (const relativePath of this.coveragePaths) {
|
|
152
|
+
const fullPath = join(projectPath, relativePath);
|
|
153
|
+
try {
|
|
154
|
+
await access(fullPath);
|
|
155
|
+
const content = await readFile(fullPath, 'utf-8');
|
|
156
|
+
if (relativePath.endsWith('.json')) {
|
|
157
|
+
return JSON.parse(content);
|
|
158
|
+
}
|
|
159
|
+
// Parse lcov.info if needed (simplified)
|
|
160
|
+
if (relativePath.endsWith('lcov.info')) {
|
|
161
|
+
return this.parseLcovInfo(content);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// File doesn't exist or can't be read
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Parse lcov.info format to coverage summary
|
|
173
|
+
*/
|
|
174
|
+
parseLcovInfo(content) {
|
|
175
|
+
// Simplified parsing - in production would use a proper lcov parser
|
|
176
|
+
const lines = content.split('\n');
|
|
177
|
+
let totalLines = 0;
|
|
178
|
+
let coveredLines = 0;
|
|
179
|
+
let totalBranches = 0;
|
|
180
|
+
let coveredBranches = 0;
|
|
181
|
+
let totalFunctions = 0;
|
|
182
|
+
let coveredFunctions = 0;
|
|
183
|
+
for (const line of lines) {
|
|
184
|
+
if (line.startsWith('LF:')) {
|
|
185
|
+
totalLines += parseInt(line.substring(3), 10);
|
|
186
|
+
}
|
|
187
|
+
else if (line.startsWith('LH:')) {
|
|
188
|
+
coveredLines += parseInt(line.substring(3), 10);
|
|
189
|
+
}
|
|
190
|
+
else if (line.startsWith('BRF:')) {
|
|
191
|
+
totalBranches += parseInt(line.substring(4), 10);
|
|
192
|
+
}
|
|
193
|
+
else if (line.startsWith('BRH:')) {
|
|
194
|
+
coveredBranches += parseInt(line.substring(4), 10);
|
|
195
|
+
}
|
|
196
|
+
else if (line.startsWith('FNF:')) {
|
|
197
|
+
totalFunctions += parseInt(line.substring(4), 10);
|
|
198
|
+
}
|
|
199
|
+
else if (line.startsWith('FNH:')) {
|
|
200
|
+
coveredFunctions += parseInt(line.substring(4), 10);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
total: {
|
|
205
|
+
lines: {
|
|
206
|
+
total: totalLines,
|
|
207
|
+
covered: coveredLines,
|
|
208
|
+
pct: totalLines > 0 ? (coveredLines / totalLines) * 100 : 0,
|
|
209
|
+
},
|
|
210
|
+
branches: {
|
|
211
|
+
total: totalBranches,
|
|
212
|
+
covered: coveredBranches,
|
|
213
|
+
pct: totalBranches > 0 ? (coveredBranches / totalBranches) * 100 : 0,
|
|
214
|
+
},
|
|
215
|
+
functions: {
|
|
216
|
+
total: totalFunctions,
|
|
217
|
+
covered: coveredFunctions,
|
|
218
|
+
pct: totalFunctions > 0 ? (coveredFunctions / totalFunctions) * 100 : 0,
|
|
219
|
+
},
|
|
220
|
+
statements: {
|
|
221
|
+
total: totalLines,
|
|
222
|
+
covered: coveredLines,
|
|
223
|
+
pct: totalLines > 0 ? (coveredLines / totalLines) * 100 : 0,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Generate coverage report by running tests
|
|
230
|
+
*/
|
|
231
|
+
async generateCoverageReport(projectPath) {
|
|
232
|
+
try {
|
|
233
|
+
const result = await this.executor.execute(this.testCommand, {
|
|
234
|
+
cwd: projectPath,
|
|
235
|
+
timeout: 120000, // 2 minutes
|
|
236
|
+
silent: true,
|
|
237
|
+
});
|
|
238
|
+
return result.success;
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
this.logger.warn('Failed to generate coverage report', error);
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Extract coverage metrics from report
|
|
247
|
+
*/
|
|
248
|
+
extractCoverageMetrics(report) {
|
|
249
|
+
return {
|
|
250
|
+
lines: report.total.lines,
|
|
251
|
+
branches: report.total.branches,
|
|
252
|
+
functions: report.total.functions,
|
|
253
|
+
statements: report.total.statements,
|
|
254
|
+
totalFiles: 0, // Would need detailed report
|
|
255
|
+
fullyCoveredFiles: 0,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Find files with low or no coverage
|
|
260
|
+
*/
|
|
261
|
+
async findUncoveredFiles(projectPath, coverage) {
|
|
262
|
+
const uncovered = [];
|
|
263
|
+
// Scan source directory for uncovered files
|
|
264
|
+
const srcDir = join(projectPath, 'src');
|
|
265
|
+
if (!existsSync(srcDir)) {
|
|
266
|
+
return uncovered;
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
await this.scanDirectoryForCoverage(srcDir, projectPath, uncovered);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
this.logger.warn('Error scanning for uncovered files', error);
|
|
273
|
+
}
|
|
274
|
+
return uncovered;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Recursively scan directory for source files
|
|
278
|
+
*/
|
|
279
|
+
async scanDirectoryForCoverage(dir, projectPath, uncovered) {
|
|
280
|
+
try {
|
|
281
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
282
|
+
for (const entry of entries) {
|
|
283
|
+
const fullPath = join(dir, entry.name);
|
|
284
|
+
if (entry.isDirectory()) {
|
|
285
|
+
// Skip common directories
|
|
286
|
+
if (['node_modules', '.git', 'dist', 'build', 'coverage'].includes(entry.name)) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
await this.scanDirectoryForCoverage(fullPath, projectPath, uncovered);
|
|
290
|
+
}
|
|
291
|
+
else if (entry.isFile()) {
|
|
292
|
+
const ext = extname(entry.name);
|
|
293
|
+
if (['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
|
|
294
|
+
// Check if file has tests (simplified check)
|
|
295
|
+
const relativePath = fullPath.substring(projectPath.length + 1);
|
|
296
|
+
const testPath = fullPath.replace(ext, `.test${ext}`);
|
|
297
|
+
try {
|
|
298
|
+
await access(testPath);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// No test file found
|
|
302
|
+
uncovered.push({
|
|
303
|
+
filepath: relativePath,
|
|
304
|
+
coverage: 0,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Directory not accessible
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Identify coverage issues
|
|
317
|
+
*/
|
|
318
|
+
identifyCoverageIssues(metrics, uncoveredFiles) {
|
|
319
|
+
const issues = [];
|
|
320
|
+
// Check overall coverage
|
|
321
|
+
const avgCoverage = (metrics.lines.pct + metrics.branches.pct + metrics.functions.pct + metrics.statements.pct) / 4;
|
|
322
|
+
if (avgCoverage < this.minCoverage) {
|
|
323
|
+
issues.push({
|
|
324
|
+
severity: 'critical',
|
|
325
|
+
category: 'testing',
|
|
326
|
+
description: `Overall test coverage (${avgCoverage.toFixed(1)}%) is below minimum threshold (${this.minCoverage}%)`,
|
|
327
|
+
fixable: false,
|
|
328
|
+
suggestion: `Add tests to increase coverage to at least ${this.targetCoverage}%`,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
else if (avgCoverage < this.targetCoverage) {
|
|
332
|
+
issues.push({
|
|
333
|
+
severity: 'medium',
|
|
334
|
+
category: 'testing',
|
|
335
|
+
description: `Overall test coverage (${avgCoverage.toFixed(1)}%) is below target (${this.targetCoverage}%)`,
|
|
336
|
+
fixable: false,
|
|
337
|
+
suggestion: `Add tests to reach ${this.targetCoverage}% coverage`,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
// Check specific metrics
|
|
341
|
+
if (metrics.lines.pct < this.targetCoverage) {
|
|
342
|
+
issues.push({
|
|
343
|
+
severity: 'medium',
|
|
344
|
+
category: 'testing',
|
|
345
|
+
description: `Line coverage (${metrics.lines.pct.toFixed(1)}%) is below target`,
|
|
346
|
+
fixable: false,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
if (metrics.branches.pct < this.targetCoverage) {
|
|
350
|
+
issues.push({
|
|
351
|
+
severity: 'medium',
|
|
352
|
+
category: 'testing',
|
|
353
|
+
description: `Branch coverage (${metrics.branches.pct.toFixed(1)}%) is below target`,
|
|
354
|
+
fixable: false,
|
|
355
|
+
suggestion: 'Add tests for conditional branches and edge cases',
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
if (metrics.functions.pct < this.targetCoverage) {
|
|
359
|
+
issues.push({
|
|
360
|
+
severity: 'medium',
|
|
361
|
+
category: 'testing',
|
|
362
|
+
description: `Function coverage (${metrics.functions.pct.toFixed(1)}%) is below target`,
|
|
363
|
+
fixable: false,
|
|
364
|
+
suggestion: 'Add tests for uncovered functions',
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
// Check for files without tests
|
|
368
|
+
if (uncoveredFiles.length > 0) {
|
|
369
|
+
issues.push({
|
|
370
|
+
severity: 'low',
|
|
371
|
+
category: 'testing',
|
|
372
|
+
description: `${uncoveredFiles.length} source files lack corresponding test files`,
|
|
373
|
+
fixable: false,
|
|
374
|
+
suggestion: 'Create test files for uncovered source files',
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return issues;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Generate improvement suggestions
|
|
381
|
+
*/
|
|
382
|
+
generateCoverageImprovements(metrics, uncoveredFiles) {
|
|
383
|
+
const improvements = [];
|
|
384
|
+
const avgCoverage = (metrics.lines.pct + metrics.branches.pct + metrics.functions.pct + metrics.statements.pct) / 4;
|
|
385
|
+
// Overall coverage improvement
|
|
386
|
+
if (avgCoverage < this.targetCoverage) {
|
|
387
|
+
const gap = this.targetCoverage - avgCoverage;
|
|
388
|
+
improvements.push({
|
|
389
|
+
type: 'add-test',
|
|
390
|
+
description: `Increase overall test coverage by ${gap.toFixed(1)}% to reach target of ${this.targetCoverage}%`,
|
|
391
|
+
effort: 'moderate',
|
|
392
|
+
impact: gap > 20 ? 'high' : 'medium',
|
|
393
|
+
steps: [
|
|
394
|
+
'Identify critical code paths lacking coverage',
|
|
395
|
+
'Write unit tests for business logic functions',
|
|
396
|
+
'Add integration tests for API endpoints',
|
|
397
|
+
'Include edge case and error scenario tests',
|
|
398
|
+
],
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// Branch coverage improvement
|
|
402
|
+
if (metrics.branches.pct < this.targetCoverage) {
|
|
403
|
+
improvements.push({
|
|
404
|
+
type: 'add-test',
|
|
405
|
+
description: 'Improve branch coverage by testing conditional logic',
|
|
406
|
+
effort: 'moderate',
|
|
407
|
+
impact: 'medium',
|
|
408
|
+
steps: [
|
|
409
|
+
'Review functions with complex conditionals',
|
|
410
|
+
'Add tests for each branch path',
|
|
411
|
+
'Test error handling paths',
|
|
412
|
+
'Include boundary value tests',
|
|
413
|
+
],
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
// Add tests for uncovered files
|
|
417
|
+
if (uncoveredFiles.length > 0 && uncoveredFiles.length <= 10) {
|
|
418
|
+
improvements.push({
|
|
419
|
+
type: 'add-test',
|
|
420
|
+
description: `Create test files for ${uncoveredFiles.length} uncovered source files`,
|
|
421
|
+
effort: 'moderate',
|
|
422
|
+
impact: 'medium',
|
|
423
|
+
steps: uncoveredFiles.slice(0, 5).map((f) => `Create tests for ${f.filepath}`),
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
return improvements;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Calculate final coverage score
|
|
430
|
+
*/
|
|
431
|
+
calculateCoverageScore(metrics) {
|
|
432
|
+
// Weighted average of coverage metrics
|
|
433
|
+
// Lines and statements are more important than functions and branches
|
|
434
|
+
const weights = {
|
|
435
|
+
lines: 0.3,
|
|
436
|
+
branches: 0.25,
|
|
437
|
+
functions: 0.2,
|
|
438
|
+
statements: 0.25,
|
|
439
|
+
};
|
|
440
|
+
const weightedAverage = metrics.lines.pct * weights.lines +
|
|
441
|
+
metrics.branches.pct * weights.branches +
|
|
442
|
+
metrics.functions.pct * weights.functions +
|
|
443
|
+
metrics.statements.pct * weights.statements;
|
|
444
|
+
// Apply curve - scores above 80% get bonus, below 50% get penalty
|
|
445
|
+
if (weightedAverage >= this.targetCoverage) {
|
|
446
|
+
return Math.min(100, weightedAverage + 5);
|
|
447
|
+
}
|
|
448
|
+
else if (weightedAverage >= this.minCoverage) {
|
|
449
|
+
return weightedAverage;
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// Penalize very low coverage
|
|
453
|
+
return (weightedAverage / this.minCoverage) * 50;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Create result when no coverage data is available
|
|
458
|
+
*/
|
|
459
|
+
createNoCoverageResult(issues, improvements) {
|
|
460
|
+
issues.unshift({
|
|
461
|
+
severity: 'critical',
|
|
462
|
+
category: 'testing',
|
|
463
|
+
description: 'No test coverage data found. Configure test coverage reporting.',
|
|
464
|
+
fixable: true,
|
|
465
|
+
suggestion: `Set up test coverage for your test runner (Vitest: --coverage, Jest: --coverage)`,
|
|
466
|
+
});
|
|
467
|
+
improvements.push({
|
|
468
|
+
type: 'add-test',
|
|
469
|
+
description: 'Set up test coverage reporting',
|
|
470
|
+
effort: 'quick',
|
|
471
|
+
impact: 'high',
|
|
472
|
+
steps: [
|
|
473
|
+
'Install coverage dependencies (c8, istanbul, or vitest/coverage)',
|
|
474
|
+
'Configure coverage in test config file',
|
|
475
|
+
'Add coverage script to package.json',
|
|
476
|
+
'Run tests with coverage flag',
|
|
477
|
+
],
|
|
478
|
+
});
|
|
479
|
+
return {
|
|
480
|
+
dimension: this.getDimension(),
|
|
481
|
+
score: 0,
|
|
482
|
+
weight: this.getWeight(),
|
|
483
|
+
weightedScore: 0,
|
|
484
|
+
issues,
|
|
485
|
+
improvements,
|
|
486
|
+
metadata: {
|
|
487
|
+
metrics: { hasCoverage: 0 },
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Default analyzer instance
|
|
494
|
+
*/
|
|
495
|
+
export const testCoverageAnalyzer = new TestCoverageAnalyzer();
|
|
496
|
+
//# sourceMappingURL=test-coverage.analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-coverage.analyzer.js","sourceRoot":"","sources":["../../../../src/services/scoring/dimensions/test-coverage.analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI/UX Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes UI/UX quality including responsive design, loading states,
|
|
5
|
+
* error handling UX, form validation feedback, and empty states.
|
|
6
|
+
*
|
|
7
|
+
* @module services/scoring/dimensions/ui-ux
|
|
8
|
+
*/
|
|
9
|
+
import type { DimensionScore, CodeDimension, DimensionAnalyzerConfig } from '../../../core/types/scoring.types.js';
|
|
10
|
+
import type { Framework } from '../../../core/types/project.types.js';
|
|
11
|
+
import type { ScoringOptions } from '../../../core/types/scoring.types.js';
|
|
12
|
+
/**
|
|
13
|
+
* UI/UX analyzer configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface UiUxAnalyzerOptions {
|
|
16
|
+
/** Check for responsive design */
|
|
17
|
+
checkResponsive?: boolean;
|
|
18
|
+
/** Check for loading states */
|
|
19
|
+
checkLoadingStates?: boolean;
|
|
20
|
+
/** Check for error handling */
|
|
21
|
+
checkErrorHandling?: boolean;
|
|
22
|
+
/** Check for form validation */
|
|
23
|
+
checkFormValidation?: boolean;
|
|
24
|
+
/** Check for empty states */
|
|
25
|
+
checkEmptyStates?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* UI/UX Analyzer
|
|
29
|
+
*
|
|
30
|
+
* Evaluates UI/UX quality across multiple dimensions:
|
|
31
|
+
* - Responsive design (viewport meta, media queries)
|
|
32
|
+
* - Loading states (skeletons, spinners)
|
|
33
|
+
* - Error handling UX
|
|
34
|
+
* - Form validation feedback
|
|
35
|
+
* - Empty states
|
|
36
|
+
*/
|
|
37
|
+
export declare class UiUxAnalyzer {
|
|
38
|
+
/** Analyzer configuration */
|
|
39
|
+
readonly config: DimensionAnalyzerConfig;
|
|
40
|
+
private readonly logger;
|
|
41
|
+
private readonly executor;
|
|
42
|
+
private readonly _checkResponsive;
|
|
43
|
+
private readonly _checkLoadingStates;
|
|
44
|
+
private readonly _checkErrorHandling;
|
|
45
|
+
private readonly _checkFormValidation;
|
|
46
|
+
private readonly _checkEmptyStates;
|
|
47
|
+
constructor(options?: UiUxAnalyzerOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Get the dimension this analyzer handles
|
|
50
|
+
*/
|
|
51
|
+
getDimension(): CodeDimension;
|
|
52
|
+
/**
|
|
53
|
+
* Get the default weight for this dimension
|
|
54
|
+
*/
|
|
55
|
+
getWeight(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Analyze UI/UX for a project
|
|
58
|
+
*
|
|
59
|
+
* @param projectPath - Path to the project root
|
|
60
|
+
* @param _framework - Detected framework (optional, for framework-specific analysis)
|
|
61
|
+
* @param _options - Scoring options (optional)
|
|
62
|
+
* @returns Dimension score with UI/UX metrics
|
|
63
|
+
*/
|
|
64
|
+
analyze(projectPath: string, _framework?: Framework, _options?: ScoringOptions): Promise<DimensionScore>;
|
|
65
|
+
/**
|
|
66
|
+
* Check for responsive design
|
|
67
|
+
*/
|
|
68
|
+
private checkResponsiveDesign;
|
|
69
|
+
/**
|
|
70
|
+
* Scan directory for media queries
|
|
71
|
+
*/
|
|
72
|
+
private scanDirectoryForMediaQueries;
|
|
73
|
+
/**
|
|
74
|
+
* Check for loading states
|
|
75
|
+
*/
|
|
76
|
+
private checkLoadingStatesPatterns;
|
|
77
|
+
/**
|
|
78
|
+
* Scan directory for loading patterns
|
|
79
|
+
*/
|
|
80
|
+
private scanDirectoryForLoadingPatterns;
|
|
81
|
+
/**
|
|
82
|
+
* Check for error handling
|
|
83
|
+
*/
|
|
84
|
+
private checkErrorHandlingPatterns;
|
|
85
|
+
/**
|
|
86
|
+
* Scan directory for error patterns
|
|
87
|
+
*/
|
|
88
|
+
private scanDirectoryForErrorPatterns;
|
|
89
|
+
/**
|
|
90
|
+
* Check for form validation
|
|
91
|
+
*/
|
|
92
|
+
private checkFormValidationPatterns;
|
|
93
|
+
/**
|
|
94
|
+
* Scan directory for validation patterns
|
|
95
|
+
*/
|
|
96
|
+
private scanDirectoryForValidationPatterns;
|
|
97
|
+
/**
|
|
98
|
+
* Check for empty states
|
|
99
|
+
*/
|
|
100
|
+
private checkEmptyStatesPatterns;
|
|
101
|
+
/**
|
|
102
|
+
* Scan directory for empty states
|
|
103
|
+
*/
|
|
104
|
+
private scanDirectoryForEmptyStates;
|
|
105
|
+
/**
|
|
106
|
+
* Identify UI/UX issues
|
|
107
|
+
*/
|
|
108
|
+
private identifyUiUxIssues;
|
|
109
|
+
/**
|
|
110
|
+
* Generate UI/UX improvements
|
|
111
|
+
*/
|
|
112
|
+
private generateUiUxImprovements;
|
|
113
|
+
/**
|
|
114
|
+
* Calculate UI/UX score
|
|
115
|
+
*/
|
|
116
|
+
private calculateUiUxScore;
|
|
117
|
+
/**
|
|
118
|
+
* Count passed checks for metadata
|
|
119
|
+
*/
|
|
120
|
+
private countPassedChecks;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Default analyzer instance
|
|
124
|
+
*/
|
|
125
|
+
export declare const uiUxAnalyzer: UiUxAnalyzer;
|
|
126
|
+
//# sourceMappingURL=ui-ux.analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-ux.analyzer.d.ts","sourceRoot":"","sources":["../../../../src/services/scoring/dimensions/ui-ux.analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,cAAc,EAGd,aAAa,EAMb,uBAAuB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AA6C3E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kCAAkC;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gCAAgC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAKtC;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;gBAEhC,OAAO,GAAE,mBAAwB;IAU7C;;OAEG;IACH,YAAY,IAAI,aAAa;IAI7B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;;;;;;OAOG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IA2F9G;;OAEG;YACW,qBAAqB;IAoDnC;;OAEG;YACW,4BAA4B;IA6B1C;;OAEG;YACW,0BAA0B;IA4BxC;;OAEG;YACW,+BAA+B;IAoC7C;;OAEG;YACW,0BAA0B;IA4BxC;;OAEG;YACW,6BAA6B;IAoC3C;;OAEG;YACW,2BAA2B;IAyCzC;;OAEG;YACW,kCAAkC;IAoChD;;OAEG;YACW,wBAAwB;IAgCtC;;OAEG;YACW,2BAA2B;IAkCzC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwD1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA+EhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAS1B;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|