blob: dc19f23332fde5c923abece3c7f0d82578ed95a1 [file] [log] [blame]
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +01001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
Ian Hickson686d8f82018-08-14 20:33:58 -07006
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +02007import 'package:flutter_tools/src/base/common.dart';
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +02008import 'package:flutter_tools/src/base/context.dart';
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +02009import 'package:flutter_tools/src/base/platform.dart';
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +020010import 'package:flutter_tools/src/cache.dart';
11import 'package:flutter_tools/src/flutter_manifest.dart';
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +010012import 'package:flutter_tools/src/project.dart';
13import 'package:flutter_tools/src/base/file_system.dart';
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +010014import 'package:file/file.dart';
15import 'package:file/memory.dart';
Ian Hickson686d8f82018-08-14 20:33:58 -070016
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +020017import 'src/common.dart';
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +010018import 'src/context.dart';
19
20void main() {
21 group('Project', () {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +020022 group('construction', () {
23 testInMemory('fails on null directory', () async {
24 await expectLater(
25 FlutterProject.fromDirectory(null),
Ian Hickson686d8f82018-08-14 20:33:58 -070026 throwsA(isInstanceOf<AssertionError>()),
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +020027 );
28 });
29
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +020030 testInMemory('fails on invalid pubspec.yaml', () async {
31 final Directory directory = fs.directory('myproject');
32 directory.childFile('pubspec.yaml')
33 ..createSync(recursive: true)
34 ..writeAsStringSync(invalidPubspec);
35 await expectToolExitLater(
36 FlutterProject.fromDirectory(directory),
37 contains('pubspec.yaml'),
38 );
39 });
40
41 testInMemory('fails on invalid example/pubspec.yaml', () async {
42 final Directory directory = fs.directory('myproject');
43 directory.childDirectory('example').childFile('pubspec.yaml')
44 ..createSync(recursive: true)
45 ..writeAsStringSync(invalidPubspec);
46 await expectToolExitLater(
47 FlutterProject.fromDirectory(directory),
48 contains('pubspec.yaml'),
49 );
50 });
51
52 testInMemory('treats missing pubspec.yaml as empty', () async {
53 final Directory directory = fs.directory('myproject')
54 ..createSync(recursive: true);
55 expect(
56 (await FlutterProject.fromDirectory(directory)).manifest.isEmpty,
57 true,
58 );
59 });
60
61 testInMemory('reads valid pubspec.yaml', () async {
62 final Directory directory = fs.directory('myproject');
63 directory.childFile('pubspec.yaml')
64 ..createSync(recursive: true)
65 ..writeAsStringSync(validPubspec);
66 expect(
67 (await FlutterProject.fromDirectory(directory)).manifest.appName,
68 'hello',
69 );
70 });
71
72 testInMemory('sets up location', () async {
73 final Directory directory = fs.directory('myproject');
74 expect(
75 (await FlutterProject.fromDirectory(directory)).directory.absolute.path,
76 directory.absolute.path,
77 );
78 expect(
79 (await FlutterProject.fromPath(directory.path)).directory.absolute.path,
80 directory.absolute.path,
81 );
82 expect(
83 (await FlutterProject.current()).directory.absolute.path,
84 fs.currentDirectory.absolute.path,
85 );
86 });
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +020087 });
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +020088
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +020089 group('materialize Android', () {
90 testInMemory('fails on non-module', () async {
91 final FlutterProject project = await someProject();
92 await expectLater(
93 project.android.materialize(),
Mikkel Nygaard Ravn26ba9372018-08-16 13:59:27 +020094 throwsA(isInstanceOf<AssertionError>()),
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +020095 );
96 });
97 testInMemory('exits on already materialized module', () async {
98 final FlutterProject project = await aModuleProject();
99 await project.android.materialize();
xstercda2c222018-08-30 20:57:44 -0700100 return expectToolExitLater(project.android.materialize(), contains('already materialized'));
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200101 });
102 testInMemory('creates android/app folder in place of .android/app', () async {
103 final FlutterProject project = await aModuleProject();
104 await project.android.materialize();
105 expectNotExists(project.directory.childDirectory('.android').childDirectory('app'));
106 expect(
107 project.directory.childDirectory('.android').childFile('settings.gradle').readAsStringSync(),
108 isNot(contains("include ':app'")),
109 );
110 expectExists(project.directory.childDirectory('android').childDirectory('app'));
111 expectExists(project.directory.childDirectory('android').childFile('local.properties'));
112 expect(
113 project.directory.childDirectory('android').childFile('settings.gradle').readAsStringSync(),
114 contains("include ':app'"),
115 );
116 });
117 testInMemory('retains .android/Flutter folder and references it', () async {
118 final FlutterProject project = await aModuleProject();
119 await project.android.materialize();
120 expectExists(project.directory.childDirectory('.android').childDirectory('Flutter'));
121 expect(
122 project.directory.childDirectory('android').childFile('settings.gradle').readAsStringSync(),
123 contains('../.android/include_flutter.groovy'),
124 );
125 });
126 testInMemory('can be redone after deletion', () async {
127 final FlutterProject project = await aModuleProject();
128 await project.android.materialize();
129 project.directory.childDirectory('android').deleteSync(recursive: true);
130 await project.android.materialize();
131 expectExists(project.directory.childDirectory('android').childDirectory('app'));
132 });
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100133 });
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200134
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100135 group('ensure ready for platform-specific tooling', () {
136 testInMemory('does nothing, if project is not created', () async {
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200137 final FlutterProject project = new FlutterProject(
138 fs.directory('not_created'),
139 FlutterManifest.empty(),
140 FlutterManifest.empty(),
141 );
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200142 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200143 expectNotExists(project.directory);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100144 });
PJ Essienfd7222e2018-04-23 02:03:46 +0100145 testInMemory('does nothing in plugin or package root project', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200146 final FlutterProject project = await aPluginProject();
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200147 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200148 expectNotExists(project.ios.directory.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200149 expectNotExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200150 expectNotExists(project.ios.directory.childDirectory('Flutter').childFile('Generated.xcconfig'));
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200151 expectNotExists(project.android.hostAppGradleRoot.childFile('local.properties'));
Mikkel Nygaard Ravnf5268052018-02-17 21:25:13 +0100152 });
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200153 testInMemory('injects plugins for iOS', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200154 final FlutterProject project = await someProject();
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200155 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200156 expectExists(project.ios.directory.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100157 });
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200158 testInMemory('generates Xcode configuration for iOS', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200159 final FlutterProject project = await someProject();
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200160 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200161 expectExists(project.ios.directory.childDirectory('Flutter').childFile('Generated.xcconfig'));
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100162 });
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200163 testInMemory('injects plugins for Android', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200164 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200165 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200166 expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200167 });
168 testInMemory('updates local properties for Android', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200169 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200170 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200171 expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200172 });
173 testInMemory('creates Android library in module', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200174 final FlutterProject project = await aModuleProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200175 await project.ensureReadyForPlatformSpecificTooling();
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200176 expectExists(project.android.hostAppGradleRoot.childFile('settings.gradle'));
177 expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
178 expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('Flutter')));
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200179 });
180 testInMemory('creates iOS pod in module', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200181 final FlutterProject project = await aModuleProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200182 await project.ensureReadyForPlatformSpecificTooling();
183 final Directory flutter = project.ios.directory.childDirectory('Flutter');
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200184 expectExists(flutter.childFile('podhelper.rb'));
185 expectExists(flutter.childFile('Generated.xcconfig'));
186 final Directory pluginRegistrantClasses = flutter
187 .childDirectory('FlutterPluginRegistrant')
188 .childDirectory('Classes');
189 expectExists(pluginRegistrantClasses.childFile('GeneratedPluginRegistrant.h'));
190 expectExists(pluginRegistrantClasses.childFile('GeneratedPluginRegistrant.m'));
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200191 });
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100192 });
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200193
194 group('module status', () {
195 testInMemory('is known for module', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200196 final FlutterProject project = await aModuleProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200197 expect(project.isModule, isTrue);
198 expect(project.android.isModule, isTrue);
199 expect(project.ios.isModule, isTrue);
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200200 expect(project.android.hostAppGradleRoot.basename, '.android');
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200201 expect(project.ios.directory.basename, '.ios');
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200202 });
203 testInMemory('is known for non-module', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200204 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200205 expect(project.isModule, isFalse);
206 expect(project.android.isModule, isFalse);
207 expect(project.ios.isModule, isFalse);
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200208 expect(project.android.hostAppGradleRoot.basename, 'android');
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200209 expect(project.ios.directory.basename, 'ios');
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200210 });
211 });
212
213 group('example', () {
214 testInMemory('exists for plugin', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200215 final FlutterProject project = await aPluginProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200216 expect(project.hasExampleApp, isTrue);
217 });
218 testInMemory('does not exist for non-plugin', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200219 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200220 expect(project.hasExampleApp, isFalse);
221 });
222 });
223
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100224 group('organization names set', () {
225 testInMemory('is empty, if project not created', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200226 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200227 expect(project.organizationNames, isEmpty);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100228 });
229 testInMemory('is empty, if no platform folders exist', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200230 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100231 project.directory.createSync();
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200232 expect(project.organizationNames, isEmpty);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100233 });
234 testInMemory('is populated from iOS bundle identifier', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200235 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100236 addIosWithBundleId(project.directory, 'io.flutter.someProject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200237 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100238 });
239 testInMemory('is populated from Android application ID', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200240 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100241 addAndroidWithApplicationId(project.directory, 'io.flutter.someproject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200242 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100243 });
244 testInMemory('is populated from iOS bundle identifier in plugin example', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200245 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100246 addIosWithBundleId(project.example.directory, 'io.flutter.someProject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200247 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100248 });
249 testInMemory('is populated from Android application ID in plugin example', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200250 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100251 addAndroidWithApplicationId(project.example.directory, 'io.flutter.someproject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200252 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100253 });
254 testInMemory('is populated from Android group in plugin', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200255 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100256 addAndroidWithGroup(project.directory, 'io.flutter.someproject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200257 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100258 });
259 testInMemory('is singleton, if sources agree', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200260 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100261 addIosWithBundleId(project.directory, 'io.flutter.someProject');
262 addAndroidWithApplicationId(project.directory, 'io.flutter.someproject');
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200263 expect(project.organizationNames, <String>['io.flutter']);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100264 });
265 testInMemory('is non-singleton, if sources disagree', () async {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200266 final FlutterProject project = await someProject();
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100267 addIosWithBundleId(project.directory, 'io.flutter.someProject');
268 addAndroidWithApplicationId(project.directory, 'io.clutter.someproject');
269 expect(
Mikkel Nygaard Ravn22832d32018-08-30 16:18:44 +0200270 project.organizationNames,
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100271 <String>['io.flutter', 'io.clutter'],
272 );
273 });
274 });
275 });
276}
277
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200278Future<FlutterProject> someProject() async {
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200279 final Directory directory = fs.directory('some_project');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100280 directory.childFile('.packages').createSync(recursive: true);
281 directory.childDirectory('ios').createSync(recursive: true);
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200282 directory.childDirectory('android').createSync(recursive: true);
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200283 return FlutterProject.fromDirectory(directory);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100284}
285
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200286Future<FlutterProject> aPluginProject() async {
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200287 final Directory directory = fs.directory('plugin_project');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100288 directory.childDirectory('ios').createSync(recursive: true);
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200289 directory.childDirectory('android').createSync(recursive: true);
290 directory.childDirectory('example').createSync(recursive: true);
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200291 directory.childFile('pubspec.yaml').writeAsStringSync('''
292name: my_plugin
293flutter:
294 plugin:
295 androidPackage: com.example
296 pluginClass: MyPlugin
297 iosPrefix: FLT
298''');
299 return FlutterProject.fromDirectory(directory);
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200300}
301
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200302Future<FlutterProject> aModuleProject() async {
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200303 final Directory directory = fs.directory('module_project');
304 directory.childFile('.packages').createSync(recursive: true);
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200305 directory.childFile('pubspec.yaml').writeAsStringSync('''
306name: my_module
307flutter:
308 module:
309 androidPackage: com.example
310''');
311 return FlutterProject.fromDirectory(directory);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100312}
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100313
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200314/// Executes the [testMethod] in a context where the file system
315/// is in memory.
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100316void testInMemory(String description, Future<Null> testMethod()) {
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200317 Cache.flutterRoot = getFlutterRoot();
318 final FileSystem testFileSystem = new MemoryFileSystem(
319 style: platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
320 );
321 // Transfer needed parts of the Flutter installation folder
322 // to the in-memory file system used during testing.
323 transfer(new Cache().getArtifactDirectory('gradle_wrapper'), testFileSystem);
324 transfer(fs.directory(Cache.flutterRoot)
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200325 .childDirectory('packages')
326 .childDirectory('flutter_tools')
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200327 .childDirectory('templates'), testFileSystem);
328 transfer(fs.directory(Cache.flutterRoot)
Mikkel Nygaard Ravn3c83c522018-08-07 23:43:15 +0200329 .childDirectory('packages')
330 .childDirectory('flutter_tools')
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200331 .childDirectory('schema'), testFileSystem);
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100332 testUsingContext(
333 description,
334 testMethod,
335 overrides: <Type, Generator>{
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200336 FileSystem: () => testFileSystem,
337 Cache: () => new Cache(),
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100338 },
339 );
340}
341
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200342/// Transfers files and folders from the local file system's Flutter
343/// installation to an (in-memory) file system used for testing.
344void transfer(FileSystemEntity entity, FileSystem target) {
345 if (entity is Directory) {
346 target.directory(entity.absolute.path).createSync(recursive: true);
347 for (FileSystemEntity child in entity.listSync()) {
348 transfer(child, target);
349 }
350 } else if (entity is File) {
351 target.file(entity.absolute.path).writeAsBytesSync(entity.readAsBytesSync(), flush: true);
352 } else {
353 throw 'Unsupported FileSystemEntity ${entity.runtimeType}';
354 }
355}
356
Mikkel Nygaard Ravnd4e5e1e2018-08-16 13:21:55 +0200357Future<Null> expectToolExitLater(Future<dynamic> future, Matcher messageMatcher) async {
358 try {
359 await future;
360 fail('ToolExit expected, but nothing thrown');
361 } on ToolExit catch(e) {
362 expect(e.message, messageMatcher);
363 } catch(e, trace) {
364 fail('ToolExit expected, got $e\n$trace');
365 }
366}
367
368void expectExists(FileSystemEntity entity) {
369 expect(entity.existsSync(), isTrue);
370}
371
372void expectNotExists(FileSystemEntity entity) {
373 expect(entity.existsSync(), isFalse);
374}
375
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100376void addIosWithBundleId(Directory directory, String id) {
377 directory
378 .childDirectory('ios')
379 .childDirectory('Runner.xcodeproj')
380 .childFile('project.pbxproj')
381 ..createSync(recursive: true)
382 ..writeAsStringSync(projectFileWithBundleId(id));
383}
384
385void addAndroidWithApplicationId(Directory directory, String id) {
386 directory
387 .childDirectory('android')
388 .childDirectory('app')
389 .childFile('build.gradle')
390 ..createSync(recursive: true)
391 ..writeAsStringSync(gradleFileWithApplicationId(id));
392}
393
394void addAndroidWithGroup(Directory directory, String id) {
395 directory.childDirectory('android').childFile('build.gradle')
396 ..createSync(recursive: true)
397 ..writeAsStringSync(gradleFileWithGroupId(id));
398}
399
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200400String get validPubspec => '''
401name: hello
402flutter:
403''';
404
405String get invalidPubspec => '''
406name: hello
407flutter:
408 invalid:
409''';
410
Mikkel Nygaard Ravn43532972018-01-18 09:21:24 +0100411String projectFileWithBundleId(String id) {
412 return '''
41397C147061CF9000F007C117D /* Debug */ = {
414 isa = XCBuildConfiguration;
415 baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
416 buildSettings = {
417 PRODUCT_BUNDLE_IDENTIFIER = $id;
418 PRODUCT_NAME = "\$(TARGET_NAME)";
419 };
420 name = Debug;
421};
422''';
423}
424
425String gradleFileWithApplicationId(String id) {
426 return '''
427apply plugin: 'com.android.application'
428android {
429 compileSdkVersion 27
430
431 defaultConfig {
432 applicationId '$id'
433 }
434}
435''';
436}
437
438String gradleFileWithGroupId(String id) {
439 return '''
440group '$id'
441version '1.0-SNAPSHOT'
442
443apply plugin: 'com.android.library'
444
445android {
446 compileSdkVersion 27
447}
448''';
449}
Mikkel Nygaard Ravna737c862018-08-10 21:49:24 +0200450
451File androidPluginRegistrant(Directory parent) {
452 return parent.childDirectory('src')
453 .childDirectory('main')
454 .childDirectory('java')
455 .childDirectory('io')
456 .childDirectory('flutter')
457 .childDirectory('plugins')
458 .childFile('GeneratedPluginRegistrant.java');
459}