mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Assert when duplicated keys are introduced in subsequent build (#81850)
This commit is contained in:
parent
6849e4b7e9
commit
3ab799bbc9
|
@ -6304,6 +6304,7 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
|
|||
void update(MultiChildRenderObjectWidget newWidget) {
|
||||
super.update(newWidget);
|
||||
assert(widget == newWidget);
|
||||
assert(!debugChildrenHaveDuplicateKeys(widget, widget.children));
|
||||
_children = updateChildren(_children, widget.children, forgottenChildren: _forgottenChildren);
|
||||
_forgottenChildren.clear();
|
||||
}
|
||||
|
|
|
@ -512,11 +512,9 @@ void main() {
|
|||
expect(
|
||||
exception.toString(),
|
||||
equalsIgnoringHashCodes(
|
||||
'Multiple widgets used the same GlobalKey.\n'
|
||||
'The key [GlobalKey#00000 problematic] was used by 2 widgets:\n'
|
||||
' SizedBox-[GlobalKey#00000 problematic]\n'
|
||||
' Placeholder-[GlobalKey#00000 problematic]\n'
|
||||
'A GlobalKey can only be specified on one widget at a time in the widget tree.',
|
||||
'Duplicate keys found.\n'
|
||||
'If multiple keyed nodes exist as children of another node, they must have unique keys.\n'
|
||||
'Stack(alignment: AlignmentDirectional.topStart, textDirection: ltr, fit: loose) has multiple children with key [GlobalKey#00000 problematic].'
|
||||
),
|
||||
);
|
||||
});
|
||||
|
@ -541,11 +539,9 @@ void main() {
|
|||
expect(
|
||||
exception.toString(),
|
||||
equalsIgnoringHashCodes(
|
||||
'Multiple widgets used the same GlobalKey.\n'
|
||||
'The key [GlobalKey#00000 problematic] was used by 2 widgets:\n'
|
||||
' Container-[GlobalKey#00000 problematic]\n'
|
||||
' Placeholder-[GlobalKey#00000 problematic]\n'
|
||||
'A GlobalKey can only be specified on one widget at a time in the widget tree.',
|
||||
'Duplicate keys found.\n'
|
||||
'If multiple keyed nodes exist as children of another node, they must have unique keys.\n'
|
||||
'Stack(alignment: AlignmentDirectional.topStart, textDirection: ltr, fit: loose) has multiple children with key [GlobalKey#00000 problematic].'
|
||||
),
|
||||
);
|
||||
});
|
||||
|
|
|
@ -58,6 +58,57 @@ void main() {
|
|||
<String>['0', '6', '7', '8', '1', '2', '3', '4', '5'],
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Building a new MultiChildRenderObjectElement with children having duplicated keys throws', (WidgetTester tester) async {
|
||||
const ValueKey<int> duplicatedKey = ValueKey<int>(1);
|
||||
|
||||
await tester.pumpWidget(Column(
|
||||
children: const <Widget>[
|
||||
Text('Text 1', textDirection: TextDirection.ltr, key: duplicatedKey),
|
||||
Text('Text 2', textDirection: TextDirection.ltr, key: duplicatedKey),
|
||||
],
|
||||
));
|
||||
|
||||
expect(
|
||||
tester.takeException(),
|
||||
isA<FlutterError>().having(
|
||||
(FlutterError error) => error.message,
|
||||
'error.message',
|
||||
startsWith('Duplicate keys found.'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Updating a MultiChildRenderObjectElement to have children with duplicated keys throws', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/81541
|
||||
|
||||
const ValueKey<int> key1 = ValueKey<int>(1);
|
||||
const ValueKey<int> key2 = ValueKey<int>(2);
|
||||
|
||||
Future<void> _buildWithKey(Key key) {
|
||||
return tester.pumpWidget(Column(
|
||||
children: <Widget>[
|
||||
const Text('Text 1', textDirection: TextDirection.ltr, key: key1),
|
||||
Text('Text 2', textDirection: TextDirection.ltr, key: key),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
// Initial build with two different keys.
|
||||
await _buildWithKey(key2);
|
||||
expect(tester.takeException(), isNull);
|
||||
|
||||
// Subsequent build with duplicated keys.
|
||||
await _buildWithKey(key1);
|
||||
expect(
|
||||
tester.takeException(),
|
||||
isA<FlutterError>().having(
|
||||
(FlutterError error) => error.message,
|
||||
'error.message',
|
||||
startsWith('Duplicate keys found.'),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Do not use tester.renderObjectList(find.byType(RenderParagraph). That returns
|
||||
|
|
Loading…
Reference in a new issue