asset_bundle_package_test.dart 21.5 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8
// 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

14
import 'package:flutter_tools/src/cache.dart';
15
import 'package:flutter_tools/src/globals.dart' as globals;
16

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

void main() {
22 23 24 25 26 27
  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.
28
    return path?.replaceAll('/', globals.fs.path.separator);
29
  }
30
  void writePubspecFile(String path, String name, { List<String> assets }) {
31 32 33 34
    String assetsSection;
    if (assets == null) {
      assetsSection = '';
    } else {
35
      final StringBuffer buffer = StringBuffer();
36 37 38 39 40
      buffer.write('''
flutter:
     assets:
''');

41
      for (final String asset in assets) {
42 43 44 45 46 47 48
        buffer.write('''
       - $asset
''');
      }
      assetsSection = buffer.toString();
    }

49
    globals.fs.file(fixPath(path))
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
      ..createSync(recursive: true)
      ..writeAsStringSync('''
name: $name
dependencies:
  flutter:
    sdk: flutter
$assetsSection
''');
  }

  void establishFlutterRoot() {
    Cache.flutterRoot = getFlutterRoot();
  }

  void writePackagesFile(String packages) {
65
    globals.fs.file('.packages')
66 67 68 69
      ..createSync()
      ..writeAsStringSync(packages);
  }

70
  Future<void> buildAndVerifyAssets(
71 72
    List<String> assets,
    List<String> packages,
73 74 75
    String expectedAssetManifest, {
    bool expectExists = true,
  }) async {
76
    final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
77
    await bundle.build(manifestPath: 'pubspec.yaml', packagesPath: '.packages');
78

79 80
    for (final String packageName in packages) {
      for (final String asset in assets) {
81
        final String entryKey = Uri.encodeFull('packages/$packageName/$asset');
82 83 84 85 86 87 88 89
        expect(bundle.entries.containsKey(entryKey), expectExists,
          reason: 'Cannot find key on bundle: $entryKey');
        if (expectExists) {
          expect(
            utf8.decode(await bundle.entries[entryKey].contentsAsBytes()),
            asset,
          );
        }
90 91 92
      }
    }

93 94 95 96 97 98
    if (expectExists) {
      expect(
        utf8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()),
        expectedAssetManifest,
      );
    }
99 100 101
  }

  void writeAssets(String path, List<String> assets) {
102
    for (final String asset in assets) {
103
      final String fullPath = fixPath(globals.fs.path.join(path, asset));
104

105
      globals.fs.file(fullPath)
106 107 108 109 110
        ..createSync(recursive: true)
        ..writeAsStringSync(asset);
    }
  }

111
  FileSystem testFileSystem;
112 113

  setUp(() async {
114
    testFileSystem = MemoryFileSystem(
115
      style: globals.platform.isWindows
116 117 118 119
        ? FileSystemStyle.windows
        : FileSystemStyle.posix,
    );
    testFileSystem.currentDirectory = testFileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.');
120 121
  });

122 123
  group('AssetBundle assets from packages', () {
    testUsingContext('No assets are bundled when the package has no assets', () async {
124
      establishFlutterRoot();
125
      writeEmptySchemaFile(globals.fs);
126 127 128 129 130

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

131
      final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
132
      await bundle.build(manifestPath: 'pubspec.yaml', packagesPath: '.packages');
133
      expect(bundle.entries.length, 3); // LICENSE, AssetManifest, FontManifest
134
      const String expectedAssetManifest = '{}';
135
      expect(
136
        utf8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()),
137 138
        expectedAssetManifest,
      );
139
      expect(
140
        utf8.decode(await bundle.entries['FontManifest.json'].contentsAsBytes()),
141 142
        '[]',
      );
143 144
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
145
      ProcessManager: () => FakeProcessManager.any(),
146
    });
147

148 149
    testUsingContext('No assets are bundled when the package has an asset that is not listed', () async {
      establishFlutterRoot();
150
      writeEmptySchemaFile(globals.fs);
151 152 153 154 155 156 157 158

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

      final List<String> assets = <String>['a/foo'];
      writeAssets('p/p/', assets);

159
      final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
160
      await bundle.build(manifestPath: 'pubspec.yaml', packagesPath: '.packages');
161
      expect(bundle.entries.length, 3); // LICENSE, AssetManifest, FontManifest
162
      const String expectedAssetManifest = '{}';
163
      expect(
164
        utf8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()),
165 166
        expectedAssetManifest,
      );
167
      expect(
168
        utf8.decode(await bundle.entries['FontManifest.json'].contentsAsBytes()),
169 170
        '[]',
      );
171 172
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
173
      ProcessManager: () => FakeProcessManager.any(),
174
    });
175

