Skip to content

Commit

Permalink
Add stress test and another fix
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Aug 9, 2024
1 parent 91679e5 commit b6af9ec
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/diff/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
}
} else if (matchingIndex !== skewedIndex) {
if (matchingIndex == skewedIndex - 1) {
skew = matchingIndex - skewedIndex;
skew--;
} else if (matchingIndex == skewedIndex + 1) {
skew++;
} else if (matchingIndex > skewedIndex) {
Expand All @@ -316,8 +316,12 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
skew--;
}
} else if (matchingIndex < skewedIndex) {
// When our new position is in front of our old position than we increase the skew
skew++;
if (matchingIndex == skewedIndex - skew) {
skew -= matchingIndex - skewedIndex;
} else {
// When our new position is in front of our old position than we increase the skew
skew++;
}
}

// Move this VNode's DOM if the original index (matchingIndex) doesn't
Expand Down Expand Up @@ -370,11 +374,7 @@ function insert(parentVNode, oldDom, parentDom) {

return oldDom;
} else if (parentVNode._dom != oldDom) {
if (
oldDom &&
parentVNode.type &&
!parentDom.contains(oldDom)
) {
if (oldDom && parentVNode.type && !parentDom.contains(oldDom)) {
oldDom = getDomSibling(parentVNode);
}
parentDom.insertBefore(parentVNode._dom, oldDom || null);
Expand Down
65 changes: 65 additions & 0 deletions test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1743,4 +1743,69 @@ describe('render()', () => {
'<ul><div>A: 4</div><div>B: 2</div><div>B: 1</div><div>A: 3</div></ul>'
);
});

it('handle shuffled array children (moving to the front)', () => {
function randomize(arr) {
for (let i = arr.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}

const App = ({ items }) => (
<div>
{items.map(key => (
<div key={key}>{key}</div>
))}
</div>
);

const a = ['0', '2', '7', '6', '1', '3', '5', '4'];
const b = ['1', '0', '6', '7', '5', '2', '4', '3'];
const c = ['0', '7', '2', '1', '3', '5', '6', '4'];

render(<App items={a} />, scratch);
expect(scratch.innerHTML).to.equal(
`<div>${a.map(n => `<div>${n}</div>`).join('')}</div>`
);

render(<App items={b} />, scratch);
expect(scratch.innerHTML).to.equal(
`<div>${b.map(n => `<div>${n}</div>`).join('')}</div>`
);

render(<App items={c} />, scratch);
expect(scratch.innerHTML).to.equal(
`<div>${c.map(n => `<div>${n}</div>`).join('')}</div>`
);
});

it('handle shuffled (stress test)', () => {
function randomize(arr) {
for (let i = arr.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}

const App = ({ items }) => (
<div>
{items.map(key => (
<div key={key}>{key}</div>
))}
</div>
);

const a = Array.from({ length: 8 }).map((_, i) => `${i}`);

for (let i = 0; i < 10000; i++) {
const aa = randomize(a);
render(<App items={aa} />, scratch);
expect(scratch.innerHTML).to.equal(
`<div>${aa.map(n => `<div>${n}</div>`).join('')}</div>`
);
}
});
});

0 comments on commit b6af9ec

Please sign in to comment.