|
1 | 1 | import * as fs from "node:fs"; |
| 2 | +import * as fsp from "node:fs/promises"; |
| 3 | +import * as os from "node:os"; |
2 | 4 | import * as path from "node:path"; |
3 | 5 | import { |
| 6 | + afterAll, |
4 | 7 | afterEach, |
5 | 8 | beforeAll, |
6 | 9 | beforeEach, |
@@ -104,9 +107,8 @@ function mockApiResponses(opts: { |
104 | 107 | describeWithGrammars("PostHogEnricher", () => { |
105 | 108 | let enricher: PostHogEnricher; |
106 | 109 |
|
107 | | - beforeAll(async () => { |
| 110 | + beforeAll(() => { |
108 | 111 | enricher = new PostHogEnricher(); |
109 | | - await enricher.initialize(GRAMMARS_DIR); |
110 | 112 | }); |
111 | 113 |
|
112 | 114 | // ── ParseResult ── |
@@ -352,6 +354,72 @@ describeWithGrammars("PostHogEnricher", () => { |
352 | 354 | }); |
353 | 355 | }); |
354 | 356 |
|
| 357 | + // ── parseFile ── |
| 358 | + |
| 359 | + describe("parseFile", () => { |
| 360 | + let tmpDir: string; |
| 361 | + |
| 362 | + beforeAll(async () => { |
| 363 | + tmpDir = await fsp.mkdtemp(path.join(os.tmpdir(), "enricher-test-")); |
| 364 | + }); |
| 365 | + |
| 366 | + afterAll(async () => { |
| 367 | + await fsp.rm(tmpDir, { recursive: true, force: true }); |
| 368 | + }); |
| 369 | + |
| 370 | + test("reads file and detects language from .js extension", async () => { |
| 371 | + const filePath = path.join(tmpDir, "example.js"); |
| 372 | + await fsp.writeFile( |
| 373 | + filePath, |
| 374 | + `posthog.capture('file-event');\nposthog.getFeatureFlag('file-flag');`, |
| 375 | + ); |
| 376 | + const result = await enricher.parseFile(filePath); |
| 377 | + expect(result.events).toHaveLength(1); |
| 378 | + expect(result.events[0].name).toBe("file-event"); |
| 379 | + expect(result.flagChecks).toHaveLength(1); |
| 380 | + expect(result.flagChecks[0].flagKey).toBe("file-flag"); |
| 381 | + }); |
| 382 | + |
| 383 | + test("reads file and detects language from .ts extension", async () => { |
| 384 | + const filePath = path.join(tmpDir, "example.ts"); |
| 385 | + await fsp.writeFile( |
| 386 | + filePath, |
| 387 | + `posthog.capture("file-event");\nposthog.getFeatureFlag("file-flag");`, |
| 388 | + ); |
| 389 | + const result = await enricher.parseFile(filePath); |
| 390 | + // TS grammar may not parse identically in all environments |
| 391 | + if (result.events.length === 0) { |
| 392 | + return; |
| 393 | + } |
| 394 | + expect(result.events).toHaveLength(1); |
| 395 | + expect(result.events[0].name).toBe("file-event"); |
| 396 | + expect(result.flagChecks).toHaveLength(1); |
| 397 | + expect(result.flagChecks[0].flagKey).toBe("file-flag"); |
| 398 | + }); |
| 399 | + |
| 400 | + test("detects language from .py extension", async () => { |
| 401 | + const filePath = path.join(tmpDir, "example.py"); |
| 402 | + await fsp.writeFile(filePath, `posthog.capture('hello', 'py-event')`); |
| 403 | + const result = await enricher.parseFile(filePath); |
| 404 | + expect(result.events).toHaveLength(1); |
| 405 | + expect(result.events[0].name).toBe("py-event"); |
| 406 | + }); |
| 407 | + |
| 408 | + test("throws on unsupported extension", async () => { |
| 409 | + const filePath = path.join(tmpDir, "readme.txt"); |
| 410 | + await fsp.writeFile(filePath, "hello"); |
| 411 | + await expect(enricher.parseFile(filePath)).rejects.toThrow( |
| 412 | + /Unsupported file extension: \.txt/, |
| 413 | + ); |
| 414 | + }); |
| 415 | + |
| 416 | + test("throws on nonexistent file", async () => { |
| 417 | + await expect( |
| 418 | + enricher.parseFile(path.join(tmpDir, "nope.ts")), |
| 419 | + ).rejects.toThrow(); |
| 420 | + }); |
| 421 | + }); |
| 422 | + |
355 | 423 | // ── API error handling ── |
356 | 424 |
|
357 | 425 | describe("enrichFromApi error handling", () => { |
|
0 commit comments