Skip to content

Commit dd17535

Browse files
committed
Expand private-in-signature support to getters and setters
The original CHANGELOG entry already (incorrectly at the time) used the word "members" so it does not need an update; it is just becoming correct now. PiperOrigin-RevId: 471606853
1 parent 21f486f commit dd17535

File tree

2 files changed

+96
-14
lines changed

2 files changed

+96
-14
lines changed

lib/src/builder.dart

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,8 @@ class _MockClassInfo {
13231323
// [_MockTargetGatherer._checkFunction].
13241324
throw InvalidMockitoAnnotationException(
13251325
"Mockito cannot generate a valid override for '$name', as it has a "
1326-
'non-nullable unknown return type.');
1326+
'non-nullable unknown return type or a private type in its '
1327+
'signature.');
13271328
}
13281329
builder.body = refer('UnsupportedError')
13291330
.call([
@@ -1771,20 +1772,26 @@ class _MockClassInfo {
17711772
builder
17721773
..name = getter.displayName
17731774
..annotations.add(referImported('override', 'dart:core'))
1774-
..type = MethodType.getter
1775-
..returns = _typeReference(getter.returnType);
1775+
..type = MethodType.getter;
1776+
1777+
if (!getter.returnType.containsPrivateName) {
1778+
builder.returns = _typeReference(getter.returnType);
1779+
}
17761780

17771781
final returnType = getter.returnType;
17781782
final fallbackGenerator = fallbackGenerators[getter.name];
1779-
if (typeSystem.isPotentiallyNonNullable(returnType) &&
1780-
returnType is analyzer.TypeParameterType &&
1781-
fallbackGenerator == null) {
1783+
final returnTypeIsTypeVariable =
1784+
typeSystem.isPotentiallyNonNullable(returnType) &&
1785+
returnType is analyzer.TypeParameterType;
1786+
final throwsUnsupported = fallbackGenerator == null &&
1787+
(returnTypeIsTypeVariable || getter.returnType.containsPrivateName);
1788+
if (throwsUnsupported) {
17821789
if (!mockTarget.unsupportedMembers.contains(getter.name)) {
17831790
// We shouldn't get here as this is guarded against in
17841791
// [_MockTargetGatherer._checkFunction].
17851792
throw InvalidMockitoAnnotationException(
17861793
"Mockito cannot generate a valid override for '${getter.name}', as "
1787-
'it has a non-nullable unknown type.');
1794+
'it has a non-nullable unknown type or a private type.');
17881795
}
17891796
builder.body = refer('UnsupportedError')
17901797
.call([
@@ -1824,22 +1831,45 @@ class _MockClassInfo {
18241831
/// This new setter just calls `super.noSuchMethod`.
18251832
void _buildOverridingSetter(
18261833
MethodBuilder builder, PropertyAccessorElement setter) {
1834+
final nameWithEquals = setter.name;
1835+
final name = setter.displayName;
18271836
builder
1828-
..name = setter.displayName
1837+
..name = name
18291838
..annotations.add(referImported('override', 'dart:core'))
18301839
..type = MethodType.setter;
18311840

18321841
assert(setter.parameters.length == 1);
18331842
final parameter = setter.parameters.single;
1834-
builder.requiredParameters.add(Parameter((pBuilder) => pBuilder
1835-
..name = parameter.displayName
1836-
..type = _typeReference(parameter.type, forceNullable: true)));
1837-
final invocationPositionalArg = refer(parameter.displayName);
1843+
builder.requiredParameters.add(Parameter((pBuilder) {
1844+
pBuilder.name = parameter.displayName;
1845+
if (!parameter.type.containsPrivateName) {
1846+
pBuilder.type = _typeReference(parameter.type, forceNullable: true);
1847+
}
1848+
}));
1849+
1850+
if (parameter.type.containsPrivateName) {
1851+
if (!mockTarget.unsupportedMembers.contains(nameWithEquals)) {
1852+
// We shouldn't get here as this is guarded against in
1853+
// [_MockTargetGatherer._checkFunction].
1854+
throw InvalidMockitoAnnotationException(
1855+
"Mockito cannot generate a valid override for '$nameWithEquals', "
1856+
'as it has a private parameter type.');
1857+
}
1858+
builder.body = refer('UnsupportedError')
1859+
.call([
1860+
literalString(
1861+
"'$nameWithEquals' cannot be used without a mockito fallback "
1862+
'generator.')
1863+
])
1864+
.thrown
1865+
.code;
1866+
return;
1867+
}
18381868

18391869
final invocation =
18401870
referImported('Invocation', 'dart:core').property('setter').call([
1841-
refer('#${setter.displayName}'),
1842-
invocationPositionalArg,
1871+
refer('#$name'),
1872+
refer(parameter.displayName),
18431873
]);
18441874
final returnNoSuchMethod = refer('super')
18451875
.property('noSuchMethod')

test/builder/custom_mocks_test.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,58 @@ void main() {
489489
r" '\'m\' cannot be used without a mockito fallback generator.');"));
490490
});
491491

492+
test('generates mock getters with private types, given unsupportedMembers',
493+
() async {
494+
var mocksContent = await buildWithNonNullable({
495+
...annotationsAsset,
496+
'foo|lib/foo.dart': dedent('''
497+
abstract class Foo {
498+
_Bar get f;
499+
}
500+
class _Bar {}
501+
'''),
502+
'foo|test/foo_test.dart': '''
503+
import 'package:foo/foo.dart';
504+
import 'package:mockito/annotations.dart';
505+
506+
@GenerateNiceMocks([
507+
MockSpec<Foo>(unsupportedMembers: {#f}),
508+
])
509+
void main() {}
510+
'''
511+
});
512+
expect(
513+
mocksContent,
514+
contains(' get f => throw UnsupportedError(\n'
515+
r" '\'f\' cannot be used without a mockito fallback generator.');"));
516+
});
517+
518+
test('generates mock setters with private types, given unsupportedMembers',
519+
() async {
520+
var mocksContent = await buildWithNonNullable({
521+
...annotationsAsset,
522+
'foo|lib/foo.dart': dedent('''
523+
abstract class Foo {
524+
set f(_Bar value);
525+
}
526+
class _Bar {}
527+
'''),
528+
'foo|test/foo_test.dart': '''
529+
import 'package:foo/foo.dart';
530+
import 'package:mockito/annotations.dart';
531+
532+
@GenerateNiceMocks([
533+
MockSpec<Foo>(unsupportedMembers: {Symbol('f=')}),
534+
])
535+
void main() {}
536+
'''
537+
});
538+
expect(
539+
mocksContent,
540+
contains(' set f(value) => throw UnsupportedError(\n'
541+
r" '\'f=\' cannot be used without a mockito fallback generator.');"));
542+
});
543+
492544
test(
493545
'generates mock methods with return types with private names in type '
494546
'arguments, given unsupportedMembers', () async {

0 commit comments

Comments
 (0)