You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/08/08 01:32:04 UTC
(texera) 01/01: test(frontend): render the version list's collapse and selection rules (#7407)
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-7407-dce17e8446358cabf6b8910705cd7a9c7737f159
in repository https://gitbox.apache.org/repos/asf/texera.git
commit 2c57707a762486a7935860d8fee7b8eb0ff89a7e
Author: Xinyuan Lin <xi...@uci.edu>
AuthorDate: Fri Aug 7 18:31:43 2026 -0700
test(frontend): render the version list's collapse and selection rules (#7407)
### What changes were proposed in this PR?
The version list keeps its display rules in the template, and the spec
never rendered it — the existing tests drive `collapse()` and
`getDisplayedVersionId()` directly. The template was at roughly **4%**
of statements locally.
The rule worth pinning is the row predicate:
```html
<tr *ngIf="(!row.importance && row.expand) || row.importance">
```
A minor version stays folded away until its important parent is expanded
— that is the whole point of the collapse, and it exists only in the
template.
Adds 9 tests: that predicate in both directions, the descending version
numbering, the `selected-row` highlight, the expand control appearing
only on important versions, the three arguments the timestamp button
passes to `getVersion`, the date format, the column headings, and the
table being absent until versions load.
**Verified by mutation**, all reverted (template diff empty):
| Mutation | Result |
|---|---|
| make the row predicate always true | red |
| drop `expand` from the predicate | red |
| key `selected-row` off the row count instead of the index | red |
| number versions by index instead of count − index | red |
| hand `getVersion` a fixed index | red |
| show the expand control on every row | red |
| change the date format | red |
| render the table before versions load | red |
Local coverage for the component directory: **~4% → 96.55%** of
statements.
The spec was already set up for this — it deliberately skips
`detectChanges()` in `beforeEach` and notes that tests needing the
rendered template should call it locally.
One gotcha worth recording: `nz-table` renders its own expand-icon
`<button>`, so `querySelector("button")` finds that rather than the
version link. The tests select `button.version-link`.
No production file is touched.
### Any related issues, documentation, discussions?
Closes #7404
### How was this PR tested?
```
npx ng test --watch=false --include="**/versions-list.component.spec.ts"
```
```
Test Files 1 passed (1)
Tests 20 passed (20)
```
9 new on top of the existing 11. `yarn format:ci` passes.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 5)
---
.../versions-list/versions-list.component.spec.ts | 83 ++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/frontend/src/app/workspace/component/left-panel/versions-list/versions-list.component.spec.ts b/frontend/src/app/workspace/component/left-panel/versions-list/versions-list.component.spec.ts
index 7517e1547a..c9a2af8af8 100644
--- a/frontend/src/app/workspace/component/left-panel/versions-list/versions-list.component.spec.ts
+++ b/frontend/src/app/workspace/component/left-panel/versions-list/versions-list.component.spec.ts
@@ -216,4 +216,87 @@ describe("VersionsListComponent", () => {
expect(component.selectedRowIndex).toBe(0);
});
});
+ /**
+ * The table's own logic lives in the template: which rows survive the collapse predicate, the
+ * descending version number, and the selection highlight. The class-level specs above drive
+ * collapse() and getDisplayedVersionId() directly and never render, so none of it was pinned.
+ */
+ describe("rendered table", () => {
+ /** Renders the given entries and returns the rows that survived the *ngIf. */
+ function renderRows(entries: ReturnType<typeof makeEntry>[]): HTMLTableRowElement[] {
+ component.versionsList = entries as any;
+ fixture.detectChanges();
+ return Array.from(fixture.nativeElement.querySelectorAll("tbody tr"));
+ }
+
+ it("renders no table at all until the versions have loaded", () => {
+ component.versionsList = undefined as any;
+ fixture.detectChanges();
+
+ expect(fixture.nativeElement.querySelector("#versions-list")).toBeNull();
+ });
+
+ it("labels the columns from versionTableHeaders", () => {
+ renderRows([makeEntry(1, true)]);
+
+ const headers = Array.from(fixture.nativeElement.querySelectorAll("thead th")).map(th =>
+ (th as HTMLElement).textContent?.trim()
+ );
+ expect(headers).toEqual(component.versionTableHeaders);
+ });
+
+ it("hides an unimportant version while it is collapsed", () => {
+ // The predicate is (!importance && expand) || importance: minor versions stay folded away
+ // until their important parent is expanded, which is the whole point of the collapse.
+ const rows = renderRows([makeEntry(3, true), makeEntry(2, false, false), makeEntry(1, false, false)]);
+
+ expect(rows).toHaveLength(1);
+ });
+
+ it("reveals an unimportant version once it is expanded", () => {
+ const rows = renderRows([makeEntry(3, true), makeEntry(2, false, true), makeEntry(1, false, false)]);
+
+ expect(rows).toHaveLength(2);
+ });
+
+ it("numbers the versions downwards, newest first", () => {
+ const rows = renderRows([makeEntry(3, true), makeEntry(2, true), makeEntry(1, true)]);
+
+ const numbers = rows.map(r => r.querySelectorAll("td")[0].textContent?.trim());
+ expect(numbers).toEqual(["3", "2", "1"]);
+ });
+
+ it("marks only the selected row", () => {
+ component.selectedRowIndex = 1;
+ const rows = renderRows([makeEntry(2, true), makeEntry(1, true)]);
+
+ expect(rows[0].classList).not.toContain("selected-row");
+ expect(rows[1].classList).toContain("selected-row");
+ });
+
+ it("offers the expand control only on an important version", () => {
+ const rows = renderRows([makeEntry(2, true), makeEntry(1, false, true)]);
+
+ expect(rows[0].querySelector("[nztableexpand], .ant-table-row-expand-icon")).not.toBeNull();
+ expect(rows[1].querySelector(".ant-table-row-expand-icon")).toBeNull();
+ });
+
+ it("asks for the version behind the row that was clicked", () => {
+ const getVersion = vi.spyOn(component, "getVersion").mockImplementation(() => {});
+ const rows = renderRows([makeEntry(30, true), makeEntry(20, true)]);
+
+ rows[1].querySelector<HTMLButtonElement>("button.version-link")!.click();
+
+ // vId of the clicked row, its displayed (descending) number, and its index.
+ expect(getVersion).toHaveBeenCalledWith(20, 1, 1);
+ });
+
+ it("shows the timestamp in the compact date format", () => {
+ const rows = renderRows([makeEntry(1, true)]);
+
+ expect(rows[0].querySelector("button.version-link")!.textContent?.trim()).toMatch(
+ /^\d{2}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}$/
+ );
+ });
+ });
});