| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:file/memory.dart'; |
| import 'package:flutter_tools/src/android/deferred_components_gen_snapshot_validator.dart'; |
| import 'package:flutter_tools/src/android/deferred_components_validator.dart'; |
| import 'package:flutter_tools/src/artifacts.dart'; |
| import 'package:flutter_tools/src/base/deferred_component.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:flutter_tools/src/build_info.dart'; |
| import 'package:flutter_tools/src/build_system/build_system.dart'; |
| |
| import '../../src/common.dart'; |
| import '../../src/fake_process_manager.dart'; |
| |
| void main() { |
| late FileSystem fileSystem; |
| late BufferLogger logger; |
| late Environment env; |
| |
| Environment createEnvironment() { |
| final Map<String, String> defines = <String, String>{ kDeferredComponents: 'true' }; |
| final Environment result = Environment.test( |
| fileSystem.directory('/project'), |
| defines: defines, |
| artifacts: Artifacts.test(), |
| fileSystem: fileSystem, |
| logger: logger, |
| processManager: FakeProcessManager.any(), |
| ); |
| return result; |
| } |
| |
| setUp(() { |
| fileSystem = MemoryFileSystem.test(); |
| logger = BufferLogger.test(); |
| env = createEnvironment(); |
| }); |
| |
| testWithoutContext('No checks passes', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| expect(logger.statusText, 'test check passed.\n'); |
| }); |
| |
| testWithoutContext('writeCache passes', () async { |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| if (cacheFile.existsSync()) { |
| cacheFile.deleteSync(); |
| } |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| validator.writeLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, 'test check passed.\n'); |
| |
| final File expectedFile = env.projectDir.childFile('deferred_components_loading_units.yaml'); |
| |
| expect(expectedFile.existsSync(), true); |
| const String expectedContents = |
| ''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| - lib2 |
| - lib3 |
| '''; |
| expect(expectedFile.readAsStringSync(), contains(expectedContents)); |
| }); |
| |
| testWithoutContext('loadingUnitCache identical passes', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| - lib2 |
| - lib3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ] |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, 'test check passed.\n'); |
| }); |
| |
| testWithoutContext('loadingUnitCache finds new loading units', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 3 |
| libraries: |
| - lib2 |
| - lib3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('New loading units were found:\n\n LoadingUnit 2\n Libraries:\n - lib1\n')); |
| }); |
| |
| testWithoutContext('loadingUnitCache finds missing loading units', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| - lib2 |
| - lib3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Previously existing loading units no longer exist:\n\n LoadingUnit 2\n Libraries:\n - lib1\n')); |
| }); |
| |
| testWithoutContext('missing cache file counts as all new loading units', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('New loading units were found:\n\n LoadingUnit 2\n Libraries:\n - lib1\n')); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: missing main entry', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units-spelled-wrong: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| - lib2 |
| - lib3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, 'loading-units' entry did not exist.")); |
| |
| expect(logger.statusText.contains('Previously existing loading units no longer exist:\n\n LoadingUnit 2\n Libraries:\n - lib1\n'), false); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: not a list', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: hello |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, 'loading-units' is not a list.")); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: not a list', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - 2 |
| - 3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, 'loading-units' is not a list of maps.")); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: missing id', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - libraries: |
| - lib2 |
| - lib3 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, all loading units must have an 'id'")); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: libraries is list', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: hello |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, 'libraries' is not a list.")); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: libraries is list of strings', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| - blah: hello |
| blah2: hello2 |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Errors checking the following files:')); |
| expect(logger.statusText, contains("Invalid loading units yaml file, 'libraries' is not a list of strings.")); |
| }); |
| |
| testWithoutContext('loadingUnitCache validator detects malformed file: empty libraries allowed', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final File cacheFile = env.projectDir.childFile(DeferredComponentsValidator.kLoadingUnitsCacheFileName); |
| cacheFile.createSync(recursive: true); |
| cacheFile.writeAsStringSync(''' |
| loading-units: |
| - id: 2 |
| libraries: |
| - lib1 |
| - id: 3 |
| libraries: |
| '''); |
| validator.checkAgainstLoadingUnitsCache( |
| <LoadingUnit>[ |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText.contains('Errors checking the following files:'), false); |
| }); |
| |
| testWithoutContext('androidStringMapping modifies strings file', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final Directory baseModuleDir = env.projectDir.childDirectory('android').childDirectory('app'); |
| final File manifest = baseModuleDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml'); |
| if (manifest.existsSync()) { |
| manifest.deleteSync(); |
| } |
| manifest.createSync(recursive: true); |
| manifest.writeAsStringSync(''' |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="com.example.splitaot"> |
| <application |
| android:name="io.flutter.app.FlutterPlayStoreSplitApplication" |
| android:label="splitaot" |
| android:extractNativeLibs="false"> |
| <activity |
| android:name=".MainActivity" |
| android:launchMode="singleTop" |
| android:windowSoftInputMode="adjustResize"> |
| </activity> |
| <!-- Don't delete the meta-data below. |
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
| <meta-data |
| android:name="flutterEmbedding" |
| android:value="2" /> |
| <meta-data |
| android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" |
| |
| android:value="invalidmapping" |
| |
| /> |
| </application> |
| </manifest> |
| '''); |
| validator.checkAppAndroidManifestComponentLoadingUnitMapping( |
| <DeferredComponent>[ |
| DeferredComponent(name: 'component1', libraries: <String>['lib2']), |
| DeferredComponent(name: 'component2', libraries: <String>['lib1', 'lib4']), |
| ], |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| LoadingUnit(id: 4, libraries: <String>['lib4', 'lib5']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Modified android files:\n')); |
| expect(logger.statusText, contains('build/${DeferredComponentsValidator.kDeferredComponentsTempDirectory}/app/src/main/AndroidManifest.xml\n')); |
| |
| final File manifestOutput = env.projectDir |
| .childDirectory('build') |
| .childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory) |
| .childDirectory('app') |
| .childDirectory('src') |
| .childDirectory('main') |
| .childFile('AndroidManifest.xml'); |
| expect(manifestOutput.existsSync(), true); |
| expect(manifestOutput.readAsStringSync().contains('<meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" android:value="3:component1,2:component2,4:component2"/>'), true); |
| expect(manifestOutput.readAsStringSync().contains('android:value="invalidmapping"'), false); |
| expect(manifestOutput.readAsStringSync().contains("<!-- Don't delete the meta-data below."), true); |
| }); |
| |
| testWithoutContext('androidStringMapping adds mapping when no existing mapping', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final Directory baseModuleDir = env.projectDir.childDirectory('android').childDirectory('app'); |
| final File manifest = baseModuleDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml'); |
| manifest.createSync(recursive: true); |
| manifest.writeAsStringSync(''' |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="com.example.splitaot"> |
| <application |
| android:name="io.flutter.app.FlutterPlayStoreSplitApplication" |
| android:label="splitaot" |
| android:extractNativeLibs="false"> |
| <activity |
| android:name=".MainActivity" |
| android:launchMode="singleTop" |
| android:windowSoftInputMode="adjustResize"> |
| </activity> |
| <!-- Don't delete the meta-data below. |
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
| <meta-data |
| android:name="flutterEmbedding" |
| android:value="2" /> |
| </application> |
| </manifest> |
| '''); |
| validator.checkAppAndroidManifestComponentLoadingUnitMapping( |
| <DeferredComponent>[ |
| DeferredComponent(name: 'component1', libraries: <String>['lib2']), |
| DeferredComponent(name: 'component2', libraries: <String>['lib1', 'lib4']), |
| ], |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| LoadingUnit(id: 4, libraries: <String>['lib4', 'lib5']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Modified android files:\n')); |
| expect(logger.statusText, contains('build/${DeferredComponentsValidator.kDeferredComponentsTempDirectory}/app/src/main/AndroidManifest.xml\n')); |
| |
| final File manifestOutput = env.projectDir |
| .childDirectory('build') |
| .childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory) |
| .childDirectory('app') |
| .childDirectory('src') |
| .childDirectory('main') |
| .childFile('AndroidManifest.xml'); |
| expect(manifestOutput.existsSync(), true); |
| expect(manifestOutput.readAsStringSync(), contains('<meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" android:value="3:component1,2:component2,4:component2"/>')); |
| expect(manifestOutput.readAsStringSync(), contains("<!-- Don't delete the meta-data below.")); |
| }); |
| |
| // The mapping is incorrectly placed in the activity instead of application. |
| testWithoutContext('androidStringMapping detects improperly placed metadata mapping', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final Directory baseModuleDir = env.projectDir.childDirectory('android').childDirectory('app'); |
| final File manifest = baseModuleDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml'); |
| manifest.createSync(recursive: true); |
| manifest.writeAsStringSync(''' |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="com.example.splitaot"> |
| <application |
| android:name="io.flutter.app.FlutterPlayStoreSplitApplication" |
| android:label="splitaot" |
| android:extractNativeLibs="false"> |
| <activity |
| android:name=".MainActivity" |
| android:launchMode="singleTop" |
| android:windowSoftInputMode="adjustResize"> |
| <meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" |
| android:value="3:component1,2:component2,4:component2"/> |
| </activity> |
| <!-- Don't delete the meta-data below. |
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
| <meta-data |
| android:name="flutterEmbedding" |
| android:value="2" /> |
| </application> |
| </manifest> |
| '''); |
| validator.checkAppAndroidManifestComponentLoadingUnitMapping( |
| <DeferredComponent>[ |
| DeferredComponent(name: 'component1', libraries: <String>['lib2']), |
| DeferredComponent(name: 'component2', libraries: <String>['lib1', 'lib4']), |
| ], |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| LoadingUnit(id: 4, libraries: <String>['lib4', 'lib5']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Modified android files:\n')); |
| expect(logger.statusText, contains('build/${DeferredComponentsValidator.kDeferredComponentsTempDirectory}/app/src/main/AndroidManifest.xml\n')); |
| |
| final File manifestOutput = env.projectDir |
| .childDirectory('build') |
| .childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory) |
| .childDirectory('app') |
| .childDirectory('src') |
| .childDirectory('main') |
| .childFile('AndroidManifest.xml'); |
| expect(manifestOutput.existsSync(), true); |
| expect(manifestOutput.readAsStringSync(), contains('<meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" android:value="3:component1,2:component2,4:component2"/>')); |
| expect(manifestOutput.readAsStringSync(), contains("<!-- Don't delete the meta-data below.")); |
| }); |
| |
| testWithoutContext('androidStringMapping generates base module loading unit mapping', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final Directory baseModuleDir = env.projectDir.childDirectory('android').childDirectory('app'); |
| final File manifest = baseModuleDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml'); |
| manifest.createSync(recursive: true); |
| manifest.writeAsStringSync(''' |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="com.example.splitaot"> |
| <application |
| android:name="io.flutter.app.FlutterPlayStoreSplitApplication" |
| android:label="splitaot" |
| android:extractNativeLibs="false"> |
| <activity |
| android:name=".MainActivity" |
| android:launchMode="singleTop" |
| android:windowSoftInputMode="adjustResize"> |
| </activity> |
| <!-- Don't delete the meta-data below. |
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
| <meta-data |
| android:name="flutterEmbedding" |
| android:value="2" /> |
| </application> |
| </manifest> |
| '''); |
| validator.checkAppAndroidManifestComponentLoadingUnitMapping( |
| <DeferredComponent>[ |
| DeferredComponent(name: 'component1', libraries: <String>['lib2']), |
| DeferredComponent(name: 'component2', libraries: <String>['lib1', 'lib4']), |
| ], |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| LoadingUnit(id: 4, libraries: <String>['lib4', 'lib5']), |
| // Loading units 6 and 7 are in base module |
| LoadingUnit(id: 5, libraries: <String>['lib6', 'lib7']), |
| LoadingUnit(id: 6, libraries: <String>['lib8', 'lib9']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Modified android files:\n')); |
| expect(logger.statusText, contains('build/${DeferredComponentsValidator.kDeferredComponentsTempDirectory}/app/src/main/AndroidManifest.xml\n')); |
| |
| final File manifestOutput = env.projectDir |
| .childDirectory('build') |
| .childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory) |
| .childDirectory('app') |
| .childDirectory('src') |
| .childDirectory('main') |
| .childFile('AndroidManifest.xml'); |
| expect(manifestOutput.existsSync(), true); |
| expect(manifestOutput.readAsStringSync(), contains('<meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" android:value="3:component1,2:component2,4:component2,5:,6:"/>')); |
| expect(manifestOutput.readAsStringSync(), contains("<!-- Don't delete the meta-data below.")); |
| }); |
| |
| // Tests if all of the regexp whitespace detection is working. |
| testWithoutContext('androidStringMapping handles whitespace within entry', () async { |
| final DeferredComponentsGenSnapshotValidator validator = DeferredComponentsGenSnapshotValidator( |
| env, |
| exitOnFail: false, |
| title: 'test check', |
| ); |
| final Directory baseModuleDir = env.projectDir.childDirectory('android').childDirectory('app'); |
| final File manifest = baseModuleDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml'); |
| manifest.createSync(recursive: true); |
| manifest.writeAsStringSync(''' |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="com.example.splitaot"> |
| <application |
| android:name="io.flutter.app.FlutterPlayStoreSplitApplication" |
| android:label="splitaot" |
| android:extractNativeLibs="false"> |
| <activity |
| android:name=".MainActivity" |
| android:launchMode="singleTop" |
| android:windowSoftInputMode="adjustResize"> |
| </activity> |
| <!-- Don't delete the meta-data below. |
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
| <meta-data |
| android:name="flutterEmbedding" |
| android:value="2" /> |
| <meta-data |
| |
| android:name = "io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" |
| |
| android:value = "invalidmapping" |
| |
| /> |
| </application> |
| </manifest> |
| '''); |
| validator.checkAppAndroidManifestComponentLoadingUnitMapping( |
| <DeferredComponent>[ |
| DeferredComponent(name: 'component1', libraries: <String>['lib2']), |
| DeferredComponent(name: 'component2', libraries: <String>['lib1', 'lib4']), |
| ], |
| <LoadingUnit>[ |
| LoadingUnit(id: 2, libraries: <String>['lib1']), |
| LoadingUnit(id: 3, libraries: <String>['lib2', 'lib3']), |
| LoadingUnit(id: 4, libraries: <String>['lib4', 'lib5']), |
| ], |
| ); |
| validator.displayResults(); |
| validator.attemptToolExit(); |
| |
| expect(logger.statusText, contains('Modified android files:\n')); |
| expect(logger.statusText, contains('build/${DeferredComponentsValidator.kDeferredComponentsTempDirectory}/app/src/main/AndroidManifest.xml\n')); |
| |
| final File manifestOutput = env.projectDir |
| .childDirectory('build') |
| .childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory) |
| .childDirectory('app') |
| .childDirectory('src') |
| .childDirectory('main') |
| .childFile('AndroidManifest.xml'); |
| expect(manifestOutput.existsSync(), true); |
| expect(manifestOutput.readAsStringSync().contains('<meta-data android:name="io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadingUnitMapping" android:value="3:component1,2:component2,4:component2"/>'), true); |
| expect(manifestOutput.readAsStringSync().contains(RegExp(r'android:value[\s\n]*=[\s\n]*"invalidmapping"')), false); |
| expect(manifestOutput.readAsStringSync().contains("<!-- Don't delete the meta-data below."), true); |
| }); |
| } |