From 1bfa2f0a150b52e31cd0ab22dfff0a845619f404 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 28 Dec 2024 18:20:51 -0800 Subject: [PATCH 1/4] Fix a type error that occurs comparing two large maps with deepEquals. --- pkgs/checks/lib/src/describe.dart | 6 ++- pkgs/checks/test/extensions/map_test.dart | 59 +++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/pkgs/checks/lib/src/describe.dart b/pkgs/checks/lib/src/describe.dart index f05a1640b..ab0b2898b 100644 --- a/pkgs/checks/lib/src/describe.dart +++ b/pkgs/checks/lib/src/describe.dart @@ -72,7 +72,11 @@ Iterable _prettyPrint( Iterable _prettyPrintCollection( String open, String close, List> elements, int maxLength) { if (elements.length > _maxItems) { - elements.replaceRange(_maxItems - 1, elements.length, [ + // Force inference as List, otherwise the type is + // List> which ends up as a type error in dart:collection + // when the underlying list is actually a List>. See + // https://github.com/dart-lang/test/issues/2441 for more details. + elements.replaceRange(_maxItems - 1, elements.length, >[ ['...'] ]); } diff --git a/pkgs/checks/test/extensions/map_test.dart b/pkgs/checks/test/extensions/map_test.dart index cb3e3e493..6cc3f5064 100644 --- a/pkgs/checks/test/extensions/map_test.dart +++ b/pkgs/checks/test/extensions/map_test.dart @@ -29,6 +29,65 @@ void main() { test('values', () { check(_testMap).values.contains(1); }); + test('can be described failing compared to another large map', () { + const expected = { + 1: -5, + 2: -4, + 3: -4, + 4: -3, + 5: -3, + 6: -2, + 7: -2, + 8: -1, + 9: -1, + 10: 0, + 11: 0, + 12: 1, + 13: 1, + 14: 2, + 15: 2, + 16: 3, + 17: 3, + 18: 4, + 19: 4, + 20: 5, + 21: 5, + 22: 6, + 23: 6, + 24: 7, + 25: 7, + 26: 8, + }; + final actual = { + 1: -4, + 2: -4, + 3: -3, + 4: -3, + 5: -2, + 6: -2, + 7: -1, + 8: -1, + 9: 0, + 10: 0, + 11: 0, + 12: 1, + 13: 1, + 14: 2, + 15: 2, + 16: 3, + 17: 3, + 18: 4, + 19: 4, + 20: 5, + 21: 5, + 22: 6, + 23: 6, + 24: 7, + 25: 7, + 26: 8, + }; + check(actual).not((a) => a.deepEquals(expected)); + }); group('operator []', () { test('succeeds for a key that exists', () { From bf27c199258488430550d1a5b63eda6330f03573 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 28 Dec 2024 18:32:33 -0800 Subject: [PATCH 2/4] Update CHANGELOG, I think. --- pkgs/checks/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/checks/CHANGELOG.md b/pkgs/checks/CHANGELOG.md index 6588352e9..52f4c3e78 100644 --- a/pkgs/checks/CHANGELOG.md +++ b/pkgs/checks/CHANGELOG.md @@ -8,6 +8,8 @@ - Add `containsMatchingInOrder` and `containsEqualInOrder` to replace the combined functionality in `containsInOrder`. - Replace `pairwiseComparesTo` with `pairwiseMatches`. +- Fix a bug where printing the result of a failed deep quality check would + fail with a `TypeError` when comparing large `Map` instances - Increase SDK constraint to ^3.5.0. ## 0.3.0 From de0079aa30c2181a0c5caf95f294d1759a09665e Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 14 Jan 2025 21:01:31 +0000 Subject: [PATCH 3/4] Use a const list, test the literal function directly Use a separate const list so the inference does not use the argument context. Add a test for specifically pretty printing large collections. Remove the test that indirectly tested the behavior. --- pkgs/checks/lib/src/describe.dart | 9 ++-- pkgs/checks/test/extensions/map_test.dart | 59 ----------------------- pkgs/checks/test/pretty_print_test.dart | 30 ++++++++++++ 3 files changed, 33 insertions(+), 65 deletions(-) create mode 100644 pkgs/checks/test/pretty_print_test.dart diff --git a/pkgs/checks/lib/src/describe.dart b/pkgs/checks/lib/src/describe.dart index ab0b2898b..79a4ea110 100644 --- a/pkgs/checks/lib/src/describe.dart +++ b/pkgs/checks/lib/src/describe.dart @@ -72,13 +72,10 @@ Iterable _prettyPrint( Iterable _prettyPrintCollection( String open, String close, List> elements, int maxLength) { if (elements.length > _maxItems) { - // Force inference as List, otherwise the type is - // List> which ends up as a type error in dart:collection - // when the underlying list is actually a List>. See - // https://github.com/dart-lang/test/issues/2441 for more details. - elements.replaceRange(_maxItems - 1, elements.length, >[ + const ellipseElement = [ ['...'] - ]); + ]; + elements.replaceRange(_maxItems - 1, elements.length, ellipseElement); } if (elements.every((e) => e.length == 1)) { final singleLine = '$open${elements.map((e) => e.single).join(', ')}$close'; diff --git a/pkgs/checks/test/extensions/map_test.dart b/pkgs/checks/test/extensions/map_test.dart index 6cc3f5064..cb3e3e493 100644 --- a/pkgs/checks/test/extensions/map_test.dart +++ b/pkgs/checks/test/extensions/map_test.dart @@ -29,65 +29,6 @@ void main() { test('values', () { check(_testMap).values.contains(1); }); - test('can be described failing compared to another large map', () { - const expected = { - 1: -5, - 2: -4, - 3: -4, - 4: -3, - 5: -3, - 6: -2, - 7: -2, - 8: -1, - 9: -1, - 10: 0, - 11: 0, - 12: 1, - 13: 1, - 14: 2, - 15: 2, - 16: 3, - 17: 3, - 18: 4, - 19: 4, - 20: 5, - 21: 5, - 22: 6, - 23: 6, - 24: 7, - 25: 7, - 26: 8, - }; - final actual = { - 1: -4, - 2: -4, - 3: -3, - 4: -3, - 5: -2, - 6: -2, - 7: -1, - 8: -1, - 9: 0, - 10: 0, - 11: 0, - 12: 1, - 13: 1, - 14: 2, - 15: 2, - 16: 3, - 17: 3, - 18: 4, - 19: 4, - 20: 5, - 21: 5, - 22: 6, - 23: 6, - 24: 7, - 25: 7, - 26: 8, - }; - check(actual).not((a) => a.deepEquals(expected)); - }); group('operator []', () { test('succeeds for a key that exists', () { diff --git a/pkgs/checks/test/pretty_print_test.dart b/pkgs/checks/test/pretty_print_test.dart new file mode 100644 index 000000000..63f1cc147 --- /dev/null +++ b/pkgs/checks/test/pretty_print_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:checks/checks.dart'; +import 'package:checks/context.dart'; +import 'package:test/scaffolding.dart'; + +void main() { + group('literal', () { + group('truncates large collections', () { + const maxUntruncatedCollection = 25; + final largeList = + List.generate(maxUntruncatedCollection + 1, (i) => i); + test('in lists', () { + check(literal(largeList)).last.equals('...]'); + }); + test('in sets', () { + check(literal(largeList.toSet())).last.equals('...}'); + }); + test('in iterables', () { + check(literal(largeList.followedBy([]))).last.equals('...)'); + }); + test('in maps', () { + final map = Map.fromIterables(largeList, largeList); + check(literal(map)).last.equals('...}'); + }); + }); + }); +} From 2104b7d78cdff2f283e7e5d98754571bed357e70 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 14 Jan 2025 21:17:25 +0000 Subject: [PATCH 4/4] Fix spelling error ellipse -> ellipsis --- pkgs/checks/lib/src/describe.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/checks/lib/src/describe.dart b/pkgs/checks/lib/src/describe.dart index 79a4ea110..910e4c3e4 100644 --- a/pkgs/checks/lib/src/describe.dart +++ b/pkgs/checks/lib/src/describe.dart @@ -72,10 +72,10 @@ Iterable _prettyPrint( Iterable _prettyPrintCollection( String open, String close, List> elements, int maxLength) { if (elements.length > _maxItems) { - const ellipseElement = [ + const ellipsisElement = [ ['...'] ]; - elements.replaceRange(_maxItems - 1, elements.length, ellipseElement); + elements.replaceRange(_maxItems - 1, elements.length, ellipsisElement); } if (elements.every((e) => e.length == 1)) { final singleLine = '$open${elements.map((e) => e.single).join(', ')}$close';