blob: 84324879c0e0446f0721f7c8d428cc720ab97637 [file] [log] [blame]
Sarah Zakarias49ba9742017-09-26 14:48:52 +02001// Copyright 2017 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
Ralph Bergmannc65e9d12018-05-30 16:51:25 +02005import 'dart:async';
6
fmatosqg197d4312018-05-21 10:52:33 +10007import 'package:file/file.dart';
8import 'package:file/memory.dart';
Emmanuel Garcia3e65bb02019-05-01 09:49:39 -07009import 'package:flutter_tools/src/base/context.dart';
fmatosqg197d4312018-05-21 10:52:33 +100010import 'package:flutter_tools/src/base/file_system.dart';
Emmanuel Garcia3e65bb02019-05-01 09:49:39 -070011import 'package:flutter_tools/src/base/logger.dart';
Sarah Zakarias49ba9742017-09-26 14:48:52 +020012import 'package:flutter_tools/src/cache.dart';
13import 'package:flutter_tools/src/flutter_manifest.dart';
Sarah Zakarias49ba9742017-09-26 14:48:52 +020014
Ian Hicksond919e692019-07-13 11:51:44 -070015import '../src/common.dart';
16import '../src/context.dart';
17import '../src/pubspec_schema.dart';
Sarah Zakarias49ba9742017-09-26 14:48:52 +020018
19void main() {
20 setUpAll(() {
21 Cache.flutterRoot = getFlutterRoot();
22 });
23
24 group('FlutterManifest', () {
Sarah Zakarias3cbbbf02017-09-26 23:14:20 +020025 testUsingContext('is empty when the pubspec.yaml file is empty', () async {
Jonah Williams4ff46712019-04-29 08:21:32 -070026 final FlutterManifest flutterManifest = FlutterManifest.createFromString('');
Sarah Zakarias3cbbbf02017-09-26 23:14:20 +020027 expect(flutterManifest.isEmpty, true);
28 expect(flutterManifest.appName, '');
29 expect(flutterManifest.usesMaterialDesign, false);
30 expect(flutterManifest.fontsDescriptor, isEmpty);
31 expect(flutterManifest.fonts, isEmpty);
32 expect(flutterManifest.assets, isEmpty);
33 });
34
Sarah Zakarias49ba9742017-09-26 14:48:52 +020035 test('has no fonts or assets when the "flutter" section is empty', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +010036 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +020037name: test
38dependencies:
39 flutter:
40 sdk: flutter
41''';
Jonah Williams4ff46712019-04-29 08:21:32 -070042 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Sarah Zakarias49ba9742017-09-26 14:48:52 +020043 expect(flutterManifest, isNotNull);
Sarah Zakarias3cbbbf02017-09-26 23:14:20 +020044 expect(flutterManifest.isEmpty, false);
Sarah Zakarias49ba9742017-09-26 14:48:52 +020045 expect(flutterManifest.appName, 'test');
46 expect(flutterManifest.usesMaterialDesign, false);
47 expect(flutterManifest.fontsDescriptor, isEmpty);
48 expect(flutterManifest.fonts, isEmpty);
49 expect(flutterManifest.assets, isEmpty);
50 });
51
52 test('knows if material design is used', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +010053 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +020054name: test
55dependencies:
56 flutter:
57 sdk: flutter
58flutter:
59 uses-material-design: true
60''';
Jonah Williams4ff46712019-04-29 08:21:32 -070061 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Sarah Zakarias49ba9742017-09-26 14:48:52 +020062 expect(flutterManifest.usesMaterialDesign, true);
63 });
64
65 test('has two assets', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +010066 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +020067name: test
68dependencies:
69 flutter:
70 sdk: flutter
71flutter:
72 uses-material-design: true
73 assets:
74 - a/foo
75 - a/bar
76''';
Jonah Williams4ff46712019-04-29 08:21:32 -070077 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Michael Goderbauer84580b52018-01-24 13:16:23 -080078 expect(flutterManifest.assets.length, 2);
79 expect(flutterManifest.assets[0], Uri.parse('a/foo'));
80 expect(flutterManifest.assets[1], Uri.parse('a/bar'));
Sarah Zakarias49ba9742017-09-26 14:48:52 +020081 });
82
83 test('has one font family with one asset', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +010084 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +020085name: test
86dependencies:
87 flutter:
88 sdk: flutter
89flutter:
90 uses-material-design: true
91 fonts:
92 - family: foo
93 fonts:
94 - asset: a/bar
95''';
Jonah Williams4ff46712019-04-29 08:21:32 -070096 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Jason Simmons3581b3a2018-10-01 14:14:48 -070097 final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
98 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +020099 final List<Font> fonts = flutterManifest.fonts;
100 expect(fonts.length, 1);
101 final Font font = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700102 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}]}; // ignore: always_specify_types
103 expect(font.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200104 expect(font.familyName, 'foo');
105 final List<FontAsset> assets = font.fontAssets;
106 expect(assets.length, 1);
107 final FontAsset fontAsset = assets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800108 expect(fontAsset.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200109 expect(fontAsset.weight, isNull);
110 expect(fontAsset.style, isNull);
111 });
112
113 test('has one font family with a simple asset and one with weight', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100114 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200115name: test
116dependencies:
117 flutter:
118 sdk: flutter
119flutter:
120 uses-material-design: true
121 fonts:
122 - family: foo
123 fonts:
124 - asset: a/bar
125 - asset: a/bar
126 weight: 400
127''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700128 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Jason Simmons3581b3a2018-10-01 14:14:48 -0700129 final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
130 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200131 final List<Font> fonts = flutterManifest.fonts;
132 expect(fonts.length, 1);
133 final Font font = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700134 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'asset': 'a/bar'}]}; // ignore: always_specify_types
135 expect(font.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200136 expect(font.familyName, 'foo');
137 final List<FontAsset> assets = font.fontAssets;
138 expect(assets.length, 2);
139 final FontAsset fontAsset0 = assets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800140 expect(fontAsset0.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200141 expect(fontAsset0.weight, isNull);
142 expect(fontAsset0.style, isNull);
143 final FontAsset fontAsset1 = assets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800144 expect(fontAsset1.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200145 expect(fontAsset1.weight, 400);
146 expect(fontAsset1.style, isNull);
147 });
148
149 test('has one font family with a simple asset and one with weight and style', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100150 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200151name: test
152dependencies:
153 flutter:
154 sdk: flutter
155flutter:
156 uses-material-design: true
157 fonts:
158 - family: foo
159 fonts:
160 - asset: a/bar
161 - asset: a/bar
162 weight: 400
163 style: italic
164''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700165 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Jason Simmons3581b3a2018-10-01 14:14:48 -0700166 final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200167
Jason Simmons3581b3a2018-10-01 14:14:48 -0700168 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200169 final List<Font> fonts = flutterManifest.fonts;
170 expect(fonts.length, 1);
171 final Font font = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700172 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
173 expect(font.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200174 expect(font.familyName, 'foo');
175 final List<FontAsset> assets = font.fontAssets;
176 expect(assets.length, 2);
177 final FontAsset fontAsset0 = assets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800178 expect(fontAsset0.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200179 expect(fontAsset0.weight, isNull);
180 expect(fontAsset0.style, isNull);
181 final FontAsset fontAsset1 = assets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800182 expect(fontAsset1.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200183 expect(fontAsset1.weight, 400);
184 expect(fontAsset1.style, 'italic');
185 });
186
187 test('has two font families, each with one simple asset and one with weight and style', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100188 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200189name: test
190dependencies:
191 flutter:
192 sdk: flutter
193flutter:
194 uses-material-design: true
195 fonts:
196 - family: foo
197 fonts:
198 - asset: a/bar
199 - asset: a/bar
200 weight: 400
201 style: italic
202 - family: bar
203 fonts:
204 - asset: a/baz
205 - weight: 400
206 asset: a/baz
207 style: italic
208''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700209 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Jason Simmons3581b3a2018-10-01 14:14:48 -0700210 final dynamic expectedFontsDescriptor = <dynamic>[
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200211 {'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}, // ignore: always_specify_types
212 {'fonts': [{'asset': 'a/baz'}, {'style': 'italic', 'weight': 400, 'asset': 'a/baz'}], 'family': 'bar'}, // ignore: always_specify_types
Jason Simmons3581b3a2018-10-01 14:14:48 -0700213 ];
214 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200215 final List<Font> fonts = flutterManifest.fonts;
216 expect(fonts.length, 2);
217
218 final Font fooFont = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700219 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
220 expect(fooFont.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200221 expect(fooFont.familyName, 'foo');
222 final List<FontAsset> fooAassets = fooFont.fontAssets;
223 expect(fooAassets.length, 2);
224 final FontAsset fooFontAsset0 = fooAassets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800225 expect(fooFontAsset0.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200226 expect(fooFontAsset0.weight, isNull);
227 expect(fooFontAsset0.style, isNull);
228 final FontAsset fooFontAsset1 = fooAassets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800229 expect(fooFontAsset1.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200230 expect(fooFontAsset1.weight, 400);
231 expect(fooFontAsset1.style, 'italic');
232
233 final Font barFont = fonts[1];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700234 const String fontDescriptor = '{family: bar, fonts: [{asset: a/baz}, {weight: 400, style: italic, asset: a/baz}]}'; // ignore: always_specify_types
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200235 expect(barFont.descriptor.toString(), fontDescriptor);
236 expect(barFont.familyName, 'bar');
237 final List<FontAsset> barAssets = barFont.fontAssets;
238 expect(barAssets.length, 2);
239 final FontAsset barFontAsset0 = barAssets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800240 expect(barFontAsset0.assetUri.path, 'a/baz');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200241 expect(barFontAsset0.weight, isNull);
242 expect(barFontAsset0.style, isNull);
243 final FontAsset barFontAsset1 = barAssets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800244 expect(barFontAsset1.assetUri.path, 'a/baz');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200245 expect(barFontAsset1.weight, 400);
246 expect(barFontAsset1.style, 'italic');
247 });
248
Josh Sorefc5a59452018-03-07 00:36:03 -0500249 testUsingContext('has only one of two font families when one declaration is missing the "family" option', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100250 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200251name: test
252dependencies:
253 flutter:
254 sdk: flutter
255flutter:
256 uses-material-design: true
257 fonts:
258 - family: foo
259 fonts:
260 - asset: a/bar
261 - asset: a/bar
262 weight: 400
263 style: italic
264 - fonts:
265 - asset: a/baz
266 - asset: a/baz
267 weight: 400
268 style: italic
269''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700270 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200271
Jason Simmons3581b3a2018-10-01 14:14:48 -0700272 final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
273 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200274 final List<Font> fonts = flutterManifest.fonts;
275 expect(fonts.length, 1);
276 final Font fooFont = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700277 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
278 expect(fooFont.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200279 expect(fooFont.familyName, 'foo');
280 final List<FontAsset> fooAassets = fooFont.fontAssets;
281 expect(fooAassets.length, 2);
282 final FontAsset fooFontAsset0 = fooAassets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800283 expect(fooFontAsset0.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200284 expect(fooFontAsset0.weight, isNull);
285 expect(fooFontAsset0.style, isNull);
286 final FontAsset fooFontAsset1 = fooAassets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800287 expect(fooFontAsset1.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200288 expect(fooFontAsset1.weight, 400);
289 expect(fooFontAsset1.style, 'italic');
290 });
291
Josh Sorefc5a59452018-03-07 00:36:03 -0500292 testUsingContext('has only one of two font families when one declaration is missing the "fonts" option', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100293 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200294name: test
295dependencies:
296 flutter:
297 sdk: flutter
298flutter:
299 uses-material-design: true
300 fonts:
301 - family: foo
302 fonts:
303 - asset: a/bar
304 - asset: a/bar
305 weight: 400
306 style: italic
307 - family: bar
308''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700309 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Jason Simmons3581b3a2018-10-01 14:14:48 -0700310 final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
311 expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200312 final List<Font> fonts = flutterManifest.fonts;
313 expect(fonts.length, 1);
314 final Font fooFont = fonts[0];
Jason Simmons3581b3a2018-10-01 14:14:48 -0700315 final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
316 expect(fooFont.descriptor, fooFontDescriptor);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200317 expect(fooFont.familyName, 'foo');
318 final List<FontAsset> fooAassets = fooFont.fontAssets;
319 expect(fooAassets.length, 2);
320 final FontAsset fooFontAsset0 = fooAassets[0];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800321 expect(fooFontAsset0.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200322 expect(fooFontAsset0.weight, isNull);
323 expect(fooFontAsset0.style, isNull);
324 final FontAsset fooFontAsset1 = fooAassets[1];
Michael Goderbauer84580b52018-01-24 13:16:23 -0800325 expect(fooFontAsset1.assetUri.path, 'a/bar');
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200326 expect(fooFontAsset1.weight, 400);
327 expect(fooFontAsset1.style, 'italic');
328 });
329
330 testUsingContext('has no font family when declaration is missing the "asset" option', () async {
Alexandre Ardhuin841d5d72018-02-01 07:51:26 +0100331 const String manifest = '''
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200332name: test
333dependencies:
334 flutter:
335 sdk: flutter
336flutter:
337 uses-material-design: true
338 fonts:
339 - family: foo
340 fonts:
341 - weight: 400
342''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700343 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200344
Jason Simmons3581b3a2018-10-01 14:14:48 -0700345 expect(flutterManifest.fontsDescriptor, <dynamic>[]);
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200346 final List<Font> fonts = flutterManifest.fonts;
347 expect(fonts.length, 0);
348 });
Victor Choueiri7edd5c82018-03-19 23:55:54 +0200349
350 test('allows a blank flutter section', () async {
351 const String manifest = '''
352name: test
353dependencies:
354 flutter:
355 sdk: flutter
356flutter:
357''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700358 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Victor Choueiri7edd5c82018-03-19 23:55:54 +0200359 expect(flutterManifest.isEmpty, false);
Greg Spencer0ff9e8a2018-10-10 11:01:40 -0700360 expect(flutterManifest.isModule, false);
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200361 expect(flutterManifest.isPlugin, false);
362 expect(flutterManifest.androidPackage, null);
363 });
364
Greg Spencer0ff9e8a2018-10-10 11:01:40 -0700365 test('allows a module declaration', () async {
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200366 const String manifest = '''
367name: test
368flutter:
Greg Spencer0ff9e8a2018-10-10 11:01:40 -0700369 module:
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200370 androidPackage: com.example
371''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700372 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Greg Spencer0ff9e8a2018-10-10 11:01:40 -0700373 expect(flutterManifest.isModule, true);
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200374 expect(flutterManifest.androidPackage, 'com.example');
375 });
376
Kaushik Iskafc05c372019-08-29 21:51:31 -0700377 test('allows a legacy plugin declaration', () async {
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200378 const String manifest = '''
379name: test
380flutter:
381 plugin:
382 androidPackage: com.example
383''';
Jonah Williams4ff46712019-04-29 08:21:32 -0700384 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Mikkel Nygaard Ravn651c5ab2018-08-02 19:16:32 +0200385 expect(flutterManifest.isPlugin, true);
386 expect(flutterManifest.androidPackage, 'com.example');
Victor Choueiri7edd5c82018-03-19 23:55:54 +0200387 });
Kaushik Iskafc05c372019-08-29 21:51:31 -0700388 test('allows a multi-plat plugin declaration', () async {
389 const String manifest = '''
390name: test
391flutter:
392 plugin:
393 platforms:
394 android:
395 package: com.example
396 pluginClass: TestPlugin
397''';
398 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
399 expect(flutterManifest.isPlugin, true);
400 expect(flutterManifest.androidPackage, 'com.example');
401 });
402
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200403
404 Future<void> checkManifestVersion({
405 String manifest,
406 String expectedAppVersion,
407 String expectedBuildName,
KyleWong4b4a94002019-02-13 23:48:03 +0800408 String expectedBuildNumber,
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200409 }) async {
Jonah Williams4ff46712019-04-29 08:21:32 -0700410 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200411 expect(flutterManifest.appVersion, expectedAppVersion);
412 expect(flutterManifest.buildName, expectedBuildName);
413 expect(flutterManifest.buildNumber, expectedBuildNumber);
414 }
415
KyleWong4b4a94002019-02-13 23:48:03 +0800416 test('parses major.minor.patch+build version clause 1', () async {
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200417 const String manifest = '''
418name: test
419version: 1.0.0+2
420dependencies:
421 flutter:
422 sdk: flutter
423flutter:
424''';
425 await checkManifestVersion(
426 manifest: manifest,
427 expectedAppVersion: '1.0.0+2',
428 expectedBuildName: '1.0.0',
KyleWong4b4a94002019-02-13 23:48:03 +0800429 expectedBuildNumber: '2',
430 );
431 });
432
Jenn Magderdd1fb3b2019-07-31 16:18:09 -0700433 test('parses major.minor.patch with no build version', () async {
434 const String manifest = '''
435name: test
436version: 0.0.1
437dependencies:
438 flutter:
439 sdk: flutter
440flutter:
441''';
442 await checkManifestVersion(
443 manifest: manifest,
444 expectedAppVersion: '0.0.1',
445 expectedBuildName: '0.0.1',
446 expectedBuildNumber: null,
447 );
448 });
449
KyleWong4b4a94002019-02-13 23:48:03 +0800450 test('parses major.minor.patch+build version clause 2', () async {
451 const String manifest = '''
452name: test
453version: 1.0.0-beta+exp.sha.5114f85
454dependencies:
455 flutter:
456 sdk: flutter
457flutter:
458''';
459 await checkManifestVersion(
460 manifest: manifest,
461 expectedAppVersion: '1.0.0-beta+exp.sha.5114f85',
462 expectedBuildName: '1.0.0-beta',
463 expectedBuildNumber: 'exp.sha.5114f85',
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200464 );
465 });
466
467 test('parses major.minor+build version clause', () async {
468 const String manifest = '''
469name: test
470version: 1.0+2
471dependencies:
472 flutter:
473 sdk: flutter
474flutter:
475''';
476 await checkManifestVersion(
477 manifest: manifest,
478 expectedAppVersion: '1.0+2',
479 expectedBuildName: '1.0',
KyleWong4b4a94002019-02-13 23:48:03 +0800480 expectedBuildNumber: '2',
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200481 );
482 });
483
484 test('parses empty version clause', () async {
485 const String manifest = '''
486name: test
487version:
488dependencies:
489 flutter:
490 sdk: flutter
491flutter:
492''';
493 await checkManifestVersion(
494 manifest: manifest,
495 expectedAppVersion: null,
496 expectedBuildName: null,
497 expectedBuildNumber: null,
498 );
499 });
Emmanuel Garcia3e65bb02019-05-01 09:49:39 -0700500
Ralph Bergmannc65e9d12018-05-30 16:51:25 +0200501 test('parses no version clause', () async {
502 const String manifest = '''
503name: test
504dependencies:
505 flutter:
506 sdk: flutter
507flutter:
508''';
509 await checkManifestVersion(
510 manifest: manifest,
511 expectedAppVersion: null,
512 expectedBuildName: null,
513 expectedBuildNumber: null,
514 );
515 });
Emmanuel Garcia3e65bb02019-05-01 09:49:39 -0700516
517 // Regression test for https://github.com/flutter/flutter/issues/31764
518 testUsingContext('Returns proper error when font detail is malformed', () async {
519 final BufferLogger logger = context.get<Logger>();
520 const String manifest = '''
521name: test
522dependencies:
523 flutter:
524 sdk: flutter
525flutter:
526 fonts:
527 - family: foo
528 fonts:
529 -asset: a/bar
530''';
531 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
532
533 expect(flutterManifest, null);
534 expect(logger.errorText, contains('Expected "fonts" to either be null or a list.'));
535 });
Zachary Anderson500d7c52019-08-05 13:14:57 -0700536
Zachary Andersond2206312019-08-14 07:57:30 -0700537 testUsingContext('Returns proper error when font is a map instead of a list', () async {
538 final BufferLogger logger = context.get<Logger>();
539 const String manifest = '''
540name: test
541dependencies:
542 flutter:
543 sdk: flutter
544flutter:
545 fonts:
546 family: foo
547 fonts:
548 -asset: a/bar
549''';
550 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
551
552 expect(flutterManifest, null);
553 expect(logger.errorText, contains('Expected "fonts" to be a list'));
554 });
555
Zachary Anderson500d7c52019-08-05 13:14:57 -0700556 testUsingContext('Returns proper error when second font family is invalid', () async {
557 final BufferLogger logger = context.get<Logger>();
558 const String manifest = '''
559name: test
560dependencies:
561 flutter:
562 sdk: flutter
563flutter:
564 uses-material-design: true
565 fonts:
566 - family: foo
567 fonts:
568 - asset: a/bar
569 - string
570''';
571 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
572 expect(flutterManifest, null);
573 expect(logger.errorText, contains('Expected a map.'));
574 });
Jonah Williams0af2a842019-10-02 12:45:51 -0700575
576 testUsingContext('Does not crash on empty entry', () async {
577 final BufferLogger logger = context.get<Logger>();
578 const String manifest = '''
579name: test
580dependencies:
581 flutter:
582 sdk: flutter
583flutter:
584 uses-material-design: true
585 assets:
586 - lib/gallery/example_code.dart
587 -
588''';
589 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
590 final List<Uri> assets = flutterManifest.assets;
591
592 expect(logger.errorText, contains('Asset manifest contains a null or empty uri.'));
593 expect(assets.length, 1);
594 });
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200595 });
fmatosqg197d4312018-05-21 10:52:33 +1000596
597 group('FlutterManifest with MemoryFileSystem', () {
Alexandre Ardhuin774ca2f2018-09-11 07:14:04 +0200598 Future<void> assertSchemaIsReadable() async {
fmatosqg197d4312018-05-21 10:52:33 +1000599 const String manifest = '''
600name: test
601dependencies:
602 flutter:
603 sdk: flutter
604flutter:
605''';
606
Jonah Williams4ff46712019-04-29 08:21:32 -0700607 final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
fmatosqg197d4312018-05-21 10:52:33 +1000608 expect(flutterManifest.isEmpty, false);
609 }
610
Alexandre Ardhuin5169ab52019-02-21 09:27:07 +0100611 void testUsingContextAndFs(
612 String description,
613 FileSystem filesystem,
614 dynamic testMethod(),
615 ) {
Alexandre Ardhuin440ce8f2019-03-07 21:09:28 +0100616 testUsingContext(
617 description,
618 () async {
619 writeEmptySchemaFile(filesystem);
620 testMethod();
621 },
622 overrides: <Type, Generator>{
623 FileSystem: () => filesystem,
624 },
fmatosqg197d4312018-05-21 10:52:33 +1000625 );
626 }
627
Alexandre Ardhuin774ca2f2018-09-11 07:14:04 +0200628 testUsingContext('Validate manifest on original fs', () {
fmatosqg197d4312018-05-21 10:52:33 +1000629 assertSchemaIsReadable();
630 });
631
Alexandre Ardhuin440ce8f2019-03-07 21:09:28 +0100632 testUsingContextAndFs(
633 'Validate manifest on Posix FS',
634 MemoryFileSystem(style: FileSystemStyle.posix),
635 () {
636 assertSchemaIsReadable();
637 },
fmatosqg197d4312018-05-21 10:52:33 +1000638 );
639
Alexandre Ardhuin440ce8f2019-03-07 21:09:28 +0100640 testUsingContextAndFs(
641 'Validate manifest on Windows FS',
642 MemoryFileSystem(style: FileSystemStyle.windows),
643 () {
644 assertSchemaIsReadable();
645 },
fmatosqg197d4312018-05-21 10:52:33 +1000646 );
647
648 });
649
Sarah Zakarias49ba9742017-09-26 14:48:52 +0200650}
fmatosqg197d4312018-05-21 10:52:33 +1000651