Skip to content

Commit a5ed62a

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 33b0458 commit a5ed62a

File tree

4 files changed

+139
-3
lines changed

4 files changed

+139
-3
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## Unreleased
9+
10+
### Added
11+
12+
- Implement mock for `embedded_hal::pwm::SetDutyCycle`
813

914
## 0.8.0 - 2021-08-16
1015

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ pub mod common;
2828
pub mod delay;
2929
pub mod i2c;
3030
pub mod pin;
31+
pub mod pwm;
3132
pub mod serial;
3233
pub mod spi;

src/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-alpha.10/embedded_hal/digital/trait.InputPin.html
4+
//! [`OutputPin`]: https://docs.rs/embedded-hal/1.0.0-alpha.10/embedded_hal/digital/trait.OutputPin.html
55
//!
66
//! ```
77
//! use std::io::ErrorKind;

src/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::MockError;
8+
//! use embedded_hal_mock::pwm::{Transaction as PwmTransaction, Mock as PwmMock};
9+
//! use embedded_hal::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::error::MockError;
37+
use embedded_hal::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 embedded_hal::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)