| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import 'dart:async'; | 1 import 'dart:async'; |
| 6 import 'dart:convert'; | 2 import 'dart:convert'; |
| 7 | |
| 8 import 'package:http/http.dart' as http; | 3 import 'package:http/http.dart' as http; |
| 9 import 'package:http/testing.dart'; | 4 import 'package:http/testing.dart'; |
| 10 import 'package:path/path.dart' as path; | 5 import 'package:path/path.dart' as path; |
| 11 import 'package:scheduled_test/scheduled_test.dart'; | 6 import 'package:scheduled_test/scheduled_test.dart'; |
| 12 | |
| 13 import '../../lib/src/entrypoint.dart'; | 7 import '../../lib/src/entrypoint.dart'; |
| 14 import '../../lib/src/validator.dart'; | 8 import '../../lib/src/validator.dart'; |
| 15 import '../../lib/src/validator/dependency.dart'; | 9 import '../../lib/src/validator/dependency.dart'; |
| 16 import '../descriptor.dart' as d; | 10 import '../descriptor.dart' as d; |
| 17 import '../test_pub.dart'; | 11 import '../test_pub.dart'; |
| 18 import 'utils.dart'; | 12 import 'utils.dart'; |
| 19 | |
| 20 Validator dependency(Entrypoint entrypoint) => | 13 Validator dependency(Entrypoint entrypoint) => |
| 21 new DependencyValidator(entrypoint); | 14 new DependencyValidator(entrypoint); |
| 22 | |
| 23 expectDependencyValidationError(String error) { | 15 expectDependencyValidationError(String error) { |
| 24 expect(schedulePackageValidation(dependency), | 16 expect( |
| 17 schedulePackageValidation(dependency), |
| 25 completion(pairOf(anyElement(contains(error)), isEmpty))); | 18 completion(pairOf(anyElement(contains(error)), isEmpty))); |
| 26 } | 19 } |
| 27 | |
| 28 expectDependencyValidationWarning(String warning) { | 20 expectDependencyValidationWarning(String warning) { |
| 29 expect(schedulePackageValidation(dependency), | 21 expect( |
| 22 schedulePackageValidation(dependency), |
| 30 completion(pairOf(isEmpty, anyElement(contains(warning))))); | 23 completion(pairOf(isEmpty, anyElement(contains(warning))))); |
| 31 } | 24 } |
| 32 | |
| 33 /// Sets up a test package with dependency [dep] and mocks a server with | |
| 34 /// [hostedVersions] of the package available. | |
| 35 setUpDependency(Map dep, {List<String> hostedVersions}) { | 25 setUpDependency(Map dep, {List<String> hostedVersions}) { |
| 36 useMockClient(new MockClient((request) { | 26 useMockClient(new MockClient((request) { |
| 37 expect(request.method, equals("GET")); | 27 expect(request.method, equals("GET")); |
| 38 expect(request.url.path, equals("/api/packages/foo")); | 28 expect(request.url.path, equals("/api/packages/foo")); |
| 39 | |
| 40 if (hostedVersions == null) { | 29 if (hostedVersions == null) { |
| 41 return new Future.value(new http.Response("not found", 404)); | 30 return new Future.value(new http.Response("not found", 404)); |
| 42 } else { | 31 } else { |
| 43 return new Future.value(new http.Response(JSON.encode({ | 32 return new Future.value(new http.Response(JSON.encode({ |
| 44 "name": "foo", | 33 "name": "foo", |
| 45 "uploaders": ["nweiz@google.com"], | 34 "uploaders": ["nweiz@google.com"], |
| 46 "versions": hostedVersions.map((version) => | 35 "versions": hostedVersions.map( |
| 47 packageVersionApiMap(packageMap('foo', version))).toList() | 36 (version) => packageVersionApiMap(packageMap('foo', version))).toLis
t() |
| 48 }), 200)); | 37 }), 200)); |
| 49 } | 38 } |
| 50 })); | 39 })); |
| 51 | 40 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 52 d.dir(appPath, [ | 41 "foo": dep |
| 53 d.libPubspec("test_pkg", "1.0.0", deps: {"foo": dep}) | 42 })]).create(); |
| 54 ]).create(); | |
| 55 } | 43 } |
| 56 | |
| 57 main() { | 44 main() { |
| 58 initConfig(); | 45 initConfig(); |
| 59 | |
| 60 integration('should consider a package valid if it looks normal', () { | 46 integration('should consider a package valid if it looks normal', () { |
| 61 d.validPackage.create(); | 47 d.validPackage.create(); |
| 62 expectNoValidationError(dependency); | 48 expectNoValidationError(dependency); |
| 63 }); | 49 }); |
| 64 | |
| 65 group('should consider a package invalid if it', () { | 50 group('should consider a package invalid if it', () { |
| 66 setUp(d.validPackage.create); | 51 setUp(d.validPackage.create); |
| 67 | |
| 68 group('has a git dependency', () { | 52 group('has a git dependency', () { |
| 69 group('where a hosted version exists', () { | 53 group('where a hosted version exists', () { |
| 70 integration("and should suggest the hosted primary version", () { | 54 integration("and should suggest the hosted primary version", () { |
| 71 setUpDependency({'git': 'git://github.com/dart-lang/foo'}, | 55 setUpDependency({ |
| 72 hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]); | 56 'git': 'git://github.com/dart-lang/foo' |
| 57 }, hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]); |
| 73 expectDependencyValidationWarning(' foo: ">=2.0.0 <3.0.0"'); | 58 expectDependencyValidationWarning(' foo: ">=2.0.0 <3.0.0"'); |
| 74 }); | 59 }); |
| 75 | 60 integration( |
| 76 integration("and should suggest the hosted prerelease version if " | 61 "and should suggest the hosted prerelease version if " |
| 77 "it's the only version available", () { | 62 "it's the only version available", |
| 78 setUpDependency({'git': 'git://github.com/dart-lang/foo'}, | 63 () { |
| 79 hostedVersions: ["3.0.0-pre", "2.0.0-pre"]); | 64 setUpDependency({ |
| 65 'git': 'git://github.com/dart-lang/foo' |
| 66 }, hostedVersions: ["3.0.0-pre", "2.0.0-pre"]); |
| 80 expectDependencyValidationWarning(' foo: ">=3.0.0-pre <4.0.0"'); | 67 expectDependencyValidationWarning(' foo: ">=3.0.0-pre <4.0.0"'); |
| 81 }); | 68 }); |
| 82 | 69 integration( |
| 83 integration("and should suggest a tighter constraint if primary is " | 70 "and should suggest a tighter constraint if primary is " "pre-1.0.0"
, |
| 84 "pre-1.0.0", () { | 71 () { |
| 85 setUpDependency({'git': 'git://github.com/dart-lang/foo'}, | 72 setUpDependency({ |
| 86 hostedVersions: ["0.0.1", "0.0.2"]); | 73 'git': 'git://github.com/dart-lang/foo' |
| 74 }, hostedVersions: ["0.0.1", "0.0.2"]); |
| 87 expectDependencyValidationWarning(' foo: ">=0.0.2 <0.1.0"'); | 75 expectDependencyValidationWarning(' foo: ">=0.0.2 <0.1.0"'); |
| 88 }); | 76 }); |
| 89 }); | 77 }); |
| 90 | |
| 91 group('where no hosted version exists', () { | 78 group('where no hosted version exists', () { |
| 92 integration("and should use the other source's version", () { | 79 integration("and should use the other source's version", () { |
| 93 setUpDependency({ | 80 setUpDependency({ |
| 94 'git': 'git://github.com/dart-lang/foo', | 81 'git': 'git://github.com/dart-lang/foo', |
| 95 'version': '>=1.0.0 <2.0.0' | 82 'version': '>=1.0.0 <2.0.0' |
| 96 }); | 83 }); |
| 97 expectDependencyValidationWarning(' foo: ">=1.0.0 <2.0.0"'); | 84 expectDependencyValidationWarning(' foo: ">=1.0.0 <2.0.0"'); |
| 98 }); | 85 }); |
| 99 | 86 integration( |
| 100 integration("and should use the other source's unquoted version if " | 87 "and should use the other source's unquoted version if " "concrete", |
| 101 "concrete", () { | 88 () { |
| 102 setUpDependency({ | 89 setUpDependency({ |
| 103 'git': 'git://github.com/dart-lang/foo', | 90 'git': 'git://github.com/dart-lang/foo', |
| 104 'version': '0.2.3' | 91 'version': '0.2.3' |
| 105 }); | 92 }); |
| 106 expectDependencyValidationWarning(' foo: 0.2.3'); | 93 expectDependencyValidationWarning(' foo: 0.2.3'); |
| 107 }); | 94 }); |
| 108 }); | 95 }); |
| 109 }); | 96 }); |
| 110 | |
| 111 group('has a path dependency', () { | 97 group('has a path dependency', () { |
| 112 group('where a hosted version exists', () { | 98 group('where a hosted version exists', () { |
| 113 integration("and should suggest the hosted primary version", () { | 99 integration("and should suggest the hosted primary version", () { |
| 114 setUpDependency({'path': path.join(sandboxDir, 'foo')}, | 100 setUpDependency({ |
| 115 hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]); | 101 'path': path.join(sandboxDir, 'foo') |
| 102 }, hostedVersions: ["3.0.0-pre", "2.0.0", "1.0.0"]); |
| 116 expectDependencyValidationError(' foo: ">=2.0.0 <3.0.0"'); | 103 expectDependencyValidationError(' foo: ">=2.0.0 <3.0.0"'); |
| 117 }); | 104 }); |
| 118 | 105 integration( |
| 119 integration("and should suggest the hosted prerelease version if " | 106 "and should suggest the hosted prerelease version if " |
| 120 "it's the only version available", () { | 107 "it's the only version available", |
| 121 setUpDependency({'path': path.join(sandboxDir, 'foo')}, | 108 () { |
| 122 hostedVersions: ["3.0.0-pre", "2.0.0-pre"]); | 109 setUpDependency({ |
| 110 'path': path.join(sandboxDir, 'foo') |
| 111 }, hostedVersions: ["3.0.0-pre", "2.0.0-pre"]); |
| 123 expectDependencyValidationError(' foo: ">=3.0.0-pre <4.0.0"'); | 112 expectDependencyValidationError(' foo: ">=3.0.0-pre <4.0.0"'); |
| 124 }); | 113 }); |
| 125 | 114 integration( |
| 126 integration("and should suggest a tighter constraint if primary is " | 115 "and should suggest a tighter constraint if primary is " "pre-1.0.0"
, |
| 127 "pre-1.0.0", () { | 116 () { |
| 128 setUpDependency({'path': path.join(sandboxDir, 'foo')}, | 117 setUpDependency({ |
| 129 hostedVersions: ["0.0.1", "0.0.2"]); | 118 'path': path.join(sandboxDir, 'foo') |
| 119 }, hostedVersions: ["0.0.1", "0.0.2"]); |
| 130 expectDependencyValidationError(' foo: ">=0.0.2 <0.1.0"'); | 120 expectDependencyValidationError(' foo: ">=0.0.2 <0.1.0"'); |
| 131 }); | 121 }); |
| 132 }); | 122 }); |
| 133 | |
| 134 group('where no hosted version exists', () { | 123 group('where no hosted version exists', () { |
| 135 integration("and should use the other source's version", () { | 124 integration("and should use the other source's version", () { |
| 136 setUpDependency({ | 125 setUpDependency({ |
| 137 'path': path.join(sandboxDir, 'foo'), | 126 'path': path.join(sandboxDir, 'foo'), |
| 138 'version': '>=1.0.0 <2.0.0' | 127 'version': '>=1.0.0 <2.0.0' |
| 139 }); | 128 }); |
| 140 expectDependencyValidationError(' foo: ">=1.0.0 <2.0.0"'); | 129 expectDependencyValidationError(' foo: ">=1.0.0 <2.0.0"'); |
| 141 }); | 130 }); |
| 142 | 131 integration( |
| 143 integration("and should use the other source's unquoted version if " | 132 "and should use the other source's unquoted version if " "concrete", |
| 144 "concrete", () { | 133 () { |
| 145 setUpDependency({ | 134 setUpDependency({ |
| 146 'path': path.join(sandboxDir, 'foo'), | 135 'path': path.join(sandboxDir, 'foo'), |
| 147 'version': '0.2.3' | 136 'version': '0.2.3' |
| 148 }); | 137 }); |
| 149 expectDependencyValidationError(' foo: 0.2.3'); | 138 expectDependencyValidationError(' foo: 0.2.3'); |
| 150 }); | 139 }); |
| 151 }); | 140 }); |
| 152 }); | 141 }); |
| 153 | |
| 154 group('has an unconstrained dependency', () { | 142 group('has an unconstrained dependency', () { |
| 155 group('and it should not suggest a version', () { | 143 group('and it should not suggest a version', () { |
| 156 integration("if there's no lockfile", () { | 144 integration("if there's no lockfile", () { |
| 157 d.dir(appPath, [ | 145 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 158 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 159 "foo": "any" | 146 "foo": "any" |
| 160 }) | 147 })]).create(); |
| 161 ]).create(); | 148 expect( |
| 162 | 149 schedulePackageValidation(dependency), |
| 163 expect(schedulePackageValidation(dependency), completion( | 150 completion(pairOf(isEmpty, everyElement(isNot(contains("\n foo:")
))))); |
| 164 pairOf(isEmpty, everyElement(isNot(contains("\n foo:")))))); | |
| 165 }); | 151 }); |
| 166 | 152 integration( |
| 167 integration("if the lockfile doesn't have an entry for the " | 153 "if the lockfile doesn't have an entry for the " "dependency", |
| 168 "dependency", () { | 154 () { |
| 169 d.dir(appPath, [ | 155 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 170 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 171 "foo": "any" | 156 "foo": "any" |
| 172 }), | 157 }), d.file("pubspec.lock", JSON.encode({ |
| 173 d.file("pubspec.lock", JSON.encode({ | |
| 174 'packages': { | 158 'packages': { |
| 175 'bar': { | 159 'bar': { |
| 176 'version': '1.2.3', | 160 'version': '1.2.3', |
| 177 'source': 'hosted', | 161 'source': 'hosted', |
| 178 'description': { | 162 'description': { |
| 179 'name': 'bar', | 163 'name': 'bar', |
| 180 'url': 'http://pub.dartlang.org' | 164 'url': 'http://pub.dartlang.org' |
| 181 } | 165 } |
| 182 } | 166 } |
| 183 } | 167 } |
| 184 })) | 168 }))]).create(); |
| 185 ]).create(); | 169 expect( |
| 186 | 170 schedulePackageValidation(dependency), |
| 187 expect(schedulePackageValidation(dependency), completion( | 171 completion(pairOf(isEmpty, everyElement(isNot(contains("\n foo:")
))))); |
| 188 pairOf(isEmpty, everyElement(isNot(contains("\n foo:")))))); | |
| 189 }); | 172 }); |
| 190 }); | 173 }); |
| 191 | |
| 192 group('with a lockfile', () { | 174 group('with a lockfile', () { |
| 193 integration('and it should suggest a constraint based on the locked ' | 175 integration( |
| 194 'version', () { | 176 'and it should suggest a constraint based on the locked ' 'version', |
| 195 d.dir(appPath, [ | 177 () { |
| 196 d.libPubspec("test_pkg", "1.0.0", deps: { | 178 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 197 "foo": "any" | 179 "foo": "any" |
| 198 }), | 180 }), d.file("pubspec.lock", JSON.encode({ |
| 199 d.file("pubspec.lock", JSON.encode({ | |
| 200 'packages': { | 181 'packages': { |
| 201 'foo': { | 182 'foo': { |
| 202 'version': '1.2.3', | 183 'version': '1.2.3', |
| 203 'source': 'hosted', | 184 'source': 'hosted', |
| 204 'description': { | 185 'description': { |
| 205 'name': 'foo', | 186 'name': 'foo', |
| 206 'url': 'http://pub.dartlang.org' | 187 'url': 'http://pub.dartlang.org' |
| 207 } | 188 } |
| 208 } | 189 } |
| 209 } | 190 } |
| 210 })) | 191 }))]).create(); |
| 211 ]).create(); | |
| 212 | |
| 213 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); | 192 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); |
| 214 }); | 193 }); |
| 215 | 194 integration( |
| 216 integration('and it should suggest a concrete constraint if the locked ' | 195 'and it should suggest a concrete constraint if the locked ' |
| 217 'version is pre-1.0.0', () { | 196 'version is pre-1.0.0', |
| 218 d.dir(appPath, [ | 197 () { |
| 219 d.libPubspec("test_pkg", "1.0.0", deps: { | 198 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 220 "foo": "any" | 199 "foo": "any" |
| 221 }), | 200 }), d.file("pubspec.lock", JSON.encode({ |
| 222 d.file("pubspec.lock", JSON.encode({ | |
| 223 'packages': { | 201 'packages': { |
| 224 'foo': { | 202 'foo': { |
| 225 'version': '0.1.2', | 203 'version': '0.1.2', |
| 226 'source': 'hosted', | 204 'source': 'hosted', |
| 227 'description': { | 205 'description': { |
| 228 'name': 'foo', | 206 'name': 'foo', |
| 229 'url': 'http://pub.dartlang.org' | 207 'url': 'http://pub.dartlang.org' |
| 230 } | 208 } |
| 231 } | 209 } |
| 232 } | 210 } |
| 233 })) | 211 }))]).create(); |
| 234 ]).create(); | |
| 235 | |
| 236 expectDependencyValidationWarning(' foo: ">=0.1.2 <0.2.0"'); | 212 expectDependencyValidationWarning(' foo: ">=0.1.2 <0.2.0"'); |
| 237 }); | 213 }); |
| 238 }); | 214 }); |
| 239 }); | 215 }); |
| 240 | 216 integration( |
| 241 integration('with a single-version dependency and it should suggest a ' | 217 'with a single-version dependency and it should suggest a ' |
| 242 'constraint based on the version', () { | 218 'constraint based on the version', |
| 243 d.dir(appPath, [ | 219 () { |
| 244 d.libPubspec("test_pkg", "1.0.0", deps: { | 220 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 245 "foo": "1.2.3" | 221 "foo": "1.2.3" |
| 246 }) | 222 })]).create(); |
| 247 ]).create(); | |
| 248 | |
| 249 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); | 223 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); |
| 250 }); | 224 }); |
| 251 | |
| 252 group('has a dependency without a lower bound', () { | 225 group('has a dependency without a lower bound', () { |
| 253 group('and it should not suggest a version', () { | 226 group('and it should not suggest a version', () { |
| 254 integration("if there's no lockfile", () { | 227 integration("if there's no lockfile", () { |
| 255 d.dir(appPath, [ | 228 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 256 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 257 "foo": "<3.0.0" | 229 "foo": "<3.0.0" |
| 258 }) | 230 })]).create(); |
| 259 ]).create(); | 231 expect( |
| 260 | 232 schedulePackageValidation(dependency), |
| 261 expect(schedulePackageValidation(dependency), completion( | 233 completion(pairOf(isEmpty, everyElement(isNot(contains("\n foo:")
))))); |
| 262 pairOf(isEmpty, everyElement(isNot(contains("\n foo:")))))); | |
| 263 }); | 234 }); |
| 264 | 235 integration( |
| 265 integration("if the lockfile doesn't have an entry for the " | 236 "if the lockfile doesn't have an entry for the " "dependency", |
| 266 "dependency", () { | 237 () { |
| 267 d.dir(appPath, [ | 238 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 268 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 269 "foo": "<3.0.0" | 239 "foo": "<3.0.0" |
| 270 }), | 240 }), d.file("pubspec.lock", JSON.encode({ |
| 271 d.file("pubspec.lock", JSON.encode({ | |
| 272 'packages': { | 241 'packages': { |
| 273 'bar': { | 242 'bar': { |
| 274 'version': '1.2.3', | 243 'version': '1.2.3', |
| 275 'source': 'hosted', | 244 'source': 'hosted', |
| 276 'description': { | 245 'description': { |
| 277 'name': 'bar', | 246 'name': 'bar', |
| 278 'url': 'http://pub.dartlang.org' | 247 'url': 'http://pub.dartlang.org' |
| 279 } | 248 } |
| 280 } | 249 } |
| 281 } | 250 } |
| 282 })) | 251 }))]).create(); |
| 283 ]).create(); | 252 expect( |
| 284 | 253 schedulePackageValidation(dependency), |
| 285 expect(schedulePackageValidation(dependency), completion( | 254 completion(pairOf(isEmpty, everyElement(isNot(contains("\n foo:")
))))); |
| 286 pairOf(isEmpty, everyElement(isNot(contains("\n foo:")))))); | |
| 287 }); | 255 }); |
| 288 }); | 256 }); |
| 289 | |
| 290 group('with a lockfile', () { | 257 group('with a lockfile', () { |
| 291 integration('and it should suggest a constraint based on the locked ' | 258 integration( |
| 292 'version', () { | 259 'and it should suggest a constraint based on the locked ' 'version', |
| 293 d.dir(appPath, [ | 260 () { |
| 294 d.libPubspec("test_pkg", "1.0.0", deps: { | 261 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 295 "foo": "<3.0.0" | 262 "foo": "<3.0.0" |
| 296 }), | 263 }), d.file("pubspec.lock", JSON.encode({ |
| 297 d.file("pubspec.lock", JSON.encode({ | |
| 298 'packages': { | 264 'packages': { |
| 299 'foo': { | 265 'foo': { |
| 300 'version': '1.2.3', | 266 'version': '1.2.3', |
| 301 'source': 'hosted', | 267 'source': 'hosted', |
| 302 'description': { | 268 'description': { |
| 303 'name': 'foo', | 269 'name': 'foo', |
| 304 'url': 'http://pub.dartlang.org' | 270 'url': 'http://pub.dartlang.org' |
| 305 } | 271 } |
| 306 } | 272 } |
| 307 } | 273 } |
| 308 })) | 274 }))]).create(); |
| 309 ]).create(); | |
| 310 | |
| 311 expectDependencyValidationWarning(' foo: ">=1.2.3 <3.0.0"'); | 275 expectDependencyValidationWarning(' foo: ">=1.2.3 <3.0.0"'); |
| 312 }); | 276 }); |
| 313 | |
| 314 integration('and it should preserve the upper-bound operator', () { | 277 integration('and it should preserve the upper-bound operator', () { |
| 315 d.dir(appPath, [ | 278 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 316 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 317 "foo": "<=3.0.0" | 279 "foo": "<=3.0.0" |
| 318 }), | 280 }), d.file("pubspec.lock", JSON.encode({ |
| 319 d.file("pubspec.lock", JSON.encode({ | |
| 320 'packages': { | 281 'packages': { |
| 321 'foo': { | 282 'foo': { |
| 322 'version': '1.2.3', | 283 'version': '1.2.3', |
| 323 'source': 'hosted', | 284 'source': 'hosted', |
| 324 'description': { | 285 'description': { |
| 325 'name': 'foo', | 286 'name': 'foo', |
| 326 'url': 'http://pub.dartlang.org' | 287 'url': 'http://pub.dartlang.org' |
| 327 } | 288 } |
| 328 } | 289 } |
| 329 } | 290 } |
| 330 })) | 291 }))]).create(); |
| 331 ]).create(); | |
| 332 | |
| 333 expectDependencyValidationWarning(' foo: ">=1.2.3 <=3.0.0"'); | 292 expectDependencyValidationWarning(' foo: ">=1.2.3 <=3.0.0"'); |
| 334 }); | 293 }); |
| 335 | 294 integration( |
| 336 integration('and it should expand the suggested constraint if the ' | 295 'and it should expand the suggested constraint if the ' |
| 337 'locked version matches the upper bound', () { | 296 'locked version matches the upper bound', |
| 338 d.dir(appPath, [ | 297 () { |
| 339 d.libPubspec("test_pkg", "1.0.0", deps: { | 298 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 340 "foo": "<=1.2.3" | 299 "foo": "<=1.2.3" |
| 341 }), | 300 }), d.file("pubspec.lock", JSON.encode({ |
| 342 d.file("pubspec.lock", JSON.encode({ | |
| 343 'packages': { | 301 'packages': { |
| 344 'foo': { | 302 'foo': { |
| 345 'version': '1.2.3', | 303 'version': '1.2.3', |
| 346 'source': 'hosted', | 304 'source': 'hosted', |
| 347 'description': { | 305 'description': { |
| 348 'name': 'foo', | 306 'name': 'foo', |
| 349 'url': 'http://pub.dartlang.org' | 307 'url': 'http://pub.dartlang.org' |
| 350 } | 308 } |
| 351 } | 309 } |
| 352 } | 310 } |
| 353 })) | 311 }))]).create(); |
| 354 ]).create(); | |
| 355 | |
| 356 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); | 312 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); |
| 357 }); | 313 }); |
| 358 }); | 314 }); |
| 359 }); | 315 }); |
| 360 | |
| 361 group('with a dependency without an upper bound', () { | 316 group('with a dependency without an upper bound', () { |
| 362 integration('and it should suggest a constraint based on the lower bound', | 317 integration( |
| 318 'and it should suggest a constraint based on the lower bound', |
| 363 () { | 319 () { |
| 364 d.dir(appPath, [ | 320 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 365 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 366 "foo": ">=1.2.3" | 321 "foo": ">=1.2.3" |
| 367 }) | 322 })]).create(); |
| 368 ]).create(); | |
| 369 | |
| 370 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); | 323 expectDependencyValidationWarning(' foo: ">=1.2.3 <2.0.0"'); |
| 371 }); | 324 }); |
| 372 | |
| 373 integration('and it should preserve the lower-bound operator', () { | 325 integration('and it should preserve the lower-bound operator', () { |
| 374 d.dir(appPath, [ | 326 d.dir(appPath, [d.libPubspec("test_pkg", "1.0.0", deps: { |
| 375 d.libPubspec("test_pkg", "1.0.0", deps: { | |
| 376 "foo": ">1.2.3" | 327 "foo": ">1.2.3" |
| 377 }) | 328 })]).create(); |
| 378 ]).create(); | |
| 379 | |
| 380 expectDependencyValidationWarning(' foo: ">1.2.3 <2.0.0"'); | 329 expectDependencyValidationWarning(' foo: ">1.2.3 <2.0.0"'); |
| 381 }); | 330 }); |
| 382 }); | 331 }); |
| 383 }); | 332 }); |
| 384 } | 333 } |
| OLD | NEW |