Skip to content

Commit bf99489

Browse files
committed
add test coverage
1 parent 7b483df commit bf99489

File tree

7 files changed

+323
-4
lines changed

7 files changed

+323
-4
lines changed

src/button_event.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,135 @@ impl ButtonEvent {
102102
&self.state
103103
}
104104
}
105+
106+
#[cfg(test)]
107+
mod tests {
108+
use crate::button_event::{Button, ButtonEvent, ButtonParseError, ButtonState};
109+
use crate::ProtocolParseError;
110+
111+
fn assert_is_button_event(
112+
result: &Result<ButtonEvent, ProtocolParseError>,
113+
button: Button,
114+
button_state: ButtonState,
115+
) {
116+
match result {
117+
Ok(event) => {
118+
assert_eq!(event.button(), &button);
119+
assert_eq!(event.state(), &button_state)
120+
}
121+
_ => assert!(false),
122+
}
123+
}
124+
125+
#[test]
126+
fn test_parse_button1_pressed_event() {
127+
let input: &[u8] = b"11";
128+
assert_is_button_event(
129+
&ButtonEvent::try_from(input),
130+
Button::Button1,
131+
ButtonState::Pressed,
132+
);
133+
}
134+
135+
#[test]
136+
fn test_parse_button1_released_event() {
137+
let input: &[u8] = b"11";
138+
assert_is_button_event(
139+
&ButtonEvent::try_from(input),
140+
Button::Button1,
141+
ButtonState::Pressed,
142+
);
143+
}
144+
145+
#[test]
146+
fn test_parse_button2_pressed_event() {
147+
let input: &[u8] = b"21";
148+
assert_is_button_event(
149+
&ButtonEvent::try_from(input),
150+
Button::Button2,
151+
ButtonState::Pressed,
152+
);
153+
}
154+
155+
#[test]
156+
fn test_parse_button3_pressed_event() {
157+
let input: &[u8] = b"31";
158+
assert_is_button_event(
159+
&ButtonEvent::try_from(input),
160+
Button::Button3,
161+
ButtonState::Pressed,
162+
);
163+
}
164+
165+
#[test]
166+
fn test_parse_button4_pressed_event() {
167+
let input: &[u8] = b"41";
168+
assert_is_button_event(
169+
&ButtonEvent::try_from(input),
170+
Button::Button4,
171+
ButtonState::Pressed,
172+
);
173+
}
174+
175+
#[test]
176+
fn test_parse_button_up_pressed_event() {
177+
let input: &[u8] = b"51";
178+
assert_is_button_event(
179+
&ButtonEvent::try_from(input),
180+
Button::Up,
181+
ButtonState::Pressed,
182+
);
183+
}
184+
185+
#[test]
186+
fn test_parse_button_down_pressed_event() {
187+
let input: &[u8] = b"61";
188+
assert_is_button_event(
189+
&ButtonEvent::try_from(input),
190+
Button::Down,
191+
ButtonState::Pressed,
192+
);
193+
}
194+
195+
#[test]
196+
fn test_parse_button_left_pressed_event() {
197+
let input: &[u8] = b"71";
198+
assert_is_button_event(
199+
&ButtonEvent::try_from(input),
200+
Button::Left,
201+
ButtonState::Pressed,
202+
);
203+
}
204+
205+
#[test]
206+
fn test_parse_button_right_pressed_event() {
207+
let input: &[u8] = b"81";
208+
assert_is_button_event(
209+
&ButtonEvent::try_from(input),
210+
Button::Right,
211+
ButtonState::Pressed,
212+
);
213+
}
214+
215+
#[test]
216+
fn test_parse_invalid_button() {
217+
let input: &[u8] = b"01";
218+
assert_eq!(
219+
ButtonEvent::try_from(input),
220+
Err(ProtocolParseError::ButtonParseError(
221+
ButtonParseError::UnknownButton(b'0')
222+
))
223+
);
224+
}
225+
226+
#[test]
227+
fn test_parse_invalid_button_state() {
228+
let input: &[u8] = b"13";
229+
assert_eq!(
230+
ButtonEvent::try_from(input),
231+
Err(ProtocolParseError::ButtonParseError(
232+
ButtonParseError::UnknownButtonState(b'3')
233+
))
234+
);
235+
}
236+
}

