|
| 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