Skip to main content

chrome_for_testing_manager/
version.rs

1use chrome_for_testing::{
2    Channel, Download, Platform, Version, VersionInChannel, VersionWithoutChannel,
3};
4
5/// How to pick which Chrome / `ChromeDriver` version to install and run.
6///
7/// See the named constructors ([`Self::stable`], [`Self::beta`], [`Self::dev`], [`Self::canary`])
8/// and the `From<Channel>` / `From<Version>` impls for the most ergonomic forms.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum VersionRequest {
11    /// Uses the latest working version. Might not be stable yet.
12    /// You may want to prefer variant [`VersionRequest::LatestIn`] instead.
13    Latest,
14
15    /// Use the latest release from the given [`Channel`],
16    /// e.g. the one from the [`Channel::Stable`] channel.
17    LatestIn(Channel),
18
19    /// Pin a specific version to use.
20    Fixed(Version),
21}
22
23impl From<Channel> for VersionRequest {
24    fn from(channel: Channel) -> Self {
25        Self::LatestIn(channel)
26    }
27}
28
29impl From<Version> for VersionRequest {
30    fn from(version: Version) -> Self {
31        Self::Fixed(version)
32    }
33}
34
35impl VersionRequest {
36    /// Latest release from the [`Channel::Stable`] channel.
37    #[must_use]
38    pub fn stable() -> Self {
39        Self::LatestIn(Channel::Stable)
40    }
41
42    /// Latest release from the [`Channel::Beta`] channel.
43    #[must_use]
44    pub fn beta() -> Self {
45        Self::LatestIn(Channel::Beta)
46    }
47
48    /// Latest release from the [`Channel::Dev`] channel.
49    #[must_use]
50    pub fn dev() -> Self {
51        Self::LatestIn(Channel::Dev)
52    }
53
54    /// Latest release from the [`Channel::Canary`] channel.
55    #[must_use]
56    pub fn canary() -> Self {
57        Self::LatestIn(Channel::Canary)
58    }
59}
60
61/// A version of Chrome and `ChromeDriver` that has been resolved against the
62/// chrome-for-testing release index but not yet downloaded.
63///
64/// Construct via [`crate::ChromeForTestingManager::resolve_version`] and pass into
65/// [`crate::ChromeForTestingManager::download`].
66#[derive(Debug)]
67pub struct SelectedVersion {
68    pub(crate) channel: Option<Channel>,
69    pub(crate) version: Version,
70    pub(crate) chrome: Option<Download>,
71    pub(crate) chromedriver: Option<Download>,
72}
73
74impl SelectedVersion {
75    /// The release channel this version was resolved through, if any.
76    /// `None` for versions resolved by [`VersionRequest::Latest`] or [`VersionRequest::Fixed`].
77    #[must_use]
78    pub fn channel(&self) -> Option<&Channel> {
79        self.channel.as_ref()
80    }
81
82    /// The pinned [`Version`] that will be downloaded.
83    #[must_use]
84    pub fn version(&self) -> Version {
85        self.version
86    }
87
88    /// Whether a Chrome download exists for this version on the detected platform.
89    #[must_use]
90    pub fn has_chrome_download(&self) -> bool {
91        self.chrome.is_some()
92    }
93
94    /// Whether a `ChromeDriver` download exists for this version on the detected platform.
95    #[must_use]
96    pub fn has_chromedriver_download(&self) -> bool {
97        self.chromedriver.is_some()
98    }
99}
100
101impl From<(VersionWithoutChannel, Platform)> for SelectedVersion {
102    fn from((v, p): (VersionWithoutChannel, Platform)) -> Self {
103        SelectedVersion {
104            channel: None,
105            version: v.version,
106            chrome: v.downloads.chrome_for_platform(p).cloned(),
107            chromedriver: v.downloads.chromedriver_for_platform(p).cloned(),
108        }
109    }
110}
111
112impl From<(VersionInChannel, Platform)> for SelectedVersion {
113    fn from((v, p): (VersionInChannel, Platform)) -> Self {
114        let chrome_download = v.downloads.chrome_for_platform(p).cloned();
115        let chromedriver_download = v.downloads.chromedriver_for_platform(p).cloned();
116
117        SelectedVersion {
118            channel: Some(v.channel),
119            version: v.version,
120            chrome: chrome_download,
121            chromedriver: chromedriver_download,
122        }
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129    use assertr::prelude::*;
130
131    mod version_request {
132        use super::*;
133
134        #[test]
135        fn from_channel_resolves_to_latest_in_channel() {
136            assert_that!(VersionRequest::from(Channel::Stable))
137                .is_equal_to(VersionRequest::LatestIn(Channel::Stable));
138        }
139
140        #[test]
141        fn named_constructors_match_explicit_variants() {
142            assert_that!(VersionRequest::stable())
143                .is_equal_to(VersionRequest::LatestIn(Channel::Stable));
144            assert_that!(VersionRequest::beta())
145                .is_equal_to(VersionRequest::LatestIn(Channel::Beta));
146            assert_that!(VersionRequest::dev()).is_equal_to(VersionRequest::LatestIn(Channel::Dev));
147            assert_that!(VersionRequest::canary())
148                .is_equal_to(VersionRequest::LatestIn(Channel::Canary));
149        }
150
151        #[test]
152        fn from_parsed_version_resolves_to_fixed() {
153            let v: Version = "135.0.7019.0".parse().expect("valid version literal");
154            assert_that!(VersionRequest::from(v)).is_equal_to(VersionRequest::Fixed(v));
155        }
156    }
157}