Skip to content

fix(util): Rectangle#intersects never returns a Boolean; add contains… - #20007

Merged
tobiu merged 1 commit into
neomjs:devfrom
arnavsingh0418:fix/rectangle-intersects-20002
Oct 22, 2026
Merged

tobiu merged 1 commit into
neomjs:devfrom
arnavsingh0418:fix/rectangle-intersects-20002

Conversation

@arnavsingh0418

Copy link
Copy Markdown
Contributor

Does this PR resolve an issue? (Required)

Resolves #20002

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Refactor

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

intersects() no longer returns true for a zero-size argument. The three in-repo callers that relied on that point branch now use containsPoint(); no caller in src/, apps/ or examples/ relies on a Boolean from intersects().

The PR fulfills this requirement:

  • It's submitted to the dev branch, not the main branch

Other information:

  • Rectangle#intersects(other) always returns the overlap Rectangle or false. A zero-size (or point-shaped) other returns false.
  • New Rectangle#containsPoint(x, y). Points on the edges count as inside, matching the old point branch.
  • JSDoc on both, with return types.
  • Window#getWindowAt, DragCoordinator#getWindowAtExcept and the remote-drop candidate check move to containsPoint().
  • Unit tests: intersects for overlapping, disjoint, edge-touching and zero-size other; containsPoint for inside, edge/corner and outside. Run against the old implementation, the zero-size case fails (Expected: false, Received: true).

Testing (Windows): test/playwright/unit/util/Rectangle.spec.mjs 19/19 pass. unit/manager, unit/dashboard and Workspace.spec.mjs: 1635 pass; the 3 failures in DockImportDirection.spec.mjs fail identically on dev without this change (Windows paths). I did not run the e2e suite locally.

AI disclosure: this change was prepared with Claude (Anthropic) and reviewed by me.

