| ... | ... | @@ -208,6 +208,34 @@ describe("computeThreadMoveAvailability matches the reference planner", () => { |
| 208 | 208 | expect(batch.get("env-w:t0")).toEqual({ canMoveUp: false, canMoveDown: false }); |
| 209 | 209 | }); |
| 210 | 210 | |
| 211 | it("answers empty and single-row sections without consulting hidden rows", () => { |
| 212 | const hidden = [makeRow("h0", "env-w", "b", true), makeRow("h1", "env-x", null, true)]; |
| 213 | expect( |
| 214 | computeThreadMoveAvailability({ |
| 215 | ordered: [], |
| 216 | allThreads: hidden, |
| 217 | section: "pinned", |
| 218 | reorderableEnvironmentIds: WRITABLE, |
| 219 | }).size, |
| 220 | ).toBe(0); |
| 221 | for (const environment of ["env-w", "env-x"]) { |
| 222 | const ordered = [makeRow("t0", environment, "a", true)]; |
| 223 | const allThreads = [...ordered, ...hidden]; |
| 224 | const batch = computeThreadMoveAvailability({ |
| 225 | ordered, |
| 226 | allThreads, |
| 227 | section: "pinned", |
| 228 | reorderableEnvironmentIds: WRITABLE, |
| 229 | }); |
| 230 | expect(Object.fromEntries(batch)).toEqual({ |
| 231 | [`${environment}:t0`]: { canMoveUp: false, canMoveDown: false }, |
| 232 | }); |
| 233 | expect(Object.fromEntries(batch)).toEqual( |
| 234 | Object.fromEntries(referenceAvailability(ordered, allThreads, WRITABLE)), |
| 235 | ); |
| 236 | } |
| 237 | }); |
| 238 | |
| 211 | 239 | it("denies rows whose section has non-writable neighbours when the fast path fails", () => { |
| 212 | 240 | // Keyless neighbors force the section-rewrite fallback; a non-writable |
| 213 | 241 | // neighbor makes the rewrite illegal for every row in the section. |