Put listen before the tests, where clippy can live with it
🚴 Build and Test BikeControl / Workspace tests (push) Successful in 21m48s
Build & Release / Run tests (push) Successful in 14m3s
🚴 Build and Test BikeControl / Android compile check (push) Failing after 10s
Build & Release / Build Linux (deb + AppImage) (push) Successful in 17m22s
Build & Release / Build Arch package (push) Successful in 29m45s
Build & Release / Build Android APK (push) Failing after 22s
Build & Release / Create release (push) Skipped
🚴 Build and Test BikeControl / Workspace tests (push) Successful in 21m48s
Build & Release / Run tests (push) Successful in 14m3s
🚴 Build and Test BikeControl / Android compile check (push) Failing after 10s
Build & Release / Build Linux (deb + AppImage) (push) Successful in 17m22s
Build & Release / Build Arch package (push) Successful in 29m45s
Build & Release / Build Android APK (push) Failing after 22s
Build & Release / Create release (push) Skipped
`probe listen` was appended to the end of commands.rs, which put it after `mod tests` — `clippy::items_after_test_module`, denied by the `-D warnings` in the workspace clippy job. Pure code motion: the listen section moves up as a block, above the test module, and nothing else changes. This is the first commit whose clippy run can actually be observed. The job has been in .gitea/workflows since the images were pinned, but the image was never in the registry, so it has never run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1056,82 +1056,6 @@ fn properties(p: CharPropFlags) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use bikecontrol_ble::indoor_bike_data::flag;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn flag_names_call_out_the_inverted_bit_zero() {
|
|
||||||
// Bit 0 clear means speed IS present.
|
|
||||||
assert!(flag_names(0x0000).contains("InstantaneousSpeed(bit0 clear)"));
|
|
||||||
// Bit 0 set means it is not.
|
|
||||||
assert!(flag_names(flag::MORE_DATA).contains("MoreData(bit0 set: no speed)"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn flag_names_list_every_present_field() {
|
|
||||||
let names = flag_names(flag::INSTANTANEOUS_CADENCE | flag::INSTANTANEOUS_POWER);
|
|
||||||
assert!(names.contains("Cadence"));
|
|
||||||
assert!(names.contains("Power"));
|
|
||||||
assert!(!names.contains("HeartRate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn flag_names_flag_reserved_bits() {
|
|
||||||
assert!(flag_names(0x8000).contains("<reserved bits set>"));
|
|
||||||
assert!(!flag_names(0x0001).contains("<reserved bits set>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn device_selector_mapping() {
|
|
||||||
assert_eq!(
|
|
||||||
Device::Address("AA:BB".into()).selector(),
|
|
||||||
TrainerSelector::Address("AA:BB".into())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
Device::Name("D100".into()).selector(),
|
|
||||||
TrainerSelector::NameContains("D100".into())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn describe_write_names_the_op_code() {
|
|
||||||
assert_eq!(
|
|
||||||
describe_write(&ControlTarget::Gradient { percent: 4.0 }, false).0,
|
|
||||||
"SetTargetInclination (0x03)"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
describe_write(&ControlTarget::Gradient { percent: 4.0 }, true).0,
|
|
||||||
"SetIndoorBikeSimulationParameters (0x11)"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
describe_write(&ControlTarget::Resistance { level: 10 }, false).0,
|
|
||||||
"SetTargetResistanceLevel (0x04)"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
describe_write(&ControlTarget::Power { watts: 100 }, false).0,
|
|
||||||
"SetTargetPower (0x05)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn as_text_only_renders_printable_payloads() {
|
|
||||||
assert_eq!(as_text(b"D100"), "\"D100\"");
|
|
||||||
assert_eq!(as_text(&[0x00, 0x01, 0xff]), "");
|
|
||||||
assert_eq!(as_text(&[]), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn properties_are_listed_in_order() {
|
|
||||||
assert_eq!(
|
|
||||||
properties(CharPropFlags::READ | CharPropFlags::INDICATE),
|
|
||||||
"read, indicate"
|
|
||||||
);
|
|
||||||
assert_eq!(properties(CharPropFlags::empty()), "(none)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// listen
|
// listen
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -1313,3 +1237,79 @@ pub async fn listen(
|
|||||||
disconnect(&peripheral).await;
|
disconnect(&peripheral).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use bikecontrol_ble::indoor_bike_data::flag;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flag_names_call_out_the_inverted_bit_zero() {
|
||||||
|
// Bit 0 clear means speed IS present.
|
||||||
|
assert!(flag_names(0x0000).contains("InstantaneousSpeed(bit0 clear)"));
|
||||||
|
// Bit 0 set means it is not.
|
||||||
|
assert!(flag_names(flag::MORE_DATA).contains("MoreData(bit0 set: no speed)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flag_names_list_every_present_field() {
|
||||||
|
let names = flag_names(flag::INSTANTANEOUS_CADENCE | flag::INSTANTANEOUS_POWER);
|
||||||
|
assert!(names.contains("Cadence"));
|
||||||
|
assert!(names.contains("Power"));
|
||||||
|
assert!(!names.contains("HeartRate"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flag_names_flag_reserved_bits() {
|
||||||
|
assert!(flag_names(0x8000).contains("<reserved bits set>"));
|
||||||
|
assert!(!flag_names(0x0001).contains("<reserved bits set>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn device_selector_mapping() {
|
||||||
|
assert_eq!(
|
||||||
|
Device::Address("AA:BB".into()).selector(),
|
||||||
|
TrainerSelector::Address("AA:BB".into())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Device::Name("D100".into()).selector(),
|
||||||
|
TrainerSelector::NameContains("D100".into())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn describe_write_names_the_op_code() {
|
||||||
|
assert_eq!(
|
||||||
|
describe_write(&ControlTarget::Gradient { percent: 4.0 }, false).0,
|
||||||
|
"SetTargetInclination (0x03)"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
describe_write(&ControlTarget::Gradient { percent: 4.0 }, true).0,
|
||||||
|
"SetIndoorBikeSimulationParameters (0x11)"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
describe_write(&ControlTarget::Resistance { level: 10 }, false).0,
|
||||||
|
"SetTargetResistanceLevel (0x04)"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
describe_write(&ControlTarget::Power { watts: 100 }, false).0,
|
||||||
|
"SetTargetPower (0x05)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn as_text_only_renders_printable_payloads() {
|
||||||
|
assert_eq!(as_text(b"D100"), "\"D100\"");
|
||||||
|
assert_eq!(as_text(&[0x00, 0x01, 0xff]), "");
|
||||||
|
assert_eq!(as_text(&[]), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn properties_are_listed_in_order() {
|
||||||
|
assert_eq!(
|
||||||
|
properties(CharPropFlags::READ | CharPropFlags::INDICATE),
|
||||||
|
"read, indicate"
|
||||||
|
);
|
||||||
|
assert_eq!(properties(CharPropFlags::empty()), "(none)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user