faf-taf-git 2.4.0 → 2.4.2
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/CHANGELOG.md +23 -1
- package/README.md +1 -1
- package/RECEIPT-FORMAT.md +1 -1
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -1
- package/dist/cli.js.map +1 -1
- package/package.json +15 -2
- package/project.faf +32 -242
- package/.faf-dna +0 -95
- package/.fafignore +0 -41
- package/.github/dependabot.yml +0 -10
- package/.github/workflows/ci.yml +0 -53
- package/.github/workflows/claude-code-review.yml +0 -36
- package/.github/workflows/claude.yml +0 -39
- package/.github/workflows/homebrew.yml +0 -19
- package/.taf +0 -98
- package/CLAUDE.md +0 -38
- package/CODE_OF_CONDUCT.md +0 -21
- package/CONTRIBUTING.md +0 -289
- package/SECURITY.md +0 -19
- package/action.yml +0 -50
- package/agent.fafa +0 -53
- package/badge.svg +0 -21
- package/dist/bundle/index.js +0 -36554
- package/dist/index.js +0 -42827
- package/dist/index.js.map +0 -1
- package/dist/licenses.txt +0 -126
- package/dist/sourcemap-register.js +0 -1
- package/docs/RELEASE-NOTES.md +0 -200
- package/docs/USER-GUIDE.md +0 -301
- package/jest.config.js +0 -13
- package/src/badge.ts +0 -138
- package/src/cli.ts +0 -297
- package/src/index.ts +0 -201
- package/src/parsers/bun.ts +0 -103
- package/src/parsers/index.ts +0 -50
- package/src/parsers/jest.ts +0 -104
- package/src/parsers/junit.ts +0 -110
- package/src/parsers/vitest.ts +0 -65
- package/src/parsers/wjttc.ts +0 -160
- package/src/taf-core.ts +0 -139
- package/test-mcp.ts +0 -83
- package/test-standalone.ts +0 -87
- package/tests/action-bundle.test.ts +0 -34
- package/tests/action-parse-error.test.ts +0 -47
- package/tests/badge.test.ts +0 -260
- package/tests/bun-parser.test.ts +0 -173
- package/tests/jest-parser.test.ts +0 -122
- package/tests/junit-parser.test.ts +0 -109
- package/tests/vitest-parser.test.ts +0 -112
- package/tests/wjttc-parser.test.ts +0 -116
- package/tests/wjttc-taf.test.ts +0 -470
- package/tsconfig.json +0 -18
package/tests/wjttc-taf.test.ts
DELETED
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🏎️ WJTTC Test Suite: faf-taf-git
|
|
3
|
-
*
|
|
4
|
-
* CAR = Claim, Audit, Receipt
|
|
5
|
-
* This tests the RECEIPT (R) - the .taf file generator
|
|
6
|
-
*
|
|
7
|
-
* TIER 0: Platform Compatibility - Runs on all tracks
|
|
8
|
-
* TIER 1: BRAKE - Receipt Accuracy (critical safety)
|
|
9
|
-
* TIER 2: ENGINE - Receipt Completeness (core function)
|
|
10
|
-
* TIER 3: AERO - Receipt Reliability (edge cases)
|
|
11
|
-
*
|
|
12
|
-
* "No CAR = No transport. The receipt must be bulletproof."
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import * as fs from 'fs';
|
|
16
|
-
import * as path from 'path';
|
|
17
|
-
import * as os from 'os';
|
|
18
|
-
import { execSync } from 'child_process';
|
|
19
|
-
|
|
20
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
21
|
-
// HELPERS
|
|
22
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
23
|
-
|
|
24
|
-
const ROOT_DIR = path.resolve(__dirname, '..');
|
|
25
|
-
const CLI_PATH = path.join(ROOT_DIR, 'dist', 'cli.js');
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Cross-platform temp directory creation
|
|
29
|
-
*/
|
|
30
|
-
function createTempDir(prefix: string): string {
|
|
31
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Cross-platform file finder
|
|
36
|
-
*/
|
|
37
|
-
function findFiles(dir: string, pattern: RegExp, excludeDirs: string[] = []): string[] {
|
|
38
|
-
const results: string[] = [];
|
|
39
|
-
|
|
40
|
-
function walk(currentDir: string) {
|
|
41
|
-
try {
|
|
42
|
-
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
43
|
-
for (const entry of entries) {
|
|
44
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
45
|
-
if (entry.isDirectory()) {
|
|
46
|
-
if (!excludeDirs.includes(entry.name)) {
|
|
47
|
-
walk(fullPath);
|
|
48
|
-
}
|
|
49
|
-
} else if (entry.isFile() && pattern.test(entry.name)) {
|
|
50
|
-
results.push(fullPath);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} catch (e) {
|
|
54
|
-
// Directory may not exist
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
walk(dir);
|
|
59
|
-
return results;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
-
// TIER 0: PLATFORM COMPATIBILITY - Runs on all tracks
|
|
64
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
65
|
-
|
|
66
|
-
describe('🏁 TIER 0: Platform Compatibility', () => {
|
|
67
|
-
const srcDir = path.join(ROOT_DIR, 'src');
|
|
68
|
-
const testsDir = path.join(ROOT_DIR, 'tests');
|
|
69
|
-
|
|
70
|
-
describe('🚫 No Hardcoded Unix Paths', () => {
|
|
71
|
-
test('source files should not use hardcoded /tmp paths', () => {
|
|
72
|
-
const violations: string[] = [];
|
|
73
|
-
const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
|
|
74
|
-
|
|
75
|
-
for (const file of srcFiles) {
|
|
76
|
-
const content = fs.readFileSync(file, 'utf8');
|
|
77
|
-
const lines = content.split('\n');
|
|
78
|
-
|
|
79
|
-
lines.forEach((line, idx) => {
|
|
80
|
-
if (line.trim().startsWith('//') || line.trim().startsWith('*')) return;
|
|
81
|
-
if (/FIX:|VIOLATION/.test(line)) return;
|
|
82
|
-
|
|
83
|
-
if (/['"`]\/tmp\//.test(line)) {
|
|
84
|
-
violations.push(`${path.basename(file)}:${idx + 1}: Hardcoded /tmp`);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
expect(violations).toHaveLength(0);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('source files should not use hardcoded /bin paths', () => {
|
|
93
|
-
const violations: string[] = [];
|
|
94
|
-
const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
|
|
95
|
-
|
|
96
|
-
for (const file of srcFiles) {
|
|
97
|
-
const content = fs.readFileSync(file, 'utf8');
|
|
98
|
-
const lines = content.split('\n');
|
|
99
|
-
|
|
100
|
-
lines.forEach((line, idx) => {
|
|
101
|
-
if (line.trim().startsWith('//') || line.trim().startsWith('*')) return;
|
|
102
|
-
|
|
103
|
-
if (/['"`]\/bin\/(bash|sh)/.test(line)) {
|
|
104
|
-
violations.push(`${path.basename(file)}:${idx + 1}: Hardcoded shell`);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
expect(violations).toHaveLength(0);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('🚫 No Unix-Only Commands', () => {
|
|
114
|
-
test('should not use Unix find command in source', () => {
|
|
115
|
-
const violations: string[] = [];
|
|
116
|
-
const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
|
|
117
|
-
|
|
118
|
-
for (const file of srcFiles) {
|
|
119
|
-
const content = fs.readFileSync(file, 'utf8');
|
|
120
|
-
|
|
121
|
-
if (/exec(Sync)?\s*\(\s*['"`]find\s/.test(content)) {
|
|
122
|
-
violations.push(path.basename(file));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
expect(violations).toHaveLength(0);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe('📊 Platform Summary', () => {
|
|
131
|
-
test('should display platform info', () => {
|
|
132
|
-
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
133
|
-
console.log('🏁 TIER 0: PLATFORM COMPATIBILITY - PASSED');
|
|
134
|
-
console.log(`Platform: ${process.platform} | Node: ${process.version}`);
|
|
135
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
136
|
-
expect(true).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
142
|
-
// TIER 1: BRAKE - Receipt Accuracy (Critical Safety)
|
|
143
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
144
|
-
|
|
145
|
-
describe('🛑 TIER 1: BRAKE - Receipt Accuracy', () => {
|
|
146
|
-
let tempDir: string;
|
|
147
|
-
|
|
148
|
-
beforeEach(() => {
|
|
149
|
-
tempDir = createTempDir('wjttc-taf-brake-');
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
afterEach(() => {
|
|
153
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
describe('📝 .taf File Creation', () => {
|
|
157
|
-
test('should create valid .taf file structure', () => {
|
|
158
|
-
const tafPath = path.join(tempDir, '.taf');
|
|
159
|
-
|
|
160
|
-
// Minimal .taf structure
|
|
161
|
-
const tafContent = `# .taf - Testing Activity Feed
|
|
162
|
-
format_version: "1.0.0"
|
|
163
|
-
project: "test-project"
|
|
164
|
-
created: "${new Date().toISOString()}"
|
|
165
|
-
last_updated: "${new Date().toISOString()}"
|
|
166
|
-
test_history: []
|
|
167
|
-
`;
|
|
168
|
-
|
|
169
|
-
fs.writeFileSync(tafPath, tafContent);
|
|
170
|
-
|
|
171
|
-
expect(fs.existsSync(tafPath)).toBe(true);
|
|
172
|
-
|
|
173
|
-
const content = fs.readFileSync(tafPath, 'utf8');
|
|
174
|
-
expect(content).toContain('format_version');
|
|
175
|
-
expect(content).toContain('project');
|
|
176
|
-
expect(content).toContain('test_history');
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test('.taf should be valid YAML', () => {
|
|
180
|
-
const yaml = require('yaml');
|
|
181
|
-
const tafPath = path.join(tempDir, '.taf');
|
|
182
|
-
|
|
183
|
-
const tafContent = `format_version: "1.0.0"
|
|
184
|
-
project: "test-project"
|
|
185
|
-
created: "2026-01-28T00:00:00Z"
|
|
186
|
-
last_updated: "2026-01-28T00:00:00Z"
|
|
187
|
-
test_history:
|
|
188
|
-
- timestamp: "2026-01-28T00:00:00Z"
|
|
189
|
-
result: PASSED
|
|
190
|
-
tests:
|
|
191
|
-
total: 10
|
|
192
|
-
passed: 10
|
|
193
|
-
failed: 0
|
|
194
|
-
`;
|
|
195
|
-
|
|
196
|
-
fs.writeFileSync(tafPath, tafContent);
|
|
197
|
-
|
|
198
|
-
const parsed = yaml.parse(fs.readFileSync(tafPath, 'utf8'));
|
|
199
|
-
|
|
200
|
-
expect(parsed.format_version).toBe('1.0.0');
|
|
201
|
-
expect(parsed.project).toBe('test-project');
|
|
202
|
-
expect(parsed.test_history).toHaveLength(1);
|
|
203
|
-
expect(parsed.test_history[0].result).toBe('PASSED');
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
describe('🎯 Result Accuracy', () => {
|
|
208
|
-
test('PASSED means all tests passed', () => {
|
|
209
|
-
const result = { total: 10, passed: 10, failed: 0, skipped: 0 };
|
|
210
|
-
const status = result.failed === 0 ? 'PASSED' : 'FAILED';
|
|
211
|
-
|
|
212
|
-
expect(status).toBe('PASSED');
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
test('FAILED means at least one test failed', () => {
|
|
216
|
-
const result = { total: 10, passed: 9, failed: 1, skipped: 0 };
|
|
217
|
-
const status = result.failed === 0 ? 'PASSED' : 'FAILED';
|
|
218
|
-
|
|
219
|
-
expect(status).toBe('FAILED');
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
test('counts must be accurate', () => {
|
|
223
|
-
const result = { total: 100, passed: 95, failed: 3, skipped: 2 };
|
|
224
|
-
|
|
225
|
-
expect(result.passed + result.failed + result.skipped).toBe(result.total);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
describe('🔗 .faf Integration', () => {
|
|
230
|
-
test('should detect .faf file when present', () => {
|
|
231
|
-
const fafPath = path.join(tempDir, '.faf');
|
|
232
|
-
fs.writeFileSync(fafPath, 'faf_version: 2.5.0\nproject:\n name: test');
|
|
233
|
-
|
|
234
|
-
const hasFaf = fs.existsSync(fafPath);
|
|
235
|
-
expect(hasFaf).toBe(true);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test('should work without .faf file', () => {
|
|
239
|
-
const fafPath = path.join(tempDir, '.faf');
|
|
240
|
-
const hasFaf = fs.existsSync(fafPath);
|
|
241
|
-
|
|
242
|
-
expect(hasFaf).toBe(false);
|
|
243
|
-
// Should not throw - .faf is optional
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
249
|
-
// TIER 2: ENGINE - Receipt Completeness (Core Function)
|
|
250
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
251
|
-
|
|
252
|
-
describe('🔧 TIER 2: ENGINE - Receipt Completeness', () => {
|
|
253
|
-
describe('📋 Jest Parser', () => {
|
|
254
|
-
// Import the parser
|
|
255
|
-
const { parseJestOutput } = require('../dist/parsers/jest');
|
|
256
|
-
|
|
257
|
-
test('should parse standard Jest output', () => {
|
|
258
|
-
const output = 'Tests: 10 passed, 10 total';
|
|
259
|
-
const result = parseJestOutput(output);
|
|
260
|
-
|
|
261
|
-
expect(result).not.toBeNull();
|
|
262
|
-
expect(result.passed).toBe(10);
|
|
263
|
-
expect(result.total).toBe(10);
|
|
264
|
-
expect(result.failed).toBe(0);
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
test('should parse Jest output with failures', () => {
|
|
268
|
-
const output = 'Tests: 2 failed, 8 passed, 10 total';
|
|
269
|
-
const result = parseJestOutput(output);
|
|
270
|
-
|
|
271
|
-
expect(result).not.toBeNull();
|
|
272
|
-
expect(result.passed).toBe(8);
|
|
273
|
-
expect(result.failed).toBe(2);
|
|
274
|
-
expect(result.total).toBe(10);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
test('should parse Jest output with skipped', () => {
|
|
278
|
-
const output = 'Tests: 1 skipped, 9 passed, 10 total';
|
|
279
|
-
const result = parseJestOutput(output);
|
|
280
|
-
|
|
281
|
-
expect(result).not.toBeNull();
|
|
282
|
-
expect(result.skipped).toBe(1);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
test('should handle malformed output gracefully', () => {
|
|
286
|
-
const output = 'This is not Jest output';
|
|
287
|
-
const result = parseJestOutput(output);
|
|
288
|
-
|
|
289
|
-
expect(result).toBeNull();
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
describe('📁 TAF Core Operations', () => {
|
|
294
|
-
const { updateTafFile } = require('../dist/taf-core');
|
|
295
|
-
let tempDir: string;
|
|
296
|
-
|
|
297
|
-
beforeEach(() => {
|
|
298
|
-
tempDir = createTempDir('wjttc-taf-engine-');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
afterEach(() => {
|
|
302
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
test('should create .taf if not exists', () => {
|
|
306
|
-
const tafPath = path.join(tempDir, '.taf');
|
|
307
|
-
const testResults = { total: 5, passed: 5, failed: 0, skipped: 0 };
|
|
308
|
-
|
|
309
|
-
updateTafFile(tafPath, testResults);
|
|
310
|
-
|
|
311
|
-
expect(fs.existsSync(tafPath)).toBe(true);
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
test('should append to existing .taf', () => {
|
|
315
|
-
const tafPath = path.join(tempDir, '.taf');
|
|
316
|
-
const testResults = { total: 5, passed: 5, failed: 0, skipped: 0 };
|
|
317
|
-
|
|
318
|
-
// First update
|
|
319
|
-
updateTafFile(tafPath, testResults);
|
|
320
|
-
const content1 = fs.readFileSync(tafPath, 'utf8');
|
|
321
|
-
|
|
322
|
-
// Second update
|
|
323
|
-
updateTafFile(tafPath, testResults);
|
|
324
|
-
const content2 = fs.readFileSync(tafPath, 'utf8');
|
|
325
|
-
|
|
326
|
-
// Should have grown (more entries)
|
|
327
|
-
expect(content2.length).toBeGreaterThan(content1.length);
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
333
|
-
// TIER 3: AERO - Receipt Reliability (Edge Cases)
|
|
334
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
335
|
-
|
|
336
|
-
describe('⚡ TIER 3: AERO - Receipt Reliability', () => {
|
|
337
|
-
let tempDir: string;
|
|
338
|
-
|
|
339
|
-
beforeEach(() => {
|
|
340
|
-
tempDir = createTempDir('wjttc-taf-aero-');
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
afterEach(() => {
|
|
344
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
describe('📈 Scale Testing', () => {
|
|
348
|
-
test('should handle large test counts', () => {
|
|
349
|
-
const result = { total: 10000, passed: 9999, failed: 1, skipped: 0 };
|
|
350
|
-
|
|
351
|
-
expect(result.total).toBe(10000);
|
|
352
|
-
expect(result.passed + result.failed + result.skipped).toBe(result.total);
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
test('should handle zero tests gracefully', () => {
|
|
356
|
-
const result = { total: 0, passed: 0, failed: 0, skipped: 0 };
|
|
357
|
-
|
|
358
|
-
expect(result.total).toBe(0);
|
|
359
|
-
// Should not throw
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
describe('🛡️ Error Recovery', () => {
|
|
364
|
-
test('should handle corrupted .taf file', () => {
|
|
365
|
-
const tafPath = path.join(tempDir, '.taf');
|
|
366
|
-
fs.writeFileSync(tafPath, 'this is not valid yaml: {{{{');
|
|
367
|
-
|
|
368
|
-
// Should not crash when reading corrupted file
|
|
369
|
-
try {
|
|
370
|
-
const yaml = require('yaml');
|
|
371
|
-
yaml.parse(fs.readFileSync(tafPath, 'utf8'));
|
|
372
|
-
} catch (e) {
|
|
373
|
-
// Expected - corrupted YAML
|
|
374
|
-
expect(e).toBeDefined();
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
test('should handle missing permissions gracefully', () => {
|
|
379
|
-
// Skip on Windows (different permission model)
|
|
380
|
-
if (process.platform === 'win32') {
|
|
381
|
-
expect(true).toBe(true);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const readonlyDir = path.join(tempDir, 'readonly');
|
|
386
|
-
fs.mkdirSync(readonlyDir);
|
|
387
|
-
fs.chmodSync(readonlyDir, 0o444);
|
|
388
|
-
|
|
389
|
-
const tafPath = path.join(readonlyDir, '.taf');
|
|
390
|
-
|
|
391
|
-
try {
|
|
392
|
-
fs.writeFileSync(tafPath, 'test');
|
|
393
|
-
} catch (e: any) {
|
|
394
|
-
expect(e.code).toBe('EACCES');
|
|
395
|
-
} finally {
|
|
396
|
-
fs.chmodSync(readonlyDir, 0o755);
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
describe('🌍 Cross-Platform Line Endings', () => {
|
|
402
|
-
test('should handle Unix line endings (LF)', () => {
|
|
403
|
-
const content = "line1\nline2\nline3";
|
|
404
|
-
const lines = content.split(/\r?\n/);
|
|
405
|
-
|
|
406
|
-
expect(lines).toHaveLength(3);
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
test('should handle Windows line endings (CRLF)', () => {
|
|
410
|
-
const content = "line1\r\nline2\r\nline3";
|
|
411
|
-
const lines = content.split(/\r?\n/);
|
|
412
|
-
|
|
413
|
-
expect(lines).toHaveLength(3);
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
419
|
-
// CAR VALIDATION - The Full Receipt
|
|
420
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
421
|
-
|
|
422
|
-
describe('🏎️ CAR VALIDATION - Complete Receipt System', () => {
|
|
423
|
-
test('should display CAR summary', () => {
|
|
424
|
-
console.log('\n');
|
|
425
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
426
|
-
console.log('🏎️ CAR = Claim, Audit, Receipt');
|
|
427
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
428
|
-
console.log('C = .faf (Claim) - Project DNA');
|
|
429
|
-
console.log('A = WJTTC (Audit) - Score Verification');
|
|
430
|
-
console.log('R = .taf (Receipt) - Proof Over Time');
|
|
431
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
432
|
-
console.log('✅ faf-taf-git is the Receipt Printer');
|
|
433
|
-
console.log('✅ WJTTC Suite: PASSED');
|
|
434
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
435
|
-
|
|
436
|
-
expect(true).toBe(true);
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* WJTTC TIER SUMMARY
|
|
442
|
-
* ==================
|
|
443
|
-
*
|
|
444
|
-
* TIER 0: Platform Compatibility
|
|
445
|
-
* - No hardcoded /tmp paths
|
|
446
|
-
* - No Unix-only commands
|
|
447
|
-
* - Cross-platform ready
|
|
448
|
-
*
|
|
449
|
-
* TIER 1: BRAKE - Receipt Accuracy
|
|
450
|
-
* - .taf file creation
|
|
451
|
-
* - Valid YAML structure
|
|
452
|
-
* - Accurate test results
|
|
453
|
-
* - .faf integration
|
|
454
|
-
*
|
|
455
|
-
* TIER 2: ENGINE - Receipt Completeness
|
|
456
|
-
* - Jest parser accuracy
|
|
457
|
-
* - TAF core operations
|
|
458
|
-
* - Append-only history
|
|
459
|
-
*
|
|
460
|
-
* TIER 3: AERO - Receipt Reliability
|
|
461
|
-
* - Scale testing
|
|
462
|
-
* - Error recovery
|
|
463
|
-
* - Line ending handling
|
|
464
|
-
*
|
|
465
|
-
* CAR VALIDATION
|
|
466
|
-
* - Full system verification
|
|
467
|
-
* - Score is truth
|
|
468
|
-
*
|
|
469
|
-
* "No CAR = No transport"
|
|
470
|
-
*/
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"lib": ["ES2020"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"declaration": true,
|
|
13
|
-
"declarationMap": true,
|
|
14
|
-
"sourceMap": true
|
|
15
|
-
},
|
|
16
|
-
"include": ["src/**/*"],
|
|
17
|
-
"exclude": ["node_modules", "dist", "tests"]
|
|
18
|
-
}
|