Skip to content

Commit

Permalink
Merge pull request #73 from botandrose/hook-tests
Browse files Browse the repository at this point in the history
Add tests to cover hooks, and fix extraneous hook call
  • Loading branch information
1cg authored Dec 17, 2024
2 parents 4d3ef0c + 350bda2 commit c1b548a
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/idiomorph.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,10 @@ var Idiomorph = (function () {
// iterate backwards to avoid skipping over items when a delete occurs
for (let i = toAttributes.length - 1; 0 <= i; i--) {
const toAttribute = toAttributes[i];
if (ignoreAttribute(toAttribute.name, toEl, 'remove', ctx)) {
continue;
}
if (!fromEl.hasAttribute(toAttribute.name)) {
if (ignoreAttribute(toAttribute.name, toEl, 'remove', ctx)) {
continue;
}
toEl.removeAttribute(toAttribute.name);
}
}
Expand Down
178 changes: 178 additions & 0 deletions test/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
describe("lifecycle hooks", function(){
beforeEach(function() {
clearWorkArea();
});

it('calls beforeNodeAdded before a new node is added to the DOM', function(){
let calls = [];
let initial = make("<ul><li>A</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li><li>B</li></ul>", { callbacks: {
beforeNodeAdded: node => {
calls.push(node.outerHTML);
}
} });
initial.outerHTML.should.equal("<ul><li>A</li><li>B</li></ul>");
calls.should.eql(["<li>B</li>"]);
});

it('returning false to beforeNodeAdded prevents adding the node', function(){
let initial = make("<ul><li>A</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li><li>B</li></ul>", { callbacks: {
beforeNodeAdded: node => false,
} });
initial.outerHTML.should.equal("<ul><li>A</li></ul>");
});

it('calls afterNodeAdded after a new node is added to the DOM', function(){
let calls = [];
let initial = make("<ul><li>A</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li><li>B</li></ul>", { callbacks: {
afterNodeAdded: node => {
calls.push(node.outerHTML);
}
} });
initial.outerHTML.should.equal("<ul><li>A</li><li>B</li></ul>");
calls.should.eql(["<li>B</li>"]);
});

it('calls beforeNodeMorphed before a node is morphed', function(){
let calls = [];
let initial = make(`<ul><li id="a">A</li></ul>`);
Idiomorph.morph(initial, `<ul><li id="a">B</li></ul>`, { callbacks: {
beforeNodeMorphed: (oldNode, newNode) => {
calls.push([
oldNode.outerHTML || oldNode.textContent,
newNode.outerHTML || newNode.textContent,
]);
}
} });
initial.outerHTML.should.equal(`<ul><li id="a">B</li></ul>`);
calls.should.eql([
[`<ul><li id="a">A</li></ul>`, `<ul><li id="a">B</li></ul>`],
[`<li id="a">A</li>`, `<li id="a">B</li>`],
[`A`, `B`],
]);
});

it('returning false to beforeNodeMorphed prevents morphing the node', function(){
let initial = make(`<ul name="a"><li name="a" id="a">A</li></ul>`);
Idiomorph.morph(initial, `<ul name="b"><li name="b" id="a">B</li></ul>`, { callbacks: {
beforeNodeMorphed: node => {
if(node.nodeType === Node.TEXT_NODE) return false
}
} })
initial.outerHTML.should.equal(`<ul name="b"><li name="b" id="a">A</li></ul>`);
});

it('calls afterNodeMorphed before a node is morphed', function(){
let calls = [];
let initial = make(`<ul><li id="a">A</li></ul>`);
Idiomorph.morph(initial, `<ul><li id="a">B</li></ul>`, { callbacks: {
afterNodeMorphed: (oldNode, newNode) => {
calls.push([
oldNode.outerHTML || oldNode.textContent,
newNode.outerHTML || newNode.textContent,
]);
}
} });
initial.outerHTML.should.equal(`<ul><li id="a">B</li></ul>`);
calls.should.eql([
[`B`, `B`],
[`<li id="a">B</li>`, `<li id="a">B</li>`],
[`<ul><li id="a">B</li></ul>`, `<ul><li id="a">B</li></ul>`],
]);
});

it('calls beforeNodeRemoved before a node is removed from the DOM', function(){
let calls = [];
let initial = make("<ul><li>A</li><li>B</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li></ul>", { callbacks: {
beforeNodeRemoved: node => {
calls.push(node.outerHTML);
}
} });
initial.outerHTML.should.equal("<ul><li>A</li></ul>");
calls.should.eql(["<li>B</li>"]);
});

it('returning false to beforeNodeRemoved prevents removing the node', function(){
let initial = make("<ul><li>A</li><li>B</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li></ul>", { callbacks: {
beforeNodeRemoved: node => false,
} });
initial.outerHTML.should.equal("<ul><li>A</li><li>B</li></ul>");
});

it('calls afterNodeRemoved after a node is removed from the DOM', function(){
let calls = [];
let initial = make("<ul><li>A</li><li>B</li></ul>");
Idiomorph.morph(initial, "<ul><li>A</li></ul>", { callbacks: {
afterNodeRemoved: node => {
calls.push(node.outerHTML);
}
} });
initial.outerHTML.should.equal("<ul><li>A</li></ul>");
calls.should.eql(["<li>B</li>"]);
});

it('calls beforeAttributeUpdated when an attribute is added', function(){
let calls = [];
let initial = make("<a></a>");
Idiomorph.morph(initial, `<a href="#"></a>`, { callbacks: {
beforeAttributeUpdated: (attributeName, node, mutationType) => {
calls.push([attributeName, node.outerHTML, mutationType]);
}
} });
initial.outerHTML.should.equal(`<a href="#"></a>`);
calls.should.eql([["href", `<a></a>`, "update"]]);
});

it('calls beforeAttributeUpdated when an attribute is updated', function(){
let calls = [];
let initial = make(`<a href="a"></a>`);
Idiomorph.morph(initial, `<a href="b"></a>`, { callbacks: {
beforeAttributeUpdated: (attributeName, node, mutationType) => {
calls.push([attributeName, node.outerHTML, mutationType]);
}
} });
initial.outerHTML.should.equal(`<a href="b"></a>`);
calls.should.eql([["href", `<a href="a"></a>`, "update"]]);
});

it('calls beforeAttributeUpdated when an attribute is removed', function(){
let calls = [];
let initial = make(`<a href="#"></a>`);
Idiomorph.morph(initial, `<a></a>`, { callbacks: {
beforeAttributeUpdated: (attributeName, node, mutationType) => {
calls.push([attributeName, node.outerHTML, mutationType]);
}
} });
initial.outerHTML.should.equal(`<a></a>`);
calls.should.eql([["href", `<a href="#"></a>`, "remove"]]);
});

it('returning false to beforeAttributeUpdated prevents the attribute addition', function(){
let initial = make("<a></a>");
Idiomorph.morph(initial, `<a href="#"></a>`, { callbacks: {
beforeAttributeUpdated: () => false,
} });
initial.outerHTML.should.equal(`<a></a>`);
});

it('returning false to beforeAttributeUpdated prevents the attribute update', function(){
let initial = make(`<a href="a"></a>`);
Idiomorph.morph(initial, `<a href="b"></a>`, { callbacks: {
beforeAttributeUpdated: () => false,
} });
initial.outerHTML.should.equal(`<a href="a"></a>`);
});

it('returning false to beforeAttributeUpdated prevents the attribute removal', function(){
let initial = make(`<a href="#"></a>`);
Idiomorph.morph(initial, `<a></a>`, { callbacks: {
beforeAttributeUpdated: () => false,
} });
initial.outerHTML.should.equal(`<a href="#"></a>`);
});
});

0 comments on commit c1b548a

Please sign in to comment.