This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-6759-b504817d472ba0b7af981a97c26b62a56bb33100 in repository https://gitbox.apache.org/repos/asf/texera.git
commit d9519850ebb30220d840802485f520c00e4c386f Author: Meng Wang <[email protected]> AuthorDate: Tue Jul 21 22:43:09 2026 -0700 test(frontend): cover UserDatasetFileRendererComponent loadTabularFile and readFileAsText (#6759) ### What changes were proposed in this PR? Extends the existing `UserDatasetFileRendererComponent` spec to cover the two file-content methods it had left untested (`frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.ts`). 3 tests cover: - `loadTabularFile` — sets the header from the first row and normalizes each row's length to the header width; leaves state unchanged for empty data. - `readFileAsText` — reads the blob text into `textContent`. Per the issue's flaky-test note, `FileReader` is **not** left to jsdom's real async: it is replaced with a deterministic stub whose `readAsText` fires `onload` on a microtask (`queueMicrotask`, awaited via `Promise.resolve()`), and the global is restored in a `finally` so it survives an assertion failure. No production code was changed. ### Any related issues, documentation, discussions? Closes #6748 ### How was this PR tested? Extended unit tests, run locally in `frontend/` (all green; the failure path was verified by breaking an assertion to confirm the suite goes red): ``` ng test --watch=false --include src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.spec.ts # Test Files 1 passed (1) | Tests 18 passed (18) prettier --write <spec> # clean eslint <spec> # clean ``` ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 4.8 [1M context]) --- .../user-dataset-file-renderer.component.spec.ts | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.spec.ts b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.spec.ts index a6306bd20a..ab19ff9539 100644 --- a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.spec.ts +++ b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-file-renderer/user-dataset-file-renderer.component.spec.ts @@ -194,4 +194,47 @@ describe("UserDatasetFileRendererComponent", () => { expect(getMimeType("")).toBe(MIME_TYPES.OCTET_STREAM); }); }); + + describe("file content loading", () => { + it("loadTabularFile sets the header, pads short rows to the header width, and keeps longer rows intact", () => { + (component as unknown as { loadTabularFile: (d: unknown[][]) => void }).loadTabularFile([ + ["a", "b", "c"], + ["1", "2"], + ["x", "y", "z", "w"], + ]); + + expect(component.tableDataHeader).toEqual(["a", "b", "c"]); + expect(component.tableContent[0]).toEqual(["1", "2", ""]); // short row padded to the header width + expect(component.tableContent[1]).toEqual(["x", "y", "z", "w"]); + }); + + it("loadTabularFile leaves state unchanged for empty data", () => { + component.tableDataHeader = ["keep"]; + component.tableContent = [["keep-content"]]; + (component as unknown as { loadTabularFile: (d: unknown[][]) => void }).loadTabularFile([]); + expect(component.tableDataHeader).toEqual(["keep"]); + expect(component.tableContent).toEqual([["keep-content"]]); + }); + + it("readFileAsText reads the blob text into textContent", async () => { + // Deterministic FileReader stub — fire onload on a microtask, never rely on jsdom's real async. + class FakeFileReader { + onload: ((e: { target: { result: string } }) => void) | null = null; + result: string | null = null; + readAsText(_blob: Blob): void { + this.result = "canned text"; + queueMicrotask(() => this.onload?.({ target: { result: this.result as string } })); + } + } + const realFileReader = globalThis.FileReader; + (globalThis as unknown as { FileReader: unknown }).FileReader = FakeFileReader; + try { + (component as unknown as { readFileAsText: (b: Blob) => void }).readFileAsText(new Blob(["ignored"])); + await Promise.resolve(); + expect(component.textContent).toBe("canned text"); + } finally { + (globalThis as unknown as { FileReader: unknown }).FileReader = realFileReader; + } + }); + }); });
