Skip to content

Commit dae2ab2

Browse files
authored
refactor: improve rf24-rs tests (#26)
also adds some constants for bitwise masks to replace magic numbers
1 parent f468315 commit dae2ab2

17 files changed

Lines changed: 263 additions & 537 deletions

crates/rf24-rs/src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ pub mod radio;
7474

7575
#[cfg(test)]
7676
mod test {
77+
use crate::radio::RF24;
78+
use embedded_hal_mock::eh1::{
79+
delay::NoopDelay,
80+
digital::{Mock as PinMock, Transaction as PinTransaction},
81+
spi::{Mock as SpiMock, Transaction as SpiTransaction},
82+
};
83+
7784
/// Takes an indefinite repetition of a tuple of 2 vectors: `(expected_data, response_data)`
7885
/// and generates an array of `SpiTransaction`s.
7986
///
@@ -90,4 +97,25 @@ mod test {
9097
]
9198
}
9299
}
100+
101+
/// A tuple struct to encapsulate objects used to mock [`RF24`],
102+
pub struct MockRadio(
103+
pub RF24<SpiMock<u8>, PinMock, NoopDelay>,
104+
pub SpiMock<u8>,
105+
pub PinMock,
106+
);
107+
108+
/// Create a mock objects using the given expectations.
109+
///
110+
/// The `spi_expectations` parameter
111+
pub fn mk_radio(
112+
ce_expectations: &[PinTransaction],
113+
spi_expectations: &[SpiTransaction<u8>],
114+
) -> MockRadio {
115+
let spi = SpiMock::new(spi_expectations);
116+
let ce_pin = PinMock::new(ce_expectations);
117+
let delay_impl = NoopDelay;
118+
let radio = RF24::new(ce_pin.clone(), spi.clone(), delay_impl);
119+
MockRadio(radio, spi, ce_pin)
120+
}
93121
}

