Skip to content

Commit 69d3d82

Browse files
committed
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 3abcea6 commit 69d3d82

File tree

4 files changed

+132
-3
lines changed

4 files changed

+132
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88
## Unreleased
99

1010
### Added
11+
- Implement mock for `embedded_hal::pwm::SetDutyCycle`
1112

1213
### Fixed
1314

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/pin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//! Mock digital [`InputPin`] and [`OutputPin`] v2 implementations
1+
//! Mock digital [`InputPin`] and [`OutputPin`] implementations
22
//!
3-
//! [`InputPin`]: https://docs.rs/embedded-hal/1.0.0-alpha.6/embedded_hal/digital/trait.InputPin.html
4-
//! [`OutputPin`]: https://docs.rs/embedded-hal/1.0.0-alpha.6/embedded_hal/digital/trait.OutputPin.html
3+
//! [`InputPin`]: https://docs.rs/embedded-hal/1.0.0-rc.1/embedded_hal/digital/trait.InputPin.html
4+
//! [`OutputPin`]: https://docs.rs/embedded-hal/1.0.0-rc.1/embedded_hal/digital/trait.OutputPin.html
55
//!
66
//! ```
77
//! # use eh1 as embedded_hal;

src/eh1/pwm.rs

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

0 commit comments

Comments
 (0)