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