blob: 11cf2027256984fb8f40a135c56bbab5a907ac54 [file] [log] [blame]
// 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(),
});
}