Skip to content

Add focused Morphlex regression coverage#44

Merged
joeldrapper merged 4 commits intomainfrom
test/morphlex-coverage-regressions
Mar 10, 2026
Merged

Add focused Morphlex regression coverage#44
joeldrapper merged 4 commits intomainfrom
test/morphlex-coverage-regressions

Conversation

@joeldrapper
Copy link
Copy Markdown
Collaborator

Protect detached-node callback behavior and no-op character data semantics while bringing src/morphlex.ts to full coverage with focused browser-first tests.

Protect detached-node callback behavior and no-op character data semantics while bringing src/morphlex.ts to full coverage with focused browser-first tests.
Copilot AI review requested due to automatic review settings March 10, 2026 13:24
Verify realistic app-shell and full-document morphs with HTML fixtures so large structural updates stay stable across browser environments.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62e2cdaf90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/morphlex.ts
Comment on lines +288 to +291
const parent = from.parentNode

if (!parent) {
for (let i = 0; i < newNodes.length; i++) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve parent before morphing first node in one-to-many

In the length > 1 path, #morphOneToOne(from, first) runs before parent is captured, so when the first target requires replacement (for example, morphing an attached <span> to "<div>...</div><em>...</em>"), from.parentNode is already null here and this branch returns early as if the source were detached. That drops all trailing nodes from the target list, so attached one-to-many morphs can produce incomplete DOM output.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds focused regression tests for the Morphlex DOM morphing library, targeting specific edge cases to achieve full coverage of src/morphlex.ts. Alongside the new tests, it includes several small source refactors to make those code paths easier to reach and verify.

Changes:

  • Adds 15+ new browser-first test files covering detached-node callbacks, character-data no-op semantics, whitespace handling, morphInner validation, id-array matching, and form control dirty-flagging.
  • Refactors src/morphlex.ts to clarify detached-node behavior in #replaceNode and #morphOneToMany, simplifies flagDirtyInputs, removes provably-redundant active-flag guards in the first matching passes, and simplifies forEachDescendantElementWithId.
  • Adds a coverage.include constraint to vitest.config.ts and three .gitignore entries for coverage temp files.

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/morphlex.ts Core refactors: detached-node callback semantics, flagDirtyInputs signature, redundant guard removal, longestIncreasingSubsequence simplification
vitest.config.ts Adds coverage.include scoped to src/morphlex.ts
.gitignore Ignores coverage temp directories
test/new/before-node-added.browser.test.ts New tests for detached-node beforeNodeAdded/beforeNodeRemoved behavior
test/new/callback-guards.browser.test.ts New tests for beforeNodeVisited, afterNodeVisited, beforeChildrenVisited guards
test/new/character-data.browser.test.ts New tests verifying no-op behavior when character data is unchanged
test/new/dirty-option.browser.test.ts New tests for option dirty-flagging before morph
test/new/dirty-textarea.browser.test.ts New tests for descendant textarea dirty-flag cleanup
test/new/document-target.browser.test.ts New test for morphDocument accepting a pre-parsed document
test/new/document.browser.test.ts New test for id-based matching from the document root
test/new/duplicate-id.browser.test.ts New test for bucketed duplicate-id candidate matching
test/new/id-array.browser.test.ts New tests for idArray/idSet descendant matching logic
test/new/morph-inner.browser.test.ts New tests for morphInner string/mismatch validation
test/new/no-matches.browser.test.ts New test for completely unmatched child removal and insertion
test/new/non-element-matching.browser.test.ts New tests for comment/text node matching fallback
test/new/textarea.browser.test.ts New tests for textarea morph including preserveChanges
test/new/whitespace.browser.test.ts Two new whitespace edge-case tests (empty and unicode)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/morphlex.ts Outdated
Comment thread src/morphlex.ts Outdated
@joeldrapper joeldrapper requested a review from Copilot March 10, 2026 13:49
@joeldrapper joeldrapper merged commit 6c31570 into main Mar 10, 2026
4 checks passed
@joeldrapper joeldrapper deleted the test/morphlex-coverage-regressions branch March 10, 2026 13:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 30 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import { expect, test } from "vitest"
import { morph, morphInner } from "../../src/morphlex"

test("beforeNodeVisited can skip non-element updates without firing afterNodeVisited", () => {
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

The test name says "without firing afterNodeVisited" but the test expects events to equal ["before", "after"], which includes "after" — the afterNodeVisited callback for the outer div element. The name is misleading: while it's true that afterNodeVisited is not fired for the text node itself (because beforeNodeVisited returned false for it), the afterNodeVisited callback does fire for the surrounding div. A clearer name would be something like "beforeNodeVisited returning false for a text node skips afterNodeVisited for that node but not the parent element".

Copilot uses AI. Check for mistakes.
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.

2 participants