mirror of
https://github.com/flutter/flutter
synced 2024-08-25 02:46:31 +00:00
Catch file system exceptions when trying to parse user-provided asset file paths (#142214)
Fixes #141211
This commit is contained in:
parent
38879daef7
commit
83bdde2bd3
|
@ -958,8 +958,8 @@ class ManifestAssetBundle implements AssetBundle {
|
|||
} on UnsupportedError catch (e) {
|
||||
throwToolExit(
|
||||
'Unable to search for asset files in directory path "${assetUri.path}". '
|
||||
'Please ensure that this is valid URI that points to a directory '
|
||||
'that is available on the local file system.\nError details:\n$e');
|
||||
'Please ensure that this entry in pubspec.yaml is a valid file path.\n'
|
||||
'Error details:\n$e');
|
||||
}
|
||||
|
||||
if (!_fileSystem.directory(directoryPath).existsSync()) {
|
||||
|
@ -1296,17 +1296,25 @@ class _AssetDirectoryCache {
|
|||
final Map<String, List<File>> _variantsPerFolder = <String, List<File>>{};
|
||||
|
||||
List<String> variantsFor(String assetPath) {
|
||||
final String directory = _fileSystem.path.dirname(assetPath);
|
||||
final String directoryName = _fileSystem.path.dirname(assetPath);
|
||||
|
||||
if (!_fileSystem.directory(directory).existsSync()) {
|
||||
return const <String>[];
|
||||
try {
|
||||
if (!_fileSystem.directory(directoryName).existsSync()) {
|
||||
return const <String>[];
|
||||
}
|
||||
} on FileSystemException catch (e) {
|
||||
throwToolExit(
|
||||
'Unable to check the existence of asset file "$assetPath". '
|
||||
'Ensure that the asset file is declared as a valid local file system path.\n'
|
||||
'Details: $e',
|
||||
);
|
||||
}
|
||||
|
||||
if (_cache.containsKey(assetPath)) {
|
||||
return _cache[assetPath]!;
|
||||
}
|
||||
if (!_variantsPerFolder.containsKey(directory)) {
|
||||
_variantsPerFolder[directory] = _fileSystem.directory(directory)
|
||||
if (!_variantsPerFolder.containsKey(directoryName)) {
|
||||
_variantsPerFolder[directoryName] = _fileSystem.directory(directoryName)
|
||||
.listSync()
|
||||
.whereType<Directory>()
|
||||
.where((Directory dir) => _assetVariantDirectoryRegExp.hasMatch(dir.basename))
|
||||
|
@ -1315,7 +1323,7 @@ class _AssetDirectoryCache {
|
|||
.toList();
|
||||
}
|
||||
final File assetFile = _fileSystem.file(assetPath);
|
||||
final List<File> potentialVariants = _variantsPerFolder[directory]!;
|
||||
final List<File> potentialVariants = _variantsPerFolder[directoryName]!;
|
||||
final String basename = assetFile.basename;
|
||||
return _cache[assetPath] = <String>[
|
||||
// It's possible that the user specifies only explicit variants (e.g. .../1x/asset.png),
|
||||
|
|
|
@ -0,0 +1,249 @@
|
|||
// 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".'),
|
||||
);
|
||||
});
|
||||
}
|
|
@ -24,18 +24,16 @@ import 'package:standard_message_codec/standard_message_codec.dart';
|
|||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
|
||||
const String shaderLibDir = '/./shader_lib';
|
||||
|
||||
void main() {
|
||||
group('AssetBundle.build', () {
|
||||
late Logger logger;
|
||||
const String shaderLibDir = '/./shader_lib';
|
||||
|
||||
group('AssetBundle.build (using context)', () {
|
||||
late FileSystem testFileSystem;
|
||||
late Platform platform;
|
||||
|
||||
setUp(() async {
|
||||
testFileSystem = MemoryFileSystem();
|
||||
testFileSystem.currentDirectory = testFileSystem.systemTempDirectory.createTempSync('flutter_asset_bundle_test.');
|
||||
logger = BufferLogger.test();
|
||||
platform = FakePlatform();
|
||||
});
|
||||
|
||||
|
@ -153,30 +151,6 @@ flutter:
|
|||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('throws ToolExit when directory entry contains invalid characters', () async {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- https://mywebsite.com/images/
|
||||
''');
|
||||
final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
|
||||
expect(() => bundle.build(packagesPath: '.packages'), throwsToolExit(
|
||||
message: 'Unable to search for asset files in directory path "https%3A//mywebsite.com/images/". '
|
||||
'Please ensure that this is valid URI that points to a directory that is '
|
||||
'available on the local file system.\n'
|
||||
'Error details:\n'
|
||||
'Unsupported operation: Illegal character in path: https:',
|
||||
));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => testFileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
Platform: () => FakePlatform(operatingSystem: 'windows'),
|
||||
});
|
||||
|
||||
testUsingContext('handle removal of wildcard directories', () async {
|
||||
globals.fs.file(globals.fs.path.join('assets', 'foo', 'bar.txt')).createSync(recursive: true);
|
||||
final File pubspec = globals.fs.file('pubspec.yaml')
|
||||
|
@ -361,180 +335,98 @@ flutter:
|
|||
Platform: () => platform,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
});
|
||||
|
||||
group('flavors feature', () {
|
||||
Future<ManifestAssetBundle> buildBundleWithFlavor(String? flavor) async {
|
||||
final ManifestAssetBundle bundle = ManifestAssetBundle(
|
||||
logger: logger,
|
||||
fileSystem: testFileSystem,
|
||||
platform: platform,
|
||||
flutterRoot: Cache.defaultFlutterRoot(
|
||||
platform: platform,
|
||||
fileSystem: testFileSystem,
|
||||
userMessages: UserMessages(),
|
||||
),
|
||||
splitDeferredAssets: true,
|
||||
);
|
||||
group('AssetBundle.build', () {
|
||||
testWithoutContext('throws ToolExit when directory entry contains invalid characters (Windows only)', () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem(style: FileSystemStyle.windows);
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
final FakePlatform platform = FakePlatform(operatingSystem: 'windows');
|
||||
final String flutterRoot = Cache.defaultFlutterRoot(
|
||||
platform: platform,
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
);
|
||||
|
||||
await bundle.build(
|
||||
packagesPath: '.packages',
|
||||
flutterProject: FlutterProject.fromDirectoryTest(testFileSystem.currentDirectory),
|
||||
flavor: flavor,
|
||||
);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
testWithoutContext('correctly bundles assets given a simple asset manifest with flavors', () async {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'common', 'image.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'vanilla', 'ice-cream.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'strawberry', 'ice-cream.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'orange', 'ice-cream.png')).createSync(recursive: true);
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
fileSystem.file('.packages').createSync();
|
||||
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
|
||||
''');
|
||||
- https://mywebsite.com/images/
|
||||
''');
|
||||
final ManifestAssetBundle bundle = ManifestAssetBundle(
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
platform: platform,
|
||||
flutterRoot: flutterRoot,
|
||||
);
|
||||
|
||||
ManifestAssetBundle bundle;
|
||||
bundle = await buildBundleWithFlavor(null);
|
||||
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');
|
||||
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');
|
||||
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 {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'unflavored.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('assets', 'vanillaOrange.png')).createSync(recursive: true);
|
||||
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- assets/
|
||||
- path: assets/vanillaOrange.png
|
||||
flavors:
|
||||
- vanilla
|
||||
- orange
|
||||
''');
|
||||
|
||||
expect(
|
||||
buildBundleWithFlavor(null),
|
||||
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 {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file(testFileSystem.path.join('vanilla', 'vanilla.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('vanilla', 'flavorless.png')).createSync(recursive: true);
|
||||
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- path: vanilla/
|
||||
flavors:
|
||||
- vanilla
|
||||
- vanilla/flavorless.png
|
||||
''');
|
||||
expect(
|
||||
buildBundleWithFlavor(null),
|
||||
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', () {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file('orange.png').createSync(recursive: true);
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- path: orange.png
|
||||
flavors:
|
||||
- orange
|
||||
- path: orange.png
|
||||
flavors:
|
||||
- mango
|
||||
''');
|
||||
|
||||
expect(
|
||||
buildBundleWithFlavor(null),
|
||||
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".'),
|
||||
);
|
||||
expect(
|
||||
() => bundle.build(
|
||||
packagesPath: '.packages',
|
||||
flutterProject: FlutterProject.fromDirectoryTest(
|
||||
fileSystem.currentDirectory,
|
||||
),
|
||||
),
|
||||
throwsToolExit(
|
||||
message: 'Unable to search for asset files in directory path "https%3A//mywebsite.com/images/". '
|
||||
'Please ensure that this entry in pubspec.yaml is a valid file path.\n'
|
||||
'Error details:\n'
|
||||
'Unsupported operation: Illegal character in path: https:',
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('throws ToolExit when flavor from file-level declaration has different flavor from containing folder flavor declaration', () async {
|
||||
testFileSystem.file('.packages').createSync();
|
||||
testFileSystem.file(testFileSystem.path.join('vanilla', 'actually-strawberry.png')).createSync(recursive: true);
|
||||
testFileSystem.file(testFileSystem.path.join('vanilla', 'vanilla.png')).createSync(recursive: true);
|
||||
testWithoutContext('throws ToolExit when file entry contains invalid characters (Windows only)', () async {
|
||||
final FileSystem fileSystem = MemoryFileSystem(
|
||||
style: FileSystemStyle.windows,
|
||||
opHandle: (String context, FileSystemOp operation) {
|
||||
if (operation == FileSystemOp.exists && context == r'C:\http:\\website.com') {
|
||||
throw const FileSystemException(
|
||||
r"FileSystemException: Exists failed, path = 'C:\http:\\website.com' "
|
||||
'(OS Error: The filename, directory name, or volume label syntax is '
|
||||
'incorrect., errno = 123)',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
final FakePlatform platform = FakePlatform(operatingSystem: 'windows');
|
||||
final String flutterRoot = Cache.defaultFlutterRoot(
|
||||
platform: platform,
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
);
|
||||
fileSystem.file('.packages').createSync();
|
||||
fileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- http://website.com/hi.png
|
||||
''');
|
||||
final ManifestAssetBundle bundle = ManifestAssetBundle(
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
platform: platform,
|
||||
flutterRoot: flutterRoot,
|
||||
);
|
||||
|
||||
testFileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..writeAsStringSync(r'''
|
||||
name: example
|
||||
flutter:
|
||||
assets:
|
||||
- path: vanilla/
|
||||
flavors:
|
||||
- vanilla
|
||||
- path: vanilla/actually-strawberry.png
|
||||
flavors:
|
||||
- strawberry
|
||||
''');
|
||||
expect(
|
||||
buildBundleWithFlavor(null),
|
||||
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".'),
|
||||
);
|
||||
});
|
||||
expect(
|
||||
() => bundle.build(
|
||||
packagesPath: '.packages',
|
||||
flutterProject: FlutterProject.fromDirectoryTest(
|
||||
fileSystem.currentDirectory,
|
||||
),
|
||||
),
|
||||
throwsToolExit(
|
||||
message: 'Unable to check the existence of asset file ',
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue