diff --git a/lib/src/builder.dart b/lib/src/builder.dart index 68d89b34..d857da18 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -17,11 +17,12 @@ import 'dart:collection'; import 'package:analyzer/dart/ast/ast.dart' as ast; import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart' as analyzer; import 'package:analyzer/dart/element/type_provider.dart'; import 'package:analyzer/dart/element/type_system.dart'; -import 'package:analyzer/dart/element/visitor.dart'; +import 'package:analyzer/dart/element/visitor2.dart'; // ignore: implementation_imports import 'package:analyzer/src/dart/element/element.dart' show ElementAnnotationImpl; @@ -32,6 +33,8 @@ import 'package:analyzer/src/dart/element/inheritance_manager3.dart' import 'package:analyzer/src/dart/element/member.dart' show ExecutableMember; // ignore: implementation_imports import 'package:analyzer/src/dart/element/type_algebra.dart' show Substitution; +// ignore: implementation_imports +import 'package:analyzer/src/utilities/extensions/element.dart'; import 'package:build/build.dart'; // Do not expose [refer] in the default namespace. // @@ -65,36 +68,46 @@ class MockBuilder implements Builder { @override final Map> buildExtensions; - const MockBuilder( - {this.buildExtensions = const { - '.dart': ['.mocks.dart'] - }}); + const MockBuilder({ + this.buildExtensions = const { + '.dart': ['.mocks.dart'], + }, + }); @override Future build(BuildStep buildStep) async { if (!await buildStep.resolver.isLibrary(buildStep.inputId)) return; - final entryLib = await buildStep.inputLibrary; + final entryLib = await buildStep.inputLibrary2; final sourceLibIsNonNullable = true; final mockLibraryAsset = buildStep.allowedOutputs.singleOrNull; if (mockLibraryAsset == null) { throw ArgumentError( - 'Build_extensions has missing or conflicting outputs for ' - '`${buildStep.inputId.path}`, this is usually caused by a misconfigured ' - 'build extension override in `build.yaml`'); + 'Build_extensions has missing or conflicting outputs for ' + '`${buildStep.inputId.path}`, this is usually caused by a misconfigured ' + 'build extension override in `build.yaml`', + ); } final inheritanceManager = InheritanceManager3(); - final mockTargetGatherer = - _MockTargetGatherer(entryLib, inheritanceManager); + final mockTargetGatherer = _MockTargetGatherer( + entryLib, + inheritanceManager, + ); - final assetUris = await _resolveAssetUris(buildStep.resolver, - mockTargetGatherer._mockTargets, mockLibraryAsset.path, entryLib); + final assetUris = await _resolveAssetUris( + buildStep.resolver, + mockTargetGatherer._mockTargets, + mockLibraryAsset.path, + entryLib, + ); - final mockLibraryInfo = _MockLibraryInfo(mockTargetGatherer._mockTargets, - assetUris: assetUris, - entryLib: entryLib, - inheritanceManager: inheritanceManager); + final mockLibraryInfo = _MockLibraryInfo( + mockTargetGatherer._mockTargets, + assetUris: assetUris, + entryLib: entryLib, + inheritanceManager: inheritanceManager, + ); if (mockLibraryInfo.fakeClasses.isEmpty && mockLibraryInfo.mockClasses.isEmpty) { @@ -114,15 +127,17 @@ class MockBuilder implements Builder { b.body.add(Code('// ignore_for_file: comment_references\n')); // We might import a deprecated library, or implement a deprecated class. b.body.add(Code('// ignore_for_file: deprecated_member_use\n')); - b.body.add(Code( - '// ignore_for_file: deprecated_member_use_from_same_package\n')); + b.body.add( + Code('// ignore_for_file: deprecated_member_use_from_same_package\n'), + ); // We might import a package's 'src' directory. b.body.add(Code('// ignore_for_file: implementation_imports\n')); // `Mock.noSuchMethod` is `@visibleForTesting`, but the generated code is // not always in a test directory; the Mockito `example/iss` tests, for // example. - b.body.add(Code( - '// ignore_for_file: invalid_use_of_visible_for_testing_member\n')); + b.body.add( + Code('// ignore_for_file: invalid_use_of_visible_for_testing_member\n'), + ); b.body.add(Code('// ignore_for_file: must_be_immutable\n')); b.body.add(Code('// ignore_for_file: prefer_const_constructors\n')); // The code_builder `asA` API unconditionally adds defensive parentheses. @@ -136,17 +151,19 @@ class MockBuilder implements Builder { }); final emitter = DartEmitter( - allocator: _AvoidConflictsAllocator( - coreConflicts: mockLibraryInfo.coreConflicts), - orderDirectives: true, - useNullSafetySyntax: sourceLibIsNonNullable); + allocator: _AvoidConflictsAllocator( + coreConflicts: mockLibraryInfo.coreConflicts, + ), + orderDirectives: true, + useNullSafetySyntax: sourceLibIsNonNullable, + ); final rawOutput = mockLibrary.accept(emitter).toString(); - final mockLibraryContent = - DartFormatter(languageVersion: entryLib.languageVersion.effective) - .format(''' + final mockLibraryContent = DartFormatter( + languageVersion: entryLib.languageVersion.effective, + ).format(''' // Mocks generated by Mockito $packageVersion from annotations -// in ${entryLib.definingCompilationUnit.source.uri.path}. +// in ${entryLib.firstFragment.source.uri.path}. // Do not manually edit this file. @@ -156,38 +173,39 @@ $rawOutput await buildStep.writeAsString(mockLibraryAsset, mockLibraryContent); } - Future> _resolveAssetUris( - Resolver resolver, - List<_MockTarget> mockTargets, - String entryAssetPath, - LibraryElement entryLib) async { + Future> _resolveAssetUris( + Resolver resolver, + List<_MockTarget> mockTargets, + String entryAssetPath, + LibraryElement2 entryLib, + ) async { // We pass in the `Future` type so that an asset URI is known for // `Future`, which is needed when overriding some methods which return // `FutureOr`. final typeVisitor = _TypeVisitor(entryLib.typeProvider.futureDynamicType); final seenTypes = {}; - final librariesWithTypes = {}; + final librariesWithTypes = {}; void addTypesFrom(analyzer.DartType type) { // Prevent infinite recursion. if (seenTypes.contains(type)) { if (type.alias != null) { // To check for duplicate typdefs that have different names - type.alias!.element.accept(typeVisitor); + type.alias!.element2.accept2(typeVisitor); } return; } seenTypes.add(type); - if (type.element?.library case final library?) { + if (type.element3?.library2 case final library?) { librariesWithTypes.add(library); } - if (type.alias?.element.library case final library?) { + if (type.alias?.element2.library2 case final library?) { librariesWithTypes.add(library); } - type.element?.accept(typeVisitor); - type.alias?.element.accept(typeVisitor); + type.element3?.accept2(typeVisitor); + type.alias?.element2.accept2(typeVisitor); switch (type) { case final analyzer.InterfaceType interface: interface.typeArguments.forEach(addTypesFrom); @@ -205,7 +223,7 @@ $rawOutput } } - final typeUris = {}; + final typeUris = {}; final elements = [ // Types which may be referenced. @@ -216,26 +234,29 @@ $rawOutput ]; for (final element in elements) { - final elementLibrary = element.library!; - if (elementLibrary.isInSdk && !elementLibrary.name.startsWith('dart._')) { + final elementLibrary = element.library2!; + if (elementLibrary.isInSdk && + !elementLibrary.name3!.startsWith('dart._')) { // For public SDK libraries, just use the source URI. - typeUris[element] = elementLibrary.source.uri.toString(); + typeUris[element] = elementLibrary.uri.toString(); continue; } final exportingLibrary = _findExportOf(librariesWithTypes, element); try { - final typeAssetId = await resolver.assetIdForElement(exportingLibrary); + final typeAssetId = await resolver.assetIdForElement2(exportingLibrary); if (typeAssetId.path.startsWith('lib/')) { typeUris[element] = typeAssetId.uri.toString(); } else { - typeUris[element] = p.posix.relative(typeAssetId.path, - from: p.posix.dirname(entryAssetPath)); + typeUris[element] = p.posix.relative( + typeAssetId.path, + from: p.posix.dirname(entryAssetPath), + ); } } on UnresolvableAssetException { // Asset may be in a summary. - typeUris[element] = exportingLibrary.source.uri.toString(); + typeUris[element] = exportingLibrary.uri.toString(); } } @@ -247,82 +268,85 @@ $rawOutput /// /// If [element] is not exported by any libraries in this set, then /// [element]'s declaring library is returned. - static LibraryElement _findExportOf( - Iterable inputLibraries, Element element) { - final elementName = element.name; + static LibraryElement2 _findExportOf( + Iterable inputLibraries, + Element2 element, + ) { + final elementName = element.name3; if (elementName == null) { - return element.library!; + return element.library2!; } final libraries = Queue.of([ - for (final library in inputLibraries) ...library.importedLibraries, + for (final library in inputLibraries) + ...library.firstFragment.importedLibraries2, ]); for (final library in libraries) { - if (library.exportNamespace.get(elementName) == element) { + if (library.exportNamespace.get2(elementName) == element) { return library; } } - return element.library!; + return element.library2!; } } -/// An [Element] visitor which collects the elements of all of the +/// An [Element2] visitor which collects the elements of all of the /// [analyzer.InterfaceType]s which it encounters. -class _TypeVisitor extends RecursiveElementVisitor { - final _elements = {}; +class _TypeVisitor extends RecursiveElementVisitor2 { + final _elements = {}; final analyzer.DartType _futureType; _TypeVisitor(this._futureType); @override - void visitClassElement(ClassElement element) { + void visitClassElement(ClassElement2 element) { _elements.add(element); super.visitClassElement(element); } @override - void visitEnumElement(EnumElement element) { + void visitEnumElement(EnumElement2 element) { _elements.add(element); super.visitEnumElement(element); } @override - void visitFieldElement(FieldElement element) { + void visitFieldElement(FieldElement2 element) { _addType(element.type); super.visitFieldElement(element); } @override - void visitMethodElement(MethodElement element) { + void visitMethodElement(MethodElement2 element) { _addType(element.returnType); super.visitMethodElement(element); } @override - void visitMixinElement(MixinElement element) { + void visitMixinElement(MixinElement2 element) { _elements.add(element); super.visitMixinElement(element); } @override - void visitParameterElement(ParameterElement element) { + void visitFormalParameterElement(FormalParameterElement element) { _addType(element.type); if (element.hasDefaultValue) { _addTypesFromConstant(element.computeConstantValue()!); } - super.visitParameterElement(element); + super.visitFormalParameterElement(element); } @override - void visitTypeParameterElement(TypeParameterElement element) { + void visitTypeParameterElement(TypeParameterElement2 element) { _addType(element.bound); super.visitTypeParameterElement(element); } @override - void visitTypeAliasElement(TypeAliasElement element) { + void visitTypeAliasElement(TypeAliasElement2 element) { _addType(element.aliasedType); _elements.add(element); super.visitTypeAliasElement(element); @@ -335,23 +359,26 @@ class _TypeVisitor extends RecursiveElementVisitor { type.alias?.typeArguments.forEach(_addType); if (type is analyzer.InterfaceType) { - final alreadyVisitedElement = _elements.contains(type.element); - _elements.add(type.element); + final alreadyVisitedElement = _elements.contains(type.element3); + _elements.add(type.element3); type.typeArguments.forEach(_addType); if (!alreadyVisitedElement) { - type.element.typeParameters.forEach(visitTypeParameterElement); + type.element3.typeParameters2.forEach(visitTypeParameterElement); - final toStringMethod = type.element.augmented - .lookUpMethod(name: 'toString', library: type.element.library); - if (toStringMethod != null && toStringMethod.parameters.isNotEmpty) { + final toStringMethod = type.element3.lookUpMethod2( + name: 'toString', + library: type.element3.library2, + ); + if (toStringMethod != null && + toStringMethod.formalParameters.isNotEmpty) { // In a Fake class which implements a class which overrides `toString` // with additional (optional) parameters, we must also override // `toString` and reference the same types referenced in those // parameters. - for (final parameter in toStringMethod.parameters) { + for (final parameter in toStringMethod.formalParameters) { final parameterType = parameter.type; if (parameterType is analyzer.InterfaceType) { - parameterType.element.accept(this); + parameterType.element3.accept2(this); } } } @@ -367,13 +394,13 @@ class _TypeVisitor extends RecursiveElementVisitor { // [RecursiveElementVisitor] does not "step out of" the element model, // into types, while traversing, so we must explicitly traverse [type] // here, in order to visit contained elements. - for (final typeParameter in type.typeFormals) { - typeParameter.accept(this); + for (final typeParameter in type.typeParameters) { + typeParameter.accept2(this); } - for (final parameter in type.parameters) { - parameter.accept(this); + for (final parameter in type.formalParameters) { + parameter.accept2(this); } - final aliasElement = type.alias?.element; + final aliasElement = type.alias?.element2; if (aliasElement != null) { _elements.add(aliasElement); } @@ -410,8 +437,8 @@ class _TypeVisitor extends RecursiveElementVisitor { _addTypesFromConstant(pair.key!); _addTypesFromConstant(pair.value!); } - } else if (object.toFunctionValue() != null) { - _elements.add(object.toFunctionValue()!); + } else if (object.toFunctionValue2() != null) { + _elements.add(object.toFunctionValue2()!); } else { // If [constant] is not null, a literal, or a type, then it must be an // object constructed with `const`. Revive it. @@ -440,7 +467,7 @@ class _MockTarget { final Set unsupportedMembers; - final Map fallbackGenerators; + final Map fallbackGenerators; /// Instantiated mock was requested, i.e. `MockSpec>`, /// instead of `MockSpec`. @@ -454,23 +481,27 @@ class _MockTarget { required this.fallbackGenerators, this.hasExplicitTypeArguments = false, String? mockName, - }) : mockName = mockName ?? - 'Mock${classType.alias?.element.name ?? classType.element.name}'; + }) : mockName = + mockName ?? + 'Mock${classType.alias?.element2.name3 ?? classType.element3.name3}'; - InterfaceElement get interfaceElement => classType.element; + InterfaceElement2 get interfaceElement => classType.element3; } /// This class gathers and verifies mock targets referenced in `GenerateMocks` /// annotations. class _MockTargetGatherer { - final LibraryElement _entryLib; + final LibraryElement2 _entryLib; final List<_MockTarget> _mockTargets; final InheritanceManager3 _inheritanceManager; _MockTargetGatherer._( - this._entryLib, this._mockTargets, this._inheritanceManager) { + this._entryLib, + this._mockTargets, + this._inheritanceManager, + ) { _checkClassesToMockAreValid(); } @@ -478,77 +509,90 @@ class _MockTargetGatherer { /// annotations and creates a [_MockTargetGatherer] with all of the classes /// identified as mocking targets. factory _MockTargetGatherer( - LibraryElement entryLib, + LibraryElement2 entryLib, InheritanceManager3 inheritanceManager, ) { final mockTargets = <_MockTarget>{}; final possiblyAnnotatedElements = [ - ...entryLib.definingCompilationUnit.libraryExports, - ...entryLib.definingCompilationUnit.libraryImports, - ...entryLib.topLevelElements, + ...entryLib.firstFragment.libraryExports2, + ...entryLib.firstFragment.libraryImports2, + ...entryLib.children2.whereType(), ]; for (final element in possiblyAnnotatedElements) { // TODO(srawlins): Re-think the idea of multiple @GenerateMocks // annotations, on one element or even on different elements in a library. - for (final annotation in element.metadata) { - if (annotation.element is! ConstructorElement) continue; - final annotationClass = annotation.element!.enclosingElement3!.name; + for (final annotation in element.metadata2.annotations) { + if (annotation.element2 is! ConstructorElement2) continue; + final annotationClass = annotation.element2!.enclosingElement2!.name3; switch (annotationClass) { case 'GenerateMocks': - mockTargets - .addAll(_mockTargetsFromGenerateMocks(annotation, entryLib)); + mockTargets.addAll( + _mockTargetsFromGenerateMocks(annotation, entryLib), + ); case 'GenerateNiceMocks': mockTargets.addAll( - _mockTargetsFromGenerateNiceMocks(annotation, entryLib)); + _mockTargetsFromGenerateNiceMocks(annotation, entryLib), + ); } } } return _MockTargetGatherer._( - entryLib, mockTargets.toList(), inheritanceManager); + entryLib, + mockTargets.toList(), + inheritanceManager, + ); } static ast.NamedType? _mockType(ast.CollectionElement mockSpec) { if (mockSpec is! ast.InstanceCreationExpression) { throw InvalidMockitoAnnotationException( - 'MockSpecs must be constructor calls inside the annotation, ' - 'please inline them if you are using a variable'); + 'MockSpecs must be constructor calls inside the annotation, ' + 'please inline them if you are using a variable', + ); } return mockSpec.constructorName.type.typeArguments?.arguments.firstOrNull as ast.NamedType?; } static ast.ListLiteral? _customMocksAst(ast.Annotation annotation) => - (annotation.arguments!.arguments - .firstWhereOrNull((arg) => arg is ast.NamedExpression) - as ast.NamedExpression?) - ?.expression as ast.ListLiteral?; + (annotation.arguments!.arguments.firstWhereOrNull( + (arg) => arg is ast.NamedExpression, + ) + as ast.NamedExpression?) + ?.expression + as ast.ListLiteral?; static ast.ListLiteral _niceMocksAst(ast.Annotation annotation) => annotation.arguments!.arguments.first as ast.ListLiteral; static Iterable<_MockTarget> _mockTargetsFromGenerateMocks( - ElementAnnotation annotation, LibraryElement entryLib) { + ElementAnnotation annotation, + LibraryElement2 entryLib, + ) { final generateMocksValue = annotation.computeConstantValue(); final classesField = generateMocksValue?.getField('classes'); if (classesField == null || classesField.isNull) { throw InvalidMockitoAnnotationException( - 'The GenerateMocks "classes" argument is missing, includes an ' - 'unknown type, or includes an extension'); + 'The GenerateMocks "classes" argument is missing, includes an ' + 'unknown type, or includes an extension', + ); } final mockTargets = <_MockTarget>[]; for (final objectToMock in classesField.toListValue()!) { final typeToMock = objectToMock.toTypeValue(); if (typeToMock == null) { throw InvalidMockitoAnnotationException( - 'The "classes" argument includes a non-type: $objectToMock'); + 'The "classes" argument includes a non-type: $objectToMock', + ); } if (typeToMock is analyzer.DynamicType || typeToMock is analyzer.InvalidType) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock `dynamic`'); + 'Mockito cannot mock `dynamic`', + ); } var type = _determineDartType(typeToMock, entryLib.typeProvider); if (type.alias == null) { @@ -557,34 +601,44 @@ class _MockTargetGatherer { // arguments. The type argument(s) on `type` have been instantiated to // bounds here. Switch to the declaration, which will be an // uninstantiated type. - type = (type.element.declaration as InterfaceElement).thisType; - } - mockTargets.add(_MockTarget( - type, - mixins: [], - onMissingStub: OnMissingStub.throwException, - unsupportedMembers: {}, - fallbackGenerators: {}, - )); + type = (type.element3.baseElement as InterfaceElement2).thisType; + } + mockTargets.add( + _MockTarget( + type, + mixins: [], + onMissingStub: OnMissingStub.throwException, + unsupportedMembers: {}, + fallbackGenerators: {}, + ), + ); } final customMocksField = generateMocksValue?.getField('customMocks'); if (customMocksField != null && !customMocksField.isNull) { final customMocksAsts = _customMocksAst(annotation.annotationAst)?.elements ?? - []; - mockTargets.addAll(customMocksField.toListValue()!.mapIndexed( + []; + mockTargets.addAll( + customMocksField.toListValue()!.mapIndexed( (index, mockSpec) => _mockTargetFromMockSpec( - mockSpec, entryLib, index, customMocksAsts.toList()))); + mockSpec, + entryLib, + index, + customMocksAsts.toList(), + ), + ), + ); } return mockTargets; } static _MockTarget _mockTargetFromMockSpec( - DartObject mockSpec, - LibraryElement entryLib, - int index, - List mockSpecAsts, - {bool nice = false}) { + DartObject mockSpec, + LibraryElement2 entryLib, + int index, + List mockSpecAsts, { + bool nice = false, + }) { final mockSpecType = mockSpec.type as analyzer.InterfaceType; assert(mockSpecType.typeArguments.length == 1); final mockType = _mockType(mockSpecAsts[index]); @@ -594,19 +648,21 @@ class _MockTargetGatherer { final mockTypeName = mockType?.qualifiedName; if (mockTypeName == null) { throw InvalidMockitoAnnotationException( - 'MockSpec requires a type argument to determine the class to mock. ' - 'Be sure to declare a type argument on the ${(index + 1).ordinal} ' - 'MockSpec() in @GenerateMocks.'); + 'MockSpec requires a type argument to determine the class to mock. ' + 'Be sure to declare a type argument on the ${(index + 1).ordinal} ' + 'MockSpec() in @GenerateMocks.', + ); } else { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock unknown type `$mockTypeName`. Did you ' - 'misspell it or forget to add a dependency on it?'); + 'Mockito cannot mock unknown type `$mockTypeName`. Did you ' + 'misspell it or forget to add a dependency on it?', + ); } } var type = _determineDartType(typeToMock, entryLib.typeProvider); final mockTypeArguments = mockType?.typeArguments; if (mockTypeArguments != null) { - final typeName = type.alias?.element.getDisplayString() ?? 'type $type'; + final typeName = type.alias?.element2.displayString2() ?? 'type $type'; final typeArguments = type.alias?.typeArguments ?? type.typeArguments; // Check explicit type arguments for unknown types that were // turned into `dynamic` by the analyzer. @@ -620,9 +676,10 @@ class _MockTargetGatherer { if (typeArgAst is! ast.NamedType) { // Is this even possible? throw InvalidMockitoAnnotationException( - 'Undefined type $typeArgAst passed as the ' - '${(typeArgIdx + 1).ordinal} type argument for mocked ' - '$typeName.'); + 'Undefined type $typeArgAst passed as the ' + '${(typeArgIdx + 1).ordinal} type argument for mocked ' + '$typeName.', + ); } if (typeArgAst.qualifiedName == 'dynamic') return; throw InvalidMockitoAnnotationException( @@ -637,7 +694,7 @@ class _MockTargetGatherer { // the type argument(s) on `type` have been instantiated to bounds if this // isn't a type alias. Switch to the declaration, which will be an // uninstantiated type. - type = (type.element.declaration as InterfaceElement).thisType; + type = (type.element3.baseElement as InterfaceElement2).thisType; } final mockName = mockSpec.getField('mockName')!.toSymbolValue(); final mixins = []; @@ -645,15 +702,19 @@ class _MockTargetGatherer { final typeToMixin = m.toTypeValue(); if (typeToMixin == null) { throw InvalidMockitoAnnotationException( - 'The "mixingIn" argument includes a non-type: $m'); + 'The "mixingIn" argument includes a non-type: $m', + ); } if (typeToMixin is analyzer.DynamicType || typeToMixin is analyzer.InvalidType) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mix `dynamic` into a mock class'); + 'Mockito cannot mix `dynamic` into a mock class', + ); } - final mixinInterfaceType = - _determineDartType(typeToMixin, entryLib.typeProvider); + final mixinInterfaceType = _determineDartType( + typeToMixin, + entryLib.typeProvider, + ); mixins.add(mixinInterfaceType); } @@ -685,35 +746,46 @@ class _MockTargetGatherer { } static Iterable<_MockTarget> _mockTargetsFromGenerateNiceMocks( - ElementAnnotation annotation, LibraryElement entryLib) { + ElementAnnotation annotation, + LibraryElement2 entryLib, + ) { final generateNiceMocksValue = annotation.computeConstantValue()!; final mockSpecsField = generateNiceMocksValue.getField('mocks')!; if (mockSpecsField.isNull) { throw InvalidMockitoAnnotationException( - 'The GenerateNiceMocks "mockSpecs" argument is missing'); + 'The GenerateNiceMocks "mockSpecs" argument is missing', + ); } final mockSpecAsts = _niceMocksAst(annotation.annotationAst).elements; - return mockSpecsField.toListValue()!.mapIndexed((index, mockSpec) => - _mockTargetFromMockSpec( - mockSpec, entryLib, index, mockSpecAsts.toList(), - nice: true)); + return mockSpecsField.toListValue()!.mapIndexed( + (index, mockSpec) => _mockTargetFromMockSpec( + mockSpec, + entryLib, + index, + mockSpecAsts.toList(), + nice: true, + ), + ); } - static Map _extractFallbackGenerators( - Map objects) { - final fallbackGenerators = {}; + static Map _extractFallbackGenerators( + Map objects, + ) { + final fallbackGenerators = {}; objects.forEach((methodName, generator) { if (methodName == null) { throw InvalidMockitoAnnotationException( - 'Unexpected null key in fallbackGenerators: $objects'); + 'Unexpected null key in fallbackGenerators: $objects', + ); } if (generator == null) { throw InvalidMockitoAnnotationException( - 'Unexpected null value in fallbackGenerators for key ' - '"$methodName"'); + 'Unexpected null value in fallbackGenerators for key ' + '"$methodName"', + ); } fallbackGenerators[methodName.toSymbolValue()!] = - generator.toFunctionValue()!; + generator.toFunctionValue2()!; }); return fallbackGenerators; } @@ -725,65 +797,80 @@ class _MockTargetGatherer { /// appropriate target for mocking. It will throw an /// [InvalidMockitoAnnotationException] under various conditions. static analyzer.InterfaceType _determineDartType( - analyzer.DartType typeToMock, TypeProvider typeProvider) { + analyzer.DartType typeToMock, + TypeProvider typeProvider, + ) { if (typeToMock is analyzer.InterfaceType) { - final elementToMock = typeToMock.element; + final elementToMock = typeToMock.element3; final displayName = "'${elementToMock.displayName}'"; - if (elementToMock is EnumElement) { + if (elementToMock is EnumElement2) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock an enum: $displayName'); + 'Mockito cannot mock an enum: $displayName', + ); } - if (typeProvider.isNonSubtypableClass(elementToMock)) { + if (typeProvider.isNonSubtypableClass2(elementToMock)) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a non-subtypable type: ' - '$displayName. It is illegal to subtype this ' - 'type.'); + 'Mockito cannot mock a non-subtypable type: ' + '$displayName. It is illegal to subtype this ' + 'type.', + ); } - if (elementToMock is ClassElement) { + if (elementToMock is ClassElement2) { if (elementToMock.isSealed) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a sealed class $displayName, ' - 'try mocking one of the variants instead.'); + 'Mockito cannot mock a sealed class $displayName, ' + 'try mocking one of the variants instead.', + ); } if (elementToMock.isBase) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a base class $displayName.'); + 'Mockito cannot mock a base class $displayName.', + ); } if (elementToMock.isFinal) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a final class $displayName.'); + 'Mockito cannot mock a final class $displayName.', + ); } } if (elementToMock.isPrivate) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a private type: $displayName.'); + 'Mockito cannot mock a private type: $displayName.', + ); } - final typeParameterErrors = - _checkTypeParameters(elementToMock.typeParameters, elementToMock); + final typeParameterErrors = _checkTypeParameters( + elementToMock.typeParameters2, + elementToMock, + ); if (typeParameterErrors.isNotEmpty) { - final joinedMessages = - typeParameterErrors.map((m) => ' $m').join('\n'); + final joinedMessages = typeParameterErrors + .map((m) => ' $m') + .join('\n'); throw InvalidMockitoAnnotationException( - 'Mockito cannot generate a valid mock class which implements ' - '$displayName for the following reasons:\n' - '$joinedMessages'); + 'Mockito cannot generate a valid mock class which implements ' + '$displayName for the following reasons:\n' + '$joinedMessages', + ); } if (typeToMock.alias != null && typeToMock.nullabilitySuffix == NullabilitySuffix.question) { throw InvalidMockitoAnnotationException( - 'Mockito cannot mock a type-aliased nullable type: ' - '${typeToMock.alias!.element.name}'); + 'Mockito cannot mock a type-aliased nullable type: ' + '${typeToMock.alias!.element2.name3}', + ); } return typeToMock; } - throw InvalidMockitoAnnotationException('Mockito cannot mock a non-class: ' - '${typeToMock.alias?.element.name ?? typeToMock.toString()}'); + throw InvalidMockitoAnnotationException( + 'Mockito cannot mock a non-class: ' + '${typeToMock.alias?.element2.name3 ?? typeToMock.toString()}', + ); } void _checkClassesToMockAreValid() { final classesInEntryLib = - _entryLib.topLevelElements.whereType(); + _entryLib.children2.whereType(); final classNamesToMock = {}; final uniqueNameSuggestion = "use the 'customMocks' argument in @GenerateMocks to specify a unique " @@ -792,37 +879,50 @@ class _MockTargetGatherer { final name = mockTarget.mockName; if (classNamesToMock.containsKey(name)) { final firstClass = classNamesToMock[name]!.interfaceElement; - final firstSource = firstClass.source.fullName; - final secondSource = mockTarget.interfaceElement.source.fullName; + final firstSource = + firstClass.firstFragment.libraryFragment.source.fullName; + final secondSource = + mockTarget + .interfaceElement + .firstFragment + .libraryFragment + .source + .fullName; throw InvalidMockitoAnnotationException( - 'Mockito cannot generate two mocks with the same name: $name (for ' - '${firstClass.name} declared in $firstSource, and for ' - '${mockTarget.interfaceElement.name} declared in $secondSource); ' - '$uniqueNameSuggestion.'); + 'Mockito cannot generate two mocks with the same name: $name (for ' + '${firstClass.name3} declared in $firstSource, and for ' + '${mockTarget.interfaceElement.name3} declared in $secondSource); ' + '$uniqueNameSuggestion.', + ); } classNamesToMock[name] = mockTarget; } classNamesToMock.forEach((name, mockTarget) { - final conflictingClass = - classesInEntryLib.firstWhereOrNull((c) => c.name == name); + final conflictingClass = classesInEntryLib.firstWhereOrNull( + (c) => c.name3 == name, + ); if (conflictingClass != null) { throw InvalidMockitoAnnotationException( - 'Mockito cannot generate a mock with a name which conflicts with ' - 'another class declared in this library: ${conflictingClass.name}; ' - '$uniqueNameSuggestion.'); + 'Mockito cannot generate a mock with a name which conflicts with ' + 'another class declared in this library: ${conflictingClass.name3}; ' + '$uniqueNameSuggestion.', + ); } - final preexistingMock = classesInEntryLib.firstWhereOrNull((c) => - c.interfaces - .map((type) => type.element) - .contains(mockTarget.interfaceElement) && - _isMockClass(c.supertype!)); + final preexistingMock = classesInEntryLib.firstWhereOrNull( + (c) => + c.interfaces + .map((type) => type.element3) + .contains(mockTarget.interfaceElement) && + _isMockClass(c.supertype!), + ); if (preexistingMock != null) { throw InvalidMockitoAnnotationException( - 'The GenerateMocks annotation contains a class which appears to ' - 'already be mocked inline: ${preexistingMock.name}; ' - '$uniqueNameSuggestion.'); + 'The GenerateMocks annotation contains a class which appears to ' + 'already be mocked inline: ${preexistingMock.name3}; ' + '$uniqueNameSuggestion.', + ); } _checkMethodsToStubAreValid(mockTarget); @@ -837,43 +937,51 @@ class _MockTargetGatherer { /// such a method. void _checkMethodsToStubAreValid(_MockTarget mockTarget) { final interfaceElement = mockTarget.interfaceElement; - final className = interfaceElement.name; + final className = interfaceElement.name3; final substitution = Substitution.fromInterfaceType(mockTarget.classType); final relevantMembers = _inheritanceManager - .getInterface(interfaceElement) - .map + .getInterface2(interfaceElement) + .map2 .values .where((m) => !m.isPrivate && !m.isStatic) - .map((member) => ExecutableMember.from2(member, substitution)); - final unstubbableErrorMessages = relevantMembers.expand((member) { - if (_entryLib.typeSystem._returnTypeIsNonNullable(member) || - _entryLib.typeSystem._hasNonNullableParameter(member) || - _needsOverrideForVoidStub(member)) { - return _checkFunction( - member.type, - member, - allowUnsupportedMember: - mockTarget.unsupportedMembers.contains(member.name), - hasDummyGenerator: - mockTarget.fallbackGenerators.containsKey(member.name), - ); - } else { - // Mockito is not going to override this method, so the types do not - // need to be checked. - return []; - } - }).toList(); + .map((member) => ExecutableMember.from(member, substitution)); + final unstubbableErrorMessages = + relevantMembers.expand((member) { + final nameWithEquals = + member is SetterElement ? '${member.name3}=' : member.name3; + if (_entryLib.typeSystem._returnTypeIsNonNullable(member) || + _entryLib.typeSystem._hasNonNullableParameter(member) || + _needsOverrideForVoidStub(member)) { + return _checkFunction( + member.type, + member, + allowUnsupportedMember: mockTarget.unsupportedMembers.contains( + nameWithEquals, + ), + hasDummyGenerator: mockTarget.fallbackGenerators.containsKey( + nameWithEquals, + ), + ); + } else { + // Mockito is not going to override this method, so the types do not + // need to be checked. + return []; + } + }).toList(); if (unstubbableErrorMessages.isNotEmpty) { - final joinedMessages = - unstubbableErrorMessages.map((m) => ' $m').join('\n'); + final joinedMessages = unstubbableErrorMessages + .map((m) => ' $m') + .join('\n'); throw InvalidMockitoAnnotationException( - 'Mockito cannot generate a valid mock class which implements ' - "'$className' for the following reasons:\n$joinedMessages"); + 'Mockito cannot generate a valid mock class which implements ' + "'$className' for the following reasons:\n$joinedMessages", + ); } } - String get _tryUnsupportedMembersMessage => 'Try generating this mock with ' + String get _tryUnsupportedMembersMessage => + 'Try generating this mock with ' "a MockSpec with 'unsupportedMembers' or a dummy generator (see " 'https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html).'; @@ -896,7 +1004,7 @@ class _MockTargetGatherer { /// been provided). List _checkFunction( analyzer.FunctionType function, - Element enclosingElement, { + Element2 enclosingElement, { bool isParameter = false, bool allowUnsupportedMember = false, bool hasDummyGenerator = false, @@ -907,56 +1015,74 @@ class _MockTargetGatherer { if (returnType.containsPrivateName) { if (!allowUnsupportedMember && !hasDummyGenerator) { errorMessages.add( - '${enclosingElement.fullName} features a private return type, ' - 'and cannot be stubbed. $_tryUnsupportedMembersMessage'); + '${enclosingElement.fullName} features a private return type, ' + 'and cannot be stubbed. $_tryUnsupportedMembersMessage', + ); } } - errorMessages.addAll(_checkTypeArguments( - returnType.typeArguments, - enclosingElement, - isParameter: isParameter, - allowUnsupportedMember: allowUnsupportedMember, - )); + errorMessages.addAll( + _checkTypeArguments( + returnType.typeArguments, + enclosingElement, + isParameter: isParameter, + allowUnsupportedMember: allowUnsupportedMember, + ), + ); } else if (returnType is analyzer.FunctionType) { - errorMessages.addAll(_checkFunction(returnType, enclosingElement, + errorMessages.addAll( + _checkFunction( + returnType, + enclosingElement, allowUnsupportedMember: allowUnsupportedMember, - hasDummyGenerator: hasDummyGenerator)); + hasDummyGenerator: hasDummyGenerator, + ), + ); } - for (final parameter in function.parameters) { + for (final parameter in function.formalParameters) { final parameterType = parameter.type; if (parameterType is analyzer.InterfaceType) { - final parameterTypeElement = parameterType.element; + final parameterTypeElement = parameterType.element3; if (parameterTypeElement.isPrivate) { // Technically, we can expand the type in the mock to something like // `Object?`. However, until there is a decent use case, we will not // generate such a mock. if (!allowUnsupportedMember) { errorMessages.add( - '${enclosingElement.fullName} features a private parameter ' - "type, '${parameterTypeElement.name}', and cannot be stubbed. " - '$_tryUnsupportedMembersMessage'); + '${enclosingElement.fullName} features a private parameter ' + "type, '${parameterTypeElement.name3}', and cannot be stubbed. " + '$_tryUnsupportedMembersMessage', + ); } } - errorMessages.addAll(_checkTypeArguments( - parameterType.typeArguments, - enclosingElement, - isParameter: true, - allowUnsupportedMember: allowUnsupportedMember, - )); + errorMessages.addAll( + _checkTypeArguments( + parameterType.typeArguments, + enclosingElement, + isParameter: true, + allowUnsupportedMember: allowUnsupportedMember, + ), + ); } else if (parameterType is analyzer.FunctionType) { errorMessages.addAll( - _checkFunction(parameterType, enclosingElement, isParameter: true)); + _checkFunction(parameterType, enclosingElement, isParameter: true), + ); } } - errorMessages - .addAll(_checkTypeParameters(function.typeFormals, enclosingElement)); + errorMessages.addAll( + _checkTypeParameters(function.typeParameters, enclosingElement), + ); final aliasArguments = function.alias?.typeArguments; if (aliasArguments != null) { - errorMessages.addAll(_checkTypeArguments(aliasArguments, enclosingElement, - isParameter: isParameter)); + errorMessages.addAll( + _checkTypeArguments( + aliasArguments, + enclosingElement, + isParameter: isParameter, + ), + ); } return errorMessages; @@ -965,7 +1091,9 @@ class _MockTargetGatherer { /// Checks the bounds of [typeParameters] for properties that would make the /// enclosing method un-stubbable. static List _checkTypeParameters( - List typeParameters, Element enclosingElement) { + List typeParameters, + Element2 enclosingElement, + ) { final errorMessages = []; for (final element in typeParameters) { final typeParameter = element.bound; @@ -973,10 +1101,11 @@ class _MockTargetGatherer { if (typeParameter is analyzer.InterfaceType) { // TODO(srawlins): Check for private names in bound; could be // `List<_Bar>`. - if (typeParameter.element.isPrivate) { + if (typeParameter.element3.isPrivate) { errorMessages.add( - '${enclosingElement.fullName} features a private type parameter ' - 'bound, and cannot be stubbed.'); + '${enclosingElement.fullName} features a private type parameter ' + 'bound, and cannot be stubbed.', + ); } } } @@ -990,25 +1119,28 @@ class _MockTargetGatherer { /// un-stubbable. List _checkTypeArguments( List typeArguments, - Element enclosingElement, { + Element2 enclosingElement, { bool isParameter = false, bool allowUnsupportedMember = false, }) { final errorMessages = []; for (final typeArgument in typeArguments) { if (typeArgument is analyzer.InterfaceType) { - if (typeArgument.element.isPrivate && !allowUnsupportedMember) { + if (typeArgument.element3.isPrivate && !allowUnsupportedMember) { errorMessages.add( - '${enclosingElement.fullName} features a private type argument, ' - 'and cannot be stubbed. $_tryUnsupportedMembersMessage'); + '${enclosingElement.fullName} features a private type argument, ' + 'and cannot be stubbed. $_tryUnsupportedMembersMessage', + ); } } else if (typeArgument is analyzer.FunctionType) { - errorMessages.addAll(_checkFunction( - typeArgument, - enclosingElement, - isParameter: isParameter, - allowUnsupportedMember: allowUnsupportedMember, - )); + errorMessages.addAll( + _checkFunction( + typeArgument, + enclosingElement, + isParameter: isParameter, + allowUnsupportedMember: allowUnsupportedMember, + ), + ); } } return errorMessages; @@ -1016,8 +1148,10 @@ class _MockTargetGatherer { /// Return whether [type] is the Mock class declared by mockito. bool _isMockClass(analyzer.InterfaceType type) => - type.element.name == 'Mock' && - type.element.source.fullName.endsWith('lib/src/mock.dart'); + type.element3.name3 == 'Mock' && + type.element3.firstFragment.libraryFragment.source.fullName.endsWith( + 'lib/src/mock.dart', + ); } class _MockLibraryInfo { @@ -1030,18 +1164,18 @@ class _MockLibraryInfo { /// values. final fakeClasses = []; - /// [InterfaceElement]s which are used in non-nullable return types, for which + /// [InterfaceElement2]s which are used in non-nullable return types, for which /// fake classes are added to the generated library. - final fakedInterfaceElements = []; + final fakedInterfaceElements2 = []; - /// A mapping of each necessary [Element] to a URI from which it can be + /// A mapping of each necessary [Element2] to a URI from which it can be /// imported. /// /// This mapping is generated eagerly so as to avoid any asynchronous /// Asset-resolving while building the mock library. - final Map assetUris; + final Map assetUris; - final LibraryElement? dartCoreLibrary; + final LibraryElement2? dartCoreLibrary; /// Names of overridden members which conflict with elements exported from /// 'dart:core'. @@ -1053,31 +1187,35 @@ class _MockLibraryInfo { _MockLibraryInfo( Iterable<_MockTarget> mockTargets, { required this.assetUris, - required LibraryElement entryLib, + required LibraryElement2 entryLib, required InheritanceManager3 inheritanceManager, - }) : dartCoreLibrary = entryLib.importedLibraries - .firstWhereOrNull((library) => library.isDartCore) { + }) : dartCoreLibrary = entryLib.firstFragment.importedLibraries2 + .firstWhereOrNull((library) => library.isDartCore) { for (final mockTarget in mockTargets) { final fallbackGenerators = mockTarget.fallbackGenerators; - mockClasses.add(_MockClassInfo( - mockTarget: mockTarget, - sourceLibIsNonNullable: true, - typeProvider: entryLib.typeProvider, - typeSystem: entryLib.typeSystem, - mockLibraryInfo: this, - fallbackGenerators: fallbackGenerators, - inheritanceManager: inheritanceManager, - )._buildMockClass()); + mockClasses.add( + _MockClassInfo( + mockTarget: mockTarget, + sourceLibIsNonNullable: true, + typeProvider: entryLib.typeProvider, + typeSystem: entryLib.typeSystem, + mockLibraryInfo: this, + fallbackGenerators: fallbackGenerators, + inheritanceManager: inheritanceManager, + )._buildMockClass(), + ); } } var _fakeNameCounter = 0; - final _fakeNames = {}; + final _fakeNames2 = {}; /// Generates a unique name for a fake class representing [element]. - String _fakeNameFor(Element element) => _fakeNames.putIfAbsent( - element, () => '_Fake${element.name}_${_fakeNameCounter++}'); + String _fakeNameFor(Element2 element) => _fakeNames2.putIfAbsent( + element, + () => '_Fake${element.name3}_${_fakeNameCounter++}', + ); } class _MockClassInfo { @@ -1097,7 +1235,7 @@ class _MockClassInfo { /// /// Each value is another mapping from method names to the generator /// function elements. - final Map fallbackGenerators; + final Map fallbackGenerators; final InheritanceManager3 inheritanceManager; @@ -1113,13 +1251,13 @@ class _MockClassInfo { Class _buildMockClass() { final typeAlias = mockTarget.classType.alias; - final aliasedElement = typeAlias?.element; + final aliasedElement = typeAlias?.element2; final aliasedType = - typeAlias?.element.aliasedType as analyzer.InterfaceType?; + typeAlias?.element2.aliasedType as analyzer.InterfaceType?; final typeToMock = aliasedType ?? mockTarget.classType; final classToMock = mockTarget.interfaceElement; final classIsImmutable = classToMock.metadata.any((it) => it.isImmutable); - final className = aliasedElement?.name ?? classToMock.name; + final className = aliasedElement?.name3 ?? classToMock.name3; return Class((cBuilder) { cBuilder @@ -1129,8 +1267,10 @@ class _MockClassInfo { // appropriate import prefix. ..docs.add('/// A class which mocks [$className].') ..docs.add('///') - ..docs.add('/// See the documentation for Mockito\'s code generation ' - 'for more information.'); + ..docs.add( + '/// See the documentation for Mockito\'s code generation ' + 'for more information.', + ); if (classIsImmutable) { cBuilder.docs.add('// ignore: must_be_immutable'); } @@ -1139,73 +1279,80 @@ class _MockClassInfo { // the "implements" clause. final typeParameters = - aliasedElement?.typeParameters ?? classToMock.typeParameters; + aliasedElement?.typeParameters2 ?? classToMock.typeParameters2; final typeArguments = typeAlias?.typeArguments ?? typeToMock.typeArguments; _withTypeParameters( - mockTarget.hasExplicitTypeArguments ? [] : typeParameters, - (typeParamsWithBounds, typeParams) { - cBuilder.types.addAll(typeParamsWithBounds); - for (final mixin in mockTarget.mixins) { - cBuilder.mixins.add(TypeReference((b) { - b - ..symbol = mixin.element.name - ..url = _typeImport(mixin.element) - ..types.addAll(mixin.typeArguments.map(_typeReference)); - })); - } - cBuilder.implements.add(TypeReference((b) { - b - ..symbol = className - ..url = _typeImport(aliasedElement ?? classToMock) - ..types.addAll(mockTarget.hasExplicitTypeArguments - ? typeArguments.map(_typeReference) - : typeParams); - })); - if (mockTarget.onMissingStub == OnMissingStub.throwException) { - cBuilder.constructors.add(_constructorWithThrowOnMissingStub); - } - - final substitution = Substitution.fromPairs([ - ...classToMock.typeParameters, - ...?aliasedElement?.typeParameters, - ], [ - ...typeToMock.typeArguments, - ...?typeAlias?.typeArguments, - ]); - final members = inheritanceManager - .getInterface(classToMock) - .map - .values - .map((member) { - return ExecutableMember.from2(member, substitution); - }); + mockTarget.hasExplicitTypeArguments ? [] : typeParameters, + (typeParamsWithBounds, typeParams) { + cBuilder.types.addAll(typeParamsWithBounds); + for (final mixin in mockTarget.mixins) { + cBuilder.mixins.add( + TypeReference((b) { + b + ..symbol = mixin.element3.name3 + ..url = _typeImport(mixin.element3) + ..types.addAll(mixin.typeArguments.map(_typeReference)); + }), + ); + } + cBuilder.implements.add( + TypeReference((b) { + b + ..symbol = className + ..url = _typeImport(aliasedElement ?? classToMock) + ..types.addAll( + mockTarget.hasExplicitTypeArguments + ? typeArguments.map(_typeReference) + : typeParams, + ); + }), + ); + if (mockTarget.onMissingStub == OnMissingStub.throwException) { + cBuilder.constructors.add(_constructorWithThrowOnMissingStub); + } - // The test can be pre-null-safety but if the class - // we want to mock is defined in a null safe library, - // we still need to override methods to get nice mocks. - final isNiceMockOfNullSafeClass = - mockTarget.onMissingStub == OnMissingStub.returnDefault; - - if (sourceLibIsNonNullable || isNiceMockOfNullSafeClass) { - cBuilder.methods.addAll( - fieldOverrides(members.whereType())); - cBuilder.methods - .addAll(methodOverrides(members.whereType())); - } else { - // For a pre-null safe library, we do not need to re-implement any - // members for the purpose of expanding their parameter types. However, - // we may need to include an implementation of `toString()`, if the - // class-to-mock has added optional parameters. - final toStringMethod = members - .whereType() - .firstWhereOrNull((m) => m.name == 'toString'); - if (toStringMethod != null) { - cBuilder.methods.addAll(methodOverrides([toStringMethod])); + final substitution = Substitution.fromPairs2( + [ + ...classToMock.typeParameters2, + ...?aliasedElement?.typeParameters2, + ], + [...typeToMock.typeArguments, ...?typeAlias?.typeArguments], + ); + final members = inheritanceManager + .getInterface2(classToMock) + .map2 + .values + .map((member) => ExecutableMember.from(member, substitution)); + + // The test can be pre-null-safety but if the class + // we want to mock is defined in a null safe library, + // we still need to override methods to get nice mocks. + final isNiceMockOfNullSafeClass = + mockTarget.onMissingStub == OnMissingStub.returnDefault; + + if (sourceLibIsNonNullable || isNiceMockOfNullSafeClass) { + cBuilder.methods.addAll( + fieldOverrides(members.whereType()), + ); + cBuilder.methods.addAll( + methodOverrides(members.whereType()), + ); + } else { + // For a pre-null safe library, we do not need to re-implement any + // members for the purpose of expanding their parameter types. However, + // we may need to include an implementation of `toString()`, if the + // class-to-mock has added optional parameters. + final toStringMethod = members + .whereType() + .firstWhereOrNull((m) => m.name3 == 'toString'); + if (toStringMethod != null) { + cBuilder.methods.addAll(methodOverrides([toStringMethod])); + } } - } - }); + }, + ); }); } @@ -1217,29 +1364,31 @@ class _MockClassInfo { /// return type (for getters) or a parameter with a potentially non-nullable /// type (for setters) are yielded. Iterable fieldOverrides( - Iterable accessors) sync* { + Iterable accessors, + ) sync* { for (final accessor in accessors) { if (accessor.isPrivate) { continue; } - if (accessor.name == 'hashCode') { + if (accessor.name3 == 'hashCode') { // Never override this getter; user code cannot narrow the return type. continue; } - if (accessor.name == 'runtimeType') { + if (accessor.name3 == 'runtimeType') { // Never override this getter; user code cannot narrow the return type. continue; } - if (accessor.isGetter && typeSystem._returnTypeIsNonNullable(accessor)) { + if (accessor is GetterElement && + typeSystem._returnTypeIsNonNullable(accessor)) { yield Method((mBuilder) => _buildOverridingGetter(mBuilder, accessor)); } - if (accessor.isSetter && sourceLibIsNonNullable) { + if (accessor is SetterElement && sourceLibIsNonNullable) { yield Method((mBuilder) => _buildOverridingSetter(mBuilder, accessor)); } } } - bool _methodNeedsOverride(MethodElement method) { + bool _methodNeedsOverride(MethodElement2 method) { if (!sourceLibIsNonNullable) { // If we get here, we are adding overrides only to make // nice mocks work. We only care about return types then. @@ -1257,16 +1406,16 @@ class _MockClassInfo { /// Only public instance methods which have either a potentially non-nullable /// return type or a parameter with a potentially non-nullable type are /// yielded. - Iterable methodOverrides(Iterable methods) sync* { + Iterable methodOverrides(Iterable methods) sync* { for (final method in methods) { if (method.isPrivate) { continue; } - final methodName = method.name; + final methodName = method.name3; if (methodName == 'noSuchMethod') { continue; } - if (methodName == 'toString' && method.parameters.isEmpty) { + if (methodName == 'toString' && method.formalParameters.isEmpty) { // Do not needlessly override this method with a simple call to // `super.toString`, unless the class has added parameters. continue; @@ -1277,14 +1426,14 @@ class _MockClassInfo { continue; } if (_methodNeedsOverride(method)) { - _checkForConflictWithCore(method.name); + _checkForConflictWithCore(method.name3!); yield Method((mBuilder) => _buildOverridingMethod(mBuilder, method)); } } } void _checkForConflictWithCore(String name) { - if (mockLibraryInfo.dartCoreLibrary?.exportNamespace.get(name) != null) { + if (mockLibraryInfo.dartCoreLibrary?.exportNamespace.get2(name) != null) { mockLibraryInfo.coreConflicts.add(name); } } @@ -1292,174 +1441,209 @@ class _MockClassInfo { /// The default behavior of mocks is to return null for unstubbed methods. To /// use the new behavior of throwing an error, we must explicitly call /// `throwOnMissingStub`. - Constructor get _constructorWithThrowOnMissingStub => - Constructor((cBuilder) => cBuilder.body = - referImported('throwOnMissingStub', 'package:mockito/mockito.dart') - .call([refer('this').expression]).statement); + Constructor get _constructorWithThrowOnMissingStub => Constructor( + (cBuilder) => + cBuilder.body = + referImported( + 'throwOnMissingStub', + 'package:mockito/mockito.dart', + ).call([refer('this').expression]).statement, + ); /// Build a method which overrides [method], with all non-nullable /// parameter types widened to be nullable. /// /// This new method just calls `super.noSuchMethod`, optionally passing a /// return value for methods with a non-nullable return type. - void _buildOverridingMethod(MethodBuilder builder, MethodElement method) { + void _buildOverridingMethod(MethodBuilder builder, MethodElement2 method) { var name = method.displayName; if (method.isOperator) name = 'operator$name'; final returnType = method.returnType; - _withTypeParameters(method.typeParameters, - typeFormalsHack: method.type.typeFormals, (typeParamsWithBounds, _) { - builder - ..name = name - ..annotations.add(referImported('override', 'dart:core')) - ..types.addAll(typeParamsWithBounds); - // We allow overriding a method with a private return type by omitting the - // return type (which is then inherited). - if (!returnType.containsPrivateName) { - builder.returns = _typeReference(returnType); - } - - // These two variables store the arguments that will be passed to the - // [Invocation] built for `noSuchMethod`. - final invocationPositionalArgs = []; - final invocationNamedArgs = {}; - - var position = 0; - for (final parameter in method.parameters) { - if (parameter.isRequiredPositional || parameter.isOptionalPositional) { - final superParameterType = - _escapeCovariance(parameter, position: position); - final matchingParameter = _matchingParameter( - parameter, - superParameterType: superParameterType, - // A parameter in the overridden method may be a wildcard, in which - // case we need to rename it, as we use the parameter when we pass - // it to `Invocation.method`. - defaultName: '_$position', - forceNullable: true, - ); - if (parameter.isRequiredPositional) { - builder.requiredParameters.add(matchingParameter); - } else { + _withTypeParameters( + method.typeParameters2, + typeFormalsHack: method.type.typeParameters, + (typeParamsWithBounds, _) { + builder + ..name = name + ..annotations.add(referImported('override', 'dart:core')) + ..types.addAll(typeParamsWithBounds); + // We allow overriding a method with a private return type by omitting the + // return type (which is then inherited). + if (!returnType.containsPrivateName) { + builder.returns = _typeReference(returnType); + } + + // These two variables store the arguments that will be passed to the + // [Invocation] built for `noSuchMethod`. + final invocationPositionalArgs = []; + final invocationNamedArgs = {}; + + var position = 0; + for (final parameter in method.formalParameters) { + if (parameter.isRequiredPositional || + parameter.isOptionalPositional) { + final superParameterType = _escapeCovariance( + parameter, + position: position, + ); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: superParameterType, + // A parameter in the overridden method may be a wildcard, in which + // case we need to rename it, as we use the parameter when we pass + // it to `Invocation.method`. + defaultName: '_$position', + forceNullable: true, + ); + if (parameter.isRequiredPositional) { + builder.requiredParameters.add(matchingParameter); + } else { + builder.optionalParameters.add(matchingParameter); + } + invocationPositionalArgs.add(refer(matchingParameter.name)); + position++; + } else if (parameter.isNamed) { + final superParameterType = _escapeCovariance( + parameter, + isNamed: true, + ); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: superParameterType, + forceNullable: true, + ); builder.optionalParameters.add(matchingParameter); + invocationNamedArgs[refer('#${parameter.displayName}')] = refer( + parameter.displayName, + ); + } else { + throw StateError( + 'Parameter ${parameter.name3} on method ${method.name3} ' + 'is not required-positional, nor optional-positional, nor named', + ); } - invocationPositionalArgs.add(refer(matchingParameter.name)); - position++; - } else if (parameter.isNamed) { - final superParameterType = - _escapeCovariance(parameter, isNamed: true); - final matchingParameter = _matchingParameter(parameter, - superParameterType: superParameterType, forceNullable: true); - builder.optionalParameters.add(matchingParameter); - invocationNamedArgs[refer('#${parameter.displayName}')] = - refer(parameter.displayName); - } else { - throw StateError( - 'Parameter ${parameter.name} on method ${method.name} ' - 'is not required-positional, nor optional-positional, nor named'); } - } - if (name == 'toString') { - // We cannot call `super.noSuchMethod` here; we must use [Mock]'s - // implementation. - builder.body = refer('super').property('toString').call([]).code; - return; - } - - final fallbackGenerator = fallbackGenerators[method.name]; - final parametersContainPrivateName = - method.parameters.any((p) => p.type.containsPrivateName); - final throwsUnsupported = fallbackGenerator == null && - (returnType.containsPrivateName || parametersContainPrivateName); + if (name == 'toString') { + // We cannot call `super.noSuchMethod` here; we must use [Mock]'s + // implementation. + builder.body = refer('super').property('toString').call([]).code; + return; + } - if (throwsUnsupported) { - if (!mockTarget.unsupportedMembers.contains(name)) { - // We shouldn't get here as this is guarded against in - // [_MockTargetGatherer._checkFunction]. - throw InvalidMockitoAnnotationException( + final fallbackGenerator = fallbackGenerators[method.name3]; + final parametersContainPrivateName = method.formalParameters.any( + (p) => p.type.containsPrivateName, + ); + final throwsUnsupported = + fallbackGenerator == null && + (returnType.containsPrivateName || parametersContainPrivateName); + + if (throwsUnsupported) { + if (!mockTarget.unsupportedMembers.contains(name)) { + // We shouldn't get here as this is guarded against in + // [_MockTargetGatherer._checkFunction]. + throw InvalidMockitoAnnotationException( "Mockito cannot generate a valid override for '$name', as it has " - 'a private type in its signature.'); + 'a private type in its signature.', + ); + } + builder.body = + refer('UnsupportedError') + .call([ + // Generate a raw string since name might contain a $. + literalString( + '"$name" cannot be used without a mockito fallback generator.', + raw: true, + ), + ]) + .thrown + .code; + return; } - builder.body = refer('UnsupportedError') - .call([ - // Generate a raw string since name might contain a $. - literalString( - '"$name" cannot be used without a mockito fallback generator.', - raw: true) - ]) - .thrown - .code; - return; - } - final invocation = - referImported('Invocation', 'dart:core').property('method').call([ - refer('#${method.displayName}'), - literalList(invocationPositionalArgs), - if (invocationNamedArgs.isNotEmpty) literalMap(invocationNamedArgs), - ]); + final invocation = referImported( + 'Invocation', + 'dart:core', + ).property('method').call([ + refer('#${method.displayName}'), + literalList(invocationPositionalArgs), + if (invocationNamedArgs.isNotEmpty) literalMap(invocationNamedArgs), + ]); - Expression? returnValueForMissingStub; - if (returnType is analyzer.VoidType) { - returnValueForMissingStub = refer('null'); - } else if (returnType.isFutureOfVoid) { - returnValueForMissingStub = - _futureReference(refer('void')).property('value').call([]); - } else if (mockTarget.onMissingStub == OnMissingStub.returnDefault) { - if (fallbackGenerator != null) { - // Re-use the fallback for missing stub. - returnValueForMissingStub = - _fallbackGeneratorCode(method, fallbackGenerator); - } else { - // Return a legal default value if no stub is found which matches a real - // call. - returnValueForMissingStub = _dummyValue(returnType, invocation); + Expression? returnValueForMissingStub; + if (returnType is analyzer.VoidType) { + returnValueForMissingStub = refer('null'); + } else if (returnType.isFutureOfVoid) { + returnValueForMissingStub = _futureReference( + refer('void'), + ).property('value').call([]); + } else if (mockTarget.onMissingStub == OnMissingStub.returnDefault) { + if (fallbackGenerator != null) { + // Re-use the fallback for missing stub. + returnValueForMissingStub = _fallbackGeneratorCode( + method, + fallbackGenerator, + ); + } else { + // Return a legal default value if no stub is found which matches a real + // call. + returnValueForMissingStub = _dummyValue(returnType, invocation); + } + } + final namedArgs = { + if (fallbackGenerator != null) + 'returnValue': _fallbackGeneratorCode(method, fallbackGenerator) + else if (typeSystem._returnTypeIsNonNullable(method)) + 'returnValue': _dummyValue(returnType, invocation), + if (returnValueForMissingStub != null) + 'returnValueForMissingStub': returnValueForMissingStub, + }; + + var superNoSuchMethod = refer( + 'super', + ).property('noSuchMethod').call([invocation], namedArgs); + if (returnType is! analyzer.VoidType && + returnType is! analyzer.DynamicType && + returnType is! analyzer.InvalidType) { + superNoSuchMethod = superNoSuchMethod.asA(_typeReference(returnType)); } - } - final namedArgs = { - if (fallbackGenerator != null) - 'returnValue': _fallbackGeneratorCode(method, fallbackGenerator) - else if (typeSystem._returnTypeIsNonNullable(method)) - 'returnValue': _dummyValue(returnType, invocation), - if (returnValueForMissingStub != null) - 'returnValueForMissingStub': returnValueForMissingStub, - }; - - var superNoSuchMethod = - refer('super').property('noSuchMethod').call([invocation], namedArgs); - if (returnType is! analyzer.VoidType && - returnType is! analyzer.DynamicType && - returnType is! analyzer.InvalidType) { - superNoSuchMethod = superNoSuchMethod.asA(_typeReference(returnType)); - } - builder.body = superNoSuchMethod.code; - }); + builder.body = superNoSuchMethod.code; + }, + ); } Expression _fallbackGeneratorCode( - ExecutableElement method, ExecutableElement function) { + ExecutableElement2 method, + ExecutableElement2 function, + ) { final positionalArguments = []; final namedArguments = {}; - for (final parameter in method.parameters) { + for (final parameter in method.formalParameters) { if (parameter.isPositional) { - positionalArguments.add(refer(parameter.name)); + positionalArguments.add(refer(parameter.name3!)); } else if (parameter.isNamed) { - namedArguments[parameter.name] = refer(parameter.name); + namedArguments[parameter.name3!] = refer(parameter.name3!); } } - final functionReference = - referImported(function.name, _typeImport(function)); + final functionReference = referImported( + function.name3!, + _typeImport(function), + ); return functionReference.call(positionalArguments, namedArguments, [ - for (final t in method.typeParameters) - _typeParameterReference(t, withBound: false) + for (final t in method.typeParameters2) + _typeParameterReference(t, withBound: false), ]); } Expression _dummyValueFallbackToRuntime( - analyzer.DartType type, Expression invocation) => - referImported('dummyValue', 'package:mockito/src/dummies.dart') - .call([refer('this'), invocation], {}, [_typeReference(type)]); + analyzer.DartType type, + Expression invocation, + ) => referImported( + 'dummyValue', + 'package:mockito/src/dummies.dart', + ).call([refer('this'), invocation], {}, [_typeReference(type)]); Expression _dummyValue(analyzer.DartType type, Expression invocation) { // The type is nullable, just take a shortcut and return `null`. @@ -1493,8 +1677,8 @@ class _MockClassInfo { return refer('() {}'); } else if (type.isDartAsyncFuture || type.isDartAsyncFutureOr) { final typeArgument = typeArguments.first; - final typeArgumentIsPotentiallyNonNullable = - typeSystem.isPotentiallyNonNullable(typeArgument); + final typeArgumentIsPotentiallyNonNullable = typeSystem + .isPotentiallyNonNullable(typeArgument); if (typeArgument is analyzer.TypeParameterType && typeArgumentIsPotentiallyNonNullable) { // We cannot create a valid Future for this unknown, potentially @@ -1504,25 +1688,41 @@ class _MockClassInfo { final futureType = typeProvider.futureType(typeArguments.first); return referImported('ifNotNull', 'package:mockito/src/dummies.dart') .call([ - referImported('dummyValueOrNull', 'package:mockito/src/dummies.dart') - .call([refer('this'), invocation], {}, - [_typeReference(typeArgument)]), - Method((b) => b - ..requiredParameters.add(Parameter((p) => p - ..type = _typeReference(typeArgument) - ..name = 'v')) - ..body = _futureReference(_typeReference(typeArgument)) - .property('value') - .call([refer('v')]).code).closure - ]).ifNullThen(_dummyValueImplementing(futureType, invocation)); + referImported( + 'dummyValueOrNull', + 'package:mockito/src/dummies.dart', + ).call( + [refer('this'), invocation], + {}, + [_typeReference(typeArgument)], + ), + Method( + (b) => + b + ..requiredParameters.add( + Parameter( + (p) => + p + ..type = _typeReference(typeArgument) + ..name = 'v', + ), + ) + ..body = + _futureReference( + _typeReference(typeArgument), + ).property('value').call([refer('v')]).code, + ).closure, + ]) + .ifNullThen(_dummyValueImplementing(futureType, invocation)); } else { // Create a real Future with a legal value, via [Future.value]. - final futureValueArguments = typeArgumentIsPotentiallyNonNullable - ? [_dummyValue(typeArgument, invocation)] - : []; - return _futureReference(_typeReference(typeArgument)) - .property('value') - .call(futureValueArguments); + final futureValueArguments = + typeArgumentIsPotentiallyNonNullable + ? [_dummyValue(typeArgument, invocation)] + : []; + return _futureReference( + _typeReference(typeArgument), + ).property('value').call(futureValueArguments); } } else if (type.isDartCoreInt) { return literalNum(0); @@ -1541,7 +1741,7 @@ class _MockClassInfo { assert(typeArguments.length == 1); final elementType = _typeReference(typeArguments[0]); return literalSet({}, elementType); - } else if (type.element.declaration == typeProvider.streamElement) { + } else if (type.element3.baseElement == typeProvider.streamElement2) { assert(typeArguments.length == 1); final elementType = _typeReference(typeArguments[0]); return TypeReference((b) { @@ -1555,8 +1755,10 @@ class _MockClassInfo { // sealed, e.g. "non-subtypeable", but they // have predicatble constructors; each has an unnamed constructor which // takes a single int argument. - return referImported(type.element.name, 'dart:typed_data') - .call([literalNum(0)]); + return referImported( + type.element3.name3!, + 'dart:typed_data', + ).call([literalNum(0)]); // TODO(srawlins): Do other types from typed_data have a "non-subtypeable" // restriction as well? } @@ -1569,43 +1771,54 @@ class _MockClassInfo { /// Returns a reference to [Future], optionally with a type argument for the /// value of the Future. TypeReference _futureReference([Reference? valueType]) => TypeReference((b) { - b - ..symbol = 'Future' - ..url = 'dart:async'; - if (valueType != null) { - b.types.add(valueType); - } - }); + b + ..symbol = 'Future' + ..url = 'dart:async'; + if (valueType != null) { + b.types.add(valueType); + } + }); Expression _dummyFunctionValue( - analyzer.FunctionType type, Expression invocation) { + analyzer.FunctionType type, + Expression invocation, + ) { return Method((b) { - _withTypeParameters(type.typeFormals, (typeParamsWithBounds, _) { + _withTypeParameters(type.typeParameters, (typeParamsWithBounds, _) { b.types.addAll(typeParamsWithBounds); // The positional parameters in a FunctionType have no names. This // counter lets us create unique dummy names. var position = 0; - for (final parameter in type.parameters) { + for (final parameter in type.formalParameters) { if (parameter.isRequiredPositional) { - final matchingParameter = _matchingParameter(parameter, - superParameterType: parameter.type, - defaultName: '__p$position'); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: parameter.type, + defaultName: '__p$position', + ); b.requiredParameters.add(matchingParameter); position++; } else if (parameter.isOptionalPositional) { - final matchingParameter = _matchingParameter(parameter, - superParameterType: parameter.type, - defaultName: '__p$position', - forceNullable: true); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: parameter.type, + defaultName: '__p$position', + forceNullable: true, + ); b.optionalParameters.add(matchingParameter); position++; } else if (parameter.isOptionalNamed) { - final matchingParameter = _matchingParameter(parameter, - superParameterType: parameter.type, forceNullable: true); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: parameter.type, + forceNullable: true, + ); b.optionalParameters.add(matchingParameter); } else if (parameter.isRequiredNamed) { - final matchingParameter = _matchingParameter(parameter, - superParameterType: parameter.type); + final matchingParameter = _matchingParameter( + parameter, + superParameterType: parameter.type, + ); b.optionalParameters.add(matchingParameter); } } @@ -1619,23 +1832,21 @@ class _MockClassInfo { } Expression _dummyRecordValue( - analyzer.RecordType type, Expression invocation) => - literalRecord( - [ - for (final f in type.positionalFields) _dummyValue(f.type, invocation) - ], - { - for (final f in type.namedFields) - f.name: _dummyValue(f.type, invocation) - }, - ); + analyzer.RecordType type, + Expression invocation, + ) => literalRecord( + [for (final f in type.positionalFields) _dummyValue(f.type, invocation)], + {for (final f in type.namedFields) f.name: _dummyValue(f.type, invocation)}, + ); Expression _dummyFakedValue( - analyzer.InterfaceType dartType, Expression invocation) { - final elementToFake = dartType.element; + analyzer.InterfaceType dartType, + Expression invocation, + ) { + final elementToFake = dartType.element3; final fakeName = mockLibraryInfo._fakeNameFor(elementToFake); // Only make one fake class for each class that needs to be faked. - if (!mockLibraryInfo.fakedInterfaceElements.contains(elementToFake)) { + if (!mockLibraryInfo.fakedInterfaceElements2.contains(elementToFake)) { _addFakeClass(fakeName, elementToFake); } final typeArguments = dartType.typeArguments; @@ -1647,75 +1858,107 @@ class _MockClassInfo { } Expression _dummyValueImplementing( - analyzer.InterfaceType dartType, Expression invocation) => - switch (dartType.element) { - EnumElement(:final fields) => _typeReference(dartType) - .property(fields.firstWhere((f) => f.isEnumConstant).name), - ClassElement() && final element - when element.isBase || element.isFinal || element.isSealed => - // This class can't be faked, so try to call `dummyValue` to get - // a dummy value at run time. - // TODO(yanok): Consider checking subtypes, maybe some of them are - // implementable. - _dummyValueFallbackToRuntime(dartType, invocation), - ClassElement() => _dummyFakedValue(dartType, invocation), - MixinElement() => - // This is a mixin and not a class. This should not happen in Dart 3, - // since it is not possible to have a value of mixin type. But we - // have to support this for reverse comptatibility. - _dummyFakedValue(dartType, invocation), - ExtensionTypeElement(:final typeErasure) - when !typeErasure.containsPrivateName => - _dummyValue(typeErasure, invocation), - ExtensionTypeElement() => - _dummyValueFallbackToRuntime(dartType, invocation), - _ => throw StateError( - "Interface type '$dartType' which is neither an enum, " - 'nor a class, nor a mixin, nor an extension type. This case is ' - 'unknown, please report a bug.') - }; + analyzer.InterfaceType dartType, + Expression invocation, + ) => switch (dartType.element3) { + EnumElement2(:final fields2) => _typeReference( + dartType, + ).property(fields2.firstWhere((f) => f.isEnumConstant).name3!), + ClassElement2() && final element + when element.isBase || element.isFinal || element.isSealed => + // This class can't be faked, so try to call `dummyValue` to get + // a dummy value at run time. + // TODO(yanok): Consider checking subtypes, maybe some of them are + // implementable. + _dummyValueFallbackToRuntime(dartType, invocation), + ClassElement2() => _dummyFakedValue(dartType, invocation), + MixinElement2() => + // This is a mixin and not a class. This should not happen in Dart 3, + // since it is not possible to have a value of mixin type. But we + // have to support this for reverse comptatibility. + _dummyFakedValue(dartType, invocation), + ExtensionTypeElement2(:final typeErasure) + when !typeErasure.containsPrivateName => + _dummyValue(typeErasure, invocation), + ExtensionTypeElement2() => _dummyValueFallbackToRuntime( + dartType, + invocation, + ), + _ => + throw StateError( + "Interface type '$dartType' which is neither an enum, " + 'nor a class, nor a mixin, nor an extension type. This case is ' + 'unknown, please report a bug.', + ), + }; /// Adds a `Fake` implementation of [elementToFake], named [fakeName]. - void _addFakeClass(String fakeName, InterfaceElement elementToFake) { - mockLibraryInfo.fakeClasses.add(Class((cBuilder) { - // For each type parameter on [elementToFake], the Fake class needs a type - // parameter with same type variables, and a mirrored type argument for - // the "implements" clause. - cBuilder - ..name = fakeName - ..extend = referImported('SmartFake', 'package:mockito/mockito.dart'); - _withTypeParameters(elementToFake.typeParameters, - (typeParamsWithBounds, typeParams) { - cBuilder.types.addAll(typeParamsWithBounds); - cBuilder.implements.add(TypeReference((b) { - b - ..symbol = elementToFake.name - ..url = _typeImport(elementToFake) - ..types.addAll(typeParams); - })); - cBuilder.constructors.add(Constructor((constrBuilder) => constrBuilder - ..requiredParameters.addAll([ - Parameter((pBuilder) => pBuilder - ..name = 'parent' - ..type = referImported('Object', 'dart:core')), - Parameter((pBuilder) => pBuilder - ..name = 'parentInvocation' - ..type = referImported('Invocation', 'dart:core')) - ]) - ..initializers.add(refer('super') - .call([refer('parent'), refer('parentInvocation')]).code))); - - final toStringMethod = elementToFake.augmented - .lookUpMethod(name: 'toString', library: elementToFake.library); - if (toStringMethod != null && toStringMethod.parameters.isNotEmpty) { - // If [elementToFake] includes an overriding `toString` implementation, - // we need to include an implementation which matches the signature. - cBuilder.methods.add(Method( - (mBuilder) => _buildOverridingMethod(mBuilder, toStringMethod))); - } - }); - })); - mockLibraryInfo.fakedInterfaceElements.add(elementToFake); + void _addFakeClass(String fakeName, InterfaceElement2 elementToFake) { + mockLibraryInfo.fakeClasses.add( + Class((cBuilder) { + // For each type parameter on [elementToFake], the Fake class needs a type + // parameter with same type variables, and a mirrored type argument for + // the "implements" clause. + cBuilder + ..name = fakeName + ..extend = referImported('SmartFake', 'package:mockito/mockito.dart'); + _withTypeParameters(elementToFake.typeParameters2.map((e) => e), ( + typeParamsWithBounds, + typeParams, + ) { + cBuilder.types.addAll(typeParamsWithBounds); + cBuilder.implements.add( + TypeReference((b) { + b + ..symbol = elementToFake.name3 + ..url = _typeImport(elementToFake) + ..types.addAll(typeParams); + }), + ); + cBuilder.constructors.add( + Constructor( + (constrBuilder) => + constrBuilder + ..requiredParameters.addAll([ + Parameter( + (pBuilder) => + pBuilder + ..name = 'parent' + ..type = referImported('Object', 'dart:core'), + ), + Parameter( + (pBuilder) => + pBuilder + ..name = 'parentInvocation' + ..type = referImported('Invocation', 'dart:core'), + ), + ]) + ..initializers.add( + refer( + 'super', + ).call([refer('parent'), refer('parentInvocation')]).code, + ), + ), + ); + + final toStringMethod = elementToFake.lookUpMethod2( + name: 'toString', + library: elementToFake.library2, + ); + if (toStringMethod != null && + toStringMethod.formalParameters.isNotEmpty) { + // If [elementToFake] includes an overriding `toString` implementation, + // we need to include an implementation which matches the signature. + cBuilder.methods.add( + Method( + (mBuilder) => _buildOverridingMethod(mBuilder, toStringMethod), + ), + ); + } + }); + }), + ); + mockLibraryInfo.fakedInterfaceElements2.add(elementToFake); } /// Returns a [Parameter] which matches [parameter]. @@ -1725,23 +1968,28 @@ class _MockClassInfo { /// /// If the type needs to be nullable, rather than matching the nullability of /// [parameter], use [forceNullable]. - Parameter _matchingParameter(ParameterElement parameter, - {required analyzer.DartType superParameterType, - String? defaultName, - bool forceNullable = false}) { - final parameterHasName = parameter.name.isNotEmpty && parameter.name != '_'; + Parameter _matchingParameter( + FormalParameterElement parameter, { + required analyzer.DartType superParameterType, + String? defaultName, + bool forceNullable = false, + }) { + final parameterHasName = parameter.name3 != '' && parameter.name3 != '_'; assert( parameterHasName || defaultName != null, 'parameter must have a non-empty name, or non-null defaultName must be ' - 'passed, but parameter name is "${parameter.name}" and defaultName is ' + 'passed, but parameter name is "${parameter.name3}" and defaultName is ' '$defaultName', ); - final name = !parameterHasName ? defaultName! : parameter.name; + final name = !parameterHasName ? defaultName! : parameter.name3!; return Parameter((pBuilder) { pBuilder.name = name; if (!superParameterType.containsPrivateName) { - pBuilder.type = _typeReference(superParameterType, - forceNullable: forceNullable, overrideVoid: true); + pBuilder.type = _typeReference( + superParameterType, + forceNullable: forceNullable, + overrideVoid: true, + ); } if (parameter.isNamed) pBuilder.named = true; if (parameter.isRequiredNamed && sourceLibIsNonNullable) { @@ -1749,16 +1997,19 @@ class _MockClassInfo { } if (parameter.defaultValueCode != null) { try { - pBuilder.defaultTo = _expressionFromDartObject( - parameter.computeConstantValue()!, parameter) - .code; + pBuilder.defaultTo = + _expressionFromDartObject( + parameter.computeConstantValue()!, + parameter, + ).code; } on _ReviveException catch (e) { - final method = parameter.enclosingElement3!; + final method = parameter.enclosingElement2!; throw InvalidMockitoAnnotationException( - 'Mockito cannot generate a valid override for method ' - "'${mockTarget.interfaceElement.displayName}.${method.displayName}'; " - "parameter '${parameter.displayName}' causes a problem: " - '${e.message}'); + 'Mockito cannot generate a valid override for method ' + "'${mockTarget.interfaceElement.displayName}.${method.displayName}'; " + "parameter '${parameter.displayName}' causes a problem: " + '${e.message}', + ); } } }); @@ -1776,30 +2027,35 @@ class _MockClassInfo { /// longer guaranteed, and we must look around at the types of of the /// corresponding parameters in all of the overridden methods in order to /// determine a legal type for a generated overridding method. - analyzer.DartType _escapeCovariance(ParameterElement parameter, - {int? position, bool isNamed = false}) { + analyzer.DartType _escapeCovariance( + FormalParameterElement parameter, { + int? position, + bool isNamed = false, + }) { assert(position != null || isNamed); assert(position == null || !isNamed); var type = parameter.type; if (!parameter.isCovariant) { return type; } - final method = parameter.enclosingElement3 as MethodElement; - final class_ = method.enclosingElement3 as InterfaceElement; - final name = Name(method.librarySource.uri, method.name); - final overriddenMethods = inheritanceManager.getOverridden2(class_, name); + final method = parameter.enclosingElement2 as MethodElement2; + final class_ = method.enclosingElement2 as InterfaceElement2; + final name = Name(method.library2.uri, method.name3!); + final overriddenMethods = inheritanceManager.getOverridden4(class_, name); if (overriddenMethods == null) { return type; } final allOverriddenMethods = Queue.of(overriddenMethods); while (allOverriddenMethods.isNotEmpty) { final overriddenMethod = allOverriddenMethods.removeFirst(); - final secondaryOverrides = inheritanceManager.getOverridden2( - overriddenMethod.enclosingElement3 as InterfaceElement, name); + final secondaryOverrides = inheritanceManager.getOverridden4( + overriddenMethod.enclosingElement2 as InterfaceElement2, + name, + ); if (secondaryOverrides != null) { allOverriddenMethods.addAll(secondaryOverrides); } - final parameters = overriddenMethod.parameters; + final parameters = overriddenMethod.formalParameters; if (position != null) { if (position >= parameters.length) { // [parameter] has been _added_ in [method], and has no corresponding @@ -1811,8 +2067,9 @@ class _MockClassInfo { // TODO(srawlins): Assert that [overriddenParameter] is not named. type = typeSystem.leastUpperBound(type, overriddenParameter.type); } else { - final overriddenParameter = - parameters.firstWhereOrNull((p) => p.name == parameter.name); + final overriddenParameter = parameters.firstWhereOrNull( + (p) => p.name3 == parameter.name3, + ); if (overriddenParameter == null) { // [parameter] has been _added_ in [method], and has no corresponding // parameter in [overriddenMethod]. @@ -1826,13 +2083,15 @@ class _MockClassInfo { } /// Creates a code_builder [Expression] from [object], a constant object from - /// analyzer and [parameter], an optional [ParameterElement], when the + /// analyzer and [parameter], an optional [FormalParameterElement], when the /// expression is created for a method parameter default value. /// /// This is very similar to Angular's revive code, in /// angular_compiler/analyzer/di/injector.dart. - Expression _expressionFromDartObject(DartObject object, - [ParameterElement? parameter]) { + Expression _expressionFromDartObject( + DartObject object, [ + FormalParameterElement? parameter, + ]) { final constant = ConstantReader(object); if (constant.isNull) { return literalNull; @@ -1851,18 +2110,19 @@ class _MockClassInfo { } else if (constant.isList) { return literalConstList([ for (final element in constant.listValue) - _expressionFromDartObject(element) + _expressionFromDartObject(element), ]); } else if (constant.isMap) { return literalConstMap({ for (final pair in constant.mapValue.entries) - _expressionFromDartObject(pair.key!): - _expressionFromDartObject(pair.value!) + _expressionFromDartObject(pair.key!): _expressionFromDartObject( + pair.value!, + ), }); } else if (constant.isSet) { return literalConstSet({ for (final element in constant.setValue) - _expressionFromDartObject(element) + _expressionFromDartObject(element), }); } else if (constant.isType) { // TODO(srawlins): It seems like this might be revivable, but Angular @@ -1875,36 +2135,41 @@ class _MockClassInfo { // object constructed with `const`. Revive it. final revivable = constant.revive(); if (revivable.isPrivate) { - final privateReference = revivable.accessor.isNotEmpty - ? '${revivable.source}::${revivable.accessor}' - : '${revivable.source}'; + final privateReference = + revivable.accessor.isNotEmpty + ? '${revivable.source}::${revivable.accessor}' + : '${revivable.source}'; throw _ReviveException( - 'default value has a private type: $privateReference.'); + 'default value has a private type: $privateReference.', + ); } - if (object.toFunctionValue() != null) { + if (object.toFunctionValue2() != null) { // A top-level function, like `void f() {}` must be referenced by its // identifier, rather than a revived value. - final element = object.toFunctionValue(); + final element = object.toFunctionValue2(); return referImported(revivable.accessor, _typeImport(element)); } else if (revivable.source.fragment.isEmpty) { // We can create this invocation by referring to a const field or // top-level variable. return referImported( - revivable.accessor, _typeImport(object.type!.element)); + revivable.accessor, + _typeImport(object.type!.element3), + ); } final name = revivable.source.fragment; final positionalArgs = [ for (final argument in revivable.positionalArguments) - _expressionFromDartObject(argument) + _expressionFromDartObject(argument), ]; final namedArgs = { for (final pair in revivable.namedArguments.entries) - pair.key: _expressionFromDartObject(pair.value) + pair.key: _expressionFromDartObject(pair.value), }; - final element = parameter != null && name != object.type!.element!.name - ? parameter.type.element - : object.type!.element; + final element = + parameter != null && name != object.type!.element3!.name3 + ? parameter.type.element3 + : object.type!.element3; final type = referImported(name, _typeImport(element)); if (revivable.accessor.isNotEmpty) { return type.constInstanceNamed( @@ -1923,8 +2188,7 @@ class _MockClassInfo { /// /// This new method just calls `super.noSuchMethod`, optionally passing a /// return value for non-nullable getters. - void _buildOverridingGetter( - MethodBuilder builder, PropertyAccessorElement getter) { + void _buildOverridingGetter(MethodBuilder builder, GetterElement getter) { builder ..name = getter.displayName ..annotations.add(referImported('override', 'dart:core')) @@ -1935,46 +2199,51 @@ class _MockClassInfo { } final returnType = getter.returnType; - final fallbackGenerator = fallbackGenerators[getter.name]; + final fallbackGenerator = fallbackGenerators[getter.name3]; final throwsUnsupported = fallbackGenerator == null && (getter.returnType.containsPrivateName); if (throwsUnsupported) { - if (!mockTarget.unsupportedMembers.contains(getter.name)) { + if (!mockTarget.unsupportedMembers.contains(getter.name3)) { // We shouldn't get here as this is guarded against in // [_MockTargetGatherer._checkFunction]. throw InvalidMockitoAnnotationException( - "Mockito cannot generate a valid override for '${getter.name}', as " - 'it has a private type.'); - } - builder.body = refer('UnsupportedError') - .call([ - // Generate a raw string since getter.name might contain a $. - literalString( - '"${getter.name}" cannot be used without a mockito fallback ' - 'generator.', - raw: true) - ]) - .thrown - .code; + "Mockito cannot generate a valid override for '${getter.name3}', as " + 'it has a private type.', + ); + } + builder.body = + refer('UnsupportedError') + .call([ + // Generate a raw string since getter.name might contain a $. + literalString( + '"${getter.name3}" cannot be used without a mockito fallback ' + 'generator.', + raw: true, + ), + ]) + .thrown + .code; return; } - final invocation = - referImported('Invocation', 'dart:core').property('getter').call([ - refer('#${getter.displayName}'), - ]); + final invocation = referImported( + 'Invocation', + 'dart:core', + ).property('getter').call([refer('#${getter.displayName}')]); final namedArgs = { if (fallbackGenerator != null) 'returnValue': _fallbackGeneratorCode(getter, fallbackGenerator) else if (typeSystem._returnTypeIsNonNullable(getter)) 'returnValue': _dummyValue(returnType, invocation), if (mockTarget.onMissingStub == OnMissingStub.returnDefault) - 'returnValueForMissingStub': (fallbackGenerator != null - ? _fallbackGeneratorCode(getter, fallbackGenerator) - : _dummyValue(returnType, invocation)), + 'returnValueForMissingStub': + (fallbackGenerator != null + ? _fallbackGeneratorCode(getter, fallbackGenerator) + : _dummyValue(returnType, invocation)), }; - var superNoSuchMethod = - refer('super').property('noSuchMethod').call([invocation], namedArgs); + var superNoSuchMethod = refer( + 'super', + ).property('noSuchMethod').call([invocation], namedArgs); if (returnType is! analyzer.VoidType && returnType is! analyzer.DynamicType && returnType is! analyzer.InvalidType) { @@ -1988,56 +2257,62 @@ class _MockClassInfo { /// type to be nullable if it is non-nullable. /// /// This new setter just calls `super.noSuchMethod`. - void _buildOverridingSetter( - MethodBuilder builder, PropertyAccessorElement setter) { - final nameWithEquals = setter.name; + void _buildOverridingSetter(MethodBuilder builder, SetterElement setter) { + final nameWithEquals = '${setter.name3}='; final name = setter.displayName; builder ..name = name ..annotations.add(referImported('override', 'dart:core')) ..type = MethodType.setter; - assert(setter.parameters.length == 1); - final parameter = setter.parameters.single; + assert(setter.formalParameters.length == 1); + final parameter = setter.formalParameters.single; // The parameter in the overridden setter may be a wildcard, in which case // we need to rename it, as we use the parameter when we pass it to // `Invocation.setter`. final parameterName = parameter.displayName == '_' ? '_value' : parameter.displayName; - builder.requiredParameters.add(Parameter((pBuilder) { - pBuilder.name = parameterName; - if (!parameter.type.containsPrivateName) { - pBuilder.type = _typeReference(parameter.type, - forceNullable: true, overrideVoid: true); - } - })); + builder.requiredParameters.add( + Parameter((pBuilder) { + pBuilder.name = parameterName; + if (!parameter.type.containsPrivateName) { + pBuilder.type = _typeReference( + parameter.type, + forceNullable: true, + overrideVoid: true, + ); + } + }), + ); if (parameter.type.containsPrivateName) { if (!mockTarget.unsupportedMembers.contains(nameWithEquals)) { // We shouldn't get here as this is guarded against in // [_MockTargetGatherer._checkFunction]. throw InvalidMockitoAnnotationException( - "Mockito cannot generate a valid override for '$nameWithEquals', " - 'as it has a private parameter type.'); - } - builder.body = refer('UnsupportedError') - .call([ - // Generate a raw string since nameWithEquals might contain a $. - literalString( - '"$nameWithEquals" cannot be used without a mockito fallback ' - 'generator.', - raw: true) - ]) - .thrown - .code; + "Mockito cannot generate a valid override for '$nameWithEquals', " + 'as it has a private parameter type.', + ); + } + builder.body = + refer('UnsupportedError') + .call([ + // Generate a raw string since nameWithEquals might contain a $. + literalString( + '"$nameWithEquals" cannot be used without a mockito fallback ' + 'generator.', + raw: true, + ), + ]) + .thrown + .code; return; } - final invocation = - referImported('Invocation', 'dart:core').property('setter').call([ - refer('#$name'), - refer(parameterName), - ]); + final invocation = referImported( + 'Invocation', + 'dart:core', + ).property('setter').call([refer('#$name'), refer(parameterName)]); final returnNoSuchMethod = refer('super') .property('noSuchMethod') .call([invocation], {'returnValueForMissingStub': refer('null')}); @@ -2045,19 +2320,21 @@ class _MockClassInfo { builder.body = returnNoSuchMethod.code; } - final List> _typeVariableScopes = []; + final List> _typeVariableScopes = []; final Set _usedTypeVariables = {}; - String _lookupTypeParameter(TypeParameterElement typeParameter) => + String _lookupTypeParameter(TypeParameterElement2 typeParameter) => _typeVariableScopes.reversed.firstWhereOrNull( - (scope) => scope.containsKey(typeParameter))?[typeParameter] ?? + (scope) => scope.containsKey(typeParameter), + )?[typeParameter] ?? (throw StateError( - '$typeParameter not found, scopes: $_typeVariableScopes')); + '$typeParameter not found, scopes: $_typeVariableScopes', + )); - String _newTypeVar(TypeParameterElement typeParameter) { + String _newTypeVar(TypeParameterElement2 typeParameter) { var idx = 0; while (true) { - final name = '${typeParameter.name}${idx == 0 ? '' : '$idx'}'; + final name = '${typeParameter.name3}${idx == 0 ? '' : '$idx'}'; if (!_usedTypeVariables.contains(name)) { _usedTypeVariables.add(name); return name; @@ -2079,9 +2356,11 @@ class _MockClassInfo { /// always correct. Unfortunately we can't just use the latter everywhere, /// since `type.typeFormals` don't contain default arguments' values /// and we need that for code generation. - T _withTypeParameters(Iterable typeParameters, - T Function(Iterable, Iterable) body, - {Iterable? typeFormalsHack}) { + T _withTypeParameters( + Iterable typeParameters, + T Function(Iterable, Iterable) body, { + Iterable? typeFormalsHack, + }) { final typeVars = [for (final t in typeParameters) _newTypeVar(t)]; final scope = Map.fromIterables(typeParameters, typeVars); _typeVariableScopes.add(scope); @@ -2093,8 +2372,9 @@ class _MockClassInfo { typeParameters = typeFormalsHack; } final typeRefsWithBounds = typeParameters.map(_typeParameterReference); - final typeRefs = - typeParameters.map((t) => _typeParameterReference(t, withBound: false)); + final typeRefs = typeParameters.map( + (t) => _typeParameterReference(t, withBound: false), + ); final result = body(typeRefsWithBounds, typeRefs); _typeVariableScopes.removeLast(); @@ -2108,8 +2388,10 @@ class _MockClassInfo { /// Create a reference for [typeParameter], properly referencing all types /// in bounds. - TypeReference _typeParameterReference(TypeParameterElement typeParameter, - {bool withBound = true}) { + TypeReference _typeParameterReference( + TypeParameterElement2 typeParameter, { + bool withBound = true, + }) { return TypeReference((b) { b.symbol = _lookupTypeParameter(typeParameter); if (withBound && typeParameter.bound != null) { @@ -2131,8 +2413,11 @@ class _MockClassInfo { /// * type variables. // TODO(srawlins): Contribute this back to a common location, like // package:source_gen? - Reference _typeReference(analyzer.DartType type, - {bool forceNullable = false, bool overrideVoid = false}) { + Reference _typeReference( + analyzer.DartType type, { + bool forceNullable = false, + bool overrideVoid = false, + }) { if (overrideVoid && type is analyzer.VoidType) { return TypeReference((b) => b..symbol = 'dynamic'); } @@ -2142,45 +2427,53 @@ class _MockClassInfo { if (type is analyzer.InterfaceType) { return TypeReference((b) { b - ..symbol = type.element.name - ..isNullable = !type.isDartCoreNull && + ..symbol = type.element3.name3 + ..isNullable = + !type.isDartCoreNull && (forceNullable || type.nullabilitySuffix == NullabilitySuffix.question) - ..url = _typeImport(type.element) + ..url = _typeImport(type.element3) ..types.addAll(type.typeArguments.map(_typeReference)); }); } else if (type is analyzer.FunctionType) { final alias = type.alias; - if (alias == null || alias.element.isPrivate) { + if (alias == null || alias.element2.isPrivate) { // [type] does not refer to a type alias, or it refers to a private type // alias; we must instead write out its signature. - return FunctionType((b) => - _withTypeParameters(type.typeFormals, (typeParams, _) { - b.types.addAll(typeParams); - b - ..isNullable = - forceNullable || typeSystem.isPotentiallyNullable(type) - ..returnType = _typeReference(type.returnType) - ..requiredParameters - .addAll(type.normalParameterTypes.map(_typeReference)) - ..optionalParameters - .addAll(type.optionalParameterTypes.map(_typeReference)); - for (final parameter - in type.parameters.where((p) => p.isOptionalNamed)) { - b.namedParameters[parameter.name] = - _typeReference(parameter.type); - } - for (final parameter - in type.parameters.where((p) => p.isRequiredNamed)) { - b.namedRequiredParameters[parameter.name] = - _typeReference(parameter.type); - } - })); + return FunctionType( + (b) => _withTypeParameters(type.typeParameters, (typeParams, _) { + b.types.addAll(typeParams); + b + ..isNullable = + forceNullable || typeSystem.isPotentiallyNullable(type) + ..returnType = _typeReference(type.returnType) + ..requiredParameters.addAll( + type.normalParameterTypes.map(_typeReference), + ) + ..optionalParameters.addAll( + type.optionalParameterTypes.map(_typeReference), + ); + for (final parameter in type.formalParameters.where( + (p) => p.isOptionalNamed, + )) { + b.namedParameters[parameter.name3!] = _typeReference( + parameter.type, + ); + } + for (final parameter in type.formalParameters.where( + (p) => p.isRequiredNamed, + )) { + b.namedRequiredParameters[parameter.name3!] = _typeReference( + parameter.type, + ); + } + }), + ); } return TypeReference((b) { b - ..symbol = alias.element.name - ..url = _typeImport(alias.element) + ..symbol = alias.element2.name3 + ..url = _typeImport(alias.element2) ..isNullable = forceNullable || typeSystem.isNullable(type); for (final typeArgument in alias.typeArguments) { b.types.add(_typeReference(typeArgument)); @@ -2189,33 +2482,41 @@ class _MockClassInfo { } else if (type is analyzer.TypeParameterType) { return TypeReference((b) { b - ..symbol = _lookupTypeParameter(type.element) + ..symbol = _lookupTypeParameter(type.element3) ..isNullable = forceNullable || typeSystem.isNullable(type); }); } else if (type is analyzer.RecordType) { - return RecordType((b) => b - ..positionalFieldTypes.addAll( - [for (final f in type.positionalFields) _typeReference(f.type)]) - ..namedFieldTypes.addAll( - {for (final f in type.namedFields) f.name: _typeReference(f.type)}) - ..isNullable = forceNullable || typeSystem.isNullable(type)); + return RecordType( + (b) => + b + ..positionalFieldTypes.addAll([ + for (final f in type.positionalFields) _typeReference(f.type), + ]) + ..namedFieldTypes.addAll({ + for (final f in type.namedFields) + f.name: _typeReference(f.type), + }) + ..isNullable = forceNullable || typeSystem.isNullable(type), + ); } else { - return referImported(type.getDisplayString(), _typeImport(type.element)); + return referImported(type.getDisplayString(), _typeImport(type.element3)); } } /// Returns the import URL for [element]. /// /// For some types, like `dynamic` and type variables, this may return null. - String? _typeImport(Element? element) { + String? _typeImport(Element2? element) { // For type variables, no import needed. - if (element is TypeParameterElement) return null; + if (element is TypeParameterElement2) return null; // For types like `dynamic`, return null; no import needed. - if (element?.library == null) return null; + if (element?.library2 == null) return null; - assert(mockLibraryInfo.assetUris.containsKey(element), - 'An element, "$element", is missing from the asset URI mapping'); + assert( + mockLibraryInfo.assetUris.containsKey(element), + 'An element, "$element", is missing from the asset URI mapping', + ); return mockLibraryInfo.assetUris[element] ?? (throw StateError('Asset URI is missing for $element')); @@ -2273,7 +2574,7 @@ class _AvoidConflictsAllocator implements Allocator { final Set _coreConflicts; _AvoidConflictsAllocator({required Set coreConflicts}) - : _coreConflicts = coreConflicts; + : _coreConflicts = coreConflicts; @override String allocate(Reference reference) { @@ -2292,16 +2593,14 @@ class _AvoidConflictsAllocator implements Allocator { @override Iterable get imports => [ - if (_imports.containsKey('dart:core')) - // 'dart:core' is explicitly imported to avoid a conflict between an - // overriding member and an element exported by 'dart:core'. We must - // add another, unprefixed, import for 'dart:core' which hides the - // conflicting names. - Directive.import('dart:core', hide: _coreConflicts.toList()), - ..._imports.keys.map( - (u) => Directive.import(u, as: '_i${_imports[u]}'), - ), - ]; + if (_imports.containsKey('dart:core')) + // 'dart:core' is explicitly imported to avoid a conflict between an + // overriding member and an element exported by 'dart:core'. We must + // add another, unprefixed, import for 'dart:core' which hides the + // conflicting names. + Directive.import('dart:core', hide: _coreConflicts.toList()), + ..._imports.keys.map((u) => Directive.import(u, as: '_i${_imports[u]}')), + ]; } /// A [MockBuilder] instance for use by `build.yaml`. @@ -2310,40 +2609,45 @@ Builder buildMocks(BuilderOptions options) { if (buildExtensions == null) return MockBuilder(); if (buildExtensions is! Map) { throw ArgumentError( - 'build_extensions should be a map from inputs to outputs'); + 'build_extensions should be a map from inputs to outputs', + ); } final result = >{}; for (final entry in buildExtensions.entries) { final input = entry.key; final output = entry.value; if (input is! String || !input.endsWith('.dart')) { - throw ArgumentError('Invalid key in build_extensions `$input`, it ' - 'should be a string ending with `.dart`'); + throw ArgumentError( + 'Invalid key in build_extensions `$input`, it ' + 'should be a string ending with `.dart`', + ); } if (output is! String || !output.endsWith('.mocks.dart')) { - throw ArgumentError('Invalid value in build_extensions `$output`, it ' - 'should be a string ending with `mocks.dart`'); + throw ArgumentError( + 'Invalid value in build_extensions `$output`, it ' + 'should be a string ending with `mocks.dart`', + ); } result[input] = [output]; } return MockBuilder(buildExtensions: result); } -extension on Element { +extension on Element2 { /// Returns the "full name" of a class or method element. String get fullName { - if (this is ClassElement) { - return "The class '$name'"; - } else if (this is EnumElement) { - return "The enum '$name'"; - } else if (this is MethodElement) { - final className = enclosingElement3!.name; - return "The method '$className.$name'"; - } else if (this is MixinElement) { - return "The mixin '$name'"; - } else if (this is PropertyAccessorElement) { - final className = enclosingElement3!.name; - return "The property accessor '$className.$name'"; + if (this is ClassElement2) { + return "The class '$name3'"; + } else if (this is EnumElement2) { + return "The enum '$name3'"; + } else if (this is MethodElement2) { + final className = enclosingElement2!.name3; + return "The method '$className.$name3'"; + } else if (this is MixinElement2) { + return "The mixin '$name3'"; + } else if (this is PropertyAccessorElement2) { + final className = enclosingElement2!.name3; + return "The property accessor '$className.$name3'"; } else { return 'unknown element'; } @@ -2360,11 +2664,11 @@ extension on analyzer.DartType { } else if (self is analyzer.InvalidType) { return false; } else if (self is analyzer.InterfaceType) { - return self.element.isPrivate || + return self.element3.isPrivate || self.typeArguments.any((t) => t.containsPrivateName); } else if (self is analyzer.FunctionType) { return self.returnType.containsPrivateName || - self.parameters.any((p) => p.type.containsPrivateName); + self.formalParameters.any((p) => p.type.containsPrivateName); } else if (self is analyzer.NeverType) { return false; } else if (self is analyzer.TypeParameterType) { @@ -2388,10 +2692,10 @@ extension on analyzer.DartType { /// Returns whether this type is a sealed type from the dart:typed_data /// library. bool get isDartTypedDataSealed { - if (element!.library!.name != 'dart.typed_data') { + if (element3!.library2!.name3 != 'dart.typed_data') { return false; } - final name = element!.name; + final name = element3!.name3; return name == 'Float32List' || name == 'Float64List' || name == 'Int8List' || @@ -2407,7 +2711,7 @@ extension on analyzer.DartType { } extension on TypeSystem { - bool _returnTypeIsNonNullable(ExecutableElement method) => + bool _returnTypeIsNonNullable(ExecutableElement2 method) => isPotentiallyNonNullable(method.returnType); // Returns whether [method] has at least one parameter whose type is @@ -2421,8 +2725,8 @@ extension on TypeSystem { // } // final c1 = C(); // m's parameter's type is nullable. // final c2 = C(); // m's parameter's type is non-nullable. - bool _hasNonNullableParameter(ExecutableElement method) => - method.parameters.any((p) => isPotentiallyNonNullable(p.type)); + bool _hasNonNullableParameter(ExecutableElement2 method) => + method.formalParameters.any((p) => isPotentiallyNonNullable(p.type)); } extension on int { @@ -2432,12 +2736,12 @@ extension on int { 1 => '${this}st', 2 => '${this}nd', 3 => '${this}rd', - _ => '${this}th' + _ => '${this}th', }; } } -bool _needsOverrideForVoidStub(ExecutableElement method) => +bool _needsOverrideForVoidStub(ExecutableElement2 method) => method.returnType is analyzer.VoidType || method.returnType.isFutureOfVoid; /// This casts `ElementAnnotation` to the internal `ElementAnnotationImpl` diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart index ddd9437d..de82ffec 100644 --- a/test/builder/auto_mocks_test.dart +++ b/test/builder/auto_mocks_test.dart @@ -49,7 +49,7 @@ class MockSpec { }) : mockName = as; } -''' +''', }; const mockitoAssets = { @@ -58,7 +58,7 @@ export 'src/mock.dart'; ''', 'mockito|lib/src/mock.dart': ''' class Mock {} -''' +''', }; const metaAssets = { @@ -68,7 +68,7 @@ class _Immutable { const _Immutable(); } const immutable = _Immutable(); -''' +''', }; const simpleTestAsset = { @@ -77,59 +77,80 @@ import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void main() {} -''' +''', }; void main() { late InMemoryAssetWriter writer; /// Test [MockBuilder] in a package which has opted into null safety. - Future testWithNonNullable(Map sourceAssets, - {Map>*/ Object>? outputs, - Map config = const {}}) async { + Future testWithNonNullable( + Map sourceAssets, { + Map>*/ Object>? outputs, + Map config = const {}, + }) async { final packageConfig = PackageConfig([ - Package('foo', Uri.file('/foo/'), - packageUriRoot: Uri.file('/foo/lib/'), - languageVersion: LanguageVersion(3, 3)) + Package( + 'foo', + Uri.file('/foo/'), + packageUriRoot: Uri.file('/foo/lib/'), + languageVersion: LanguageVersion(3, 3), + ), ]); - await testBuilder(buildMocks(BuilderOptions(config)), sourceAssets, - writer: writer, outputs: outputs, packageConfig: packageConfig); + await testBuilder( + buildMocks(BuilderOptions(config)), + sourceAssets, + writer: writer, + outputs: outputs, + packageConfig: packageConfig, + ); } /// Builds with [MockBuilder] in a package which has opted into null safety, /// returning the content of the generated mocks library. Future buildWithNonNullable(Map sourceAssets) async { final packageConfig = PackageConfig([ - Package('foo', Uri.file('/foo/'), - packageUriRoot: Uri.file('/foo/lib/'), - languageVersion: LanguageVersion(3, 3)) + Package( + 'foo', + Uri.file('/foo/'), + packageUriRoot: Uri.file('/foo/lib/'), + languageVersion: LanguageVersion(3, 3), + ), ]); - await testBuilder(buildMocks(BuilderOptions({})), sourceAssets, - writer: writer, packageConfig: packageConfig); + await testBuilder( + buildMocks(BuilderOptions({})), + sourceAssets, + writer: writer, + packageConfig: packageConfig, + ); final mocksAsset = AssetId('foo', 'test/foo_test.mocks.dart'); return utf8.decode(writer.assets[mocksAsset]!); } /// Test [MockBuilder] on a single source file, in a package which has opted /// into null safety, and with the non-nullable experiment enabled. - Future expectSingleNonNullableOutput(String sourceAssetText, - /*String|Matcher>*/ Object output) async { - await testWithNonNullable({ - ...metaAssets, - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': sourceAssetText, - }, outputs: { - 'foo|test/foo_test.mocks.dart': output - }); + Future expectSingleNonNullableOutput( + String sourceAssetText, + /*String|Matcher>*/ Object output, + ) async { + await testWithNonNullable( + { + ...metaAssets, + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': sourceAssetText, + }, + outputs: {'foo|test/foo_test.mocks.dart': output}, + ); } /// Builds with [MockBuilder] in a package which has opted into the /// non-nullable type system, returning the content of the generated mocks /// library. Future buildWithSingleNonNullableSource( - String sourceAssetText) async { + String sourceAssetText, + ) async { await testWithNonNullable({ ...annotationsAsset, ...simpleTestAsset, @@ -144,50 +165,69 @@ void main() { }); test( - 'generates a mock class but does not override methods w/ zero parameters', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + 'generates a mock class but does not override methods w/ zero parameters', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { dynamic method1() => 7; } - ''')); - expect(mocksContent, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect( + mocksContent, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('generates a mock class but does not override private methods', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'generates a mock class but does not override private methods', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int _method1(int x) => 8; } - ''')); - expect(mocksContent, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect( + mocksContent, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); test('generates a mock class but does not override static methods', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { static int method1(int y) => 9; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('method1'))); }); - test('generates a mock class but does not override any extension methods', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'generates a mock class but does not override any extension methods', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' extension X on Foo { dynamic x(int m, String n) => n + 1; } class Foo {} - ''')); - expect(mocksContent, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - }); + '''), + ); + expect( + mocksContent, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + }, + ); test('overrides methods, matching required positional parameters', () async { await expectSingleNonNullableOutput( @@ -207,13 +247,15 @@ void main() { void m(int a, [int b, int c = 0]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? a, [ int? b, int? c = 0, ]) => - ''')), + '''), + ), ); }); @@ -224,13 +266,15 @@ void main() { void m(int a, {int b, int c = 0}) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? a, { int? b, int? c = 0, }) => - ''')), + '''), + ), ); }); @@ -241,11 +285,13 @@ void main() { void m([int a, int b = 0]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ int? a, int? b = 0, - ]) =>''')), + ]) =>'''), + ), ); }); @@ -256,12 +302,14 @@ void main() { void m([bool a = true, bool b = false]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ bool? a = true, bool? b = false, ]) => - ''')), + '''), + ), ); }); @@ -272,12 +320,14 @@ void main() { void m([int a = 0, double b = 0.5]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ int? a = 0, double? b = 0.5, ]) => - ''')), + '''), + ), ); }); @@ -288,31 +338,37 @@ void main() { void m([String a = 'Hello', String b = "World"]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ String? a = 'Hello', String? b = 'World', ]) => - ''')), + '''), + ), ); }); - test('matches string literal parameter default values with quote characters', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches string literal parameter default values with quote characters', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([String a = 'Hel"lo', String b = "Wor'ld"]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ String? a = 'Hel"lo', String? b = 'Wor\\'ld', ]) => - ''')), - ); - }); + '''), + ), + ); + }, + ); test('matches raw string literal parameter default values', () async { await expectSingleNonNullableOutput( @@ -321,12 +377,14 @@ void main() { void m([String a = r'$Hello', String b = r"$World"]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ String? a = '\\\$Hello', String? b = '\\\$World', ]) => - ''')), + '''), + ), ); }); @@ -337,12 +395,14 @@ void main() { void m([List a = const [], Map b = const {}]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m([ List? a = const [], Map? b = const {}, ]) => - ''')), + '''), + ), ); }); @@ -353,14 +413,16 @@ void main() { void m([List a = const [1, 2, 3]]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( [List? a = const [ 1, 2, 3, ]]) => - ''')), + '''), + ), ); }); @@ -371,13 +433,15 @@ void main() { void m([Map a = const {1: 'a', 2: 'b'}]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( [Map? a = const { 1: 'a', 2: 'b', }]) => - ''')), + '''), + ), ); }); @@ -388,20 +452,23 @@ void main() { void m([Map a = const {1: 'a', 2: 'b'}]) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( [Map? a = const { 1: 'a', 2: 'b', }]) => - ''')), + '''), + ), ); }); - test('matches parameter default values constructed from a local class', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed from a local class', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([Bar a = const Bar()]) {} } @@ -409,28 +476,34 @@ void main() { const Bar(); } '''), - _containsAllOf( - 'void m([_i2.Bar? a = const _i2.Bar()]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([_i2.Bar? a = const _i2.Bar()]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed from a Dart SDK class', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed from a Dart SDK class', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([Duration a = const Duration(days: 1)]) {} } '''), - _containsAllOf( - 'void m([Duration? a = const Duration(days: 1)]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([Duration? a = const Duration(days: 1)]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed from a named constructor', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed from a named constructor', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([Bar a = const Bar.named()]) {} } @@ -438,15 +511,18 @@ void main() { const Bar.named(); } '''), - _containsAllOf( - 'void m([_i2.Bar? a = const _i2.Bar.named()]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([_i2.Bar? a = const _i2.Bar.named()]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed with positional arguments', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed with positional arguments', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([Bar a = const Bar(7)]) {} } @@ -455,15 +531,18 @@ void main() { const Bar(this.i); } '''), - _containsAllOf( - 'void m([_i2.Bar? a = const _i2.Bar(7)]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([_i2.Bar? a = const _i2.Bar(7)]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed with named arguments', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed with named arguments', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([Bar a = const Bar(i: 7)]) {} } @@ -472,51 +551,60 @@ void main() { const Bar({this.i}); } '''), - _containsAllOf( - 'void m([_i2.Bar? a = const _i2.Bar(i: 7)]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([_i2.Bar? a = const _i2.Bar(i: 7)]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed with top-level variable', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed with top-level variable', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { void m([int a = x]) {} } const x = 1; '''), - _containsAllOf('void m([int? a = 1]) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m([int? a = 1]) => super.noSuchMethod('), + ); + }, + ); - test('matches parameter default values constructed with top-level function', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed with top-level function', + () async { + await expectSingleNonNullableOutput( + dedent(r''' typedef Callback = void Function(); void defaultCallback() {} class Foo { void m([Callback a = defaultCallback]) {} } '''), - _containsAllOf( - 'void m([_i2.Callback? a = _i2.defaultCallback]) => super.noSuchMethod('), - ); - }); + _containsAllOf( + 'void m([_i2.Callback? a = _i2.defaultCallback]) => super.noSuchMethod(', + ), + ); + }, + ); - test('matches parameter default values constructed with static field', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches parameter default values constructed with static field', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { static const x = 1; void m([int a = x]) {} } '''), - _containsAllOf('void m([int? a = 1]) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m([int? a = 1]) => super.noSuchMethod('), + ); + }, + ); test('throws when given a parameter default value using a private type', () { _expectBuilderThrows( @@ -534,14 +622,14 @@ void main() { '''), }, message: contains( - "Mockito cannot generate a valid override for method 'Foo.m'; " - "parameter 'a' causes a problem: default value has a private type: " - 'asset:foo/lib/foo.dart#_Bar'), + "Mockito cannot generate a valid override for method 'Foo.m'; " + "parameter 'a' causes a problem: default value has a private type: " + 'asset:foo/lib/foo.dart#_Bar', + ), ); }); - test( - 'throws when given a parameter default value using a private type, and ' + test('throws when given a parameter default value using a private type, and ' 'refers to the class-to-mock', () { _expectBuilderThrows( assets: { @@ -559,20 +647,21 @@ void main() { '''), }, message: contains( - "Mockito cannot generate a valid override for method 'Foo.m'; " - "parameter 'a' causes a problem: default value has a private type: " - 'asset:foo/lib/foo.dart#_Bar'), + "Mockito cannot generate a valid override for method 'Foo.m'; " + "parameter 'a' causes a problem: default value has a private type: " + 'asset:foo/lib/foo.dart#_Bar', + ), ); }); test( - 'throws when given a parameter default value using a private constructor', - () { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': dedent(r''' + 'throws when given a parameter default value using a private constructor', + () { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': dedent(r''' class Foo { void m([Bar a = const Bar._named()]) {} } @@ -580,13 +669,15 @@ void main() { const Bar._named(); } '''), - }, - message: contains( + }, + message: contains( "Mockito cannot generate a valid override for method 'Foo.m'; " "parameter 'a' causes a problem: default value has a private type: " - 'asset:foo/lib/foo.dart#Bar::_named'), - ); - }); + 'asset:foo/lib/foo.dart#Bar::_named', + ), + ); + }, + ); test('throws when given a parameter default value which is a type', () { _expectBuilderThrows( @@ -599,9 +690,11 @@ void main() { } '''), }, - message: contains('Mockito cannot generate a valid override for method ' - "'Foo.m'; parameter 'a' causes a problem: default value is a Type: " - 'int'), + message: contains( + 'Mockito cannot generate a valid override for method ' + "'Foo.m'; parameter 'a' causes a problem: default value is a Type: " + 'int', + ), ); }); @@ -650,18 +743,20 @@ void main() { ); }); - test('overrides methods of generic super classes, substituting types', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'overrides methods of generic super classes, substituting types', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class FooBase { void m(T a) {} } class Foo extends FooBase {} '''), - _containsAllOf('void m(int? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(int? a) => super.noSuchMethod('), + ); + }, + ); test('overrides methods of mixed in classes, substituting types', () async { await expectSingleNonNullableOutput( @@ -688,10 +783,11 @@ void main() { ); }); - test('overrides mixed in methods, using correct overriding signature', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'overrides mixed in methods, using correct overriding signature', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Base { void m(int a) {} } @@ -702,9 +798,10 @@ void main() { } class Foo with MixinConstraint, Mixin {} '''), - _containsAllOf('void m(num? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(num? a) => super.noSuchMethod('), + ); + }, + ); test('overrides methods of implemented classes', () async { await expectSingleNonNullableOutput( @@ -734,19 +831,20 @@ void main() { }); test( - 'overrides methods of indirect generic super classes, substituting types', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + 'overrides methods of indirect generic super classes, substituting types', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class FooBase2 { void m(T a) {} } class FooBase1 extends FooBase2 {} class Foo extends FooBase2 {} '''), - _containsAllOf('void m(int? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(int? a) => super.noSuchMethod('), + ); + }, + ); test('overrides methods of generic super classes using void', () async { await expectSingleNonNullableOutput( @@ -772,9 +870,10 @@ void main() { ); }); - test('overrides methods, adjusting imports for names that conflict with core', - () async { - await expectSingleNonNullableOutput( + test( + 'overrides methods, adjusting imports for names that conflict with core', + () async { + await expectSingleNonNullableOutput( dedent(''' import 'dart:core' as core; class Foo { @@ -785,11 +884,12 @@ void main() { _containsAllOf( ' void List(int? a) => super.noSuchMethod(\n', ' _i3.List m() => (super.noSuchMethod(\n', - )); - }); + ), + ); + }, + ); - test( - 'overrides `toString` with a correct signature if the class overrides ' + test('overrides `toString` with a correct signature if the class overrides ' 'it', () async { await expectSingleNonNullableOutput( dedent(''' @@ -801,19 +901,19 @@ void main() { ); }); - test( - 'does not override `toString` if the class does not override `toString` ' + test('does not override `toString` if the class does not override `toString` ' 'with additional parameters', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' abstract class Foo { String toString() => 'Foo'; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('toString'))); }); - test( - 'overrides `toString` with a correct signature if a mixed in class ' + test('overrides `toString` with a correct signature if a mixed in class ' 'overrides it, in a Fake', () async { await expectSingleNonNullableOutput( dedent(''' @@ -829,25 +929,33 @@ void main() { ); }); - test('does not override `operator==`, even if the class overrides it', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + test( + 'does not override `operator==`, even if the class overrides it', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' class Foo { bool operator==(Object? other); } - ''')); - expect(mocksContent, isNot(contains('=='))); - }); + '''), + ); + expect(mocksContent, isNot(contains('=='))); + }, + ); - test('does not override `hashCode`, even if the class overrides it', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + test( + 'does not override `hashCode`, even if the class overrides it', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' class Foo { final int hashCode = 7; } - ''')); - expect(mocksContent, isNot(contains('hashCode'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('hashCode'))); + }, + ); test('generates mock classes from part files', () async { final mocksOutput = await buildWithNonNullable({ @@ -864,57 +972,64 @@ void main() { part of 'foo_test.dart'; @GenerateMocks([Foo]) void fooTests() {} - ''' + ''', }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); }); test('does not crash upon finding non-library files', () async { - await testWithNonNullable( - { - ...annotationsAsset, - 'foo|lib/foo.dart': dedent('class Foo {}'), - 'foo|test/foo_test.dart': "part 'part.dart';", - 'foo|test/part.dart': "part of 'foo_test.dart';", - }, - outputs: {}, - ); + await testWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent('class Foo {}'), + 'foo|test/foo_test.dart': "part 'part.dart';", + 'foo|test/part.dart': "part of 'foo_test.dart';", + }, outputs: {}); }); - test('generates mock classes from an annotation on an import directive', - () async { - final mocksOutput = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': dedent(r'class Foo {} class Bar {}'), - 'foo|test/foo_test.dart': ''' + test( + 'generates mock classes from an annotation on an import directive', + () async { + final mocksOutput = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r'class Foo {} class Bar {}'), + 'foo|test/foo_test.dart': ''' @GenerateMocks([Foo]) import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; - ''' - }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - }); + ''', + }); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + }, + ); - test('generates mock classes from an annotation on an export directive', - () async { - final mocksOutput = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': dedent(r''' + test( + 'generates mock classes from an annotation on an export directive', + () async { + final mocksOutput = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' class Foo {} class Bar {} '''), - 'foo|test/foo_test.dart': ''' + 'foo|test/foo_test.dart': ''' @GenerateMocks([Foo]) export 'dart:core'; import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; - ''' - }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - }); + ''', + }); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + }, + ); test('generates multiple mock classes', () async { final mocksOutput = await buildWithNonNullable({ @@ -928,12 +1043,16 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo, Bar]) void main() {} - ''' + ''', }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - expect(mocksOutput, - contains('class MockBar extends _i1.Mock implements _i2.Bar')); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect( + mocksOutput, + contains('class MockBar extends _i1.Mock implements _i2.Bar'), + ); }); test('generates mock classes from multiple annotations', () async { @@ -950,44 +1069,56 @@ void main() { void fooTests() {} @GenerateMocks([Bar]) void barTests() {} - ''' + ''', }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - expect(mocksOutput, - contains('class MockBar extends _i1.Mock implements _i2.Bar')); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect( + mocksOutput, + contains('class MockBar extends _i1.Mock implements _i2.Bar'), + ); }); - test('generates mock classes from multiple annotations on a single element', - () async { - final mocksOutput = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': dedent(r''' + test( + 'generates mock classes from multiple annotations on a single element', + () async { + final mocksOutput = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' class Foo {} class Bar {} '''), - 'foo|test/foo_test.dart': ''' + 'foo|test/foo_test.dart': ''' import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) @GenerateMocks([Bar]) void barTests() {} - ''' - }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - expect(mocksOutput, - contains('class MockBar extends _i1.Mock implements _i2.Bar')); - }); + ''', + }); + expect( + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect( + mocksOutput, + contains('class MockBar extends _i1.Mock implements _i2.Bar'), + ); + }, + ); test('generates generic mock classes', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo {} - ''')); + '''), + ); expect( - mocksContent, - contains( - 'class MockFoo extends _i1.Mock implements _i2.Foo')); + mocksContent, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); }); test('generates generic mock classes with type bounds', () async { @@ -1002,14 +1133,19 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo, Bar]) void main() {} - ''' + ''', }); - expect(mocksOutput, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); expect( - mocksOutput, - contains('class MockBar extends _i1.Mock ' - 'implements _i2.Bar')); + mocksOutput, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + expect( + mocksOutput, + contains( + 'class MockBar extends _i1.Mock ' + 'implements _i2.Bar', + ), + ); }); test('writes dynamic, void w/o import prefix', () async { @@ -1019,12 +1155,14 @@ void main() { void m(dynamic a, int b) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( dynamic a, int? b, ) => - ''')), + '''), + ), ); }); @@ -1051,204 +1189,229 @@ void main() { }); test('imports libraries for external class types', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { dynamic f(List list) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'package:foo/foo.dart' as _i2;")); expect(mocksContent, contains('implements _i2.Foo')); expect(mocksContent, contains('List<_i2.Foo>? list')); }); - test('imports libraries for external class types declared in parts', - () async { - final mocksContent = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': dedent(r''' + test( + 'imports libraries for external class types declared in parts', + () async { + final mocksContent = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' part 'foo_part.dart'; '''), - 'foo|lib/foo_part.dart': dedent(r''' + 'foo|lib/foo_part.dart': dedent(r''' part of 'foo.dart'; class Foo {} '''), - 'foo|test/foo_test.dart': ''' + 'foo|test/foo_test.dart': ''' import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void fooTests() {} - ''' - }); - expect(mocksContent, contains("import 'package:foo/foo.dart' as _i2;")); - expect(mocksContent, - contains('class MockFoo extends _i1.Mock implements _i2.Foo')); - }); + ''', + }); + expect(mocksContent, contains("import 'package:foo/foo.dart' as _i2;")); + expect( + mocksContent, + contains('class MockFoo extends _i1.Mock implements _i2.Foo'), + ); + }, + ); - test( - 'imports libraries for external class types found in a method return ' + test('imports libraries for external class types found in a method return ' 'type', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { Future f() async {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('_i3.Future f()')); }); - test('imports libraries for external class types found in a type argument', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'imports libraries for external class types found in a type argument', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { List f() => []; } - ''')); - expect(mocksContent, contains("import 'dart:async' as _i3;")); - expect(mocksContent, contains('List<_i3.Future> f()')); - }); + '''), + ); + expect(mocksContent, contains("import 'dart:async' as _i3;")); + expect(mocksContent, contains('List<_i3.Future> f()')); + }, + ); - test( - 'imports libraries for external class types found in the return type of ' + test('imports libraries for external class types found in the return type of ' 'a function-typed parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(Future a()) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('f(_i3.Future Function()? a)')); }); test( - 'imports libraries for external class types found in a parameter type of ' - 'a function-typed parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + 'imports libraries for external class types found in a parameter type of ' + 'a function-typed parameter', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(void a(Future b)) {} } - ''')); - expect(mocksContent, contains("import 'dart:async' as _i3;")); - expect(mocksContent, contains('f(void Function(_i3.Future)? a)')); - }); + '''), + ); + expect(mocksContent, contains("import 'dart:async' as _i3;")); + expect(mocksContent, contains('f(void Function(_i3.Future)? a)')); + }, + ); - test( - 'imports libraries for external class types found in a function-typed ' + test('imports libraries for external class types found in a function-typed ' 'parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(Future a()) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('f(_i3.Future Function()? a)')); }); - test( - 'imports libraries for external class types found in a FunctionType ' + test('imports libraries for external class types found in a FunctionType ' 'parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(Future Function() a) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('f(_i3.Future Function()? a)')); }); - test( - 'imports libraries for external class types found nested in a ' + test('imports libraries for external class types found nested in a ' 'function-typed parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(void a(Future b)) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('f(void Function(_i3.Future)? a)')); }); - test( - 'imports libraries for external class types found in the bound of a ' + test('imports libraries for external class types found in the bound of a ' 'type parameter of a method', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; class Foo { void f(T a) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('f>(T? a)')); }); - test( - 'imports libraries for external class types found in the default value ' + test('imports libraries for external class types found in the default value ' 'of a parameter', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:convert'; class Foo { void f([Object a = utf8]) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:convert' as _i3;")); expect(mocksContent, contains('f([Object? a = const _i3.Utf8Codec()])')); }); test( - 'imports libraries for external class types found in an inherited method', - () async { - await testWithNonNullable({ - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': ''' + 'imports libraries for external class types found in an inherited method', + () async { + await testWithNonNullable({ + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': ''' import 'bar.dart'; class Foo extends Bar {} ''', - 'foo|lib/bar.dart': ''' + 'foo|lib/bar.dart': ''' import 'dart:async'; class Bar { m(Future a) {} } ''', - }); - final mocksAsset = AssetId('foo', 'test/foo_test.mocks.dart'); - final mocksContent = utf8.decode(writer.assets[mocksAsset]!); - expect(mocksContent, contains("import 'dart:async' as _i3;")); - expect(mocksContent, contains('m(_i3.Future? a)')); - }); + }); + final mocksAsset = AssetId('foo', 'test/foo_test.mocks.dart'); + final mocksContent = utf8.decode(writer.assets[mocksAsset]!); + expect(mocksContent, contains("import 'dart:async' as _i3;")); + expect(mocksContent, contains('m(_i3.Future? a)')); + }, + ); test( - 'imports libraries for external class types found in an inherited method ' - 'via a generic instantiation', () async { - await testWithNonNullable({ - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': ''' + 'imports libraries for external class types found in an inherited method ' + 'via a generic instantiation', + () async { + await testWithNonNullable({ + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': ''' import 'dart:async'; import 'bar.dart'; class Foo extends Bar> {} ''', - 'foo|lib/bar.dart': ''' + 'foo|lib/bar.dart': ''' class Bar { m(T a) {} } ''', - }); - final mocksAsset = AssetId('foo', 'test/foo_test.mocks.dart'); - final mocksContent = utf8.decode(writer.assets[mocksAsset]!); - expect(mocksContent, contains("import 'dart:async' as _i3;")); - expect(mocksContent, contains('m(_i3.Future? a)')); - }); + }); + final mocksAsset = AssetId('foo', 'test/foo_test.mocks.dart'); + final mocksContent = utf8.decode(writer.assets[mocksAsset]!); + expect(mocksContent, contains("import 'dart:async' as _i3;")); + expect(mocksContent, contains('m(_i3.Future? a)')); + }, + ); test('imports libraries for type aliases with external types', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; typedef Callback = void Function(); typedef void Callback2(); @@ -1258,7 +1421,8 @@ void main() { dynamic g(Callback2 c) {} dynamic h(Callback3 c) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'package:foo/foo.dart' as _i2;")); expect(mocksContent, contains('implements _i2.Foo')); expect(mocksContent, contains('_i2.Callback? c')); @@ -1267,14 +1431,16 @@ void main() { }); test('imports libraries for type aliases with external types 2', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' import 'dart:async'; typedef Ignore = String Function(int); class Foo { dynamic f(Ignore> c) {} dynamic g(Ignore c) {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'package:foo/foo.dart' as _i2;")); expect(mocksContent, contains("import 'dart:async' as _i3;")); expect(mocksContent, contains('implements _i2.Foo')); @@ -1282,40 +1448,46 @@ void main() { expect(mocksContent, contains('_i2.Ignore<_i3.Future>? c')); }); - test('imports libraries for types declared in private SDK libraries', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + test( + 'imports libraries for types declared in private SDK libraries', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' import 'dart:io'; abstract class Foo { HttpClient f() {} } - ''')); - expect(mocksContent, contains("import 'dart:io' as _i2;")); - expect(mocksContent, contains('_i2.HttpClient f() =>')); - }); + '''), + ); + expect(mocksContent, contains("import 'dart:io' as _i2;")); + expect(mocksContent, contains('_i2.HttpClient f() =>')); + }, + ); - test( - 'imports libraries for types declared in private SDK libraries exported ' + test('imports libraries for types declared in private SDK libraries exported ' 'in dart:io', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' import 'dart:io'; abstract class Foo { HttpStatus f() {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:io' as _i2;")); expect(mocksContent, contains('_i2.HttpStatus f() =>')); }); - test( - 'imports libraries for types declared in private SDK libraries exported ' + test('imports libraries for types declared in private SDK libraries exported ' 'in dart:html', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' import 'dart:html'; abstract class Foo { HttpStatus f() {} } - ''')); + '''), + ); expect(mocksContent, contains("import 'dart:html' as _i2;")); expect(mocksContent, contains('_i2.HttpStatus f() =>')); }); @@ -1346,22 +1518,24 @@ void main() { expect(mocksContent, contains('m(_i3.Bar? a)')); }); - test('imports dart:core with a prefix when members conflict with dart:core', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'imports dart:core with a prefix when members conflict with dart:core', + () async { + await expectSingleNonNullableOutput( + dedent(''' import 'dart:core' as core; class Foo { void List(int a) {} core.List m() => []; } '''), - _containsAllOf( - "import 'dart:core' hide List;", - "import 'dart:core' as _i3;", - ), - ); - }); + _containsAllOf( + "import 'dart:core' hide List;", + "import 'dart:core' as _i3;", + ), + ); + }, + ); test('prefixes parameter type on generic function-typed parameter', () async { await expectSingleNonNullableOutput( @@ -1371,7 +1545,8 @@ void main() { } '''), _containsAllOf( - 'dynamic m(void Function(_i2.Foo)? a) => super.noSuchMethod(Invocation.method('), + 'dynamic m(void Function(_i2.Foo)? a) => super.noSuchMethod(Invocation.method(', + ), ); }); @@ -1394,7 +1569,8 @@ void main() { } '''), _containsAllOf( - 'void m(void Function(_i2.Foo)? a) => super.noSuchMethod('), + 'void m(void Function(_i2.Foo)? a) => super.noSuchMethod(', + ), ); }); @@ -1430,17 +1606,18 @@ void main() { void m(int? a, int b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? a, int? b, ) => - ''')), + '''), + ), ); }); - test( - 'widens the type of potentially non-nullable type variables to be ' + test('widens the type of potentially non-nullable type variables to be ' 'nullable', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -1448,12 +1625,14 @@ void main() { void m(int? a, T b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? a, T? b, ) => - ''')), + '''), + ), ); }); @@ -1472,10 +1651,10 @@ void main() { }); test( - 'widens the type of covariant parameters with default values to be nullable', - () async { - await expectSingleNonNullableOutput( - dedent(''' + 'widens the type of covariant parameters with default values to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class FooBase { void m([num a = 0]); } @@ -1483,12 +1662,12 @@ void main() { void m([covariant int a = 0]); } '''), - _containsAllOf('void m([num? a = 0]) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m([num? a = 0]) => super.noSuchMethod('), + ); + }, + ); - test( - 'widens the type of covariant parameters (declared covariant in a ' + test('widens the type of covariant parameters (declared covariant in a ' 'superclass) to be nullable', () async { await expectSingleNonNullableOutput( dedent(''' @@ -1503,10 +1682,11 @@ void main() { ); }); - test('widens the type of successively covariant parameters to be nullable', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'widens the type of successively covariant parameters to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class FooBaseBase { void m(Object a); } @@ -1517,15 +1697,16 @@ void main() { void m(covariant int a); } '''), - _containsAllOf('void m(Object? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(Object? a) => super.noSuchMethod('), + ); + }, + ); test( - 'widens the type of covariant parameters, overriding a mixin, to be nullable', - () async { - await expectSingleNonNullableOutput( - dedent(''' + 'widens the type of covariant parameters, overriding a mixin, to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' mixin FooMixin { void m(num a); } @@ -1533,15 +1714,17 @@ void main() { void m(covariant int a); } '''), - _containsAllOf('void m(num? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(num? a) => super.noSuchMethod('), + ); + }, + ); test( - "widens the type of covariant parameters, which don't have corresponding " - 'parameters in all overridden methods, to be nullable', () async { - await expectSingleNonNullableOutput( - dedent(''' + "widens the type of covariant parameters, which don't have corresponding " + 'parameters in all overridden methods, to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class FooBaseBase { void m(); } @@ -1552,14 +1735,16 @@ void main() { void m([covariant int a]); } '''), - _containsAllOf('void m([num? a]) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m([num? a]) => super.noSuchMethod('), + ); + }, + ); - test('widens the type of covariant named parameters to be nullable', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'widens the type of covariant named parameters to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class FooBase extends FooBaseBase { void m({required num a}); } @@ -1567,14 +1752,16 @@ void main() { void m({required covariant int a}); } '''), - _containsAllOf('void m({required num? a}) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m({required num? a}) => super.noSuchMethod('), + ); + }, + ); - test('widens the type of covariant generic parameters to be nullable', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'widens the type of covariant generic parameters to be nullable', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class FooBase { void m(Object a); } @@ -1582,9 +1769,10 @@ void main() { void m(covariant T a); } '''), - _containsAllOf('void m(Object? a) => super.noSuchMethod('), - ); - }); + _containsAllOf('void m(Object? a) => super.noSuchMethod('), + ); + }, + ); test('matches nullability of type arguments of a parameter', () async { await expectSingleNonNullableOutput( @@ -1593,17 +1781,18 @@ void main() { void m(List a, List b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( List? a, List? b, ) => - ''')), + '''), + ), ); }); - test( - 'matches nullability of return type of a generic function-typed ' + test('matches nullability of return type of a generic function-typed ' 'parameter', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -1611,31 +1800,33 @@ void main() { void m(int? Function() a, int Function() b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? Function()? a, int Function()? b, ) => - ''')), + '''), + ), ); }); test( - 'matches nullability of return type of FutureOr for potentially nullable T', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + 'matches nullability of return type of FutureOr for potentially nullable T', + () async { + await expectSingleNonNullableOutput( + dedent(r''' import 'dart:async'; abstract class Foo { FutureOr m(); } '''), - _containsAllOf('_i2.FutureOr m() => (super.noSuchMethod('), - ); - }); + _containsAllOf('_i2.FutureOr m() => (super.noSuchMethod('), + ); + }, + ); - test( - 'matches nullability of parameter types within a generic function-typed ' + test('matches nullability of parameter types within a generic function-typed ' 'parameter', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -1643,34 +1834,39 @@ void main() { void m(void Function(int?) a, void Function(int) b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( void Function(int?)? a, void Function(int)? b, ) => - ''')), + '''), + ), ); }); - test('matches nullability of return type of a function-typed parameter', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'matches nullability of return type of a function-typed parameter', + () async { + await expectSingleNonNullableOutput( + dedent(r''' abstract class Foo { void m(int? a(), int b()); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( int? Function()? a, int Function()? b, ) => - ''')), - ); - }); + '''), + ), + ); + }, + ); - test( - 'matches nullability of parameter types within a function-typed ' + test('matches nullability of parameter types within a function-typed ' 'parameter', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -1678,26 +1874,29 @@ void main() { void m(void a(int? x), void b(int x)); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( void Function(int?)? a, void Function(int)? b, ) => - ''')), + '''), + ), ); }); - test( - 'matches requiredness of parameter types within a function-typed ' + test('matches requiredness of parameter types within a function-typed ' 'parameter', () async { await expectSingleNonNullableOutput( - dedent(''' + dedent(''' class Foo { void m(void Function({required int p}) cb) {} } '''), - _containsAllOf( - 'void m(void Function({required int p})? cb) => super.noSuchMethod(')); + _containsAllOf( + 'void m(void Function({required int p})? cb) => super.noSuchMethod(', + ), + ); }); test('matches nullability of a generic parameter', () async { @@ -1707,12 +1906,14 @@ void main() { void m(T? a, T b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( T? a, T? b, ) => - ''')), + '''), + ), ); }); @@ -1723,12 +1924,14 @@ void main() { void m(dynamic a, int b); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void m( dynamic a, int? b, ) => - ''')), + '''), + ), ); }); @@ -1784,7 +1987,8 @@ void main() { } '''), _containsAllOf( - 'dynamic m(int? a) => super.noSuchMethod(Invocation.method('), + 'dynamic m(int? a) => super.noSuchMethod(Invocation.method(', + ), ); }); @@ -1796,108 +2000,144 @@ void main() { } '''), _containsAllOf( - 'dynamic f(int? a) => super.noSuchMethod(Invocation.method('), + 'dynamic f(int? a) => super.noSuchMethod(Invocation.method(', + ), ); }); test('does not override methods with all nullable parameters', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(int? p) => null; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('method1'))); }); - test('does not override methods with all nullable parameters (dynamic)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with all nullable parameters (dynamic)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(dynamic p) => null; } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('does not override methods with all nullable parameters (var untyped)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with all nullable parameters (var untyped)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(var p) => null; } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('does not override methods with all nullable parameters (final untyped)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with all nullable parameters (final untyped)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(final p) => null; } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('does not override methods with all nullable parameters (type variable)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with all nullable parameters (type variable)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(T? p) => null; } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); test( - 'does not override methods with all nullable parameters (function-typed)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + 'does not override methods with all nullable parameters (function-typed)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? method1(int Function()? p) => null; } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('does not override methods with an implicit dynamic return type', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with an implicit dynamic return type', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' abstract class Foo { method1(); } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); - test('does not override methods with an explicit dynamic return type', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with an explicit dynamic return type', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' abstract class Foo { dynamic method1(); } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); test('does not override methods with a nullable return type', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' abstract class Foo { int? method1(); } - ''')); + '''), + ); expect(mocksContent, isNot(contains('method1'))); }); - test('does not override methods with a nullable return type (type variable)', - () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + test( + 'does not override methods with a nullable return type (type variable)', + () async { + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' abstract class Foo { T? method1(); } - ''')); - expect(mocksContent, isNot(contains('method1'))); - }); + '''), + ); + expect(mocksContent, isNot(contains('method1'))); + }, + ); test('overrides methods with a non-nullable return type', () async { await expectSingleNonNullableOutput( @@ -1906,7 +2146,8 @@ void main() { int m(); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int m() => (super.noSuchMethod( Invocation.method( #m, @@ -1914,19 +2155,22 @@ void main() { ), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); test('overrides inherited methods with a non-nullable return type', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class FooBase { num m() => 7; } class Foo extends FooBase { int m() => 7; } - ''')); + '''), + ); expect(mocksContent, contains('int m()')); expect(mocksContent, isNot(contains('num m()'))); }); @@ -1943,24 +2187,28 @@ void main() { '''), }, outputs: { - 'foo|test/foo_test.mocks.dart': _containsAllOf(dedent2(''' + 'foo|test/foo_test.mocks.dart': _containsAllOf( + dedent2(''' void m(T? a) => super.noSuchMethod( Invocation.method( #m, [a], ), - ''')), + '''), + ), }, ); }); test('overrides generic methods', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { dynamic f(int a) {} dynamic g(int a) {} } - ''')); + '''), + ); expect(mocksContent, contains('dynamic f(int? a) =>')); expect(mocksContent, contains('dynamic g(int? a) =>')); }); @@ -1972,21 +2220,25 @@ void main() { int get m => 7; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int get m => (super.noSuchMethod( Invocation.getter(#m), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); test('does not override nullable instance getters', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? get getter1 => 7; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('getter1'))); }); @@ -1998,24 +2250,28 @@ void main() { } class Foo extends FooBase {} '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int get m => (super.noSuchMethod( Invocation.getter(#m), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); test('overrides inherited instance getters only once', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' class FooBase { num get m => 7; } class Foo extends FooBase { int get m => 7; } - ''')); + '''), + ); expect(mocksContent, contains('int get m')); expect(mocksContent, isNot(contains('num get m'))); }); @@ -2027,7 +2283,8 @@ void main() { void set m(int a) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' set m(int? a) => super.noSuchMethod( Invocation.setter( #m, @@ -2035,7 +2292,8 @@ void main() { ), returnValueForMissingStub: null, ); - ''')), + '''), + ), ); }); @@ -2046,7 +2304,8 @@ void main() { void set m(int? a) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' set m(int? a) => super.noSuchMethod( Invocation.setter( #m, @@ -2054,26 +2313,31 @@ void main() { ), returnValueForMissingStub: null, ); - ''')), + '''), + ), ); }); - test('overrides nullable instance setters with wildcard parameters', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'overrides nullable instance setters with wildcard parameters', + () async { + await expectSingleNonNullableOutput( + dedent(''' class Foo { void set m(int? _) {} } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' set m(int? _value) => super.noSuchMethod( Invocation.setter(#m, _value), returnValueForMissingStub: null, ); - ''')), - ); - }); + '''), + ), + ); + }, + ); test('overrides inherited non-nullable instance setters', () async { await expectSingleNonNullableOutput( @@ -2083,7 +2347,8 @@ void main() { } class Foo extends FooBase {} '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' set m(int? a) => super.noSuchMethod( Invocation.setter( #m, @@ -2091,19 +2356,22 @@ void main() { ), returnValueForMissingStub: null, ); - ''')), + '''), + ), ); }); test('overrides inherited non-nullable instance setters only once', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' class FooBase { set m(int a) {} } class Foo extends FooBase { set m(num a) {} } - ''')); + '''), + ); expect(mocksContent, contains('set m(num? a)')); expect(mocksContent, isNot(contains('set m(int? a)'))); }); @@ -2115,12 +2383,14 @@ void main() { int m; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int get m => (super.noSuchMethod( Invocation.getter(#m), returnValue: 0, ) as int); - '''), dedent2(''' + '''), + dedent2(''' set m(int? _m) => super.noSuchMethod( Invocation.setter( #m, @@ -2128,7 +2398,8 @@ void main() { ), returnValueForMissingStub: null, ); - ''')), + '''), + ), ); }); @@ -2140,12 +2411,14 @@ void main() { } class Foo extends FooBase {} '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int get m => (super.noSuchMethod( Invocation.getter(#m), returnValue: 0, ) as int); - '''), dedent2(''' + '''), + dedent2(''' set m(int? _m) => super.noSuchMethod( Invocation.setter( #m, @@ -2153,12 +2426,14 @@ void main() { ), returnValueForMissingStub: null, ); - ''')), + '''), + ), ); }); test('overrides inherited non-nullable fields only once', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(''' class FooBase { num m; } @@ -2166,7 +2441,8 @@ void main() { int get m => 7; void set m(covariant int value) {} } - ''')); + '''), + ); expect(mocksContent, contains('int get m')); expect(mocksContent, contains('set m(int? value)')); expect(mocksContent, isNot(contains('num get m'))); @@ -2181,39 +2457,47 @@ void main() { Foo(this.m); } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int get m => (super.noSuchMethod( Invocation.getter(#m), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); test('does not override getters for nullable fields', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int? field1; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('get field1'))); }); test('does not override private fields', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { int _field1; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('int _field1'))); }); test('does not override static fields', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { static int field1; } - ''')); + '''), + ); expect(mocksContent, isNot(contains('int field1'))); }); @@ -2224,7 +2508,8 @@ void main() { int operator +(Foo other) => 7; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int operator +(_i2.Foo? other) => (super.noSuchMethod( Invocation.method( #+, @@ -2232,7 +2517,8 @@ void main() { ), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); @@ -2243,7 +2529,8 @@ void main() { int operator [](int x) => 7; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int operator [](int? x) => (super.noSuchMethod( Invocation.method( #[], @@ -2251,7 +2538,8 @@ void main() { ), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); @@ -2262,7 +2550,8 @@ void main() { int operator ~() => 7; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' int operator ~() => (super.noSuchMethod( Invocation.method( #~, @@ -2270,7 +2559,8 @@ void main() { ), returnValue: 0, ) as int); - ''')), + '''), + ), ); }); @@ -2307,17 +2597,19 @@ void main() { ); }); - test('calls dummyValue to get a dummy non-null String return value', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'calls dummyValue to get a dummy non-null String return value', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { String m() => "Hello"; } '''), - _containsAllOf('returnValue: _i3.dummyValue('), - ); - }); + _containsAllOf('returnValue: _i3.dummyValue('), + ); + }, + ); test('creates dummy non-null List return value', () async { await expectSingleNonNullableOutput( @@ -2374,17 +2666,19 @@ void main() { ); }); - test('creates dummy non-null return values for Futures of unknown types', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'creates dummy non-null return values for Futures of unknown types', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { Future m() async => false; } '''), - _containsAllOf('dummyValueOrNull(', '_FakeFuture_0('), - ); - }); + _containsAllOf('dummyValueOrNull(', '_FakeFuture_0('), + ); + }, + ); test('creates dummy non-null Stream return value', () async { await expectSingleNonNullableOutput( @@ -2453,8 +2747,7 @@ void main() { ); }); - test( - 'creates a dummy non-null function-typed return value, with optional ' + test('creates a dummy non-null function-typed return value, with optional ' 'parameters', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2470,8 +2763,7 @@ void main() { ); }); - test( - 'creates a dummy non-null function-typed return value, with named ' + test('creates a dummy non-null function-typed return value, with named ' 'parameters', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2487,8 +2779,7 @@ void main() { ); }); - test( - 'creates a dummy non-null function-typed return value, with required ' + test('creates a dummy non-null function-typed return value, with required ' 'named parameters', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2504,8 +2795,7 @@ void main() { ); }); - test( - 'creates a dummy non-null function-typed return value, with non-core ' + test('creates a dummy non-null function-typed return value, with non-core ' 'return type', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2525,16 +2815,17 @@ void main() { }); test( - 'creates a dummy non-null function-typed return value, with private type ' - 'alias', () async { - await expectSingleNonNullableOutput( - dedent(r''' + 'creates a dummy non-null function-typed return value, with private type ' + 'alias', + () async { + await expectSingleNonNullableOutput( + dedent(r''' typedef _Callback = Foo Function(); class Foo { _Callback m() => () => Foo(); } '''), - _containsAllOf(''' + _containsAllOf(''' returnValue: () => _FakeFoo_0( this, Invocation.method( @@ -2543,31 +2834,36 @@ void main() { ), ) '''), - ); - }); + ); + }, + ); - test('creates a dummy non-null generic function-typed return value', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'creates a dummy non-null generic function-typed return value', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Foo { T? Function(T) m() => (int i, [String s]) {}; } '''), - _containsAllOf('returnValue: (T __p0) => null'), - ); - }); + _containsAllOf('returnValue: (T __p0) => null'), + ); + }, + ); - test('creates a dummy non-null generic bounded function-typed return value', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'creates a dummy non-null generic bounded function-typed return value', + () async { + await expectSingleNonNullableOutput( + dedent(r''' import 'dart:io'; class Foo { T? Function(T) m() => (int i, [String s]) {}; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' T? Function(T) m() => (super.noSuchMethod( Invocation.method( #m, @@ -2575,12 +2871,13 @@ void main() { ), returnValue: (T __p0) => null, ) as T? Function(T)); - ''')), - ); - }); + '''), + ), + ); + }, + ); - test( - 'creates a dummy non-null function-typed (with an imported parameter ' + test('creates a dummy non-null function-typed (with an imported parameter ' 'type) return value', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2589,7 +2886,8 @@ void main() { void Function(File) m() => (int i, [String s]) {}; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' void Function(_i3.File) m() => (super.noSuchMethod( Invocation.method( #m, @@ -2597,12 +2895,12 @@ void main() { ), returnValue: (_i3.File __p0) {}, ) as void Function(_i3.File)); - ''')), + '''), + ), ); }); - test( - 'creates a dummy non-null function-typed (with an imported return type) ' + test('creates a dummy non-null function-typed (with an imported return type) ' 'return value', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -2611,7 +2909,8 @@ void main() { File Function() m() => (int i, [String s]) {}; } '''), - _containsAllOf(dedent2(''' + _containsAllOf( + dedent2(''' _i2.File Function() m() => (super.noSuchMethod( Invocation.method( #m, @@ -2625,7 +2924,8 @@ void main() { ), ), ) as _i2.File Function()); - ''')), + '''), + ), ); }); @@ -2637,7 +2937,8 @@ void main() { } class Bar {} '''), - _containsAllOf(dedent(''' + _containsAllOf( + dedent(''' class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar { _FakeBar_0( Object parent, @@ -2646,7 +2947,8 @@ void main() { parent, parentInvocation, ); - }''')), + }'''), + ), ); }); @@ -2670,13 +2972,13 @@ void main() { ''', }); expect( - mocksOutput, - contains( - 'class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {')); + mocksOutput, + contains('class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {'), + ); expect( - mocksOutput, - contains( - 'class _FakeBar_1 extends _i1.SmartFake implements _i3.Bar {')); + mocksOutput, + contains('class _FakeBar_1 extends _i1.SmartFake implements _i3.Bar {'), + ); }); test('generates a fake generic class used in return values', () async { @@ -2688,26 +2990,31 @@ void main() { class Bar {} '''), _containsAllOf( - 'class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {'), + 'class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {', + ), ); }); - test('generates a fake, bounded generic class used in return values', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + test( + 'generates a fake, bounded generic class used in return values', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Baz {} class Bar {} class Foo { Bar m1() => Bar(); } '''), - _containsAllOf(dedent(''' + _containsAllOf( + dedent(''' class _FakeBar_0 extends _i2.SmartFake implements _i1.Bar { - ''')), - ); - }); + '''), + ), + ); + }, + ); test('generates a fake, aliased class used in return values', () async { await expectSingleNonNullableOutput( @@ -2719,33 +3026,38 @@ void main() { BarOfBaz m1() => Bar(); } '''), - _containsAllOf(dedent(''' + _containsAllOf( + dedent(''' class _FakeBar_0 extends _i2.SmartFake implements _i1.Bar { - ''')), + '''), + ), ); }); test( - 'generates a fake, recursively bounded generic class used in return values', - () async { - await expectSingleNonNullableOutput( - dedent(r''' + 'generates a fake, recursively bounded generic class used in return values', + () async { + await expectSingleNonNullableOutput( + dedent(r''' class Baz> {} class Bar {} class Foo { Bar m1() => Bar(); } '''), - _containsAllOf( - 'class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {'), - ); - }); + _containsAllOf( + 'class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar {', + ), + ); + }, + ); - test('generates a fake class with an overridden `toString` implementation', - () async { - await expectSingleNonNullableOutput( - dedent(''' + test( + 'generates a fake class with an overridden `toString` implementation', + () async { + await expectSingleNonNullableOutput( + dedent(''' class Foo { Bar m1() => Bar('name1'); } @@ -2753,7 +3065,8 @@ void main() { String toString({bool a = true}) => ''; } '''), - _containsAllOf(dedent(''' + _containsAllOf( + dedent(''' class _FakeBar_0 extends _i1.SmartFake implements _i2.Bar { _FakeBar_0( Object parent, @@ -2766,9 +3079,11 @@ void main() { @override String toString({bool? a = true}) => super.toString(); } - ''')), - ); - }); + '''), + ), + ); + }, + ); test('imports libraries for types used in generated fake classes', () async { await expectSingleNonNullableOutput( @@ -2786,7 +3101,8 @@ void main() { }); test('deduplicates fake classes', () async { - final mocksContent = await buildWithSingleNonNullableSource(dedent(r''' + final mocksContent = await buildWithSingleNonNullableSource( + dedent(r''' class Foo { Bar m1() => Bar('name1'); Bar m2() => Bar('name2'); @@ -2795,38 +3111,50 @@ void main() { final String name; Bar(this.name); } - ''')); + '''), + ); final mocksContentLines = mocksContent.split('\n'); // The _FakeBar_0 class should be generated exactly once. - expect(mocksContentLines.where((line) => line.contains('class _FakeBar_0')), - hasLength(1)); + expect( + mocksContentLines.where((line) => line.contains('class _FakeBar_0')), + hasLength(1), + ); }); test('does not try to generate a fake for a final class', () async { - await expectSingleNonNullableOutput(dedent(r''' + await expectSingleNonNullableOutput( + dedent(r''' class Foo { Bar m1() => Bar(); } final class Bar {} - '''), _containsAllOf('dummyValue<_i2.Bar>(')); + '''), + _containsAllOf('dummyValue<_i2.Bar>('), + ); }); test('does not try to generate a fake for a base class', () async { - await expectSingleNonNullableOutput(dedent(r''' + await expectSingleNonNullableOutput( + dedent(r''' class Foo { Bar m1() => Bar(); } base class Bar {} - '''), _containsAllOf('dummyValue<_i2.Bar>(')); + '''), + _containsAllOf('dummyValue<_i2.Bar>('), + ); }); test('does not try to generate a fake for a sealed class', () async { - await expectSingleNonNullableOutput(dedent(r''' + await expectSingleNonNullableOutput( + dedent(r''' class Foo { Bar m1() => Bar(); } sealed class Bar {} - '''), _containsAllOf('dummyValue<_i2.Bar>(')); + '''), + _containsAllOf('dummyValue<_i2.Bar>('), + ); }); test('throws when GenerateMocks is given a class multiple times', () async { @@ -2841,59 +3169,65 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo, Foo]) void main() {} - ''' + ''', }, message: contains( - 'Mockito cannot generate two mocks with the same name: MockFoo (for ' - 'Foo declared in /foo/lib/foo.dart, and for Foo declared in ' - '/foo/lib/foo.dart)'), + 'Mockito cannot generate two mocks with the same name: MockFoo (for ' + 'Foo declared in /foo/lib/foo.dart, and for Foo declared in ' + '/foo/lib/foo.dart)', + ), ); }); test( - 'throws when GenerateMocks is given a class with a getter with a private ' - 'return type', () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': dedent(''' + 'throws when GenerateMocks is given a class with a getter with a private ' + 'return type', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': dedent(''' abstract class Foo with FooMixin {} mixin FooMixin { _Bar get f => _Bar(); } class _Bar {} '''), - }, - message: contains( + }, + message: contains( "The property accessor 'FooMixin.f' features a private return type, " - 'and cannot be stubbed.'), - ); - }); + 'and cannot be stubbed.', + ), + ); + }, + ); test( - 'throws when GenerateMocks is given a class with a setter with a private ' - 'return type', () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': dedent(''' + 'throws when GenerateMocks is given a class with a setter with a private ' + 'return type', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': dedent(''' abstract class Foo with FooMixin {} mixin FooMixin { void set f(_Bar value) {} } class _Bar {} '''), - }, - message: contains( - "The property accessor 'FooMixin.f=' features a private parameter " - "type, '_Bar', and cannot be stubbed."), - ); - }); + }, + message: contains( + "The property accessor 'FooMixin.f' features a private parameter " + "type, '_Bar', and cannot be stubbed.", + ), + ); + }, + ); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'private return type', () async { _expectBuilderThrows( assets: { @@ -2907,13 +3241,13 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private return type, and cannot be " - 'stubbed.'), + "The method 'Foo.m' features a private return type, and cannot be " + 'stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with an inherited method ' + test('throws when GenerateMocks is given a class with an inherited method ' 'with a private return type', () async { _expectBuilderThrows( assets: { @@ -2928,13 +3262,13 @@ void main() { '''), }, message: contains( - "The method 'FooMixin.m' features a private return type, and cannot " - 'be stubbed.'), + "The method 'FooMixin.m' features a private return type, and cannot " + 'be stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'type alias return type which refers to private types', () async { _expectBuilderThrows( assets: { @@ -2949,35 +3283,37 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private parameter type, '_Bar', and " - 'cannot be stubbed.'), + "The method 'Foo.m' features a private parameter type, '_Bar', and " + 'cannot be stubbed.', + ), ); }); test( - 'throws when GenerateMocks is given a class with a method with a ' - 'private type alias parameter type which refers to private types', - () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': dedent(''' + 'throws when GenerateMocks is given a class with a method with a ' + 'private type alias parameter type which refers to private types', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': dedent(''' abstract class Foo { void m(_Callback c); } class _Bar {} typedef _Callback = Function(_Bar?); '''), - }, - message: contains( + }, + message: contains( "The method 'Foo.m' features a private parameter type, '_Bar', and " - 'cannot be stubbed.'), - ); - }); + 'cannot be stubbed.', + ), + ); + }, + ); - test( - 'throws when GenerateMocks is given a class with a method with a return ' + test('throws when GenerateMocks is given a class with a method with a return ' 'type with private type arguments', () async { _expectBuilderThrows( assets: { @@ -2991,13 +3327,13 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private type argument, and cannot be " - 'stubbed.'), + "The method 'Foo.m' features a private type argument, and cannot be " + 'stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a return ' + test('throws when GenerateMocks is given a class with a method with a return ' 'function type, with a private return type', () async { _expectBuilderThrows( assets: { @@ -3010,13 +3346,14 @@ void main() { class _Bar {} '''), }, - message: contains("The method 'Foo.m' features a private return type, " - 'and cannot be stubbed.'), + message: contains( + "The method 'Foo.m' features a private return type, " + 'and cannot be stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'private parameter type', () async { _expectBuilderThrows( assets: { @@ -3030,13 +3367,13 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private parameter type, '_Bar', and " - 'cannot be stubbed.'), + "The method 'Foo.m' features a private parameter type, '_Bar', and " + 'cannot be stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'parameter with private type arguments', () async { _expectBuilderThrows( assets: { @@ -3050,13 +3387,13 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private type argument, and cannot be " - 'stubbed.'), + "The method 'Foo.m' features a private type argument, and cannot be " + 'stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'function parameter type, with a private return type', () async { _expectBuilderThrows( assets: { @@ -3070,13 +3407,13 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private return type, and cannot be " - 'stubbed.'), + "The method 'Foo.m' features a private return type, and cannot be " + 'stubbed.', + ), ); }); - test( - 'throws when GenerateMocks is given a class with a method with a return ' + test('throws when GenerateMocks is given a class with a method with a return ' 'function type, with a private parameter type', () async { _expectBuilderThrows( assets: { @@ -3090,33 +3427,36 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private parameter type, '_Bar', and " - 'cannot be stubbed.'), + "The method 'Foo.m' features a private parameter type, '_Bar', and " + 'cannot be stubbed.', + ), ); }); test( - 'throws when GenerateMocks is given a class with a type parameter with a ' - 'private bound', () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': dedent(r''' + 'throws when GenerateMocks is given a class with a type parameter with a ' + 'private bound', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': dedent(r''' class Foo { void m(int a) {} } class _Bar {} '''), - }, - message: contains( + }, + message: contains( "The class 'Foo' features a private type parameter bound, and cannot " - 'be stubbed.'), - ); - }); + 'be stubbed.', + ), + ); + }, + ); - test( - 'throws when GenerateMocks is given a class with a method with a ' + test('throws when GenerateMocks is given a class with a method with a ' 'type parameter with a private bound', () async { _expectBuilderThrows( assets: { @@ -3130,51 +3470,62 @@ void main() { '''), }, message: contains( - "The method 'Foo.m' features a private type parameter bound, and " - 'cannot be stubbed.'), + "The method 'Foo.m' features a private type parameter bound, and " + 'cannot be stubbed.', + ), ); }); - test( - "calls 'dummyValue' for a getter with a " + test("calls 'dummyValue' for a getter with a " 'non-nullable class-declared type variable type', () async { - await expectSingleNonNullableOutput(dedent(''' + await expectSingleNonNullableOutput( + dedent(''' abstract class Foo { T get f; } - '''), _containsAllOf('dummyValue(')); + '''), + _containsAllOf('dummyValue('), + ); }); - test( - "calls 'dummyValue' for a method with a " + test("calls 'dummyValue' for a method with a " 'non-nullable class-declared type variable return type', () async { - await expectSingleNonNullableOutput(dedent(''' + await expectSingleNonNullableOutput( + dedent(''' abstract class Foo { T m(int a); } - '''), _containsAllOf('dummyValue(')); + '''), + _containsAllOf('dummyValue('), + ); }); - test( - "calls 'dummyValue' for a method with a " + test("calls 'dummyValue' for a method with a " 'non-nullable method-declared type variable return type', () async { - await expectSingleNonNullableOutput(dedent(''' + await expectSingleNonNullableOutput( + dedent(''' abstract class Foo { T m(int a); } - '''), _containsAllOf('dummyValue(')); + '''), + _containsAllOf('dummyValue('), + ); }); test( - "calls 'dummyValue' for a method with a " - 'non-nullable method-declared bounded type variable return type', - () async { - await expectSingleNonNullableOutput(dedent(''' + "calls 'dummyValue' for a method with a " + 'non-nullable method-declared bounded type variable return type', + () async { + await expectSingleNonNullableOutput( + dedent(''' abstract class Foo { T m(int a); } - '''), _containsAllOf('dummyValue(')); - }); + '''), + _containsAllOf('dummyValue('), + ); + }, + ); test('throws when GenerateMocks is missing an argument', () async { _expectBuilderThrows( @@ -3224,31 +3575,34 @@ void main() { ); }); - test('throws when two distinct classes with the same name are mocked', - () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - 'foo|lib/a.dart': dedent(r''' + test( + 'throws when two distinct classes with the same name are mocked', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + 'foo|lib/a.dart': dedent(r''' class Foo {} '''), - 'foo|lib/b.dart': dedent(r''' + 'foo|lib/b.dart': dedent(r''' class Foo {} '''), - 'foo|test/foo_test.dart': dedent(''' + 'foo|test/foo_test.dart': dedent(''' import 'package:foo/a.dart' as a; import 'package:foo/b.dart' as b; import 'package:mockito/annotations.dart'; @GenerateMocks([a.Foo, b.Foo]) void main() {} '''), - }, - message: contains( + }, + message: contains( 'Mockito cannot generate two mocks with the same name: MockFoo (for ' 'Foo declared in /foo/lib/a.dart, and for Foo declared in ' - '/foo/lib/b.dart)'), - ); - }); + '/foo/lib/b.dart)', + ), + ); + }, + ); test('throws when a mock class of the same name already exists', () async { _expectBuilderThrows( @@ -3266,8 +3620,9 @@ void main() { '''), }, message: contains( - 'Mockito cannot generate a mock with a name which conflicts with ' - 'another class declared in this library: MockFoo'), + 'Mockito cannot generate a mock with a name which conflicts with ' + 'another class declared in this library: MockFoo', + ), ); }); @@ -3289,7 +3644,8 @@ void main() { '''), }, message: contains( - 'contains a class which appears to already be mocked inline: FakeFoo'), + 'contains a class which appears to already be mocked inline: FakeFoo', + ), ); }); @@ -3376,12 +3732,13 @@ void main() { ); }); - test('throws when GenerateMocks references sealed a class via typedef', - () async { - _expectBuilderThrows( - assets: { - ...annotationsAsset, - 'foo|test/foo_test.dart': dedent(''' + test( + 'throws when GenerateMocks references sealed a class via typedef', + () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + 'foo|test/foo_test.dart': dedent(''' // @dart=3.0 import 'package:mockito/annotations.dart'; sealed class Foo {} @@ -3389,10 +3746,11 @@ void main() { @GenerateMocks([Bar]) void main() {} '''), - }, - message: contains("Mockito cannot mock a sealed class 'Foo'"), - ); - }); + }, + message: contains("Mockito cannot mock a sealed class 'Foo'"), + ); + }, + ); test('throws when GenerateMocks references a base class', () async { _expectBuilderThrows( @@ -3426,8 +3784,7 @@ void main() { ); }); - test( - 'adds ignore: must_be_immutable analyzer comment if mocked class is ' + test('adds ignore: must_be_immutable analyzer comment if mocked class is ' 'immutable', () async { await expectSingleNonNullableOutput( dedent(r''' @@ -3455,7 +3812,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Bar]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBar extends _i1.Mock')); @@ -3474,7 +3831,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Bar]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBar extends _i1.Mock')); @@ -3493,7 +3850,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Bar]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBar extends _i1.Mock')); @@ -3512,7 +3869,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Bar]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBar extends _i1.Mock')); @@ -3531,11 +3888,13 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Bar]) void main() {} - ''' + ''', }); - expect(mocksContent, - contains('class MockBar extends _i1.Mock')); + expect( + mocksContent, + contains('class MockBar extends _i1.Mock'), + ); expect(mocksContent, contains('implements _i2.Bar')); }); @@ -3555,7 +3914,7 @@ void main() { @GenerateMocks([Bar]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBar extends _i1.Mock')); @@ -3578,7 +3937,7 @@ void main() { @GenerateMocks([Baz]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockBaz extends _i1.Mock')); @@ -3604,17 +3963,18 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockFoo extends _i1.Mock')); expect(mocksContent, contains('implements _i2.Foo')); }); - test('when the underlying type is identical to another type alias', - () async { - final mocksContent = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': dedent(r''' + test( + 'when the underlying type is identical to another type alias', + () async { + final mocksContent = await buildWithNonNullable({ + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(r''' class Bar {} typedef BarDef = int Function(); typedef BarDef2 = int Function(); @@ -3627,19 +3987,20 @@ void main() { Foo() : super(() => 1, () => 2); } '''), - 'foo|test/foo_test.dart': ''' + 'foo|test/foo_test.dart': ''' import 'package:foo/foo.dart'; import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void main() {} - ''' - }); + ''', + }); - expect(mocksContent, contains('class MockFoo extends _i1.Mock')); - expect(mocksContent, contains('implements _i2.Foo')); - expect(mocksContent, contains('_i2.BarDef get t1')); - expect(mocksContent, contains('_i2.BarDef2 get t2')); - }); + expect(mocksContent, contains('class MockFoo extends _i1.Mock')); + expect(mocksContent, contains('implements _i2.Foo')); + expect(mocksContent, contains('_i2.BarDef get t1')); + expect(mocksContent, contains('_i2.BarDef2 get t2')); + }, + ); }); test('generation throws when the aliased type is nullable', () { @@ -3659,10 +4020,11 @@ void main() { @GenerateMocks([Bar]) void main() {} - ''' + ''', }, - message: - contains('Mockito cannot mock a type-aliased nullable type: Bar'), + message: contains( + 'Mockito cannot mock a type-aliased nullable type: Bar', + ), enabledExperiments: ['nonfunction-type-aliases'], languageVersion: LanguageVersion(2, 13), ); @@ -3688,24 +4050,31 @@ void main() { }); group('Record types', () { test('are supported as arguments', () async { - await expectSingleNonNullableOutput(dedent(''' + await expectSingleNonNullableOutput( + dedent(''' abstract class Foo { int m((int, {Foo foo}) a); } - '''), _containsAllOf('int m((int, {_i2.Foo foo})? a)')); + '''), + _containsAllOf('int m((int, {_i2.Foo foo})? a)'), + ); }); test('are supported as return types', () async { await expectSingleNonNullableOutput( - dedent(''' + dedent(''' class Bar {} abstract class Foo { Future<(int, {Bar bar})> get v; } '''), - decodedMatches(allOf( - contains('Future<(int, {_i2.Bar bar})> get v'), - contains('returnValue: _i3.Future<(int, {_i2.Bar bar})>.value('), - contains('bar: _FakeBar_0(')))); + decodedMatches( + allOf( + contains('Future<(int, {_i2.Bar bar})> get v'), + contains('returnValue: _i3.Future<(int, {_i2.Bar bar})>.value('), + contains('bar: _FakeBar_0('), + ), + ), + ); }); test('are supported as type arguments', () async { final mocksContent = await buildWithNonNullable({ @@ -3725,7 +4094,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockFoo extends _i1.Mock')); @@ -3749,7 +4118,7 @@ void main() { import 'package:mockito/annotations.dart'; @GenerateMocks([Foo]) void main() {} - ''' + ''', }); expect(mocksContent, contains('class MockFoo extends _i1.Mock')); @@ -3759,44 +4128,50 @@ void main() { group('Extension types', () { test('are supported as arguments', () async { - await expectSingleNonNullableOutput(dedent(''' + await expectSingleNonNullableOutput( + dedent(''' extension type E(int v) {} class Foo { int m(E e); } - '''), _containsAllOf('int m(_i2.E? e)')); + '''), + _containsAllOf('int m(_i2.E? e)'), + ); }); test('are supported as return types', () async { await expectSingleNonNullableOutput( - dedent(''' + dedent(''' extension type E(int v) {} class Foo { E get v; } '''), - decodedMatches( - allOf(contains('E get v'), contains('returnValue: 0')))); + decodedMatches(allOf(contains('E get v'), contains('returnValue: 0'))), + ); }); }); group('build_extensions support', () { test('should export mocks to different directory', () async { - await testWithNonNullable({ - ...annotationsAsset, - ...simpleTestAsset, - 'foo|lib/foo.dart': ''' + await testWithNonNullable( + { + ...annotationsAsset, + ...simpleTestAsset, + 'foo|lib/foo.dart': ''' import 'bar.dart'; class Foo extends Bar {} ''', - 'foo|lib/bar.dart': ''' + 'foo|lib/bar.dart': ''' import 'dart:async'; class Bar { m(Future a) {} } ''', - }, config: { - 'build_extensions': {'^test/{{}}.dart': 'test/mocks/{{}}.mocks.dart'} - }); + }, + config: { + 'build_extensions': {'^test/{{}}.dart': 'test/mocks/{{}}.mocks.dart'}, + }, + ); final mocksAsset = AssetId('foo', 'test/mocks/foo_test.mocks.dart'); final mocksContent = utf8.decode(writer.assets[mocksAsset]!); expect(mocksContent, contains("import 'dart:async' as _i3;")); @@ -3805,7 +4180,8 @@ void main() { test('should throw if it has confilicting outputs', () async { await expectLater( - testWithNonNullable({ + testWithNonNullable( + { ...annotationsAsset, ...simpleTestAsset, 'foo|lib/foo.dart': ''' @@ -3818,17 +4194,22 @@ void main() { m(Future a) {} } ''', - }, config: { + }, + config: { 'build_extensions': { '^test/{{}}.dart': 'test/mocks/{{}}.mocks.dart', - 'test/{{}}.dart': 'test/{{}}.something.mocks.dart' - } - }), - throwsArgumentError); + 'test/{{}}.dart': 'test/{{}}.something.mocks.dart', + }, + }, + ), + throwsArgumentError, + ); final mocksAsset = AssetId('foo', 'test/mocks/foo_test.mocks.dart'); final otherMocksAsset = AssetId('foo', 'test/mocks/foo_test.mocks.dart'); - final somethingMocksAsset = - AssetId('foo', 'test/mocks/foo_test.something.mocks.dart'); + final somethingMocksAsset = AssetId( + 'foo', + 'test/mocks/foo_test.something.mocks.dart', + ); expect(writer.assets.containsKey(mocksAsset), false); expect(writer.assets.containsKey(otherMocksAsset), false); @@ -3837,7 +4218,8 @@ void main() { test('should throw if input is in incorrect format', () async { await expectLater( - testWithNonNullable({ + testWithNonNullable( + { ...annotationsAsset, ...simpleTestAsset, 'foo|lib/foo.dart': ''' @@ -3850,10 +4232,13 @@ void main() { m(Future a) {} } ''', - }, config: { - 'build_extensions': {'^test/{{}}': 'test/mocks/{{}}.mocks.dart'} - }), - throwsArgumentError); + }, + config: { + 'build_extensions': {'^test/{{}}': 'test/mocks/{{}}.mocks.dart'}, + }, + ), + throwsArgumentError, + ); final mocksAsset = AssetId('foo', 'test/mocks/foo_test.mocks.dart'); final mocksAssetOriginal = AssetId('foo', 'test/foo_test.mocks.dart'); @@ -3863,7 +4248,8 @@ void main() { test('should throw if output is in incorrect format', () async { await expectLater( - testWithNonNullable({ + testWithNonNullable( + { ...annotationsAsset, ...simpleTestAsset, 'foo|lib/foo.dart': ''' @@ -3876,10 +4262,13 @@ void main() { m(Future a) {} } ''', - }, config: { - 'build_extensions': {'^test/{{}}.dart': 'test/mocks/{{}}.g.dart'} - }), - throwsArgumentError); + }, + config: { + 'build_extensions': {'^test/{{}}.dart': 'test/mocks/{{}}.g.dart'}, + }, + ), + throwsArgumentError, + ); final mocksAsset = AssetId('foo', 'test/mocks/foo_test.mocks.dart'); final mocksAssetOriginal = AssetId('foo', 'test/foo_test.mocks.dart'); expect(writer.assets.containsKey(mocksAsset), false); @@ -3888,10 +4277,11 @@ void main() { }); } -TypeMatcher> _containsAllOf(String a, [String? b]) => - decodedMatches(b == null - ? containsIgnoringFormatting(a) - : allOf(containsIgnoringFormatting(a), containsIgnoringFormatting(b))); +TypeMatcher> _containsAllOf(String a, [String? b]) => decodedMatches( + b == null + ? 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 @@ -3903,22 +4293,31 @@ void _expectBuilderThrows({ LanguageVersion? languageVersion, }) { final packageConfig = PackageConfig([ - Package('foo', Uri.file('/foo/'), - packageUriRoot: Uri.file('/foo/lib/'), - languageVersion: languageVersion ?? LanguageVersion(2, 12)) + Package( + 'foo', + Uri.file('/foo/'), + packageUriRoot: Uri.file('/foo/lib/'), + languageVersion: languageVersion ?? LanguageVersion(2, 12), + ), ]); expect( - () => withEnabledExperiments( - () => testBuilder( - buildMocks(BuilderOptions({})), - assets, - packageConfig: packageConfig, - ), - enabledExperiments, - ), - throwsA(TypeMatcher() - .having((e) => e.message, 'message', message))); + () => withEnabledExperiments( + () => testBuilder( + buildMocks(BuilderOptions({})), + assets, + packageConfig: packageConfig, + ), + enabledExperiments, + ), + throwsA( + TypeMatcher().having( + (e) => e.message, + 'message', + message, + ), + ), + ); } /// Dedent [input], so that each line is shifted to the left, so that the first @@ -3926,8 +4325,10 @@ void _expectBuilderThrows({ String dedent(String input) { final indentMatch = RegExp(r'^(\s*)').firstMatch(input)!; final indent = ''.padRight(indentMatch.group(1)!.length); - return input.splitMapJoin('\n', - onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), '')); + return input.splitMapJoin( + '\n', + onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), ''), + ); } /// Dedent [input], so that each line is shifted to the left, so that the first @@ -3935,6 +4336,10 @@ String dedent(String input) { String dedent2(String input) { final indentMatch = RegExp(r'^ (\s*)').firstMatch(input)!; final indent = ''.padRight(indentMatch.group(1)!.length); - return input.replaceFirst(RegExp(r'\s*$'), '').splitMapJoin('\n', - onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), '')); + return input + .replaceFirst(RegExp(r'\s*$'), '') + .splitMapJoin( + '\n', + onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), ''), + ); }