Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@GenerateMocks imports types without taking conditional exports into account #443

Closed
tolotrasamuel opened this issue Jul 8, 2021 · 2 comments
Assignees
Labels
P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@tolotrasamuel
Copy link

tolotrasamuel commented Jul 8, 2021

With the package image_picker that used conditional import,


@GenerateMocks([
  ImagePicker,
], customMocks: [])
void main() {}

In the generated mock file, it imports this line:

import 'package:image_picker_platform_interface/src/types/picked_file/unsupported.dart'
    as _i27;

And then don't get an error by the static analysis but at compile time, we get this bigger error

Screenshot 2021-07-08 at 17 50 51

lib/tests/mock/mock_lib_generator.outlets.dart:638:48: Error: A value of type 'Future<PickedFile/*1*/?>' can't be returned from an async function with return type 'Future<PickedFile/*2*/?>'.
 - 'Future' is from 'dart:async'.
 - 'PickedFile/*1*/' is from 'package:image_picker_platform_interface/src/types/picked_file/io.dart' ('../../.pub-cache/hosted/pub.dartlang.org/image_picker_platform_interface-2.1.0/lib/src/types/picked_file/io.dart').
 - 'PickedFile/*2*/' is from 'package:image_picker_platform_interface/src/types/picked_file/unsupported.dart' ('../../.pub-cache/hosted/pub.dartlang.org/image_picker_platform_interface-2.1.0/lib/src/types/picked_file/unsupported.dart').
      )).thenAnswer((_) async => getImage.stub.future);
                                               ^
lib/tests/mock/mock_lib_generator.outlets.dart:646:48: Error: A value of type 'Future<PickedFile/*1*/?>' can't be returned from an async function with return type 'Future<PickedFile/*2*/?>'.
 - 'Future' is from 'dart:async'.
 - 'PickedFile/*1*/' is from 'package:image_picker_platform_interface/src/types/picked_file/io.dart' ('../../.pub-cache/hosted/pub.dartlang.org/image_picker_platform_interface-2.1.0/lib/src/types/picked_file/io.dart').
 - 'PickedFile/*2*/' is from 'package:image_picker_platform_interface/src/types/picked_file/unsupported.dart' ('../../.pub-cache/hosted/pub.dartlang.org/image_picker_platform_interface-2.1.0/lib/src/types/picked_file/unsupported.dart').
      )).thenAnswer((_) async => getVideo.stub.future);

Upon check the code, I understood the source of the issue:

picked_file/picked_file.dart


export 'lost_data.dart';
export 'unsupported.dart'
    if (dart.library.html) 'html.dart'
    if (dart.library.io) 'io.dart';

When Mockito build runner lauches, there is no either dart HTML or dart io. So it falls back to the default unsupported implementation. But when you run it on a platform, in my case on web, it a different object.

Expect:

Do not import beyond the condition importation

Stay at picked_file/picked_file.dart

@tolotrasamuel
Copy link
Author

Any plan to fix this or a workaround ?

@srawlins srawlins changed the title @GenerateMocks is importing unsupported Implementation @GenerateMocks imports types without taking conditional imports into account Jul 15, 2021
@srawlins srawlins changed the title @GenerateMocks imports types without taking conditional imports into account @GenerateMocks imports types without taking conditional exports into account Jul 15, 2021
@srawlins
Copy link
Member

Hrm de hrm. Good catch. We fixed a similar bug recently so there is an algorithm in place to help with a fix for this bug.

@srawlins srawlins added P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Jul 15, 2021
@srawlins srawlins self-assigned this Jul 15, 2021
srawlins added a commit that referenced this issue Jul 18, 2021
If the generated code needs to represent a type, `T`, and that type is declared
in library `L`, then we now prefer to import a library which _exports_ `L` (if
one exists), over importing `L` directly.

To find such a library, we look at the type, `U` which references `T`. Perhaps
`U` is a class to mocked, and `U` has a method with a return type `T`, or `U` is
a supertype of a class to be mocked, which has a method with a parameter type
`T`, etc. We examine all of the import libraries, `IL`, of the library in which
`U` is declared, and all of the libraries which are exported by the libraries
`IL`.

If the type `T` is declared in a library which is exported as a conditional
export, this strategy avoids complications with the conditional export.
Additionally, as a heuristic, it generally leads to public libraries which
export private implementation, avoiding importing the private implementation
directly.

Fixes #443

PiperOrigin-RevId: 385425794
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

2 participants