crates/rf24-rs/src/radio/rf24/auto_ack.rs

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,16 @@ where
8282
#[cfg(test)]
8383
mod test {
8484
extern crate std;
85-
use crate::radio::prelude::{EsbAutoAck, EsbPayloadLength};
86-
use crate::spi_test_expects;
87-
88-
use super::{commands, registers, RF24};
89-
use embedded_hal_mock::eh1::delay::NoopDelay;
90-
use embedded_hal_mock::eh1::digital::Mock as PinMock;
91-
use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
85+
use super::{commands, registers, EsbAutoAck};
86+
use crate::{radio::prelude::EsbPayloadLength, spi_test_expects, test::mk_radio};
87+
use embedded_hal_mock::eh1::spi::Transaction as SpiTransaction;
9288
use std::vec;
9389

9490
const EN_ACK_PAY: u8 = 1 << 1;
9591
const EN_DPL: u8 = 1 << 2;
9692

9793
#[test]
9894
pub fn allow_ack_payloads() {
99-
// Create pin
100-
let pin_expectations = [];
101-
let mut pin_mock = PinMock::new(&pin_expectations);
102-
103-
// create delay fn
104-
let delay_mock = NoopDelay::new();
10595
let mut ack_buf = [0x55; 3];
10696
let valid_pipe = 2;
10797
ack_buf[0] = commands::W_ACK_PAYLOAD | valid_pipe;
@@ -150,8 +140,8 @@ mod test {
150140
vec![0xEu8, 0u8],
151141
),
152142
];
153-
let mut spi_mock = SpiMock::new(&spi_expectations);
154-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
143+
let mocks = mk_radio(&[], &spi_expectations);
144+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
155145
radio.set_ack_payloads(true).unwrap();
156146
// do again for region coverage (should result in Ok non-op)
157147
radio.set_ack_payloads(true).unwrap();
@@ -168,19 +158,12 @@ mod test {
168158
radio.set_auto_ack_pipe(false, 0).unwrap();
169159
// disable pipe 1 for region coverage
170160
radio.set_auto_ack_pipe(false, 1).unwrap();
171-
spi_mock.done();
172-
pin_mock.done();
161+
spi.done();
162+
ce_pin.done();
173163
}
174164

175165
#[test]
176166
pub fn set_auto_ack() {
177-
// Create pin
178-
let pin_expectations = [];
179-
let mut pin_mock = PinMock::new(&pin_expectations);
180-
181-
// create delay fn
182-
let delay_mock = NoopDelay::new();
183-
184167
let spi_expectations = spi_test_expects![
185168
// enable ACK payloads
186169
// read/write FEATURE register
@@ -214,25 +197,18 @@ mod test {
214197
// read RX_PL_WID
215198
(vec![commands::R_RX_PL_WID, 0u8], vec![0xEu8, 32]),
216199
];
217-
let mut spi_mock = SpiMock::new(&spi_expectations);
218-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
200+
let mocks = mk_radio(&[], &spi_expectations);
201+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
219202
radio.set_ack_payloads(true).unwrap();
220203
assert!(radio.get_ack_payloads());
221204
radio.set_auto_ack(false).unwrap();
222205
assert_eq!(radio.get_dynamic_payload_length().unwrap(), 32u8);
223-
spi_mock.done();
224-
pin_mock.done();
206+
spi.done();
207+
ce_pin.done();
225208
}
226209

227210
#[test]
228211
pub fn allow_ask_no_ack() {
229-
// Create pin
230-
let pin_expectations = [];
231-
let mut pin_mock = PinMock::new(&pin_expectations);
232-
233-
// create delay fn
234-
let delay_mock = NoopDelay::new();
235-
236212
let spi_expectations = spi_test_expects![
237213
// disable EN_DYN_ACK flag in FEATURE register
238214
(vec![registers::FEATURE, 0u8], vec![0u8, EN_ACK_PAY]),
@@ -241,10 +217,10 @@ mod test {
241217
vec![0xEu8, 0u8],
242218
),
243219
];
244-
let mut spi_mock = SpiMock::new(&spi_expectations);
245-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
220+
let mocks = mk_radio(&[], &spi_expectations);
221+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
246222
radio.allow_ask_no_ack(true).unwrap();
247-
spi_mock.done();
248-
pin_mock.done();
223+
spi.done();
224+
ce_pin.done();
249225
}
250226
}

crates/rf24-rs/src/radio/rf24/bit_fields.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub(crate) struct Config {
3030
}
3131

3232
impl Config {
33-
const CRC_MASK: u8 = 0b1100;
33+
pub(crate) const CRC_MASK: u8 = 0b1100;
3434

3535
pub const fn crc_length(&self) -> CrcLength {
3636
CrcLength::from_bits(self.into_bits() & Self::CRC_MASK)

crates/rf24-rs/src/radio/rf24/channel.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,23 @@ where
2828
#[cfg(test)]
2929
mod test {
3030
extern crate std;
31-
use crate::radio::prelude::EsbChannel;
32-
use crate::spi_test_expects;
33-
34-
use super::{registers, RF24};
35-
use embedded_hal_mock::eh1::delay::NoopDelay;
36-
use embedded_hal_mock::eh1::digital::Mock as PinMock;
37-
use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
31+
use super::{registers, EsbChannel};
32+
use crate::{spi_test_expects, test::mk_radio};
33+
use embedded_hal_mock::eh1::spi::Transaction as SpiTransaction;
3834
use std::vec;
3935

4036
// set_channel() is already tested in RF24::init() and RF24::start_carrier_wave()
4137

4238
#[test]
4339
pub fn get_channel() {
44-
// Create pin
45-
let pin_expectations = [];
46-
let mut pin_mock = PinMock::new(&pin_expectations);
47-
48-
// create delay fn
49-
let delay_mock = NoopDelay::new();
50-
5140
let spi_expectations = spi_test_expects![
5241
// get the RF_CH register value
5342
(vec![registers::RF_CH, 0u8], vec![0xEu8, 76u8]),
5443
];
55-
let mut spi_mock = SpiMock::new(&spi_expectations);
56-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
44+
let mocks = mk_radio(&[], &spi_expectations);
45+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
5746
assert_eq!(radio.get_channel().unwrap(), 76u8);
58-
spi_mock.done();
59-
pin_mock.done();
47+
spi.done();
48+
ce_pin.done();
6049
}
6150
}

crates/rf24-rs/src/radio/rf24/crc_length.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ where
1414

1515
fn get_crc_length(&mut self) -> Result<CrcLength, Self::CrcLengthErrorType> {
1616
self.spi_read(1, registers::CONFIG)?;
17-
if self._buf[1] & 12 == 4 {
17+
if self._buf[1] & Config::CRC_MASK == 4 {
1818
return Err(Nrf24Error::BinaryCorruption);
1919
}
2020
self._config_reg = Config::from_bits(self._buf[1]);
@@ -33,54 +33,35 @@ where
3333
#[cfg(test)]
3434
mod test {
3535
extern crate std;
36-
use crate::radio::prelude::EsbCrcLength;
37-
use crate::radio::rf24::commands;
38-
use crate::{spi_test_expects, CrcLength};
39-
40-
use super::{registers, RF24};
41-
use embedded_hal_mock::eh1::delay::NoopDelay;
42-
use embedded_hal_mock::eh1::digital::Mock as PinMock;
43-
use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
36+
use super::{registers, EsbCrcLength};
37+
use crate::{radio::rf24::commands, spi_test_expects, test::mk_radio, CrcLength};
38+
use embedded_hal_mock::eh1::spi::Transaction as SpiTransaction;
4439
use std::vec;
4540

4641
#[test]
4742
pub fn get_crc_length() {
48-
// Create pin
49-
let pin_expectations = [];
50-
let mut pin_mock = PinMock::new(&pin_expectations);
51-
52-
// create delay fn
53-
let delay_mock = NoopDelay::new();
54-
5543
let spi_expectations = spi_test_expects![
5644
// get the CONFIG register value for each possible result
5745
(vec![registers::CONFIG, 0u8], vec![0xEu8, 0u8]),
5846
(vec![registers::CONFIG, 0u8], vec![0xEu8, 0x8u8]),
5947
(vec![registers::CONFIG, 0x8u8], vec![0xEu8, 0xCu8]),
6048
(vec![registers::CONFIG, 0xCu8], vec![0xEu8, 4u8]),
6149
];
62-
let mut spi_mock = SpiMock::new(&spi_expectations);
63-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
50+
let mocks = mk_radio(&[], &spi_expectations);
51+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
6452
assert_eq!(radio.get_crc_length(), Ok(CrcLength::Disabled));
6553
assert_eq!(radio.get_crc_length(), Ok(CrcLength::Bit8));
6654
assert_eq!(radio.get_crc_length(), Ok(CrcLength::Bit16));
6755
assert_eq!(
6856
radio.get_crc_length(),
6957
Err(crate::radio::Nrf24Error::BinaryCorruption)
7058
);
71-
spi_mock.done();
72-
pin_mock.done();
59+
spi.done();
60+
ce_pin.done();
7361
}
7462

7563
#[test]
7664
pub fn set_crc_length() {
77-
// Create pin
78-
let pin_expectations = [];
79-
let mut pin_mock = PinMock::new(&pin_expectations);
80-
81-
// create delay fn
82-
let delay_mock = NoopDelay::new();
83-
8465
let spi_expectations = spi_test_expects![
8566
// set the CONFIG register value for each possible enumeration of CrcLength
8667
(vec![registers::CONFIG, 0u8], vec![0xEu8, 4u8]),
@@ -99,12 +80,12 @@ mod test {
9980
vec![0xEu8, 0u8],
10081
),
10182
];
102-
let mut spi_mock = SpiMock::new(&spi_expectations);
103-
let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
83+
let mocks = mk_radio(&[], &spi_expectations);
84+
let (mut radio, mut spi, mut ce_pin) = (mocks.0, mocks.1, mocks.2);
10485
radio.set_crc_length(CrcLength::Disabled).unwrap();
10586
radio.set_crc_length(CrcLength::Bit8).unwrap();
10687
radio.set_crc_length(CrcLength::Bit16).unwrap();
107-
spi_mock.done();
108-
pin_mock.done();
88+
spi.done();
89+
ce_pin.done();
10990
}
11091
}

0 commit comments

Comments
 (0)