Skip to content

Commit ec4b93b

Browse files
rursprungcdunster
authored andcommitted
add SetDutyCycle mock
this is the 1.0 equivalent of the old `PwmPin` trait (the mock for this has been added in dbrgn#52). note that the test coverage is fully handled by the doc test which is why there's no additional `mod test` in this file. this fixes dbrgn#73
1 parent 1d970f1 commit ec4b93b

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ contributions!
3131
- Support for both `embedded-hal` 0.x and 1.x in the same crate (#75)
3232
- Print a warning to stderr and fail test if a mock is dropped without having
3333
calling `.done()` on it, or if `.done()` is called twice (#59, #61)
34+
- Implement mock for `embedded_hal::pwm::SetDutyCycle`
3435

3536
### Fixed
3637

src/eh1.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ pub use crate::eh1::error::MockError;
1010
pub mod delay;
1111
pub mod i2c;
1212
pub mod pin;
13+
pub mod pwm;
1314
pub mod serial;
1415
pub mod spi;

src/eh1/pwm.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//! Mock implementations for [`embedded_hal::pwm`].
2+
//!
3+
//! Usage example:
4+
//! ```
5+
//! use std::io::ErrorKind;
6+
//!
7+
//! use embedded_hal_mock::eh1::MockError;
8+
//! use embedded_hal_mock::eh1::pwm::{Transaction as PwmTransaction, Mock as PwmMock};
9+
//! use eh1::pwm::SetDutyCycle;
10+
//!
11+
//! let err = MockError::Io(ErrorKind::NotConnected);
12+
//!
13+
//! // Configure expectations
14+
//! let expectations = [
15+
//! PwmTransaction::get_max_duty_cycle(100),
16+
//! PwmTransaction::set_duty_cycle(50),
17+
//! PwmTransaction::set_duty_cycle(101).with_error(err.clone()),
18+
//! ];
19+
//!
20+
//! // Create pin
21+
//! let mut pwm = PwmMock::new(&expectations);
22+
//!
23+
//! // Run and test
24+
//! pwm.set_duty_cycle_percent(50).unwrap();
25+
//! pwm.set_duty_cycle(101).expect_err("expected error return");
26+
//!
27+
//! pwm.done();
28+
//!
29+
//! // Update expectations
30+
//! pwm.expect(&[]);
31+
//! // ...
32+
//! pwm.done();
33+
//! ```
34+
35+
use crate::common::Generic;
36+
use crate::eh1::MockError;
37+
use eh1::pwm::{ErrorKind, ErrorType, SetDutyCycle};
38+
39+
/// MockPwm transaction
40+
#[derive(PartialEq, Clone, Debug)]
41+
pub struct Transaction {
42+
/// Kind is the transaction kind (and data) expected
43+
kind: TransactionKind,
44+
/// Err is an optional error return for a transaction.
45+
/// This is in addition to kind to allow validation that the transaction kind
46+
/// is correct prior to returning the error.
47+
err: Option<MockError>,
48+
}
49+
50+
impl Transaction {
51+
/// Create a new PWM transaction
52+
pub fn new(kind: TransactionKind) -> Transaction {
53+
Transaction { kind, err: None }
54+
}
55+
56+
/// Create a new [`TransactionKind::GetMaxDutyCycle`] transaction for [`SetDutyCycle::get_max_duty_cycle`].
57+
pub fn get_max_duty_cycle(duty: u16) -> Transaction {
58+
Transaction::new(TransactionKind::GetMaxDutyCycle(duty))
59+
}
60+
61+
/// Create a new [`TransactionKind::SetDutyCycle`] transaction for [`SetDutyCycle::set_duty_cycle`].
62+
pub fn set_duty_cycle(duty: u16) -> Transaction {
63+
Transaction::new(TransactionKind::SetDutyCycle(duty))
64+
}
65+
66+
/// Add an error return to a transaction
67+
///
68+
/// This is used to mock failure behaviours.
69+
pub fn with_error(mut self, error: MockError) -> Self {
70+
self.err = Some(error);
71+
self
72+
}
73+
}
74+
75+
/// MockPwm transaction kind
76+
#[derive(PartialEq, Clone, Debug)]
77+
pub enum TransactionKind {
78+
/// [`SetDutyCycle::get_max_duty_cycle`] which will return the defined duty.
79+
GetMaxDutyCycle(u16),
80+
/// [`SetDutyCycle::set_duty_cycle`] with the expected duty.
81+
SetDutyCycle(u16),
82+
}
83+
84+
/// Mock SetDutyCycle implementation
85+
pub type Mock = Generic<Transaction>;
86+
87+
impl eh1::pwm::Error for MockError {
88+
fn kind(&self) -> ErrorKind {
89+
ErrorKind::Other
90+
}
91+
}
92+
93+
impl ErrorType for Mock {
94+
type Error = MockError;
95+
}
96+
97+
impl SetDutyCycle for Mock {
98+
fn get_max_duty_cycle(&self) -> u16 {
99+
let mut s = self.clone();
100+
101+
let Transaction { kind, err } = s
102+
.next()
103+
.expect("no expectation for get_max_duty_cycle call");
104+
105+
assert_eq!(err, None, "error not supported by get_max_duty_cycle!");
106+
107+
if let TransactionKind::GetMaxDutyCycle(duty) = kind {
108+
duty
109+
} else {
110+
unreachable!();
111+
}
112+
}
113+
114+
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
115+
let Transaction { kind, err } =
116+
self.next().expect("no expectation for set_duty_cycle call");
117+
118+
assert_eq!(
119+
kind,
120+
TransactionKind::SetDutyCycle(duty),
121+
"expected set_duty_cycle"
122+
);
123+
124+
if let Some(e) = err {
125+
Err(e)
126+
} else {
127+
Ok(())
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)