Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
02c10b78
Commit
02c10b78
authored
Sep 05, 2017
by
Sarah Zakarias
Committed by
GitHub
Sep 05, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bundle assets used in packages (#11751)
parent
baf3b45e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
576 additions
and
38 deletions
+576
-38
image_provider.dart
packages/flutter/lib/src/services/image_provider.dart
+82
-11
image_resolution.dart
packages/flutter/lib/src/services/image_resolution.dart
+85
-11
image.dart
packages/flutter/lib/src/widgets/image.dart
+65
-8
image_package_asset_test.dart
packages/flutter/test/widgets/image_package_asset_test.dart
+47
-0
asset.dart
packages/flutter_tools/lib/src/asset.dart
+72
-8
asset_bundle_package_test.dart
packages/flutter_tools/test/asset_bundle_package_test.dart
+225
-0
No files found.
packages/flutter/lib/src/services/image_provider.dart
View file @
02c10b78
...
...
@@ -589,27 +589,94 @@ class MemoryImage extends ImageProvider<MemoryImage> {
/// Fetches an image from an [AssetBundle], associating it with the given scale.
///
/// This implementation requires an explicit final [
n
ame] and [scale] on
/// This implementation requires an explicit final [
assetN
ame] and [scale] on
/// construction, and ignores the device pixel ratio and size in the
/// configuration passed into [resolve]. For a resolution-aware variant that
/// uses the configuration to pick an appropriate image based on the device
/// pixel ratio and size, see [AssetImage].
///
/// ## Fetching assets
///
/// When fetching an image provided by the app itself, use the [assetName]
/// argument to name the asset to choose. For instance, consider a directory
/// `icons` with an image `heart.png`. First, the [pubspec.yaml] of the project
/// should specify its assets in the `flutter` section:
///
/// ```yaml
/// flutter:
/// assets:
/// - icons/heart.png
/// ```
///
/// Then, to fetch the image and associate it with scale `1.5`, use
///
/// ```dart
/// new AssetImage('icons/heart.png', scale: 1.5)
/// ```
///
///## Assets in packages
///
/// To fetch an asset from a package, the [package] argument must be provided.
/// For instance, suppose the structure above is inside a package called
/// `my_icons`. Then to fetch the image, use:
///
/// ```dart
/// new AssetImage('icons/heart.png', scale: 1.5, package: 'my_icons')
/// ```
///
/// Assets used by the package itself should also be fetched using the [package]
/// argument as above.
///
/// If the desired asset is specified in the [pubspec.yaml] of the package, it
/// is bundled automatically with the app. In particular, assets used by the
/// package itself must be specified in its [pubspec.yaml].
///
/// A package can also choose to have assets in its 'lib/' folder that are not
/// specified in its [pubspec.yaml]. In this case for those images to be
/// bundled, the app has to specify which ones to include. For instance a
/// package named `fancy_backgrounds` could have:
///
/// ```
/// lib/backgrounds/background1.png
/// lib/backgrounds/background2.png
/// lib/backgrounds/background3.png
///```
///
/// To include, say the first image, the [pubspec.yaml] of the app should specify
/// it in the `assets` section:
///
/// ```yaml
/// assets:
/// - packages/fancy_backgrounds/backgrounds/background1.png
/// ```
///
/// Note that the `lib/` is implied, so it should not be included in the asset
/// path.
///
class
ExactAssetImage
extends
AssetBundleImageProvider
{
/// Creates an object that fetches the given image from an asset bundle.
///
/// The [
n
ame] and [scale] arguments must not be null. The [scale] arguments
/// The [
assetN
ame] and [scale] arguments must not be null. The [scale] arguments
/// defaults to 1.0. The [bundle] argument may be null, in which case the
/// bundle provided in the [ImageConfiguration] passed to the [resolve] call
/// will be used instead.
const
ExactAssetImage
(
this
.
name
,
{
///
/// The [package] argument must be non-null when fetching an asset that is
/// included in a package. See the documentation for the [ExactAssetImage] class
/// itself for details.
const
ExactAssetImage
(
this
.
assetName
,
{
this
.
scale
:
1.0
,
this
.
bundle
})
:
assert
(
name
!=
null
),
this
.
bundle
,
this
.
package
,
})
:
assert
(
assetName
!=
null
),
assert
(
scale
!=
null
);
/// The name of the asset.
final
String
assetName
;
/// The key to use to obtain the resource from the [bundle]. This is the
/// argument passed to [AssetBundle.load].
final
String
name
;
String
get
keyName
=>
package
==
null
?
assetName
:
'packages/
$package
/
$assetName
'
;
/// The scale to place in the [ImageInfo] object of the image.
final
double
scale
;
...
...
@@ -621,14 +688,18 @@ class ExactAssetImage extends AssetBundleImageProvider {
/// that is also null, the [rootBundle] is used.
///
/// The image is obtained by calling [AssetBundle.load] on the given [bundle]
/// using the key given by [
n
ame].
/// using the key given by [
keyN
ame].
final
AssetBundle
bundle
;
/// The name of the package from which the image is included. See the
/// documentation for the [ExactAssetImage] class itself for details.
final
String
package
;
@override
Future
<
AssetBundleImageKey
>
obtainKey
(
ImageConfiguration
configuration
)
{
return
new
SynchronousFuture
<
AssetBundleImageKey
>(
new
AssetBundleImageKey
(
bundle:
bundle
??
configuration
.
bundle
??
rootBundle
,
name:
n
ame
,
name:
keyN
ame
,
scale:
scale
));
}
...
...
@@ -638,14 +709,14 @@ class ExactAssetImage extends AssetBundleImageProvider {
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
ExactAssetImage
typedOther
=
other
;
return
name
==
typedOther
.
n
ame
return
keyName
==
typedOther
.
keyN
ame
&&
scale
==
typedOther
.
scale
&&
bundle
==
typedOther
.
bundle
;
}
@override
int
get
hashCode
=>
hashValues
(
n
ame
,
scale
,
bundle
);
int
get
hashCode
=>
hashValues
(
keyN
ame
,
scale
,
bundle
);
@override
String
toString
()
=>
'
$runtimeType
(name: "
$
n
ame
", scale:
$scale
, bundle:
$bundle
)'
;
String
toString
()
=>
'
$runtimeType
(name: "
$
keyN
ame
", scale:
$scale
, bundle:
$bundle
)'
;
}
packages/flutter/lib/src/services/image_resolution.dart
View file @
02c10b78
...
...
@@ -55,16 +55,84 @@ const String _kAssetManifestFileName = 'AssetManifest.json';
/// icons/1.5x/heart.png
/// icons/2.0x/heart.png
/// ```
///
/// ## Fetching assets
///
/// When fetching an image provided by the app itself, use the [assetName]
/// argument to name the asset to choose. For instance, consider the structure
/// above. First, the [pubspec.yaml] of the project should specify its assets in
/// the `flutter` section:
///
/// ```yaml
/// flutter:
/// assets:
/// - icons/heart.png
/// ```
///
/// Then, to fetch the image, use
/// ```dart
/// new AssetImage('icons/heart.png')
/// ```
///
/// ## Assets in packages
///
/// To fetch an asset from a package, the [package] argument must be provided.
/// For instance, suppose the structure above is inside a package called
/// `my_icons`. Then to fetch the image, use:
///
/// ```dart
/// new AssetImage('icons/heart.png', package: 'my_icons')
/// ```
///
/// Assets used by the package itself should also be fetched using the [package]
/// argument as above.
///
/// If the desired asset is specified in the [pubspec.yaml] of the package, it
/// is bundled automatically with the app. In particular, assets used by the
/// package itself must be specified in its [pubspec.yaml].
///
/// A package can also choose to have assets in its 'lib/' folder that are not
/// specified in its [pubspec.yaml]. In this case for those images to be
/// bundled, the app has to specify which ones to include. For instance a
/// package named `fancy_backgrounds` could have:
///
/// ```
/// lib/backgrounds/background1.png
/// lib/backgrounds/background2.png
/// lib/backgrounds/background3.png
///```
///
/// To include, say the first image, the [pubspec.yaml] of the app should specify
/// it in the `assets` section:
///
/// ```yaml
/// assets:
/// - packages/fancy_backgrounds/backgrounds/background1.png
/// ```
///
/// Note that the `lib/` is implied, so it should not be included in the asset
/// path.
///
class
AssetImage
extends
AssetBundleImageProvider
{
/// Creates an object that fetches an image from an asset bundle.
///
/// The [name] argument must not be null. It should name the main asset from
/// the set of images to chose from.
const
AssetImage
(
this
.
name
,
{
this
.
bundle
})
:
assert
(
name
!=
null
);
/// The [assetName] argument must not be null. It should name the main asset
/// from the set of images to choose from. The [package] argument must be
/// non-null when fetching an asset that is included in package. See the
/// documentation for the [AssetImage] class itself for details.
const
AssetImage
(
this
.
assetName
,
{
this
.
bundle
,
this
.
package
,
})
:
assert
(
assetName
!=
null
);
/// The name of the main asset from the set of images to chose from. See the
/// The name of the main asset from the set of images to cho
o
se from. See the
/// documentation for the [AssetImage] class itself for details.
final
String
name
;
final
String
assetName
;
/// The name used to generate the key to obtain the asset. For local assets
/// this is [assetName], and for assets from packages the [assetName] is
/// prefixed 'packages/<package_name>/'.
String
get
keyName
=>
package
==
null
?
assetName
:
'packages/
$package
/
$assetName
'
;
/// The bundle from which the image will be obtained.
///
...
...
@@ -73,9 +141,15 @@ class AssetImage extends AssetBundleImageProvider {
/// that is also null, the [rootBundle] is used.
///
/// The image is obtained by calling [AssetBundle.load] on the given [bundle]
/// using the key given by [
n
ame].
/// using the key given by [
keyN
ame].
final
AssetBundle
bundle
;
/// The name of the package from which the image is included. See the
/// documentation for the [AssetImage] class itself for details.
final
String
package
;
// We assume the main asset is designed for a device pixel ratio of 1.0
static
const
double
_naturalResolution
=
1.0
;
...
...
@@ -93,9 +167,9 @@ class AssetImage extends AssetBundleImageProvider {
chosenBundle
.
loadStructuredData
<
Map
<
String
,
List
<
String
>>>(
_kAssetManifestFileName
,
_manifestParser
).
then
<
Null
>(
(
Map
<
String
,
List
<
String
>>
manifest
)
{
final
String
chosenName
=
_chooseVariant
(
n
ame
,
keyN
ame
,
configuration
,
manifest
==
null
?
null
:
manifest
[
n
ame
]
manifest
==
null
?
null
:
manifest
[
keyN
ame
]
);
final
double
chosenScale
=
_parseScale
(
chosenName
);
final
AssetBundleImageKey
key
=
new
AssetBundleImageKey
(
...
...
@@ -185,13 +259,13 @@ class AssetImage extends AssetBundleImageProvider {
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
AssetImage
typedOther
=
other
;
return
name
==
typedOther
.
n
ame
return
keyName
==
typedOther
.
keyN
ame
&&
bundle
==
typedOther
.
bundle
;
}
@override
int
get
hashCode
=>
hashValues
(
n
ame
,
bundle
);
int
get
hashCode
=>
hashValues
(
keyN
ame
,
bundle
);
@override
String
toString
()
=>
'
$runtimeType
(bundle:
$bundle
, name: "
$
n
ame
")'
;
String
toString
()
=>
'
$runtimeType
(bundle:
$bundle
, name: "
$
keyN
ame
")'
;
}
packages/flutter/lib/src/widgets/image.dart
View file @
02c10b78
...
...
@@ -113,7 +113,8 @@ class Image extends StatefulWidget {
this
.
alignment
,
this
.
repeat
:
ImageRepeat
.
noRepeat
,
this
.
centerSlice
,
this
.
gaplessPlayback
:
false
this
.
gaplessPlayback
:
false
,
this
.
package
,
})
:
assert
(
image
!=
null
),
super
(
key:
key
);
...
...
@@ -131,7 +132,8 @@ class Image extends StatefulWidget {
this
.
alignment
,
this
.
repeat
:
ImageRepeat
.
noRepeat
,
this
.
centerSlice
,
this
.
gaplessPlayback
:
false
this
.
gaplessPlayback
:
false
,
this
.
package
,
})
:
image
=
new
NetworkImage
(
src
,
scale:
scale
),
super
(
key:
key
);
...
...
@@ -152,13 +154,18 @@ class Image extends StatefulWidget {
this
.
alignment
,
this
.
repeat
:
ImageRepeat
.
noRepeat
,
this
.
centerSlice
,
this
.
gaplessPlayback
:
false
this
.
gaplessPlayback
:
false
,
this
.
package
,
})
:
image
=
new
FileImage
(
file
,
scale:
scale
),
super
(
key:
key
);
/// Creates a widget that displays an [ImageStream] obtained from an asset
/// bundle. The key for the image is given by the `name` argument.
///
/// The `package` argument must be non-null when displaying an image from a
/// package and null otherwise. See the `Assets in packages` section for
/// details.
///
/// If the `bundle` argument is omitted or null, then the
/// [DefaultAssetBundle] will be used.
///
...
...
@@ -210,6 +217,49 @@ class Image extends StatefulWidget {
/// be present in the manifest). If it is omitted, then on a device with a 1.0
/// device pixel ratio, the `images/2x/cat.png` image would be used instead.
///
///
/// ## Assets in packages
///
/// To create the widget with an asset from a package, the [package] argument
/// must be provided. For instance, suppose a package called `my_icons` has
/// `icons/heart.png` .
///
/// Then to display the image, use:
///
/// ```dart
/// new Image.asset('icons/heart.png', package: 'my_icons')
/// ```
///
/// Assets used by the package itself should also be displayed using the
/// [package] argument as above.
///
/// If the desired asset is specified in the [pubspec.yaml] of the package, it
/// is bundled automatically with the app. In particular, assets used by the
/// package itself must be specified in its [pubspec.yaml].
///
/// A package can also choose to have assets in its 'lib/' folder that are not
/// specified in its [pubspec.yaml]. In this case for those images to be
/// bundled, the app has to specify which ones to include. For instance a
/// package named `fancy_backgrounds` could have:
///
/// ```
/// lib/backgrounds/background1.png
/// lib/backgrounds/background2.png
/// lib/backgrounds/background3.png
///```
///
/// To include, say the first image, the [pubspec.yaml] of the app should
/// specify it in the assets section:
///
/// ```yaml
/// assets:
/// - packages/fancy_backgrounds/backgrounds/background1.png
/// ```
///
/// Note that the `lib/` is implied, so it should not be included in the asset
/// path.
///
///
/// See also:
///
/// * [AssetImage], which is used to implement the behavior when the scale is
...
...
@@ -230,10 +280,12 @@ class Image extends StatefulWidget {
this
.
alignment
,
this
.
repeat
:
ImageRepeat
.
noRepeat
,
this
.
centerSlice
,
this
.
gaplessPlayback
:
false
})
:
image
=
scale
!=
null
?
new
ExactAssetImage
(
name
,
bundle:
bundle
,
scale:
scale
)
:
new
AssetImage
(
name
,
bundle:
bundle
),
super
(
key:
key
);
this
.
gaplessPlayback
:
false
,
this
.
package
,
})
:
image
=
scale
!=
null
?
new
ExactAssetImage
(
name
,
bundle:
bundle
,
scale:
scale
,
package:
package
)
:
new
AssetImage
(
name
,
bundle:
bundle
,
package:
package
),
super
(
key:
key
);
/// Creates a widget that displays an [ImageStream] obtained from a [Uint8List].
///
...
...
@@ -249,7 +301,8 @@ class Image extends StatefulWidget {
this
.
alignment
,
this
.
repeat
:
ImageRepeat
.
noRepeat
,
this
.
centerSlice
,
this
.
gaplessPlayback
:
false
this
.
gaplessPlayback
:
false
,
this
.
package
,
})
:
image
=
new
MemoryImage
(
bytes
,
scale:
scale
),
super
(
key:
key
);
...
...
@@ -310,6 +363,10 @@ class Image extends StatefulWidget {
/// (false), when the image provider changes.
final
bool
gaplessPlayback
;
/// The name of the package from which the image is included. See the
/// documentation for the [Image.asset] constructor for details.
final
String
package
;
@override
_ImageState
createState
()
=>
new
_ImageState
();
...
...
packages/flutter/test/widgets/image_package_asset_test.dart
0 → 100644
View file @
02c10b78
// 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
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
test
(
'AssetImage from package'
,
()
{
final
AssetImage
image
=
const
AssetImage
(
'assets/image.png'
,
package:
'test_package'
,
);
expect
(
image
.
keyName
,
'packages/test_package/assets/image.png'
);
});
test
(
'ExactAssetImage from package'
,
()
{
final
ExactAssetImage
image
=
const
ExactAssetImage
(
'assets/image.png'
,
scale:
1.5
,
package:
'test_package'
,
);
expect
(
image
.
keyName
,
'packages/test_package/assets/image.png'
);
});
test
(
'Image.asset from package'
,
()
{
final
Image
imageWidget
=
new
Image
.
asset
(
'assets/image.png'
,
package:
'test_package'
,
);
assert
(
imageWidget
.
image
is
AssetImage
);
final
AssetImage
assetImage
=
imageWidget
.
image
;
expect
(
assetImage
.
keyName
,
'packages/test_package/assets/image.png'
);
});
test
(
'Image.asset from package'
,
()
{
final
Image
imageWidget
=
new
Image
.
asset
(
'assets/image.png'
,
scale:
1.5
,
package:
'test_package'
,
);
assert
(
imageWidget
.
image
is
ExactAssetImage
);
final
ExactAssetImage
asssetImage
=
imageWidget
.
image
;
expect
(
asssetImage
.
keyName
,
'packages/test_package/assets/image.png'
);
});
}
packages/flutter_tools/lib/src/asset.dart
View file @
02c10b78
...
...
@@ -86,11 +86,12 @@ class AssetBundle {
return
0
;
}
if
(
manifest
!=
null
)
{
final
int
result
=
await
_validateFlutterManifest
(
manifest
);
if
(
result
!=
0
)
return
result
;
final
int
result
=
await
_validateFlutterManifest
(
manifest
);
if
(
result
!=
0
)
return
result
;
}
Map
<
String
,
dynamic
>
manifestDescriptor
=
manifest
;
final
String
appName
=
manifestDescriptor
[
'name'
];
manifestDescriptor
=
manifestDescriptor
[
'flutter'
]
??
<
String
,
dynamic
>{};
final
String
assetBasePath
=
fs
.
path
.
dirname
(
fs
.
path
.
absolute
(
manifestPath
));
...
...
@@ -116,6 +117,33 @@ class AssetBundle {
manifestDescriptor
.
containsKey
(
'uses-material-design'
)
&&
manifestDescriptor
[
'uses-material-design'
];
// Add assets from packages.
for
(
String
packageName
in
packageMap
.
map
.
keys
)
{
final
Uri
package
=
packageMap
.
map
[
packageName
];
if
(
package
!=
null
&&
package
.
scheme
==
'file'
)
{
final
String
packageManifestPath
=
package
.
resolve
(
'../pubspec.yaml'
).
path
;
final
Object
packageManifest
=
_loadFlutterManifest
(
packageManifestPath
);
if
(
packageManifest
==
null
)
continue
;
final
int
result
=
await
_validateFlutterManifest
(
packageManifest
);
if
(
result
==
0
)
{
final
Map
<
String
,
dynamic
>
packageManifestDescriptor
=
packageManifest
;
// Skip the app itself.
if
(
packageManifestDescriptor
[
'name'
]
==
appName
)
continue
;
if
(
packageManifestDescriptor
.
containsKey
(
'flutter'
))
{
final
String
packageBasePath
=
fs
.
path
.
dirname
(
packageManifestPath
);
assetVariants
.
addAll
(
_parseAssets
(
packageMap
,
packageManifestDescriptor
[
'flutter'
],
packageBasePath
,
packageKey:
packageName
,
));
}
}
}
}
// Save the contents of each image, image variant, and font
// asset in entries.
for
(
_Asset
asset
in
assetVariants
.
keys
)
{
...
...
@@ -203,6 +231,27 @@ class _Asset {
@override
String
toString
()
=>
'asset:
$assetEntry
'
;
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
other
,
this
))
return
true
;
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
_Asset
otherAsset
=
other
;
return
otherAsset
.
base
==
base
&&
otherAsset
.
assetEntry
==
assetEntry
&&
otherAsset
.
relativePath
==
relativePath
&&
otherAsset
.
source
==
source
;
}
@override
int
get
hashCode
{
return
base
.
hashCode
^
assetEntry
.
hashCode
^
relativePath
.
hashCode
^
source
.
hashCode
;
}
}
Map
<
String
,
dynamic
>
_readMaterialFontsManifest
()
{
...
...
@@ -312,8 +361,8 @@ DevFSContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
for
(
_Asset
main
in
assetVariants
.
keys
)
{
final
List
<
String
>
variants
=
<
String
>[];
for
(
_Asset
variant
in
assetVariants
[
main
])
variants
.
add
(
variant
.
relativePath
);
json
[
main
.
relativePath
]
=
variants
;
variants
.
add
(
variant
.
assetEntry
);
json
[
main
.
assetEntry
]
=
variants
;
}
return
new
DevFSStringContent
(
JSON
.
encode
(
json
));
}
...
...
@@ -384,7 +433,8 @@ Map<_Asset, List<_Asset>> _parseAssets(
PackageMap
packageMap
,
Map
<
String
,
dynamic
>
manifestDescriptor
,
String
assetBase
,
{
List
<
String
>
excludeDirs:
const
<
String
>[]
List
<
String
>
excludeDirs:
const
<
String
>[],
String
packageKey
})
{
final
Map
<
_Asset
,
List
<
_Asset
>>
result
=
<
_Asset
,
List
<
_Asset
>>{};
...
...
@@ -394,7 +444,9 @@ Map<_Asset, List<_Asset>> _parseAssets(
if
(
manifestDescriptor
.
containsKey
(
'assets'
))
{
final
_AssetDirectoryCache
cache
=
new
_AssetDirectoryCache
(
excludeDirs
);
for
(
String
assetName
in
manifestDescriptor
[
'assets'
])
{
final
_Asset
asset
=
_resolveAsset
(
packageMap
,
assetBase
,
assetName
);
final
_Asset
asset
=
packageKey
!=
null
?
_resolvePackageAsset
(
assetBase
,
packageKey
,
assetName
)
:
_resolveAsset
(
packageMap
,
assetBase
,
assetName
);
final
List
<
_Asset
>
variants
=
<
_Asset
>[];
for
(
String
path
in
cache
.
variantsFor
(
asset
.
assetFile
.
path
))
{
...
...
@@ -435,10 +487,22 @@ Map<_Asset, List<_Asset>> _parseAssets(
return
result
;
}
_Asset
_resolvePackageAsset
(
String
assetBase
,
String
packageName
,
String
asset
,
)
{
return
new
_Asset
(
base:
assetBase
,
assetEntry:
'packages/
$packageName
/
$asset
'
,
relativePath:
asset
,
);
}
_Asset
_resolveAsset
(
PackageMap
packageMap
,
String
assetBase
,
String
asset
String
asset
,
)
{
if
(
asset
.
startsWith
(
'packages/'
)
&&
!
fs
.
isFileSync
(
fs
.
path
.
join
(
assetBase
,
asset
)))
{
// Convert packages/flutter_gallery_assets/clouds-0.png to clouds-0.png.
...
...
packages/flutter_tools/test/asset_bundle_package_test.dart
0 → 100644
View file @
02c10b78
// 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'
;
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/cache.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
void
main
(
)
{
void
writePubspecFile
(
String
path
,
String
name
,
{
List
<
String
>
assets
})
{
String
assetsSection
;
if
(
assets
==
null
)
{
assetsSection
=
''
;
}
else
{
final
StringBuffer
buffer
=
new
StringBuffer
();
buffer
.
write
(
'''
flutter:
assets:
'''
);
for
(
String
asset
in
assets
)
{
buffer
.
write
(
'''
-
$asset
'''
);
}
assetsSection
=
buffer
.
toString
();
}
fs
.
file
(
path
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'''
name:
$name
dependencies:
flutter:
sdk: flutter
$assetsSection
'''
);
}
void
establishFlutterRoot
()
{
// Setting flutterRoot here so that it picks up the MemoryFileSystem's
// path separator.
Cache
.
flutterRoot
=
getFlutterRoot
();
}
void
writePackagesFile
(
String
packages
)
{
fs
.
file
(
".packages"
)
..
createSync
()
..
writeAsStringSync
(
packages
);
}
Future
<
Null
>
buildAndVerifyAssets
(
List
<
String
>
assets
,
List
<
String
>
packages
,
String
expectedAssetManifest
,
)
async
{
final
AssetBundle
bundle
=
new
AssetBundle
();
await
bundle
.
build
(
manifestPath:
'pubspec.yaml'
);
for
(
String
packageName
in
packages
)
{
for
(
String
asset
in
assets
)
{
final
String
entryKey
=
'packages/
$packageName
/
$asset
'
;
expect
(
bundle
.
entries
.
containsKey
(
entryKey
),
true
);
expect
(
UTF8
.
decode
(
await
bundle
.
entries
[
entryKey
].
contentsAsBytes
()),
asset
,
);
}
}
expect
(
UTF8
.
decode
(
await
bundle
.
entries
[
'AssetManifest.json'
].
contentsAsBytes
()),
expectedAssetManifest
,
);
}
void
writeAssets
(
String
path
,
List
<
String
>
assets
)
{
for
(
String
asset
in
assets
)
{
fs
.
file
(
'
$path$asset
'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
asset
);
}
}
group
(
'AssetBundle assets from package'
,
()
{
testUsingContext
(
'One package with no assets'
,
()
async
{
establishFlutterRoot
();
writePubspecFile
(
'pubspec.yaml'
,
'test'
);
writePackagesFile
(
'test_package:p/p/lib/'
);
writePubspecFile
(
'p/p/pubspec.yaml'
,
'test_package'
);
final
AssetBundle
bundle
=
new
AssetBundle
();
await
bundle
.
build
(
manifestPath:
'pubspec.yaml'
);
expect
(
bundle
.
entries
.
length
,
2
);
// LICENSE, AssetManifest
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
new
MemoryFileSystem
(),
});
testUsingContext
(
'One package with one asset'
,
()
async
{
establishFlutterRoot
();
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
);
final
String
expectedAssetManifest
=
'{"packages/test_package/a/foo":'
'["packages/test_package/a/foo"]}'
;
await
buildAndVerifyAssets
(
assets
,
<
String
>[
'test_package'
],
expectedAssetManifest
,
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
new
MemoryFileSystem
(),
});
testUsingContext
(
'One package with asset variants'
,
()
async
{
establishFlutterRoot
();
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
);
final
String
expectedManifest
=
'{"packages/test_package/a/foo":'
'["packages/test_package/a/foo","packages/test_package/a/v/foo"]}'
;
await
buildAndVerifyAssets
(
assets
,
<
String
>[
'test_package'
],
expectedManifest
,
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
new
MemoryFileSystem
(),
});
testUsingContext
(
'One package with two assets'
,
()
async
{
establishFlutterRoot
();
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
);
final
String
expectedAssetManifest
=
'{"packages/test_package/a/foo":["packages/test_package/a/foo"],'
'"packages/test_package/a/bar":["packages/test_package/a/bar"]}'
;
await
buildAndVerifyAssets
(
assets
,
<
String
>[
'test_package'
],
expectedAssetManifest
,
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
new
MemoryFileSystem
(),
});
testUsingContext
(
'Two packages with assets'
,
()
async
{
establishFlutterRoot
();
writePubspecFile
(
'pubspec.yaml'
,
'test'
);
writePackagesFile
(
'test_package:p/p/lib/
\n
test_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
);
final
String
expectedAssetManifest
=
'{"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
,
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
new
MemoryFileSystem
(),
});
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment