mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:07:11 +00:00
Take Sam Elkhateeb's path for "path" dependencies and clean it up some.
BUG=http://code.google.com/p/dart/issues/detail?id=3732 Review URL: https://codereview.chromium.org//12208138 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18465 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
5694a140e3
commit
bd0d874a53
11 changed files with 396 additions and 123 deletions
|
@ -315,7 +315,7 @@ Future<File> createSymlink(from, to) {
|
|||
from = _getPath(from);
|
||||
to = _getPath(to);
|
||||
|
||||
log.fine("Create symlink $from -> $to.");
|
||||
log.fine("Creating symlink ($to is a symlink to $from)");
|
||||
|
||||
var command = 'ln';
|
||||
var args = ['-s', from, to];
|
||||
|
|
78
utils/pub/path_source.dart
Normal file
78
utils/pub/path_source.dart
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2013, 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.
|
||||
|
||||
library path_source;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import '../../pkg/path/lib/path.dart' as path;
|
||||
|
||||
import 'io.dart';
|
||||
import 'package.dart';
|
||||
import 'pubspec.dart';
|
||||
import 'version.dart';
|
||||
import 'source.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
// TODO(rnystrom): Support relative paths. (See comment in _validatePath().)
|
||||
/// A package [Source] that installs packages from a given local file path.
|
||||
class PathSource extends Source {
|
||||
final name = 'path';
|
||||
final shouldCache = false;
|
||||
|
||||
Future<Pubspec> describe(PackageId id) {
|
||||
return defer(() {
|
||||
_validatePath(id.name, id.description);
|
||||
return new Pubspec.load(id.name, id.description, systemCache.sources);
|
||||
});
|
||||
}
|
||||
|
||||
Future<bool> install(PackageId id, String path) {
|
||||
return defer(() {
|
||||
try {
|
||||
_validatePath(id.name, id.description);
|
||||
} on FormatException catch(err) {
|
||||
return false;
|
||||
}
|
||||
return createPackageSymlink(id.name, id.description, path);
|
||||
}).then((_) => true);
|
||||
}
|
||||
|
||||
void validateDescription(description, {bool fromLockFile: false}) {
|
||||
if (description is! String) {
|
||||
throw new FormatException("The description must be a path string.");
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures that [dir] is a valid path. It must be an absolute path that
|
||||
/// points to an existing directory. Throws a [FormatException] if the path
|
||||
/// is invalid.
|
||||
void _validatePath(String name, String dir) {
|
||||
// Relative paths are not (currently) allowed because the user would expect
|
||||
// them to be relative to the pubspec where the dependency appears. That in
|
||||
// turn means that two pubspecs in different locations with the same
|
||||
// relative path dependency could refer to two different packages. That
|
||||
// violates pub's rule that a description should uniquely identify a
|
||||
// package.
|
||||
//
|
||||
// At some point, we may want to loosen this, but it will mean tracking
|
||||
// where a given PackageId appeared.
|
||||
if (!path.isAbsolute(dir)) {
|
||||
throw new FormatException(
|
||||
"Path dependency for package '$name' must be an absolute path. "
|
||||
"Was '$dir'.");
|
||||
}
|
||||
|
||||
if (fileExists(dir)) {
|
||||
throw new FormatException(
|
||||
"Path dependency for package '$name' must refer to a "
|
||||
"directory, not a file. Was '$dir'.");
|
||||
}
|
||||
|
||||
if (!dirExists(dir)) {
|
||||
throw new FormatException("Could not find package '$name' at '$dir'.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import 'io.dart';
|
|||
import 'io.dart' as io show createTempDir;
|
||||
import 'log.dart' as log;
|
||||
import 'package.dart';
|
||||
import 'path_source.dart';
|
||||
import 'pubspec.dart';
|
||||
import 'sdk_source.dart';
|
||||
import 'source.dart';
|
||||
|
@ -46,9 +47,10 @@ class SystemCache {
|
|||
/// Creates a system cache and registers the standard set of sources.
|
||||
factory SystemCache.withSources(String rootDir) {
|
||||
var cache = new SystemCache(rootDir);
|
||||
cache.register(new SdkSource());
|
||||
cache.register(new GitSource());
|
||||
cache.register(new HostedSource());
|
||||
cache.register(new PathSource());
|
||||
cache.register(new SdkSource());
|
||||
cache.sources.setDefault('hosted');
|
||||
return cache;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import '../entrypoint.dart';
|
|||
import '../hosted_source.dart';
|
||||
import '../http.dart';
|
||||
import '../package.dart';
|
||||
import '../path_source.dart';
|
||||
import '../utils.dart';
|
||||
import '../validator.dart';
|
||||
import '../version.dart';
|
||||
|
@ -62,7 +63,13 @@ class DependencyValidator extends Validator {
|
|||
}
|
||||
}
|
||||
|
||||
warnings.add('Don\'t depend on "${ref.name}" from the ${ref.source.name} '
|
||||
// Path sources are errors. Other sources are just warnings.
|
||||
var messages = warnings;
|
||||
if (ref.source is PathSource) {
|
||||
messages = errors;
|
||||
}
|
||||
|
||||
messages.add('Don\'t depend on "${ref.name}" from the ${ref.source.name} '
|
||||
'source. Use the hosted source instead. For example:\n'
|
||||
'\n'
|
||||
'dependencies:\n'
|
||||
|
|
46
utils/tests/pub/install/path/absolute_path_test.dart
Normal file
46
utils/tests/pub/install/path/absolute_path_test.dart
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2013, 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 '../../../../../pkg/path/lib/path.dart' as path;
|
||||
|
||||
import '../../test_pub.dart';
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
integration('path dependency with absolute path', () {
|
||||
dir('foo', [
|
||||
libDir('foo'),
|
||||
libPubspec('foo', '0.0.1')
|
||||
]).scheduleCreate();
|
||||
|
||||
dir(appPath, [
|
||||
pubspec({
|
||||
"name": "myapp",
|
||||
"dependencies": {
|
||||
"foo": {"path": path.join(sandboxDir, "foo")}
|
||||
}
|
||||
})
|
||||
]).scheduleCreate();
|
||||
|
||||
schedulePub(args: ["install"],
|
||||
output: new RegExp(r"Dependencies installed!$"));
|
||||
|
||||
dir(packagesPath, [
|
||||
dir("foo", [
|
||||
file("foo.dart", 'main() => "foo";')
|
||||
])
|
||||
]).scheduleValidate();
|
||||
|
||||
// Move the packages directory and ensure the symlink still works. That
|
||||
// will validate that we actually created an absolute symlink.
|
||||
dir("moved").scheduleCreate();
|
||||
scheduleRename(packagesPath, "moved/packages");
|
||||
|
||||
dir("moved/packages", [
|
||||
dir("foo", [
|
||||
file("foo.dart", 'main() => "foo";')
|
||||
])
|
||||
]).scheduleValidate();
|
||||
});
|
||||
}
|
32
utils/tests/pub/install/path/no_pubspec_test.dart
Normal file
32
utils/tests/pub/install/path/no_pubspec_test.dart
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2013, 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:io';
|
||||
|
||||
import '../../../../../pkg/path/lib/path.dart' as path;
|
||||
|
||||
import '../../test_pub.dart';
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
integration('path dependency to non-package directory', () {
|
||||
// Make an empty directory.
|
||||
dir('foo').scheduleCreate();
|
||||
var fooPath = path.join(sandboxDir, "foo");
|
||||
|
||||
dir(appPath, [
|
||||
pubspec({
|
||||
"name": "myapp",
|
||||
"dependencies": {
|
||||
"foo": {"path": fooPath}
|
||||
}
|
||||
})
|
||||
]).scheduleCreate();
|
||||
|
||||
schedulePub(args: ['install'],
|
||||
error:
|
||||
new RegExp('Package "foo" doesn\'t have a pubspec.yaml file.'),
|
||||
exitCode: 1);
|
||||
});
|
||||
}
|
31
utils/tests/pub/install/path/nonexistent_dir_test.dart
Normal file
31
utils/tests/pub/install/path/nonexistent_dir_test.dart
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) 2013, 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:io';
|
||||
|
||||
import '../../../../../pkg/path/lib/path.dart' as path;
|
||||
|
||||
import '../../../../pub/exit_codes.dart' as exit_codes;
|
||||
import '../../test_pub.dart';
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
integration('path dependency to non-existent directory', () {
|
||||
var badPath = path.join(sandboxDir, "bad_path");
|
||||
|
||||
dir(appPath, [
|
||||
pubspec({
|
||||
"name": "myapp",
|
||||
"dependencies": {
|
||||
"foo": {"path": badPath}
|
||||
}
|
||||
})
|
||||
]).scheduleCreate();
|
||||
|
||||
schedulePub(args: ['install'],
|
||||
error:
|
||||
new RegExp("Could not find package 'foo' at '$badPath'."),
|
||||
exitCode: exit_codes.DATA);
|
||||
});
|
||||
}
|
35
utils/tests/pub/install/path/path_is_file_test.dart
Normal file
35
utils/tests/pub/install/path/path_is_file_test.dart
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2013, 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 '../../../../../pkg/path/lib/path.dart' as path;
|
||||
|
||||
import '../../../../pub/exit_codes.dart' as exit_codes;
|
||||
import '../../test_pub.dart';
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
integration('path dependency when path is a file', () {
|
||||
dir('foo', [
|
||||
libDir('foo'),
|
||||
libPubspec('foo', '0.0.1')
|
||||
]).scheduleCreate();
|
||||
|
||||
file('dummy.txt', '').scheduleCreate();
|
||||
var dummyPath = path.join(sandboxDir, 'dummy.txt');
|
||||
|
||||
dir(appPath, [
|
||||
pubspec({
|
||||
"name": "myapp",
|
||||
"dependencies": {
|
||||
"foo": {"path": dummyPath}
|
||||
}
|
||||
})
|
||||
]).scheduleCreate();
|
||||
|
||||
schedulePub(args: ['install'],
|
||||
error: new RegExp("Path dependency for package 'foo' must refer to a "
|
||||
"directory, not a file. Was '$dummyPath'."),
|
||||
exitCode: exit_codes.DATA);
|
||||
});
|
||||
}
|
25
utils/tests/pub/install/path/relative_path_test.dart
Normal file
25
utils/tests/pub/install/path/relative_path_test.dart
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2013, 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 '../../../../pub/exit_codes.dart' as exit_codes;
|
||||
import '../../test_pub.dart';
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
integration('path dependencies cannot use relative paths', () {
|
||||
dir(appPath, [
|
||||
pubspec({
|
||||
"name": "myapp",
|
||||
"dependencies": {
|
||||
"foo": {"path": "../foo"}
|
||||
}
|
||||
})
|
||||
]).scheduleCreate();
|
||||
|
||||
schedulePub(args: ['install'],
|
||||
error: new RegExp("Path dependency for package 'foo' must be an "
|
||||
"absolute path. Was '../foo'."),
|
||||
exitCode: exit_codes.DATA);
|
||||
});
|
||||
}
|
|
@ -31,6 +31,7 @@ import '../../pub/git_source.dart';
|
|||
import '../../pub/hosted_source.dart';
|
||||
import '../../pub/http.dart';
|
||||
import '../../pub/io.dart';
|
||||
import '../../pub/path_source.dart';
|
||||
import '../../pub/sdk_source.dart';
|
||||
import '../../pub/system_cache.dart';
|
||||
import '../../pub/utils.dart';
|
||||
|
@ -404,6 +405,9 @@ Future<Map> _dependencyListToMap(List<Map> dependencies) {
|
|||
case "hosted":
|
||||
source = new HostedSource();
|
||||
break;
|
||||
case "path":
|
||||
source = new PathSource();
|
||||
break;
|
||||
case "sdk":
|
||||
source = new SdkSource();
|
||||
break;
|
||||
|
@ -427,6 +431,8 @@ String _packageName(String sourceName, description) {
|
|||
case "hosted":
|
||||
if (description is String) return description;
|
||||
return description['name'];
|
||||
case "path":
|
||||
return basename(description);
|
||||
case "sdk":
|
||||
return description;
|
||||
default:
|
||||
|
@ -434,6 +440,10 @@ String _packageName(String sourceName, description) {
|
|||
}
|
||||
}
|
||||
|
||||
/// The full path to the created sandbox directory for an integration test.
|
||||
String get sandboxDir => _sandboxDir.path;
|
||||
Directory _sandboxDir;
|
||||
|
||||
/// The path of the package cache directory used for tests. Relative to the
|
||||
/// sandbox directory.
|
||||
final String cachePath = "cache";
|
||||
|
@ -488,27 +498,32 @@ void _integration(String description, void body(), [Function testFn]) {
|
|||
file('version', '0.1.2.3')
|
||||
]).scheduleCreate();
|
||||
|
||||
_sandboxDir = createTempDir();
|
||||
|
||||
// Schedule the test.
|
||||
body();
|
||||
|
||||
// Run all of the scheduled tasks. If an error occurs, it will propagate
|
||||
// through the futures back up to here where we can hand it off to unittest.
|
||||
var asyncDone = expectAsync0(() {});
|
||||
var sandboxDir = createTempDir();
|
||||
return timeout(_runScheduled(sandboxDir, _scheduled),
|
||||
return timeout(_runScheduled(_scheduled),
|
||||
_TIMEOUT, 'waiting for a test to complete').catchError((e) {
|
||||
return _runScheduled(sandboxDir, _scheduledOnException).then((_) {
|
||||
return _runScheduled(_scheduledOnException).then((_) {
|
||||
// Rethrow the original error so it keeps propagating.
|
||||
throw e;
|
||||
});
|
||||
}).whenComplete(() {
|
||||
// Clean up after ourselves. Do this first before reporting back to
|
||||
// unittest because it will advance to the next test immediately.
|
||||
return _runScheduled(sandboxDir, _scheduledCleanup).then((_) {
|
||||
return _runScheduled(_scheduledCleanup).then((_) {
|
||||
_scheduled = null;
|
||||
_scheduledCleanup = null;
|
||||
_scheduledOnException = null;
|
||||
if (sandboxDir != null) return deleteDir(sandboxDir);
|
||||
if (_sandboxDir != null) {
|
||||
var dir = _sandboxDir;
|
||||
_sandboxDir = null;
|
||||
return deleteDir(dir);
|
||||
}
|
||||
});
|
||||
}).then((_) {
|
||||
// If we got here, the test completed successfully so tell unittest so.
|
||||
|
@ -532,6 +547,14 @@ String get testDirectory {
|
|||
return getFullPath(dir);
|
||||
}
|
||||
|
||||
/// Schedules renaming (moving) the directory at [from] to [to], both of which
|
||||
/// are assumed to be relative to [sandboxDir].
|
||||
void scheduleRename(String from, String to) {
|
||||
_schedule((sandboxDir) {
|
||||
return renameDir(join(sandboxDir, from), join(sandboxDir, to));
|
||||
});
|
||||
}
|
||||
|
||||
/// Schedules a call to the Pub command-line utility. Runs Pub with [args] and
|
||||
/// validates that its results match [output], [error], and [exitCode].
|
||||
void schedulePub({List args, Pattern output, Pattern error,
|
||||
|
@ -602,7 +625,6 @@ void confirmPublish(ScheduledProcess pub) {
|
|||
pub.writeLine("y");
|
||||
}
|
||||
|
||||
|
||||
/// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
|
||||
/// should have the same signature as [startProcess], except that the returned
|
||||
/// [Future] may have a type other than [Process].
|
||||
|
@ -677,7 +699,7 @@ void useMockClient(MockClient client) {
|
|||
});
|
||||
}
|
||||
|
||||
Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) {
|
||||
Future _runScheduled(List<_ScheduledEvent> scheduled) {
|
||||
if (scheduled == null) return new Future.immediate(null);
|
||||
var iterator = scheduled.iterator;
|
||||
|
||||
|
@ -688,7 +710,7 @@ Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) {
|
|||
return new Future.immediate(null);
|
||||
}
|
||||
|
||||
var future = iterator.current(parentDir);
|
||||
var future = iterator.current(_sandboxDir);
|
||||
if (future != null) {
|
||||
return future.then(runNextEvent);
|
||||
} else {
|
||||
|
@ -1169,7 +1191,7 @@ class NothingDescriptor extends Descriptor {
|
|||
typedef Validator ValidatorCreator(Entrypoint entrypoint);
|
||||
|
||||
/// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
|
||||
/// Future that contains the erros and warnings produced by that validator.
|
||||
/// Future that contains the errors and warnings produced by that validator.
|
||||
Future<Pair<List<String>, List<String>>> schedulePackageValidation(
|
||||
ValidatorCreator fn) {
|
||||
return _scheduleValue((sandboxDir) {
|
||||
|
|
|
@ -10,9 +10,10 @@ import 'dart:json' as json;
|
|||
import 'dart:math' as math;
|
||||
|
||||
import 'test_pub.dart';
|
||||
import '../../../pkg/unittest/lib/unittest.dart';
|
||||
import '../../../pkg/http/lib/http.dart' as http;
|
||||
import '../../../pkg/http/lib/testing.dart';
|
||||
import '../../../pkg/path/lib/path.dart' as path;
|
||||
import '../../../pkg/unittest/lib/unittest.dart';
|
||||
import '../../pub/entrypoint.dart';
|
||||
import '../../pub/io.dart';
|
||||
import '../../pub/validator.dart';
|
||||
|
@ -38,6 +39,16 @@ void expectValidationWarning(ValidatorCreator fn) {
|
|||
expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isNot(isEmpty)));
|
||||
}
|
||||
|
||||
expectDependencyValidationError(String error) {
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(someElement(contains(error)), isEmpty));
|
||||
}
|
||||
|
||||
expectDependencyValidationWarning(String warning) {
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(warning))));
|
||||
}
|
||||
|
||||
Validator compiledDartdoc(Entrypoint entrypoint) =>
|
||||
new CompiledDartdocValidator(entrypoint);
|
||||
|
||||
|
@ -66,7 +77,31 @@ Validator utf8Readme(Entrypoint entrypoint) =>
|
|||
|
||||
void scheduleNormalPackage() => normalPackage.scheduleCreate();
|
||||
|
||||
/// Sets up a test package with dependency [dep] and mocks a server with
|
||||
/// [hostedVersions] of the package available.
|
||||
setUpDependency(Map dep, {List<String> hostedVersions}) {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
|
||||
if (hostedVersions == null) {
|
||||
return new Future.immediate(new http.Response("not found", 404));
|
||||
} else {
|
||||
return new Future.immediate(new http.Response(json.stringify({
|
||||
"name": "foo",
|
||||
"uploaders": ["nweiz@google.com"],
|
||||
"versions": hostedVersions
|
||||
}), 200));
|
||||
}
|
||||
}));
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [dep])
|
||||
]).scheduleCreate();
|
||||
}
|
||||
|
||||
main() {
|
||||
initConfig();
|
||||
group('should consider a package valid if it', () {
|
||||
setUp(scheduleNormalPackage);
|
||||
|
||||
|
@ -326,124 +361,88 @@ main() {
|
|||
expectValidationError(lib);
|
||||
});
|
||||
|
||||
group('has a dependency with a non-hosted source', () {
|
||||
group('where a hosted version of that dependency exists', () {
|
||||
integration("and should suggest the hosted package's primary "
|
||||
"version", () {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
|
||||
return new Future.immediate(new http.Response(json.stringify({
|
||||
"name": "foo",
|
||||
"uploaders": ["nweiz@google.com"],
|
||||
"versions": ["3.0.0-pre", "2.0.0", "1.0.0"]
|
||||
}), 200));
|
||||
}));
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [
|
||||
{'git': 'git://github.com/dart-lang/foo'}
|
||||
])
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=2.0.0 <3.0.0"'))));
|
||||
group('has a git dependency', () {
|
||||
group('where a hosted version exists', () {
|
||||
integration("and should suggest the hosted primary version", () {
|
||||
setUpDependency({'git': 'git://github.com/dart-lang/foo'},
|
||||
hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]);
|
||||
expectDependencyValidationWarning(' foo: ">=2.0.0 <3.0.0"');
|
||||
});
|
||||
|
||||
integration("and should suggest the hosted package's prerelease "
|
||||
"version if it's the only version available", () {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
|
||||
return new Future.immediate(new http.Response(json.stringify({
|
||||
"name": "foo",
|
||||
"uploaders": ["nweiz@google.com"],
|
||||
"versions": ["3.0.0-pre", "2.0.0-pre"]
|
||||
}), 200));
|
||||
}));
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [
|
||||
{'git': 'git://github.com/dart-lang/foo'}
|
||||
])
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=3.0.0-pre <4.0.0"'))));
|
||||
integration("and should suggest the hosted prerelease version if "
|
||||
"it's the only version available", () {
|
||||
setUpDependency({'git': 'git://github.com/dart-lang/foo'},
|
||||
hostedVersions: ["3.0.0-pre", "2.0.0-pre"]);
|
||||
expectDependencyValidationWarning(' foo: ">=3.0.0-pre <4.0.0"');
|
||||
});
|
||||
|
||||
integration("and should suggest a tighter constraint if the primary "
|
||||
"version is pre-1.0.0", () {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
|
||||
return new Future.immediate(new http.Response(json.stringify({
|
||||
"name": "foo",
|
||||
"uploaders": ["nweiz@google.com"],
|
||||
"versions": ["0.0.1", "0.0.2"]
|
||||
}), 200));
|
||||
}));
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [
|
||||
{'git': 'git://github.com/dart-lang/foo'}
|
||||
])
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=0.0.2 <0.0.3"'))));
|
||||
integration("and should suggest a tighter constraint if primary is "
|
||||
"pre-1.0.0", () {
|
||||
setUpDependency({'git': 'git://github.com/dart-lang/foo'},
|
||||
hostedVersions: ["0.0.1", "0.0.2"]);
|
||||
expectDependencyValidationWarning(' foo: ">=0.0.2 <0.0.3"');
|
||||
});
|
||||
});
|
||||
|
||||
group('where no hosted version of that dependency exists', () {
|
||||
group('where no hosted version exists', () {
|
||||
integration("and should use the other source's version", () {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
|
||||
return new Future.immediate(new http.Response("not found", 404));
|
||||
}));
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [
|
||||
{
|
||||
'git': {'url': 'git://github.com/dart-lang/foo'},
|
||||
'version': '>=1.0.0 <2.0.0'
|
||||
}
|
||||
])
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=1.0.0 <2.0.0"'))));
|
||||
setUpDependency({
|
||||
'git': 'git://github.com/dart-lang/foo',
|
||||
'version': '>=1.0.0 <2.0.0'
|
||||
});
|
||||
expectDependencyValidationWarning(' foo: ">=1.0.0 <2.0.0"');
|
||||
});
|
||||
|
||||
integration("and should use the other source's unquoted version if "
|
||||
"it's concrete", () {
|
||||
useMockClient(new MockClient((request) {
|
||||
expect(request.method, equals("GET"));
|
||||
expect(request.url.path, equals("/packages/foo.json"));
|
||||
"concrete", () {
|
||||
setUpDependency({
|
||||
'git': 'git://github.com/dart-lang/foo',
|
||||
'version': '0.2.3'
|
||||
});
|
||||
expectDependencyValidationWarning(' foo: 0.2.3');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return new Future.immediate(new http.Response("not found", 404));
|
||||
}));
|
||||
group('has a path dependency', () {
|
||||
group('where a hosted version exists', () {
|
||||
integration("and should suggest the hosted primary version", () {
|
||||
setUpDependency({'path': path.join(sandboxDir, 'foo')},
|
||||
hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]);
|
||||
expectDependencyValidationError(' foo: ">=2.0.0 <3.0.0"');
|
||||
});
|
||||
|
||||
dir(appPath, [
|
||||
libPubspec("test_pkg", "1.0.0", deps: [
|
||||
{
|
||||
'git': {'url': 'git://github.com/dart-lang/foo'},
|
||||
'version': '0.2.3'
|
||||
}
|
||||
])
|
||||
]).scheduleCreate();
|
||||
integration("and should suggest the hosted prerelease version if "
|
||||
"it's the only version available", () {
|
||||
setUpDependency({'path': path.join(sandboxDir, 'foo')},
|
||||
hostedVersions: ["3.0.0-pre", "2.0.0-pre"]);
|
||||
expectDependencyValidationError(' foo: ">=3.0.0-pre <4.0.0"');
|
||||
});
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(' foo: 0.2.3'))));
|
||||
integration("and should suggest a tighter constraint if primary is "
|
||||
"pre-1.0.0", () {
|
||||
setUpDependency({'path': path.join(sandboxDir, 'foo')},
|
||||
hostedVersions: ["0.0.1", "0.0.2"]);
|
||||
expectDependencyValidationError(' foo: ">=0.0.2 <0.0.3"');
|
||||
});
|
||||
});
|
||||
|
||||
group('where no hosted version exists', () {
|
||||
integration("and should use the other source's version", () {
|
||||
setUpDependency({
|
||||
'path': path.join(sandboxDir, 'foo'),
|
||||
'version': '>=1.0.0 <2.0.0'
|
||||
});
|
||||
expectDependencyValidationError(' foo: ">=1.0.0 <2.0.0"');
|
||||
});
|
||||
|
||||
integration("and should use the other source's unquoted version if "
|
||||
"concrete", () {
|
||||
setUpDependency({
|
||||
'path': path.join(sandboxDir, 'foo'),
|
||||
'version': '0.2.3'
|
||||
});
|
||||
expectDependencyValidationError(' foo: 0.2.3');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -507,9 +506,7 @@ main() {
|
|||
}))
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=1.2.3 <2.0.0"'))));
|
||||
expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"');
|
||||
});
|
||||
|
||||
integration('and it should suggest a concrete constraint if the locked '
|
||||
|
@ -532,9 +529,7 @@ main() {
|
|||
}))
|
||||
]).scheduleCreate();
|
||||
|
||||
expectLater(schedulePackageValidation(dependency),
|
||||
pairOf(isEmpty, someElement(contains(
|
||||
' foo: ">=0.1.2 <0.1.3"'))));
|
||||
expectDependencyValidationWarning(' foo: ">=0.1.2 <0.1.3"');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue