@@ -31,6 +31,17 @@ import '../src/fake_pub_deps.dart';
3131import '../src/fakes.dart' ;
3232
3333void main () {
34+ // TODO(matanlurey): Remove after `explicit-package-dependencies` is enabled by default.
35+ // See https://github.com/flutter/flutter/issues/160257 for details.
36+ FeatureFlags enableExplicitPackageDependencies () {
37+ return TestFeatureFlags (isExplicitPackageDependenciesEnabled: true );
38+ }
39+
40+ FeatureFlags disableExplicitPackageDependencies () {
41+ // ignore: avoid_redundant_argument_values
42+ return TestFeatureFlags (isExplicitPackageDependenciesEnabled: false );
43+ }
44+
3445 // TODO(zanderso): remove once FlutterProject is fully refactored.
3546 // this is safe since no tests have expectations on the test logger.
3647 final BufferLogger logger = BufferLogger .test ();
@@ -272,6 +283,107 @@ void main() {
272283 await project.regeneratePlatformSpecificTooling (releaseMode: false );
273284 expectExists (project.android.hostAppGradleRoot.childFile ('local.properties' ));
274285 });
286+
287+ testUsingContext (
288+ '--no-explicit-package-dependencies does not determine dev dependencies' ,
289+ () async {
290+ // Create a plugin.
291+ await aPluginProject (legacy: false );
292+ // Create a project that depends on that plugin.
293+ final FlutterProject project = await projectWithPluginDependency ();
294+ // Don't bother with Android, we just want the manifest.
295+ project.directory.childDirectory ('android' ).deleteSync (recursive: true );
296+
297+ await project.regeneratePlatformSpecificTooling (releaseMode: false );
298+ expect (
299+ project.flutterPluginsDependenciesFile.readAsStringSync (),
300+ isNot (contains ('"dev_dependency":true' )),
301+ );
302+ },
303+ overrides: < Type , Generator > {
304+ FeatureFlags : disableExplicitPackageDependencies,
305+ FileSystem : () => MemoryFileSystem .test (),
306+ ProcessManager : () => FakeProcessManager .any (),
307+ Pub : () => FakePubWithPrimedDeps (devDependencies: < String > {'my_plugin' }),
308+ FlutterProjectFactory :
309+ () => FlutterProjectFactory (logger: logger, fileSystem: globals.fs),
310+ },
311+ );
312+
313+ testUsingContext (
314+ '--explicit-package-dependencies determines dev dependencies' ,
315+ () async {
316+ // Create a plugin.
317+ await aPluginProject (legacy: false );
318+ // Create a project that depends on that plugin.
319+ final FlutterProject project = await projectWithPluginDependency ();
320+ // Don't bother with Android, we just want the manifest.
321+ project.directory.childDirectory ('android' ).deleteSync (recursive: true );
322+
323+ await project.regeneratePlatformSpecificTooling (releaseMode: false );
324+ expect (
325+ project.flutterPluginsDependenciesFile.readAsStringSync (),
326+ contains ('"dev_dependency":true' ),
327+ );
328+ },
329+ overrides: < Type , Generator > {
330+ FeatureFlags : enableExplicitPackageDependencies,
331+ FileSystem : () => MemoryFileSystem .test (),
332+ ProcessManager : () => FakeProcessManager .any (),
333+ Pub : () => FakePubWithPrimedDeps (devDependencies: < String > {'my_plugin' }),
334+ FlutterProjectFactory :
335+ () => FlutterProjectFactory (logger: logger, fileSystem: globals.fs),
336+ },
337+ );
338+
339+ testUsingContext (
340+ '--explicit-package-dependencies with releaseMode: false retains dev plugins' ,
341+ () async {
342+ // Create a plugin.
343+ await aPluginProject (includeAndroidMain: true , legacy: false );
344+ // Create a project that depends on that plugin.
345+ final FlutterProject project = await projectWithPluginDependency ();
346+
347+ await project.regeneratePlatformSpecificTooling (releaseMode: false );
348+ expect (
349+ project.android.generatedPluginRegistrantFile.readAsStringSync (),
350+ contains ('MyPlugin' ),
351+ );
352+ },
353+ overrides: < Type , Generator > {
354+ FeatureFlags : enableExplicitPackageDependencies,
355+ FileSystem : () => MemoryFileSystem .test (),
356+ ProcessManager : () => FakeProcessManager .any (),
357+ Pub : () => FakePubWithPrimedDeps (devDependencies: < String > {'my_plugin' }),
358+ FlutterProjectFactory :
359+ () => FlutterProjectFactory (logger: logger, fileSystem: globals.fs),
360+ },
361+ );
362+
363+ testUsingContext (
364+ '--explicit-package-dependencies with releaseMode: true omits dev plugins' ,
365+ () async {
366+ // Create a plugin.
367+ await aPluginProject (includeAndroidMain: true , legacy: false );
368+ // Create a project that depends on that plugin.
369+ final FlutterProject project = await projectWithPluginDependency ();
370+
371+ await project.regeneratePlatformSpecificTooling (releaseMode: true );
372+ expect (
373+ project.android.generatedPluginRegistrantFile.readAsStringSync (),
374+ isNot (contains ('MyPlugin' )),
375+ );
376+ },
377+ overrides: < Type , Generator > {
378+ FeatureFlags : enableExplicitPackageDependencies,
379+ FileSystem : () => MemoryFileSystem .test (),
380+ ProcessManager : () => FakeProcessManager .any (),
381+ Pub : () => FakePubWithPrimedDeps (devDependencies: < String > {'my_plugin' }),
382+ FlutterProjectFactory :
383+ () => FlutterProjectFactory (logger: logger, fileSystem: globals.fs),
384+ },
385+ );
386+
275387 testUsingContext (
276388 'injects plugins for macOS' ,
277389 () async {
@@ -1730,7 +1842,41 @@ Future<FlutterProject> someProject({
17301842 return FlutterProject .fromDirectory (directory);
17311843}
17321844
1733- Future <FlutterProject > aPluginProject ({bool legacy = true }) async {
1845+ Future <FlutterProject > projectWithPluginDependency () async {
1846+ final Directory directory = globals.fs.directory ('some_project' );
1847+ directory.childDirectory ('.dart_tool' ).childFile ('package_config.json' )
1848+ ..createSync (recursive: true )
1849+ ..writeAsStringSync ('''
1850+ {
1851+ "configVersion": 2,
1852+ "packages": [
1853+ {
1854+ "name": "my_plugin",
1855+ "rootUri": "/plugin_project",
1856+ "packageUri": "lib/",
1857+ "languageVersion": "2.12"
1858+ }
1859+ ]
1860+ }
1861+ ''' );
1862+ directory.childFile ('pubspec.yaml' )
1863+ ..createSync (recursive: true )
1864+ ..writeAsStringSync ('''
1865+ name: app_name
1866+ flutter:
1867+
1868+ dependencies:
1869+ my_plugin:
1870+ sdk: flutter
1871+ ''' );
1872+ directory.childDirectory ('ios' ).createSync (recursive: true );
1873+ final Directory androidDirectory = directory.childDirectory ('android' )
1874+ ..createSync (recursive: true );
1875+ androidDirectory.childFile ('AndroidManifest.xml' ).writeAsStringSync ('<manifest></manifest>' );
1876+ return FlutterProject .fromDirectory (directory);
1877+ }
1878+
1879+ Future <FlutterProject > aPluginProject ({bool legacy = true , bool includeAndroidMain = false }) async {
17341880 final Directory directory = globals.fs.directory ('plugin_project' );
17351881 directory.childDirectory ('ios' ).createSync (recursive: true );
17361882 directory.childDirectory ('android' ).createSync (recursive: true );
@@ -1765,6 +1911,16 @@ flutter:
17651911''' ;
17661912 }
17671913 directory.childFile ('pubspec.yaml' ).writeAsStringSync (pluginPubSpec);
1914+ if (includeAndroidMain) {
1915+ directory
1916+ .childDirectory ('android' )
1917+ .childFile (globals.fs.path.join ('src' , 'main' , 'java' , 'com' , 'example' , 'MyPlugin.java' ))
1918+ ..createSync (recursive: true )
1919+ ..writeAsStringSync ('''
1920+ import io.flutter.embedding.engine.plugins.FlutterPlugin;
1921+ class MyPlugin extends FluttPlugin { /* ... */ }
1922+ ''' );
1923+ }
17681924 return FlutterProject .fromDirectory (directory);
17691925}
17701926
0 commit comments