@facet-coverage/core 0.1.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/LICENSE +21 -0
- package/README.md +422 -0
- package/bin/facet-coverage.js +3 -0
- package/dist/cli/commands/analyze.d.ts +13 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +161 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +10 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +67 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +11 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +120 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +10 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +151 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +47 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/CoverageCalculator.d.ts +34 -0
- package/dist/core/CoverageCalculator.d.ts.map +1 -0
- package/dist/core/CoverageCalculator.js +167 -0
- package/dist/core/CoverageCalculator.js.map +1 -0
- package/dist/core/FacetParser.d.ts +39 -0
- package/dist/core/FacetParser.d.ts.map +1 -0
- package/dist/core/FacetParser.js +114 -0
- package/dist/core/FacetParser.js.map +1 -0
- package/dist/core/StructureReader.d.ts +37 -0
- package/dist/core/StructureReader.d.ts.map +1 -0
- package/dist/core/StructureReader.js +126 -0
- package/dist/core/StructureReader.js.map +1 -0
- package/dist/core/TestScanner.d.ts +36 -0
- package/dist/core/TestScanner.d.ts.map +1 -0
- package/dist/core/TestScanner.js +192 -0
- package/dist/core/TestScanner.js.map +1 -0
- package/dist/core/Validator.d.ts +33 -0
- package/dist/core/Validator.d.ts.map +1 -0
- package/dist/core/Validator.js +183 -0
- package/dist/core/Validator.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/playwright.d.ts +95 -0
- package/dist/integrations/playwright.d.ts.map +1 -0
- package/dist/integrations/playwright.js +168 -0
- package/dist/integrations/playwright.js.map +1 -0
- package/dist/reporters/HtmlReporter.d.ts +53 -0
- package/dist/reporters/HtmlReporter.d.ts.map +1 -0
- package/dist/reporters/HtmlReporter.js +484 -0
- package/dist/reporters/HtmlReporter.js.map +1 -0
- package/dist/reporters/JsonReporter.d.ts +21 -0
- package/dist/reporters/JsonReporter.d.ts.map +1 -0
- package/dist/reporters/JsonReporter.js +58 -0
- package/dist/reporters/JsonReporter.js.map +1 -0
- package/dist/reporters/MarkdownReporter.d.ts +25 -0
- package/dist/reporters/MarkdownReporter.d.ts.map +1 -0
- package/dist/reporters/MarkdownReporter.js +141 -0
- package/dist/reporters/MarkdownReporter.js.map +1 -0
- package/dist/reporters/index.d.ts +4 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +10 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoverageCalculator.js","sourceRoot":"","sources":["../../src/core/CoverageCalculator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { MarkdownSection, ParsedMarkdown } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses markdown files and extracts sections
|
|
4
|
+
*/
|
|
5
|
+
export declare class FacetParser {
|
|
6
|
+
/**
|
|
7
|
+
* Convert a title to a URL-friendly slug
|
|
8
|
+
*/
|
|
9
|
+
static slugify(title: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Parse a markdown file and extract all sections
|
|
12
|
+
*/
|
|
13
|
+
parseFile(filePath: string): ParsedMarkdown;
|
|
14
|
+
/**
|
|
15
|
+
* Parse markdown content and extract sections
|
|
16
|
+
*/
|
|
17
|
+
parseContent(content: string, filePath?: string): ParsedMarkdown;
|
|
18
|
+
/**
|
|
19
|
+
* Find a section by its slug
|
|
20
|
+
*/
|
|
21
|
+
findSection(parsed: ParsedMarkdown, slug: string): MarkdownSection | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a section exists in a file
|
|
24
|
+
*/
|
|
25
|
+
sectionExists(filePath: string, sectionSlug: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get all section slugs from a file
|
|
28
|
+
*/
|
|
29
|
+
getSectionSlugs(filePath: string): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Extract the filename without extension as a prefix
|
|
32
|
+
*/
|
|
33
|
+
static getFilePrefix(filePath: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Generate facet ID from file and section
|
|
36
|
+
*/
|
|
37
|
+
static generateFacetId(filePath: string, sectionSlug: string): string;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=FacetParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetParser.d.ts","sourceRoot":"","sources":["../../src/core/FacetParser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUrC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAS3C;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAW,GAAG,cAAc;IAgDpE;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI9E;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAS7D;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAK3C;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAK9C;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAItE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FacetParser = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
/**
|
|
6
|
+
* Parses markdown files and extracts sections
|
|
7
|
+
*/
|
|
8
|
+
class FacetParser {
|
|
9
|
+
/**
|
|
10
|
+
* Convert a title to a URL-friendly slug
|
|
11
|
+
*/
|
|
12
|
+
static slugify(title) {
|
|
13
|
+
return title
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.trim()
|
|
16
|
+
.replace(/[^\w\s-]/g, '') // Remove special characters
|
|
17
|
+
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
18
|
+
.replace(/-+/g, '-') // Replace multiple hyphens with single
|
|
19
|
+
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a markdown file and extract all sections
|
|
23
|
+
*/
|
|
24
|
+
parseFile(filePath) {
|
|
25
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
26
|
+
throw new Error(`Markdown file not found: ${filePath}`);
|
|
27
|
+
}
|
|
28
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
29
|
+
return this.parseContent(content, filePath);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse markdown content and extract sections
|
|
33
|
+
*/
|
|
34
|
+
parseContent(content, filePath = '') {
|
|
35
|
+
const lines = content.split('\n');
|
|
36
|
+
const sections = [];
|
|
37
|
+
// First pass: find all headings
|
|
38
|
+
const headings = [];
|
|
39
|
+
for (let i = 0; i < lines.length; i++) {
|
|
40
|
+
const line = lines[i];
|
|
41
|
+
const match = line.match(/^(#{1,6})\s+(.+)$/);
|
|
42
|
+
if (match) {
|
|
43
|
+
headings.push({
|
|
44
|
+
level: match[1].length,
|
|
45
|
+
title: match[2].trim(),
|
|
46
|
+
line: i + 1, // 1-indexed
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Second pass: create sections with content
|
|
51
|
+
for (let i = 0; i < headings.length; i++) {
|
|
52
|
+
const heading = headings[i];
|
|
53
|
+
const nextHeading = headings[i + 1];
|
|
54
|
+
const startLine = heading.line;
|
|
55
|
+
const endLine = nextHeading ? nextHeading.line - 1 : lines.length;
|
|
56
|
+
// Extract content between headings
|
|
57
|
+
const contentLines = lines.slice(startLine, endLine - 1);
|
|
58
|
+
const sectionContent = contentLines.join('\n').trim();
|
|
59
|
+
sections.push({
|
|
60
|
+
title: heading.title,
|
|
61
|
+
slug: FacetParser.slugify(heading.title),
|
|
62
|
+
level: heading.level,
|
|
63
|
+
startLine,
|
|
64
|
+
endLine,
|
|
65
|
+
content: sectionContent,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
file: filePath,
|
|
70
|
+
sections,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find a section by its slug
|
|
75
|
+
*/
|
|
76
|
+
findSection(parsed, slug) {
|
|
77
|
+
return parsed.sections.find(s => s.slug === slug);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a section exists in a file
|
|
81
|
+
*/
|
|
82
|
+
sectionExists(filePath, sectionSlug) {
|
|
83
|
+
try {
|
|
84
|
+
const parsed = this.parseFile(filePath);
|
|
85
|
+
return this.findSection(parsed, sectionSlug) !== undefined;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get all section slugs from a file
|
|
93
|
+
*/
|
|
94
|
+
getSectionSlugs(filePath) {
|
|
95
|
+
const parsed = this.parseFile(filePath);
|
|
96
|
+
return parsed.sections.map(s => s.slug);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract the filename without extension as a prefix
|
|
100
|
+
*/
|
|
101
|
+
static getFilePrefix(filePath) {
|
|
102
|
+
const basename = filePath.split('/').pop() || '';
|
|
103
|
+
return basename.replace(/\.md$/i, '').toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate facet ID from file and section
|
|
107
|
+
*/
|
|
108
|
+
static generateFacetId(filePath, sectionSlug) {
|
|
109
|
+
const prefix = FacetParser.getFilePrefix(filePath);
|
|
110
|
+
return `${prefix}:${sectionSlug}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.FacetParser = FacetParser;
|
|
114
|
+
//# sourceMappingURL=FacetParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacetParser.js","sourceRoot":"","sources":["../../src/core/FacetParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FacetStructure, Facet, FacetConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads and parses facet structure files
|
|
4
|
+
*/
|
|
5
|
+
export declare class StructureReader {
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config?: Partial<FacetConfig>);
|
|
8
|
+
/**
|
|
9
|
+
* Find all structure files matching the configured patterns
|
|
10
|
+
*/
|
|
11
|
+
findStructureFiles(cwd?: string): Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Read and parse a single structure file
|
|
14
|
+
*/
|
|
15
|
+
readStructure(filePath: string): FacetStructure;
|
|
16
|
+
/**
|
|
17
|
+
* Read all structure files and return combined facets
|
|
18
|
+
*/
|
|
19
|
+
readAllStructures(cwd?: string): Promise<Map<string, FacetStructure>>;
|
|
20
|
+
/**
|
|
21
|
+
* Get all facets from all structure files
|
|
22
|
+
*/
|
|
23
|
+
getAllFacets(cwd?: string): Promise<Facet[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get facet by ID
|
|
26
|
+
*/
|
|
27
|
+
getFacetById(id: string, cwd?: string): Promise<Facet | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the absolute path to a facet's source file
|
|
30
|
+
*/
|
|
31
|
+
resolveSourcePath(facet: Facet, structureFilePath: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Validate structure object
|
|
34
|
+
*/
|
|
35
|
+
private validateStructure;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=StructureReader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StructureReader.d.ts","sourceRoot":"","sources":["../../src/core/StructureReader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAiB,MAAM,aAAa,CAAC;AAErF;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM;IAK7C;;OAEG;IACG,kBAAkB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWxE;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IA8B/C;;OAEG;IACG,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAY1F;;OAEG;IACG,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAWjE;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAKvF;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM;IAOlE;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAkC1B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StructureReader = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const glob_1 = require("glob");
|
|
7
|
+
/**
|
|
8
|
+
* Reads and parses facet structure files
|
|
9
|
+
*/
|
|
10
|
+
class StructureReader {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config = {}) {
|
|
13
|
+
const { defaultConfig } = require('../types.js');
|
|
14
|
+
this.config = { ...defaultConfig, ...config };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find all structure files matching the configured patterns
|
|
18
|
+
*/
|
|
19
|
+
async findStructureFiles(cwd = process.cwd()) {
|
|
20
|
+
const files = [];
|
|
21
|
+
for (const pattern of this.config.structureFiles) {
|
|
22
|
+
const matches = await (0, glob_1.glob)(pattern, { cwd, absolute: true });
|
|
23
|
+
files.push(...matches);
|
|
24
|
+
}
|
|
25
|
+
return [...new Set(files)]; // Remove duplicates
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read and parse a single structure file
|
|
29
|
+
*/
|
|
30
|
+
readStructure(filePath) {
|
|
31
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
32
|
+
throw new Error(`Structure file not found: ${filePath}`);
|
|
33
|
+
}
|
|
34
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
35
|
+
let structure;
|
|
36
|
+
try {
|
|
37
|
+
structure = JSON.parse(content);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new Error(`Invalid JSON in structure file: ${filePath}`);
|
|
41
|
+
}
|
|
42
|
+
// Validate structure
|
|
43
|
+
this.validateStructure(structure, filePath);
|
|
44
|
+
// Resolve relative paths in facets
|
|
45
|
+
const structureDir = (0, path_1.dirname)(filePath);
|
|
46
|
+
structure.facets = structure.facets.map(facet => ({
|
|
47
|
+
...facet,
|
|
48
|
+
source: {
|
|
49
|
+
...facet.source,
|
|
50
|
+
file: facet.source.file, // Keep relative for portability
|
|
51
|
+
},
|
|
52
|
+
}));
|
|
53
|
+
return structure;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Read all structure files and return combined facets
|
|
57
|
+
*/
|
|
58
|
+
async readAllStructures(cwd = process.cwd()) {
|
|
59
|
+
const files = await this.findStructureFiles(cwd);
|
|
60
|
+
const structures = new Map();
|
|
61
|
+
for (const file of files) {
|
|
62
|
+
const structure = this.readStructure(file);
|
|
63
|
+
structures.set(file, structure);
|
|
64
|
+
}
|
|
65
|
+
return structures;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get all facets from all structure files
|
|
69
|
+
*/
|
|
70
|
+
async getAllFacets(cwd = process.cwd()) {
|
|
71
|
+
const structures = await this.readAllStructures(cwd);
|
|
72
|
+
const facets = [];
|
|
73
|
+
for (const structure of structures.values()) {
|
|
74
|
+
facets.push(...structure.facets);
|
|
75
|
+
}
|
|
76
|
+
return facets;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get facet by ID
|
|
80
|
+
*/
|
|
81
|
+
async getFacetById(id, cwd = process.cwd()) {
|
|
82
|
+
const facets = await this.getAllFacets(cwd);
|
|
83
|
+
return facets.find(f => f.id === id);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve the absolute path to a facet's source file
|
|
87
|
+
*/
|
|
88
|
+
resolveSourcePath(facet, structureFilePath) {
|
|
89
|
+
const structureDir = (0, path_1.dirname)(structureFilePath);
|
|
90
|
+
// Go up one level from .facet directory to get feature directory
|
|
91
|
+
const featureDir = (0, path_1.dirname)(structureDir);
|
|
92
|
+
return (0, path_1.resolve)(featureDir, facet.source.file);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate structure object
|
|
96
|
+
*/
|
|
97
|
+
validateStructure(structure, filePath) {
|
|
98
|
+
if (!structure.feature) {
|
|
99
|
+
throw new Error(`Missing 'feature' field in structure file: ${filePath}`);
|
|
100
|
+
}
|
|
101
|
+
if (!Array.isArray(structure.facets)) {
|
|
102
|
+
throw new Error(`Missing or invalid 'facets' array in structure file: ${filePath}`);
|
|
103
|
+
}
|
|
104
|
+
const seenIds = new Set();
|
|
105
|
+
for (const facet of structure.facets) {
|
|
106
|
+
if (!facet.id) {
|
|
107
|
+
throw new Error(`Facet missing 'id' field in structure file: ${filePath}`);
|
|
108
|
+
}
|
|
109
|
+
if (seenIds.has(facet.id)) {
|
|
110
|
+
throw new Error(`Duplicate facet ID '${facet.id}' in structure file: ${filePath}`);
|
|
111
|
+
}
|
|
112
|
+
seenIds.add(facet.id);
|
|
113
|
+
if (!facet.source?.file) {
|
|
114
|
+
throw new Error(`Facet '${facet.id}' missing 'source.file' in structure file: ${filePath}`);
|
|
115
|
+
}
|
|
116
|
+
if (!facet.source?.section) {
|
|
117
|
+
throw new Error(`Facet '${facet.id}' missing 'source.section' in structure file: ${filePath}`);
|
|
118
|
+
}
|
|
119
|
+
if (!facet.type) {
|
|
120
|
+
throw new Error(`Facet '${facet.id}' missing 'type' in structure file: ${filePath}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.StructureReader = StructureReader;
|
|
126
|
+
//# sourceMappingURL=StructureReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StructureReader.js","sourceRoot":"","sources":["../../src/core/StructureReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TestLink, FacetConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scans test files for facet annotations
|
|
4
|
+
*/
|
|
5
|
+
export declare class TestScanner {
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config?: Partial<FacetConfig>);
|
|
8
|
+
/**
|
|
9
|
+
* Find all test files matching configured patterns
|
|
10
|
+
*/
|
|
11
|
+
findTestFiles(cwd?: string): Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Scan a single test file for facet annotations
|
|
14
|
+
*/
|
|
15
|
+
scanFile(filePath: string, cwd?: string): TestLink[];
|
|
16
|
+
/**
|
|
17
|
+
* Scan test content for facet annotations
|
|
18
|
+
* Supports both Playwright-style annotations and comment-based annotations:
|
|
19
|
+
* - Playwright: test('name', { annotation: facet('id1', 'id2') }, ...)
|
|
20
|
+
* - Comment: // @facet id1, id2 \n test('name', ...)
|
|
21
|
+
*/
|
|
22
|
+
scanContent(content: string, filePath: string, cwd?: string): TestLink[];
|
|
23
|
+
/**
|
|
24
|
+
* Scan all test files for facet annotations
|
|
25
|
+
*/
|
|
26
|
+
scanAllTests(cwd?: string): Promise<TestLink[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Get all facet IDs referenced in tests
|
|
29
|
+
*/
|
|
30
|
+
getAllReferencedFacetIds(cwd?: string): Promise<Set<string>>;
|
|
31
|
+
/**
|
|
32
|
+
* Get tests that cover a specific facet ID
|
|
33
|
+
*/
|
|
34
|
+
getTestsForFacet(facetId: string, cwd?: string): Promise<TestLink[]>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=TestScanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestScanner.d.ts","sourceRoot":"","sources":["../../src/core/TestScanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM;IAI7C;;OAEG;IACG,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBnE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,QAAQ,EAAE;IASnE;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,QAAQ,EAAE;IAwHvF;;OAEG;IACG,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAgBpE;;OAEG;IACG,wBAAwB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAajF;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAI1F"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestScanner = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const glob_1 = require("glob");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const types_js_1 = require("../types.js");
|
|
8
|
+
/**
|
|
9
|
+
* Scans test files for facet annotations
|
|
10
|
+
*/
|
|
11
|
+
class TestScanner {
|
|
12
|
+
config;
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.config = { ...types_js_1.defaultConfig, ...config };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find all test files matching configured patterns
|
|
18
|
+
*/
|
|
19
|
+
async findTestFiles(cwd = process.cwd()) {
|
|
20
|
+
const patterns = this.config.testPatterns || ['**/*.spec.ts', '**/*.test.ts'];
|
|
21
|
+
const files = [];
|
|
22
|
+
// Expand testDir pattern
|
|
23
|
+
const testDirs = await (0, glob_1.glob)(this.config.testDir, { cwd, absolute: true });
|
|
24
|
+
for (const testDir of testDirs) {
|
|
25
|
+
for (const pattern of patterns) {
|
|
26
|
+
const matches = await (0, glob_1.glob)(pattern, { cwd: testDir, absolute: true });
|
|
27
|
+
files.push(...matches);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Also search in the testDir pattern directly if it includes globs
|
|
31
|
+
for (const pattern of patterns) {
|
|
32
|
+
const fullPattern = `${this.config.testDir}/${pattern}`;
|
|
33
|
+
const matches = await (0, glob_1.glob)(fullPattern, { cwd, absolute: true });
|
|
34
|
+
files.push(...matches);
|
|
35
|
+
}
|
|
36
|
+
return [...new Set(files)]; // Remove duplicates
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scan a single test file for facet annotations
|
|
40
|
+
*/
|
|
41
|
+
scanFile(filePath, cwd = process.cwd()) {
|
|
42
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
43
|
+
throw new Error(`Test file not found: ${filePath}`);
|
|
44
|
+
}
|
|
45
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
46
|
+
return this.scanContent(content, filePath, cwd);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scan test content for facet annotations
|
|
50
|
+
* Supports both Playwright-style annotations and comment-based annotations:
|
|
51
|
+
* - Playwright: test('name', { annotation: facet('id1', 'id2') }, ...)
|
|
52
|
+
* - Comment: // @facet id1, id2 \n test('name', ...)
|
|
53
|
+
*/
|
|
54
|
+
scanContent(content, filePath, cwd = process.cwd()) {
|
|
55
|
+
const testLinks = [];
|
|
56
|
+
const lines = content.split('\n');
|
|
57
|
+
// Track describe blocks for full title
|
|
58
|
+
const describeStack = [];
|
|
59
|
+
// Patterns for test definitions
|
|
60
|
+
const testPattern = /(?:test|it)\s*\(\s*(['"`])(.+?)\1\s*,\s*\{/g;
|
|
61
|
+
const testSimplePattern = /(?:test|it)\s*\(\s*(['"`])(.+?)\1\s*,/g;
|
|
62
|
+
const describePattern = /describe\s*\(\s*(['"`])(.+?)\1/g;
|
|
63
|
+
// Pattern for Playwright-style facet annotations
|
|
64
|
+
const facetPattern = /annotation\s*:\s*facet\s*\(\s*([^)]+)\s*\)/g;
|
|
65
|
+
const facetIdsPattern = /(['"`])([^'"`]+)\1/g;
|
|
66
|
+
// Pattern for comment-based facet annotations: // @facet id1, id2
|
|
67
|
+
const commentFacetPattern = /^\s*\/\/\s*@facet\s+(.+)$/;
|
|
68
|
+
// Track brace depth for describe blocks
|
|
69
|
+
let braceDepth = 0;
|
|
70
|
+
const describeDepths = [];
|
|
71
|
+
// Track pending comment-based facet IDs
|
|
72
|
+
let pendingFacetIds = [];
|
|
73
|
+
let pendingFacetLine = -1;
|
|
74
|
+
for (let i = 0; i < lines.length; i++) {
|
|
75
|
+
const line = lines[i];
|
|
76
|
+
const lineNumber = i + 1;
|
|
77
|
+
// Check for comment-based facet annotation
|
|
78
|
+
const commentMatch = commentFacetPattern.exec(line);
|
|
79
|
+
if (commentMatch) {
|
|
80
|
+
const facetString = commentMatch[1];
|
|
81
|
+
// Parse comma-separated facet IDs, trimming whitespace
|
|
82
|
+
pendingFacetIds = facetString.split(',').map(id => id.trim()).filter(id => id.length > 0);
|
|
83
|
+
pendingFacetLine = lineNumber;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// Track describe blocks
|
|
87
|
+
const describeMatch = describePattern.exec(line);
|
|
88
|
+
if (describeMatch) {
|
|
89
|
+
describeStack.push(describeMatch[2]);
|
|
90
|
+
describeDepths.push(braceDepth);
|
|
91
|
+
describePattern.lastIndex = 0;
|
|
92
|
+
}
|
|
93
|
+
// Count braces for scope tracking
|
|
94
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
95
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
96
|
+
braceDepth += openBraces - closeBraces;
|
|
97
|
+
// Pop describe blocks when we exit their scope
|
|
98
|
+
while (describeDepths.length > 0 && braceDepth <= describeDepths[describeDepths.length - 1]) {
|
|
99
|
+
describeStack.pop();
|
|
100
|
+
describeDepths.pop();
|
|
101
|
+
}
|
|
102
|
+
// Look for test definitions
|
|
103
|
+
// First try with annotation block pattern
|
|
104
|
+
let testMatch = testPattern.exec(line);
|
|
105
|
+
testPattern.lastIndex = 0;
|
|
106
|
+
// Also try simple test pattern for comment-based annotations
|
|
107
|
+
if (!testMatch) {
|
|
108
|
+
testMatch = testSimplePattern.exec(line);
|
|
109
|
+
testSimplePattern.lastIndex = 0;
|
|
110
|
+
}
|
|
111
|
+
if (testMatch) {
|
|
112
|
+
const testTitle = testMatch[2];
|
|
113
|
+
let facetIds = [];
|
|
114
|
+
// Check for pending comment-based facet IDs (within 3 lines)
|
|
115
|
+
if (pendingFacetIds.length > 0 && lineNumber - pendingFacetLine <= 3) {
|
|
116
|
+
facetIds = [...pendingFacetIds];
|
|
117
|
+
pendingFacetIds = [];
|
|
118
|
+
pendingFacetLine = -1;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Look for Playwright-style facet annotation in the next few lines
|
|
122
|
+
const annotationBlock = lines.slice(i, Math.min(i + 10, lines.length)).join('\n');
|
|
123
|
+
const facetMatch = facetPattern.exec(annotationBlock);
|
|
124
|
+
facetPattern.lastIndex = 0;
|
|
125
|
+
if (facetMatch) {
|
|
126
|
+
const facetArgs = facetMatch[1];
|
|
127
|
+
let idMatch;
|
|
128
|
+
while ((idMatch = facetIdsPattern.exec(facetArgs)) !== null) {
|
|
129
|
+
facetIds.push(idMatch[2]);
|
|
130
|
+
}
|
|
131
|
+
facetIdsPattern.lastIndex = 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (facetIds.length > 0) {
|
|
135
|
+
const fullTitle = [...describeStack, testTitle].join(' > ');
|
|
136
|
+
testLinks.push({
|
|
137
|
+
file: (0, path_1.relative)(cwd, filePath),
|
|
138
|
+
title: testTitle,
|
|
139
|
+
fullTitle,
|
|
140
|
+
facetIds,
|
|
141
|
+
line: lineNumber,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Clear pending facet IDs if we've moved too far past them
|
|
146
|
+
if (pendingFacetIds.length > 0 && lineNumber - pendingFacetLine > 3) {
|
|
147
|
+
pendingFacetIds = [];
|
|
148
|
+
pendingFacetLine = -1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return testLinks;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Scan all test files for facet annotations
|
|
155
|
+
*/
|
|
156
|
+
async scanAllTests(cwd = process.cwd()) {
|
|
157
|
+
const files = await this.findTestFiles(cwd);
|
|
158
|
+
const allLinks = [];
|
|
159
|
+
for (const file of files) {
|
|
160
|
+
try {
|
|
161
|
+
const links = this.scanFile(file, cwd);
|
|
162
|
+
allLinks.push(...links);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.warn(`Warning: Could not scan test file ${file}: ${error}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return allLinks;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get all facet IDs referenced in tests
|
|
172
|
+
*/
|
|
173
|
+
async getAllReferencedFacetIds(cwd = process.cwd()) {
|
|
174
|
+
const links = await this.scanAllTests(cwd);
|
|
175
|
+
const ids = new Set();
|
|
176
|
+
for (const link of links) {
|
|
177
|
+
for (const id of link.facetIds) {
|
|
178
|
+
ids.add(id);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return ids;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get tests that cover a specific facet ID
|
|
185
|
+
*/
|
|
186
|
+
async getTestsForFacet(facetId, cwd = process.cwd()) {
|
|
187
|
+
const links = await this.scanAllTests(cwd);
|
|
188
|
+
return links.filter(link => link.facetIds.includes(facetId));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.TestScanner = TestScanner;
|
|
192
|
+
//# sourceMappingURL=TestScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestScanner.js","sourceRoot":"","sources":["../../src/core/TestScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FacetConfig, FacetStructure, ValidationResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates facet structures, source files, and test links
|
|
4
|
+
*/
|
|
5
|
+
export declare class Validator {
|
|
6
|
+
private config;
|
|
7
|
+
private structureReader;
|
|
8
|
+
private facetParser;
|
|
9
|
+
private testScanner;
|
|
10
|
+
constructor(config?: Partial<FacetConfig>);
|
|
11
|
+
/**
|
|
12
|
+
* Run full validation
|
|
13
|
+
*/
|
|
14
|
+
validate(cwd?: string): Promise<ValidationResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Validate a single structure
|
|
17
|
+
*/
|
|
18
|
+
validateStructure(structure: FacetStructure, structureFile: string, cwd: string): ValidationResult;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a facet ID is valid
|
|
21
|
+
*/
|
|
22
|
+
private isValidFacetId;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a reference is a valid path-style reference
|
|
25
|
+
* e.g., 'facets/business.md#guest-purchase-flow'
|
|
26
|
+
*/
|
|
27
|
+
private isValidPathReference;
|
|
28
|
+
/**
|
|
29
|
+
* Quick validation check - returns boolean
|
|
30
|
+
*/
|
|
31
|
+
isValid(cwd?: string): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../src/core/Validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EAGd,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAMrB;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAc;gBAErB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM;IAO7C;;OAEG;IACG,QAAQ,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+EtE;;OAEG;IACH,iBAAiB,CACf,SAAS,EAAE,cAAc,EACzB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,GACV,gBAAgB;IAuDnB;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA2B5B;;OAEG;IACG,OAAO,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;CAI7D"}
|