1use errors::Error;
15use parser;
16#[cfg(feature = "serde")]
17use serde::de::{self, Deserialize, Deserializer, Visitor};
18#[cfg(feature = "serde")]
19use serde::ser::{Serialize, Serializer};
20use std::cmp::{self, Ordering};
21use std::fmt;
22use std::hash;
23use std::str;
24
25#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
30pub enum Identifier {
31 Numeric(u64),
33 AlphaNumeric(String),
35}
36
37impl fmt::Display for Identifier {
38 #[inline]
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40 match *self {
41 Identifier::Numeric(ref n) => fmt::Display::fmt(n, f),
42 Identifier::AlphaNumeric(ref s) => fmt::Display::fmt(s, f),
43 }
44 }
45}
46
47#[cfg(feature = "serde")]
48impl Serialize for Identifier {
49 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50 where
51 S: Serializer,
52 {
53 match *self {
55 Identifier::Numeric(n) => serializer.serialize_u64(n),
56 Identifier::AlphaNumeric(ref s) => serializer.serialize_str(s),
57 }
58 }
59}
60
61#[cfg(feature = "serde")]
62impl<'de> Deserialize<'de> for Identifier {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: Deserializer<'de>,
66 {
67 struct IdentifierVisitor;
68
69 impl<'de> Visitor<'de> for IdentifierVisitor {
71 type Value = Identifier;
72
73 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
74 formatter.write_str("a SemVer pre-release or build identifier")
75 }
76
77 fn visit_u64<E>(self, numeric: u64) -> Result<Self::Value, E>
78 where
79 E: de::Error,
80 {
81 Ok(Identifier::Numeric(numeric))
82 }
83
84 fn visit_str<E>(self, alphanumeric: &str) -> Result<Self::Value, E>
85 where
86 E: de::Error,
87 {
88 Ok(Identifier::AlphaNumeric(alphanumeric.to_owned()))
89 }
90 }
91
92 deserializer.deserialize_any(IdentifierVisitor)
93 }
94}
95
96#[derive(Clone, Eq, Debug)]
98pub struct Version {
99 pub major: u64,
101 pub minor: u64,
104 pub patch: u64,
107 pub pre: Vec<Identifier>,
109 pub build: Vec<Identifier>,
111}
112
113#[cfg(feature = "serde")]
114impl Serialize for Version {
115 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
116 where
117 S: Serializer,
118 {
119 serializer.collect_str(self)
121 }
122}
123
124#[cfg(feature = "serde")]
125impl<'de> Deserialize<'de> for Version {
126 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
127 where
128 D: Deserializer<'de>,
129 {
130 struct VersionVisitor;
131
132 impl<'de> Visitor<'de> for VersionVisitor {
134 type Value = Version;
135
136 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
137 formatter.write_str("a SemVer version as a string")
138 }
139
140 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
141 where
142 E: de::Error,
143 {
144 Version::parse(v).map_err(de::Error::custom)
145 }
146 }
147
148 deserializer.deserialize_str(VersionVisitor)
149 }
150}
151
152impl Version {
153 pub fn new(major: u64, minor: u64, patch: u64) -> Version {
155 Version {
156 major: major,
157 minor: minor,
158 patch: patch,
159 pre: Vec::new(),
160 build: Vec::new(),
161 }
162 }
163
164 pub fn parse(version: &str) -> Result<Version, Error> {
187 let mut parser = parser::Parser::new(version)?;
188 let version = parser.version()?;
189
190 if !parser.is_eof() {
191 return Err(Error::MoreInput);
192 }
193
194 Ok(version)
195 }
196
197 fn clear_metadata(&mut self) {
199 self.build = Vec::new();
200 self.pre = Vec::new();
201 }
202
203 pub fn increment_patch(&mut self) {
205 self.patch += 1;
206 self.clear_metadata();
207 }
208
209 pub fn increment_minor(&mut self) {
213 self.minor += 1;
214 self.patch = 0;
215 self.clear_metadata();
216 }
217
218 pub fn increment_major(&mut self) {
223 self.major += 1;
224 self.minor = 0;
225 self.patch = 0;
226 self.clear_metadata();
227 }
228
229 pub fn is_prerelease(&self) -> bool {
231 !self.pre.is_empty()
232 }
233}
234
235impl fmt::Display for Version {
236 #[inline]
237 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238 try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch));
239 if !self.pre.is_empty() {
240 try!(write!(f, "-"));
241 for (i, x) in self.pre.iter().enumerate() {
242 if i != 0 {
243 try!(write!(f, "."))
244 }
245 try!(write!(f, "{}", x));
246 }
247 }
248 if !self.build.is_empty() {
249 try!(write!(f, "+"));
250 for (i, x) in self.build.iter().enumerate() {
251 if i != 0 {
252 try!(write!(f, "."))
253 }
254 try!(write!(f, "{}", x));
255 }
256 }
257 Ok(())
258 }
259}
260
261impl cmp::PartialEq for Version {
262 #[inline]
263 fn eq(&self, other: &Version) -> bool {
264 self.major == other.major && self.minor == other.minor && self.patch == other.patch
268 && self.pre == other.pre
269 }
270}
271
272impl cmp::PartialOrd for Version {
273 fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
274 Some(self.cmp(other))
275 }
276}
277
278impl cmp::Ord for Version {
279 fn cmp(&self, other: &Version) -> Ordering {
280 match self.major.cmp(&other.major) {
281 Ordering::Equal => {}
282 r => return r,
283 }
284
285 match self.minor.cmp(&other.minor) {
286 Ordering::Equal => {}
287 r => return r,
288 }
289
290 match self.patch.cmp(&other.patch) {
291 Ordering::Equal => {}
292 r => return r,
293 }
294
295 match (self.pre.len(), other.pre.len()) {
299 (0, 0) => Ordering::Equal,
300 (0, _) => Ordering::Greater,
301 (_, 0) => Ordering::Less,
302 (_, _) => self.pre.cmp(&other.pre),
303 }
304 }
305}
306
307impl hash::Hash for Version {
308 fn hash<H: hash::Hasher>(&self, into: &mut H) {
309 self.major.hash(into);
310 self.minor.hash(into);
311 self.patch.hash(into);
312 self.pre.hash(into);
313 }
314}
315
316impl From<(u64, u64, u64)> for Version {
317 fn from(tuple: (u64, u64, u64)) -> Version {
318 let (major, minor, patch) = tuple;
319 Version::new(major, minor, patch)
320 }
321}
322
323#[cfg(test)]
324mod tests {
325 use super::*;
326 use range::Range;
327
328 #[test]
329 fn test_parse() {
330 assert_eq!(
331 Version::parse("1.2.3"),
332 Ok(Version {
333 major: 1,
334 minor: 2,
335 patch: 3,
336 pre: Vec::new(),
337 build: Vec::new(),
338 },)
339 );
340
341 assert_eq!(Version::parse("1.2.3"), Ok(Version::new(1, 2, 3)));
342
343 assert_eq!(
344 Version::parse(" 1.2.3 "),
345 Ok(Version {
346 major: 1,
347 minor: 2,
348 patch: 3,
349 pre: Vec::new(),
350 build: Vec::new(),
351 },)
352 );
353 assert_eq!(
354 Version::parse("1.2.3-alpha1"),
355 Ok(Version {
356 major: 1,
357 minor: 2,
358 patch: 3,
359 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
360 build: Vec::new(),
361 },)
362 );
363 assert_eq!(
364 Version::parse(" 1.2.3-alpha1 "),
365 Ok(Version {
366 major: 1,
367 minor: 2,
368 patch: 3,
369 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
370 build: Vec::new(),
371 },)
372 );
373 assert_eq!(
374 Version::parse("1.2.3+build5"),
375 Ok(Version {
376 major: 1,
377 minor: 2,
378 patch: 3,
379 pre: Vec::new(),
380 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
381 },)
382 );
383 assert_eq!(
384 Version::parse(" 1.2.3+build5 "),
385 Ok(Version {
386 major: 1,
387 minor: 2,
388 patch: 3,
389 pre: Vec::new(),
390 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
391 },)
392 );
393 assert_eq!(
394 Version::parse("1.2.3-alpha1+build5"),
395 Ok(Version {
396 major: 1,
397 minor: 2,
398 patch: 3,
399 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
400 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
401 },)
402 );
403 assert_eq!(
404 Version::parse(" 1.2.3-alpha1+build5 "),
405 Ok(Version {
406 major: 1,
407 minor: 2,
408 patch: 3,
409 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
410 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
411 },)
412 );
413 assert_eq!(
414 Version::parse("1.2.3-1.alpha1.9+build5.7.3aedf "),
415 Ok(Version {
416 major: 1,
417 minor: 2,
418 patch: 3,
419 pre: vec![
420 Identifier::Numeric(1),
421 Identifier::AlphaNumeric(String::from("alpha1")),
422 Identifier::Numeric(9),
423 ],
424 build: vec![
425 Identifier::AlphaNumeric(String::from("build5")),
426 Identifier::Numeric(7),
427 Identifier::AlphaNumeric(String::from("3aedf")),
428 ],
429 },)
430 );
431 assert_eq!(
432 Version::parse("0.4.0-beta.1+0851523"),
433 Ok(Version {
434 major: 0,
435 minor: 4,
436 patch: 0,
437 pre: vec![
438 Identifier::AlphaNumeric(String::from("beta")),
439 Identifier::Numeric(1),
440 ],
441 build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
442 },)
443 );
444 }
445
446 #[test]
447 fn test_increment_patch() {
448 let mut buggy_release = Version::parse("0.1.0").unwrap();
449 buggy_release.increment_patch();
450 assert_eq!(buggy_release, Version::parse("0.1.1").unwrap());
451 }
452
453 #[test]
454 fn test_increment_minor() {
455 let mut feature_release = Version::parse("1.4.6").unwrap();
456 feature_release.increment_minor();
457 assert_eq!(feature_release, Version::parse("1.5.0").unwrap());
458 }
459
460 #[test]
461 fn test_increment_major() {
462 let mut chrome_release = Version::parse("46.1.246773").unwrap();
463 chrome_release.increment_major();
464 assert_eq!(chrome_release, Version::parse("47.0.0").unwrap());
465 }
466
467 #[test]
468 fn test_increment_keep_prerelease() {
469 let mut release = Version::parse("1.0.0-alpha").unwrap();
470 release.increment_patch();
471
472 assert_eq!(release, Version::parse("1.0.1").unwrap());
473
474 release.increment_minor();
475
476 assert_eq!(release, Version::parse("1.1.0").unwrap());
477
478 release.increment_major();
479
480 assert_eq!(release, Version::parse("2.0.0").unwrap());
481 }
482
483 #[test]
484 fn test_increment_clear_metadata() {
485 let mut release = Version::parse("1.0.0+4442").unwrap();
486 release.increment_patch();
487
488 assert_eq!(release, Version::parse("1.0.1").unwrap());
489 release = Version::parse("1.0.1+hello").unwrap();
490
491 release.increment_minor();
492
493 assert_eq!(release, Version::parse("1.1.0").unwrap());
494 release = Version::parse("1.1.3747+hello").unwrap();
495
496 release.increment_major();
497
498 assert_eq!(release, Version::parse("2.0.0").unwrap());
499 }
500
501 #[test]
502 fn test_eq() {
503 assert_eq!(Version::parse("1.2.3"), Version::parse("1.2.3"));
504 assert_eq!(
505 Version::parse("1.2.3-alpha1"),
506 Version::parse("1.2.3-alpha1")
507 );
508 assert_eq!(
509 Version::parse("1.2.3+build.42"),
510 Version::parse("1.2.3+build.42")
511 );
512 assert_eq!(
513 Version::parse("1.2.3-alpha1+42"),
514 Version::parse("1.2.3-alpha1+42")
515 );
516 assert_eq!(Version::parse("1.2.3+23"), Version::parse("1.2.3+42"));
517 }
518
519 #[test]
520 fn test_ne() {
521 assert!(Version::parse("0.0.0") != Version::parse("0.0.1"));
522 assert!(Version::parse("0.0.0") != Version::parse("0.1.0"));
523 assert!(Version::parse("0.0.0") != Version::parse("1.0.0"));
524 assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
525 }
526
527 #[test]
528 fn test_show() {
529 assert_eq!(
530 format!("{}", Version::parse("1.2.3").unwrap()),
531 "1.2.3".to_string()
532 );
533 assert_eq!(
534 format!("{}", Version::parse("1.2.3-alpha1").unwrap()),
535 "1.2.3-alpha1".to_string()
536 );
537 assert_eq!(
538 format!("{}", Version::parse("1.2.3+build.42").unwrap()),
539 "1.2.3+build.42".to_string()
540 );
541 assert_eq!(
542 format!("{}", Version::parse("1.2.3-alpha1+42").unwrap()),
543 "1.2.3-alpha1+42".to_string()
544 );
545 }
546
547 #[test]
548 fn test_to_string() {
549 assert_eq!(
550 Version::parse("1.2.3").unwrap().to_string(),
551 "1.2.3".to_string()
552 );
553 assert_eq!(
554 Version::parse("1.2.3-alpha1").unwrap().to_string(),
555 "1.2.3-alpha1".to_string()
556 );
557 assert_eq!(
558 Version::parse("1.2.3+build.42").unwrap().to_string(),
559 "1.2.3+build.42".to_string()
560 );
561 assert_eq!(
562 Version::parse("1.2.3-alpha1+42").unwrap().to_string(),
563 "1.2.3-alpha1+42".to_string()
564 );
565 }
566
567 #[test]
568 fn test_lt() {
569 assert!(Version::parse("0.0.0") < Version::parse("1.2.3-alpha2"));
570 assert!(Version::parse("1.0.0") < Version::parse("1.2.3-alpha2"));
571 assert!(Version::parse("1.2.0") < Version::parse("1.2.3-alpha2"));
572 assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3"));
573 assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3-alpha2"));
574 assert!(!(Version::parse("1.2.3-alpha2") < Version::parse("1.2.3-alpha2")));
575 assert!(!(Version::parse("1.2.3+23") < Version::parse("1.2.3+42")));
576 }
577
578 #[test]
579 fn test_le() {
580 assert!(Version::parse("0.0.0") <= Version::parse("1.2.3-alpha2"));
581 assert!(Version::parse("1.0.0") <= Version::parse("1.2.3-alpha2"));
582 assert!(Version::parse("1.2.0") <= Version::parse("1.2.3-alpha2"));
583 assert!(Version::parse("1.2.3-alpha1") <= Version::parse("1.2.3-alpha2"));
584 assert!(Version::parse("1.2.3-alpha2") <= Version::parse("1.2.3-alpha2"));
585 assert!(Version::parse("1.2.3+23") <= Version::parse("1.2.3+42"));
586 }
587
588 #[test]
589 fn test_gt() {
590 assert!(Version::parse("1.2.3-alpha2") > Version::parse("0.0.0"));
591 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.0.0"));
592 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0"));
593 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha1"));
594 assert!(Version::parse("1.2.3") > Version::parse("1.2.3-alpha2"));
595 assert!(!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha2")));
596 assert!(!(Version::parse("1.2.3+23") > Version::parse("1.2.3+42")));
597 }
598
599 #[test]
600 fn test_ge() {
601 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("0.0.0"));
602 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.0.0"));
603 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.0"));
604 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha1"));
605 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha2"));
606 assert!(Version::parse("1.2.3+23") >= Version::parse("1.2.3+42"));
607 }
608
609 #[test]
610 fn test_prerelease_check() {
611 assert!(Version::parse("1.0.0").unwrap().is_prerelease() == false);
612 assert!(Version::parse("0.0.1").unwrap().is_prerelease() == false);
613 assert!(Version::parse("4.1.4-alpha").unwrap().is_prerelease());
614 assert!(Version::parse("1.0.0-beta294296").unwrap().is_prerelease());
615 }
616
617 #[test]
618 fn test_spec_order() {
619 let vs = [
620 "1.0.0-alpha",
621 "1.0.0-alpha.1",
622 "1.0.0-alpha.beta",
623 "1.0.0-beta",
624 "1.0.0-beta.2",
625 "1.0.0-beta.11",
626 "1.0.0-rc.1",
627 "1.0.0",
628 ];
629 let mut i = 1;
630 while i < vs.len() {
631 let a = Version::parse(vs[i - 1]);
632 let b = Version::parse(vs[i]);
633 assert!(a < b, "nope {:?} < {:?}", a, b);
634 i += 1;
635 }
636 }
637
638 #[test]
639 fn test_from_str() {
640 assert_eq!(
641 Version::parse("1.2.3"),
642 Ok(Version {
643 major: 1,
644 minor: 2,
645 patch: 3,
646 pre: Vec::new(),
647 build: Vec::new(),
648 },)
649 );
650 assert_eq!(
651 Version::parse(" 1.2.3 "),
652 Ok(Version {
653 major: 1,
654 minor: 2,
655 patch: 3,
656 pre: Vec::new(),
657 build: Vec::new(),
658 },)
659 );
660 assert_eq!(
661 Version::parse("1.2.3-alpha1"),
662 Ok(Version {
663 major: 1,
664 minor: 2,
665 patch: 3,
666 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
667 build: Vec::new(),
668 },)
669 );
670 assert_eq!(
671 Version::parse(" 1.2.3-alpha1 "),
672 Ok(Version {
673 major: 1,
674 minor: 2,
675 patch: 3,
676 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
677 build: Vec::new(),
678 },)
679 );
680 assert_eq!(
681 Version::parse("1.2.3+build5"),
682 Ok(Version {
683 major: 1,
684 minor: 2,
685 patch: 3,
686 pre: Vec::new(),
687 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
688 },)
689 );
690 assert_eq!(
691 Version::parse(" 1.2.3+build5 "),
692 Ok(Version {
693 major: 1,
694 minor: 2,
695 patch: 3,
696 pre: Vec::new(),
697 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
698 },)
699 );
700 assert_eq!(
701 Version::parse("1.2.3-alpha1+build5"),
702 Ok(Version {
703 major: 1,
704 minor: 2,
705 patch: 3,
706 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
707 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
708 },)
709 );
710 assert_eq!(
711 Version::parse(" 1.2.3-alpha1+build5 "),
712 Ok(Version {
713 major: 1,
714 minor: 2,
715 patch: 3,
716 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
717 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
718 },)
719 );
720 assert_eq!(
721 Version::parse("1.2.3-1.alpha1.9+build5.7.3aedf "),
722 Ok(Version {
723 major: 1,
724 minor: 2,
725 patch: 3,
726 pre: vec![
727 Identifier::Numeric(1),
728 Identifier::AlphaNumeric(String::from("alpha1")),
729 Identifier::Numeric(9),
730 ],
731 build: vec![
732 Identifier::AlphaNumeric(String::from("build5")),
733 Identifier::Numeric(7),
734 Identifier::AlphaNumeric(String::from("3aedf")),
735 ],
736 },)
737 );
738 assert_eq!(
739 Version::parse("0.4.0-beta.1+0851523"),
740 Ok(Version {
741 major: 0,
742 minor: 4,
743 patch: 0,
744 pre: vec![
745 Identifier::AlphaNumeric(String::from("beta")),
746 Identifier::Numeric(1),
747 ],
748 build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
749 },)
750 );
751 }
752
753 struct SemverTest(&'static str, &'static str, bool);
754
755 macro_rules! semver_tests {
757 ($(($($test:tt)*),)+) => {
758 [$(semver_tests!(@test $($test)*),)+]
759 };
760
761 (@test $req:expr, $version:expr) => {
762 SemverTest($req, $version, false)
763 };
764
765 (@test $req:expr, $version:expr, true) => {
766 SemverTest($req, $version, true)
767 };
768 }
769
770 #[test]
773 fn node_semver_comparisons() {
774 let input = semver_tests![
775 ("0.0.0", "0.0.0-foo"),
776 ("0.0.1", "0.0.0"),
777 ("1.0.0", "0.9.9"),
778 ("0.10.0", "0.9.0"),
779 ("0.99.0", "0.10.0"),
780 ("2.0.0", "1.2.3"),
781 ("v0.0.0", "0.0.0-foo", true),
782 ("v0.0.1", "0.0.0", true),
783 ("v1.0.0", "0.9.9", true),
784 ("v0.10.0", "0.9.0", true),
785 ("v0.99.0", "0.10.0", true),
786 ("v2.0.0", "1.2.3", true),
787 ("0.0.0", "v0.0.0-foo", true),
788 ("0.0.1", "v0.0.0", true),
789 ("1.0.0", "v0.9.9", true),
790 ("0.10.0", "v0.9.0", true),
791 ("0.99.0", "v0.10.0", true),
792 ("2.0.0", "v1.2.3", true),
793 ("1.2.3", "1.2.3-asdf"),
794 ("1.2.3", "1.2.3-4"),
795 ("1.2.3", "1.2.3-4-foo"),
796 ("1.2.3-5-foo", "1.2.3-5"),
797 ("1.2.3-5", "1.2.3-4"),
798 ("1.2.3-5-foo", "1.2.3-5-Foo"),
799 ("3.0.0", "2.7.2+asdf"),
800 ("1.2.3-a.10", "1.2.3-a.5"),
801 ("1.2.3-a.b", "1.2.3-a.5"),
802 ("1.2.3-a.b", "1.2.3-a"),
803 ("1.2.3-a.b.c.10.d.5", "1.2.3-a.b.c.5.d.100"),
804 ("1.2.3-r2", "1.2.3-r100"),
805 ("1.2.3-r100", "1.2.3-R2"),
806 ];
807
808 for (i, &SemverTest(left, right, loose)) in input.into_iter().enumerate() {
809 if loose {
811 continue;
812 }
813
814 let left = Version::parse(left)
815 .map_err(|e| format!("failed to parse: {}: {}", left, e))
816 .unwrap();
817
818 let right = Version::parse(right)
819 .map_err(|e| format!("failed to parse: {}: {}", right, e))
820 .unwrap();
821
822 assert!(left > right, "#{}: {} > {}", i, left, right);
823 assert!(!(left < right));
824 assert!(!(left <= right));
825 assert!(!(left == right));
826 assert!(left != right);
827 }
828 }
829
830 #[test]
833 fn node_semver_range() {
834 let input = semver_tests![
836 ("^1.2.3+build", "1.2.3"),
838 ("^1.2.3+build", "1.3.0"),
839 ("1.0.0", "1.0.0"),
848 (">=*", "0.2.4"),
849 ("", "1.0.0"),
850 ("*", "1.2.3"),
851 ("*", "v1.2.3", true),
852 (">=1.0.0", "1.0.0"),
853 (">=1.0.0", "1.0.1"),
854 (">=1.0.0", "1.1.0"),
855 (">1.0.0", "1.0.1"),
856 (">1.0.0", "1.1.0"),
857 ("<=2.0.0", "2.0.0"),
858 ("<=2.0.0", "1.9999.9999"),
859 ("<=2.0.0", "0.2.9"),
860 ("<2.0.0", "1.9999.9999"),
861 ("<2.0.0", "0.2.9"),
862 (">= 1.0.0", "1.0.0"),
863 (">= 1.0.0", "1.0.1"),
864 (">= 1.0.0", "1.1.0"),
865 ("> 1.0.0", "1.0.1"),
866 ("> 1.0.0", "1.1.0"),
867 ("<= 2.0.0", "2.0.0"),
868 ("<= 2.0.0", "1.9999.9999"),
869 ("<= 2.0.0", "0.2.9"),
870 ("< 2.0.0", "1.9999.9999"),
871 ("<\t2.0.0", "0.2.9"),
872 (">=0.1.97", "v0.1.97", true),
873 (">=0.1.97", "0.1.97"),
874 ("2.x.x", "2.1.3"),
880 ("1.2.x", "1.2.3"),
881 ("x", "1.2.3"),
884 ("2.*.*", "2.1.3"),
885 ("1.2.*", "1.2.3"),
886 ("*", "1.2.3"),
889 ("2", "2.1.2"),
890 ("2.3", "2.3.1"),
891 ("~x", "0.0.9"), ("~2", "2.0.9"), ("~2.4", "2.4.0"), ("~2.4", "2.4.5"),
895 ("~1", "1.2.3"), ("~1.0", "1.0.2"), ("~ 1.0", "1.0.2"),
901 ("~ 1.0.3", "1.0.12"),
902 (">=1", "1.0.0"),
903 (">= 1", "1.0.0"),
904 ("<1.2", "1.1.1"),
905 ("< 1.2", "1.1.1"),
906 ("=0.7.x", "0.7.2"),
909 ("~1.2.1, >=1.2.3", "1.2.3"),
914 ("~1.2.1, =1.2.3", "1.2.3"),
915 ("~1.2.1, 1.2.3", "1.2.3"),
916 ("~1.2.1, >=1.2.3, 1.2.3", "1.2.3"),
917 ("~1.2.1, 1.2.3, >=1.2.3", "1.2.3"),
918 ("~1.2.1, 1.2.3", "1.2.3"),
919 (">=1.2.1, 1.2.3", "1.2.3"),
920 ("1.2.3, >=1.2.1", "1.2.3"),
921 (">=1.2.3, >=1.2.1", "1.2.3"),
922 (">=1.2.1, >=1.2.3", "1.2.3"),
923 (">=1.2", "1.2.8"),
924 ("^1.2.3", "1.8.1"),
925 ("^0.1.2", "0.1.2"),
926 ("^0.1", "0.1.2"),
927 ("^0.0.1", "0.0.1"),
928 ("^1.2", "1.4.2"),
929 ("^1.2, ^1", "1.4.2"),
930 ("^1.2.3-alpha", "1.2.3-pre"),
931 ("^1.2.0-alpha", "1.2.0-pre"),
932 ("^0.0.1-alpha", "0.0.1-beta"),
933 ("^0.1.1-alpha", "0.1.1-beta"),
934 ("^x", "1.2.3"),
935 ];
942
943 for (i, &SemverTest(req, version, loose)) in input.into_iter().enumerate() {
944 if loose {
946 continue;
947 }
948
949 let req = Range::parse(req)
950 .map_err(|e| format!("{}: {}", e, req))
951 .unwrap();
952 let version = Version::parse(version).unwrap();
953
954 assert!(
955 req.matches(&version),
956 "#{}: ({}).matches({})",
957 i,
958 req,
959 version
960 );
961 }
962 }
963}