Skip to content

Commit 0214869

Browse files
committed
Add stress test and another fix
1 parent 91679e5 commit 0214869

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

src/diff/children.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
299299
}
300300
} else if (matchingIndex !== skewedIndex) {
301301
if (matchingIndex == skewedIndex - 1) {
302-
skew = matchingIndex - skewedIndex;
302+
skew--;
303303
} else if (matchingIndex == skewedIndex + 1) {
304304
skew++;
305305
} else if (matchingIndex > skewedIndex) {
@@ -316,8 +316,12 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
316316
skew--;
317317
}
318318
} else if (matchingIndex < skewedIndex) {
319-
// When our new position is in front of our old position than we increase the skew
320-
skew++;
319+
if (matchingIndex === skewedIndex - skew) {
320+
skew -= matchingIndex - skewedIndex;
321+
} else {
322+
// When our new position is in front of our old position than we increase the skew
323+
skew++;
324+
}
321325
}
322326

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

371375
return oldDom;
372376
} else if (parentVNode._dom != oldDom) {
373-
if (
374-
oldDom &&
375-
parentVNode.type &&
376-
!parentDom.contains(oldDom)
377-
) {
377+
if (oldDom && parentVNode.type && !parentDom.contains(oldDom)) {
378378
oldDom = getDomSibling(parentVNode);
379379
}
380380
parentDom.insertBefore(parentVNode._dom, oldDom || null);

test/browser/render.test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,4 +1743,69 @@ describe('render()', () => {
17431743
'<ul><div>A: 4</div><div>B: 2</div><div>B: 1</div><div>A: 3</div></ul>'
17441744
);
17451745
});
1746+
1747+
it('handle shuffled array children (moving to the front)', () => {
1748+
function randomize(arr) {
1749+
for (let i = arr.length - 1; i > 0; i--) {
1750+
let j = Math.floor(Math.random() * (i + 1));
1751+
[arr[i], arr[j]] = [arr[j], arr[i]];
1752+
}
1753+
return arr;
1754+
}
1755+
1756+
const App = ({ items }) => (
1757+
<div>
1758+
{items.map(key => (
1759+
<div key={key}>{key}</div>
1760+
))}
1761+
</div>
1762+
);
1763+
1764+
const a = ['0', '2', '7', '6', '1', '3', '5', '4'];
1765+
const b = ['1', '0', '6', '7', '5', '2', '4', '3'];
1766+
const c = ['0', '7', '2', '1', '3', '5', '6', '4'];
1767+
1768+
render(<App items={a} />, scratch);
1769+
expect(scratch.innerHTML).to.equal(
1770+
`<div>${a.map(n => `<div>${n}</div>`).join('')}</div>`
1771+
);
1772+
1773+
render(<App items={b} />, scratch);
1774+
expect(scratch.innerHTML).to.equal(
1775+
`<div>${b.map(n => `<div>${n}</div>`).join('')}</div>`
1776+
);
1777+
1778+
render(<App items={c} />, scratch);
1779+
expect(scratch.innerHTML).to.equal(
1780+
`<div>${c.map(n => `<div>${n}</div>`).join('')}</div>`
1781+
);
1782+
});
1783+
1784+
it('handle shuffled (stress test)', () => {
1785+
function randomize(arr) {
1786+
for (let i = arr.length - 1; i > 0; i--) {
1787+
let j = Math.floor(Math.random() * (i + 1));
1788+
[arr[i], arr[j]] = [arr[j], arr[i]];
1789+
}
1790+
return arr;
1791+
}
1792+
1793+
const App = ({ items }) => (
1794+
<div>
1795+
{items.map(key => (
1796+
<div key={key}>{key}</div>
1797+
))}
1798+
</div>
1799+
);
1800+
1801+
const a = Array.from({ length: 8 }).map((_, i) => `${i}`);
1802+
1803+
for (let i = 0; i < 10000; i++) {
1804+
const aa = randomize(a);
1805+
render(<App items={aa} />, scratch);
1806+
expect(scratch.innerHTML).to.equal(
1807+
`<div>${aa.map(n => `<div>${n}</div>`).join('')}</div>`
1808+
);
1809+
}
1810+
});
17461811
});

0 commit comments

Comments
 (0)