…Point() (neomjs#20002)

Signed-off-by: Arnav Singh <arnavsingh08@outlook.com>
@neo-opus-ada

Copy link
Copy Markdown
Contributor

Welcome, @arnavsingh0418, and thank you. You picked up #20002 within two hours of it being filed, and the PR follows the prescription closely:

  • intersects() always returns a Rectangle or false
  • a dedicated containsPoint() keeps the old inclusive-edge semantics
  • all three callers are migrated
  • both methods have JSDoc
  • the unit arms include a red against the old implementation

I filed the ticket, so I'll review this PR. The maintainer just started CI on your fork, and the formal review follows as soon as it's green. The three DockImportDirection.spec.mjs failures you saw on Windows also fail on dev without your change. That's a known Windows path issue in two unit specs (#19209), not your change.

⚖️ Ada · @neo-opus-ada · Claude Opus 5.5 · Claude Code

@neo-opus-ada neo-opus-ada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: This head is merge-safe and delivers the ticket's prescription exactly. My one observation, that external callers who pass point objects get a new answer, is a release-note item that comes from the ticket I wrote, not a defect in this PR.

Peer-Review Opening: @arnavsingh0418, thank you, and welcome! You picked up #20002 within two hours of it being filed. The change is small, precise and well tested: intersects() now has one meaning, containsPoint() names the other, all three callers moved over, and you showed the zero-size case failing against the old code. That is exactly the evidence a reviewer hopes for.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: #20002, which I authored. Its Design authority: line says "none recorded": intersects() had no JSDoc, only an inline comment on its point branch. I also read dev's src/util/Rectangle.mjs (intersects, contains → includes, which reads left/top) and the three callers, all of which pass point-shaped {bottom: y, right: x, x, y} objects: Window#getWindowAt and DragCoordinator (twice).
  • Expected Solution Shape:
    • intersects() returns only a Rectangle or false.
    • A dedicated point test keeps the old inclusive-edge semantics.
    • The three callers migrate, and JSDoc states both return types.
    • contains() and includes() stay untouched, since their semantics are out of scope.
    • Unit cases cover overlap, disjoint, touching and zero-size inputs, plus inside, edge and outside points.
  • Patch Verdict: Matches.
    • intersects() rejects any other without positive width and height.
    • containsPoint(x, y) uses >=/<= against x/right and y/bottom, matching the old point branch.
    • All three callers use containsPoint(x, y).
    • At this head the only other .intersects( caller is DomAccess#getClippedRect, which uses the area overlap and stays correct.
  • Premise Coherence: Coheres with verify-before-assert. The PR body states its red-first receipt, and I reproduced it.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #20002
  • Related Graph Nodes: #19997 / #19984 (where the mixed return type caused a page error), #19209 (the Windows path issue behind the contributor's three unrelated local failures)
  • Origin Session ID: ad72172d-1af5-4daa-84ba-e3520e41b6d3

🔬 Depth Floor

Challenge OR documented search (per guide §7.1):

  • Challenge (non-blocking): Rectangle is a public engine utility. Application code outside this repository that calls intersects() with a point-shaped object, as Neo's own callers did, now gets false instead of a containment answer, with no error. The PR body marks "no breaking change", which holds for every caller inside the repository. For external callers it is a behaviour change worth one line in the next release notes: "use containsPoint(x, y) for point tests". That traces back to my ticket, not to this PR.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description: framing matches what the diff substantiates (no overshoot)
  • Anchor & Echo summaries: precise codebase terminology, no metaphor or source-code snapshot anchor (ticket/PR/lane/AC/cycle/line number) that overshoots durable intent
  • [RETROSPECTIVE] tag: accurately characterizes what shipped (no inflation of architectural significance)
  • Linked anchors: cited tickets/PRs actually establish the claimed pattern (no borrowed authority)

Findings: Pass. The new JSDoc states both return types plainly.


🧠 Graph Ingestion Notes

  • [KB_GAP]: N/A
  • [TOOLING_GAP]: N/A. The one red CI run was the CodeQL extraction guard running while the Analyze leg was still queued; re-run, it passed.
  • [RETROSPECTIVE]: A method whose return type depends on the size of its argument hides a crash until a zero-size box appears. Splitting it into two named methods makes the contract visible.

N/A Audits — 📡 🔗

N/A across listed dimensions: no OpenAPI, no skill or convention change.


🎯 Close-Target Audit

  • Close-targets identified: #20002
  • For each #N: confirmed not epic-labeled

Findings: Pass


📑 Contract Completeness Audit

  • Originating ticket (or parent epic) contains a Contract Ledger matrix: #20002 has none, but its Fix and ACs state the contract (intersects returns Rectangle|false, plus a dedicated point method)
  • Implemented PR diff matches the stated contract (no drift)

Findings: Pass. The diff implements the ticket's stated contract exactly. Its one external-facing consequence is in the Depth Floor.


🧪 Test-Evidence & Location Audit

  • Execution evidence: exact-head CI green at bd23e9dde2 (44 checks pass, 1 skipped; the latest attempts)
  • AC-table cross-read: N/A (the external-contributor template), and every #20002 AC is covered below
  • Reviewer falsifier: test/playwright/unit/util/Rectangle.spec.mjs from this head, run against dev's Rectangle, fails 4 tests: the zero-size intersects case and the three containsPoint cases. It passes 19/19 at this head.
  • Test location: pass (test/playwright/unit/util/Rectangle.spec.mjs, the existing spec for this class)

Findings: Pass. AC mapping:

  • AC-1, intersects never returns true: the overlap, disjoint, touching and zero-size cases.
  • AC-2: containsPoint cases for inside, edge and outside.
  • AC-3: the callers are migrated, and the manager suites are green in CI.
  • AC-4: no Boolean-relying caller is left, checked with git grep at the head.

📋 Required Actions

No required actions — eligible for human merge.


📊 Evaluation Metrics

Verdict weights: 30% premise / right thing, 30% architecture + placement, 30% diff correctness, 10% AC/audit sanity. These are importance-to-verdict weights, not effort budgets.

  • [ARCH_ALIGNMENT]: 97. owner: src/util/Rectangle.mjs · primitive: Rectangle#intersects / Rectangle#containsPoint · retired: the size-dependent point branch | kept: contains()/includes(). 3 deducted: the zero-size guard #19997 added in DomAccess#getClippedRect is now redundant. That is a follow-up simplification and out of this PR's scope.
  • [CONTENT_COMPLETENESS]: 92. JSDoc on both methods gives the return types and points from one to the other. 8 deducted: the "no breaking change" mark doesn't cover external point callers (Depth Floor).
  • [EXECUTION_QUALITY]: 98. Checked:
    • non-positive sizes return false
    • edge points count as inside, as before
    • every caller is migrated
    • the red-first evidence reproduces
  • [PRODUCTIVITY]: 100. All four #20002 ACs are delivered.
  • [IMPACT]: 35. Removes a crash trap from a core utility used by window and drag targeting.
  • [COMPLEXITY]: 15. One class and three one-line call sites.
  • [EFFORT_PROFILE]: Quick Win. A small, exact API cleanup with full tests.

Thank you again for the contribution. It is ready for the maintainer's merge.

⚖️ Ada · @neo-opus-ada · Claude Opus 5.5 · Claude Code

@tobiu
tobiu merged commit 3f27e5f into neomjs:dev Oct 22, 2026
54 of 55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rectangle#intersects returns a Boolean for a zero-size rectangle

3 participants