| // 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/memory.dart'; |
| import 'package:flutter_tools/src/asset.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:flutter_tools/src/base/platform.dart'; |
| import 'package:flutter_tools/src/base/user_messages.dart'; |
| import 'package:flutter_tools/src/cache.dart'; |
| import 'package:flutter_tools/src/project.dart'; |
| |
| import '../src/common.dart'; |
| |
| void main() { |
| Future<ManifestAssetBundle> buildBundleWithFlavor(String? flavor, { |
| required Logger logger, |
| required FileSystem fileSystem, |
| required Platform platform, |
| }) async { |
| final ManifestAssetBundle bundle = ManifestAssetBundle( |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| flutterRoot: Cache.defaultFlutterRoot( |
| platform: platform, |
| fileSystem: fileSystem, |
| userMessages: UserMessages(), |
| ), |
| splitDeferredAssets: true, |
| ); |
| |
| await bundle.build( |
| packagesPath: '.packages', |
| flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), |
| flavor: flavor, |
| ); |
| return bundle; |
| } |
| |
| testWithoutContext('correctly bundles assets given a simple asset manifest with flavors', () async { |
| final MemoryFileSystem fileSystem = MemoryFileSystem(); |
| fileSystem.currentDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.'); |
| final BufferLogger logger = BufferLogger.test(); |
| final FakePlatform platform = FakePlatform(); |
| |
| fileSystem.file('.packages').createSync(); |
| fileSystem.file(fileSystem.path.join('assets', 'common', 'image.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('assets', 'vanilla', 'ice-cream.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('assets', 'strawberry', 'ice-cream.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('assets', 'orange', 'ice-cream.png')).createSync(recursive: true); |
| fileSystem.file('pubspec.yaml') |
| ..createSync() |
| ..writeAsStringSync(r''' |
| name: example |
| flutter: |
| assets: |
| - assets/common/ |
| - path: assets/vanilla/ |
| flavors: |
| - vanilla |
| - path: assets/strawberry/ |
| flavors: |
| - strawberry |
| - path: assets/orange/ice-cream.png |
| flavors: |
| - orange |
| '''); |
| |
| ManifestAssetBundle bundle; |
| bundle = await buildBundleWithFlavor( |
| null, |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ); |
| expect(bundle.entries.keys, contains('assets/common/image.png')); |
| expect(bundle.entries.keys, isNot(contains('assets/vanilla/ice-cream.png'))); |
| expect(bundle.entries.keys, isNot(contains('assets/strawberry/ice-cream.png'))); |
| expect(bundle.entries.keys, isNot(contains('assets/orange/ice-cream.png'))); |
| |
| bundle = await buildBundleWithFlavor( |
| 'strawberry', |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ); |
| expect(bundle.entries.keys, contains('assets/common/image.png')); |
| expect(bundle.entries.keys, isNot(contains('assets/vanilla/ice-cream.png'))); |
| expect(bundle.entries.keys, contains('assets/strawberry/ice-cream.png')); |
| expect(bundle.entries.keys, isNot(contains('assets/orange/ice-cream.png'))); |
| |
| bundle = await buildBundleWithFlavor( |
| 'orange', |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ); |
| expect(bundle.entries.keys, contains('assets/common/image.png')); |
| expect(bundle.entries.keys, isNot(contains('assets/vanilla/ice-cream.png'))); |
| expect(bundle.entries.keys, isNot(contains('assets/strawberry/ice-cream.png'))); |
| expect(bundle.entries.keys, contains('assets/orange/ice-cream.png')); |
| }); |
| |
| testWithoutContext('throws a tool exit when a non-flavored folder contains a flavored asset', () async { |
| final MemoryFileSystem fileSystem = MemoryFileSystem(); |
| fileSystem.currentDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.'); |
| final BufferLogger logger = BufferLogger.test(); |
| final FakePlatform platform = FakePlatform(); |
| fileSystem.file('.packages').createSync(); |
| fileSystem.file(fileSystem.path.join('assets', 'unflavored.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('assets', 'vanillaOrange.png')).createSync(recursive: true); |
| |
| fileSystem.file('pubspec.yaml') |
| ..createSync() |
| ..writeAsStringSync(r''' |
| name: example |
| flutter: |
| assets: |
| - assets/ |
| - path: assets/vanillaOrange.png |
| flavors: |
| - vanilla |
| - orange |
| '''); |
| |
| expect( |
| buildBundleWithFlavor( |
| null, |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ), |
| throwsToolExit(message: 'Multiple assets entries include the file ' |
| '"assets/vanillaOrange.png", but they specify different lists of flavors.\n' |
| 'An entry with the path "assets/" does not specify any flavors.\n' |
| 'An entry with the path "assets/vanillaOrange.png" specifies the flavor(s): "vanilla", "orange".\n\n' |
| 'Consider organizing assets with different flavors into different directories.'), |
| ); |
| }); |
| |
| testWithoutContext('throws a tool exit when a flavored folder contains a flavorless asset', () async { |
| final MemoryFileSystem fileSystem = MemoryFileSystem(); |
| fileSystem.currentDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.'); |
| final BufferLogger logger = BufferLogger.test(); |
| final FakePlatform platform = FakePlatform(); |
| fileSystem.file('.packages').createSync(); |
| fileSystem.file(fileSystem.path.join('vanilla', 'vanilla.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('vanilla', 'flavorless.png')).createSync(recursive: true); |
| |
| fileSystem.file('pubspec.yaml') |
| ..createSync() |
| ..writeAsStringSync(r''' |
| name: example |
| flutter: |
| assets: |
| - path: vanilla/ |
| flavors: |
| - vanilla |
| - vanilla/flavorless.png |
| '''); |
| expect( |
| buildBundleWithFlavor( |
| null, |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ), |
| throwsToolExit(message: 'Multiple assets entries include the file ' |
| '"vanilla/flavorless.png", but they specify different lists of flavors.\n' |
| 'An entry with the path "vanilla/" specifies the flavor(s): "vanilla".\n' |
| 'An entry with the path "vanilla/flavorless.png" does not specify any flavors.\n\n' |
| 'Consider organizing assets with different flavors into different directories.'), |
| ); |
| }); |
| |
| testWithoutContext('tool exits when two file-explicit entries give the same asset different flavors', () { |
| final MemoryFileSystem fileSystem = MemoryFileSystem(); |
| fileSystem.currentDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.'); |
| final BufferLogger logger = BufferLogger.test(); |
| final FakePlatform platform = FakePlatform(); |
| fileSystem.file('.packages').createSync(); |
| fileSystem.file('orange.png').createSync(recursive: true); |
| fileSystem.file('pubspec.yaml') |
| ..createSync() |
| ..writeAsStringSync(r''' |
| name: example |
| flutter: |
| assets: |
| - path: orange.png |
| flavors: |
| - orange |
| - path: orange.png |
| flavors: |
| - mango |
| '''); |
| |
| expect( |
| buildBundleWithFlavor( |
| null, |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ), |
| throwsToolExit(message: 'Multiple assets entries include the file ' |
| '"orange.png", but they specify different lists of flavors.\n' |
| 'An entry with the path "orange.png" specifies the flavor(s): "orange".\n' |
| 'An entry with the path "orange.png" specifies the flavor(s): "mango".'), |
| ); |
| }); |
| |
| testWithoutContext('throws ToolExit when flavor from file-level declaration has different flavor from containing folder flavor declaration', () async { |
| final MemoryFileSystem fileSystem = MemoryFileSystem(); |
| fileSystem.currentDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.'); |
| final BufferLogger logger = BufferLogger.test(); |
| final FakePlatform platform = FakePlatform(); |
| fileSystem.file('.packages').createSync(); |
| fileSystem.file(fileSystem.path.join('vanilla', 'actually-strawberry.png')).createSync(recursive: true); |
| fileSystem.file(fileSystem.path.join('vanilla', 'vanilla.png')).createSync(recursive: true); |
| |
| fileSystem.file('pubspec.yaml') |
| ..createSync() |
| ..writeAsStringSync(r''' |
| name: example |
| flutter: |
| assets: |
| - path: vanilla/ |
| flavors: |
| - vanilla |
| - path: vanilla/actually-strawberry.png |
| flavors: |
| - strawberry |
| '''); |
| expect( |
| buildBundleWithFlavor( |
| null, |
| logger: logger, |
| fileSystem: fileSystem, |
| platform: platform, |
| ), |
| throwsToolExit(message: 'Multiple assets entries include the file ' |
| '"vanilla/actually-strawberry.png", but they specify different lists of flavors.\n' |
| 'An entry with the path "vanilla/" specifies the flavor(s): "vanilla".\n' |
| 'An entry with the path "vanilla/actually-strawberry.png" ' |
| 'specifies the flavor(s): "strawberry".'), |
| ); |
| }); |
| } |