v0.0.13: Refactored the render-loop to solve hard-to-track bugs and added more (elaborate) unit-tests to make sure it all works
This commit is contained in:
@@ -194,13 +194,14 @@ describe("Children", () => {
|
||||
].join(''));
|
||||
});
|
||||
|
||||
test("Nulls are ignored", async () => {
|
||||
test("Nulls and undefined are ignored", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
<h1>Title</h1>
|
||||
{null}
|
||||
{undefined}
|
||||
<button>Save</button>
|
||||
</div>
|
||||
)
|
||||
@@ -212,4 +213,50 @@ describe("Children", () => {
|
||||
`</div>`
|
||||
].join(''));
|
||||
});
|
||||
|
||||
test("Update maintains the same elements where possible", async () => {
|
||||
let initialVSpec = (
|
||||
<div class="container">
|
||||
<h1>Title</h1>
|
||||
<button>Save</button>
|
||||
</div>
|
||||
);
|
||||
let rendered = render(initialVSpec);
|
||||
let container = testContainer(rendered);
|
||||
|
||||
let children = Array.from(rendered.childNodes);// Capture current child-nodes
|
||||
|
||||
expect(
|
||||
container.innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`<h1>Title</h1>`,
|
||||
`<button>Save</button>`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
|
||||
// Update it
|
||||
let updatedVSpec = (
|
||||
<div class="container">
|
||||
<h1>Update</h1>
|
||||
<button>Dismiss</button>
|
||||
</div>
|
||||
);
|
||||
render(updatedVSpec, {host: rendered, old: initialVSpec});
|
||||
expect(
|
||||
container.innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`<h1>Update</h1>`,
|
||||
`<button>Dismiss</button>`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
|
||||
let updatedChildren = Array.from(rendered.childNodes);// Capture current child-nodes
|
||||
|
||||
expect(children.length).toBe(updatedChildren.length);
|
||||
for(let i = 0; i < children.length; ++i){
|
||||
expect(children[i] === updatedChildren[i]).toBe(true);// Expect the element to be the same by ref
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -3,14 +3,14 @@ import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("Key-property tests", () => {
|
||||
test("Keyed list", async () => {
|
||||
let renderedIndexes = [];
|
||||
let initIndexes = [0, 1, 2, 3];
|
||||
let initialRendered = new Map();
|
||||
let initIndexes = [1, 2, 3, 4];
|
||||
|
||||
let makeSpec = (targetList, indexes)=>(
|
||||
<ul>
|
||||
{
|
||||
indexes.map(index => (
|
||||
<li id={`li_${index}`} key={index} ref={(el) => targetList[ index ] = el}>
|
||||
<li id={`li_${index}`} key={index} ref={(el) => targetList.set(index, el)}>
|
||||
{index}
|
||||
</li>
|
||||
))
|
||||
@@ -18,7 +18,7 @@ describe("Key-property tests", () => {
|
||||
</ul>
|
||||
);
|
||||
|
||||
let initialVSpec = makeSpec(renderedIndexes, initIndexes);
|
||||
let initialVSpec = makeSpec(initialRendered, initIndexes);
|
||||
|
||||
let rendered = render(initialVSpec);
|
||||
let container = testContainer(rendered);
|
||||
@@ -31,17 +31,18 @@ describe("Key-property tests", () => {
|
||||
].join('')
|
||||
);
|
||||
|
||||
expect(renderedIndexes.length).toBe(4);
|
||||
for(let rendered of renderedIndexes){
|
||||
expect(initialRendered.size).toBe(4);
|
||||
for(let rendered of initialRendered){
|
||||
expect(rendered).not.toBeUndefined();
|
||||
}
|
||||
|
||||
let reorderedIndexes = [3,2,1,0];
|
||||
let rerenderedIndexes = renderedIndexes.slice();
|
||||
// Reverse order
|
||||
let reorderedIndexes = [4,3,2,1];
|
||||
let rerenderedIndexes = new Map(initialRendered);
|
||||
let updatedVSpec = makeSpec(rerenderedIndexes, reorderedIndexes);
|
||||
render(updatedVSpec, {host: rendered, old: initialVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
|
||||
render(updatedVSpec, {host: rendered, old: initialVSpec});
|
||||
|
||||
// Updated
|
||||
// Updated (reverse order)
|
||||
expect(container.innerHTML).toBe(
|
||||
[
|
||||
`<ul>`,
|
||||
@@ -51,11 +52,46 @@ describe("Key-property tests", () => {
|
||||
);
|
||||
|
||||
// Validate that items were merely re-arranged and not re-created
|
||||
expect(rerenderedIndexes.length).toBe(4);
|
||||
for(let i=0; i<4; ++i){
|
||||
let initRendered = renderedIndexes[i];
|
||||
let reorderedRendered = rerenderedIndexes[i];
|
||||
expect(rerenderedIndexes.size).toBe(4);
|
||||
for(let i of initIndexes){
|
||||
let initRendered = initialRendered.get(i);
|
||||
let reorderedRendered = rerenderedIndexes.get(i);
|
||||
expect(initRendered === reorderedRendered).toBe(true); // These should've remained the same
|
||||
}
|
||||
|
||||
// Add items and change order
|
||||
let additionalIndexes = [0, 1, 2.5, 2, 3, 4, 5.5];
|
||||
let additionalRerenderedIndexes = new Map(initialRendered);
|
||||
let secondUpdatedVSpec = makeSpec(additionalRerenderedIndexes, additionalIndexes);
|
||||
render(secondUpdatedVSpec, {host: rendered, old: updatedVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
|
||||
|
||||
// Validate add items and changed order
|
||||
expect(container.innerHTML).toBe(
|
||||
[
|
||||
`<ul>`,
|
||||
...additionalIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
|
||||
`</ul>`
|
||||
].join('')
|
||||
);
|
||||
|
||||
// Validate that items were merely re-arranged and not re-created
|
||||
expect(additionalRerenderedIndexes.size).toBe(additionalIndexes.length);
|
||||
for(let i of initIndexes){
|
||||
let initRendered = initialRendered.get(i);
|
||||
let additionalRendered = additionalRerenderedIndexes.get(i);
|
||||
expect(initRendered === additionalRendered).toBe(true); // These should've still remained the same
|
||||
}
|
||||
|
||||
// Revert back to the original
|
||||
render(initialVSpec, {host: rendered, old: secondUpdatedVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
|
||||
|
||||
// Validate reverting back to the original
|
||||
expect(container.innerHTML).toBe(
|
||||
[
|
||||
`<ul>`,
|
||||
...initIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
|
||||
`</ul>`
|
||||
].join('')
|
||||
);
|
||||
});
|
||||
});
|
||||
62
jest/render/svg-rendering.test.js
Normal file
62
jest/render/svg-rendering.test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import { render } from "@cerxes/csx";
|
||||
import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("SVG-rendering test", () => {
|
||||
test("Simple", async () => {
|
||||
let makeSpec = (stroke, strokeWidth) => (
|
||||
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg"
|
||||
stroke={stroke}>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(1 1)" stroke-width={strokeWidth}>
|
||||
<circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
|
||||
<path d="M36 18c0-9.94-8.06-18-18-18">
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 18 18"
|
||||
to="360 18 18"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
let initialVSpec = makeSpec("#000", 2);
|
||||
let rendered = render(initialVSpec);
|
||||
let container = testContainer(rendered);
|
||||
|
||||
expect(container.innerHTML).toBe([
|
||||
`<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#000">`,
|
||||
`<g fill="none" fill-rule="evenodd">`,
|
||||
`<g transform="translate(1 1)" stroke-width="2">`,
|
||||
`<circle stroke-opacity=".5" cx="18" cy="18" r="18">`,
|
||||
`</circle>`,
|
||||
`<path d="M36 18c0-9.94-8.06-18-18-18">`,
|
||||
`<animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s" repeatCount="indefinite">`,
|
||||
`</animateTransform>`,
|
||||
`</path>`,
|
||||
`</g>`,
|
||||
`</g>`,
|
||||
`</svg>`
|
||||
].join(''));
|
||||
|
||||
let updatedVSpec = makeSpec("#FFF", 4);
|
||||
render(updatedVSpec, { host: rendered, old: initialVSpec });
|
||||
|
||||
expect(container.innerHTML).toBe([
|
||||
`<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#FFF">`,
|
||||
`<g fill="none" fill-rule="evenodd">`,
|
||||
`<g transform="translate(1 1)" stroke-width="4">`,
|
||||
`<circle stroke-opacity=".5" cx="18" cy="18" r="18">`,
|
||||
`</circle>`,
|
||||
`<path d="M36 18c0-9.94-8.06-18-18-18">`,
|
||||
`<animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s" repeatCount="indefinite">`,
|
||||
`</animateTransform>`,
|
||||
`</path>`,
|
||||
`</g>`,
|
||||
`</g>`,
|
||||
`</svg>`
|
||||
].join(''));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user