baada36222
led accepted any u16 and main.rs clamped to 0..=1000 with no feedback, inconsistent with sidetone which rejects out-of-range at parse time. Add a clap range validator (0..=1000) and drop the silent clamp, so invalid input now fails loudly. Further quality-audit follow-ups: - remove dead BragiDevice::open() (no caller; binary uses open_with_verbose) - add tests: led range validation, format_battery for all status variants, waybar "unknown" class Bump 0.1.2 -> 0.1.3.
181 lines
6.2 KiB
Rust
181 lines
6.2 KiB
Rust
// ABOUTME: Unit-Tests für Output-Formatierung (Plain-Text und Waybar-JSON).
|
|
// ABOUTME: Testet alle BatteryStatus-Varianten und Grenzwerte in der Waybar-Ausgabe.
|
|
|
|
use corsairctl::bragi::properties::BatteryStatus;
|
|
use corsairctl::output;
|
|
|
|
#[test]
|
|
fn format_battery_discharging() {
|
|
let result = output::format_battery(75.0, &BatteryStatus::Discharging);
|
|
assert_eq!(result, "Battery: 75% (Discharging)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_battery_charging() {
|
|
let result = output::format_battery(50.0, &BatteryStatus::Charging);
|
|
assert_eq!(result, "Battery: 50% (Charging)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_battery_fully_charged() {
|
|
let result = output::format_battery(100.0, &BatteryStatus::FullyCharged);
|
|
assert_eq!(result, "Battery: 100% (Full)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_battery_low() {
|
|
let result = output::format_battery(10.0, &BatteryStatus::Low);
|
|
assert_eq!(result, "Battery: 10% (Low)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_battery_offline() {
|
|
let result = output::format_battery(0.0, &BatteryStatus::Offline);
|
|
assert_eq!(result, "Battery: 0% (Offline)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_battery_unknown() {
|
|
let result = output::format_battery(50.0, &BatteryStatus::Unknown(0x99));
|
|
assert_eq!(result, "Battery: 50% (Unknown)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_brightness_value() {
|
|
let result = output::format_brightness(330);
|
|
assert_eq!(result, "LED Brightness: 330/1000 (33%)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_brightness_zero() {
|
|
let result = output::format_brightness(0);
|
|
assert_eq!(result, "LED Brightness: 0/1000 (0%)");
|
|
}
|
|
|
|
#[test]
|
|
fn format_sidetone_value() {
|
|
let result = output::format_sidetone(3);
|
|
assert_eq!(result, "Sidetone: 3/23");
|
|
}
|
|
|
|
#[test]
|
|
fn format_info_values() {
|
|
let result = output::format_info(0x1B1C, 0x0A69, 1797, 0);
|
|
let expected = "Vendor ID: 0x1B1C\nProduct ID: 0x0A69\nFirmware: 1797.0";
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
// Waybar-JSON Tests
|
|
|
|
#[test]
|
|
fn waybar_json_is_valid_json() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).expect("muss valides JSON sein");
|
|
assert!(parsed.is_object());
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_has_required_fields() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert!(parsed["text"].is_string(), "text fehlt");
|
|
assert!(parsed["tooltip"].is_string(), "tooltip fehlt");
|
|
assert!(parsed["class"].is_string(), "class fehlt");
|
|
assert!(parsed["percentage"].is_number(), "percentage fehlt");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_percentage_matches_level() {
|
|
let json_str = output::format_waybar_json(73.5, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["percentage"], 74); // 73.5 rounded
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_charging() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Charging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "charging");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_fully_charged() {
|
|
let json_str = output::format_waybar_json(100.0, &BatteryStatus::FullyCharged, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "charging");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_low() {
|
|
let json_str = output::format_waybar_json(20.0, &BatteryStatus::Low, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "low");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_critical_when_discharging_below_15() {
|
|
let json_str = output::format_waybar_json(10.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "critical");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_warning_when_discharging_below_30() {
|
|
let json_str = output::format_waybar_json(25.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "warning");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_normal_when_discharging_above_30() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "normal");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_at_boundary_15() {
|
|
let json_str = output::format_waybar_json(15.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
// 15.0 ist <= 15.0 → critical
|
|
assert_eq!(parsed["class"], "critical");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_at_boundary_30() {
|
|
let json_str = output::format_waybar_json(30.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
// 30.0 ist <= 30.0 → warning
|
|
assert_eq!(parsed["class"], "warning");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_class_unknown() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Unknown(0x99), None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "unknown");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_offline() {
|
|
let json_str = output::format_waybar_json(0.0, &BatteryStatus::Offline, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
assert_eq!(parsed["class"], "offline");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_tooltip_without_sidetone() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Discharging, None);
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
let tooltip = parsed["tooltip"].as_str().unwrap();
|
|
assert!(!tooltip.contains("Sidetone"), "tooltip should not contain sidetone when None");
|
|
}
|
|
|
|
#[test]
|
|
fn waybar_json_tooltip_with_sidetone() {
|
|
let json_str = output::format_waybar_json(50.0, &BatteryStatus::Discharging, Some(10));
|
|
let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
|
let tooltip = parsed["tooltip"].as_str().unwrap();
|
|
assert!(tooltip.contains("Sidetone: 10/23"), "tooltip should contain sidetone value");
|
|
}
|