176 177
    testUsingContext('One asset is bundled when the package has and lists one '
      'asset its pubspec', () async {
178
      establishFlutterRoot();
179
      writeEmptySchemaFile(globals.fs);
180 181 182 183 184 185 186 187 188 189 190 191 192

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

      final List<String> assets = <String>['a/foo'];
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assets,
      );

      writeAssets('p/p/', assets);

193
      const String expectedAssetManifest = '{"packages/test_package/a/foo":'
194 195 196 197 198 199
          '["packages/test_package/a/foo"]}';
      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedAssetManifest,
      );
200 201
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
202
      ProcessManager: () => FakeProcessManager.any(),
203
    });
204

205 206
    testUsingContext('One asset is bundled when the package has one asset, '
      "listed in the app's pubspec", () async {
207
      establishFlutterRoot();
208
      writeEmptySchemaFile(globals.fs);
209 210 211 212 213 214 215 216 217 218 219 220 221

      final List<String> assetEntries = <String>['packages/test_package/a/foo'];
      writePubspecFile(
        'pubspec.yaml',
        'test',
        assets: assetEntries,
      );
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile('p/p/pubspec.yaml', 'test_package');

      final List<String> assets = <String>['a/foo'];
      writeAssets('p/p/lib/', assets);

222
      const String expectedAssetManifest = '{"packages/test_package/a/foo":'
223 224 225 226 227 228
          '["packages/test_package/a/foo"]}';
      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedAssetManifest,
      );
229 230
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
231
      ProcessManager: () => FakeProcessManager.any(),
232
    });
233

234 235
    testUsingContext('One asset and its variant are bundled when the package '
      'has an asset and a variant, and lists the asset in its pubspec', () async {
236
      establishFlutterRoot();
237
      writeEmptySchemaFile(globals.fs);
238 239 240 241 242 243 244 245 246 247 248 249

      writePubspecFile('pubspec.yaml', 'test');
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: <String>['a/foo'],
      );

      final List<String> assets = <String>['a/foo', 'a/v/foo'];
      writeAssets('p/p/', assets);

250
      const String expectedManifest = '{"packages/test_package/a/foo":'
251 252 253 254 255 256 257
          '["packages/test_package/a/foo","packages/test_package/a/v/foo"]}';

      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedManifest,
      );
258 259
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
260
      ProcessManager: () => FakeProcessManager.any(),
261
    });
262

263 264
    testUsingContext('One asset and its variant are bundled when the package '
      'has an asset and a variant, and the app lists the asset in its pubspec', () async {
265
      establishFlutterRoot();
266
      writeEmptySchemaFile(globals.fs);
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281

      writePubspecFile(
        'pubspec.yaml',
        'test',
        assets: <String>['packages/test_package/a/foo'],
      );
      writePackagesFile('test_package:p/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
      );

      final List<String> assets = <String>['a/foo', 'a/v/foo'];
      writeAssets('p/p/lib/', assets);

282
      const String expectedManifest = '{"packages/test_package/a/foo":'
283 284 285 286 287 288 289
          '["packages/test_package/a/foo","packages/test_package/a/v/foo"]}';

      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedManifest,
      );
290 291
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
292
      ProcessManager: () => FakeProcessManager.any(),
293
    });
294

295 296
    testUsingContext('Two assets are bundled when the package has and lists '
      'two assets in its pubspec', () async {
297
      establishFlutterRoot();
298
      writeEmptySchemaFile(globals.fs);
299 300 301 302 303 304 305 306 307 308 309 310

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

      final List<String> assets = <String>['a/foo', 'a/bar'];
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assets,
      );

      writeAssets('p/p/', assets);
311
      const String expectedAssetManifest =
312 313
          '{"packages/test_package/a/bar":["packages/test_package/a/bar"],'
          '"packages/test_package/a/foo":["packages/test_package/a/foo"]}';
314 315 316 317 318 319

      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedAssetManifest,
      );
320 321
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
322
      ProcessManager: () => FakeProcessManager.any(),
323
    });
324

325
    testUsingContext("Two assets are bundled when the package has two assets, listed in the app's pubspec", () async {
326
      establishFlutterRoot();
327
      writeEmptySchemaFile(globals.fs);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346

      final List<String> assetEntries = <String>[
        'packages/test_package/a/foo',
        'packages/test_package/a/bar',
      ];
      writePubspecFile(
        'pubspec.yaml',
        'test',
         assets: assetEntries,
      );
      writePackagesFile('test_package:p/p/lib/');

      final List<String> assets = <String>['a/foo', 'a/bar'];
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
      );

      writeAssets('p/p/lib/', assets);
347
      const String expectedAssetManifest =
348 349
          '{"packages/test_package/a/bar":["packages/test_package/a/bar"],'
          '"packages/test_package/a/foo":["packages/test_package/a/foo"]}';
350 351 352 353 354 355

      await buildAndVerifyAssets(
        assets,
        <String>['test_package'],
        expectedAssetManifest,
      );
356 357
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
358
      ProcessManager: () => FakeProcessManager.any(),
359
    });
