asset_bundle_package_fonts_test.dart 9.76 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2017 The Chromium 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 'dart:async';
import 'dart:convert';

import 'package:file/file.dart';
9
import 'package:file/memory.dart';
10 11 12

import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
13
import 'package:flutter_tools/src/base/platform.dart';
14 15 16 17
import 'package:flutter_tools/src/cache.dart';

import 'src/common.dart';
import 'src/context.dart';
18
import 'src/pubspec_schema.dart';
19 20

void main() {
21 22 23 24 25 26 27 28
  String fixPath(String path) {
    // The in-memory file system is strict about slashes on Windows being the
    // correct way so until https://github.com/google/file.dart/issues/112 is
    // fixed we fix them here.
    // TODO(dantup): Remove this function once the above issue is fixed and
    // rolls into Flutter.
    return path?.replaceAll('/', fs.path.separator);
  }
29 30 31 32 33 34 35 36 37 38 39
  void writePubspecFile(String path, String name, {String fontsSection}) {
    if (fontsSection == null) {
      fontsSection = '';
    } else {
      fontsSection = '''
flutter:
     fonts:
$fontsSection
''';
    }

40
    fs.file(fixPath(path))
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
      ..createSync(recursive: true)
      ..writeAsStringSync('''
name: $name
dependencies:
  flutter:
    sdk: flutter
$fontsSection
''');
  }

  void establishFlutterRoot() {
    // Setting flutterRoot here so that it picks up the MemoryFileSystem's
    // path separator.
    Cache.flutterRoot = getFlutterRoot();
  }

  void writePackagesFile(String packages) {
58
    fs.file('.packages')
59 60 61 62 63 64 65 66 67 68
      ..createSync()
      ..writeAsStringSync(packages);
  }

  Future<Null> buildAndVerifyFonts(
    List<String> localFonts,
    List<String> packageFonts,
    List<String> packages,
    String expectedAssetManifest,
  ) async {
69
    final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
70 71 72 73 74 75 76
    await bundle.build(manifestPath: 'pubspec.yaml');

    for (String packageName in packages) {
      for (String packageFont in packageFonts) {
        final String entryKey = 'packages/$packageName/$packageFont';
        expect(bundle.entries.containsKey(entryKey), true);
        expect(
77
          utf8.decode(await bundle.entries[entryKey].contentsAsBytes()),
78 79 80 81 82 83 84
          packageFont,
        );
      }

      for (String localFont in localFonts) {
        expect(bundle.entries.containsKey(localFont), true);
        expect(
85
          utf8.decode(await bundle.entries[localFont].contentsAsBytes()),
86 87 88 89 90 91
          localFont,
        );
      }
    }

    expect(
92
      utf8.decode(await bundle.entries['FontManifest.json'].contentsAsBytes()),
93 94 95 96 97
      expectedAssetManifest,
    );
  }

  void writeFontAsset(String path, String font) {
98
    fs.file(fixPath('$path$font'))
99 100 101 102
      ..createSync(recursive: true)
      ..writeAsStringSync(font);
  }

103 104
  group('AssetBundle fonts from packages', () {
    FileSystem testFileSystem;
105

106
    setUp(() async {
107
      testFileSystem = MemoryFileSystem(
108 109 110 111 112 113
        style: platform.isWindows
          ? FileSystemStyle.windows
          : FileSystemStyle.posix,
      );
      testFileSystem.currentDirectory = testFileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.');
    });
114

115 116
    testUsingContext('App includes neither font manifest nor fonts when no defines fonts', () async {
      establishFlutterRoot();
117
      writeEmptySchemaFile(fs);
118 119 120 121 122

      writePubspecFile('pubspec.yaml', 'test');
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile('p/p/pubspec.yaml', 'test_package');

123
      final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
124
      await bundle.build(manifestPath: 'pubspec.yaml');
125 126
      expect(bundle.entries.length, 3); // LICENSE, AssetManifest, FontManifest
      expect(bundle.entries.containsKey('FontManifest.json'), isTrue);
127 128
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
129
    });
130 131 132

    testUsingContext('App font uses font file from package', () async {
      establishFlutterRoot();
133
      writeEmptySchemaFile(fs);
134

135
      const String fontsSection = '''
136 137 138 139 140 141 142 143
       - family: foo
         fonts:
           - asset: packages/test_package/bar
''';
      writePubspecFile('pubspec.yaml', 'test', fontsSection: fontsSection);
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile('p/p/pubspec.yaml', 'test_package');

144
      const String font = 'bar';
145 146
      writeFontAsset('p/p/lib/', font);

147
      const String expectedFontManifest =
148 149 150 151 152 153 154
          '[{"fonts":[{"asset":"packages/test_package/bar"}],"family":"foo"}]';
      await buildAndVerifyFonts(
        <String>[],
        <String>[font],
        <String>['test_package'],
        expectedFontManifest,
      );
155 156
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
157
    });
158 159 160

    testUsingContext('App font uses local font file and package font file', () async {
      establishFlutterRoot();
161
      writeEmptySchemaFile(fs);
162

163
      const String fontsSection = '''
164 165 166 167 168 169 170 171 172
       - family: foo
         fonts:
           - asset: packages/test_package/bar
           - asset: a/bar
''';
      writePubspecFile('pubspec.yaml', 'test', fontsSection: fontsSection);
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile('p/p/pubspec.yaml', 'test_package');

173
      const String packageFont = 'bar';
174
      writeFontAsset('p/p/lib/', packageFont);
175
      const String localFont = 'a/bar';
176 177
      writeFontAsset('', localFont);

178
      const String expectedFontManifest =
179 180 181 182 183 184 185 186
          '[{"fonts":[{"asset":"packages/test_package/bar"},{"asset":"a/bar"}],'
          '"family":"foo"}]';
      await buildAndVerifyFonts(
        <String>[localFont],
        <String>[packageFont],
        <String>['test_package'],
        expectedFontManifest,
      );
187 188
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
189
    });
190 191 192

    testUsingContext('App uses package font with own font file', () async {
      establishFlutterRoot();
193
      writeEmptySchemaFile(fs);
194 195 196

      writePubspecFile('pubspec.yaml', 'test');
      writePackagesFile('test_package:p/p/lib/');
197
      const String fontsSection = '''
198 199 200 201 202 203 204 205 206 207
       - family: foo
         fonts:
           - asset: a/bar
''';
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        fontsSection: fontsSection,
      );

208
      const String font = 'a/bar';
209 210
      writeFontAsset('p/p/', font);

211
      const String expectedFontManifest =
212 213
          '[{"family":"packages/test_package/foo",'
          '"fonts":[{"asset":"packages/test_package/a/bar"}]}]';
214 215 216 217 218 219
      await buildAndVerifyFonts(
        <String>[],
        <String>[font],
        <String>['test_package'],
        expectedFontManifest,
      );
220 221
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
222
    });
223 224 225

    testUsingContext('App uses package font with font file from another package', () async {
      establishFlutterRoot();
226
      writeEmptySchemaFile(fs);
227 228 229

      writePubspecFile('pubspec.yaml', 'test');
      writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
230
      const String fontsSection = '''
231 232 233 234 235 236 237 238 239 240 241
       - family: foo
         fonts:
           - asset: packages/test_package2/bar
''';
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        fontsSection: fontsSection,
      );
      writePubspecFile('p2/p/pubspec.yaml', 'test_package2');

242
      const String font = 'bar';
243 244
      writeFontAsset('p2/p/lib/', font);

245
      const String expectedFontManifest =
246 247
          '[{"family":"packages/test_package/foo",'
          '"fonts":[{"asset":"packages/test_package2/bar"}]}]';
248 249 250 251 252 253
      await buildAndVerifyFonts(
        <String>[],
        <String>[font],
        <String>['test_package2'],
        expectedFontManifest,
      );
254 255
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
256
    });
257 258 259

    testUsingContext('App uses package font with properties and own font file', () async {
      establishFlutterRoot();
260
      writeEmptySchemaFile(fs);
261 262 263 264

      writePubspecFile('pubspec.yaml', 'test');
      writePackagesFile('test_package:p/p/lib/');

265
      const String pubspec = '''
266 267 268 269 270 271 272 273 274 275 276
       - family: foo
         fonts:
           - style: italic
             weight: 400
             asset: a/bar
''';
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        fontsSection: pubspec,
      );
277
      const String font = 'a/bar';
278 279
      writeFontAsset('p/p/', font);

280
      const String expectedFontManifest =
281 282
          '[{"family":"packages/test_package/foo",'
          '"fonts":[{"weight":400,"style":"italic","asset":"packages/test_package/a/bar"}]}]';
283 284 285 286 287 288
      await buildAndVerifyFonts(
        <String>[],
        <String>[font],
        <String>['test_package'],
        expectedFontManifest,
      );
289 290
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
291
    });
292 293 294

    testUsingContext('App uses local font and package font with own font file.', () async {
      establishFlutterRoot();
295
      writeEmptySchemaFile(fs);
296

297
      const String fontsSection = '''
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
       - family: foo
         fonts:
           - asset: a/bar
''';
      writePubspecFile(
        'pubspec.yaml',
        'test',
        fontsSection: fontsSection,
      );
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        fontsSection: fontsSection,
      );

314
      const String font = 'a/bar';
315 316 317
      writeFontAsset('', font);
      writeFontAsset('p/p/', font);

318
      const String expectedFontManifest =
319 320 321
          '[{"fonts":[{"asset":"a/bar"}],"family":"foo"},'
          '{"family":"packages/test_package/foo",'
          '"fonts":[{"asset":"packages/test_package/a/bar"}]}]';
322 323 324 325 326 327
      await buildAndVerifyFonts(
        <String>[font],
        <String>[font],
        <String>['test_package'],
        expectedFontManifest,
      );
328 329
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
330
    });
331 332
  });
}