github.com/snyk/vervet/v4@v4.27.2/version_test.go (about) 1 package vervet_test 2 3 import ( 4 "fmt" 5 "sort" 6 "testing" 7 "time" 8 9 qt "github.com/frankban/quicktest" 10 11 . "github.com/snyk/vervet/v4" 12 ) 13 14 func TestParseVersion(t *testing.T) { 15 c := qt.New(t) 16 tests := []struct { 17 vs string 18 d string 19 stab Stability 20 err string 21 }{{ 22 vs: "2021-01-01", 23 d: "2021-01-01", 24 stab: StabilityGA, 25 }, { 26 vs: "2021-02-02~beta", 27 d: "2021-02-02", 28 stab: StabilityBeta, 29 }, { 30 vs: "2021-03-03~experimental", 31 d: "2021-03-03", 32 stab: StabilityExperimental, 33 }, { 34 vs: "unknown", 35 err: `invalid version "unknown"`, 36 }} 37 for i := range tests { 38 c.Logf("parse version %q", tests[i].vs) 39 v, err := ParseVersion(tests[i].vs) 40 if tests[i].err != "" { 41 c.Assert(err, qt.ErrorMatches, tests[i].err) 42 c.Assert(func() { MustParseVersion(tests[i].vs) }, qt.PanicMatches, tests[i].err) 43 } else { 44 c.Assert(v.Date.Format("2006-01-02"), qt.Equals, tests[i].d) 45 c.Assert(v.Stability, qt.Equals, tests[i].stab) 46 } 47 } 48 } 49 50 func TestVersionStringPanics(t *testing.T) { 51 c := qt.New(t) 52 var v Version 53 c.Assert(func() { 54 c.Log(v.String()) 55 }, qt.PanicMatches, "invalid stability.*") 56 var s Stability 57 c.Assert(func() { 58 c.Log(s.String()) 59 }, qt.PanicMatches, "invalid stability.*") 60 } 61 62 func TestVersionOrder(t *testing.T) { 63 c := qt.New(t) 64 tests := []struct { 65 l, r string 66 cmp int 67 }{{ 68 // Compare some date versions 69 l: "2020-12-31", r: "2021-01-01", cmp: -1, 70 }, { 71 l: "2021-01-01", r: "2020-12-31", cmp: 1, 72 }, { 73 l: "2021-01-01", r: "2021-01-01", cmp: 0, 74 }, { 75 l: "9999-12-31", r: "9999-12-31~beta", cmp: 1, 76 }, { 77 // Compare date versions and special tags 78 l: "9999-12-31~beta", r: "9999-12-31", cmp: -1, 79 }, { 80 l: "9999-12-31", r: "9999-12-31~experimental", cmp: 1, 81 }, { 82 l: "9999-12-31~experimental", r: "9999-12-31", cmp: -1, 83 // Compare special tags 84 }, { 85 l: "2021-08-01~beta", r: "2021-08-01~experimental", cmp: 1, 86 }, { 87 l: "2021-08-01~experimental", r: "2021-08-01~beta", cmp: -1, 88 }, { 89 l: "2021-08-01~beta", r: "2021-08-01~beta", cmp: 0, 90 }, { 91 l: "2021-08-01~experimental", r: "2021-08-01~experimental", cmp: 0, 92 }, { 93 l: "2021-08-01~wip", r: "2021-08-01~experimental", cmp: -1, 94 }} 95 for i := range tests { 96 c.Logf("test %d %#v", i, tests[i]) 97 lv, err := ParseVersion(tests[i].l) 98 c.Assert(err, qt.IsNil) 99 rv, err := ParseVersion(tests[i].r) 100 c.Assert(err, qt.IsNil) 101 c.Assert(lv.Compare(rv), qt.Equals, tests[i].cmp) 102 } 103 } 104 105 func TestVersionDateStrings(t *testing.T) { 106 c := qt.New(t) 107 c.Assert(VersionDateStrings([]Version{ 108 MustParseVersion("2021-06-01~wip"), 109 MustParseVersion("2021-06-01~beta"), 110 MustParseVersion("2021-06-10~beta"), 111 MustParseVersion("2021-06-10"), 112 MustParseVersion("2021-07-12~wip"), 113 MustParseVersion("2021-07-12~experimental"), 114 MustParseVersion("2021-07-12~beta"), 115 }), qt.ContentEquals, []string{"2021-06-01", "2021-06-10", "2021-07-12"}) 116 } 117 118 func TestVersionSlice(t *testing.T) { 119 type matchTest struct { 120 match string 121 result string 122 err string 123 } 124 tests := []struct { 125 versions VersionSlice 126 first string 127 last string 128 matchTests []matchTest 129 }{{ 130 versions: VersionSlice{ 131 MustParseVersion("2021-07-12~experimental"), 132 MustParseVersion("2021-06-01~beta"), 133 MustParseVersion("2021-07-12~beta"), 134 MustParseVersion("2021-06-10"), 135 MustParseVersion("2021-06-01~wip"), 136 MustParseVersion("2021-07-12~wip"), 137 MustParseVersion("2021-06-10~beta"), 138 }, 139 first: "2021-06-01~wip", 140 last: "2021-07-12~beta", 141 matchTests: []matchTest{{ 142 match: "2021-06-10", 143 result: "2021-06-10", 144 }, { 145 match: "2021-06-10~beta", 146 result: "2021-06-10", 147 }, { 148 match: "2021-06-10~experimental", 149 result: "2021-06-10", 150 }, { 151 match: "2021-06-11~experimental", 152 result: "2021-06-10", 153 }, { 154 match: "2021-01-01", 155 err: "no matching version", 156 }, { 157 match: "2022-01-01", 158 result: "2021-06-10", 159 }, { 160 match: "2022-01-01~experimental", 161 result: "2021-07-12~beta", 162 }}, 163 }, { 164 versions: VersionSlice{ 165 MustParseVersion("2021-06-10~beta"), 166 }, 167 first: "2021-06-10~beta", 168 last: "2021-06-10~beta", 169 matchTests: []matchTest{{ 170 match: "2021-06-10", 171 err: "no matching version", 172 }, { 173 match: "2021-06-10~beta", 174 result: "2021-06-10~beta", 175 }, { 176 match: "2021-06-10~experimental", 177 result: "2021-06-10~beta", 178 }, { 179 match: "2021-06-11~wip", 180 result: "2021-06-10~beta", 181 }, { 182 match: "2021-01-01", 183 err: "no matching version", 184 }, { 185 match: "2022-01-01~wip", 186 result: "2021-06-10~beta", 187 }}, 188 }, { 189 versions: VersionSlice{ 190 MustParseVersion("2021-06-10~beta"), 191 MustParseVersion("2022-01-10~experimental"), 192 }, 193 first: "2021-06-10~beta", 194 last: "2022-01-10~experimental", 195 matchTests: []matchTest{{ 196 match: "2021-04-10", 197 err: "no matching version", 198 }, { 199 match: "2021-08-10~beta", 200 result: "2021-06-10~beta", 201 }, { 202 match: "2022-02-10~wip", 203 result: "2022-01-10~experimental", 204 }, { 205 match: "2021-01-30", 206 err: "no matching version", 207 }}, 208 }, { 209 versions: VersionSlice{ 210 MustParseVersion("2021-09-06"), 211 MustParseVersion("2021-10-06"), 212 }, 213 first: "2021-09-06", 214 last: "2021-10-06", 215 matchTests: []matchTest{{ 216 match: "2021-10-12~wip", 217 result: "2021-10-06", 218 }}, 219 }} 220 c := qt.New(t) 221 for _, t := range tests { 222 sort.Sort(t.versions) 223 c.Assert(t.versions[0].String(), qt.Equals, t.first) 224 c.Assert(t.versions[len(t.versions)-1].String(), qt.Equals, t.last) 225 for _, mt := range t.matchTests { 226 match := MustParseVersion(mt.match) 227 result, err := t.versions.Resolve(match) 228 if err != nil { 229 c.Assert(err, qt.ErrorMatches, mt.err) 230 } else { 231 c.Assert(result.String(), qt.Equals, mt.result) 232 } 233 } 234 } 235 } 236 237 func TestVersionSliceResolveEmpty(t *testing.T) { 238 c := qt.New(t) 239 _, err := VersionSlice{}.Resolve(MustParseVersion("2021-10-31")) 240 c.Assert(err, qt.ErrorMatches, "no matching version") 241 } 242 243 func TestDeprecatedBy(t *testing.T) { 244 c := qt.New(t) 245 tests := []struct { 246 base, deprecatedBy string 247 result bool 248 }{{ 249 "2021-06-01", "2021-02-01", false, 250 }, { 251 "2021-06-01", "2021-02-01~experimental", false, 252 }, { 253 "2021-06-01", "2021-02-01~beta", false, 254 }, { 255 "2021-06-01", "2022-02-01~beta", false, 256 }, { 257 "2021-06-01", "2022-02-01~experimental", false, 258 }, { 259 "2021-06-01", "2021-06-01", false, 260 }, { 261 "2021-06-01", "2021-06-02", true, 262 }, { 263 "2021-06-01~experimental", "2021-06-02~beta", true, 264 }, { 265 "2021-06-01~beta", "2021-06-02", true, 266 }, { 267 "2021-06-01", "2021-06-01", false, 268 }} 269 for i, test := range tests { 270 c.Logf("test#%d: %#v", i, test) 271 base, deprecatedBy := MustParseVersion(test.base), MustParseVersion(test.deprecatedBy) 272 c.Assert(base.DeprecatedBy(deprecatedBy), qt.Equals, test.result) 273 } 274 } 275 276 func TestDeprecates(t *testing.T) { 277 c := qt.New(t) 278 versions := VersionSlice{ 279 MustParseVersion("2021-06-01~experimental"), 280 MustParseVersion("2021-06-07~beta"), 281 MustParseVersion("2021-07-01"), 282 MustParseVersion("2021-08-12~experimental"), 283 MustParseVersion("2021-09-16~beta"), 284 MustParseVersion("2021-10-31"), 285 } 286 sort.Sort(versions) 287 tests := []struct { 288 name string 289 target Version 290 deprecatedBy Version 291 isDeprecated bool 292 sunset time.Time 293 }{{ 294 name: "beta deprecates experimental", 295 target: MustParseVersion("2021-06-01~experimental"), 296 deprecatedBy: MustParseVersion("2021-06-07~beta"), 297 isDeprecated: true, 298 sunset: time.Date(2021, time.June, 8, 0, 0, 0, 0, time.UTC), 299 }, { 300 name: "ga deprecates beta", 301 target: MustParseVersion("2021-06-07~beta"), 302 deprecatedBy: MustParseVersion("2021-07-01"), 303 isDeprecated: true, 304 sunset: time.Date(2021, time.September, 30, 0, 0, 0, 0, time.UTC), 305 }, { 306 name: "ga deprecates ga", 307 target: MustParseVersion("2021-07-01"), 308 deprecatedBy: MustParseVersion("2021-10-31"), 309 isDeprecated: true, 310 sunset: time.Date(2022, time.April, 30, 0, 0, 0, 0, time.UTC), 311 }} 312 for i, test := range tests { 313 c.Logf("test#%d: %s", i, test.name) 314 deprecates, ok := versions.Deprecates(test.target) 315 c.Assert(ok, qt.Equals, test.isDeprecated) 316 if test.isDeprecated { 317 c.Assert(test.deprecatedBy, qt.DeepEquals, deprecates) 318 sunset, ok := test.target.Sunset(deprecates) 319 c.Assert(ok, qt.IsTrue) 320 c.Assert(test.sunset, qt.Equals, sunset) 321 } 322 } 323 } 324 325 func TestLifecycleAtEnv(t *testing.T) { 326 c := qt.New(t) 327 tests := []struct { 328 version Version 329 lifecycle string 330 at string 331 }{{ 332 version: MustParseVersion("2022-08-16~wip"), 333 lifecycle: "sunset", 334 at: "2022-08-16", 335 }, { 336 version: MustParseVersion("2022-08-16~experimental"), 337 lifecycle: "deprecated", 338 at: "2022-08-16", 339 }, { 340 version: MustParseVersion("2022-08-16~experimental"), 341 lifecycle: "sunset", 342 at: "2022-11-16", 343 }, { 344 version: MustParseVersion("2022-08-16~beta"), 345 lifecycle: "released", 346 at: "2022-08-16", 347 }, { 348 version: MustParseVersion("2022-08-16~beta"), 349 lifecycle: "released", 350 at: "2022-11-16", 351 }} 352 for _, test := range tests { 353 c.Run(fmt.Sprintf("test %v", test.version), func(c *qt.C) { 354 c.Setenv("VERVET_LIFECYCLE_AT", test.at) 355 lifecycle := test.version.LifecycleAt(time.Time{}) 356 c.Assert(lifecycle.String(), qt.Equals, test.lifecycle) 357 }) 358 } 359 } 360 361 func TestLifecycleAtDefaultDate(t *testing.T) { 362 c := qt.New(t) 363 tests := []struct { 364 version Version 365 lifecycle string 366 at string 367 }{{ 368 version: MustParseVersion("2022-08-16~wip"), 369 lifecycle: "sunset", 370 }, { 371 version: MustParseVersion("2022-08-16~experimental"), 372 lifecycle: "deprecated", 373 }, { 374 version: MustParseVersion("2022-05-16~experimental"), 375 lifecycle: "sunset", 376 }, { 377 version: MustParseVersion("2022-08-16~beta"), 378 lifecycle: "released", 379 }, { 380 version: MustParseVersion("2022-08-16~beta"), 381 lifecycle: "released", 382 }} 383 for _, test := range tests { 384 c.Run(fmt.Sprintf("test %v", test.version), func(c *qt.C) { 385 c.Patch(TimeNow, func() time.Time { return time.Date(2022, time.September, 6, 14, 49, 50, 0, time.UTC) }) 386 lifecycle := test.version.LifecycleAt(time.Time{}) 387 c.Assert(lifecycle.String(), qt.Equals, test.lifecycle) 388 }) 389 } 390 } 391 392 func TestLifecycleAtUnreleasedVersionStringPanics(t *testing.T) { 393 c := qt.New(t) 394 c.Patch(TimeNow, func() time.Time { return time.Date(2022, time.June, 6, 14, 49, 50, 0, time.UTC) }) 395 version := MustParseVersion("2022-10-16~wip") 396 lifecycle := version.LifecycleAt(time.Time{}) 397 c.Assert(func() { 398 c.Log(lifecycle.String()) 399 }, qt.PanicMatches, "invalid lifecycle.*") 400 }