360

361
    testUsingContext('Two assets are bundled when two packages each have and list an asset their pubspec', () async {
362
      establishFlutterRoot();
363
      writeEmptySchemaFile(globals.fs);
364

365 366 367 368
      writePubspecFile(
        'pubspec.yaml',
        'test',
      );
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
      writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: <String>['a/foo'],
      );
      writePubspecFile(
        'p2/p/pubspec.yaml',
        'test_package2',
        assets: <String>['a/foo'],
      );

      final List<String> assets = <String>['a/foo', 'a/v/foo'];
      writeAssets('p/p/', assets);
      writeAssets('p2/p/', assets);

385
      const String expectedAssetManifest =
386 387 388 389 390 391 392 393 394 395
          '{"packages/test_package/a/foo":'
          '["packages/test_package/a/foo","packages/test_package/a/v/foo"],'
          '"packages/test_package2/a/foo":'
          '["packages/test_package2/a/foo","packages/test_package2/a/v/foo"]}';

      await buildAndVerifyAssets(
        assets,
        <String>['test_package', 'test_package2'],
        expectedAssetManifest,
      );
396 397
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
398
      ProcessManager: () => FakeProcessManager.any(),
399
    });
400

401
    testUsingContext("Two assets are bundled when two packages each have an asset, listed in the app's pubspec", () async {
402
      establishFlutterRoot();
403
      writeEmptySchemaFile(globals.fs);
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427

      final List<String> assetEntries = <String>[
        'packages/test_package/a/foo',
        'packages/test_package2/a/foo',
      ];
      writePubspecFile(
        'pubspec.yaml',
        'test',
        assets: assetEntries,
      );
      writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
      );
      writePubspecFile(
        'p2/p/pubspec.yaml',
        'test_package2',
      );

      final List<String> assets = <String>['a/foo', 'a/v/foo'];
      writeAssets('p/p/lib/', assets);
      writeAssets('p2/p/lib/', assets);

428
      const String expectedAssetManifest =
429 430 431 432 433 434 435 436 437 438
          '{"packages/test_package/a/foo":'
          '["packages/test_package/a/foo","packages/test_package/a/v/foo"],'
          '"packages/test_package2/a/foo":'
          '["packages/test_package2/a/foo","packages/test_package2/a/v/foo"]}';

      await buildAndVerifyAssets(
        assets,
        <String>['test_package', 'test_package2'],
        expectedAssetManifest,
      );
439 440
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
441
      ProcessManager: () => FakeProcessManager.any(),
442
    });
443

444 445
    testUsingContext('One asset is bundled when the app depends on a package, '
      'listing in its pubspec an asset from another package', () async {
446
      establishFlutterRoot();
447
      writeEmptySchemaFile(globals.fs);
448 449 450 451 452 453 454 455
      writePubspecFile(
        'pubspec.yaml',
        'test',
      );
      writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
456
        assets: <String>['packages/test_package2/a/foo'],
457 458 459 460 461 462 463 464 465
      );
      writePubspecFile(
        'p2/p/pubspec.yaml',
        'test_package2',
      );

      final List<String> assets = <String>['a/foo', 'a/v/foo'];
      writeAssets('p2/p/lib/', assets);

466
      const String expectedAssetManifest =
467 468 469 470 471 472 473 474
          '{"packages/test_package2/a/foo":'
          '["packages/test_package2/a/foo","packages/test_package2/a/v/foo"]}';

      await buildAndVerifyAssets(
        assets,
        <String>['test_package2'],
        expectedAssetManifest,
      );
475 476
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
477
      ProcessManager: () => FakeProcessManager.any(),
478
    });
479
  });
480 481 482

  testUsingContext('Asset paths can contain URL reserved characters', () async {
    establishFlutterRoot();
483
    writeEmptySchemaFile(globals.fs);
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504

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

    final List<String> assets = <String>['a/foo', 'a/foo[x]'];
    writePubspecFile(
      'p/p/pubspec.yaml',
      'test_package',
      assets: assets,
    );

    writeAssets('p/p/', assets);
    const String expectedAssetManifest =
        '{"packages/test_package/a/foo":["packages/test_package/a/foo"],'
        '"packages/test_package/a/foo%5Bx%5D":["packages/test_package/a/foo%5Bx%5D"]}';

    await buildAndVerifyAssets(
      assets,
      <String>['test_package'],
      expectedAssetManifest,
    );
505 506
  }, overrides: <Type, Generator>{
    FileSystem: () => testFileSystem,
507
      ProcessManager: () => FakeProcessManager.any(),
508
  });
