| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, 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 library version_test; | |
| 6 | |
| 7 import 'package:unittest/unittest.dart'; | |
| 8 import 'test_pub.dart'; | |
| 9 import '../../pub/utils.dart'; | |
| 10 import '../../pub/version.dart'; | |
| 11 | |
| 12 main() { | |
| 13 initConfig(); | |
| 14 | |
| 15 final v123 = new Version.parse('1.2.3'); | |
| 16 final v114 = new Version.parse('1.1.4'); | |
| 17 final v124 = new Version.parse('1.2.4'); | |
| 18 final v200 = new Version.parse('2.0.0'); | |
| 19 final v234 = new Version.parse('2.3.4'); | |
| 20 final v250 = new Version.parse('2.5.0'); | |
| 21 final v300 = new Version.parse('3.0.0'); | |
| 22 | |
| 23 group('Version', () { | |
| 24 test('none', () { | |
| 25 expect(Version.none.toString(), equals('0.0.0')); | |
| 26 }); | |
| 27 | |
| 28 group('constructor', () { | |
| 29 test('throws on negative numbers', () { | |
| 30 throwsIllegalArg(() => new Version(-1, 1, 1)); | |
| 31 throwsIllegalArg(() => new Version(1, -1, 1)); | |
| 32 throwsIllegalArg(() => new Version(1, 1, -1)); | |
| 33 }); | |
| 34 }); | |
| 35 | |
| 36 group('comparison', () { | |
| 37 // A correctly sorted list of versions. | |
| 38 var versions = [ | |
| 39 '1.0.0-alpha', | |
| 40 '1.0.0-alpha.1', | |
| 41 '1.0.0-beta.2', | |
| 42 '1.0.0-beta.11', | |
| 43 '1.0.0-rc.1', | |
| 44 '1.0.0-rc.1+build.1', | |
| 45 '1.0.0', | |
| 46 '1.0.0+0.3.7', | |
| 47 '1.3.7+build', | |
| 48 '1.3.7+build.2.b8f12d7', | |
| 49 '1.3.7+build.11.e0f985a', | |
| 50 '2.0.0', | |
| 51 '2.1.0', | |
| 52 '2.2.0', | |
| 53 '2.11.0', | |
| 54 '2.11.1' | |
| 55 ]; | |
| 56 | |
| 57 test('compareTo()', () { | |
| 58 // Ensure that every pair of versions compares in the order that it | |
| 59 // appears in the list. | |
| 60 for (var i = 0; i < versions.length; i++) { | |
| 61 for (var j = 0; j < versions.length; j++) { | |
| 62 var a = new Version.parse(versions[i]); | |
| 63 var b = new Version.parse(versions[j]); | |
| 64 var expectation = i.compareTo(j); | |
| 65 expect(a.compareTo(b), equals(expectation)); | |
| 66 } | |
| 67 } | |
| 68 }); | |
| 69 | |
| 70 test('operators', () { | |
| 71 for (var i = 0; i < versions.length; i++) { | |
| 72 for (var j = 0; j < versions.length; j++) { | |
| 73 var a = new Version.parse(versions[i]); | |
| 74 var b = new Version.parse(versions[j]); | |
| 75 expect(a < b, equals(i < j)); | |
| 76 expect(a > b, equals(i > j)); | |
| 77 expect(a <= b, equals(i <= j)); | |
| 78 expect(a >= b, equals(i >= j)); | |
| 79 expect(a == b, equals(i == j)); | |
| 80 expect(a != b, equals(i != j)); | |
| 81 } | |
| 82 } | |
| 83 }); | |
| 84 }); | |
| 85 | |
| 86 test('allows()', () { | |
| 87 expect(v123.allows(v123), isTrue); | |
| 88 expect(v123.allows(v114), isFalse); | |
| 89 expect(v123.allows(v124), isFalse); | |
| 90 }); | |
| 91 | |
| 92 test('intersect()', () { | |
| 93 // Intersecting the same version returns the version. | |
| 94 expect(v123.intersect(v123), equals(v123)); | |
| 95 | |
| 96 // Intersecting a different version allows no versions. | |
| 97 expect(v123.intersect(v114).isEmpty, isTrue); | |
| 98 | |
| 99 // Intersecting a range returns the version if the range allows it. | |
| 100 expect(v123.intersect(new VersionRange(min: v114, max: v124)), | |
| 101 equals(v123)); | |
| 102 | |
| 103 // Intersecting a range allows no versions if the range doesn't allow it. | |
| 104 expect(v114.intersect(new VersionRange(min: v123, max: v124)).isEmpty, | |
| 105 isTrue); | |
| 106 }); | |
| 107 | |
| 108 test('isEmpty', () { | |
| 109 expect(v123.isEmpty, isFalse); | |
| 110 }); | |
| 111 | |
| 112 test('parse()', () { | |
| 113 expect(new Version.parse('0.0.0'), equals(new Version(0, 0, 0))); | |
| 114 expect(new Version.parse('12.34.56'), equals(new Version(12, 34, 56))); | |
| 115 | |
| 116 expect(new Version.parse('1.2.3-alpha.1'), equals( | |
| 117 new Version(1, 2, 3, pre: 'alpha.1'))); | |
| 118 expect(new Version.parse('1.2.3-x.7.z-92'), equals( | |
| 119 new Version(1, 2, 3, pre: 'x.7.z-92'))); | |
| 120 | |
| 121 expect(new Version.parse('1.2.3+build.1'), equals( | |
| 122 new Version(1, 2, 3, build: 'build.1'))); | |
| 123 expect(new Version.parse('1.2.3+x.7.z-92'), equals( | |
| 124 new Version(1, 2, 3, build: 'x.7.z-92'))); | |
| 125 | |
| 126 expect(new Version.parse('1.0.0-rc-1+build-1'), equals( | |
| 127 new Version(1, 0, 0, pre: 'rc-1', build: 'build-1'))); | |
| 128 | |
| 129 expect(() => new Version.parse('1.0'), throwsFormatException); | |
| 130 expect(() => new Version.parse('1.2.3.4'), throwsFormatException); | |
| 131 expect(() => new Version.parse('1234'), throwsFormatException); | |
| 132 expect(() => new Version.parse('-2.3.4'), throwsFormatException); | |
| 133 expect(() => new Version.parse('1.3-pre'), throwsFormatException); | |
| 134 expect(() => new Version.parse('1.3+build'), throwsFormatException); | |
| 135 expect(() => new Version.parse('1.3+bu?!3ild'), throwsFormatException); | |
| 136 }); | |
| 137 | |
| 138 test('toString()', () { | |
| 139 expect(new Version(0, 0, 0).toString(), equals('0.0.0')); | |
| 140 expect(new Version(12, 34, 56).toString(), equals('12.34.56')); | |
| 141 | |
| 142 expect(new Version(1, 2, 3, pre: 'alpha.1').toString(), equals( | |
| 143 '1.2.3-alpha.1')); | |
| 144 expect(new Version(1, 2, 3, pre: 'x.7.z-92').toString(), equals( | |
| 145 '1.2.3-x.7.z-92')); | |
| 146 | |
| 147 expect(new Version(1, 2, 3, build: 'build.1').toString(), equals( | |
| 148 '1.2.3+build.1')); | |
| 149 expect(new Version(1, 2, 3, pre: 'pre', build: 'bui').toString(), equals( | |
| 150 '1.2.3-pre+bui')); | |
| 151 }); | |
| 152 }); | |
| 153 | |
| 154 group('VersionRange', () { | |
| 155 group('constructor', () { | |
| 156 test('takes a min and max', () { | |
| 157 var range = new VersionRange(min: v123, max: v124); | |
| 158 expect(range.min, equals(v123)); | |
| 159 expect(range.max, equals(v124)); | |
| 160 }); | |
| 161 | |
| 162 test('allows omitting max', () { | |
| 163 var range = new VersionRange(min: v123); | |
| 164 expect(range.min, equals(v123)); | |
| 165 expect(range.max, isNull); | |
| 166 }); | |
| 167 | |
| 168 test('allows omitting min and max', () { | |
| 169 var range = new VersionRange(); | |
| 170 expect(range.min, isNull); | |
| 171 expect(range.max, isNull); | |
| 172 }); | |
| 173 | |
| 174 test('takes includeMin', () { | |
| 175 var range = new VersionRange(min: v123, includeMin: true); | |
| 176 expect(range.includeMin, isTrue); | |
| 177 }); | |
| 178 | |
| 179 test('includeMin defaults to false if omitted', () { | |
| 180 var range = new VersionRange(min: v123); | |
| 181 expect(range.includeMin, isFalse); | |
| 182 }); | |
| 183 | |
| 184 test('takes includeMax', () { | |
| 185 var range = new VersionRange(max: v123, includeMax: true); | |
| 186 expect(range.includeMax, isTrue); | |
| 187 }); | |
| 188 | |
| 189 test('includeMax defaults to false if omitted', () { | |
| 190 var range = new VersionRange(max: v123); | |
| 191 expect(range.includeMax, isFalse); | |
| 192 }); | |
| 193 | |
| 194 test('throws if min > max', () { | |
| 195 throwsIllegalArg(() => new VersionRange(min: v124, max: v123)); | |
| 196 }); | |
| 197 }); | |
| 198 | |
| 199 group('allows()', () { | |
| 200 test('version must be greater than min', () { | |
| 201 var range = new VersionRange(min: v123, max: v234); | |
| 202 | |
| 203 expect(range.allows(new Version.parse('1.2.2')), isFalse); | |
| 204 expect(range.allows(new Version.parse('1.2.3')), isFalse); | |
| 205 expect(range.allows(new Version.parse('1.3.3')), isTrue); | |
| 206 expect(range.allows(new Version.parse('2.3.3')), isTrue); | |
| 207 }); | |
| 208 | |
| 209 test('version must be min or greater if includeMin', () { | |
| 210 var range = new VersionRange(min: v123, max: v234, includeMin: true); | |
| 211 | |
| 212 expect(range.allows(new Version.parse('1.2.2')), isFalse); | |
| 213 expect(range.allows(new Version.parse('1.2.3')), isTrue); | |
| 214 expect(range.allows(new Version.parse('1.3.3')), isTrue); | |
| 215 expect(range.allows(new Version.parse('2.3.3')), isTrue); | |
| 216 }); | |
| 217 | |
| 218 test('version must be less than max', () { | |
| 219 var range = new VersionRange(min: v123, max: v234); | |
| 220 | |
| 221 expect(range.allows(new Version.parse('2.3.3')), isTrue); | |
| 222 expect(range.allows(new Version.parse('2.3.4')), isFalse); | |
| 223 expect(range.allows(new Version.parse('2.4.3')), isFalse); | |
| 224 }); | |
| 225 | |
| 226 test('version must be max or less if includeMax', () { | |
| 227 var range = new VersionRange(min: v123, max: v234, includeMax: true); | |
| 228 | |
| 229 expect(range.allows(new Version.parse('2.3.3')), isTrue); | |
| 230 expect(range.allows(new Version.parse('2.3.4')), isTrue); | |
| 231 expect(range.allows(new Version.parse('2.4.3')), isFalse); | |
| 232 }); | |
| 233 | |
| 234 test('has no min if one was not set', () { | |
| 235 var range = new VersionRange(max: v123); | |
| 236 | |
| 237 expect(range.allows(new Version.parse('0.0.0')), isTrue); | |
| 238 expect(range.allows(new Version.parse('1.2.3')), isFalse); | |
| 239 }); | |
| 240 | |
| 241 test('has no max if one was not set', () { | |
| 242 var range = new VersionRange(min: v123); | |
| 243 | |
| 244 expect(range.allows(new Version.parse('1.2.3')), isFalse); | |
| 245 expect(range.allows(new Version.parse('1.3.3')), isTrue); | |
| 246 expect(range.allows(new Version.parse('999.3.3')), isTrue); | |
| 247 }); | |
| 248 | |
| 249 test('allows any version if there is no min or max', () { | |
| 250 var range = new VersionRange(); | |
| 251 | |
| 252 expect(range.allows(new Version.parse('0.0.0')), isTrue); | |
| 253 expect(range.allows(new Version.parse('999.99.9')), isTrue); | |
| 254 }); | |
| 255 }); | |
| 256 | |
| 257 group('intersect()', () { | |
| 258 test('two overlapping ranges', () { | |
| 259 var a = new VersionRange(min: v123, max: v250); | |
| 260 var b = new VersionRange(min: v200, max: v300); | |
| 261 var intersect = a.intersect(b); | |
| 262 expect(intersect.min, equals(v200)); | |
| 263 expect(intersect.max, equals(v250)); | |
| 264 expect(intersect.includeMin, isFalse); | |
| 265 expect(intersect.includeMax, isFalse); | |
| 266 }); | |
| 267 | |
| 268 test('a non-overlapping range allows no versions', () { | |
| 269 var a = new VersionRange(min: v114, max: v124); | |
| 270 var b = new VersionRange(min: v200, max: v250); | |
| 271 expect(a.intersect(b).isEmpty, isTrue); | |
| 272 }); | |
| 273 | |
| 274 test('adjacent ranges allow no versions if exclusive', () { | |
| 275 var a = new VersionRange(min: v114, max: v124, includeMax: false); | |
| 276 var b = new VersionRange(min: v124, max: v200, includeMin: true); | |
| 277 expect(a.intersect(b).isEmpty, isTrue); | |
| 278 }); | |
| 279 | |
| 280 test('adjacent ranges allow version if inclusive', () { | |
| 281 var a = new VersionRange(min: v114, max: v124, includeMax: true); | |
| 282 var b = new VersionRange(min: v124, max: v200, includeMin: true); | |
| 283 expect(a.intersect(b), equals(v124)); | |
| 284 }); | |
| 285 | |
| 286 test('with an open range', () { | |
| 287 var open = new VersionRange(); | |
| 288 var a = new VersionRange(min: v114, max: v124); | |
| 289 expect(open.intersect(open), equals(open)); | |
| 290 expect(a.intersect(open), equals(a)); | |
| 291 }); | |
| 292 | |
| 293 test('returns the version if the range allows it', () { | |
| 294 expect(new VersionRange(min: v114, max: v124).intersect(v123), | |
| 295 equals(v123)); | |
| 296 expect(new VersionRange(min: v123, max: v124).intersect(v114).isEmpty, | |
| 297 isTrue); | |
| 298 }); | |
| 299 }); | |
| 300 | |
| 301 test('isEmpty', () { | |
| 302 expect(new VersionRange().isEmpty, isFalse); | |
| 303 expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); | |
| 304 }); | |
| 305 }); | |
| 306 | |
| 307 group('VersionConstraint', () { | |
| 308 test('any', () { | |
| 309 expect(VersionConstraint.any.isAny, isTrue); | |
| 310 expect(VersionConstraint.any, allows([ | |
| 311 new Version.parse('0.0.0-blah'), | |
| 312 new Version.parse('1.2.3'), | |
| 313 new Version.parse('12345.678.90')])); | |
| 314 }); | |
| 315 | |
| 316 test('empty', () { | |
| 317 expect(VersionConstraint.empty.isEmpty, isTrue); | |
| 318 expect(VersionConstraint.empty, doesNotAllow([ | |
| 319 new Version.parse('0.0.0-blah'), | |
| 320 new Version.parse('1.2.3'), | |
| 321 new Version.parse('12345.678.90')])); | |
| 322 }); | |
| 323 | |
| 324 group('parse()', () { | |
| 325 test('parses an exact version', () { | |
| 326 var constraint = new VersionConstraint.parse('1.2.3-alpha'); | |
| 327 expect(constraint is Version, isTrue); | |
| 328 expect(constraint, equals(new Version(1, 2, 3, pre: 'alpha'))); | |
| 329 }); | |
| 330 | |
| 331 test('parses "any"', () { | |
| 332 var constraint = new VersionConstraint.parse('any'); | |
| 333 expect(constraint is VersionConstraint, isTrue); | |
| 334 expect(constraint, allows([ | |
| 335 new Version.parse('0.0.0'), | |
| 336 new Version.parse('1.2.3'), | |
| 337 new Version.parse('12345.678.90')])); | |
| 338 }); | |
| 339 | |
| 340 test('parses a ">" minimum version', () { | |
| 341 expect(new VersionConstraint.parse('>1.2.3'), allows([ | |
| 342 new Version.parse('1.2.3+foo'), | |
| 343 new Version.parse('1.2.4')])); | |
| 344 expect(new VersionConstraint.parse('>1.2.3'), doesNotAllow([ | |
| 345 new Version.parse('1.2.1'), | |
| 346 new Version.parse('1.2.3-build'), | |
| 347 new Version.parse('1.2.3')])); | |
| 348 }); | |
| 349 | |
| 350 test('parses a ">=" minimum version', () { | |
| 351 expect(new VersionConstraint.parse('>=1.2.3'), allows([ | |
| 352 new Version.parse('1.2.3'), | |
| 353 new Version.parse('1.2.3+foo'), | |
| 354 new Version.parse('1.2.4')])); | |
| 355 expect(new VersionConstraint.parse('>=1.2.3'), doesNotAllow([ | |
| 356 new Version.parse('1.2.1'), | |
| 357 new Version.parse('1.2.3-build')])); | |
| 358 }); | |
| 359 | |
| 360 test('parses a "<" maximum version', () { | |
| 361 expect(new VersionConstraint.parse('<1.2.3'), allows([ | |
| 362 new Version.parse('1.2.1'), | |
| 363 new Version.parse('1.2.3-build')])); | |
| 364 expect(new VersionConstraint.parse('<1.2.3'), doesNotAllow([ | |
| 365 new Version.parse('1.2.3'), | |
| 366 new Version.parse('1.2.3+foo'), | |
| 367 new Version.parse('1.2.4')])); | |
| 368 }); | |
| 369 | |
| 370 test('parses a "<=" maximum version', () { | |
| 371 expect(new VersionConstraint.parse('<=1.2.3'), allows([ | |
| 372 new Version.parse('1.2.1'), | |
| 373 new Version.parse('1.2.3-build'), | |
| 374 new Version.parse('1.2.3')])); | |
| 375 expect(new VersionConstraint.parse('<=1.2.3'), doesNotAllow([ | |
| 376 new Version.parse('1.2.3+foo'), | |
| 377 new Version.parse('1.2.4')])); | |
| 378 }); | |
| 379 | |
| 380 test('parses a series of space-separated constraints', () { | |
| 381 var constraint = new VersionConstraint.parse('>1.0.0 >=1.2.3 <1.3.0'); | |
| 382 expect(constraint, allows([ | |
| 383 new Version.parse('1.2.3'), | |
| 384 new Version.parse('1.2.5')])); | |
| 385 expect(constraint, doesNotAllow([ | |
| 386 new Version.parse('1.2.3-pre'), | |
| 387 new Version.parse('1.3.0'), | |
| 388 new Version.parse('3.4.5')])); | |
| 389 }); | |
| 390 | |
| 391 test('ignores whitespace around operators', () { | |
| 392 var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); | |
| 393 expect(constraint, allows([ | |
| 394 new Version.parse('1.2.3'), | |
| 395 new Version.parse('1.2.5')])); | |
| 396 expect(constraint, doesNotAllow([ | |
| 397 new Version.parse('1.2.3-pre'), | |
| 398 new Version.parse('1.3.0'), | |
| 399 new Version.parse('3.4.5')])); | |
| 400 }); | |
| 401 | |
| 402 test('does not allow "any" to be mixed with other constraints', () { | |
| 403 expect(() => new VersionConstraint.parse('any 1.0.0'), | |
| 404 throwsFormatException); | |
| 405 }); | |
| 406 | |
| 407 test('throws FormatException on a bad string', () { | |
| 408 var bad = [ | |
| 409 "", " ", // Empty string. | |
| 410 "foo", // Bad text. | |
| 411 ">foo", // Bad text after operator. | |
| 412 "1.0.0 foo", "1.0.0foo", // Bad text after version. | |
| 413 "anything", // Bad text after "any". | |
| 414 "<>1.0.0", // Multiple operators. | |
| 415 "1.0.0<" // Trailing operator. | |
| 416 ]; | |
| 417 | |
| 418 for (var text in bad) { | |
| 419 expect(() => new VersionConstraint.parse(text), | |
| 420 throwsFormatException); | |
| 421 } | |
| 422 }); | |
| 423 }); | |
| 424 }); | |
| 425 } | |
| 426 | |
| 427 class VersionConstraintMatcher implements Matcher { | |
| 428 final List<Version> _expected; | |
| 429 final bool _allow; | |
| 430 | |
| 431 VersionConstraintMatcher(this._expected, this._allow); | |
| 432 | |
| 433 bool matches(item, MatchState matchState) => (item is VersionConstraint) && | |
| 434 _expected.every((version) => item.allows(version) == _allow); | |
| 435 | |
| 436 Description describe(Description description) => | |
| 437 description.add(' ${_allow ? "allows" : "does not allow"} versions'); | |
| 438 | |
| 439 Description describeMismatch(item, Description mismatchDescription, | |
| 440 MatchState matchState, bool verbose) { | |
| 441 if (item is! VersionConstraint) { | |
| 442 mismatchDescription.add('was not a VersionConstraint'); | |
| 443 return mismatchDescription; | |
| 444 } | |
| 445 | |
| 446 bool first = true; | |
| 447 for (var version in _expected) { | |
| 448 if (item.allows(version) != _allow) { | |
| 449 if (first) { | |
| 450 if (_allow) { | |
| 451 mismatchDescription.addDescriptionOf(item).add('did not allow '); | |
| 452 } else { | |
| 453 mismatchDescription.addDescriptionOf(item).add('allowed '); | |
| 454 } | |
| 455 } else { | |
| 456 mismatchDescription.add(' and '); | |
| 457 } | |
| 458 first = false; | |
| 459 | |
| 460 mismatchDescription.add(version.toString()); | |
| 461 } | |
| 462 } | |
| 463 | |
| 464 return mismatchDescription; | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 Matcher allows(List<Version> versions) => | |
| 469 new VersionConstraintMatcher(versions, true); | |
| 470 | |
| 471 Matcher doesNotAllow(List<Version> versions) => | |
| 472 new VersionConstraintMatcher(versions, false); | |
| 473 | |
| 474 throwsIllegalArg(function) { | |
| 475 expect(function, throwsA((e) => e is ArgumentError)); | |
| 476 } | |
| OLD | NEW |