Materialize Flutter module, Android (#20520)
diff --git a/packages/flutter_tools/test/project_test.dart b/packages/flutter_tools/test/project_test.dart index a8b7388..7a4775d 100644 --- a/packages/flutter_tools/test/project_test.dart +++ b/packages/flutter_tools/test/project_test.dart
@@ -27,17 +27,6 @@ ); }); - Future<Null> expectToolExitLater(Future<dynamic> future, Matcher messageMatcher) async { - try { - await future; - fail('ToolExit expected, but nothing thrown'); - } on ToolExit catch(e) { - expect(e.message, messageMatcher); - } catch(e, trace) { - fail('ToolExit expected, got $e\n$trace'); - } - } - testInMemory('fails on invalid pubspec.yaml', () async { final Directory directory = fs.directory('myproject'); directory.childFile('pubspec.yaml') @@ -95,16 +84,55 @@ fs.currentDirectory.absolute.path, ); }); + }); + group('materialize Android', () { + testInMemory('fails on non-module', () async { + final FlutterProject project = await someProject(); + await expectLater( + project.android.materialize(), + throwsA(const isInstanceOf<AssertionError>()), + ); + }); + testInMemory('exits on already materialized module', () async { + final FlutterProject project = await aModuleProject(); + await project.android.materialize(); + expectToolExitLater(project.android.materialize(), contains('already materialized')); + }); + testInMemory('creates android/app folder in place of .android/app', () async { + final FlutterProject project = await aModuleProject(); + await project.android.materialize(); + expectNotExists(project.directory.childDirectory('.android').childDirectory('app')); + expect( + project.directory.childDirectory('.android').childFile('settings.gradle').readAsStringSync(), + isNot(contains("include ':app'")), + ); + expectExists(project.directory.childDirectory('android').childDirectory('app')); + expectExists(project.directory.childDirectory('android').childFile('local.properties')); + expect( + project.directory.childDirectory('android').childFile('settings.gradle').readAsStringSync(), + contains("include ':app'"), + ); + }); + testInMemory('retains .android/Flutter folder and references it', () async { + final FlutterProject project = await aModuleProject(); + await project.android.materialize(); + expectExists(project.directory.childDirectory('.android').childDirectory('Flutter')); + expect( + project.directory.childDirectory('android').childFile('settings.gradle').readAsStringSync(), + contains('../.android/include_flutter.groovy'), + ); + }); + testInMemory('can be redone after deletion', () async { + final FlutterProject project = await aModuleProject(); + await project.android.materialize(); + project.directory.childDirectory('android').deleteSync(recursive: true); + await project.android.materialize(); + expectExists(project.directory.childDirectory('android').childDirectory('app')); + }); }); group('ensure ready for platform-specific tooling', () { - void expectExists(FileSystemEntity entity) { - expect(entity.existsSync(), isTrue); - } - void expectNotExists(FileSystemEntity entity) { - expect(entity.existsSync(), isFalse); - } testInMemory('does nothing, if project is not created', () async { final FlutterProject project = new FlutterProject( fs.directory('not_created'), @@ -118,9 +146,9 @@ final FlutterProject project = await aPluginProject(); await project.ensureReadyForPlatformSpecificTooling(); expectNotExists(project.ios.directory.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h')); - expectNotExists(androidPluginRegistrant(project.android.directory.childDirectory('app'))); + expectNotExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app'))); expectNotExists(project.ios.directory.childDirectory('Flutter').childFile('Generated.xcconfig')); - expectNotExists(project.android.directory.childFile('local.properties')); + expectNotExists(project.android.hostAppGradleRoot.childFile('local.properties')); }); testInMemory('injects plugins for iOS', () async { final FlutterProject project = await someProject(); @@ -135,19 +163,19 @@ testInMemory('injects plugins for Android', () async { final FlutterProject project = await someProject(); await project.ensureReadyForPlatformSpecificTooling(); - expectExists(androidPluginRegistrant(project.android.directory.childDirectory('app'))); + expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app'))); }); testInMemory('updates local properties for Android', () async { final FlutterProject project = await someProject(); await project.ensureReadyForPlatformSpecificTooling(); - expectExists(project.android.directory.childFile('local.properties')); + expectExists(project.android.hostAppGradleRoot.childFile('local.properties')); }); testInMemory('creates Android library in module', () async { final FlutterProject project = await aModuleProject(); await project.ensureReadyForPlatformSpecificTooling(); - expectExists(project.android.directory.childFile('settings.gradle')); - expectExists(project.android.directory.childFile('local.properties')); - expectExists(androidPluginRegistrant(project.android.directory.childDirectory('Flutter'))); + expectExists(project.android.hostAppGradleRoot.childFile('settings.gradle')); + expectExists(project.android.hostAppGradleRoot.childFile('local.properties')); + expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('Flutter'))); }); testInMemory('creates iOS pod in module', () async { final FlutterProject project = await aModuleProject(); @@ -169,7 +197,7 @@ expect(project.isModule, isTrue); expect(project.android.isModule, isTrue); expect(project.ios.isModule, isTrue); - expect(project.android.directory.basename, '.android'); + expect(project.android.hostAppGradleRoot.basename, '.android'); expect(project.ios.directory.basename, '.ios'); }); testInMemory('is known for non-module', () async { @@ -177,7 +205,7 @@ expect(project.isModule, isFalse); expect(project.android.isModule, isFalse); expect(project.ios.isModule, isFalse); - expect(project.android.directory.basename, 'android'); + expect(project.android.hostAppGradleRoot.basename, 'android'); expect(project.ios.directory.basename, 'ios'); }); }); @@ -326,6 +354,25 @@ } } +Future<Null> expectToolExitLater(Future<dynamic> future, Matcher messageMatcher) async { + try { + await future; + fail('ToolExit expected, but nothing thrown'); + } on ToolExit catch(e) { + expect(e.message, messageMatcher); + } catch(e, trace) { + fail('ToolExit expected, got $e\n$trace'); + } +} + +void expectExists(FileSystemEntity entity) { + expect(entity.existsSync(), isTrue); +} + +void expectNotExists(FileSystemEntity entity) { + expect(entity.existsSync(), isFalse); +} + void addIosWithBundleId(Directory directory, String id) { directory .childDirectory('ios')