Stricter key clash detection. Fixes #12691 (#12837)

This commit is contained in:
Steve Sanderson 2019-08-02 22:16:47 +01:00 committed by GitHub
parent c15f1e145f
commit 8a1cf8386f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 5 deletions

View File

@ -99,6 +99,10 @@ namespace Microsoft.AspNetCore.Components.RenderTree
if (oldKey != null || newKey != null)
{
#region "Get diff action by matching on key"
// Regardless of whether these two keys match, since you are using keys, we want to validate at this point that there are no clashes
// so ensure we've built the dictionary that will be used for lookups if any don't match
keyedItemInfos ??= BuildKeyToInfoLookup(diffContext, origOldStartIndex, oldEndIndexExcl, origNewStartIndex, newEndIndexExcl);
if (Equals(oldKey, newKey))
{
// Keys match
@ -108,11 +112,6 @@ namespace Microsoft.AspNetCore.Components.RenderTree
else
{
// Keys don't match
if (keyedItemInfos == null)
{
keyedItemInfos = BuildKeyToInfoLookup(diffContext, origOldStartIndex, oldEndIndexExcl, origNewStartIndex, newEndIndexExcl);
}
var oldKeyItemInfo = oldKey != null ? keyedItemInfos[oldKey] : new KeyedItemInfo(-1, -1);
var newKeyItemInfo = newKey != null ? keyedItemInfos[newKey] : new KeyedItemInfo(-1, -1);
var oldKeyIsInNewTree = oldKeyItemInfo.NewIndex >= 0;

View File

@ -360,6 +360,23 @@ namespace Microsoft.AspNetCore.Components.Test
Assert.Equal("More than one sibling has the same key value, 'key1'. Key values must be unique.", ex.Message);
}
[Fact]
public void RejectsClashingKeysEvenIfAllPairsMatch()
{
// This sort of scenario would happen if you accidentally used a constant value for @key
// Arrange
AddWithKey(oldTree, "key1", "attrib1a");
AddWithKey(oldTree, "key1", "attrib1b");
AddWithKey(newTree, "key1", "attrib1a");
AddWithKey(newTree, "key1", "attrib1b");
// Act/Assert
var ex = Assert.Throws<InvalidOperationException>(() => GetSingleUpdatedComponent());
Assert.Equal("More than one sibling has the same key value, 'key1'. Key values must be unique.", ex.Message);
}
[Fact]
public void HandlesInsertionOfUnkeyedItemsAroundKey()
{