Skip to content

Commit

Permalink
Add support for ToggleableOutputPin for pin::Mock
Browse files Browse the repository at this point in the history
  • Loading branch information
cdunster committed Sep 18, 2023
1 parent 7c9373d commit f8b507b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 11 deletions.
54 changes: 50 additions & 4 deletions src/eh0/pin.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Mock digital [`InputPin`] and [`OutputPin`] v2 implementations
//! Mock digital [`InputPin`], [`OutputPin`], and [`ToggleableOutputPin`] v2 implementations
//!
//! [`InputPin`]: https://docs.rs/embedded-hal/0.2/embedded_hal/digital/v2/trait.InputPin.html
//! [`OutputPin`]: https://docs.rs/embedded-hal/0.2/embedded_hal/digital/v2/trait.OutputPin.html
//! [`ToggleableOutputPin`]: https://docs.rs/embedded-hal/0.2/embedded_hal/digital/v2/trait.ToggleableOutputPin.html
//!
//! ```
//! # use eh0 as embedded_hal;
//! use std::io::ErrorKind;
//!
//! use embedded_hal_mock::eh0::MockError;
//! use embedded_hal_mock::eh0::pin::{Transaction as PinTransaction, Mock as PinMock, State as PinState};
//! use embedded_hal::digital::v2::{InputPin, OutputPin};
//! use embedded_hal::digital::v2::{InputPin, OutputPin, ToggleableOutputPin};
//!
//! let err = MockError::Io(ErrorKind::NotConnected);
//!
Expand All @@ -19,6 +20,7 @@
//! PinTransaction::get(PinState::High),
//! PinTransaction::set(PinState::Low),
//! PinTransaction::set(PinState::High).with_error(err.clone()),
//! PinTransaction::toggle(),
//! ];
//!
//! // Create pin
Expand All @@ -31,6 +33,8 @@
//! pin.set_low().unwrap();
//! pin.set_high().expect_err("expected error return");
//!
//! pin.toggle().unwrap();
//!
//! pin.done();
//!
//! // Update expectations
Expand All @@ -44,7 +48,7 @@ use super::error::MockError;
use crate::common::Generic;

use eh0 as embedded_hal;
use embedded_hal::digital::v2::{InputPin, OutputPin};
use embedded_hal::digital::v2::{InputPin, OutputPin, ToggleableOutputPin};
use embedded_hal::PwmPin;

/// The type used for the duty of the [`PwmPin`] mock.
Expand Down Expand Up @@ -81,6 +85,11 @@ impl Transaction {
Transaction::new(TransactionKind::Get(state))
}

/// Create a new toggle transaction
pub fn toggle() -> Transaction {
Transaction::new(TransactionKind::Toggle)
}