src/color_event.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,36 @@ impl Into<RGB8> for ColorEvent {
5959
}
6060
}
6161
}
62+
63+
#[cfg(test)]
64+
mod tests {
65+
use crate::color_event::ColorEvent;
66+
#[cfg(feature = "rgb")]
67+
use rgb::RGB8;
68+
69+
#[test]
70+
fn test_parse_color_event() {
71+
let input: &[u8] = b"\xff-9";
72+
let expected = ColorEvent {
73+
red: 255,
74+
green: 45,
75+
blue: 57,
76+
};
77+
78+
assert_eq!(ColorEvent::try_from(input), Ok(expected));
79+
}
80+
81+
#[test]
82+
#[cfg(feature = "rgb")]
83+
fn test_into_rgb8() {
84+
let input = ColorEvent {
85+
red: 1,
86+
green: 2,
87+
blue: 3,
88+
};
89+
let expected = RGB8 { r: 1, g: 2, b: 3 };
90+
91+
let result: RGB8 = input.into();
92+
assert_eq!(result, expected);
93+
}
94+
}

src/gyro_event.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,20 @@ impl GyroEvent {
4646
self.z
4747
}
4848
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use crate::gyro_event::GyroEvent;
53+
54+
#[test]
55+
fn test_parse_gyro_event() {
56+
let input: &[u8] = b"H.\xd7;\x0c\xb2\xe8<z\xe62\xbd";
57+
let expected = GyroEvent {
58+
x: 0.0065667965,
59+
y: 0.028405212,
60+
z: -0.04367683,
61+
};
62+
63+
assert_eq!(GyroEvent::try_from(input), Ok(expected));
64+
}
65+
}

src/lib.rs

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,22 @@ pub enum ControllerEvent {
8585
#[derive(PartialEq, Eq, Debug)]
8686
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8787
pub enum ProtocolParseError {
88-
/// The message contained an event which is not known to the current implementation. This can either mean that the message was malformed or that a newer protocol version has been used.
88+
/// The message contained an event which is not known to the current implementation.
89+
/// This can mean that:
90+
/// * the message was malformed or
91+
/// * that a newer protocol version has been used or
92+
/// * that the event type has not been enabled as a feature.
8993
UnknownEvent(Option<u8>),
9094
/// The message contained an event which is known to the library but has not been selected as a feature and can thus not be parsed. Select the feature when compiling the library to handle this message.
9195
DisabledControllerDataPackageType(ControllerDataPackageType),
9296
/// An error occurred while parsing a [`ButtonEvent`].
9397
#[cfg(feature = "button_event")]
9498
ButtonParseError(ButtonParseError),
95-
/// The event in the message did not have the expected length.
99+
/// The event in the message did not have the expected length. The first value is the expected length, the second the actual length.
96100
InvalidLength(usize, usize),
97-
/// The event in the message did not have the expected CRC.
101+
/// The event in the message did not have the expected CRC. The first value is the expected CRC, the second the actual CRC.
98102
InvalidCrc(u8, u16),
99-
/// There was a problem parsing a float from a message.
103+
/// There was a problem parsing a float from a message. The parameter gives the length of the received input.
100104
InvalidFloatSize(usize),
101105
}
102106

@@ -307,3 +311,74 @@ fn try_f32_from_le_bytes(input: &[u8]) -> Result<f32, ProtocolParseError> {
307311
|_| ProtocolParseError::InvalidFloatSize(input.len()),
308312
)?))
309313
}
314+
315+
#[cfg(test)]
316+
mod tests {
317+
use crate::button_event::{Button, ButtonState};
318+
use crate::{check_crc, parse, try_f32_from_le_bytes, ControllerEvent, ProtocolParseError};
319+
320+
fn assert_is_button_event(
321+
event: &Result<ControllerEvent, ProtocolParseError>,
322+
button: Button,
323+
button_state: ButtonState,
324+
) {
325+
match event {
326+
Ok(ControllerEvent::ButtonEvent(event)) => {
327+
assert_eq!(event.button(), &button);
328+
assert_eq!(event.state(), &button_state)
329+
}
330+
_ => assert!(false),
331+
}
332+
}
333+
334+
#[test]
335+
fn test_parse() {
336+
const MAX_RESULTS: usize = 4;
337+
let input = b"\x00!B11:!B10;\x00\x00\x00\x00\x00\x00";
338+
let result = parse::<MAX_RESULTS>(input);
339+
340+
assert_eq!(result.len(), 2);
341+
assert_is_button_event(&result[0], Button::Button1, ButtonState::Pressed);
342+
assert_is_button_event(&result[1], Button::Button1, ButtonState::Released);
343+
}
344+
345+
#[test]
346+
fn test_check_crc_ok() {
347+
let input = b"!B11:";
348+
let data = &input[0..input.len() - 1];
349+
let crc = input.last().unwrap();
350+
351+
assert!(check_crc(data, &crc).is_ok());
352+
}
353+
354+
#[test]
355+
fn test_check_crc_err() {
356+
let input = b"!B11;"; // should either be "!B11:" or "!B10;"
357+
let correct_crc = b':';
358+
let data = &input[0..input.len() - 1];
359+
let crc = input.last().unwrap();
360+
361+
assert_eq!(
362+
check_crc(data, &crc),
363+
Err(ProtocolParseError::InvalidCrc(*crc, correct_crc as u16))
364+
);
365+
}
366+
367+
#[test]
368+
fn test_try_f32_from_le_bytes_ok() {
369+
let input = b"9\x1e\x0c\xc0";
370+
let expected: f32 = -2.1893446;
371+
372+
assert_eq!(try_f32_from_le_bytes(input), Ok(expected));
373+
}
374+
375+
#[test]
376+
fn test_try_f32_from_le_bytes_err() {
377+
let input = b"\x1e\x0c\xc0";
378+
379+
assert_eq!(
380+
try_f32_from_le_bytes(input),
381+
Err(ProtocolParseError::InvalidFloatSize(3))
382+
);
383+
}
384+
}

