Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / hexpm / src / version / tests.rs
13 kB 474 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2026 The Gleam contributors 3 4use std::cmp::Ordering::{Equal, Greater, Less}; 5use std::collections::HashMap; 6 7use parser::Error; 8 9use super::{ 10 Identifier::{AlphaNumeric, Numeric}, 11 *, 12}; 13 14// Tests adapted from the tests for Elixir's version module 15 16macro_rules! version_parse_test { 17 ($name:ident, $input:expr, $major:expr, $minor:expr, $patch:expr,$pre:expr, $build:expr) => { 18 #[test] 19 fn $name() { 20 assert_eq!( 21 Version::parse($input).unwrap(), 22 Version { 23 major: $major, 24 minor: $minor, 25 patch: $patch, 26 pre: $pre, 27 build: $build 28 } 29 ); 30 } 31 }; 32 33 ($name:ident, $input:expr, $major:expr, $minor:expr, $patch:expr, $pre:expr) => { 34 #[test] 35 fn $name() { 36 assert_eq!( 37 Version::parse($input).unwrap(), 38 Version { 39 major: $major, 40 minor: $minor, 41 patch: $patch, 42 pre: $pre, 43 build: None 44 } 45 ); 46 } 47 }; 48 49 ($name:ident, $input:expr, $major:expr, $minor:expr, $patch:expr) => { 50 #[test] 51 fn $name() { 52 assert_eq!( 53 Version::parse($input).unwrap(), 54 Version { 55 major: $major, 56 minor: $minor, 57 patch: $patch, 58 pre: vec![], 59 build: None 60 } 61 ); 62 } 63 }; 64} 65 66macro_rules! version_parse_fail_test { 67 ($name:ident, $input:expr) => { 68 #[test] 69 fn $name() { 70 println!("{}", $input); 71 Version::parse($input).unwrap_err(); 72 } 73 }; 74} 75 76macro_rules! version_parse_print { 77 ($name:ident, $input:expr) => { 78 #[test] 79 fn $name() { 80 assert_eq!($input, Version::parse($input).unwrap().to_string().as_str()); 81 } 82 }; 83} 84 85version_parse_test!(triplet, "1.2.3", 1, 2, 3); 86 87version_parse_test!( 88 build, 89 "1.4.5+ignore", 90 1, 91 4, 92 5, 93 vec![], 94 Some("ignore".to_string()) 95); 96 97version_parse_test!( 98 two_part_build, 99 "0.0.1+sha.0702245", 100 0, 101 0, 102 1, 103 vec![], 104 Some("sha.0702245".to_string()) 105); 106 107version_parse_test!( 108 pre, 109 "1.4.5-6-g3318bd5", 110 1, 111 4, 112 5, 113 vec![AlphaNumeric("6-g3318bd5".to_string())] 114); 115 116version_parse_test!( 117 multi_part_pre, 118 "1.4.5-6.7.eight", 119 1, 120 4, 121 5, 122 vec![Numeric(6), Numeric(7), AlphaNumeric("eight".to_string())] 123); 124 125version_parse_test!( 126 pre_and_build, 127 "1.4.5-6-g3318bd5+ignore", 128 1, 129 4, 130 5, 131 vec![AlphaNumeric("6-g3318bd5".to_string())], 132 Some("ignore".to_string()) 133); 134 135version_parse_fail_test!(just_a_word, "wibble"); 136 137version_parse_fail_test!(just_major, "2"); 138 139version_parse_fail_test!(major_dor, "2."); 140 141version_parse_fail_test!(major_minor, "2.3"); 142 143version_parse_fail_test!(major_minor_dot, "2.3."); 144 145version_parse_fail_test!(triplet_dash, "2.3.0-"); 146 147version_parse_fail_test!(triplet_plus, "2.3.0+"); 148 149version_parse_fail_test!(triplet_dot, "2.3.0."); 150 151version_parse_fail_test!(quad, "2.3.0.4"); 152 153version_parse_fail_test!(missing_minor, "2.3.-rc.1"); 154 155version_parse_fail_test!(missing_minor_with_dot, "2.3.+rc.1"); 156 157version_parse_fail_test!(zero_pre, "2.3.0-01"); 158 159version_parse_fail_test!(double_zero_pre, "2.3.00-1"); 160 161version_parse_fail_test!(double_zero, "2.3.00"); 162 163version_parse_fail_test!(leading_zero_minor, "2.03.0"); 164 165version_parse_fail_test!(leading_zero_major, "02.3.0"); 166 167version_parse_fail_test!(extra_whitespace, "0. 0.0"); 168 169version_parse_fail_test!(and_in_version, "0.1.0-andpre"); 170 171version_parse_print!(print_triplet, "1.100.1000"); 172 173version_parse_print!(print_pre, "1.100.4-dev"); 174 175version_parse_print!(print_pre_dot, "1.100.4-dev.1.r.t"); 176 177version_parse_print!(print_build, "1.100.4+dev.1.r.t"); 178 179version_parse_print!(print_pre_build, "1.100.4-ewfjhwefj.wefw.w.1.ff+dev.1.r.t"); 180 181macro_rules! parse_range_test { 182 ($name:ident, $input:expr, $expected:expr) => { 183 #[test] 184 fn $name() { 185 assert_eq!(Version::parse_range($input).unwrap(), $expected); 186 } 187 }; 188} 189 190macro_rules! parse_range_fail_test { 191 ($name:ident, $input:expr) => { 192 #[test] 193 fn $name() { 194 Version::parse_range($input).unwrap_err(); 195 } 196 }; 197} 198 199fn v(a: u32, b: u32, c: u32) -> Version { 200 Version::new(a, b, c) 201} 202 203fn v_(major: u32, minor: u32, patch: u32, pre: Vec<Identifier>, build: Option<String>) -> Version { 204 Version { 205 major, 206 minor, 207 patch, 208 pre, 209 build, 210 } 211} 212 213type PubgrubRange = pubgrub::Range<Version>; 214 215parse_range_test!(leading_space, " 1.2.3", PubgrubRange::singleton(v(1, 2, 3))); 216parse_range_test!( 217 trailing_space, 218 "1.2.3 ", 219 PubgrubRange::singleton(v(1, 2, 3)) 220); 221 222parse_range_test!(eq_triplet, "== 1.2.3 ", PubgrubRange::singleton(v(1, 2, 3))); 223 224parse_range_test!( 225 eq_triplet_nospace, 226 "==1.2.3 ", 227 PubgrubRange::singleton(v(1, 2, 3)) 228); 229 230parse_range_test!( 231 neq_triplet, 232 "!= 1.2.3", 233 PubgrubRange::strictly_lower_than(v(1, 2, 3)).union(&PubgrubRange::higher_than(v(1, 2, 4))) 234); 235 236parse_range_test!(implicit_eq, "2.2.3", PubgrubRange::singleton(v(2, 2, 3))); 237 238parse_range_test!( 239 range_pre_build, 240 "1.2.3-thing+oop", 241 PubgrubRange::singleton(v_( 242 1, 243 2, 244 3, 245 vec![Identifier::AlphaNumeric("thing".to_string())], 246 Some("oop".to_string()) 247 )) 248); 249 250parse_range_test!( 251 and, 252 "< 1.2.3 and > 1.0.1", 253 PubgrubRange::strictly_lower_than(v(1, 2, 3)) 254 .intersection(&PubgrubRange::higher_than(v(1, 0, 2))) 255); 256 257parse_range_test!( 258 or, 259 "< 1.2.3 or > 1.0.1", 260 PubgrubRange::strictly_lower_than(v(1, 2, 3)).union(&PubgrubRange::higher_than(v(1, 0, 2))) 261); 262 263parse_range_test!(gt, "> 1.0.0", PubgrubRange::higher_than(v(1, 0, 1))); 264parse_range_test!(gt_eq, ">= 1.0.0", PubgrubRange::higher_than(v(1, 0, 0))); 265parse_range_test!(lt, "< 1.0.0", PubgrubRange::strictly_lower_than(v(1, 0, 0))); 266parse_range_test!( 267 lt_eq, 268 "<= 1.0.0", 269 PubgrubRange::strictly_lower_than(v(1, 0, 1)) 270); 271 272parse_range_test!( 273 pessimistic_pair, 274 "~> 2.2", 275 PubgrubRange::higher_than(v(2, 2, 0)) 276 .intersection(&PubgrubRange::strictly_lower_than(v(3, 0, 0))) 277); 278 279parse_range_test!( 280 pessimistic_triplet, 281 "~> 4.6.5", 282 PubgrubRange::higher_than(v(4, 6, 5)) 283 .intersection(&PubgrubRange::strictly_lower_than(v(4, 7, 0))) 284); 285 286parse_range_test!( 287 pessimistic_triplet_pre, 288 "~> 4.6.5-eee", 289 PubgrubRange::higher_than(v_( 290 4, 291 6, 292 5, 293 vec![Identifier::AlphaNumeric("eee".to_string())], 294 None, 295 )) 296 .intersection(&PubgrubRange::strictly_lower_than(v(4, 7, 0))) 297); 298 299parse_range_test!( 300 pessimistic_triplet_build, 301 "~> 4.6.5+eee", 302 PubgrubRange::higher_than(v_(4, 6, 5, vec![], Some("eee".to_string()))) 303 .intersection(&PubgrubRange::strictly_lower_than(v(4, 7, 0))) 304); 305 306parse_range_test!( 307 greater_or_pessimistic, 308 "> 10.0.0 or ~> 3.0.0", 309 PubgrubRange::higher_than(v(10, 0, 1)).union( 310 &PubgrubRange::higher_than(v(3, 0, 0)) 311 .intersection(&PubgrubRange::strictly_lower_than(v(3, 1, 0))) 312 ) 313); 314 315parse_range_test!( 316 pessimistic_or_pessimistic, 317 "~> 1.0.0 or ~> 3.0.0", 318 PubgrubRange::higher_than(v(1, 0, 0)) 319 .intersection(&PubgrubRange::strictly_lower_than(v(1, 1, 0))) 320 .union( 321 &PubgrubRange::higher_than(v(3, 0, 0)) 322 .intersection(&PubgrubRange::strictly_lower_than(v(3, 1, 0))) 323 ) 324); 325 326parse_range_test!( 327 pessimistic_and_gt, 328 "~> 0.6 and >= 0.6.16", 329 PubgrubRange::higher_than(v(0, 6, 0)) 330 .intersection(&PubgrubRange::strictly_lower_than(v(1, 0, 0))) 331 .intersection(&PubgrubRange::higher_than(v(0, 6, 16))) 332); 333 334parse_range_test!( 335 pessimistic_and_gt_pre, 336 "~> 1.0-pre and >= 1.0.0-pre.5", 337 PubgrubRange::higher_than(v_( 338 1, 339 0, 340 0, 341 vec![Identifier::AlphaNumeric("pre".to_string())], 342 None 343 )) 344 .intersection(&PubgrubRange::strictly_lower_than(v(2, 0, 0))) 345 .intersection(&PubgrubRange::higher_than(v_( 346 1, 347 0, 348 0, 349 vec![ 350 Identifier::AlphaNumeric("pre".to_string()), 351 Identifier::Numeric(5) 352 ], 353 None 354 ))) 355); 356 357parse_range_fail_test!(range_quad, "1.1.1.1"); 358parse_range_fail_test!(range_just_major, "1"); 359parse_range_fail_test!(range_just_major_minor, "1.1"); 360parse_range_fail_test!(alpha_component, "1.1.a"); 361 362parse_range_fail_test!(range_word, "wibble"); 363parse_range_fail_test!(range_major_dot, "2."); 364parse_range_fail_test!(range_major_minor_dot, "2.3."); 365parse_range_fail_test!(range_triplet_dash, "2.3.0-"); 366parse_range_fail_test!(range_triplet_plus, "2.3.0+"); 367parse_range_fail_test!(range_triplet_dot, "2.3.0."); 368parse_range_fail_test!(range_dot_dash, "2.3.-rc.1"); 369parse_range_fail_test!(range_dot_plus, "2.3.+rc.1"); 370parse_range_fail_test!(range_zero_pre, "2.3.0-01"); 371parse_range_fail_test!(patch_zerozero_dash, "2.3.00-1"); 372parse_range_fail_test!(patch_zerozero, "2.3.00"); 373parse_range_fail_test!(minor_leading_zero, "2.03.0"); 374parse_range_fail_test!(major_leading_zero, "02.3.0"); 375parse_range_fail_test!(triplet_containing_whitespace, "0. 0.0"); 376parse_range_fail_test!(dash_amp, "0.1.0-&&pre"); 377 378parse_range_fail_test!(or_whitespace_before, "!= 1.2.3or == 1.0.1"); 379parse_range_fail_test!(or_whitespace_after, "!= 1.2.3 or== 1.0.1"); 380parse_range_fail_test!(and_whitespace_before, "!= 1.2.3and == 1.0.1"); 381parse_range_fail_test!(and_whitespace_after, "!= 1.2.3 and== 1.0.1"); 382 383parse_range_fail_test!(trailing_and, "1.1.1 and"); 384parse_range_fail_test!(trailing_or, "1.1.1 or"); 385parse_range_fail_test!(leading_and, "and 1.1.1"); 386parse_range_fail_test!(leading_or, "and 1.1.1"); 387parse_range_fail_test!(just_and, "and"); 388parse_range_fail_test!(just_or, "and"); 389 390parse_range_fail_test!(duplicate_eq, "== =="); 391parse_range_fail_test!(just_eq, "=="); 392parse_range_fail_test!(empty, ""); 393 394parse_range_fail_test!(pessimistic_major, "~> 1"); 395 396macro_rules! assert_order { 397 ($name:ident, $left:expr, $ord:expr, $right:expr) => { 398 #[test] 399 fn $name() { 400 let left = Version::parse($left); 401 let right = Version::parse($right); 402 assert_eq!(left.cmp(&right), $ord) 403 } 404 }; 405} 406 407assert_order!(ord_same, "1.0.0", Equal, "1.0.0"); 408assert_order!(ord_same_build_right, "1.0.0", Equal, "1.0.0+1"); 409assert_order!(ord_same_build_left, "1.0.0+1", Equal, "1.0.0"); 410assert_order!(ord_same_diff_build, "1.0.0+1", Equal, "1.0.0+2"); 411 412assert_order!(ord_diff_build, "1.0.0+2", Equal, "1.0.0+1"); 413 414assert_order!(ord_major_greater, "3.0.0", Greater, "2.0.0"); 415assert_order!(ord_major_lesser, "1.0.0", Less, "2.0.0"); 416 417assert_order!(ord_minor_greater, "1.1.0", Greater, "1.0.0"); 418assert_order!(ord_minor_lesser, "1.0.0", Less, "1.1.0"); 419 420assert_order!(ord_patch_greater, "1.0.1", Greater, "1.0.0"); 421assert_order!(ord_patch_lesser, "1.0.0", Less, "1.0.1"); 422 423assert_order!(ord_pre_smaller_than_zero, "1.0.0", Greater, "1.0.0-rc1"); 424assert_order!(ord_pre_smaller_than_zero_flip, "1.0.0-rc1", Less, "1.0.0"); 425 426assert_order!(ord_pre_rc1_2, "1.0.0-rc1", Less, "1.0.0-rc2"); 427 428#[test] 429fn manifest_toml() { 430 let manifest = toml::to_string( 431 &vec![ 432 ( 433 "gleam_stdlib".to_string(), 434 Version { 435 major: 0, 436 minor: 17, 437 patch: 1, 438 pre: vec![], 439 build: None, 440 }, 441 ), 442 ( 443 "thingy".to_string(), 444 Version { 445 major: 0, 446 minor: 1, 447 patch: 0, 448 pre: vec![], 449 build: None, 450 }, 451 ), 452 ] 453 .into_iter() 454 .collect::<HashMap<String, Version>>(), 455 ) 456 .unwrap(); 457 let expected1 = r#"thingy = "0.1.0" 458gleam_stdlib = "0.17.1" 459"#; 460 let expected2 = r#"gleam_stdlib = "0.17.1" 461thingy = "0.1.0" 462"#; 463 assert!(manifest == expected1 || manifest == expected2); 464} 465 466#[test] 467fn missing_minor_has_correct_error_type() { 468 assert_eq!(Version::parse("1"), Err(Error::MinorVersionMissing(1))) 469} 470 471#[test] 472fn missing_patch_has_correct_error_type() { 473 assert_eq!(Version::parse("1.2"), Err(Error::PatchVersionMissing(1, 2))) 474}