From 99dc00f71d3d936afd2d505bd653285eff3cfc00 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Wed, 30 Oct 2024 18:41:04 -0700 Subject: [PATCH] In custom_mocks_test, there were only a handful that were sensitive to formatting, so I just loosened the tests a bit manually. In auto_mocks_test, there were about 50 failures, so I cobbled together a more generic approach. I used the existing _containsAllOf() function to hook in a custom matcher that ignores differences in whitespace and trailing commas. PiperOrigin-RevId: 691623798 --- test/builder/auto_mocks_test.dart | 81 ++++++++++++++++++++++------- test/builder/custom_mocks_test.dart | 51 ++++++++++++------ 2 files changed, 97 insertions(+), 35 deletions(-) diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart index 83631677..b6b2c573 100644 --- a/test/builder/auto_mocks_test.dart +++ b/test/builder/auto_mocks_test.dart @@ -2250,7 +2250,7 @@ void main() { bool m() => false; } '''), - _containsAllOf('returnValue: false,'), + _containsAllOf('returnValue: false'), ); }); @@ -2261,7 +2261,7 @@ void main() { double m() => 3.14; } '''), - _containsAllOf('returnValue: 0.0,'), + _containsAllOf('returnValue: 0.0'), ); }); @@ -2272,7 +2272,7 @@ void main() { int m() => 7; } '''), - _containsAllOf('returnValue: 0,'), + _containsAllOf('returnValue: 0'), ); }); @@ -2295,7 +2295,7 @@ void main() { List m() => [Foo()]; } '''), - _containsAllOf('returnValue: <_i2.Foo>[],'), + _containsAllOf('returnValue: <_i2.Foo>[]'), ); }); @@ -2306,7 +2306,7 @@ void main() { Set m() => {Foo()}; } '''), - _containsAllOf('returnValue: <_i2.Foo>{},'), + _containsAllOf('returnValue: <_i2.Foo>{}'), ); }); @@ -2317,7 +2317,7 @@ void main() { Map m() => {7: Foo()}; } '''), - _containsAllOf('returnValue: {},'), + _containsAllOf('returnValue: {}'), ); }); @@ -2328,7 +2328,7 @@ void main() { Map m(); } '''), - _containsAllOf('returnValue: {},'), + _containsAllOf('returnValue: {}'), ); }); @@ -2339,7 +2339,7 @@ void main() { Future m() async => false; } '''), - _containsAllOf('returnValue: _i3.Future.value(false),'), + _containsAllOf('returnValue: _i3.Future.value(false)'), ); }); @@ -2362,7 +2362,7 @@ void main() { Stream m(); } '''), - _containsAllOf('returnValue: _i3.Stream.empty(),'), + _containsAllOf('returnValue: _i3.Stream.empty()'), ); }); @@ -2384,7 +2384,7 @@ void main() { #m, [], ), - ),'''), + )'''), ); }); @@ -2403,7 +2403,7 @@ void main() { #m, [], ), - ),'''), + )'''), ); }); @@ -2418,7 +2418,7 @@ void main() { two, } '''), - _containsAllOf('returnValue: _i2.Bar.one,'), + _containsAllOf('returnValue: _i2.Bar.one'), ); }); @@ -2435,7 +2435,7 @@ void main() { returnValue: ( int __p0, [ String? __p1, - ]) {},'''), + ]) {}'''), ); }); @@ -2452,7 +2452,7 @@ void main() { returnValue: ( _i2.Foo __p0, { bool? b, - }) {},'''), + }) {}'''), ); }); @@ -2469,7 +2469,7 @@ void main() { returnValue: ( _i2.Foo __p0, { required bool b, - }) {},'''), + }) {}'''), ); }); @@ -2489,7 +2489,7 @@ void main() { #m, [], ), - ),'''), + )'''), ); }); @@ -2510,7 +2510,7 @@ void main() { #m, [], ), - ), + ) '''), ); }); @@ -2523,7 +2523,7 @@ void main() { T? Function(T) m() => (int i, [String s]) {}; } '''), - _containsAllOf('returnValue: (T __p0) => null,'), + _containsAllOf('returnValue: (T __p0) => null'), ); }); @@ -3753,8 +3753,49 @@ void main() { }); } -TypeMatcher> _containsAllOf(a, [b]) => decodedMatches( - b == null ? allOf(contains(a)) : allOf(contains(a), contains(b))); +TypeMatcher> _containsAllOf(String a, [String? b]) => + decodedMatches(b == null + ? _ContainsIgnoringFormattingMatcher(a) + : allOf(_ContainsIgnoringFormattingMatcher(a), + _ContainsIgnoringFormattingMatcher(b))); + +/// Matches a string that contains a given string, ignoring differences related +/// to formatting: whitespace and trailing commas. +class _ContainsIgnoringFormattingMatcher extends Matcher { + /// Matches one or more whitespace characters. + static final _whitespacePattern = RegExp(r'\s+'); + + /// Matches a trailing comma preceding a closing bracket character. + static final _trailingCommaPattern = RegExp(r',\s*([)}\]])'); + + /// The string that the actual value must contain in order for the match to + /// succeed. + final String _expected; + + _ContainsIgnoringFormattingMatcher(this._expected); + + @override + Description describe(Description description) { + return description + .add('Contains "$_expected" when ignoring source formatting'); + } + + @override + bool matches(item, Map matchState) => + _stripFormatting(item.toString()).contains(_stripFormatting(_expected)); + + /// Removes whitespace and trailing commas. + /// + /// Note that the result is not valid code because it means adjacent + ///.identifiers and operators may be joined in ways that break the semantics. + /// The goal is not to produce an but valid version of the code, just to + /// produce a string that will reliably match the actual string when it has + /// also been stripped the same way. + String _stripFormatting(String code) => code + .replaceAll(_whitespacePattern, '') + .replaceAllMapped(_trailingCommaPattern, (match) => match[1]!) + .trim(); +} /// Expect that [testBuilder], given [assets], in a package which has opted into /// null safety, throws an [InvalidMockitoAnnotationException] with a message diff --git a/test/builder/custom_mocks_test.dart b/test/builder/custom_mocks_test.dart index cdf253ae..fce83e1e 100644 --- a/test/builder/custom_mocks_test.dart +++ b/test/builder/custom_mocks_test.dart @@ -439,10 +439,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('m() => throw UnsupportedError(\n')); expect( mocksContent, - contains(' m() => throw UnsupportedError(\n' - ' r\'"m" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"m" cannot be used without a mockito fallback generator.\'')); }); test('generates mock getters with private types, given unsupportedMembers', @@ -465,10 +466,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('get f => throw UnsupportedError(')); expect( mocksContent, - contains(' get f => throw UnsupportedError(\n' - ' r\'"f" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"f" cannot be used without a mockito fallback generator.\'')); }); test('generates mock setters with private types, given unsupportedMembers', @@ -491,10 +493,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('set f(value) => throw UnsupportedError(')); expect( mocksContent, - contains(' set f(value) => throw UnsupportedError(\n' - ' r\'"f=" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"f=" cannot be used without a mockito fallback generator.\'')); }); test( @@ -518,10 +521,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('m() => throw UnsupportedError(')); expect( mocksContent, - contains(' m() => throw UnsupportedError(\n' - ' r\'"m" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"m" cannot be used without a mockito fallback generator.\'')); }); test( @@ -545,10 +549,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('m() => throw UnsupportedError(')); expect( mocksContent, - contains(' m() => throw UnsupportedError(\n' - ' r\'"m" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"m" cannot be used without a mockito fallback generator.\'')); }); test( @@ -572,10 +577,11 @@ void main() { void main() {} ''' }); + expect(mocksContent, contains('void m(b) => throw UnsupportedError(')); expect( mocksContent, - contains(' void m(b) => throw UnsupportedError(\n' - ' r\'"m" cannot be used without a mockito fallback generator.\');')); + contains( + 'r\'"m" cannot be used without a mockito fallback generator.\'')); }); test( @@ -629,7 +635,20 @@ void main() { void main() {} ''' }); - expect(mocksContent, contains(''' + + // TODO(rnystrom): Allow the test to pass using the old or new formatting + // styles. Remove the test for the old style once google3 is migrated to + // the new formatter. + expect( + mocksContent, + anyOf( + contains(''' + returnValue: _FakeBar_0(this, Invocation.method(#m, [])), + returnValueForMissingStub: _FakeBar_0( + this, + Invocation.method(#m, []), + ),'''), + contains(''' returnValue: _FakeBar_0( this, Invocation.method( @@ -643,7 +662,9 @@ void main() { #m, [], ), - ),''')); + ),'''), + ), + ); }); test('generates mock classes including a fallback generator for a getter', @@ -672,7 +693,7 @@ void main() { void main() {} ''' }); - expect(mocksContent, contains('returnValue: _i3.fShim(),')); + expect(mocksContent, contains('returnValue: _i3.fShim()')); }); test(