From 2b1c4a562bb3cee5515f78c659a8f874d959a00a Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Wed, 27 Jul 2022 16:06:51 -0700 Subject: [PATCH 1/3] Update equalsIgnoringHashCodes to take a list of Strings --- .../test/material/checkbox_theme_test.dart | 19 ++++--- .../flutter/test/material/list_tile_test.dart | 53 ++++++++++--------- .../test/material/list_tile_theme_test.dart | 34 ++++++------ .../test/material/radio_theme_test.dart | 17 +++--- .../flutter/test/widgets/actions_test.dart | 15 ++++-- packages/flutter_test/lib/src/matchers.dart | 44 ++++++++++----- packages/flutter_test/test/matchers_test.dart | 16 +++++- 7 files changed, 127 insertions(+), 71 deletions(-) diff --git a/packages/flutter/test/material/checkbox_theme_test.dart b/packages/flutter/test/material/checkbox_theme_test.dart index c180dacc15540..b57ce852e9f64 100644 --- a/packages/flutter/test/material/checkbox_theme_test.dart +++ b/packages/flutter/test/material/checkbox_theme_test.dart @@ -64,13 +64,18 @@ void main() { .map((DiagnosticsNode node) => node.toString()) .toList(); - expect(description[0], 'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(click))'); - expect(description[1], 'fillColor: MaterialStatePropertyAll(Color(0xfffffff0))'); - expect(description[2], 'checkColor: MaterialStatePropertyAll(Color(0xfffffff1))'); - expect(description[3], 'overlayColor: MaterialStatePropertyAll(Color(0xfffffff2))'); - expect(description[4], 'splashRadius: 1.0'); - expect(description[5], 'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap'); - expect(description[6], equalsIgnoringHashCodes('visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)')); + expect( + description, + equalsIgnoringHashCodes([ + 'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(click))', + 'fillColor: MaterialStatePropertyAll(Color(0xfffffff0))', + 'checkColor: MaterialStatePropertyAll(Color(0xfffffff1))', + 'overlayColor: MaterialStatePropertyAll(Color(0xfffffff2))', + 'splashRadius: 1.0', + 'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap', + 'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)', + ]), + ); }); testWidgets('Checkbox is themeable', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/list_tile_test.dart b/packages/flutter/test/material/list_tile_test.dart index e54352736245a..8aaca6f211177 100644 --- a/packages/flutter/test/material/list_tile_test.dart +++ b/packages/flutter/test/material/list_tile_test.dart @@ -2276,30 +2276,35 @@ void main() { .map((DiagnosticsNode node) => node.toString()) .toList(); - expect(description[0], 'leading: Text'); - expect(description[1], 'title: Text'); - expect(description[2], 'subtitle: Text'); - expect(description[3], 'trailing: Text'); - expect(description[4], 'isThreeLine: THREE_LINE'); - expect(description[5], 'dense: true'); - expect(description[6], equalsIgnoringHashCodes('visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)')); - expect(description[7], 'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)'); - expect(description[8], 'style: ListTileStyle.list'); - expect(description[9], 'selectedColor: Color(0xff0000ff)'); - expect(description[10], 'iconColor: Color(0xff00ff00)'); - expect(description[11], 'textColor: Color(0xffff0000)'); - expect(description[12], 'contentPadding: EdgeInsets.zero'); - expect(description[13], 'enabled: false'); - expect(description[14], 'selected: true'); - expect(description[15], 'focusColor: Color(0xff00ffff)'); - expect(description[16], 'hoverColor: Color(0xff0000ff)'); - expect(description[17], 'autofocus: true'); - expect(description[18], 'tileColor: Color(0xffffff00)'); - expect(description[19], 'selectedTileColor: Color(0xff123456)'); - expect(description[20], 'enableFeedback: false'); - expect(description[21], 'horizontalTitleGap: 4.0'); - expect(description[22], 'minVerticalPadding: 2.0'); - expect(description[23], 'minLeadingWidth: 6.0'); + expect( + description, + equalsIgnoringHashCodes([ + 'leading: Text', + 'title: Text', + 'subtitle: Text', + 'trailing: Text', + 'isThreeLine: THREE_LINE', + 'dense: true', + 'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)', + 'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)', + 'style: ListTileStyle.list', + 'selectedColor: Color(0xff0000ff)', + 'iconColor: Color(0xff00ff00)', + 'textColor: Color(0xffff0000)', + 'contentPadding: EdgeInsets.zero', + 'enabled: false', + 'selected: true', + 'focusColor: Color(0xff00ffff)', + 'hoverColor: Color(0xff0000ff)', + 'autofocus: true', + 'tileColor: Color(0xffffff00)', + 'selectedTileColor: Color(0xff123456)', + 'enableFeedback: false', + 'horizontalTitleGap: 4.0', + 'minVerticalPadding: 2.0', + 'minLeadingWidth: 6.0', + ]), + ); }); group('Material 2', () { diff --git a/packages/flutter/test/material/list_tile_theme_test.dart b/packages/flutter/test/material/list_tile_theme_test.dart index 5a64101e76fc8..bed87072fdeec 100644 --- a/packages/flutter/test/material/list_tile_theme_test.dart +++ b/packages/flutter/test/material/list_tile_theme_test.dart @@ -107,23 +107,25 @@ void main() { .map((DiagnosticsNode node) => node.toString()) .toList(); - expect(description[0], 'dense: true'); - expect(description[1], 'shape: StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none))'); - expect(description[2], 'style: drawer'); - expect(description[3], 'selectedColor: Color(0x00000001)'); - expect(description[4], 'iconColor: Color(0x00000002)'); - expect(description[5], 'textColor: Color(0x00000003)'); - expect(description[6], 'contentPadding: EdgeInsets.all(100.0)'); - expect(description[7], 'tileColor: Color(0x00000004)'); - expect(description[8], 'selectedTileColor: Color(0x00000005)'); - expect(description[9], 'horizontalTitleGap: 200.0'); - expect(description[10], 'minVerticalPadding: 300.0'); - expect(description[11], 'minLeadingWidth: 400.0'); - expect(description[12], 'enableFeedback: true'); - expect(description[13], 'mouseCursor: MaterialStateMouseCursor(clickable)'); expect( - description[14], - equalsIgnoringHashCodes('visualDensity: VisualDensity#00000(h: -1.0, v: -1.0)(horizontal: -1.0, vertical: -1.0)'), + description, + equalsIgnoringHashCodes([ + 'dense: true', + 'shape: StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none))', + 'style: drawer', + 'selectedColor: Color(0x00000001)', + 'iconColor: Color(0x00000002)', + 'textColor: Color(0x00000003)', + 'contentPadding: EdgeInsets.all(100.0)', + 'tileColor: Color(0x00000004)', + 'selectedTileColor: Color(0x00000005)', + 'horizontalTitleGap: 200.0', + 'minVerticalPadding: 300.0', + 'minLeadingWidth: 400.0', + 'enableFeedback: true', + 'mouseCursor: MaterialStateMouseCursor(clickable)', + 'visualDensity: VisualDensity#00000(h: -1.0, v: -1.0)(horizontal: -1.0, vertical: -1.0)', + ]), ); }); diff --git a/packages/flutter/test/material/radio_theme_test.dart b/packages/flutter/test/material/radio_theme_test.dart index f3a5f76e501bf..ab53ff8c88941 100644 --- a/packages/flutter/test/material/radio_theme_test.dart +++ b/packages/flutter/test/material/radio_theme_test.dart @@ -61,12 +61,17 @@ void main() { .map((DiagnosticsNode node) => node.toString()) .toList(); - expect(description[0], 'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(click))'); - expect(description[1], 'fillColor: MaterialStatePropertyAll(Color(0xfffffff0))'); - expect(description[2], 'overlayColor: MaterialStatePropertyAll(Color(0xfffffff1))'); - expect(description[3], 'splashRadius: 1.0'); - expect(description[4], 'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap'); - expect(description[5], equalsIgnoringHashCodes('visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)')); + expect( + description, + equalsIgnoringHashCodes([ + 'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(click))', + 'fillColor: MaterialStatePropertyAll(Color(0xfffffff0))', + 'overlayColor: MaterialStatePropertyAll(Color(0xfffffff1))', + 'splashRadius: 1.0', + 'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap', + 'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)', + ]), + ); }); testWidgets('Radio is themeable', (WidgetTester tester) async { diff --git a/packages/flutter/test/widgets/actions_test.dart b/packages/flutter/test/widgets/actions_test.dart index 24d1f6fbb8b24..ae2a4750e5ffd 100644 --- a/packages/flutter/test/widgets/actions_test.dart +++ b/packages/flutter/test/widgets/actions_test.dart @@ -1009,8 +1009,10 @@ void main() { .toList(); expect(description.length, equals(2)); - expect(description[0], equalsIgnoringHashCodes('dispatcher: ActionDispatcher#00000')); - expect(description[1], equals('actions: {}')); + expect( + description, + equalsIgnoringHashCodes(['dispatcher: ActionDispatcher#00000', 'actions: {}']), + ); }); testWidgets('Actions implements debugFillProperties', (WidgetTester tester) async { final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); @@ -1032,8 +1034,13 @@ void main() { .toList(); expect(description.length, equals(2)); - expect(description[0], equalsIgnoringHashCodes('dispatcher: ActionDispatcher#00000')); - expect(description[1], equalsIgnoringHashCodes('actions: {TestIntent: TestAction#00000}')); + expect( + description, + equalsIgnoringHashCodes([ + 'dispatcher: ActionDispatcher#00000', + 'actions: {TestIntent: TestAction#00000}', + ]), + ); }); }); diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart index cb9932f894e8a..89ec460bce5d3 100644 --- a/packages/flutter_test/lib/src/matchers.dart +++ b/packages/flutter_test/lib/src/matchers.dart @@ -292,7 +292,8 @@ Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTo return _IsWithinDistance(_offsetDistance, value, epsilon); } -/// Asserts that two [String]s are equal after normalizing likely hash codes. +/// Asserts that two [String]s or `Iterable`s are equal after +/// normalizing likely hash codes. /// /// A `#` followed by 5 hexadecimal digits is assumed to be a short hash code /// and is normalized to `#00000`. @@ -305,7 +306,7 @@ Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTo /// [String] based on [Object.hashCode]. /// * [DiagnosticableTree.toStringDeep], a method that returns a [String] /// typically containing multiple hash codes. -Matcher equalsIgnoringHashCodes(String value) { +Matcher equalsIgnoringHashCodes(Object value) { return _EqualsIgnoringHashCodes(value); } @@ -1056,21 +1057,35 @@ class _HasOneLineDescription extends Matcher { } class _EqualsIgnoringHashCodes extends Matcher { - _EqualsIgnoringHashCodes(String v) : _value = _normalize(v); + _EqualsIgnoringHashCodes(Object v) : _value = _normalize(v); - final String _value; + final Object _value; static final Object _mismatchedValueKey = Object(); - static String _normalize(String s) { - return s.replaceAll(RegExp(r'#[0-9a-fA-F]{5}'), '#00000'); + static String _normalizeString(String value) { + return value.replaceAll(RegExp(r'#[\da-fA-F]{5}'), '#00000'); + } + + static Object _normalize(Object value, {bool expected = true}) { + if (value is String) { + return _normalizeString(value); + } + if (value is Iterable) { + return value.map((dynamic item) => _normalizeString(item.toString())); + } + throw ArgumentError( + 'The specified ${expected ? 'expected' : 'comparison'} value for ' + 'equalsIgnoringHashCodes must be a String or an Iterable, ' + 'not a ${value.runtimeType}' + ); } @override bool matches(dynamic object, Map matchState) { - final String description = _normalize(object as String); - if (_value != description) { - matchState[_mismatchedValueKey] = description; + final Object normalized = _normalize(object as Object, expected: false); + if (!equals(_value).matches(normalized, matchState)) { + matchState[_mismatchedValueKey] = normalized; return false; } return true; @@ -1078,7 +1093,10 @@ class _EqualsIgnoringHashCodes extends Matcher { @override Description describe(Description description) { - return description.add('multi line description equals $_value'); + if (_value is String) { + return description.add('normalized value matches $_value'); + } + return description.add('normalized value matches\n').addDescriptionOf(_value); } @override @@ -1089,14 +1107,14 @@ class _EqualsIgnoringHashCodes extends Matcher { bool verbose, ) { if (matchState.containsKey(_mismatchedValueKey)) { - final String actualValue = matchState[_mismatchedValueKey] as String; + final Object actualValue = matchState[_mismatchedValueKey] as Object; // Leading whitespace is added so that lines in the multiline // description returned by addDescriptionOf are all indented equally // which makes the output easier to read for this case. return mismatchDescription - .add('expected normalized value\n ') + .add('was expected to be normalized value\n') .addDescriptionOf(_value) - .add('\nbut got\n ') + .add('\nbut got\n') .addDescriptionOf(actualValue); } return mismatchDescription; diff --git a/packages/flutter_test/test/matchers_test.dart b/packages/flutter_test/test/matchers_test.dart index 5e6f3d7866211..b29deaf541fa5 100644 --- a/packages/flutter_test/test/matchers_test.dart +++ b/packages/flutter_test/test/matchers_test.dart @@ -135,7 +135,7 @@ void main() { ); }); - test('normalizeHashCodesEquals', () { + test('equalsIgnoringHashCodes', () { expect('Foo#34219', equalsIgnoringHashCodes('Foo#00000')); expect('Foo#34219', equalsIgnoringHashCodes('Foo#12345')); expect('Foo#34219', equalsIgnoringHashCodes('Foo#abcdf')); @@ -173,6 +173,20 @@ void main() { expect('Foo#', isNot(equalsIgnoringHashCodes('Foo#00000'))); expect('Foo#3421', isNot(equalsIgnoringHashCodes('Foo#00000'))); expect('Foo#342193', isNot(equalsIgnoringHashCodes('Foo#00000'))); + expect(['Foo#a3b4d'], equalsIgnoringHashCodes(['Foo#12345'])); + expect( + ['Foo#a3b4d', 'Foo#12345'], + equalsIgnoringHashCodes(['Foo#00000', 'Foo#00000']), + ); + expect( + ['Foo#a3b4d', 'Bar#12345'], + equalsIgnoringHashCodes(['Foo#00000', 'Bar#00000']), + ); + expect( + ['Foo#a3b4d', 'Bar#12345'], + isNot(equalsIgnoringHashCodes(['Bar#00000', 'Foo#00000'])), + ); + expect(['Foo#a3b4d'], isNot(equalsIgnoringHashCodes(['Foo']))); }); test('moreOrLessEquals', () { From ef91570ebcc5f01e16f215a1e705cb91987c88d4 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Wed, 3 Aug 2022 11:44:15 -0700 Subject: [PATCH 2/3] Review Changes --- .../flutter/test/widgets/actions_test.dart | 5 +- packages/flutter_test/lib/src/matchers.dart | 218 +++++++++--------- packages/flutter_test/test/matchers_test.dart | 4 + 3 files changed, 116 insertions(+), 111 deletions(-) diff --git a/packages/flutter/test/widgets/actions_test.dart b/packages/flutter/test/widgets/actions_test.dart index ae2a4750e5ffd..26de85156ab87 100644 --- a/packages/flutter/test/widgets/actions_test.dart +++ b/packages/flutter/test/widgets/actions_test.dart @@ -1011,7 +1011,10 @@ void main() { expect(description.length, equals(2)); expect( description, - equalsIgnoringHashCodes(['dispatcher: ActionDispatcher#00000', 'actions: {}']), + equalsIgnoringHashCodes([ + 'dispatcher: ActionDispatcher#00000', + 'actions: {}', + ]), ); }); testWidgets('Actions implements debugFillProperties', (WidgetTester tester) async { diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart index 89ec460bce5d3..35738f31e5bb9 100644 --- a/packages/flutter_test/lib/src/matchers.dart +++ b/packages/flutter_test/lib/src/matchers.dart @@ -248,7 +248,7 @@ TypeMatcher isInstanceOf() => isA(); /// range. /// * [rectMoreOrLessEquals] and [offsetMoreOrLessEquals], which do something /// similar but for [Rect]s and [Offset]s respectively. -Matcher moreOrLessEquals(double value, { double epsilon = precisionErrorTolerance }) { +Matcher moreOrLessEquals(double value, {double epsilon = precisionErrorTolerance}) { return _MoreOrLessEquals(value, epsilon); } @@ -262,7 +262,7 @@ Matcher moreOrLessEquals(double value, { double epsilon = precisionErrorToleranc /// * [offsetMoreOrLessEquals], which is for [Offset]s. /// * [within], which offers a generic version of this functionality that can /// be used to match [Rect]s as well as other types. -Matcher rectMoreOrLessEquals(Rect value, { double epsilon = precisionErrorTolerance }) { +Matcher rectMoreOrLessEquals(Rect value, {double epsilon = precisionErrorTolerance}) { return _IsWithinDistance(_rectDistance, value, epsilon); } @@ -274,7 +274,7 @@ Matcher rectMoreOrLessEquals(Rect value, { double epsilon = precisionErrorTolera /// /// * [moreOrLessEquals], which is for [double]s. /// * [offsetMoreOrLessEquals], which is for [Offset]s. -Matcher matrixMoreOrLessEquals(Matrix4 value, { double epsilon = precisionErrorTolerance }) { +Matcher matrixMoreOrLessEquals(Matrix4 value, {double epsilon = precisionErrorTolerance}) { return _IsWithinDistance(_matrixDistance, value, epsilon); } @@ -288,7 +288,7 @@ Matcher matrixMoreOrLessEquals(Matrix4 value, { double epsilon = precisionErrorT /// * [rectMoreOrLessEquals], which is for [Rect]s. /// * [within], which offers a generic version of this functionality that can /// be used to match [Offset]s as well as other types. -Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTolerance }) { +Matcher offsetMoreOrLessEquals(Offset value, {double epsilon = precisionErrorTolerance}) { return _IsWithinDistance(_offsetDistance, value, epsilon); } @@ -298,6 +298,8 @@ Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTo /// A `#` followed by 5 hexadecimal digits is assumed to be a short hash code /// and is normalized to `#00000`. /// +/// Only [String] or `Iterable` are allowed types for `value`. +/// /// See Also: /// /// * [describeIdentity], a method that generates short descriptions of objects @@ -307,6 +309,7 @@ Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTo /// * [DiagnosticableTree.toStringDeep], a method that returns a [String] /// typically containing multiple hash codes. Matcher equalsIgnoringHashCodes(Object value) { + assert(value is String || value is Iterable, "Only String or Iterable are allowed types for equalsIgnoringHashCodes, it doesn't accept ${value.runtimeType}"); return _EqualsIgnoringHashCodes(value); } @@ -314,7 +317,7 @@ Matcher equalsIgnoringHashCodes(Object value) { /// method [name] and [arguments]. /// /// Arguments checking implements deep equality for [List] and [Map] types. -Matcher isMethodCall(String name, { required dynamic arguments }) { +Matcher isMethodCall(String name, {required dynamic arguments}) { return _IsMethodCall(name, arguments); } @@ -327,8 +330,8 @@ Matcher isMethodCall(String name, { required dynamic arguments }) { /// When using this matcher you typically want to use a rectangle larger than /// the area you expect to paint in for [areaToCompare] to catch errors where /// the path draws outside the expected area. -Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int sampleSize = 20 }) - => _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize); +Matcher coversSameAreaAs(Path expectedPath, {required Rect areaToCompare, int sampleSize = 20}) => + _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize); /// Asserts that a [Finder], [Future], or [ui.Image] matches the /// golden image file identified by [key], with an optional [version] number. @@ -1046,10 +1049,10 @@ class _HasOneLineDescription extends Matcher { @override bool matches(dynamic object, Map matchState) { final String description = object.toString(); - return description.isNotEmpty - && !description.contains('\n') - && !description.contains('Instance of ') - && description.trim() == description; + return description.isNotEmpty && + !description.contains('\n') && + !description.contains('Instance of ') && + description.trim() == description; } @override @@ -1074,11 +1077,9 @@ class _EqualsIgnoringHashCodes extends Matcher { if (value is Iterable) { return value.map((dynamic item) => _normalizeString(item.toString())); } - throw ArgumentError( - 'The specified ${expected ? 'expected' : 'comparison'} value for ' - 'equalsIgnoringHashCodes must be a String or an Iterable, ' - 'not a ${value.runtimeType}' - ); + throw ArgumentError('The specified ${expected ? 'expected' : 'comparison'} value for ' + 'equalsIgnoringHashCodes must be a String or an Iterable, ' + 'not a ${value.runtimeType}'); } @override @@ -1182,11 +1183,11 @@ class _HasGoodToStringDeep extends Matcher { for (int i = 0; i < lines.length; ++i) { final String line = lines[i]; if (line.isEmpty) { - issues.add('Line ${i+1} is empty.'); + issues.add('Line ${i + 1} is empty.'); } if (line.trimRight() != line) { - issues.add('Line ${i+1} has trailing whitespace.'); + issues.add('Line ${i + 1} has trailing whitespace.'); } } @@ -1197,16 +1198,15 @@ class _HasGoodToStringDeep extends Matcher { // If a toStringDeep method doesn't properly handle nested values that // contain line breaks it can fail to add the required prefixes to all // lined when toStringDeep is called specifying prefixes. - const String prefixLineOne = 'PREFIX_LINE_ONE____'; + const String prefixLineOne = 'PREFIX_LINE_ONE____'; const String prefixOtherLines = 'PREFIX_OTHER_LINES_'; final List prefixIssues = []; - String descriptionWithPrefixes = - object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; // ignore: avoid_dynamic_calls + String descriptionWithPrefixes = object.toStringDeep( + prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; // ignore: avoid_dynamic_calls if (descriptionWithPrefixes.endsWith('\n')) { // Trim off trailing \n as the remaining calculations assume // the description does not end with a trailing \n. - descriptionWithPrefixes = descriptionWithPrefixes.substring( - 0, descriptionWithPrefixes.length - 1); + descriptionWithPrefixes = descriptionWithPrefixes.substring(0, descriptionWithPrefixes.length - 1); } final List linesWithPrefixes = descriptionWithPrefixes.split('\n'); if (!linesWithPrefixes.first.startsWith(prefixLineOne)) { @@ -1215,7 +1215,7 @@ class _HasGoodToStringDeep extends Matcher { for (int i = 1; i < linesWithPrefixes.length; ++i) { if (!linesWithPrefixes[i].startsWith(prefixOtherLines)) { - prefixIssues.add('Line ${i+1} does not contain the expected prefix.'); + prefixIssues.add('Line ${i + 1} does not contain the expected prefix.'); } } @@ -1227,15 +1227,14 @@ class _HasGoodToStringDeep extends Matcher { } if (prefixIssues.isNotEmpty) { - errorDescription.writeln( - 'Bad toStringDeep(prefixLineOne: "$prefixLineOne", prefixOtherLines: "$prefixOtherLines"):'); + errorDescription + .writeln('Bad toStringDeep(prefixLineOne: "$prefixLineOne", prefixOtherLines: "$prefixOtherLines"):'); errorDescription.writeln(descriptionWithPrefixes); errorDescription.writeAll(prefixIssues, '\n'); } if (errorDescription.isNotEmpty) { - matchState[_toStringDeepErrorDescriptionKey] = - errorDescription.toString(); + matchState[_toStringDeepErrorDescriptionKey] = errorDescription.toString(); return false; } return true; @@ -1380,11 +1379,9 @@ Matcher within({ distanceFunction ??= _kStandardDistanceFunctions[T] as DistanceFunction?; if (distanceFunction == null) { - throw ArgumentError( - 'The specified distanceFunction was null, and a standard distance ' - 'function was not found for type ${from.runtimeType} of the provided ' - '`from` argument.' - ); + throw ArgumentError('The specified distanceFunction was null, and a standard distance ' + 'function was not found for type ${from.runtimeType} of the provided ' + '`from` argument.'); } return _IsWithinDistance(distanceFunction, from, distance); @@ -1407,11 +1404,9 @@ class _IsWithinDistance extends Matcher { } final num distance = distanceFunction(object, value); if (distance < 0) { - throw ArgumentError( - 'Invalid distance function was used to compare a ${value.runtimeType} ' - 'to a ${object.runtimeType}. The function must return a non-negative ' - 'double value, but it returned $distance.' - ); + throw ArgumentError('Invalid distance function was used to compare a ${value.runtimeType} ' + 'to a ${object.runtimeType}. The function must return a non-negative ' + 'double value, but it returned $distance.'); } matchState['distance'] = distance; return distance <= epsilon; @@ -1433,8 +1428,7 @@ class _IsWithinDistance extends Matcher { } class _MoreOrLessEquals extends Matcher { - const _MoreOrLessEquals(this.value, this.epsilon) - : assert(epsilon >= 0); + const _MoreOrLessEquals(this.value, this.epsilon) : assert(epsilon >= 0); final double value; final double epsilon; @@ -1454,7 +1448,8 @@ class _MoreOrLessEquals extends Matcher { Description describe(Description description) => description.add('$value (±$epsilon)'); @override - Description describeMismatch(dynamic item, Description mismatchDescription, Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, Description mismatchDescription, Map matchState, bool verbose) { return super.describeMismatch(item, mismatchDescription, matchState, verbose) ..add('$item is not in the range of $value (±$epsilon).'); } @@ -1517,8 +1512,10 @@ class _IsMethodCall extends Matcher { @override Description describe(Description description) { return description - .add('has method name: ').addDescriptionOf(name) - .add(' with arguments: ').addDescriptionOf(arguments); + .add('has method name: ') + .addDescriptionOf(name) + .add(' with arguments: ') + .addDescriptionOf(arguments); } } @@ -1535,14 +1532,14 @@ const Matcher hasNoImmediateClip = _MatchAnythingExceptClip(); /// Asserts that a [Finder] locates a single object whose root RenderObject /// is a [RenderClipRRect] with no clipper set, and border radius equals to /// [borderRadius], or an equivalent [RenderClipPath]. -Matcher clipsWithBoundingRRect({ required BorderRadius borderRadius }) { +Matcher clipsWithBoundingRRect({required BorderRadius borderRadius}) { return _ClipsWithBoundingRRect(borderRadius: borderRadius); } /// Asserts that a [Finder] locates a single object whose root RenderObject /// is a [RenderClipPath] with a [ShapeBorderClipper] that clips to /// [shape]. -Matcher clipsWithShapeBorder({ required ShapeBorder shape }) { +Matcher clipsWithShapeBorder({required ShapeBorder shape}) { return _ClipsWithShapeBorder(shape: shape); } @@ -1703,14 +1700,12 @@ class _RendersOnPhysicalModel extends _MatchRenderObject matchState) { + bool assertRoundedRectangle( + ShapeBorderClipper shapeClipper, BorderRadius borderRadius, Map matchState) { if (shapeClipper.shape.runtimeType != RoundedRectangleBorder) { return failWithDescription(matchState, 'had shape border: ${shapeClipper.shape}'); } @@ -1825,8 +1821,7 @@ class _ClipsWithBoundingRect extends _MatchRenderObject - description.add('clips with bounding rectangle'); + Description describe(Description description) => description.add('clips with bounding rectangle'); } class _ClipsWithBoundingRRect extends _MatchRenderObject { @@ -1834,7 +1829,6 @@ class _ClipsWithBoundingRRect extends _MatchRenderObject matchState, RenderClipRRect renderObject) { if (renderObject.clipper != null) { @@ -1866,7 +1860,7 @@ class _ClipsWithBoundingRRect extends _MatchRenderObject - description.add('clips with bounding rounded rectangle with borderRadius: $borderRadius'); + description.add('clips with bounding rounded rectangle with borderRadius: $borderRadius'); } class _ClipsWithShapeBorder extends _MatchRenderObject { @@ -1891,10 +1885,8 @@ class _ClipsWithShapeBorder extends _MatchRenderObject - description.add('clips with shape: $shape'); + Description describe(Description description) => description.add('clips with shape: $shape'); } class _CoversSameAreaAs extends Matcher { @@ -1902,8 +1894,8 @@ class _CoversSameAreaAs extends Matcher { this.expectedPath, { required this.areaToCompare, this.sampleSize = 20, - }) : maxHorizontalNoise = areaToCompare.width / sampleSize, - maxVerticalNoise = areaToCompare.height / sampleSize { + }) : maxHorizontalNoise = areaToCompare.width / sampleSize, + maxVerticalNoise = areaToCompare.height / sampleSize { // Use a fixed random seed to make sure tests are deterministic. random = math.Random(1); } @@ -1969,8 +1961,7 @@ class _CoversSameAreaAs extends Matcher { } @override - Description describe(Description description) => - description.add('covers expected area and only expected area'); + Description describe(Description description) => description.add('covers expected area and only expected area'); } class _ColorMatcher extends Matcher { @@ -1995,11 +1986,11 @@ class _ColorMatcher extends Matcher { int _countDifferentPixels(Uint8List imageA, Uint8List imageB) { assert(imageA.length == imageB.length); int delta = 0; - for (int i = 0; i < imageA.length; i+=4) { + for (int i = 0; i < imageA.length; i += 4) { if (imageA[i] != imageB[i] || - imageA[i+1] != imageB[i+1] || - imageA[i+2] != imageB[i+2] || - imageA[i+3] != imageB[i+3]) { + imageA[i + 1] != imageB[i + 1] || + imageA[i + 2] != imageB[i + 2] || + imageA[i + 3] != imageB[i + 3]) { delta++; } } @@ -2172,18 +2163,24 @@ class _MatchesSemanticsData extends Matcher { if (hasIncreaseAction != null) SemanticsAction.increase: hasIncreaseAction, if (hasDecreaseAction != null) SemanticsAction.decrease: hasDecreaseAction, if (hasShowOnScreenAction != null) SemanticsAction.showOnScreen: hasShowOnScreenAction, - if (hasMoveCursorForwardByCharacterAction != null) SemanticsAction.moveCursorForwardByCharacter: hasMoveCursorForwardByCharacterAction, - if (hasMoveCursorBackwardByCharacterAction != null) SemanticsAction.moveCursorBackwardByCharacter: hasMoveCursorBackwardByCharacterAction, + if (hasMoveCursorForwardByCharacterAction != null) + SemanticsAction.moveCursorForwardByCharacter: hasMoveCursorForwardByCharacterAction, + if (hasMoveCursorBackwardByCharacterAction != null) + SemanticsAction.moveCursorBackwardByCharacter: hasMoveCursorBackwardByCharacterAction, if (hasSetSelectionAction != null) SemanticsAction.setSelection: hasSetSelectionAction, if (hasCopyAction != null) SemanticsAction.copy: hasCopyAction, if (hasCutAction != null) SemanticsAction.cut: hasCutAction, if (hasPasteAction != null) SemanticsAction.paste: hasPasteAction, - if (hasDidGainAccessibilityFocusAction != null) SemanticsAction.didGainAccessibilityFocus: hasDidGainAccessibilityFocusAction, - if (hasDidLoseAccessibilityFocusAction != null) SemanticsAction.didLoseAccessibilityFocus: hasDidLoseAccessibilityFocusAction, + if (hasDidGainAccessibilityFocusAction != null) + SemanticsAction.didGainAccessibilityFocus: hasDidGainAccessibilityFocusAction, + if (hasDidLoseAccessibilityFocusAction != null) + SemanticsAction.didLoseAccessibilityFocus: hasDidLoseAccessibilityFocusAction, if (customActions != null) SemanticsAction.customAction: customActions.isNotEmpty, if (hasDismissAction != null) SemanticsAction.dismiss: hasDismissAction, - if (hasMoveCursorForwardByWordAction != null) SemanticsAction.moveCursorForwardByWord: hasMoveCursorForwardByWordAction, - if (hasMoveCursorBackwardByWordAction != null) SemanticsAction.moveCursorBackwardByWord: hasMoveCursorBackwardByWordAction, + if (hasMoveCursorForwardByWordAction != null) + SemanticsAction.moveCursorForwardByWord: hasMoveCursorForwardByWordAction, + if (hasMoveCursorBackwardByWordAction != null) + SemanticsAction.moveCursorBackwardByWord: hasMoveCursorBackwardByWordAction, if (hasSetTextAction != null) SemanticsAction.setText: hasSetTextAction, }, hintOverrides = onTapHint == null && onLongPressHint == null @@ -2262,13 +2259,13 @@ class _MatchesSemanticsData extends Matcher { } if (actions.isNotEmpty) { final List expectedActions = actions.entries - .where((MapEntry e) => e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => e.value) + .map((MapEntry e) => e.key) + .toList(); final List notExpectedActions = actions.entries - .where((MapEntry e) => !e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => !e.value) + .map((MapEntry e) => e.key) + .toList(); if (expectedActions.isNotEmpty) { description.add(' with actions: ').addDescriptionOf(expectedActions); @@ -2279,13 +2276,13 @@ class _MatchesSemanticsData extends Matcher { } if (flags.isNotEmpty) { final List expectedFlags = flags.entries - .where((MapEntry e) => e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => e.value) + .map((MapEntry e) => e.key) + .toList(); final List notExpectedFlags = flags.entries - .where((MapEntry e) => !e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => !e.value) + .map((MapEntry e) => e.key) + .toList(); if (expectedFlags.isNotEmpty) { description.add(' with flags: ').addDescriptionOf(expectedFlags); @@ -2339,14 +2336,13 @@ class _MatchesSemanticsData extends Matcher { } for (int i = 0; i < first.length; i++) { if (first[i] is SpellOutStringAttribute && - (second[i] is! SpellOutStringAttribute || - second[i].range != first[i].range)) { + (second[i] is! SpellOutStringAttribute || second[i].range != first[i].range)) { return false; } if (first[i] is LocaleStringAttribute && (second[i] is! LocaleStringAttribute || - second[i].range != first[i].range || - (second[i] as LocaleStringAttribute).locale != (second[i] as LocaleStringAttribute).locale)) { + second[i].range != first[i].range || + (second[i] as LocaleStringAttribute).locale != (second[i] as LocaleStringAttribute).locale)) { return false; } } @@ -2356,8 +2352,10 @@ class _MatchesSemanticsData extends Matcher { @override bool matches(dynamic node, Map matchState) { if (node == null) { - return failWithDescription(matchState, 'No SemanticsData provided. ' - 'Maybe you forgot to enable semantics?'); + return failWithDescription( + matchState, + 'No SemanticsData provided. ' + 'Maybe you forgot to enable semantics?'); } final SemanticsData data = node is SemanticsNode ? node.getSemanticsData() : (node as SemanticsData); if (label != null && label != data.label) { @@ -2365,45 +2363,40 @@ class _MatchesSemanticsData extends Matcher { } if (attributedLabel != null && (attributedLabel!.string != data.attributedLabel.string || - !_stringAttributesEqual(attributedLabel!.attributes, data.attributedLabel.attributes))) { - return failWithDescription( - matchState, 'attributedLabel was: ${data.attributedLabel}'); + !_stringAttributesEqual(attributedLabel!.attributes, data.attributedLabel.attributes))) { + return failWithDescription(matchState, 'attributedLabel was: ${data.attributedLabel}'); } if (hint != null && hint != data.hint) { return failWithDescription(matchState, 'hint was: ${data.hint}'); } if (attributedHint != null && (attributedHint!.string != data.attributedHint.string || - !_stringAttributesEqual(attributedHint!.attributes, data.attributedHint.attributes))) { - return failWithDescription( - matchState, 'attributedHint was: ${data.attributedHint}'); + !_stringAttributesEqual(attributedHint!.attributes, data.attributedHint.attributes))) { + return failWithDescription(matchState, 'attributedHint was: ${data.attributedHint}'); } if (value != null && value != data.value) { return failWithDescription(matchState, 'value was: ${data.value}'); } if (attributedValue != null && (attributedValue!.string != data.attributedValue.string || - !_stringAttributesEqual(attributedValue!.attributes, data.attributedValue.attributes))) { - return failWithDescription( - matchState, 'attributedValue was: ${data.attributedValue}'); + !_stringAttributesEqual(attributedValue!.attributes, data.attributedValue.attributes))) { + return failWithDescription(matchState, 'attributedValue was: ${data.attributedValue}'); } if (increasedValue != null && increasedValue != data.increasedValue) { return failWithDescription(matchState, 'increasedValue was: ${data.increasedValue}'); } if (attributedIncreasedValue != null && (attributedIncreasedValue!.string != data.attributedIncreasedValue.string || - !_stringAttributesEqual(attributedIncreasedValue!.attributes, data.attributedIncreasedValue.attributes))) { - return failWithDescription( - matchState, 'attributedIncreasedValue was: ${data.attributedIncreasedValue}'); + !_stringAttributesEqual(attributedIncreasedValue!.attributes, data.attributedIncreasedValue.attributes))) { + return failWithDescription(matchState, 'attributedIncreasedValue was: ${data.attributedIncreasedValue}'); } if (decreasedValue != null && decreasedValue != data.decreasedValue) { return failWithDescription(matchState, 'decreasedValue was: ${data.decreasedValue}'); } if (attributedDecreasedValue != null && (attributedDecreasedValue!.string != data.attributedDecreasedValue.string || - !_stringAttributesEqual(attributedDecreasedValue!.attributes, data.attributedDecreasedValue.attributes))) { - return failWithDescription( - matchState, 'attributedDecreasedValue was: ${data.attributedDecreasedValue}'); + !_stringAttributesEqual(attributedDecreasedValue!.attributes, data.attributedDecreasedValue.attributes))) { + return failWithDescription(matchState, 'attributedDecreasedValue was: ${data.attributedDecreasedValue}'); } if (tooltip != null && tooltip != data.tooltip) { return failWithDescription(matchState, 'tooltip was: ${data.tooltip}'); @@ -2447,15 +2440,19 @@ class _MatchesSemanticsData extends Matcher { } } if (customActions != null || hintOverrides != null) { - final List providedCustomActions = data.customSemanticsActionIds?.map((int id) { - return CustomSemanticsAction.getAction(id)!; - }).toList() ?? []; + final List providedCustomActions = + data.customSemanticsActionIds?.map((int id) { + return CustomSemanticsAction.getAction(id)!; + }).toList() ?? + []; final List expectedCustomActions = customActions?.toList() ?? []; if (hintOverrides?.onTapHint != null) { - expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onTapHint!, action: SemanticsAction.tap)); + expectedCustomActions + .add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onTapHint!, action: SemanticsAction.tap)); } if (hintOverrides?.onLongPressHint != null) { - expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onLongPressHint!, action: SemanticsAction.longPress)); + expectedCustomActions.add(CustomSemanticsAction.overridingAction( + hint: hintOverrides!.onLongPressHint!, action: SemanticsAction.longPress)); } if (expectedCustomActions.length != providedCustomActions.length) { return failWithDescription(matchState, 'custom actions were: $providedCustomActions'); @@ -2463,6 +2460,7 @@ class _MatchesSemanticsData extends Matcher { int sortActions(CustomSemanticsAction left, CustomSemanticsAction right) { return CustomSemanticsAction.getIdentifier(left) - CustomSemanticsAction.getIdentifier(right); } + expectedCustomActions.sort(sortActions); providedCustomActions.sort(sortActions); for (int i = 0; i < expectedCustomActions.length; i++) { diff --git a/packages/flutter_test/test/matchers_test.dart b/packages/flutter_test/test/matchers_test.dart index b29deaf541fa5..b4b37b63d3c17 100644 --- a/packages/flutter_test/test/matchers_test.dart +++ b/packages/flutter_test/test/matchers_test.dart @@ -187,6 +187,10 @@ void main() { isNot(equalsIgnoringHashCodes(['Bar#00000', 'Foo#00000'])), ); expect(['Foo#a3b4d'], isNot(equalsIgnoringHashCodes(['Foo']))); + expect( + ['Foo#a3b4d'], + isNot(equalsIgnoringHashCodes(['Foo#00000', 'Bar#00000'])), + ); }); test('moreOrLessEquals', () { From 03a3ce7113e906af8f94b5dbe7595bdb3c230bcd Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Wed, 3 Aug 2022 12:08:51 -0700 Subject: [PATCH 3/3] Fix formatting --- packages/flutter_test/lib/src/matchers.dart | 193 ++++++++++---------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart index 35738f31e5bb9..0d069761aef88 100644 --- a/packages/flutter_test/lib/src/matchers.dart +++ b/packages/flutter_test/lib/src/matchers.dart @@ -248,7 +248,7 @@ TypeMatcher isInstanceOf() => isA(); /// range. /// * [rectMoreOrLessEquals] and [offsetMoreOrLessEquals], which do something /// similar but for [Rect]s and [Offset]s respectively. -Matcher moreOrLessEquals(double value, {double epsilon = precisionErrorTolerance}) { +Matcher moreOrLessEquals(double value, { double epsilon = precisionErrorTolerance }) { return _MoreOrLessEquals(value, epsilon); } @@ -262,7 +262,7 @@ Matcher moreOrLessEquals(double value, {double epsilon = precisionErrorTolerance /// * [offsetMoreOrLessEquals], which is for [Offset]s. /// * [within], which offers a generic version of this functionality that can /// be used to match [Rect]s as well as other types. -Matcher rectMoreOrLessEquals(Rect value, {double epsilon = precisionErrorTolerance}) { +Matcher rectMoreOrLessEquals(Rect value, { double epsilon = precisionErrorTolerance }) { return _IsWithinDistance(_rectDistance, value, epsilon); } @@ -274,7 +274,7 @@ Matcher rectMoreOrLessEquals(Rect value, {double epsilon = precisionErrorToleran /// /// * [moreOrLessEquals], which is for [double]s. /// * [offsetMoreOrLessEquals], which is for [Offset]s. -Matcher matrixMoreOrLessEquals(Matrix4 value, {double epsilon = precisionErrorTolerance}) { +Matcher matrixMoreOrLessEquals(Matrix4 value, { double epsilon = precisionErrorTolerance }) { return _IsWithinDistance(_matrixDistance, value, epsilon); } @@ -288,7 +288,7 @@ Matcher matrixMoreOrLessEquals(Matrix4 value, {double epsilon = precisionErrorTo /// * [rectMoreOrLessEquals], which is for [Rect]s. /// * [within], which offers a generic version of this functionality that can /// be used to match [Offset]s as well as other types. -Matcher offsetMoreOrLessEquals(Offset value, {double epsilon = precisionErrorTolerance}) { +Matcher offsetMoreOrLessEquals(Offset value, { double epsilon = precisionErrorTolerance }) { return _IsWithinDistance(_offsetDistance, value, epsilon); } @@ -317,7 +317,7 @@ Matcher equalsIgnoringHashCodes(Object value) { /// method [name] and [arguments]. /// /// Arguments checking implements deep equality for [List] and [Map] types. -Matcher isMethodCall(String name, {required dynamic arguments}) { +Matcher isMethodCall(String name, { required dynamic arguments }) { return _IsMethodCall(name, arguments); } @@ -330,8 +330,8 @@ Matcher isMethodCall(String name, {required dynamic arguments}) { /// When using this matcher you typically want to use a rectangle larger than /// the area you expect to paint in for [areaToCompare] to catch errors where /// the path draws outside the expected area. -Matcher coversSameAreaAs(Path expectedPath, {required Rect areaToCompare, int sampleSize = 20}) => - _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize); +Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int sampleSize = 20 }) + => _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize); /// Asserts that a [Finder], [Future], or [ui.Image] matches the /// golden image file identified by [key], with an optional [version] number. @@ -1049,10 +1049,10 @@ class _HasOneLineDescription extends Matcher { @override bool matches(dynamic object, Map matchState) { final String description = object.toString(); - return description.isNotEmpty && - !description.contains('\n') && - !description.contains('Instance of ') && - description.trim() == description; + return description.isNotEmpty + && !description.contains('\n') + && !description.contains('Instance of ') + && description.trim() == description; } @override @@ -1201,12 +1201,13 @@ class _HasGoodToStringDeep extends Matcher { const String prefixLineOne = 'PREFIX_LINE_ONE____'; const String prefixOtherLines = 'PREFIX_OTHER_LINES_'; final List prefixIssues = []; - String descriptionWithPrefixes = object.toStringDeep( - prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; // ignore: avoid_dynamic_calls + // ignore: avoid_dynamic_calls + String descriptionWithPrefixes = object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; if (descriptionWithPrefixes.endsWith('\n')) { // Trim off trailing \n as the remaining calculations assume // the description does not end with a trailing \n. - descriptionWithPrefixes = descriptionWithPrefixes.substring(0, descriptionWithPrefixes.length - 1); + descriptionWithPrefixes = descriptionWithPrefixes.substring( + 0, descriptionWithPrefixes.length - 1); } final List linesWithPrefixes = descriptionWithPrefixes.split('\n'); if (!linesWithPrefixes.first.startsWith(prefixLineOne)) { @@ -1227,14 +1228,15 @@ class _HasGoodToStringDeep extends Matcher { } if (prefixIssues.isNotEmpty) { - errorDescription - .writeln('Bad toStringDeep(prefixLineOne: "$prefixLineOne", prefixOtherLines: "$prefixOtherLines"):'); + errorDescription.writeln( + 'Bad toStringDeep(prefixLineOne: "$prefixLineOne", prefixOtherLines: "$prefixOtherLines"):'); errorDescription.writeln(descriptionWithPrefixes); errorDescription.writeAll(prefixIssues, '\n'); } if (errorDescription.isNotEmpty) { - matchState[_toStringDeepErrorDescriptionKey] = errorDescription.toString(); + matchState[_toStringDeepErrorDescriptionKey] = + errorDescription.toString(); return false; } return true; @@ -1379,9 +1381,11 @@ Matcher within({ distanceFunction ??= _kStandardDistanceFunctions[T] as DistanceFunction?; if (distanceFunction == null) { - throw ArgumentError('The specified distanceFunction was null, and a standard distance ' - 'function was not found for type ${from.runtimeType} of the provided ' - '`from` argument.'); + throw ArgumentError( + 'The specified distanceFunction was null, and a standard distance ' + 'function was not found for type ${from.runtimeType} of the provided ' + '`from` argument.' + ); } return _IsWithinDistance(distanceFunction, from, distance); @@ -1404,9 +1408,11 @@ class _IsWithinDistance extends Matcher { } final num distance = distanceFunction(object, value); if (distance < 0) { - throw ArgumentError('Invalid distance function was used to compare a ${value.runtimeType} ' - 'to a ${object.runtimeType}. The function must return a non-negative ' - 'double value, but it returned $distance.'); + throw ArgumentError( + 'Invalid distance function was used to compare a ${value.runtimeType} ' + 'to a ${object.runtimeType}. The function must return a non-negative ' + 'double value, but it returned $distance.' + ); } matchState['distance'] = distance; return distance <= epsilon; @@ -1428,7 +1434,8 @@ class _IsWithinDistance extends Matcher { } class _MoreOrLessEquals extends Matcher { - const _MoreOrLessEquals(this.value, this.epsilon) : assert(epsilon >= 0); + const _MoreOrLessEquals(this.value, this.epsilon) + : assert(epsilon >= 0); final double value; final double epsilon; @@ -1448,8 +1455,7 @@ class _MoreOrLessEquals extends Matcher { Description describe(Description description) => description.add('$value (±$epsilon)'); @override - Description describeMismatch( - dynamic item, Description mismatchDescription, Map matchState, bool verbose) { + Description describeMismatch(dynamic item, Description mismatchDescription, Map matchState, bool verbose) { return super.describeMismatch(item, mismatchDescription, matchState, verbose) ..add('$item is not in the range of $value (±$epsilon).'); } @@ -1512,10 +1518,8 @@ class _IsMethodCall extends Matcher { @override Description describe(Description description) { return description - .add('has method name: ') - .addDescriptionOf(name) - .add(' with arguments: ') - .addDescriptionOf(arguments); + .add('has method name: ').addDescriptionOf(name) + .add(' with arguments: ').addDescriptionOf(arguments); } } @@ -1532,14 +1536,14 @@ const Matcher hasNoImmediateClip = _MatchAnythingExceptClip(); /// Asserts that a [Finder] locates a single object whose root RenderObject /// is a [RenderClipRRect] with no clipper set, and border radius equals to /// [borderRadius], or an equivalent [RenderClipPath]. -Matcher clipsWithBoundingRRect({required BorderRadius borderRadius}) { +Matcher clipsWithBoundingRRect({ required BorderRadius borderRadius }) { return _ClipsWithBoundingRRect(borderRadius: borderRadius); } /// Asserts that a [Finder] locates a single object whose root RenderObject /// is a [RenderClipPath] with a [ShapeBorderClipper] that clips to /// [shape]. -Matcher clipsWithShapeBorder({required ShapeBorder shape}) { +Matcher clipsWithShapeBorder({ required ShapeBorder shape }) { return _ClipsWithShapeBorder(shape: shape); } @@ -1700,12 +1704,14 @@ class _RendersOnPhysicalModel extends _MatchRenderObject matchState) { + bool assertRoundedRectangle(ShapeBorderClipper shapeClipper, BorderRadius borderRadius, Map matchState) { if (shapeClipper.shape.runtimeType != RoundedRectangleBorder) { return failWithDescription(matchState, 'had shape border: ${shapeClipper.shape}'); } @@ -1821,7 +1826,8 @@ class _ClipsWithBoundingRect extends _MatchRenderObject description.add('clips with bounding rectangle'); + Description describe(Description description) => + description.add('clips with bounding rectangle'); } class _ClipsWithBoundingRRect extends _MatchRenderObject { @@ -1829,6 +1835,7 @@ class _ClipsWithBoundingRRect extends _MatchRenderObject matchState, RenderClipRRect renderObject) { if (renderObject.clipper != null) { @@ -1860,7 +1867,7 @@ class _ClipsWithBoundingRRect extends _MatchRenderObject - description.add('clips with bounding rounded rectangle with borderRadius: $borderRadius'); + description.add('clips with bounding rounded rectangle with borderRadius: $borderRadius'); } class _ClipsWithShapeBorder extends _MatchRenderObject { @@ -1885,8 +1892,10 @@ class _ClipsWithShapeBorder extends _MatchRenderObject description.add('clips with shape: $shape'); + Description describe(Description description) => + description.add('clips with shape: $shape'); } class _CoversSameAreaAs extends Matcher { @@ -1894,8 +1903,8 @@ class _CoversSameAreaAs extends Matcher { this.expectedPath, { required this.areaToCompare, this.sampleSize = 20, - }) : maxHorizontalNoise = areaToCompare.width / sampleSize, - maxVerticalNoise = areaToCompare.height / sampleSize { + }) : maxHorizontalNoise = areaToCompare.width / sampleSize, + maxVerticalNoise = areaToCompare.height / sampleSize { // Use a fixed random seed to make sure tests are deterministic. random = math.Random(1); } @@ -1961,7 +1970,8 @@ class _CoversSameAreaAs extends Matcher { } @override - Description describe(Description description) => description.add('covers expected area and only expected area'); + Description describe(Description description) => + description.add('covers expected area and only expected area'); } class _ColorMatcher extends Matcher { @@ -1986,7 +1996,7 @@ class _ColorMatcher extends Matcher { int _countDifferentPixels(Uint8List imageA, Uint8List imageB) { assert(imageA.length == imageB.length); int delta = 0; - for (int i = 0; i < imageA.length; i += 4) { + for (int i = 0; i < imageA.length; i+=4) { if (imageA[i] != imageB[i] || imageA[i + 1] != imageB[i + 1] || imageA[i + 2] != imageB[i + 2] || @@ -2163,24 +2173,18 @@ class _MatchesSemanticsData extends Matcher { if (hasIncreaseAction != null) SemanticsAction.increase: hasIncreaseAction, if (hasDecreaseAction != null) SemanticsAction.decrease: hasDecreaseAction, if (hasShowOnScreenAction != null) SemanticsAction.showOnScreen: hasShowOnScreenAction, - if (hasMoveCursorForwardByCharacterAction != null) - SemanticsAction.moveCursorForwardByCharacter: hasMoveCursorForwardByCharacterAction, - if (hasMoveCursorBackwardByCharacterAction != null) - SemanticsAction.moveCursorBackwardByCharacter: hasMoveCursorBackwardByCharacterAction, + if (hasMoveCursorForwardByCharacterAction != null) SemanticsAction.moveCursorForwardByCharacter: hasMoveCursorForwardByCharacterAction, + if (hasMoveCursorBackwardByCharacterAction != null) SemanticsAction.moveCursorBackwardByCharacter: hasMoveCursorBackwardByCharacterAction, if (hasSetSelectionAction != null) SemanticsAction.setSelection: hasSetSelectionAction, if (hasCopyAction != null) SemanticsAction.copy: hasCopyAction, if (hasCutAction != null) SemanticsAction.cut: hasCutAction, if (hasPasteAction != null) SemanticsAction.paste: hasPasteAction, - if (hasDidGainAccessibilityFocusAction != null) - SemanticsAction.didGainAccessibilityFocus: hasDidGainAccessibilityFocusAction, - if (hasDidLoseAccessibilityFocusAction != null) - SemanticsAction.didLoseAccessibilityFocus: hasDidLoseAccessibilityFocusAction, + if (hasDidGainAccessibilityFocusAction != null) SemanticsAction.didGainAccessibilityFocus: hasDidGainAccessibilityFocusAction, + if (hasDidLoseAccessibilityFocusAction != null) SemanticsAction.didLoseAccessibilityFocus: hasDidLoseAccessibilityFocusAction, if (customActions != null) SemanticsAction.customAction: customActions.isNotEmpty, if (hasDismissAction != null) SemanticsAction.dismiss: hasDismissAction, - if (hasMoveCursorForwardByWordAction != null) - SemanticsAction.moveCursorForwardByWord: hasMoveCursorForwardByWordAction, - if (hasMoveCursorBackwardByWordAction != null) - SemanticsAction.moveCursorBackwardByWord: hasMoveCursorBackwardByWordAction, + if (hasMoveCursorForwardByWordAction != null) SemanticsAction.moveCursorForwardByWord: hasMoveCursorForwardByWordAction, + if (hasMoveCursorBackwardByWordAction != null) SemanticsAction.moveCursorBackwardByWord: hasMoveCursorBackwardByWordAction, if (hasSetTextAction != null) SemanticsAction.setText: hasSetTextAction, }, hintOverrides = onTapHint == null && onLongPressHint == null @@ -2259,13 +2263,13 @@ class _MatchesSemanticsData extends Matcher { } if (actions.isNotEmpty) { final List expectedActions = actions.entries - .where((MapEntry e) => e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => e.value) + .map((MapEntry e) => e.key) + .toList(); final List notExpectedActions = actions.entries - .where((MapEntry e) => !e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => !e.value) + .map((MapEntry e) => e.key) + .toList(); if (expectedActions.isNotEmpty) { description.add(' with actions: ').addDescriptionOf(expectedActions); @@ -2276,13 +2280,13 @@ class _MatchesSemanticsData extends Matcher { } if (flags.isNotEmpty) { final List expectedFlags = flags.entries - .where((MapEntry e) => e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => e.value) + .map((MapEntry e) => e.key) + .toList(); final List notExpectedFlags = flags.entries - .where((MapEntry e) => !e.value) - .map((MapEntry e) => e.key) - .toList(); + .where((MapEntry e) => !e.value) + .map((MapEntry e) => e.key) + .toList(); if (expectedFlags.isNotEmpty) { description.add(' with flags: ').addDescriptionOf(expectedFlags); @@ -2336,13 +2340,14 @@ class _MatchesSemanticsData extends Matcher { } for (int i = 0; i < first.length; i++) { if (first[i] is SpellOutStringAttribute && - (second[i] is! SpellOutStringAttribute || second[i].range != first[i].range)) { + (second[i] is! SpellOutStringAttribute || + second[i].range != first[i].range)) { return false; } if (first[i] is LocaleStringAttribute && (second[i] is! LocaleStringAttribute || - second[i].range != first[i].range || - (second[i] as LocaleStringAttribute).locale != (second[i] as LocaleStringAttribute).locale)) { + second[i].range != first[i].range || + (second[i] as LocaleStringAttribute).locale != (second[i] as LocaleStringAttribute).locale)) { return false; } } @@ -2352,10 +2357,8 @@ class _MatchesSemanticsData extends Matcher { @override bool matches(dynamic node, Map matchState) { if (node == null) { - return failWithDescription( - matchState, - 'No SemanticsData provided. ' - 'Maybe you forgot to enable semantics?'); + return failWithDescription(matchState, 'No SemanticsData provided. ' + 'Maybe you forgot to enable semantics?'); } final SemanticsData data = node is SemanticsNode ? node.getSemanticsData() : (node as SemanticsData); if (label != null && label != data.label) { @@ -2363,40 +2366,45 @@ class _MatchesSemanticsData extends Matcher { } if (attributedLabel != null && (attributedLabel!.string != data.attributedLabel.string || - !_stringAttributesEqual(attributedLabel!.attributes, data.attributedLabel.attributes))) { - return failWithDescription(matchState, 'attributedLabel was: ${data.attributedLabel}'); + !_stringAttributesEqual(attributedLabel!.attributes, data.attributedLabel.attributes))) { + return failWithDescription( + matchState, 'attributedLabel was: ${data.attributedLabel}'); } if (hint != null && hint != data.hint) { return failWithDescription(matchState, 'hint was: ${data.hint}'); } if (attributedHint != null && (attributedHint!.string != data.attributedHint.string || - !_stringAttributesEqual(attributedHint!.attributes, data.attributedHint.attributes))) { - return failWithDescription(matchState, 'attributedHint was: ${data.attributedHint}'); + !_stringAttributesEqual(attributedHint!.attributes, data.attributedHint.attributes))) { + return failWithDescription( + matchState, 'attributedHint was: ${data.attributedHint}'); } if (value != null && value != data.value) { return failWithDescription(matchState, 'value was: ${data.value}'); } if (attributedValue != null && (attributedValue!.string != data.attributedValue.string || - !_stringAttributesEqual(attributedValue!.attributes, data.attributedValue.attributes))) { - return failWithDescription(matchState, 'attributedValue was: ${data.attributedValue}'); + !_stringAttributesEqual(attributedValue!.attributes, data.attributedValue.attributes))) { + return failWithDescription( + matchState, 'attributedValue was: ${data.attributedValue}'); } if (increasedValue != null && increasedValue != data.increasedValue) { return failWithDescription(matchState, 'increasedValue was: ${data.increasedValue}'); } if (attributedIncreasedValue != null && (attributedIncreasedValue!.string != data.attributedIncreasedValue.string || - !_stringAttributesEqual(attributedIncreasedValue!.attributes, data.attributedIncreasedValue.attributes))) { - return failWithDescription(matchState, 'attributedIncreasedValue was: ${data.attributedIncreasedValue}'); + !_stringAttributesEqual(attributedIncreasedValue!.attributes, data.attributedIncreasedValue.attributes))) { + return failWithDescription( + matchState, 'attributedIncreasedValue was: ${data.attributedIncreasedValue}'); } if (decreasedValue != null && decreasedValue != data.decreasedValue) { return failWithDescription(matchState, 'decreasedValue was: ${data.decreasedValue}'); } if (attributedDecreasedValue != null && (attributedDecreasedValue!.string != data.attributedDecreasedValue.string || - !_stringAttributesEqual(attributedDecreasedValue!.attributes, data.attributedDecreasedValue.attributes))) { - return failWithDescription(matchState, 'attributedDecreasedValue was: ${data.attributedDecreasedValue}'); + !_stringAttributesEqual(attributedDecreasedValue!.attributes, data.attributedDecreasedValue.attributes))) { + return failWithDescription( + matchState, 'attributedDecreasedValue was: ${data.attributedDecreasedValue}'); } if (tooltip != null && tooltip != data.tooltip) { return failWithDescription(matchState, 'tooltip was: ${data.tooltip}'); @@ -2440,19 +2448,15 @@ class _MatchesSemanticsData extends Matcher { } } if (customActions != null || hintOverrides != null) { - final List providedCustomActions = - data.customSemanticsActionIds?.map((int id) { - return CustomSemanticsAction.getAction(id)!; - }).toList() ?? - []; + final List providedCustomActions = data.customSemanticsActionIds?.map((int id) { + return CustomSemanticsAction.getAction(id)!; + }).toList() ?? []; final List expectedCustomActions = customActions?.toList() ?? []; if (hintOverrides?.onTapHint != null) { - expectedCustomActions - .add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onTapHint!, action: SemanticsAction.tap)); + expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onTapHint!, action: SemanticsAction.tap)); } if (hintOverrides?.onLongPressHint != null) { - expectedCustomActions.add(CustomSemanticsAction.overridingAction( - hint: hintOverrides!.onLongPressHint!, action: SemanticsAction.longPress)); + expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onLongPressHint!, action: SemanticsAction.longPress)); } if (expectedCustomActions.length != providedCustomActions.length) { return failWithDescription(matchState, 'custom actions were: $providedCustomActions'); @@ -2460,7 +2464,6 @@ class _MatchesSemanticsData extends Matcher { int sortActions(CustomSemanticsAction left, CustomSemanticsAction right) { return CustomSemanticsAction.getIdentifier(left) - CustomSemanticsAction.getIdentifier(right); } - expectedCustomActions.sort(sortActions); providedCustomActions.sort(sortActions); for (int i = 0; i < expectedCustomActions.length; i++) {