From c4c15c3071dd9be51841570114fd2f493574ec2d Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 9 Jan 2025 01:49:09 +1300 Subject: [PATCH] Improve test coverage --- src/idiomorph.js | 11 +++-------- test/bootstrap.js | 29 +++++++++++++++++++++++++++++ test/head.js | 20 +++++++++++++++++--- test/htmx-integration.js | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/src/idiomorph.js b/src/idiomorph.js index b2e42a9..93fd206 100644 --- a/src/idiomorph.js +++ b/src/idiomorph.js @@ -814,17 +814,14 @@ var Idiomorph = (function () { /** * - * @param {Node | null} node1 - * @param {Node | null} node2 + * @param {Node} node1 + * @param {Node} node2 * @param {MorphContext} ctx * @returns {boolean} */ // TODO: The function handles this as if it's Element or null, but the function is called in // places where the arguments may be just a Node, not an Element function isIdSetMatch(node1, node2, ctx) { - if (node1 == null || node2 == null) { - return false; - } if ( node1 instanceof Element && node2 instanceof Element && @@ -1044,10 +1041,8 @@ var Idiomorph = (function () { let htmlElement = content.firstChild; if (htmlElement) { generatedByIdiomorph.add(htmlElement); - return htmlElement; - } else { - return null; } + return htmlElement; } } else { // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help diff --git a/test/bootstrap.js b/test/bootstrap.js index f4cd785..2c8f3fa 100644 --- a/test/bootstrap.js +++ b/test/bootstrap.js @@ -91,4 +91,33 @@ describe("Bootstrap test", function () { // }, 0) // print(div1); }); + + it("findIdSetMatch rejects morphing node that would lose more IDs", function (done) { + let div1 = make( + '
A
B
C
', + ); + + let d1 = div1.querySelector("#d1"); + let d2 = div1.querySelector("#d2"); + let d3 = div1.querySelector("#d3"); + + let morphTo = + '
F
D
E
'; + let div2 = make(morphTo); + + print(div1); + Idiomorph.morph(div1, div2); + print(div1); + + // first and second paragraph should have morphed + d1.innerHTML.should.equal("D"); + d2.innerHTML.should.equal("E"); + + // third paragrah should have been discarded because it was moved in front of two other paragraphs with ID's + // it should detect that removing the first two nodes with ID's to preserve just one ID is not worth it + d3.innerHTML.should.not.equal("F"); + + div1.outerHTML.should.equal(morphTo); + done(); + }); }); diff --git a/test/head.js b/test/head.js index 64e87e9..4156c30 100644 --- a/test/head.js +++ b/test/head.js @@ -193,13 +193,27 @@ describe("Tests to ensure that the head tag merging works correctly", function ( ); }); - it("can handle scripts with block mode", async function () { + it("can handle scripts with block mode with innerHTML morph", async function () { Idiomorph.morph( window.document, - ``, - { head: { block: true, style: "append" } }, + `${window.document.body.outerHTML}`, + { morphStyle: "innerHTML", head: { block: true, style: "append" } }, ); await waitFor(() => window.hasOwnProperty("fixture")); window.fixture.should.equal("FIXTURE"); + delete(window.fixture); + window.document.head.querySelector('script[src="/test/lib/fixture.js"]').remove(); + }); + + it("can handle scripts with block mode with outerHTML morph", async function () { + Idiomorph.morph( + window.document, + `${window.document.body.outerHTML}`, + { morphStyle: "outerHTML", head: { block: true, style: "append" } }, + ); + await waitFor(() => window.hasOwnProperty("fixture")); + window.fixture.should.equal("FIXTURE"); + delete(window.fixture); + window.document.head.querySelector('script[src="/test/lib/fixture.js"]').remove(); }); }); diff --git a/test/htmx-integration.js b/test/htmx-integration.js index fc3572e..eb5b8fe 100644 --- a/test/htmx-integration.js +++ b/test/htmx-integration.js @@ -147,4 +147,40 @@ describe("Tests for the htmx integration", function () { initialBtn.should.equal(newBtn); initialBtn.classList.contains("bar").should.equal(true); }); + + it("keeps the element stable in an outer morph with oob-swap", function () { + this.server.respondWith( + "GET", + "/test", + "", + ); + let div = makeForHtmxTest( + "
", + ); + let initialBtn = document.getElementById("b1"); + div.click(); + this.server.respond(); + let newBtn = document.getElementById("b1"); + initialBtn.should.equal(newBtn); + initialBtn.innerHTML.should.equal("Bar"); + }); + + /* Currently unable to test innerHTML style oob swaps because oob-swap syntax uses a : which conflicts with morph:innerHTML + it("keeps the element stable in an inner morph with oob-swap", function () { + this.server.respondWith( + "GET", + "/test", + "
", + ); + let div = makeForHtmxTest( + "
", + ); + let initialBtn = document.getElementById("b1"); + div.click(); + this.server.respond(); + let newBtn = document.getElementById("b1"); + initialBtn.should.equal(newBtn); + initialBtn.innerHTML.should.equal("Bar"); + }); + */ });