Skip to content

Commit

Permalink
Merge pull request #4287 from preactjs/reconcile-test
Browse files Browse the repository at this point in the history
chore: add reconcile bug test
  • Loading branch information
marvinhagemeister authored Feb 22, 2024
2 parents 5b6a62e + 0435d0c commit ea75640
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/diff/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,11 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
if (remainingOldChildren > newChildrenLength - skewedIndex) {
skew += matchingIndex - skewedIndex;
} else {
// ### Change from keyed: I think this was missing from the algo...
skew--;
}
} else if (matchingIndex < skewedIndex) {
if (matchingIndex == skewedIndex - 1) {
skew = matchingIndex - skewedIndex;
} else {
skew = 0;
}
} else {
skew = 0;
Expand Down Expand Up @@ -429,7 +426,10 @@ function findMatchingIndex(

if (
oldVNode === null ||
(oldVNode && key == oldVNode.key && type === oldVNode.type)
(oldVNode &&
key == oldVNode.key &&
type === oldVNode.type &&
(oldVNode._flags & MATCHED) === 0)
) {
return skewedIndex;
} else if (shouldSearch) {
Expand Down
127 changes: 127 additions & 0 deletions test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,133 @@ describe('render()', () => {
expect(scratch.innerHTML).to.equal('<div><div></div><div>B</div></div>');
});

it('should reconcile children in right order', () => {
let data = ['A', 'B', 'C', 'D', 'E'];
render(
<ul>
{data.map(d => (
<li key={d}>{d}</li>
))}
</ul>,
scratch
);

expect(scratch.textContent).to.equal('ABCDE');

data = ['B', 'E', 'C', 'D'];
render(
<ul>
{data.map(d => (
<li key={d}>{d}</li>
))}
</ul>,
scratch
);
expect(scratch.textContent).to.equal('BECD');
});

it('should reconcile children in right order #2', () => {
let data = ['A', 'B', 'C', 'D', 'E'];
render(
<ul>
{data.map(d => (
<li key={d}>{d}</li>
))}
</ul>,
scratch
);

expect(scratch.textContent).to.equal('ABCDE');

data = ['B', 'E', 'D', 'C'];
render(
<ul>
{data.map(d => (
<li key={d}>{d}</li>
))}
</ul>,
scratch
);
expect(scratch.textContent).to.equal('BEDC');
});

it('should reconcile children in right order #3', () => {
render(
<div>
<p>_A1</p>
<p>_A2</p>
<h2>_A3</h2>
<p>_A4</p>
<h2>_A5</h2>
<p>_A6</p>
<h2>_A7</h2>
<p>_A8</p>
</div>,
scratch
);

render(
<div>
<p>_B1</p>
<p>_B2</p>
<p>_B3</p>
<h2>_B4</h2>
<p>_B5</p>
<p>_B6</p>
<h2>_B7</h2>
<p>_B8</p>
</div>,
scratch
);

expect(serializeHtml(scratch)).to.equal(
'<div><p>_B1</p><p>_B2</p><p>_B3</p><h2>_B4</h2><p>_B5</p><p>_B6</p><h2>_B7</h2><p>_B8</p></div>'
);
});

it('should reconcile children in right order #4', () => {
render(
<div>
<p>_A1</p>
<p>_A2</p>
<div>_A3</div>
<h2>_A4</h2>
<p>_A5</p>
<div>_A6</div>
<h2>_A7</h2>
<p>_A8</p>
<div>_A9</div>
<h2>_A10</h2>
<p>_A11</p>
<div>_A12</div>
</div>,
scratch
);

render(
<div>
<p>_B1</p>
<p>_B2</p>
<p>_B3</p>
<h2>_B4</h2>
<p>_B5</p>
<p>_B6</p>
<p>_B7</p>
<h2>_B8</h2>
<p>_B9</p>
<p>_B10</p>
<p>_B11</p>
<p>_B12</p>
<h2>_B13</h2>
</div>,
scratch
);

expect(serializeHtml(scratch)).to.equal(
'<div><p>_B1</p><p>_B2</p><p>_B3</p><h2>_B4</h2><p>_B5</p><p>_B6</p><p>_B7</p><h2>_B8</h2><p>_B9</p><p>_B10</p><p>_B11</p><p>_B12</p><h2>_B13</h2></div>'
);
});

it('should not crash or repeatedly add the same child when replacing a matched vnode with null (mixed dom-types)', () => {
const B = () => <div>B</div>;

Expand Down

0 comments on commit ea75640

Please sign in to comment.