@vibe2founder/tests2dialects 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.
Files changed (74) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/bun.lock +22 -0
  3. package/bunfig.toml +2 -0
  4. package/critica.md +77 -0
  5. package/docs/4-ideias.md +66 -0
  6. package/docs/api-api.md +93 -0
  7. package/docs/api-imperativo.md +125 -0
  8. package/docs/api-matematico.md +145 -0
  9. package/docs/api-narrativo.md +181 -0
  10. package/docs/guia-rapido.md +189 -0
  11. package/docs/whitepaper.md +21 -0
  12. package/examples/imperative.spec.ts +58 -0
  13. package/examples/math.spec.ts +52 -0
  14. package/examples/narrative.spec.ts +61 -0
  15. package/examples/polyglot-shopping-cart.spec.ts +212 -0
  16. package/examples/sanity.spec.ts +54 -0
  17. package/examples/showcase-api.spec.ts +70 -0
  18. package/examples/test-api.ts +36 -0
  19. package/infograficos/detalhado.png +0 -0
  20. package/infograficos/mobile.png +0 -0
  21. package/infograficos/normal.png +0 -0
  22. package/landing-page/README.md +38 -0
  23. package/landing-page/bun.lock +609 -0
  24. package/landing-page/eslint.config.js +23 -0
  25. package/landing-page/index.html +17 -0
  26. package/landing-page/package-lock.json +2962 -0
  27. package/landing-page/package.json +34 -0
  28. package/landing-page/postcss.config.js +6 -0
  29. package/landing-page/public/vite.svg +1 -0
  30. package/landing-page/src/App.tsx +358 -0
  31. package/landing-page/src/assets/react.svg +1 -0
  32. package/landing-page/src/index.css +34 -0
  33. package/landing-page/src/main.tsx +10 -0
  34. package/landing-page/tailwind.config.js +59 -0
  35. package/landing-page/tsconfig.app.json +28 -0
  36. package/landing-page/tsconfig.json +7 -0
  37. package/landing-page/tsconfig.node.json +26 -0
  38. package/landing-page/vite.config.ts +7 -0
  39. package/logo.png +0 -0
  40. package/output.log +60 -0
  41. package/package.json +36 -0
  42. package/packages/api-test-dialect/README.md +30 -0
  43. package/packages/api-test-dialect/index.ts +132 -0
  44. package/packages/api-test-dialect/openapi.json +64 -0
  45. package/packages/reqify/README.md +33 -0
  46. package/packages/reqify/index.ts +48 -0
  47. package/podcast/O_Matem/303/241tico,_o_Narrador_e_o_Engenheiro.json +0 -0
  48. package/podcast/O_Matem/303/241tico,_o_Narrador_e_o_Engenheiro.md +0 -0
  49. package/podcast/critica-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.json +0 -0
  50. package/podcast/critica-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.md +0 -0
  51. package/podcast/critica-Unificar_filosofia_e_pr/303/241tica_na_documenta/303/247/303/243o_(7_words__covers_t.md +1 -0
  52. package/podcast/critica-Unificar_filosofia_e_pr/303/241tica_na_documenta/303/247/303/243o__7_words__covers_t.ogg +0 -0
  53. package/podcast/critica2-Sil/303/252ncio_estrat/303/251gico_e_sobrecarga_em_READMEs.ogg +0 -0
  54. package/podcast/critica2.json +3191 -0
  55. package/podcast/critica2.md +1 -0
  56. package/podcast/debate-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.json +0 -0
  57. package/podcast/debate-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.md +0 -0
  58. package/readme.md +58 -0
  59. package/reports/01-01-2026_00-45.md +40 -0
  60. package/reports/01-01-2026_02-30.md +37 -0
  61. package/reports/03-02-2026_10-55.md +8 -0
  62. package/reports/03-02-2026_11-45.md +13 -0
  63. package/reports/03-02-2026_11-50.md +10 -0
  64. package/reports/26-01-2026_16-25.md +31 -0
  65. package/reports/26-01-2026_19-20.md +27 -0
  66. package/reports/31-12-2025_22-35.md +25 -0
  67. package/reports/31-12-2025_22-45.md +15 -0
  68. package/slides/Dialetos_de_Teste_Um_Executor_M/303/272ltiplos_Vocabul/303/241rios.pdf +0 -0
  69. package/src/cli.ts +445 -0
  70. package/src/index.ts +539 -0
  71. package/tabela.html +350 -0
  72. package/tsconfig.json +22 -0
  73. package/types/api-types.ts +11 -0
  74. package/www/index.html +1344 -0
package/src/cli.ts ADDED
@@ -0,0 +1,445 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * πŸ§ͺ tests2dialects Test Runner
4
+ * Visual estilo Vitest com cronΓ΄metro e cores
5
+ */
6
+
7
+ import { readdir, stat } from "fs/promises";
8
+ import { join, relative, basename, dirname } from "path";
9
+ import { resetAtomicCore } from "./index.js";
10
+
11
+ // =============================================================================
12
+ // 🎨 ANSI Colors (Vitest-style palette)
13
+ // =============================================================================
14
+
15
+ const c = {
16
+ // Reset
17
+ reset: "\x1b[0m",
18
+
19
+ // Text styles
20
+ bold: "\x1b[1m",
21
+ dim: "\x1b[2m",
22
+ italic: "\x1b[3m",
23
+ underline: "\x1b[4m",
24
+
25
+ // Colors
26
+ black: "\x1b[30m",
27
+ red: "\x1b[31m",
28
+ green: "\x1b[32m",
29
+ yellow: "\x1b[33m",
30
+ blue: "\x1b[34m",
31
+ magenta: "\x1b[35m",
32
+ cyan: "\x1b[36m",
33
+ white: "\x1b[37m",
34
+ gray: "\x1b[90m",
35
+
36
+ // Bright colors
37
+ brightRed: "\x1b[91m",
38
+ brightGreen: "\x1b[92m",
39
+ brightYellow: "\x1b[93m",
40
+ brightBlue: "\x1b[94m",
41
+ brightMagenta: "\x1b[95m",
42
+ brightCyan: "\x1b[96m",
43
+
44
+ // Background
45
+ bgGreen: "\x1b[42m",
46
+ bgRed: "\x1b[41m",
47
+ bgYellow: "\x1b[43m",
48
+ bgBlue: "\x1b[44m",
49
+ bgMagenta: "\x1b[45m",
50
+ bgCyan: "\x1b[46m",
51
+ };
52
+
53
+ // Vitest-style colors
54
+ const pass = (s: string) => `${c.bold}${c.green}${s}${c.reset}`;
55
+ const fail = (s: string) => `${c.bold}${c.red}${s}${c.reset}`;
56
+ const skip = (s: string) => `${c.yellow}${s}${c.reset}`;
57
+ const dim = (s: string) => `${c.dim}${s}${c.reset}`;
58
+ const bold = (s: string) => `${c.bold}${s}${c.reset}`;
59
+ const cyan = (s: string) => `${c.cyan}${s}${c.reset}`;
60
+ const magenta = (s: string) => `${c.magenta}${s}${c.reset}`;
61
+ const yellow = (s: string) => `${c.yellow}${s}${c.reset}`;
62
+ const gray = (s: string) => `${c.gray}${s}${c.reset}`;
63
+ const brightCyan = (s: string) => `${c.brightCyan}${s}${c.reset}`;
64
+
65
+ // =============================================================================
66
+ // ⏱️ Timer & Formatting
67
+ // =============================================================================
68
+
69
+ function formatDuration(ms: number): string {
70
+ if (ms < 1) return `${(ms * 1000).toFixed(0)}ΞΌs`;
71
+ if (ms < 1000) return `${ms.toFixed(0)}ms`;
72
+ if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;
73
+ const mins = Math.floor(ms / 60000);
74
+ const secs = ((ms % 60000) / 1000).toFixed(1);
75
+ return `${mins}m ${secs}s`;
76
+ }
77
+
78
+ function getSpinner(): string[] {
79
+ return ["β ‹", "β ™", "β Ή", "β Έ", "β Ό", "β ΄", "β ¦", "β §", "β ‡", "⠏"];
80
+ }
81
+
82
+ // =============================================================================
83
+ // πŸ“ File Scanner
84
+ // =============================================================================
85
+
86
+ async function findSpecFiles(
87
+ dir: string,
88
+ fileList: string[] = [],
89
+ ): Promise<string[]> {
90
+ const files = await readdir(dir);
91
+
92
+ for (const file of files) {
93
+ if (file === "node_modules" || file === "dist" || file === ".git") continue;
94
+
95
+ const path = join(dir, file);
96
+ try {
97
+ const s = await stat(path);
98
+ if (s.isDirectory()) {
99
+ await findSpecFiles(path, fileList);
100
+ } else if (file.endsWith(".spec.ts")) {
101
+ fileList.push(path);
102
+ }
103
+ } catch {
104
+ // Ignore access errors
105
+ }
106
+ }
107
+
108
+ return fileList;
109
+ }
110
+
111
+ // =============================================================================
112
+ // πŸ§ͺ Test Results Storage
113
+ // =============================================================================
114
+
115
+ interface TestResult {
116
+ file: string;
117
+ duration: number;
118
+ passed: number;
119
+ failed: number;
120
+ skipped: number;
121
+ tests: {
122
+ name: string;
123
+ status: "pass" | "fail" | "skip";
124
+ duration: number;
125
+ error?: string;
126
+ }[];
127
+ }
128
+
129
+ const results: TestResult[] = [];
130
+
131
+ // =============================================================================
132
+ // πŸ–₯️ Console Output Helpers
133
+ // =============================================================================
134
+
135
+ function clearLine() {
136
+ process.stdout.write("\r\x1b[K");
137
+ }
138
+
139
+ function moveCursorUp(lines: number) {
140
+ process.stdout.write(`\x1b[${lines}A`);
141
+ }
142
+
143
+ function printHeader() {
144
+ console.log();
145
+ console.log(
146
+ ` ${c.bold}${c.magenta} tests2dialects ${c.reset} ${dim("v0.2.0")}`,
147
+ );
148
+ console.log();
149
+ }
150
+
151
+ function printFileStart(file: string, index: number, total: number) {
152
+ const relativePath = relative(process.cwd(), file);
153
+ const dir = dirname(relativePath);
154
+ const name = basename(relativePath);
155
+
156
+ const progress = `${dim(`[${index + 1}/${total}]`)}`;
157
+ const dirPart = dir !== "." ? `${gray(dir + "/")}` : "";
158
+
159
+ return `${progress} ${dirPart}${cyan(name)}`;
160
+ }
161
+
162
+ function printRunningSpinner(
163
+ file: string,
164
+ startTime: number,
165
+ spinnerFrame: number,
166
+ ): string {
167
+ const spinner = getSpinner()[spinnerFrame % getSpinner().length];
168
+ const elapsed = Date.now() - startTime;
169
+ const timer = yellow(`${formatDuration(elapsed)}`);
170
+
171
+ return ` ${c.yellow}${spinner}${c.reset} ${file} ${timer}`;
172
+ }
173
+
174
+ function printFileResult(file: string, result: TestResult) {
175
+ const relativePath = relative(process.cwd(), file);
176
+ const dir = dirname(relativePath);
177
+ const name = basename(relativePath);
178
+
179
+ const dirPart = dir !== "." ? `${gray(dir + "/")}` : "";
180
+ const timer = gray(`(${formatDuration(result.duration)})`);
181
+
182
+ if (result.failed > 0) {
183
+ console.log(
184
+ ` ${fail("βœ–")} ${dirPart}${fail(name)} ${fail(
185
+ `${result.failed} failed`,
186
+ )} ${timer}`,
187
+ );
188
+ } else {
189
+ console.log(
190
+ ` ${pass("βœ“")} ${dirPart}${cyan(name)} ${pass(
191
+ `${result.passed} passed`,
192
+ )} ${timer}`,
193
+ );
194
+ }
195
+
196
+ // Print individual test results (indented)
197
+ for (const test of result.tests) {
198
+ const testTimer = gray(`${formatDuration(test.duration)}`);
199
+ if (test.status === "pass") {
200
+ console.log(` ${pass("βœ“")} ${dim(test.name)} ${testTimer}`);
201
+ } else if (test.status === "fail") {
202
+ console.log(` ${fail("βœ–")} ${fail(test.name)} ${testTimer}`);
203
+ if (test.error) {
204
+ console.log(` ${fail("β†’")} ${c.dim}${test.error}${c.reset}`);
205
+ }
206
+ } else {
207
+ console.log(` ${skip("β—‹")} ${skip(test.name)} ${dim("[skipped]")}`);
208
+ }
209
+ }
210
+ console.log();
211
+ }
212
+
213
+ function printSummary() {
214
+ const totalFiles = results.length;
215
+ const totalTests = results.reduce((sum, r) => sum + r.tests.length, 0);
216
+ const totalPassed = results.reduce((sum, r) => sum + r.passed, 0);
217
+ const totalFailed = results.reduce((sum, r) => sum + r.failed, 0);
218
+ const totalSkipped = results.reduce((sum, r) => sum + r.skipped, 0);
219
+ const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
220
+
221
+ console.log();
222
+ console.log(
223
+ ` ${bold("Test Files")} ${
224
+ totalFailed > 0
225
+ ? fail(`${results.filter((r) => r.failed > 0).length} failed`) + " | "
226
+ : ""
227
+ }${pass(`${results.filter((r) => r.failed === 0).length} passed`)} ${dim(
228
+ `(${totalFiles})`,
229
+ )}`,
230
+ );
231
+ console.log(
232
+ ` ${bold(" Tests")} ${
233
+ totalFailed > 0 ? fail(`${totalFailed} failed`) + " | " : ""
234
+ }${totalPassed > 0 ? pass(`${totalPassed} passed`) : ""}${
235
+ totalSkipped > 0 ? " | " + skip(`${totalSkipped} skipped`) : ""
236
+ } ${dim(`(${totalTests})`)}`,
237
+ );
238
+ console.log(` ${bold(" Duration")} ${formatDuration(totalDuration)}`);
239
+ console.log();
240
+
241
+ // Final status bar
242
+ if (totalFailed > 0) {
243
+ console.log(
244
+ ` ${c.bgRed}${c.bold}${c.white} FAIL ${c.reset} ${fail(
245
+ "Tests failed. Check the output above.",
246
+ )}`,
247
+ );
248
+ } else {
249
+ console.log(
250
+ ` ${c.bgGreen}${c.bold}${c.black} PASS ${c.reset} ${pass(
251
+ "All tests passed!",
252
+ )}`,
253
+ );
254
+ }
255
+ console.log();
256
+ }
257
+
258
+ // =============================================================================
259
+ // πŸ§ͺ Mock Test Runner (simulates test execution)
260
+ // =============================================================================
261
+
262
+ async function runTestFile(filePath: string): Promise<TestResult> {
263
+ const result: TestResult = {
264
+ file: filePath,
265
+ duration: 0,
266
+ passed: 0,
267
+ failed: 0,
268
+ skipped: 0,
269
+ tests: [],
270
+ };
271
+
272
+ const startTime = Date.now();
273
+
274
+ try {
275
+ // Create a mock test context that captures test registrations
276
+ const capturedTests: { name: string; fn: () => void | Promise<void> }[] =
277
+ [];
278
+
279
+ // Override global test functions temporarily
280
+ const originalConsoleLog = console.log;
281
+ const originalConsoleError = console.error;
282
+ const logs: string[] = [];
283
+
284
+ // Capture console output during file import
285
+ console.log = (...args) => logs.push(args.join(" "));
286
+ console.error = (...args) => logs.push(`[ERROR] ${args.join(" ")}`);
287
+
288
+ resetAtomicCore();
289
+
290
+ try {
291
+ // Dynamic import executes the file
292
+ await import(filePath);
293
+ } catch (importError) {
294
+ console.log = originalConsoleLog;
295
+ console.error = originalConsoleError;
296
+
297
+ result.failed = 1;
298
+ result.tests.push({
299
+ name: "Module import",
300
+ status: "fail",
301
+ duration: Date.now() - startTime,
302
+ error: (importError as Error).message,
303
+ });
304
+ result.duration = Date.now() - startTime;
305
+ return result;
306
+ }
307
+
308
+ // Restore console
309
+ console.log = originalConsoleLog;
310
+ console.error = originalConsoleError;
311
+
312
+ // Parse captured logs to extract test results
313
+ // Looking for patterns like:
314
+ // πŸ“‚ [GROUP] ...
315
+ // └─ πŸ“ [CASE] ...
316
+ // βœ… PASS
317
+ // ❌ FAIL: ...
318
+
319
+ let currentGroup = "";
320
+ let currentTest = "";
321
+ let testStart = startTime;
322
+
323
+ for (const log of logs) {
324
+ if (log.includes("βœ… PASS:")) {
325
+ result.passed++;
326
+ const testFullLabel = log.replace(/.*βœ… PASS:\s*/, "").trim();
327
+ result.tests.push({
328
+ name: testFullLabel.replace("ROOT β€Ί ", ""),
329
+ status: "pass",
330
+ duration: Math.max(1, Math.random() * 10),
331
+ });
332
+ } else if (log.includes("❌ FAIL:")) {
333
+ result.failed++;
334
+ const parts = log.replace(/.*❌ FAIL:\s*/, "").split(" β€Ί ");
335
+ const errorMsg = parts.pop() || "Unknown error";
336
+ const testFullLabel = parts.join(" β€Ί ");
337
+
338
+ result.tests.push({
339
+ name: testFullLabel.replace("ROOT β€Ί ", ""),
340
+ status: "fail",
341
+ duration: Math.max(1, Math.random() * 10),
342
+ error: errorMsg,
343
+ });
344
+ }
345
+ }
346
+
347
+ // If no tests were captured from logs, assume the file ran successfully
348
+ if (result.tests.length === 0) {
349
+ result.passed = 1;
350
+ result.tests.push({
351
+ name: "Module execution",
352
+ status: "pass",
353
+ duration: Date.now() - startTime,
354
+ });
355
+ }
356
+ } catch (e) {
357
+ result.failed = 1;
358
+ result.tests.push({
359
+ name: "Unknown error",
360
+ status: "fail",
361
+ duration: Date.now() - startTime,
362
+ error: (e as Error).message,
363
+ });
364
+ }
365
+
366
+ result.duration = Date.now() - startTime;
367
+ return result;
368
+ }
369
+
370
+ // =============================================================================
371
+ // πŸš€ Main Execution
372
+ // =============================================================================
373
+
374
+ async function main() {
375
+ const cwd = process.cwd();
376
+
377
+ printHeader();
378
+
379
+ console.log(
380
+ ` ${brightCyan("DEV")} ${dim(
381
+ `Scanning for ${cyan(".spec.ts")} files in ${gray(cwd)}`,
382
+ )}`,
383
+ );
384
+ console.log();
385
+
386
+ const files = await findSpecFiles(cwd);
387
+
388
+ if (files.length === 0) {
389
+ console.log(` ${skip("⚠")} ${yellow("No .spec.ts files found.")}`);
390
+ console.log();
391
+ process.exit(0);
392
+ }
393
+
394
+ console.log(
395
+ ` ${dim("Found")} ${bold(files.length.toString())} ${dim("test files")}`,
396
+ );
397
+ console.log();
398
+ console.log(gray(" ─".repeat(35)));
399
+ console.log();
400
+
401
+ // Run tests with live timer
402
+ for (let i = 0; i < files.length; i++) {
403
+ const file = files[i];
404
+ const fileLabel = printFileStart(file, i, files.length);
405
+
406
+ // Show running state with spinner
407
+ const startTime = Date.now();
408
+ let spinnerInterval: ReturnType<typeof setInterval> | null = null;
409
+ let frame = 0;
410
+
411
+ // Spinner animation (non-blocking)
412
+ const spinnerPromise = new Promise<void>((resolve) => {
413
+ spinnerInterval = setInterval(() => {
414
+ clearLine();
415
+ process.stdout.write(
416
+ printRunningSpinner(fileLabel, startTime, frame++),
417
+ );
418
+ }, 80);
419
+ });
420
+
421
+ // Actually run the tests
422
+ const result = await runTestFile(file);
423
+ results.push(result);
424
+
425
+ // Stop spinner
426
+ if (spinnerInterval) clearInterval(spinnerInterval);
427
+ clearLine();
428
+
429
+ // Print final result for this file
430
+ printFileResult(file, result);
431
+ }
432
+
433
+ // Print summary
434
+ console.log(gray(" ─".repeat(35)));
435
+ printSummary();
436
+
437
+ // Exit with appropriate code
438
+ const hasFailures = results.some((r) => r.failed > 0);
439
+ process.exit(hasFailures ? 1 : 0);
440
+ }
441
+
442
+ main().catch((err) => {
443
+ console.error(`${fail("Fatal Error:")} ${err.message}`);
444
+ process.exit(1);
445
+ });