github.com/sdboyer/gps@v0.16.3/constraint_test.go (about) 1 package gps 2 3 import ( 4 "fmt" 5 "testing" 6 ) 7 8 // gu - helper func for stringifying what we assume is a VersionPair (otherwise 9 // will panic), but is given as a Constraint 10 func gu(v Constraint) string { 11 return fmt.Sprintf("%q at rev %q", v, v.(PairedVersion).Underlying()) 12 } 13 14 func TestBranchConstraintOps(t *testing.T) { 15 v1 := NewBranch("master").(branchVersion) 16 v2 := NewBranch("test").(branchVersion) 17 18 if !v1.MatchesAny(any) { 19 t.Errorf("Branches should always match the any constraint") 20 } 21 if v1.Intersect(any) != v1 { 22 t.Errorf("Branches should always return self when intersecting the any constraint, but got %s", v1.Intersect(any)) 23 } 24 25 if v1.MatchesAny(none) { 26 t.Errorf("Branches should never match the none constraint") 27 } 28 if v1.Intersect(none) != none { 29 t.Errorf("Branches should always return none when intersecting the none constraint, but got %s", v1.Intersect(none)) 30 } 31 32 if v1.Matches(v2) { 33 t.Errorf("%s should not match %s", v1, v2) 34 } 35 36 if v1.MatchesAny(v2) { 37 t.Errorf("%s should not allow any matches when combined with %s", v1, v2) 38 } 39 40 if v1.Intersect(v2) != none { 41 t.Errorf("Intersection of %s with %s should result in empty set", v1, v2) 42 } 43 44 // Add rev to one 45 snuffster := Revision("snuffleupagus") 46 v3 := v1.Is(snuffster).(versionPair) 47 if v2.Matches(v3) { 48 t.Errorf("%s should not match %s", v2, gu(v3)) 49 } 50 if v3.Matches(v2) { 51 t.Errorf("%s should not match %s", gu(v3), v2) 52 } 53 54 if v2.MatchesAny(v3) { 55 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 56 } 57 if v3.MatchesAny(v2) { 58 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 59 } 60 61 if v2.Intersect(v3) != none { 62 t.Errorf("Intersection of %s with %s should result in empty set", v2, gu(v3)) 63 } 64 if v3.Intersect(v2) != none { 65 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), v2) 66 } 67 68 // Add different rev to the other 69 v4 := v2.Is(Revision("cookie monster")).(versionPair) 70 if v4.Matches(v3) { 71 t.Errorf("%s should not match %s", gu(v4), gu(v3)) 72 } 73 if v3.Matches(v4) { 74 t.Errorf("%s should not match %s", gu(v3), gu(v4)) 75 } 76 77 if v4.MatchesAny(v3) { 78 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 79 } 80 if v3.MatchesAny(v4) { 81 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 82 } 83 84 if v4.Intersect(v3) != none { 85 t.Errorf("Intersection of %s with %s should result in empty set", gu(v4), gu(v3)) 86 } 87 if v3.Intersect(v4) != none { 88 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), gu(v4)) 89 } 90 91 // Now add same rev to different branches 92 // TODO(sdboyer) this might not actually be a good idea, when you consider the 93 // semantics of floating versions...matching on an underlying rev might be 94 // nice in the short term, but it's probably shit most of the time 95 v5 := v2.Is(Revision("snuffleupagus")).(versionPair) 96 if !v5.Matches(v3) { 97 t.Errorf("%s should match %s", gu(v5), gu(v3)) 98 } 99 if !v3.Matches(v5) { 100 t.Errorf("%s should match %s", gu(v3), gu(v5)) 101 } 102 103 if !v5.MatchesAny(v3) { 104 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 105 } 106 if !v3.MatchesAny(v5) { 107 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 108 } 109 110 if v5.Intersect(v3) != snuffster { 111 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v5), gu(v3)) 112 } 113 if v3.Intersect(v5) != snuffster { 114 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v3), gu(v5)) 115 } 116 117 // Set up for cross-type constraint ops 118 cookie := Revision("cookie monster") 119 o1 := NewVersion("master").(plainVersion) 120 o2 := NewVersion("1.0.0").(semVersion) 121 o3 := o1.Is(cookie).(versionPair) 122 o4 := o2.Is(cookie).(versionPair) 123 v6 := v1.Is(cookie).(versionPair) 124 125 if v1.Matches(o1) { 126 t.Errorf("%s (branch) should not match %s (version) across types", v1, o1) 127 } 128 129 if v1.MatchesAny(o1) { 130 t.Errorf("%s (branch) should not allow any matches when combined with %s (version)", v1, o1) 131 } 132 133 if v1.Intersect(o1) != none { 134 t.Errorf("Intersection of %s (branch) with %s (version) should result in empty set", v1, o1) 135 } 136 137 if v1.Matches(o2) { 138 t.Errorf("%s (branch) should not match %s (semver) across types", v1, o2) 139 } 140 141 if v1.MatchesAny(o2) { 142 t.Errorf("%s (branch) should not allow any matches when combined with %s (semver)", v1, o2) 143 } 144 145 if v1.Intersect(o2) != none { 146 t.Errorf("Intersection of %s (branch) with %s (semver) should result in empty set", v1, o2) 147 } 148 149 if v1.Matches(o3) { 150 t.Errorf("%s (branch) should not match %s (version) across types", v1, gu(o3)) 151 } 152 153 if v1.MatchesAny(o3) { 154 t.Errorf("%s (branch) should not allow any matches when combined with %s (version)", v1, gu(o3)) 155 } 156 157 if v1.Intersect(o3) != none { 158 t.Errorf("Intersection of %s (branch) with %s (version) should result in empty set", v1, gu(o3)) 159 } 160 161 if v1.Matches(o4) { 162 t.Errorf("%s (branch) should not match %s (semver) across types", v1, gu(o4)) 163 } 164 165 if v1.MatchesAny(o4) { 166 t.Errorf("%s (branch) should not allow any matches when combined with %s (semver)", v1, gu(o4)) 167 } 168 169 if v1.Intersect(o4) != none { 170 t.Errorf("Intersection of %s (branch) with %s (semver) should result in empty set", v1, gu(o4)) 171 } 172 173 if !v6.Matches(o3) { 174 t.Errorf("%s (branch) should match %s (version) across types due to shared rev", gu(v6), gu(o3)) 175 } 176 177 if !v6.MatchesAny(o3) { 178 t.Errorf("%s (branch) should allow some matches when combined with %s (version) across types due to shared rev", gu(v6), gu(o3)) 179 } 180 181 if v6.Intersect(o3) != cookie { 182 t.Errorf("Intersection of %s (branch) with %s (version) should return shared underlying rev", gu(v6), gu(o3)) 183 } 184 185 if !v6.Matches(o4) { 186 t.Errorf("%s (branch) should match %s (version) across types due to shared rev", gu(v6), gu(o4)) 187 } 188 189 if !v6.MatchesAny(o4) { 190 t.Errorf("%s (branch) should allow some matches when combined with %s (version) across types due to shared rev", gu(v6), gu(o4)) 191 } 192 193 if v6.Intersect(o4) != cookie { 194 t.Errorf("Intersection of %s (branch) with %s (version) should return shared underlying rev", gu(v6), gu(o4)) 195 } 196 } 197 198 func TestVersionConstraintOps(t *testing.T) { 199 v1 := NewVersion("ab123").(plainVersion) 200 v2 := NewVersion("b2a13").(plainVersion) 201 202 if !v1.MatchesAny(any) { 203 t.Errorf("Versions should always match the any constraint") 204 } 205 if v1.Intersect(any) != v1 { 206 t.Errorf("Versions should always return self when intersecting the any constraint, but got %s", v1.Intersect(any)) 207 } 208 209 if v1.MatchesAny(none) { 210 t.Errorf("Versions should never match the none constraint") 211 } 212 if v1.Intersect(none) != none { 213 t.Errorf("Versions should always return none when intersecting the none constraint, but got %s", v1.Intersect(none)) 214 } 215 216 if v1.Matches(v2) { 217 t.Errorf("%s should not match %s", v1, v2) 218 } 219 220 if v1.MatchesAny(v2) { 221 t.Errorf("%s should not allow any matches when combined with %s", v1, v2) 222 } 223 224 if v1.Intersect(v2) != none { 225 t.Errorf("Intersection of %s with %s should result in empty set", v1, v2) 226 } 227 228 // Add rev to one 229 snuffster := Revision("snuffleupagus") 230 v3 := v1.Is(snuffster).(versionPair) 231 if v2.Matches(v3) { 232 t.Errorf("%s should not match %s", v2, gu(v3)) 233 } 234 if v3.Matches(v2) { 235 t.Errorf("%s should not match %s", gu(v3), v2) 236 } 237 238 if v2.MatchesAny(v3) { 239 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 240 } 241 if v3.MatchesAny(v2) { 242 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 243 } 244 245 if v2.Intersect(v3) != none { 246 t.Errorf("Intersection of %s with %s should result in empty set", v2, gu(v3)) 247 } 248 if v3.Intersect(v2) != none { 249 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), v2) 250 } 251 252 // Add different rev to the other 253 v4 := v2.Is(Revision("cookie monster")).(versionPair) 254 if v4.Matches(v3) { 255 t.Errorf("%s should not match %s", gu(v4), gu(v3)) 256 } 257 if v3.Matches(v4) { 258 t.Errorf("%s should not match %s", gu(v3), gu(v4)) 259 } 260 261 if v4.MatchesAny(v3) { 262 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 263 } 264 if v3.MatchesAny(v4) { 265 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 266 } 267 268 if v4.Intersect(v3) != none { 269 t.Errorf("Intersection of %s with %s should result in empty set", gu(v4), gu(v3)) 270 } 271 if v3.Intersect(v4) != none { 272 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), gu(v4)) 273 } 274 275 // Now add same rev to different versions, and things should line up 276 v5 := v2.Is(Revision("snuffleupagus")).(versionPair) 277 if !v5.Matches(v3) { 278 t.Errorf("%s should match %s", gu(v5), gu(v3)) 279 } 280 if !v3.Matches(v5) { 281 t.Errorf("%s should match %s", gu(v3), gu(v5)) 282 } 283 284 if !v5.MatchesAny(v3) { 285 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 286 } 287 if !v3.MatchesAny(v5) { 288 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 289 } 290 291 if v5.Intersect(v3) != snuffster { 292 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v5), gu(v3)) 293 } 294 if v3.Intersect(v5) != snuffster { 295 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v3), gu(v5)) 296 } 297 298 // Set up for cross-type constraint ops 299 cookie := Revision("cookie monster") 300 o1 := NewBranch("master").(branchVersion) 301 o2 := NewVersion("1.0.0").(semVersion) 302 o3 := o1.Is(cookie).(versionPair) 303 o4 := o2.Is(cookie).(versionPair) 304 v6 := v1.Is(cookie).(versionPair) 305 306 if v1.Matches(o1) { 307 t.Errorf("%s (version) should not match %s (branch) across types", v1, o1) 308 } 309 310 if v1.MatchesAny(o1) { 311 t.Errorf("%s (version) should not allow any matches when combined with %s (branch)", v1, o1) 312 } 313 314 if v1.Intersect(o1) != none { 315 t.Errorf("Intersection of %s (version) with %s (branch) should result in empty set", v1, o1) 316 } 317 318 if v1.Matches(o2) { 319 t.Errorf("%s (version) should not match %s (semver) across types", v1, o2) 320 } 321 322 if v1.MatchesAny(o2) { 323 t.Errorf("%s (version) should not allow any matches when combined with %s (semver)", v1, o2) 324 } 325 326 if v1.Intersect(o2) != none { 327 t.Errorf("Intersection of %s (version) with %s (semver) should result in empty set", v1, o2) 328 } 329 330 if v1.Matches(o3) { 331 t.Errorf("%s (version) should not match %s (branch) across types", v1, gu(o3)) 332 } 333 334 if v1.MatchesAny(o3) { 335 t.Errorf("%s (version) should not allow any matches when combined with %s (branch)", v1, gu(o3)) 336 } 337 338 if v1.Intersect(o3) != none { 339 t.Errorf("Intersection of %s (version) with %s (branch) should result in empty set", v1, gu(o3)) 340 } 341 342 if v1.Matches(o4) { 343 t.Errorf("%s (version) should not match %s (semver) across types", v1, gu(o4)) 344 } 345 346 if v1.MatchesAny(o4) { 347 t.Errorf("%s (version) should not allow any matches when combined with %s (semver)", v1, gu(o4)) 348 } 349 350 if v1.Intersect(o4) != none { 351 t.Errorf("Intersection of %s (version) with %s (semver) should result in empty set", v1, gu(o4)) 352 } 353 354 if !v6.Matches(o3) { 355 t.Errorf("%s (version) should match %s (branch) across types due to shared rev", gu(v6), gu(o3)) 356 } 357 358 if !v6.MatchesAny(o3) { 359 t.Errorf("%s (version) should allow some matches when combined with %s (branch) across types due to shared rev", gu(v6), gu(o3)) 360 } 361 362 if v6.Intersect(o3) != cookie { 363 t.Errorf("Intersection of %s (version) with %s (branch) should return shared underlying rev", gu(v6), gu(o3)) 364 } 365 366 if !v6.Matches(o4) { 367 t.Errorf("%s (version) should match %s (branch) across types due to shared rev", gu(v6), gu(o4)) 368 } 369 370 if !v6.MatchesAny(o4) { 371 t.Errorf("%s (version) should allow some matches when combined with %s (branch) across types due to shared rev", gu(v6), gu(o4)) 372 } 373 374 if v6.Intersect(o4) != cookie { 375 t.Errorf("Intersection of %s (version) with %s (branch) should return shared underlying rev", gu(v6), gu(o4)) 376 } 377 } 378 379 func TestSemverVersionConstraintOps(t *testing.T) { 380 v1 := NewVersion("1.0.0").(semVersion) 381 v2 := NewVersion("2.0.0").(semVersion) 382 383 if !v1.MatchesAny(any) { 384 t.Errorf("Semvers should always match the any constraint") 385 } 386 if v1.Intersect(any) != v1 { 387 t.Errorf("Semvers should always return self when intersecting the any constraint, but got %s", v1.Intersect(any)) 388 } 389 390 if v1.MatchesAny(none) { 391 t.Errorf("Semvers should never match the none constraint") 392 } 393 if v1.Intersect(none) != none { 394 t.Errorf("Semvers should always return none when intersecting the none constraint, but got %s", v1.Intersect(none)) 395 } 396 397 if v1.Matches(v2) { 398 t.Errorf("%s should not match %s", v1, v2) 399 } 400 401 if v1.MatchesAny(v2) { 402 t.Errorf("%s should not allow any matches when combined with %s", v1, v2) 403 } 404 405 if v1.Intersect(v2) != none { 406 t.Errorf("Intersection of %s with %s should result in empty set", v1, v2) 407 } 408 409 // Add rev to one 410 snuffster := Revision("snuffleupagus") 411 v3 := v1.Is(snuffster).(versionPair) 412 if v2.Matches(v3) { 413 t.Errorf("%s should not match %s", v2, gu(v3)) 414 } 415 if v3.Matches(v2) { 416 t.Errorf("%s should not match %s", gu(v3), v2) 417 } 418 419 if v2.MatchesAny(v3) { 420 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 421 } 422 if v3.MatchesAny(v2) { 423 t.Errorf("%s should not allow any matches when combined with %s", v2, gu(v3)) 424 } 425 426 if v2.Intersect(v3) != none { 427 t.Errorf("Intersection of %s with %s should result in empty set", v2, gu(v3)) 428 } 429 if v3.Intersect(v2) != none { 430 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), v2) 431 } 432 433 // Add different rev to the other 434 v4 := v2.Is(Revision("cookie monster")).(versionPair) 435 if v4.Matches(v3) { 436 t.Errorf("%s should not match %s", gu(v4), gu(v3)) 437 } 438 if v3.Matches(v4) { 439 t.Errorf("%s should not match %s", gu(v3), gu(v4)) 440 } 441 442 if v4.MatchesAny(v3) { 443 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 444 } 445 if v3.MatchesAny(v4) { 446 t.Errorf("%s should not allow any matches when combined with %s", gu(v4), gu(v3)) 447 } 448 449 if v4.Intersect(v3) != none { 450 t.Errorf("Intersection of %s with %s should result in empty set", gu(v4), gu(v3)) 451 } 452 if v3.Intersect(v4) != none { 453 t.Errorf("Intersection of %s with %s should result in empty set", gu(v3), gu(v4)) 454 } 455 456 // Now add same rev to different versions, and things should line up 457 v5 := v2.Is(Revision("snuffleupagus")).(versionPair) 458 if !v5.Matches(v3) { 459 t.Errorf("%s should match %s", gu(v5), gu(v3)) 460 } 461 if !v3.Matches(v5) { 462 t.Errorf("%s should match %s", gu(v3), gu(v5)) 463 } 464 465 if !v5.MatchesAny(v3) { 466 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 467 } 468 if !v3.MatchesAny(v5) { 469 t.Errorf("%s should allow some matches when combined with %s", gu(v5), gu(v3)) 470 } 471 472 if v5.Intersect(v3) != snuffster { 473 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v5), gu(v3)) 474 } 475 if v3.Intersect(v5) != snuffster { 476 t.Errorf("Intersection of %s with %s should return underlying rev", gu(v3), gu(v5)) 477 } 478 479 // Set up for cross-type constraint ops 480 cookie := Revision("cookie monster") 481 o1 := NewBranch("master").(branchVersion) 482 o2 := NewVersion("ab123").(plainVersion) 483 o3 := o1.Is(cookie).(versionPair) 484 o4 := o2.Is(cookie).(versionPair) 485 v6 := v1.Is(cookie).(versionPair) 486 487 if v1.Matches(o1) { 488 t.Errorf("%s (semver) should not match %s (branch) across types", v1, o1) 489 } 490 491 if v1.MatchesAny(o1) { 492 t.Errorf("%s (semver) should not allow any matches when combined with %s (branch)", v1, o1) 493 } 494 495 if v1.Intersect(o1) != none { 496 t.Errorf("Intersection of %s (semver) with %s (branch) should result in empty set", v1, o1) 497 } 498 499 if v1.Matches(o2) { 500 t.Errorf("%s (semver) should not match %s (version) across types", v1, o2) 501 } 502 503 if v1.MatchesAny(o2) { 504 t.Errorf("%s (semver) should not allow any matches when combined with %s (version)", v1, o2) 505 } 506 507 if v1.Intersect(o2) != none { 508 t.Errorf("Intersection of %s (semver) with %s (version) should result in empty set", v1, o2) 509 } 510 511 if v1.Matches(o3) { 512 t.Errorf("%s (semver) should not match %s (branch) across types", v1, gu(o3)) 513 } 514 515 if v1.MatchesAny(o3) { 516 t.Errorf("%s (semver) should not allow any matches when combined with %s (branch)", v1, gu(o3)) 517 } 518 519 if v1.Intersect(o3) != none { 520 t.Errorf("Intersection of %s (semver) with %s (branch) should result in empty set", v1, gu(o3)) 521 } 522 523 if v1.Matches(o4) { 524 t.Errorf("%s (semver) should not match %s (version) across types", v1, gu(o4)) 525 } 526 527 if v1.MatchesAny(o4) { 528 t.Errorf("%s (semver) should not allow any matches when combined with %s (version)", v1, gu(o4)) 529 } 530 531 if v1.Intersect(o4) != none { 532 t.Errorf("Intersection of %s (semver) with %s (version) should result in empty set", v1, gu(o4)) 533 } 534 535 if !v6.Matches(o3) { 536 t.Errorf("%s (semver) should match %s (branch) across types due to shared rev", gu(v6), gu(o3)) 537 } 538 539 if !v6.MatchesAny(o3) { 540 t.Errorf("%s (semver) should allow some matches when combined with %s (branch) across types due to shared rev", gu(v6), gu(o3)) 541 } 542 543 if v6.Intersect(o3) != cookie { 544 t.Errorf("Intersection of %s (semver) with %s (branch) should return shared underlying rev", gu(v6), gu(o3)) 545 } 546 547 if !v6.Matches(o4) { 548 t.Errorf("%s (semver) should match %s (branch) across types due to shared rev", gu(v6), gu(o4)) 549 } 550 551 if !v6.MatchesAny(o4) { 552 t.Errorf("%s (semver) should allow some matches when combined with %s (branch) across types due to shared rev", gu(v6), gu(o4)) 553 } 554 555 if v6.Intersect(o4) != cookie { 556 t.Errorf("Intersection of %s (semver) with %s (branch) should return shared underlying rev", gu(v6), gu(o4)) 557 } 558 559 // Regression check - make sure that semVersion -> semverConstraint works 560 // the same as verified in the other test 561 c1, _ := NewSemverConstraint("=1.0.0") 562 if !v1.MatchesAny(c1) { 563 t.Errorf("%s (semver) should allow some matches - itself - when combined with an equivalent semverConstraint", gu(v1)) 564 } 565 if v1.Intersect(c1) != v1 { 566 t.Errorf("Intersection of %s (semver) with equivalent semver constraint should return self, got %s", gu(v1), v1.Intersect(c1)) 567 } 568 569 if !v6.MatchesAny(c1) { 570 t.Errorf("%s (semver pair) should allow some matches - itself - when combined with an equivalent semverConstraint", gu(v6)) 571 } 572 if v6.Intersect(c1) != v6 { 573 t.Errorf("Intersection of %s (semver pair) with equivalent semver constraint should return self, got %s", gu(v6), v6.Intersect(c1)) 574 } 575 576 } 577 578 // The other test is about the semverVersion, this is about semverConstraint 579 func TestSemverConstraintOps(t *testing.T) { 580 v1 := NewBranch("master").(branchVersion) 581 v2 := NewVersion("ab123").(plainVersion) 582 v3 := NewVersion("1.0.0").(semVersion) 583 584 fozzie := Revision("fozzie bear") 585 v4 := v1.Is(fozzie).(versionPair) 586 v5 := v2.Is(fozzie).(versionPair) 587 v6 := v3.Is(fozzie).(versionPair) 588 589 // TODO(sdboyer) we can't use the same range as below b/c semver.rangeConstraint is 590 // still an incomparable type 591 c1, err := NewSemverConstraint("=1.0.0") 592 if err != nil { 593 t.Fatalf("Failed to create constraint: %s", err) 594 } 595 596 if !c1.MatchesAny(any) { 597 t.Errorf("Semver constraints should always match the any constraint") 598 } 599 if c1.Intersect(any) != c1 { 600 t.Errorf("Semver constraints should always return self when intersecting the any constraint, but got %s", c1.Intersect(any)) 601 } 602 603 if c1.MatchesAny(none) { 604 t.Errorf("Semver constraints should never match the none constraint") 605 } 606 if c1.Intersect(none) != none { 607 t.Errorf("Semver constraints should always return none when intersecting the none constraint, but got %s", c1.Intersect(none)) 608 } 609 610 c1, err = NewSemverConstraint(">= 1.0.0") 611 if err != nil { 612 t.Fatalf("Failed to create constraint: %s", err) 613 } 614 615 if c1.Matches(v1) { 616 t.Errorf("Semver constraint should not match simple branch") 617 } 618 if c1.Matches(v2) { 619 t.Errorf("Semver constraint should not match simple version") 620 } 621 if !c1.Matches(v3) { 622 t.Errorf("Semver constraint should match a simple semver version in its range") 623 } 624 if c1.Matches(v4) { 625 t.Errorf("Semver constraint should not match paired branch") 626 } 627 if c1.Matches(v5) { 628 t.Errorf("Semver constraint should not match paired version") 629 } 630 if !c1.Matches(v6) { 631 t.Errorf("Semver constraint should match a paired semver version in its range") 632 } 633 634 if c1.MatchesAny(v1) { 635 t.Errorf("Semver constraint should not allow any when intersected with simple branch") 636 } 637 if c1.MatchesAny(v2) { 638 t.Errorf("Semver constraint should not allow any when intersected with simple version") 639 } 640 if !c1.MatchesAny(v3) { 641 t.Errorf("Semver constraint should allow some when intersected with a simple semver version in its range") 642 } 643 if c1.MatchesAny(v4) { 644 t.Errorf("Semver constraint should not allow any when intersected with paired branch") 645 } 646 if c1.MatchesAny(v5) { 647 t.Errorf("Semver constraint should not allow any when intersected with paired version") 648 } 649 if !c1.MatchesAny(v6) { 650 t.Errorf("Semver constraint should allow some when intersected with a paired semver version in its range") 651 } 652 653 if c1.Intersect(v1) != none { 654 t.Errorf("Semver constraint should return none when intersected with a simple branch") 655 } 656 if c1.Intersect(v2) != none { 657 t.Errorf("Semver constraint should return none when intersected with a simple version") 658 } 659 if c1.Intersect(v3) != v3 { 660 t.Errorf("Semver constraint should return input when intersected with a simple semver version in its range") 661 } 662 if c1.Intersect(v4) != none { 663 t.Errorf("Semver constraint should return none when intersected with a paired branch") 664 } 665 if c1.Intersect(v5) != none { 666 t.Errorf("Semver constraint should return none when intersected with a paired version") 667 } 668 if c1.Intersect(v6) != v6 { 669 t.Errorf("Semver constraint should return input when intersected with a paired semver version in its range") 670 } 671 } 672 673 // Test that certain types of cross-version comparisons work when they are 674 // expressed as a version union (but that others don't). 675 func TestVersionUnion(t *testing.T) { 676 rev := Revision("flooboofoobooo") 677 v1 := NewBranch("master") 678 v2 := NewBranch("test") 679 v3 := NewVersion("1.0.0").Is(rev) 680 v4 := NewVersion("1.0.1") 681 v5 := NewVersion("v2.0.5").Is(Revision("notamatch")) 682 683 uv1 := versionTypeUnion{v1, v4, rev} 684 uv2 := versionTypeUnion{v2, v3} 685 686 if uv1.MatchesAny(none) { 687 t.Errorf("Union can't match none") 688 } 689 if none.MatchesAny(uv1) { 690 t.Errorf("Union can't match none") 691 } 692 693 if !uv1.MatchesAny(any) { 694 t.Errorf("Union must match any") 695 } 696 if !any.MatchesAny(uv1) { 697 t.Errorf("Union must match any") 698 } 699 700 // Basic matching 701 if !uv1.Matches(v4) { 702 t.Errorf("Union should match on branch to branch") 703 } 704 if !v4.Matches(uv1) { 705 t.Errorf("Union should reverse-match on branch to branch") 706 } 707 708 if !uv1.Matches(v3) { 709 t.Errorf("Union should match on rev to paired rev") 710 } 711 if !v3.Matches(uv1) { 712 t.Errorf("Union should reverse-match on rev to paired rev") 713 } 714 715 if uv1.Matches(v2) { 716 t.Errorf("Union should not match on anything in disjoint unpaired") 717 } 718 if v2.Matches(uv1) { 719 t.Errorf("Union should not reverse-match on anything in disjoint unpaired") 720 } 721 722 if uv1.Matches(v5) { 723 t.Errorf("Union should not match on anything in disjoint pair") 724 } 725 if v5.Matches(uv1) { 726 t.Errorf("Union should not reverse-match on anything in disjoint pair") 727 } 728 729 if !uv1.Matches(uv2) { 730 t.Errorf("Union should succeed on matching comparison to other union with some overlap") 731 } 732 733 // MatchesAny - repeat Matches for safety, but add more, too 734 if !uv1.MatchesAny(v4) { 735 t.Errorf("Union should match on branch to branch") 736 } 737 if !v4.MatchesAny(uv1) { 738 t.Errorf("Union should reverse-match on branch to branch") 739 } 740 741 if !uv1.MatchesAny(v3) { 742 t.Errorf("Union should match on rev to paired rev") 743 } 744 if !v3.MatchesAny(uv1) { 745 t.Errorf("Union should reverse-match on rev to paired rev") 746 } 747 748 if uv1.MatchesAny(v2) { 749 t.Errorf("Union should not match on anything in disjoint unpaired") 750 } 751 if v2.MatchesAny(uv1) { 752 t.Errorf("Union should not reverse-match on anything in disjoint unpaired") 753 } 754 755 if uv1.MatchesAny(v5) { 756 t.Errorf("Union should not match on anything in disjoint pair") 757 } 758 if v5.MatchesAny(uv1) { 759 t.Errorf("Union should not reverse-match on anything in disjoint pair") 760 } 761 762 c1, _ := NewSemverConstraint("~1.0.0") 763 c2, _ := NewSemverConstraint("~2.0.0") 764 if !uv1.MatchesAny(c1) { 765 t.Errorf("Union should have some overlap due to containing 1.0.1 version") 766 } 767 if !c1.MatchesAny(uv1) { 768 t.Errorf("Union should have some overlap due to containing 1.0.1 version") 769 } 770 771 if uv1.MatchesAny(c2) { 772 t.Errorf("Union should have no overlap with ~2.0.0 semver range") 773 } 774 if c2.MatchesAny(uv1) { 775 t.Errorf("Union should have no overlap with ~2.0.0 semver range") 776 } 777 778 if !uv1.MatchesAny(uv2) { 779 t.Errorf("Union should succeed on MatchAny against other union with some overlap") 780 } 781 782 // Intersect - repeat all previous 783 if uv1.Intersect(v4) != v4 { 784 t.Errorf("Union intersection on contained version should return that version") 785 } 786 if v4.Intersect(uv1) != v4 { 787 t.Errorf("Union reverse-intersection on contained version should return that version") 788 } 789 790 if uv1.Intersect(v3) != rev { 791 t.Errorf("Union intersection on paired version w/matching rev should return rev, got %s", uv1.Intersect(v3)) 792 } 793 if v3.Intersect(uv1) != rev { 794 t.Errorf("Union reverse-intersection on paired version w/matching rev should return rev, got %s", v3.Intersect(uv1)) 795 } 796 797 if uv1.Intersect(v2) != none { 798 t.Errorf("Union should not intersect with anything in disjoint unpaired") 799 } 800 if v2.Intersect(uv1) != none { 801 t.Errorf("Union should not reverse-intersect with anything in disjoint unpaired") 802 } 803 804 if uv1.Intersect(v5) != none { 805 t.Errorf("Union should not intersect with anything in disjoint pair") 806 } 807 if v5.Intersect(uv1) != none { 808 t.Errorf("Union should not reverse-intersect with anything in disjoint pair") 809 } 810 811 if uv1.Intersect(c1) != v4 { 812 t.Errorf("Union intersecting with semver range should return 1.0.1 version, got %s", uv1.Intersect(c1)) 813 } 814 if c1.Intersect(uv1) != v4 { 815 t.Errorf("Union reverse-intersecting with semver range should return 1.0.1 version, got %s", c1.Intersect(uv1)) 816 } 817 818 if uv1.Intersect(c2) != none { 819 t.Errorf("Union intersecting with non-overlapping semver range should return none, got %s", uv1.Intersect(c2)) 820 } 821 if c2.Intersect(uv1) != none { 822 t.Errorf("Union reverse-intersecting with non-overlapping semver range should return none, got %s", uv1.Intersect(c2)) 823 } 824 825 if uv1.Intersect(uv2) != rev { 826 t.Errorf("Unions should intersect down to rev, but got %s", uv1.Intersect(uv2)) 827 } 828 } 829 830 func TestVersionUnionPanicOnType(t *testing.T) { 831 // versionTypeUnions need to panic if Type() gets called 832 defer func() { 833 if err := recover(); err == nil { 834 t.Error("versionTypeUnion did not panic on Type() call") 835 } 836 }() 837 _ = versionTypeUnion{}.Type() 838 } 839 840 func TestVersionUnionPanicOnString(t *testing.T) { 841 // versionStringUnions need to panic if String() gets called 842 defer func() { 843 if err := recover(); err == nil { 844 t.Error("versionStringUnion did not panic on String() call") 845 } 846 }() 847 _ = versionTypeUnion{}.String() 848 } 849 850 func TestTypedConstraintString(t *testing.T) { 851 // Also tests typedVersionString(), as this nests down into that 852 rev := Revision("flooboofoobooo") 853 v1 := NewBranch("master") 854 v2 := NewBranch("test").Is(rev) 855 v3 := NewVersion("1.0.1") 856 v4 := NewVersion("v2.0.5") 857 v5 := NewVersion("2.0.5.2") 858 859 table := []struct { 860 in Constraint 861 out string 862 }{ 863 { 864 in: anyConstraint{}, 865 out: "any-*", 866 }, 867 { 868 in: noneConstraint{}, 869 out: "none-", 870 }, 871 { 872 in: mkSVC("^1.0.0"), 873 out: "svc-^1.0.0", 874 }, 875 { 876 in: v1, 877 out: "b-master", 878 }, 879 { 880 in: v2, 881 out: "b-test-r-" + string(rev), 882 }, 883 { 884 in: v3, 885 out: "sv-1.0.1", 886 }, 887 { 888 in: v4, 889 out: "sv-v2.0.5", 890 }, 891 { 892 in: v5, 893 out: "pv-2.0.5.2", 894 }, 895 } 896 897 for _, fix := range table { 898 got := fix.in.typedString() 899 if got != fix.out { 900 t.Errorf("Typed string for %v (%T) was not expected %q; got %q", fix.in, fix.in, fix.out, got) 901 } 902 } 903 }