From 32a3b04239b7f797701cf8759cfb327eb7f898e3 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 1 Feb 2016 15:13:58 -0800 Subject: [PATCH 1/3] extract out the _SimpleAsset* classes to a separate file, and use the package graph to enable reading files from other packages --- e2e_example/.gitignore | 1 + lib/src/asset/exceptions.dart | 19 ++++++++ lib/src/asset/file_based.dart | 67 ++++++++++++++++++++++++++ lib/src/generate/build.dart | 88 +++++++++++++++-------------------- 4 files changed, 124 insertions(+), 51 deletions(-) create mode 100644 e2e_example/.gitignore create mode 100644 lib/src/asset/file_based.dart diff --git a/e2e_example/.gitignore b/e2e_example/.gitignore new file mode 100644 index 000000000..fe688680b --- /dev/null +++ b/e2e_example/.gitignore @@ -0,0 +1 @@ +**/*.txt.copy diff --git a/lib/src/asset/exceptions.dart b/lib/src/asset/exceptions.dart index 4051a1b68..fbc5e2a5d 100644 --- a/lib/src/asset/exceptions.dart +++ b/lib/src/asset/exceptions.dart @@ -1,6 +1,7 @@ // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'asset.dart'; import 'id.dart'; class AssetNotFoundException implements Exception { @@ -11,3 +12,21 @@ class AssetNotFoundException implements Exception { @override String toString() => 'AssetNotFoundException: $assetId'; } + +class PackageNotFoundException implements Exception { + final String name; + + PackageNotFoundException(this.name); + + @override + String toString() => 'PackageNotFoundException: $name'; +} + +class InvalidOutputException implements Exception { + final Asset asset; + + InvalidOutputException(this.asset); + + @override + String toString() => 'InvalidOutputException: $asset'; +} diff --git a/lib/src/asset/file_based.dart b/lib/src/asset/file_based.dart new file mode 100644 index 000000000..d9c30be08 --- /dev/null +++ b/lib/src/asset/file_based.dart @@ -0,0 +1,67 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. 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 'dart:io'; + +import 'package:path/path.dart' as path; + +import '../asset/asset.dart'; +import '../asset/exceptions.dart'; +import '../asset/id.dart'; +import '../asset/reader.dart'; +import '../asset/writer.dart'; +import '../package_graph/package_graph.dart'; +import 'exceptions.dart'; + +/// Basic [AssetReader] which uses a [PackageGraph] to look up where to read +/// files from disk. +class FileBasedAssetReader implements AssetReader { + final PackageGraph packageGraph; + + FileBasedAssetReader(this.packageGraph); + + @override + Future hasInput(AssetId id) => _fileFor(id, packageGraph).exists(); + + @override + Future readAsString(AssetId id, {Encoding encoding: UTF8}) async { + var file = await _fileFor(id, packageGraph); + if (!await file.exists()) { + throw new AssetNotFoundException(id); + } + return file.readAsString(encoding: encoding); + } +} + +/// Basic [AssetWriter] which uses a [PackageGraph] to look up where to write +/// files to disk. +class FileBasedAssetWriter implements AssetWriter { + final PackageGraph packageGraph; + + FileBasedAssetWriter(this.packageGraph); + + @override + // Not using async/await here so that the first check can throw synchronously + // which helps with debugging. + Future writeAsString(Asset asset, {Encoding encoding: UTF8}) { + if (asset.id.package != packageGraph.root.name) { + throw new InvalidOutputException(asset); + } + + var file = _fileFor(asset.id, packageGraph); + return file.create(recursive: true).then((_) { + return file.writeAsString(asset.stringContents, encoding: encoding); + }); + } +} + +/// Returns a [File] for [id] given [packageGraph]. +File _fileFor(AssetId id, PackageGraph packageGraph) { + var package = packageGraph[id.package]; + if (package == null) { + throw new PackageNotFoundException(id.package); + } + return new File(path.join(package.location.toFilePath(), id.path)); +} diff --git a/lib/src/generate/build.dart b/lib/src/generate/build.dart index ebe78e916..dfc3f9157 100644 --- a/lib/src/generate/build.dart +++ b/lib/src/generate/build.dart @@ -2,33 +2,62 @@ // for details. 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 'dart:io'; import 'package:path/path.dart' as path; import 'package:yaml/yaml.dart'; import '../asset/asset.dart'; +import '../asset/file_based.dart'; import '../asset/id.dart'; import '../asset/reader.dart'; import '../asset/writer.dart'; import '../builder/builder.dart'; import '../builder/build_step_impl.dart'; +import '../package_graph/package_graph.dart'; import 'build_result.dart'; import 'input_set.dart'; import 'phase.dart'; /// Runs all of the [Phases] in [phaseGroups]. -Future build(List> phaseGroups) async { - try { +/// +/// A [packageGraph] may be supplied, otherwise one will be constructed using +/// [PackageGraph.forThisPackage]. The default functionality assumes you are +/// running in the root directory of a package, with both a `pubspec.yaml` and +/// `.packages` file present. +/// +/// A [reader] and [writer] may also be supplied, which can read/write assets +/// to arbitrary locations or file systems. By default they will write to the +/// current directory, and will use the `packageGraph` to know where to read +/// files from. +Future build(List> phaseGroups, + {PackageGraph packageGraph, AssetReader reader, AssetWriter writer}) async { + packageGraph ??= new PackageGraph.forThisPackage(); + reader ??= new FileBasedAssetReader(packageGraph); + writer ??= new FileBasedAssetWriter(packageGraph); + return runZoned(() { _validatePhases(phaseGroups); return _runPhases(phaseGroups); - } catch (e, s) { + }, onError: (e, s) { return new BuildResult(BuildStatus.Failure, BuildType.Full, [], exception: e, stackTrace: s); - } + }, zoneValues: { + _assetReaderKey: reader, + _assetWriterKey: writer, + _packageGraphKey: packageGraph, + }); } +/// Keys for reading zone local values. +Symbol _assetReaderKey = #buildAssetReader; +Symbol _assetWriterKey = #buildAssetWriter; +Symbol _packageGraphKey = #buildPackageGraph; + +/// Getters for zone local values. +AssetReader get _reader => Zone.current[_assetReaderKey]; +AssetWriter get _writer => Zone.current[_assetWriterKey]; +PackageGraph get _packageGraph => Zone.current[_packageGraphKey]; + /// The local package name from your pubspec. final String _localPackageName = () { var pubspec = new File('pubspec.yaml'); @@ -89,18 +118,15 @@ List _assetIdsFor(List inputSets) { /// Returns all files matching [inputSet]. Set _filesMatching(InputSet inputSet) { - if (inputSet.package != _localPackageName) { - throw new UnimplementedError('Running on packages other than the ' - 'local package is not yet supported'); - } - var files = new Set(); + var root = _packageGraph[inputSet.package].location.toFilePath(); for (var glob in inputSet.globs) { - files.addAll(glob.listSync(followLinks: false).where( + files.addAll(glob.listSync(followLinks: false, root: root).where( (e) => e is File && !_ignoredDirs.contains(path.split(e.path)[1]))); } return files; } +const _ignoredDirs = const ['build']; /// Runs [builder] with [inputs] as inputs. Stream _runBuilder(Builder builder, List inputs) async* { @@ -116,43 +142,3 @@ Stream _runBuilder(Builder builder, List inputs) async* { } } } - -/// Very simple [AssetReader], only works on local package and assumes you are -/// running from the root of the package. -class _SimpleAssetReader implements AssetReader { - const _SimpleAssetReader(); - - @override - Future hasInput(AssetId id) async { - assert(id.package == _localPackageName); - return new File(id.path).exists(); - } - - @override - Future readAsString(AssetId id, {Encoding encoding: UTF8}) async { - assert(id.package == _localPackageName); - return new File(id.path).readAsString(encoding: encoding); - } -} - -const AssetReader _reader = const _SimpleAssetReader(); - -/// Very simple [AssetWriter], only works on local package and assumes you are -/// running from the root of the package. -class _SimpleAssetWriter implements AssetWriter { - final _outputDir; - - const _SimpleAssetWriter(this._outputDir); - - @override - Future writeAsString(Asset asset, {Encoding encoding: UTF8}) async { - assert(asset.id.package == _localPackageName); - var file = new File(path.join(_outputDir, asset.id.path)); - await file.create(recursive: true); - await file.writeAsString(asset.stringContents, encoding: encoding); - } -} - -const AssetWriter _writer = const _SimpleAssetWriter('generated'); - -const _ignoredDirs = const ['generated', 'build', 'packages']; From 49c9c6aa236a4a774c65c4a57828bb9338c7916a Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 2 Feb 2016 08:17:21 -0800 Subject: [PATCH 2/3] add FileBasedAsset* tests --- .gitignore | 2 +- lib/build.dart | 1 + lib/src/asset/exceptions.dart | 13 ++- lib/src/asset/file_based.dart | 24 +++-- test/asset/file_based_test.dart | 97 +++++++++++++++++++ .../basic_pkg/.packages | 0 test/fixtures/basic_pkg/hello.txt | 1 + test/fixtures/basic_pkg/lib/hello.txt | 1 + test/fixtures/basic_pkg/pkg/a/a.txt | 1 + test/fixtures/basic_pkg/pkg/a/lib/a.txt | 1 + .../basic_pkg/pkg/a/pubspec.yaml | 0 test/fixtures/basic_pkg/pkg/a/web/a.txt | 1 + .../basic_pkg/pkg/b/pubspec.yaml | 0 .../basic_pkg/pkg/c/pubspec.yaml | 0 .../basic_pkg/pubspec.yaml | 0 test/fixtures/basic_pkg/web/hello.txt | 1 + .../no_packages_file/pubspec.yaml | 0 .../no_pubspec/.packages | 0 test/package_graph/package_graph_test.dart | 7 +- 19 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 test/asset/file_based_test.dart rename test/{package_graph => fixtures}/basic_pkg/.packages (100%) create mode 100644 test/fixtures/basic_pkg/hello.txt create mode 100644 test/fixtures/basic_pkg/lib/hello.txt create mode 100644 test/fixtures/basic_pkg/pkg/a/a.txt create mode 100644 test/fixtures/basic_pkg/pkg/a/lib/a.txt rename test/{package_graph => fixtures}/basic_pkg/pkg/a/pubspec.yaml (100%) create mode 100644 test/fixtures/basic_pkg/pkg/a/web/a.txt rename test/{package_graph => fixtures}/basic_pkg/pkg/b/pubspec.yaml (100%) rename test/{package_graph => fixtures}/basic_pkg/pkg/c/pubspec.yaml (100%) rename test/{package_graph => fixtures}/basic_pkg/pubspec.yaml (100%) create mode 100644 test/fixtures/basic_pkg/web/hello.txt rename test/{package_graph => fixtures}/no_packages_file/pubspec.yaml (100%) rename test/{package_graph => fixtures}/no_pubspec/.packages (100%) diff --git a/.gitignore b/.gitignore index 0b3df5ff4..4a5e7f9b9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ build/ pubspec.lock # Include .packages files from tests which are hand coded -!test/package_graph/**/.packages +!test/fixtures/**/.packages diff --git a/lib/build.dart b/lib/build.dart index db8bc7c06..7dad2a564 100644 --- a/lib/build.dart +++ b/lib/build.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. export 'src/asset/asset.dart'; export 'src/asset/exceptions.dart'; +export 'src/asset/file_based.dart'; export 'src/asset/id.dart'; export 'src/asset/reader.dart'; export 'src/asset/writer.dart'; diff --git a/lib/src/asset/exceptions.dart b/lib/src/asset/exceptions.dart index fbc5e2a5d..9e1f8b43f 100644 --- a/lib/src/asset/exceptions.dart +++ b/lib/src/asset/exceptions.dart @@ -28,5 +28,16 @@ class InvalidOutputException implements Exception { InvalidOutputException(this.asset); @override - String toString() => 'InvalidOutputException: $asset'; + String toString() => 'InvalidOutputException: $asset\n' + 'Files may only be output in the root (application) package.'; +} + +class InvalidInputException implements Exception { + final AssetId assetId; + + InvalidInputException(this.assetId); + + @override + String toString() => 'InvalidInputException: $assetId\n' + 'For package dependencies, only files under `lib` may be used as inputs.'; } diff --git a/lib/src/asset/file_based.dart b/lib/src/asset/file_based.dart index d9c30be08..a8a8a915d 100644 --- a/lib/src/asset/file_based.dart +++ b/lib/src/asset/file_based.dart @@ -23,16 +23,29 @@ class FileBasedAssetReader implements AssetReader { FileBasedAssetReader(this.packageGraph); @override - Future hasInput(AssetId id) => _fileFor(id, packageGraph).exists(); + Future hasInput(AssetId id) async { + _checkInput(id); + return _fileFor(id, packageGraph).exists(); + } @override Future readAsString(AssetId id, {Encoding encoding: UTF8}) async { + _checkInput(id); + var file = await _fileFor(id, packageGraph); if (!await file.exists()) { throw new AssetNotFoundException(id); } return file.readAsString(encoding: encoding); } + + /// Checks that [id] is a valid input, and throws an [InvalidInputException] + /// if its not. + void _checkInput(AssetId id) { + if (id.package != packageGraph.root.name && !id.path.startsWith('lib/')) { + throw new InvalidInputException(id); + } + } } /// Basic [AssetWriter] which uses a [PackageGraph] to look up where to write @@ -43,17 +56,14 @@ class FileBasedAssetWriter implements AssetWriter { FileBasedAssetWriter(this.packageGraph); @override - // Not using async/await here so that the first check can throw synchronously - // which helps with debugging. - Future writeAsString(Asset asset, {Encoding encoding: UTF8}) { + Future writeAsString(Asset asset, {Encoding encoding: UTF8}) async { if (asset.id.package != packageGraph.root.name) { throw new InvalidOutputException(asset); } var file = _fileFor(asset.id, packageGraph); - return file.create(recursive: true).then((_) { - return file.writeAsString(asset.stringContents, encoding: encoding); - }); + await file.create(recursive: true); + await file.writeAsString(asset.stringContents, encoding: encoding); } } diff --git a/test/asset/file_based_test.dart b/test/asset/file_based_test.dart new file mode 100644 index 000000000..64ff7d4ce --- /dev/null +++ b/test/asset/file_based_test.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +@TestOn('vm') +import 'dart:async'; +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'package:build/build.dart'; +import '../common/common.dart'; + +main() async { + final packageGraph = new PackageGraph.forPath('test/fixtures/basic_pkg'); + final assetNotFoundException = new isInstanceOf(); + final invalidInputException = new isInstanceOf(); + final invalidOutputException = new isInstanceOf(); + final packageNotFoundException = new isInstanceOf(); + + group('FileBasedAssetReader', () { + final reader = new FileBasedAssetReader(packageGraph); + + test('can read any application package files', () async { + expect(await reader.readAsString(makeAssetId('basic_pkg|hello.txt')), + 'world\n'); + expect(await reader.readAsString(makeAssetId('basic_pkg|lib/hello.txt')), + 'world\n'); + expect(await reader.readAsString(makeAssetId('basic_pkg|web/hello.txt')), + 'world\n'); + }); + + test('can only read package dependency files in the lib dir', () async { + expect(await reader.readAsString(makeAssetId('a|lib/a.txt')), 'A\n'); + expect(reader.readAsString(makeAssetId('a|web/a.txt')), + throwsA(invalidInputException)); + expect(reader.readAsString(makeAssetId('a|a.txt')), + throwsA(invalidInputException)); + }); + + test('can check for existence of any application package files', () async { + expect(await reader.hasInput(makeAssetId('basic_pkg|hello.txt')), isTrue); + expect(await reader.hasInput(makeAssetId('basic_pkg|lib/hello.txt')), + isTrue); + expect(await reader.hasInput(makeAssetId('basic_pkg|web/hello.txt')), + isTrue); + + expect(await reader.hasInput(makeAssetId('basic_pkg|a.txt')), isFalse); + expect( + await reader.hasInput(makeAssetId('basic_pkg|lib/a.txt')), isFalse); + }); + + test('can only check for existence of package dependency files in lib', + () async { + expect(await reader.hasInput(makeAssetId('a|lib/a.txt')), isTrue); + expect(await reader.hasInput(makeAssetId('a|lib/b.txt')), isFalse); + expect(reader.hasInput(makeAssetId('a|web/a.txt')), + throwsA(invalidInputException)); + expect(reader.hasInput(makeAssetId('a|a.txt')), + throwsA(invalidInputException)); + expect(reader.hasInput(makeAssetId('foo|bar.txt')), + throwsA(invalidInputException)); + }); + + test('throws when attempting to read a non-existent file', () async { + expect(reader.readAsString(makeAssetId('basic_pkg|foo.txt')), + throwsA(assetNotFoundException)); + expect(reader.readAsString(makeAssetId('a|lib/b.txt')), + throwsA(assetNotFoundException)); + expect(reader.readAsString(makeAssetId('foo|lib/bar.txt')), + throwsA(packageNotFoundException)); + }); + }); + + group('FileBasedAssetWriter', () { + final writer = new FileBasedAssetWriter(packageGraph); + + test('can output files in the application package', () async { + var asset = makeAsset('basic_pkg|test_file.txt', 'test'); + await writer.writeAsString(asset); + var id = asset.id; + var file = new File('test/fixtures/${id.package}/${id.path}'); + expect(await file.exists(), isTrue); + expect(await file.readAsString(), 'test'); + await file.delete(); + }); + + test('can\'t output files in package dependencies', () async { + var asset = makeAsset('a|test.txt'); + expect(writer.writeAsString(asset), throwsA(invalidOutputException)); + }); + + test('can\'t output files in arbitrary packages', () async { + var asset = makeAsset('foo|bar.txt'); + expect(writer.writeAsString(asset), throwsA(invalidOutputException)); + }); + }); +} diff --git a/test/package_graph/basic_pkg/.packages b/test/fixtures/basic_pkg/.packages similarity index 100% rename from test/package_graph/basic_pkg/.packages rename to test/fixtures/basic_pkg/.packages diff --git a/test/fixtures/basic_pkg/hello.txt b/test/fixtures/basic_pkg/hello.txt new file mode 100644 index 000000000..cc628ccd1 --- /dev/null +++ b/test/fixtures/basic_pkg/hello.txt @@ -0,0 +1 @@ +world diff --git a/test/fixtures/basic_pkg/lib/hello.txt b/test/fixtures/basic_pkg/lib/hello.txt new file mode 100644 index 000000000..cc628ccd1 --- /dev/null +++ b/test/fixtures/basic_pkg/lib/hello.txt @@ -0,0 +1 @@ +world diff --git a/test/fixtures/basic_pkg/pkg/a/a.txt b/test/fixtures/basic_pkg/pkg/a/a.txt new file mode 100644 index 000000000..f70f10e4d --- /dev/null +++ b/test/fixtures/basic_pkg/pkg/a/a.txt @@ -0,0 +1 @@ +A diff --git a/test/fixtures/basic_pkg/pkg/a/lib/a.txt b/test/fixtures/basic_pkg/pkg/a/lib/a.txt new file mode 100644 index 000000000..f70f10e4d --- /dev/null +++ b/test/fixtures/basic_pkg/pkg/a/lib/a.txt @@ -0,0 +1 @@ +A diff --git a/test/package_graph/basic_pkg/pkg/a/pubspec.yaml b/test/fixtures/basic_pkg/pkg/a/pubspec.yaml similarity index 100% rename from test/package_graph/basic_pkg/pkg/a/pubspec.yaml rename to test/fixtures/basic_pkg/pkg/a/pubspec.yaml diff --git a/test/fixtures/basic_pkg/pkg/a/web/a.txt b/test/fixtures/basic_pkg/pkg/a/web/a.txt new file mode 100644 index 000000000..f70f10e4d --- /dev/null +++ b/test/fixtures/basic_pkg/pkg/a/web/a.txt @@ -0,0 +1 @@ +A diff --git a/test/package_graph/basic_pkg/pkg/b/pubspec.yaml b/test/fixtures/basic_pkg/pkg/b/pubspec.yaml similarity index 100% rename from test/package_graph/basic_pkg/pkg/b/pubspec.yaml rename to test/fixtures/basic_pkg/pkg/b/pubspec.yaml diff --git a/test/package_graph/basic_pkg/pkg/c/pubspec.yaml b/test/fixtures/basic_pkg/pkg/c/pubspec.yaml similarity index 100% rename from test/package_graph/basic_pkg/pkg/c/pubspec.yaml rename to test/fixtures/basic_pkg/pkg/c/pubspec.yaml diff --git a/test/package_graph/basic_pkg/pubspec.yaml b/test/fixtures/basic_pkg/pubspec.yaml similarity index 100% rename from test/package_graph/basic_pkg/pubspec.yaml rename to test/fixtures/basic_pkg/pubspec.yaml diff --git a/test/fixtures/basic_pkg/web/hello.txt b/test/fixtures/basic_pkg/web/hello.txt new file mode 100644 index 000000000..cc628ccd1 --- /dev/null +++ b/test/fixtures/basic_pkg/web/hello.txt @@ -0,0 +1 @@ +world diff --git a/test/package_graph/no_packages_file/pubspec.yaml b/test/fixtures/no_packages_file/pubspec.yaml similarity index 100% rename from test/package_graph/no_packages_file/pubspec.yaml rename to test/fixtures/no_packages_file/pubspec.yaml diff --git a/test/package_graph/no_pubspec/.packages b/test/fixtures/no_pubspec/.packages similarity index 100% rename from test/package_graph/no_pubspec/.packages rename to test/fixtures/no_pubspec/.packages diff --git a/test/package_graph/package_graph_test.dart b/test/package_graph/package_graph_test.dart index 587dd2a29..cfa00534b 100644 --- a/test/package_graph/package_graph_test.dart +++ b/test/package_graph/package_graph_test.dart @@ -21,7 +21,7 @@ main() async { }); group('basic package ', () { - var basicPkgPath = 'test/package_graph/basic_pkg'; + var basicPkgPath = 'test/fixtures/basic_pkg'; setUp(() async { graph = await new PackageGraph.forPath(basicPkgPath); @@ -58,11 +58,12 @@ main() async { }); test('missing pubspec throws on create', () { - expect(() => new PackageGraph.forPath('no_pubspec'), throws); + expect(() => new PackageGraph.forPath('test/fixtures/no_pubspec'), throws); }); test('missing .packages file throws on create', () { - expect(() => new PackageGraph.forPath('no_packages_file'), throws); + expect(() => new PackageGraph.forPath('test/fixtures/no_packages_file'), + throws); }); } From cc2d4bce2e7dd2204e9f15e35c86f4968452ccc0 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 2 Feb 2016 08:25:10 -0800 Subject: [PATCH 3/3] move matchers to common test file --- test/asset/file_based_test.dart | 9 +++------ test/common/assets.dart | 35 +++++++++++++++++++++++++++++++++ test/common/common.dart | 35 ++------------------------------- test/common/matchers.dart | 11 +++++++++++ 4 files changed, 51 insertions(+), 39 deletions(-) create mode 100644 test/common/assets.dart create mode 100644 test/common/matchers.dart diff --git a/test/asset/file_based_test.dart b/test/asset/file_based_test.dart index 64ff7d4ce..b6dda3989 100644 --- a/test/asset/file_based_test.dart +++ b/test/asset/file_based_test.dart @@ -2,20 +2,17 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. @TestOn('vm') -import 'dart:async'; import 'dart:io'; import 'package:test/test.dart'; import 'package:build/build.dart'; + import '../common/common.dart'; +final packageGraph = new PackageGraph.forPath('test/fixtures/basic_pkg'); + main() async { - final packageGraph = new PackageGraph.forPath('test/fixtures/basic_pkg'); - final assetNotFoundException = new isInstanceOf(); - final invalidInputException = new isInstanceOf(); - final invalidOutputException = new isInstanceOf(); - final packageNotFoundException = new isInstanceOf(); group('FileBasedAssetReader', () { final reader = new FileBasedAssetReader(packageGraph); diff --git a/test/common/assets.dart b/test/common/assets.dart new file mode 100644 index 000000000..498f4415b --- /dev/null +++ b/test/common/assets.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. 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:build/build.dart'; + +import 'in_memory_writer.dart'; + +int _nextId = 0; +AssetId makeAssetId([String assetIdString]) { + if (assetIdString == null) { + assetIdString = 'a|web/asset_$_nextId.txt'; + _nextId++; + } + return new AssetId.parse(assetIdString); +} + +Asset makeAsset([String assetIdString, String contents]) { + var id = makeAssetId(assetIdString); + return new Asset(id, contents ?? '$id'); +} + +Map makeAssets(Map assetsMap) { + var assets = {}; + assetsMap.forEach((idString, content) { + var asset = makeAsset(idString, content); + assets[asset.id] = asset; + }); + return assets; +} + +void addAssets(Iterable assets, InMemoryAssetWriter writer) { + for (var asset in assets) { + writer.assets[asset.id] = asset.stringContents; + } +} diff --git a/test/common/common.dart b/test/common/common.dart index 2f5f3fb09..780269815 100644 --- a/test/common/common.dart +++ b/test/common/common.dart @@ -1,43 +1,12 @@ // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. 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:build/build.dart'; - -import 'in_memory_writer.dart'; - +export 'assets.dart'; export 'copy_builder.dart'; export 'file_combiner_builder.dart'; export 'in_memory_reader.dart'; export 'in_memory_writer.dart'; export 'generic_builder_transformer.dart'; +export 'matchers.dart'; export 'stub_reader.dart'; export 'stub_writer.dart'; - -int _nextId = 0; -AssetId makeAssetId([String assetIdString]) { - if (assetIdString == null) { - assetIdString = 'a|web/asset_$_nextId.txt'; - _nextId++; - } - return new AssetId.parse(assetIdString); -} - -Asset makeAsset([String assetIdString, String contents]) { - var id = makeAssetId(assetIdString); - return new Asset(id, contents ?? '$id'); -} - -Map makeAssets(Map assetsMap) { - var assets = {}; - assetsMap.forEach((idString, content) { - var asset = makeAsset(idString, content); - assets[asset.id] = asset; - }); - return assets; -} - -void addAssets(Iterable assets, InMemoryAssetWriter writer) { - for (var asset in assets) { - writer.assets[asset.id] = asset.stringContents; - } -} diff --git a/test/common/matchers.dart b/test/common/matchers.dart new file mode 100644 index 000000000..051ef455d --- /dev/null +++ b/test/common/matchers.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. 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:test/test.dart'; + +import 'package:build/build.dart'; + +final assetNotFoundException = new isInstanceOf(); +final invalidInputException = new isInstanceOf(); +final invalidOutputException = new isInstanceOf(); +final packageNotFoundException = new isInstanceOf();