Skip to content

Commit

Permalink
In my previous change, I tried a simpler approach in custom_mocks_tes…
Browse files Browse the repository at this point in the history
…t to try to not be sensitive to formatting changes before I realized that wouldn't work in auto_mocks_test and came up with something more robust.

It turns out the simpler approach is still too brittle and some tests fail under the new style (specifically, the new formatter splits after `=>` when the old one doesn't). So I hoisted containsIgnoringFormatting() into a separate library and refactored custom_mocks_test to use it too.

PiperOrigin-RevId: 691836139
  • Loading branch information
munificent authored and copybara-github committed Oct 31, 2024
1 parent 0d582b7 commit f72791d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 75 deletions.
45 changes: 4 additions & 41 deletions test/builder/auto_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import 'package:mockito/src/builder.dart';
import 'package:package_config/package_config.dart';
import 'package:test/test.dart';

import 'contains_ignoring_formatting.dart';

const annotationsAsset = {
'mockito|lib/annotations.dart': '''
class GenerateMocks {
Expand Down Expand Up @@ -3755,47 +3757,8 @@ void main() {

TypeMatcher<List<int>> _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();
}
? containsIgnoringFormatting(a)
: allOf(containsIgnoringFormatting(a), containsIgnoringFormatting(b)));

/// Expect that [testBuilder], given [assets], in a package which has opted into
/// null safety, throws an [InvalidMockitoAnnotationException] with a message
Expand Down
59 changes: 59 additions & 0 deletions test/builder/contains_ignoring_formatting.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2024 Dart Mockito authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'package:test/test.dart';

/// Returns a [Matcher] that checks that the actual string of Dart code
/// contains [expected] when ignoring differences due to formatting: whitespace
/// and trailing commas.
Matcher containsIgnoringFormatting(String expected) =>
_ContainsIgnoringFormattingMatcher(expected);

/// 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();
}
44 changes: 10 additions & 34 deletions test/builder/custom_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import 'package:mockito/src/builder.dart';
import 'package:package_config/package_config.dart';
import 'package:test/test.dart';

import 'contains_ignoring_formatting.dart';

Builder buildMocks(BuilderOptions options) => MockBuilder();

const annotationsAsset = {
Expand Down Expand Up @@ -439,10 +441,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('m() => throw UnsupportedError(\n'));
expect(
mocksContent,
contains(
containsIgnoringFormatting('m() => throw UnsupportedError('
'r\'"m" cannot be used without a mockito fallback generator.\''));
});

Expand All @@ -466,10 +467,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('get f => throw UnsupportedError('));
expect(
mocksContent,
contains(
containsIgnoringFormatting('get f => throw UnsupportedError('
'r\'"f" cannot be used without a mockito fallback generator.\''));
});

Expand All @@ -493,10 +493,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('set f(value) => throw UnsupportedError('));
expect(
mocksContent,
contains(
containsIgnoringFormatting('set f(value) => throw UnsupportedError('
'r\'"f=" cannot be used without a mockito fallback generator.\''));
});

Expand All @@ -521,10 +520,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('m() => throw UnsupportedError('));
expect(
mocksContent,
contains(
containsIgnoringFormatting('m() => throw UnsupportedError('
'r\'"m" cannot be used without a mockito fallback generator.\''));
});

Expand All @@ -549,10 +547,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('m() => throw UnsupportedError('));
expect(
mocksContent,
contains(
containsIgnoringFormatting('m() => throw UnsupportedError('
'r\'"m" cannot be used without a mockito fallback generator.\''));
});

Expand All @@ -577,10 +574,9 @@ void main() {
void main() {}
'''
});
expect(mocksContent, contains('void m(b) => throw UnsupportedError('));
expect(
mocksContent,
contains(
containsIgnoringFormatting('void m(b) => throw UnsupportedError('
'r\'"m" cannot be used without a mockito fallback generator.\''));
});

Expand Down Expand Up @@ -636,34 +632,14 @@ void main() {
'''
});

// 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('''
containsIgnoringFormatting('''
returnValue: _FakeBar_0(this, Invocation.method(#m, [])),
returnValueForMissingStub: _FakeBar_0(
this,
Invocation.method(#m, []),
),'''),
contains('''
returnValue: _FakeBar_0(
this,
Invocation.method(
#m,
[],
),
),
returnValueForMissingStub: _FakeBar_0(
this,
Invocation.method(
#m,
[],
),
),'''),
),
)'''),
);
});

Expand Down

0 comments on commit f72791d

Please sign in to comment.