509 510

  group('AssetBundle assets from scanned paths', () {
511
    testUsingContext('Two assets are bundled when scanning their directory', () async {
512
      establishFlutterRoot();
513
      writeEmptySchemaFile(globals.fs);
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536

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

      final List<String> assetsOnDisk = <String>['a/foo', 'a/bar'];
      final List<String> assetsOnManifest = <String>['a/'];

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetsOnManifest,
      );

      writeAssets('p/p/', assetsOnDisk);
      const String expectedAssetManifest =
          '{"packages/test_package/a/bar":["packages/test_package/a/bar"],'
          '"packages/test_package/a/foo":["packages/test_package/a/foo"]}';

      await buildAndVerifyAssets(
        assetsOnDisk,
        <String>['test_package'],
        expectedAssetManifest,
      );
537 538
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
539
      ProcessManager: () => FakeProcessManager.any(),
540 541
    });

542
    testUsingContext('Two assets are bundled when listing one and scanning second directory', () async {
543
      establishFlutterRoot();
544
      writeEmptySchemaFile(globals.fs);
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567

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

      final List<String> assetsOnDisk = <String>['a/foo', 'abc/bar'];
      final List<String> assetOnManifest = <String>['a/foo', 'abc/'];

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetOnManifest,
      );

      writeAssets('p/p/', assetsOnDisk);
      const String expectedAssetManifest =
          '{"packages/test_package/abc/bar":["packages/test_package/abc/bar"],'
          '"packages/test_package/a/foo":["packages/test_package/a/foo"]}';

      await buildAndVerifyAssets(
        assetsOnDisk,
        <String>['test_package'],
        expectedAssetManifest,
      );
568 569
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
570
      ProcessManager: () => FakeProcessManager.any(),
571 572
    });

573
    testUsingContext('One asset is bundled with variant, scanning wrong directory', () async {
574
      establishFlutterRoot();
575
      writeEmptySchemaFile(globals.fs);
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591

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

      final List<String> assetsOnDisk = <String>['a/foo','a/b/foo','a/bar'];
      final List<String> assetOnManifest = <String>['a','a/bar']; // can't list 'a' as asset, should be 'a/'

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetOnManifest,
      );

      writeAssets('p/p/', assetsOnDisk);

      final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
592
      await bundle.build(manifestPath: 'pubspec.yaml', packagesPath: '.packages');
593 594 595

      expect(bundle.entries['AssetManifest.json'], isNull,
        reason: 'Invalid pubspec.yaml should not generate AssetManifest.json'  );
596 597
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
598
      ProcessManager: () => FakeProcessManager.any(),
599 600 601 602
    });
  });

  group('AssetBundle assets from scanned paths with MemoryFileSystem', () {
603
    testUsingContext('One asset is bundled with variant, scanning directory', () async {
604
      establishFlutterRoot();
605
      writeEmptySchemaFile(globals.fs);
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627

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

      final List<String> assetsOnDisk = <String>['a/foo','a/b/foo'];
      final List<String> assetOnManifest = <String>['a/',];

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetOnManifest,
      );

      writeAssets('p/p/', assetsOnDisk);
      const String expectedAssetManifest =
          '{"packages/test_package/a/foo":["packages/test_package/a/foo","packages/test_package/a/b/foo"]}';

      await buildAndVerifyAssets(
        assetsOnDisk,
        <String>['test_package'],
        expectedAssetManifest,
      );
628 629
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
630
      ProcessManager: () => FakeProcessManager.any(),
631 632
    });

633
    testUsingContext('No asset is bundled with variant, no assets or directories are listed', () async {
634
      establishFlutterRoot();
635
      writeEmptySchemaFile(globals.fs);
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656

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

      final List<String> assetsOnDisk = <String>['a/foo', 'a/b/foo'];
      final List<String> assetOnManifest = <String>[];

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetOnManifest,
      );

      writeAssets('p/p/', assetsOnDisk);
      const String expectedAssetManifest = '{}';

      await buildAndVerifyAssets(
        assetOnManifest,
        <String>['test_package'],
        expectedAssetManifest,
      );
657 658
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
659
      ProcessManager: () => FakeProcessManager.any(),
660 661
    });

662
    testUsingContext('Expect error generating manifest, wrong non-existing directory is listed', () async {
663
      establishFlutterRoot();
664
      writeEmptySchemaFile(globals.fs);
665 666 667 668 669 670 671 672 673 674 675 676

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

      final List<String> assetOnManifest = <String>['c/'];

      writePubspecFile(
        'p/p/pubspec.yaml',
        'test_package',
        assets: assetOnManifest,
      );

677 678 679 680 681 682
      await buildAndVerifyAssets(
        assetOnManifest,
        <String>['test_package'],
        null,
        expectExists: false,
      );
683 684
    }, overrides: <Type, Generator>{
      FileSystem: () => testFileSystem,
685
      ProcessManager: () => FakeProcessManager.any(),
686 687
    });
  });
688
}