1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std
::error
::Error
;
17 use version
::Identifier
;
20 #[cfg(feature = "serde")]
21 use serde
::ser
::{Serialize, Serializer}
;
22 #[cfg(feature = "serde")]
23 use serde
::de
::{self, Deserialize, Deserializer, Visitor}
;
25 use self::Op
::{Ex, Gt, GtEq, Lt, LtEq, Tilde, Compatible, Wildcard}
;
26 use self::WildcardVersion
::{Major, Minor, Patch}
;
27 use self::ReqParseError
::*;
29 /// A `VersionReq` is a struct containing a list of predicates that can apply to ranges of version
30 /// numbers. Matching operations can then be done with the `VersionReq` against a particular
31 /// version to see if it satisfies some or all of the constraints.
32 #[derive(PartialEq,Clone,Debug)]
33 pub struct VersionReq
{
34 predicates
: Vec
<Predicate
>,
37 impl From
<semver_parser
::range
::VersionReq
> for VersionReq
{
38 fn from(other
: semver_parser
::range
::VersionReq
) -> VersionReq
{
39 VersionReq { predicates: other.predicates.into_iter().map(From::from).collect() }
43 #[cfg(feature = "serde")]
44 impl Serialize
for VersionReq
{
45 fn serialize
<S
>(&self, serializer
: S
) -> result
::Result
<S
::Ok
, S
::Error
>
48 // Serialize VersionReq as a string.
49 serializer
.collect_str(self)
53 #[cfg(feature = "serde")]
54 impl<'de
> Deserialize
<'de
> for VersionReq
{
55 fn deserialize
<D
>(deserializer
: D
) -> result
::Result
<Self, D
::Error
>
56 where D
: Deserializer
<'de
>
58 struct VersionReqVisitor
;
60 /// Deserialize `VersionReq` from a string.
61 impl<'de
> Visitor
<'de
> for VersionReqVisitor
{
62 type Value
= VersionReq
;
64 fn expecting(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
65 formatter
.write_str("a SemVer version requirement as a string")
68 fn visit_str
<E
>(self, v
: &str) -> result
::Result
<Self::Value
, E
>
71 VersionReq
::parse(v
).map_err(de
::Error
::custom
)
75 deserializer
.deserialize_str(VersionReqVisitor
)
79 #[derive(Clone, PartialEq, Debug)]
80 enum WildcardVersion
{
86 #[derive(PartialEq,Clone,Debug)]
90 GtEq
, // Greater than or equal to
92 LtEq
, // Less than or equal to
94 Compatible
, // compatible by definition of semver, indicated by ^
95 Wildcard(WildcardVersion
), // x.y.*, x.*, *
98 impl From
<semver_parser
::range
::Op
> for Op
{
99 fn from(other
: semver_parser
::range
::Op
) -> Op
{
100 use semver_parser
::range
;
102 range
::Op
::Ex
=> Op
::Ex
,
103 range
::Op
::Gt
=> Op
::Gt
,
104 range
::Op
::GtEq
=> Op
::GtEq
,
105 range
::Op
::Lt
=> Op
::Lt
,
106 range
::Op
::LtEq
=> Op
::LtEq
,
107 range
::Op
::Tilde
=> Op
::Tilde
,
108 range
::Op
::Compatible
=> Op
::Compatible
,
109 range
::Op
::Wildcard(version
) => {
111 range
::WildcardVersion
::Major
=> Op
::Wildcard(WildcardVersion
::Major
),
112 range
::WildcardVersion
::Minor
=> Op
::Wildcard(WildcardVersion
::Minor
),
113 range
::WildcardVersion
::Patch
=> Op
::Wildcard(WildcardVersion
::Patch
),
120 #[derive(PartialEq,Clone,Debug)]
126 pre
: Vec
<Identifier
>,
129 impl From
<semver_parser
::range
::Predicate
> for Predicate
{
130 fn from(other
: semver_parser
::range
::Predicate
) -> Predicate
{
132 op
: From
::from(other
.op
),
136 pre
: other
.pre
.into_iter().map(From
::from
).collect(),
141 /// A `ReqParseError` is returned from methods which parse a string into a `VersionReq`. Each
142 /// enumeration is one of the possible errors that can occur.
143 #[derive(Clone, Debug, PartialEq)]
144 pub enum ReqParseError
{
145 /// The given version requirement is invalid.
146 InvalidVersionRequirement
,
147 /// You have already provided an operation, such as `=`, `~`, or `^`. Only use one.
149 /// The sigil you have written is not correct.
151 /// All components of a version must be numeric.
152 VersionComponentsMustBeNumeric
,
153 /// There was an error parsing an identifier.
155 /// At least a major version is required.
156 MajorVersionRequired
,
157 /// An unimplemented version requirement.
158 UnimplementedVersionRequirement
,
159 /// This form of requirement is deprecated.
160 DeprecatedVersionRequirement(VersionReq
),
163 impl fmt
::Display
for ReqParseError
{
164 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
165 self.description().fmt(f
)
169 impl Error
for ReqParseError
{
170 fn description(&self) -> &str {
172 &InvalidVersionRequirement
=> "the given version requirement is invalid",
174 "you have already provided an operation, such as =, ~, or ^; only use one"
176 &InvalidSigil
=> "the sigil you have written is not correct",
177 &VersionComponentsMustBeNumeric
=> "version components must be numeric",
178 &InvalidIdentifier
=> "invalid identifier",
179 &MajorVersionRequired
=> "at least a major version number is required",
180 &UnimplementedVersionRequirement
=> {
181 "the given version requirement is not implemented, yet"
183 &DeprecatedVersionRequirement(_
) => "This requirement is deprecated",
188 impl From
<String
> for ReqParseError
{
189 fn from(other
: String
) -> ReqParseError
{
191 "Null is not a valid VersionReq" => ReqParseError
::InvalidVersionRequirement
,
192 "VersionReq did not parse properly." => ReqParseError
::OpAlreadySet
,
193 _
=> ReqParseError
::InvalidVersionRequirement
,
199 /// `any()` is a factory method which creates a `VersionReq` with no constraints. In other
200 /// words, any version will match against it.
205 /// use semver::VersionReq;
207 /// let anything = VersionReq::any();
209 pub fn any() -> VersionReq
{
210 VersionReq { predicates: vec![] }
213 /// `parse()` is the main constructor of a `VersionReq`. It takes a string like `"^1.2.3"`
214 /// and turns it into a `VersionReq` that matches that particular constraint.
216 /// A `Result` is returned which contains a `ReqParseError` if there was a problem parsing the
222 /// use semver::VersionReq;
224 /// let version = VersionReq::parse("=1.2.3");
225 /// let version = VersionReq::parse(">1.2.3");
226 /// let version = VersionReq::parse("<1.2.3");
227 /// let version = VersionReq::parse("~1.2.3");
228 /// let version = VersionReq::parse("^1.2.3");
229 /// let version = VersionReq::parse("1.2.3"); // synonym for ^1.2.3
230 /// let version = VersionReq::parse("<=1.2.3");
231 /// let version = VersionReq::parse(">=1.2.3");
234 /// This example demonstrates error handling, and will panic.
237 /// use semver::VersionReq;
239 /// let version = match VersionReq::parse("not a version") {
240 /// Ok(version) => version,
241 /// Err(e) => panic!("There was a problem parsing: {}", e),
244 pub fn parse(input
: &str) -> Result
<VersionReq
, ReqParseError
> {
245 let res
= semver_parser
::range
::parse(input
);
248 return Ok(From
::from(v
));
251 return match VersionReq
::parse_deprecated(input
) {
253 Err(ReqParseError
::DeprecatedVersionRequirement(v
))
255 None
=> Err(From
::from(res
.err().unwrap())),
259 fn parse_deprecated(version
: &str) -> Option
<VersionReq
> {
260 return match version
{
261 ".*" => Some(VersionReq
::any()),
262 "0.1.0." => Some(VersionReq
::parse("0.1.0").unwrap()),
263 "0.3.1.3" => Some(VersionReq
::parse("0.3.13").unwrap()),
264 "0.2*" => Some(VersionReq
::parse("0.2.*").unwrap()),
265 "*.0" => Some(VersionReq
::any()),
270 /// `exact()` is a factory method which creates a `VersionReq` with one exact constraint.
275 /// use semver::VersionReq;
276 /// use semver::Version;
278 /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] };
279 /// let exact = VersionReq::exact(&version);
281 pub fn exact(version
: &Version
) -> VersionReq
{
282 VersionReq { predicates: vec![Predicate::exact(version)] }
285 /// `matches()` matches a given `Version` against this `VersionReq`.
290 /// use semver::VersionReq;
291 /// use semver::Version;
293 /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] };
294 /// let exact = VersionReq::exact(&version);
296 /// assert!(exact.matches(&version));
298 pub fn matches(&self, version
: &Version
) -> bool
{
299 // no predicates means anything matches
300 if self.predicates
.is_empty() {
304 self.predicates
.iter().all(|p
| p
.matches(version
)) &&
305 self.predicates
.iter().any(|p
| p
.pre_tag_is_compatible(version
))
309 impl str::FromStr
for VersionReq
{
310 type Err
= ReqParseError
;
312 fn from_str(s
: &str) -> Result
<VersionReq
, ReqParseError
> {
318 fn exact(version
: &Version
) -> Predicate
{
321 major
: version
.major
,
322 minor
: Some(version
.minor
),
323 patch
: Some(version
.patch
),
324 pre
: version
.pre
.clone(),
328 /// `matches()` takes a `Version` and determines if it matches this particular `Predicate`.
329 pub fn matches(&self, ver
: &Version
) -> bool
{
331 Ex
=> self.is_exact(ver
),
332 Gt
=> self.is_greater(ver
),
333 GtEq
=> self.is_exact(ver
) || self.is_greater(ver
),
334 Lt
=> !self.is_exact(ver
) && !self.is_greater(ver
),
335 LtEq
=> !self.is_greater(ver
),
336 Tilde
=> self.matches_tilde(ver
),
337 Compatible
=> self.is_compatible(ver
),
338 Wildcard(_
) => self.matches_wildcard(ver
),
342 fn is_exact(&self, ver
: &Version
) -> bool
{
343 if self.major
!= ver
.major
{
349 if minor
!= ver
.minor
{
358 if patch
!= ver
.patch
{
365 if self.pre
!= ver
.pre
{
372 // https://docs.npmjs.com/misc/semver#prerelease-tags
373 fn pre_tag_is_compatible(&self, ver
: &Version
) -> bool
{
374 // If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will
376 // allowed to satisfy comparator sets if at least one comparator with the same
378 // minor, patch] tuple also has a prerelease tag.
379 !ver
.is_prerelease() ||
380 (self.major
== ver
.major
&& self.minor
== Some(ver
.minor
) &&
381 self.patch
== Some(ver
.patch
) && !self.pre
.is_empty())
384 fn is_greater(&self, ver
: &Version
) -> bool
{
385 if self.major
!= ver
.major
{
386 return ver
.major
> self.major
;
391 if minor
!= ver
.minor
{
392 return ver
.minor
> minor
;
395 None
=> return false,
400 if patch
!= ver
.patch
{
401 return ver
.patch
> patch
;
404 None
=> return false,
407 if !self.pre
.is_empty() {
408 return ver
.pre
.is_empty() || ver
.pre
> self.pre
;
414 // see https://www.npmjs.org/doc/misc/semver.html for behavior
415 fn matches_tilde(&self, ver
: &Version
) -> bool
{
416 let minor
= match self.minor
{
418 None
=> return self.major
== ver
.major
,
423 self.major
== ver
.major
&& minor
== ver
.minor
&&
424 (ver
.patch
> patch
|| (ver
.patch
== patch
&& self.pre_is_compatible(ver
)))
426 None
=> self.major
== ver
.major
&& minor
== ver
.minor
,
430 // see https://www.npmjs.org/doc/misc/semver.html for behavior
431 fn is_compatible(&self, ver
: &Version
) -> bool
{
432 if self.major
!= ver
.major
{
436 let minor
= match self.minor
{
438 None
=> return self.major
== ver
.major
,
445 ver
.minor
== minor
&& ver
.patch
== patch
&& self.pre_is_compatible(ver
)
447 ver
.minor
== minor
&&
448 (ver
.patch
> patch
|| (ver
.patch
== patch
&& self.pre_is_compatible(ver
)))
452 (ver
.minor
== minor
&&
453 (ver
.patch
> patch
|| (ver
.patch
== patch
&& self.pre_is_compatible(ver
))))
466 fn pre_is_compatible(&self, ver
: &Version
) -> bool
{
467 ver
.pre
.is_empty() || ver
.pre
>= self.pre
470 // see https://www.npmjs.org/doc/misc/semver.html for behavior
471 fn matches_wildcard(&self, ver
: &Version
) -> bool
{
473 Wildcard(Major
) => true,
474 Wildcard(Minor
) => self.major
== ver
.major
,
477 Some(minor
) => self.major
== ver
.major
&& minor
== ver
.minor
,
479 // minor and patch version astericks mean match on major
480 self.major
== ver
.major
484 _
=> false, // unreachable
489 impl fmt
::Display
for VersionReq
{
490 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
491 if self.predicates
.is_empty() {
492 try
!(write
!(fmt
, "*"));
494 for (i
, ref pred
) in self.predicates
.iter().enumerate() {
496 try
!(write
!(fmt
, "{}", pred
));
498 try
!(write
!(fmt
, ", {}", pred
));
507 impl fmt
::Display
for Predicate
{
508 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
510 Wildcard(Major
) => try
!(write
!(fmt
, "*")),
511 Wildcard(Minor
) => try
!(write
!(fmt
, "{}.*", self.major
)),
513 if let Some(minor
) = self.minor
{
514 try
!(write
!(fmt
, "{}.{}.*", self.major
, minor
))
516 try
!(write
!(fmt
, "{}.*.*", self.major
))
520 try
!(write
!(fmt
, "{}{}", self.op
, self.major
));
523 Some(v
) => try
!(write
!(fmt
, ".{}", v
)),
528 Some(v
) => try
!(write
!(fmt
, ".{}", v
)),
532 if !self.pre
.is_empty() {
533 try
!(write
!(fmt
, "-"));
534 for (i
, x
) in self.pre
.iter().enumerate() {
536 try
!(write
!(fmt
, "."))
538 try
!(write
!(fmt
, "{}", x
));
548 impl fmt
::Display
for Op
{
549 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
551 Ex
=> try
!(write
!(fmt
, "= ")),
552 Gt
=> try
!(write
!(fmt
, "> ")),
553 GtEq
=> try
!(write
!(fmt
, ">= ")),
554 Lt
=> try
!(write
!(fmt
, "< ")),
555 LtEq
=> try
!(write
!(fmt
, "<= ")),
556 Tilde
=> try
!(write
!(fmt
, "~")),
557 Compatible
=> try
!(write
!(fmt
, "^")),
558 // gets handled specially in Predicate::fmt
559 Wildcard(_
) => try
!(write
!(fmt
, "")),
567 use super::{VersionReq, Op}
;
568 use super::super::version
::Version
;
570 fn req(s
: &str) -> VersionReq
{
571 VersionReq
::parse(s
).unwrap()
574 fn version(s
: &str) -> Version
{
575 match Version
::parse(s
) {
577 Err(e
) => panic
!("`{}` is not a valid version. Reason: {:?}", s
, e
),
581 fn assert_match(req
: &VersionReq
, vers
: &[&str]) {
582 for ver
in vers
.iter() {
583 assert
!(req
.matches(&version(*ver
)), "did not match {}", ver
);
587 fn assert_not_match(req
: &VersionReq
, vers
: &[&str]) {
588 for ver
in vers
.iter() {
589 assert
!(!req
.matches(&version(*ver
)), "matched {}", ver
);
594 fn test_parsing_default() {
595 let r
= req("1.0.0");
597 assert_eq
!(r
.to_string(), "^1.0.0".to_string());
599 assert_match(&r
, &["1.0.0", "1.0.1"]);
600 assert_not_match(&r
, &["0.9.9", "0.10.0", "0.1.0"]);
604 fn test_parsing_exact() {
605 let r
= req("=1.0.0");
607 assert
!(r
.to_string() == "= 1.0.0".to_string());
608 assert_eq
!(r
.to_string(), "= 1.0.0".to_string());
610 assert_match(&r
, &["1.0.0"]);
611 assert_not_match(&r
, &["1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"]);
613 let r
= req("=0.9.0");
615 assert_eq
!(r
.to_string(), "= 0.9.0".to_string());
617 assert_match(&r
, &["0.9.0"]);
618 assert_not_match(&r
, &["0.9.1", "1.9.0", "0.0.9"]);
620 let r
= req("=0.1.0-beta2.a");
622 assert_eq
!(r
.to_string(), "= 0.1.0-beta2.a".to_string());
624 assert_match(&r
, &["0.1.0-beta2.a"]);
625 assert_not_match(&r
, &["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"]);
629 fn test_parse_metadata_see_issue_88_see_issue_88() {
630 for op
in &[Op
::Compatible
, Op
::Ex
, Op
::Gt
, Op
::GtEq
, Op
::Lt
, Op
::LtEq
, Op
::Tilde
] {
631 req(&format
!("{} 1.2.3+meta", op
));
636 pub fn test_parsing_greater_than() {
637 let r
= req(">= 1.0.0");
639 assert_eq
!(r
.to_string(), ">= 1.0.0".to_string());
641 assert_match(&r
, &["1.0.0", "2.0.0"]);
642 assert_not_match(&r
, &["0.1.0", "0.0.1", "1.0.0-pre", "2.0.0-pre"]);
644 let r
= req(">= 2.1.0-alpha2");
646 assert_match(&r
, &["2.1.0-alpha2", "2.1.0-alpha3", "2.1.0", "3.0.0"]);
648 &["2.0.0", "2.1.0-alpha1", "2.0.0-alpha2", "3.0.0-alpha2"]);
652 pub fn test_parsing_less_than() {
653 let r
= req("< 1.0.0");
655 assert_eq
!(r
.to_string(), "< 1.0.0".to_string());
657 assert_match(&r
, &["0.1.0", "0.0.1"]);
658 assert_not_match(&r
, &["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]);
660 let r
= req("<= 2.1.0-alpha2");
662 assert_match(&r
, &["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"]);
664 &["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"]);
668 pub fn test_multiple() {
669 let r
= req("> 0.0.9, <= 2.5.3");
670 assert_eq
!(r
.to_string(), "> 0.0.9, <= 2.5.3".to_string());
671 assert_match(&r
, &["0.0.10", "1.0.0", "2.5.3"]);
672 assert_not_match(&r
, &["0.0.8", "2.5.4"]);
674 let r
= req("0.3.0, 0.4.0");
675 assert_eq
!(r
.to_string(), "^0.3.0, ^0.4.0".to_string());
676 assert_not_match(&r
, &["0.0.8", "0.3.0", "0.4.0"]);
678 let r
= req("<= 0.2.0, >= 0.5.0");
679 assert_eq
!(r
.to_string(), "<= 0.2.0, >= 0.5.0".to_string());
680 assert_not_match(&r
, &["0.0.8", "0.3.0", "0.5.1"]);
682 let r
= req("0.1.0, 0.1.4, 0.1.6");
683 assert_eq
!(r
.to_string(), "^0.1.0, ^0.1.4, ^0.1.6".to_string());
684 assert_match(&r
, &["0.1.6", "0.1.9"]);
685 assert_not_match(&r
, &["0.1.0", "0.1.4", "0.2.0"]);
687 assert
!(VersionReq
::parse("> 0.1.0,").is_err());
688 assert
!(VersionReq
::parse("> 0.3.0, ,").is_err());
690 let r
= req(">=0.5.1-alpha3, <0.6");
691 assert_eq
!(r
.to_string(), ">= 0.5.1-alpha3, < 0.6".to_string());
693 &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]);
695 &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"]);
696 assert_not_match(&r
, &["0.6.0", "0.6.0-pre"]);
700 pub fn test_parsing_tilde() {
702 assert_match(&r
, &["1.0.0", "1.0.1", "1.1.1"]);
703 assert_not_match(&r
, &["0.9.1", "2.9.0", "0.0.9"]);
706 assert_match(&r
, &["1.2.0", "1.2.1"]);
707 assert_not_match(&r
, &["1.1.1", "1.3.0", "0.0.9"]);
709 let r
= req("~1.2.2");
710 assert_match(&r
, &["1.2.2", "1.2.4"]);
711 assert_not_match(&r
, &["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
713 let r
= req("~1.2.3-beta.2");
714 assert_match(&r
, &["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"]);
715 assert_not_match(&r
, &["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"]);
719 pub fn test_parsing_compatible() {
721 assert_match(&r
, &["1.1.2", "1.1.0", "1.2.1", "1.0.1"]);
722 assert_not_match(&r
, &["0.9.1", "2.9.0", "0.1.4"]);
723 assert_not_match(&r
, &["1.0.0-beta1", "0.1.0-alpha", "1.0.1-pre"]);
726 assert_match(&r
, &["1.1.2", "1.1.0", "1.2.1"]);
727 assert_not_match(&r
, &["0.9.1", "2.9.0", "1.0.1", "0.1.4"]);
729 let r
= req("^1.1.2");
730 assert_match(&r
, &["1.1.2", "1.1.4", "1.2.1"]);
731 assert_not_match(&r
, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
732 assert_not_match(&r
, &["1.1.2-alpha1", "1.1.3-alpha1", "2.9.0-alpha1"]);
734 let r
= req("^0.1.2");
735 assert_match(&r
, &["0.1.2", "0.1.4"]);
736 assert_not_match(&r
, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
737 assert_not_match(&r
, &["0.1.2-beta", "0.1.3-alpha", "0.2.0-pre"]);
739 let r
= req("^0.5.1-alpha3");
741 &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]);
743 &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre", "0.6.0"]);
745 let r
= req("^0.0.2");
746 assert_match(&r
, &["0.0.2"]);
747 assert_not_match(&r
, &["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]);
750 assert_match(&r
, &["0.0.2", "0.0.0"]);
751 assert_not_match(&r
, &["0.9.1", "2.9.0", "1.1.1", "0.1.4"]);
754 assert_match(&r
, &["0.9.1", "0.0.2", "0.0.0"]);
755 assert_not_match(&r
, &["2.9.0", "1.1.1"]);
757 let r
= req("^1.4.2-beta.5");
759 &["1.4.2", "1.4.3", "1.4.2-beta.5", "1.4.2-beta.6", "1.4.2-c"]);
761 &["0.9.9", "2.0.0", "1.4.2-alpha", "1.4.2-beta.4", "1.4.3-beta.5"]);
765 pub fn test_parsing_wildcard() {
767 assert_match(&r
, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
768 assert_not_match(&r
, &[]);
770 assert_match(&r
, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
771 assert_not_match(&r
, &[]);
773 assert_match(&r
, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
774 assert_not_match(&r
, &[]);
776 assert_match(&r
, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
777 assert_not_match(&r
, &[]);
780 assert_match(&r
, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
781 assert_not_match(&r
, &["0.0.9"]);
783 assert_match(&r
, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
784 assert_not_match(&r
, &["0.0.9"]);
786 assert_match(&r
, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
787 assert_not_match(&r
, &["0.0.9"]);
789 let r
= req("1.2.*");
790 assert_match(&r
, &["1.2.0", "1.2.2", "1.2.4"]);
791 assert_not_match(&r
, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
792 let r
= req("1.2.x");
793 assert_match(&r
, &["1.2.0", "1.2.2", "1.2.4"]);
794 assert_not_match(&r
, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
795 let r
= req("1.2.X");
796 assert_match(&r
, &["1.2.0", "1.2.2", "1.2.4"]);
797 assert_not_match(&r
, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
802 let r
= VersionReq
::any();
803 assert_match(&r
, &["0.0.1", "0.1.0", "1.0.0"]);
808 let r
= req("=2.1.1-really.0");
809 assert_match(&r
, &["2.1.1-really.0"]);
813 // pub fn test_parse_errors() {
814 // assert_eq!(Err(InvalidVersionRequirement), VersionReq::parse("\0"));
815 // assert_eq!(Err(OpAlreadySet), VersionReq::parse(">= >= 0.0.2"));
816 // assert_eq!(Err(InvalidSigil), VersionReq::parse(">== 0.0.2"));
817 // assert_eq!(Err(VersionComponentsMustBeNumeric),
818 // VersionReq::parse("a.0.0"));
819 // assert_eq!(Err(InvalidIdentifier), VersionReq::parse("1.0.0-"));
820 // assert_eq!(Err(MajorVersionRequired), VersionReq::parse(">="));
824 pub fn test_from_str() {
825 assert_eq
!("1.0.0".parse
::<VersionReq
>().unwrap().to_string(),
826 "^1.0.0".to_string());
827 assert_eq
!("=1.0.0".parse
::<VersionReq
>().unwrap().to_string(),
828 "= 1.0.0".to_string());
829 assert_eq
!("~1".parse
::<VersionReq
>().unwrap().to_string(),
831 assert_eq
!("~1.2".parse
::<VersionReq
>().unwrap().to_string(),
833 assert_eq
!("^1".parse
::<VersionReq
>().unwrap().to_string(),
835 assert_eq
!("^1.1".parse
::<VersionReq
>().unwrap().to_string(),
837 assert_eq
!("*".parse
::<VersionReq
>().unwrap().to_string(),
839 assert_eq
!("1.*".parse
::<VersionReq
>().unwrap().to_string(),
841 assert_eq
!("< 1.0.0".parse
::<VersionReq
>().unwrap().to_string(),
842 "< 1.0.0".to_string());
846 // pub fn test_from_str_errors() {
847 // assert_eq!(Err(InvalidVersionRequirement), "\0".parse::<VersionReq>());
848 // assert_eq!(Err(OpAlreadySet), ">= >= 0.0.2".parse::<VersionReq>());
849 // assert_eq!(Err(InvalidSigil), ">== 0.0.2".parse::<VersionReq>());
850 // assert_eq!(Err(VersionComponentsMustBeNumeric),
851 // "a.0.0".parse::<VersionReq>());
852 // assert_eq!(Err(InvalidIdentifier), "1.0.0-".parse::<VersionReq>());
853 // assert_eq!(Err(MajorVersionRequired), ">=".parse::<VersionReq>());
857 fn test_cargo3202() {
858 let v
= "0.*.*".parse
::<VersionReq
>().unwrap();
859 assert_eq
!("0.*.*", format
!("{}", v
.predicates
[0]));
861 let v
= "0.0.*".parse
::<VersionReq
>().unwrap();
862 assert_eq
!("0.0.*", format
!("{}", v
.predicates
[0]));
864 let r
= req("0.*.*");
865 assert_match(&r
, &["0.5.0"]);