Skip to main content

nextest_runner/config/elements/
priority.rs

1// Copyright (c) The nextest Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use crate::errors::TestPriorityOutOfRange;
5use serde::{Deserialize, Deserializer};
6
7/// A test priority between -100 and 100, inclusive. Higher values run sooner.
8#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
9#[cfg_attr(feature = "config-schema", derive(schemars::JsonSchema))]
10pub struct TestPriority(
11    #[cfg_attr(feature = "config-schema", schemars(range(min = -100, max = 100)))] i8,
12);
13
14impl TestPriority {
15    /// Creates a new `TestPriority`.
16    pub fn new(priority: i8) -> Result<Self, TestPriorityOutOfRange> {
17        if !(-100..=100).contains(&priority) {
18            return Err(TestPriorityOutOfRange { priority });
19        }
20        Ok(Self(priority))
21    }
22
23    /// Returns the priority as an `i8`.
24    pub fn to_i8(self) -> i8 {
25        self.0
26    }
27}
28
29impl PartialOrd for TestPriority {
30    #[inline]
31    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
32        Some(self.cmp(other))
33    }
34}
35
36impl Ord for TestPriority {
37    #[inline]
38    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
39        // Reverse the order to sort from highest to lowest priority.
40        other.0.cmp(&self.0)
41    }
42}
43
44impl<'de> Deserialize<'de> for TestPriority {
45    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46    where
47        D: Deserializer<'de>,
48    {
49        let priority = i8::deserialize(deserializer)?;
50        TestPriority::new(priority).map_err(serde::de::Error::custom)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn priority_out_of_range() {
60        let priority = TestPriority::new(-101);
61        priority.expect_err("priority must be between -100 and 100");
62
63        let priority = TestPriority::new(101);
64        priority.expect_err("priority must be between -100 and 100");
65    }
66
67    #[test]
68    fn priority_deserialize() {
69        let priority: TestPriority = serde_json::from_str("-100").unwrap();
70        assert_eq!(priority.to_i8(), -100);
71
72        let priority: TestPriority = serde_json::from_str("0").unwrap();
73        assert_eq!(priority.to_i8(), 0);
74
75        let priority: TestPriority = serde_json::from_str("100").unwrap();
76        assert_eq!(priority.to_i8(), 100);
77
78        let priority: Result<TestPriority, _> = serde_json::from_str("-101");
79        priority.expect_err("priority must be between -100 and 100");
80
81        let priority: Result<TestPriority, _> = serde_json::from_str("101");
82        priority.expect_err("priority must be between -100 and 100");
83    }
84
85    #[test]
86    fn priority_sort_order() {
87        let mut priorities = vec![
88            TestPriority::new(0).unwrap(),
89            TestPriority::new(100).unwrap(),
90            TestPriority::new(-100).unwrap(),
91        ];
92        priorities.sort();
93        assert_eq!(
94            priorities,
95            [
96                TestPriority::new(100).unwrap(),
97                TestPriority::new(0).unwrap(),
98                TestPriority::new(-100).unwrap()
99            ]
100        );
101    }
102}