From a003f3a0b9ea13624de3d863b1553aa957e984be Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Sat, 22 Jul 2017 22:37:05 -0700 Subject: [PATCH] Error if duplicate keys are present --- packages/diffhtml/lib/tree/sync.js | 6 ++++++ packages/diffhtml/test/tree.js | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/packages/diffhtml/lib/tree/sync.js b/packages/diffhtml/lib/tree/sync.js index 90748d49..6f71b58b 100644 --- a/packages/diffhtml/lib/tree/sync.js +++ b/packages/diffhtml/lib/tree/sync.js @@ -44,6 +44,12 @@ export default function syncTree(oldTree, newTree, patches, parentTree, specialC const vTree = nodes[i]; if (vTree.key) { + if (process.env.NODE_ENV !== 'production') { + if (map.has(vTree.key)) { + throw new Error(`Key: ${vTree.key} cannot be duplicated`); + } + } + map.set(vTree.key, vTree); } } diff --git a/packages/diffhtml/test/tree.js b/packages/diffhtml/test/tree.js index 6e51fbb2..5ce55bab 100644 --- a/packages/diffhtml/test/tree.js +++ b/packages/diffhtml/test/tree.js @@ -750,6 +750,31 @@ describe('Tree', function() { }); describe('Elements (keyed)', () => { + it('will error if duplicate keys are provided in development', () => { + const referenceNode = createTree('div', { key: '0' }); + const duplicateNode = createTree('div', { key: '0' }); + const oldTree = createTree('div', null, [referenceNode]); + const newTree = createTree('div', null, [ + referenceNode, + duplicateNode, + ]); + + throws(() => syncTree(oldTree, newTree)); + }); + + it('will not error if duplicate keys are provided in production', () => { + const referenceNode = createTree('div', { key: '0' }); + const duplicateNode = createTree('div', { key: '0' }); + const oldTree = createTree('div', null, [referenceNode]); + const newTree = createTree('div', null, [ + referenceNode, + duplicateNode, + ]); + + process.env.NODE_ENV = 'production'; + doesNotThrow(() => syncTree(oldTree, newTree)); + }); + describe('insertBefore', () => { it('will prepend an element', () => { const referenceNode = createTree('div', { key: '0' });