| // 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/file.dart'; | |
| import 'package:file/memory.dart'; | |
| import 'package:flutter_tools/src/android/multidex.dart'; | |
| import 'package:flutter_tools/src/base/file_system.dart'; | |
| import 'package:flutter_tools/src/globals.dart' as globals; | |
| import '../../src/common.dart'; | |
| import '../../src/context.dart'; | |
| void main() { | |
| testUsingContext('ensureMultidexUtilsExists patches file when invalid', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childDirectory('java') | |
| .childDirectory('io') | |
| .childDirectory('flutter') | |
| .childDirectory('app') | |
| .childFile('FlutterMultiDexApplication.java'); | |
| applicationFile.createSync(recursive: true); | |
| applicationFile.writeAsStringSync('hello', flush: true); | |
| expect(applicationFile.readAsStringSync(), 'hello'); | |
| ensureMultiDexApplicationExists(directory); | |
| // File should remain untouched | |
| expect(applicationFile.readAsStringSync(), ''' | |
| // Generated file. | |
| // | |
| // If you wish to remove Flutter's multidex support, delete this entire file. | |
| // | |
| // Modifications to this file should be done in a copy under a different name | |
| // as this file may be regenerated. | |
| package io.flutter.app; | |
| import android.app.Application; | |
| import android.content.Context; | |
| import androidx.annotation.CallSuper; | |
| import androidx.multidex.MultiDex; | |
| /** | |
| * Extension of {@link android.app.Application}, adding multidex support. | |
| */ | |
| public class FlutterMultiDexApplication extends Application { | |
| @Override | |
| @CallSuper | |
| protected void attachBaseContext(Context base) { | |
| super.attachBaseContext(base); | |
| MultiDex.install(this); | |
| } | |
| } | |
| '''); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('ensureMultiDexApplicationExists generates when does not exist', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childDirectory('java') | |
| .childDirectory('io') | |
| .childDirectory('flutter') | |
| .childDirectory('app') | |
| .childFile('FlutterMultiDexApplication.java'); | |
| ensureMultiDexApplicationExists(directory); | |
| final String contents = applicationFile.readAsStringSync(); | |
| expect(contents.contains('FlutterMultiDexApplication'), true); | |
| expect(contents.contains('MultiDex.install(this);'), true); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('multiDexApplicationExists false when does not exist', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| expect(multiDexApplicationExists(directory), false); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('multiDexApplicationExists true when does exist', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File utilsFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childDirectory('java') | |
| .childDirectory('io') | |
| .childDirectory('flutter') | |
| .childDirectory('app') | |
| .childFile('FlutterMultiDexApplication.java'); | |
| utilsFile.createSync(recursive: true); | |
| expect(multiDexApplicationExists(directory), true); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('androidManifestHasNameVariable true with valid manifest', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childFile('AndroidManifest.xml'); | |
| applicationFile.createSync(recursive: true); | |
| applicationFile.writeAsStringSync(r''' | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.example.multidexapp"> | |
| <application | |
| android:label="multidextest2" | |
| android:name="${applicationName}" | |
| android:icon="@mipmap/ic_launcher"> | |
| </application> | |
| </manifest> | |
| ''', flush: true); | |
| expect(androidManifestHasNameVariable(directory), true); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('androidManifestHasNameVariable false with no android:name attribute', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childFile('AndroidManifest.xml'); | |
| applicationFile.createSync(recursive: true); | |
| applicationFile.writeAsStringSync(r''' | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.example.multidexapp"> | |
| <application | |
| android:label="multidextest2" | |
| android:icon="@mipmap/ic_launcher"> | |
| </application> | |
| ''', flush: true); | |
| expect(androidManifestHasNameVariable(directory), false); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('androidManifestHasNameVariable false with incorrect android:name attribute', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childFile('AndroidManifest.xml'); | |
| applicationFile.createSync(recursive: true); | |
| applicationFile.writeAsStringSync(r''' | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.example.multidexapp"> | |
| <application | |
| android:label="multidextest2" | |
| android:name="io.flutter.app.FlutterApplication" | |
| android:icon="@mipmap/ic_launcher"> | |
| </application> | |
| ''', flush: true); | |
| expect(androidManifestHasNameVariable(directory), false); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('androidManifestHasNameVariable false with invalid xml manifest', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| final File applicationFile = directory.childDirectory('android') | |
| .childDirectory('app') | |
| .childDirectory('src') | |
| .childDirectory('main') | |
| .childFile('AndroidManifest.xml'); | |
| applicationFile.createSync(recursive: true); | |
| applicationFile.writeAsStringSync(r''' | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.example.multidexapp"> | |
| <application | |
| android:label="multidextest2" | |
| android:name="${applicationName}" | |
| android:icon="@mipmap/ic_launcher"> | |
| </application> | |
| ''', flush: true); | |
| expect(androidManifestHasNameVariable(directory), false); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| testUsingContext('androidManifestHasNameVariable false with no manifest file', () async { | |
| final Directory directory = globals.fs.currentDirectory; | |
| expect(androidManifestHasNameVariable(directory), false); | |
| }, overrides: <Type, Generator>{ | |
| FileSystem: () => MemoryFileSystem.test(), | |
| ProcessManager: () => FakeProcessManager.any(), | |
| }); | |
| } |