/// Create a new get transaction
pub fn set(state: State) -> Transaction {
Transaction::new(TransactionKind::Set(state))
Expand Down Expand Up @@ -134,6 +143,8 @@ pub enum TransactionKind {
Set(State),
/// Get the pin state
Get(State),
/// Toggle for an expected toggle of the pin
Toggle,
/// Disable a [`PwmPin`] using [`PwmPin::disable`]
Disable,
/// Enable a [`PwmPin`] using [`PwmPin::enable`]
Expand All @@ -157,7 +168,7 @@ impl TransactionKind {
/// Specifies whether the actual API returns a [`Result`] (= supports errors) or not.
fn supports_errors(&self) -> bool {
match self {
TransactionKind::Set(_) | TransactionKind::Get(_) => true,
TransactionKind::Set(_) | TransactionKind::Get(_) | TransactionKind::Toggle => true,
_ => false,
}
}
Expand Down Expand Up @@ -243,6 +254,24 @@ impl InputPin for Mock {
}
}

/// Single digital output pin that can be toggled between high and low states
impl ToggleableOutputPin for Mock {
/// Error type
type Error = MockError;

/// Toggle the pin low to high or high to low
fn toggle(&mut self) -> Result<(), Self::Error> {
let Transaction { kind, err } = self.next().expect("no expectation for pin::toggle call");

assert_eq!(kind, TransactionKind::Toggle, "expected pin::toggle");

match err {
Some(e) => Err(e),
None => Ok(()),
}
}
}

impl PwmPin for Mock {
type Duty = PwmDuty;

Expand Down Expand Up @@ -348,6 +377,23 @@ mod test {
pin.done();
}

#[test]
fn test_toggleable_output_pin() {
let expectations = [
Transaction::new(Toggle),
Transaction::toggle(),
Transaction::new(Toggle).with_error(MockError::Io(ErrorKind::NotConnected)),
];
let mut pin = Mock::new(&expectations);

pin.toggle().unwrap();
pin.toggle().unwrap();

pin.toggle().expect_err("expected error return");

pin.done();
}

#[test]
fn test_pwm_pin() {
let expected_duty = 10_000;
Expand Down
57 changes: 50 additions & 7 deletions src/eh1/pin.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Mock digital [`InputPin`] and [`OutputPin`] v2 implementations
//! Mock digital [`InputPin`], [`OutputPin`], and [`ToggleableOutputPin`] implementations
//!
//! [`InputPin`]: https://docs.rs/embedded-hal/1.0.0-alpha.6/embedded_hal/digital/trait.InputPin.html
//! [`OutputPin`]: https://docs.rs/embedded-hal/1.0.0-alpha.6/embedded_hal/digital/trait.OutputPin.html
//! [`InputPin`]: https://docs.rs/embedded-hal/1.0.0-rc.1/embedded_hal/digital/trait.InputPin.html
//! [`OutputPin`]: https://docs.rs/embedded-hal/1.0.0-rc.1/embedded_hal/digital/trait.OutputPin.html
//! [`ToggleableOutputPin`]: https://docs.rs/embedded-hal/1.0.0-rc.1/embedded_hal/digital/trait.ToggleableOutputPin.html
//!
//! ```
//! # use eh1 as embedded_hal;
//! use std::io::ErrorKind;
//!
//! use embedded_hal_mock::eh1::MockError;
//! use embedded_hal_mock::eh1::pin::{Transaction as PinTransaction, Mock as PinMock, State as PinState};
//! use embedded_hal::digital::{InputPin, OutputPin};
//! use embedded_hal::digital::{InputPin, OutputPin, ToggleableOutputPin};
//!
//! let err = MockError::Io(ErrorKind::NotConnected);
//!
Expand All @@ -19,6 +20,7 @@
//! PinTransaction::get(PinState::High),
//! PinTransaction::set(PinState::Low),
//! PinTransaction::set(PinState::High).with_error(err.clone()),
//! PinTransaction::toggle(),
//! ];
//!
//! // Create pin
Expand All @@ -31,6 +33,8 @@
//! pin.set_low().unwrap();
//! pin.set_high().expect_err("expected error return");
//!
//! pin.toggle().unwrap();
//!
//! pin.done();
//!
//! // Update expectations
Expand All @@ -44,7 +48,7 @@ use crate::common::Generic;
use crate::eh1::error::MockError;
use eh1 as embedded_hal;

use embedded_hal::digital::{ErrorType, InputPin, OutputPin};
use embedded_hal::digital::{ErrorType, InputPin, OutputPin, ToggleableOutputPin};

/// MockPin transaction
#[derive(PartialEq, Eq, Clone, Debug)]
Expand Down Expand Up @@ -82,6 +86,11 @@ impl Transaction {
Transaction::new(TransactionKind::Set(state))
}

/// Create a new toggle transaction
pub fn toggle() -> Transaction {
Transaction::new(TransactionKind::Toggle)
}

/// Add an error return to a transaction
///
/// This is used to mock failure behaviours.
Expand All @@ -105,6 +114,8 @@ pub enum TransactionKind {
Set(State),
/// Get the pin state
Get(State),
/// Toggle for an expected toggle of the pin
Toggle,
}

impl TransactionKind {
Expand Down Expand Up @@ -199,16 +210,31 @@ impl InputPin for Mock {
}
}

/// Single digital output pin that can be toggled between high and low states
impl ToggleableOutputPin for Mock {
/// Toggle the pin low to high or high to low
fn toggle(&mut self) -> Result<(), Self::Error> {
let Transaction { kind, err } = self.next().expect("no expectation for pin::toggle call");

assert_eq!(kind, TransactionKind::Toggle, "expected pin::toggle");

match err {
Some(e) => Err(e),
None => Ok(()),
}
}
}

#[cfg(test)]
mod test {
use super::super::error::MockError;
use super::TransactionKind::{Get, Set};
use super::TransactionKind::{Get, Set, Toggle};
use super::*;

use std::io::ErrorKind;

use eh1 as embedded_hal;
use embedded_hal::digital::{InputPin, OutputPin};
use embedded_hal::digital::{InputPin, OutputPin, ToggleableOutputPin};

#[test]
fn test_input_pin() {
Expand Down Expand Up @@ -247,4 +273,21 @@ mod test {

pin.done();
}

#[test]
fn test_toggleable_output_pin() {
let expectations = [
Transaction::new(Toggle),
Transaction::toggle(),
Transaction::new(Toggle).with_error(MockError::Io(ErrorKind::NotConnected)),
];
let mut pin = Mock::new(&expectations);

pin.toggle().unwrap();
pin.toggle().unwrap();

pin.toggle().expect_err("expected error return");

pin.done();
}
}

0 comments on commit f8b507b

Please sign in to comment.