106 lines
2.7 KiB
Rust
106 lines
2.7 KiB
Rust
use application::DataProjection;
|
|
use domain::{DisplayHint, DisplayHintKind, KeyMapping, Value, WidgetConfig};
|
|
use std::collections::BTreeMap;
|
|
|
|
fn weather_widget() -> WidgetConfig {
|
|
WidgetConfig::new(
|
|
1,
|
|
"weather".into(),
|
|
DisplayHint::new(DisplayHintKind::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())),
|
|
]))
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn apply_poll_result_detects_new_widget_state() {
|
|
let projection = DataProjection::new();
|
|
let widgets = vec![weather_widget()];
|
|
|
|
let changed = projection
|
|
.apply_poll_result(10, &weather_response(5.4), &widgets)
|
|
.await;
|
|
|
|
assert_eq!(changed.len(), 1);
|
|
assert_eq!(changed[0].0, 1);
|
|
assert_eq!(
|
|
changed[0].1.data.get("temperature"),
|
|
Some(&Value::Number(5.4))
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn apply_poll_result_returns_empty_when_nothing_changed() {
|
|
let projection = DataProjection::new();
|
|
let widgets = vec![weather_widget()];
|
|
|
|
projection
|
|
.apply_poll_result(10, &weather_response(5.4), &widgets)
|
|
.await;
|
|
let changed = projection
|
|
.apply_poll_result(10, &weather_response(5.4), &widgets)
|
|
.await;
|
|
|
|
assert!(changed.is_empty());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn apply_poll_result_detects_changed_value() {
|
|
let projection = DataProjection::new();
|
|
let widgets = vec![weather_widget()];
|
|
|
|
projection
|
|
.apply_poll_result(10, &weather_response(5.4), &widgets)
|
|
.await;
|
|
let changed = projection
|
|
.apply_poll_result(10, &weather_response(6.1), &widgets)
|
|
.await;
|
|
|
|
assert_eq!(changed.len(), 1);
|
|
assert_eq!(
|
|
changed[0].1.data.get("temperature"),
|
|
Some(&Value::Number(6.1))
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn apply_poll_result_only_updates_widgets_bound_to_source() {
|
|
let projection = DataProjection::new();
|
|
let widgets = vec![
|
|
weather_widget(),
|
|
WidgetConfig::new(
|
|
2,
|
|
"portfolio".into(),
|
|
DisplayHint::new(DisplayHintKind::KeyValue),
|
|
20,
|
|
vec![KeyMapping {
|
|
source_path: "$.value".into(),
|
|
target_key: "amount".into(),
|
|
}],
|
|
),
|
|
];
|
|
|
|
let changed = projection
|
|
.apply_poll_result(10, &weather_response(5.4), &widgets)
|
|
.await;
|
|
|
|
assert_eq!(changed.len(), 1);
|
|
assert_eq!(changed[0].0, 1);
|
|
}
|