Files
k-frame/crates/application/tests/data_projection_tests.rs
Gabriel Kaszewski 557cceb498 add all crates: domain, protocol, application, client, adapters, ESP32 firmware
Server: domain (entities, value objects, ports), protocol (postcard wire types),
application (config service, data projection), adapters (config-memory, tcp-server),
bootstrap (composition root with fake data).

Client: client-domain (layout engine, render tree, HAL ports),
client-application (message handling, repaint commands),
adapters (tcp-client, display-terminal), client-desktop (end-to-end working).

ESP32: client-esp32 firmware with ILI9341 display over SPI, WiFi networking.
Display test verified on hardware — landscape orientation, text rendering works.

60 workspace tests, all passing.
2026-06-18 21:43:59 +02:00

83 lines
2.4 KiB
Rust

use std::collections::BTreeMap;
use domain::{
DisplayHint, KeyMapping, Value, WidgetConfig, WidgetId, WidgetState,
};
use application::DataProjection;
fn weather_widget() -> WidgetConfig {
WidgetConfig::new(
1,
"weather".into(),
DisplayHint::IconValue,
10,
vec![
KeyMapping { source_path: "$.temp".into(), target_key: "temperature".into() },
KeyMapping { source_path: "$.icon".into(), target_key: "icon".into() },
],
)
}
fn weather_response(temp: f64) -> Value {
Value::Object(BTreeMap::from([
("temp".into(), Value::Number(temp)),
("icon".into(), Value::String("sunny".into())),
]))
}
#[test]
fn apply_poll_result_detects_new_widget_state() {
let mut projection = DataProjection::new();
let widgets = vec![weather_widget()];
let changed = projection.apply_poll_result(10, &weather_response(5.4), &widgets);
assert_eq!(changed.len(), 1);
assert_eq!(changed[0].0, 1);
assert_eq!(changed[0].1.data.get("temperature"), Some(&Value::Number(5.4)));
}
#[test]
fn apply_poll_result_returns_empty_when_nothing_changed() {
let mut projection = DataProjection::new();
let widgets = vec![weather_widget()];
projection.apply_poll_result(10, &weather_response(5.4), &widgets);
let changed = projection.apply_poll_result(10, &weather_response(5.4), &widgets);
assert!(changed.is_empty());
}
#[test]
fn apply_poll_result_detects_changed_value() {
let mut projection = DataProjection::new();
let widgets = vec![weather_widget()];
projection.apply_poll_result(10, &weather_response(5.4), &widgets);
let changed = projection.apply_poll_result(10, &weather_response(6.1), &widgets);
assert_eq!(changed.len(), 1);
assert_eq!(changed[0].1.data.get("temperature"), Some(&Value::Number(6.1)));
}
#[test]
fn apply_poll_result_only_updates_widgets_bound_to_source() {
let mut projection = DataProjection::new();
let widgets = vec![
weather_widget(),
WidgetConfig::new(
2,
"portfolio".into(),
DisplayHint::KeyValue,
20,
vec![
KeyMapping { source_path: "$.value".into(), target_key: "amount".into() },
],
),
];
let changed = projection.apply_poll_result(10, &weather_response(5.4), &widgets);
assert_eq!(changed.len(), 1);
assert_eq!(changed[0].0, 1);
}