src/location_event.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,30 @@ impl LocationEvent {
4646
self.altitude
4747
}
4848
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use crate::location_event::LocationEvent;
53+
54+
#[test]
55+
fn test_parse_gyro_event() {
56+
// as an exception this is not done using a real-world string received via bluetooth as I don't have a mock GPS app installed and don't want my real location in the source code :)
57+
let expected_lat = 1.2f32;
58+
let expected_lon = 2.3f32;
59+
let expected_alt = 3.4f32;
60+
let input = [
61+
expected_lat.to_le_bytes(),
62+
expected_lon.to_le_bytes(),
63+
expected_alt.to_le_bytes(),
64+
]
65+
.concat();
66+
67+
let expected = LocationEvent {
68+
latitude: expected_lat,
69+
longitude: expected_lon,
70+
altitude: expected_alt,
71+
};
72+
73+
assert_eq!(LocationEvent::try_from(input.as_slice()), Ok(expected));
74+
}
75+
}

src/magnetometer_event.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,20 @@ impl MagnetometerEvent {
4646
self.z
4747
}
4848
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use crate::magnetometer_event::MagnetometerEvent;
53+
54+
#[test]
55+
fn test_parse_gyro_event() {
56+
let input: &[u8] = b"\xcd\xcc\x8bA\x00@\x03\xc2\x9a\x19\xcb\xc1";
57+
let expected = MagnetometerEvent {
58+
x: 17.475,
59+
y: -32.8125,
60+
z: -25.3875,
61+
};
62+
63+
assert_eq!(MagnetometerEvent::try_from(input), Ok(expected));
64+
}
65+
}

src/quaternion_event.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,21 @@ impl QuaternionEvent {
5252
self.w
5353
}
5454
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::quaternion_event::QuaternionEvent;
59+
60+
#[test]
61+
fn test_parse_quaternion_event() {
62+
let input: &[u8] = b"9\x1e\x0c\xc03\xf7P\xbf\xefv\x96>\x00\x00\x00\x00";
63+
let expected = QuaternionEvent {
64+
x: -2.1893446,
65+
y: -0.81627196,
66+
z: 0.29387614,
67+
w: 0.0,
68+
};
69+
70+
assert_eq!(QuaternionEvent::try_from(input), Ok(expected));
71+
}
72+
}

0 commit comments

Comments
 (0)