diff --git a/Cargo.lock b/Cargo.lock index f6edfdd..75b21c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,6 +350,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.32" @@ -370,6 +381,7 @@ checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -805,6 +817,7 @@ name = "shturman-power" version = "0.0.0" dependencies = [ "anyhow", + "futures-util", "shturman-common", "shturman-ipc", "shturman-sdk", @@ -830,6 +843,7 @@ name = "shturman-settings" version = "0.0.0" dependencies = [ "anyhow", + "futures-util", "serde_json", "shturman-common", "shturman-ipc", diff --git a/Cargo.toml b/Cargo.toml index 597fd1d..9e8747c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,4 +30,5 @@ thiserror = "1" clap = { version = "4", features = ["derive"] } # dev tempfile = "3" +futures-util = "0.3" # slint — добавляется в Плане 4 (вместе с slint GPL-3.0 exception в deny.toml) diff --git a/crates/core/shturman-power/Cargo.toml b/crates/core/shturman-power/Cargo.toml index cb4e3a2..ed4ec94 100644 --- a/crates/core/shturman-power/Cargo.toml +++ b/crates/core/shturman-power/Cargo.toml @@ -19,4 +19,5 @@ tracing.workspace = true [dev-dependencies] tempfile.workspace = true +futures-util.workspace = true shturman-sdk = { path = "../../shturman-sdk" } diff --git a/crates/core/shturman-power/tests/integration.rs b/crates/core/shturman-power/tests/integration.rs new file mode 100644 index 0000000..da5ca98 --- /dev/null +++ b/crates/core/shturman-power/tests/integration.rs @@ -0,0 +1,50 @@ +//! Интеграция `Power1` + dev-mock на session-шине. `#[ignore]` — запуск: `just test-integration`. +//! Проверяет state по шине и fake-ACC: `dev.PowerMock1.SetAcc` → сигнал `Power1.AccChanged`. + +use futures_util::StreamExt; +use shturman_ipc::types::PowerState; +use shturman_power::PowerService; +use shturman_sdk::PowerClient; + +#[tokio::test] +#[ignore = "нужна session-шина: just test-integration"] +async fn power_state_and_fake_acc() { + let svc = PowerService::new(); + let mock = svc.mock(); + + // сервер: Power1 + dev.PowerMock1 на одном пути (владеет ru.shturman.Power) + let server = zbus::Connection::session().await.unwrap(); + server + .object_server() + .at("/ru/shturman/Power", svc) + .await + .unwrap(); + server + .object_server() + .at("/ru/shturman/Power", mock) + .await + .unwrap(); + server.request_name("ru.shturman.Power").await.unwrap(); + + let client_conn = zbus::Connection::session().await.unwrap(); + let power = PowerClient::new(&client_conn).await.unwrap(); + assert_eq!(power.power_state().await.unwrap(), PowerState::Running); + + // подписка на AccChanged + let mut acc = power.proxy().receive_acc_changed().await.unwrap(); + + // dev.PowerMock1.SetAcc(false) сырым D-Bus-вызовом + client_conn + .call_method( + Some("ru.shturman.Power"), + "/ru/shturman/Power", + Some("ru.shturman.dev.PowerMock1"), + "SetAcc", + &(false,), + ) + .await + .unwrap(); + + let sig = acc.next().await.unwrap(); + assert!(!sig.args().unwrap().on()); +} diff --git a/crates/core/shturman-settings/Cargo.toml b/crates/core/shturman-settings/Cargo.toml index a54171b..f6635cf 100644 --- a/crates/core/shturman-settings/Cargo.toml +++ b/crates/core/shturman-settings/Cargo.toml @@ -15,4 +15,5 @@ tracing.workspace = true [dev-dependencies] tempfile.workspace = true +futures-util.workspace = true shturman-sdk = { path = "../../shturman-sdk" } diff --git a/crates/core/shturman-settings/tests/integration.rs b/crates/core/shturman-settings/tests/integration.rs new file mode 100644 index 0000000..9b5f564 --- /dev/null +++ b/crates/core/shturman-settings/tests/integration.rs @@ -0,0 +1,44 @@ +//! Интеграция `Settings1` на session-шине. `#[ignore]` — запуск: `just test-integration` +//! (под `dbus-run-session`). Проверяет server-стаб + `sdk::SettingsClient` по реальной шине. + +use futures_util::StreamExt; +use shturman_common::Layout; +use shturman_sdk::SettingsClient; +use shturman_settings::{store::Store, SettingsService}; +use zbus::zvariant::Value; + +#[tokio::test] +#[ignore = "нужна session-шина: just test-integration"] +async fn settings_round_trip_and_changed() { + let tmp = tempfile::tempdir().unwrap(); + let store = Store::load_or_seed(Layout::new(tmp.path())).unwrap(); + + // сервер на отдельном соединении (владеет ru.shturman.Settings) + let server = zbus::Connection::session().await.unwrap(); + server + .object_server() + .at("/ru/shturman/Settings", SettingsService::new(store)) + .await + .unwrap(); + server.request_name("ru.shturman.Settings").await.unwrap(); + + // клиент на отдельном соединении + let client_conn = zbus::Connection::session().await.unwrap(); + let client = SettingsClient::new(&client_conn).await.unwrap(); + + // дефолт засеян + let theme: String = client.get("ui.theme").await.unwrap().try_into().unwrap(); + assert_eq!(theme, "auto"); + + // подписка на Changed до изменения + let mut changed = client.proxy().receive_changed().await.unwrap(); + + client.set("ui.theme", &Value::from("night")).await.unwrap(); + + let got: String = client.get("ui.theme").await.unwrap().try_into().unwrap(); + assert_eq!(got, "night"); + + // сигнал Changed пришёл с нужным ключом + let sig = changed.next().await.unwrap(); + assert_eq!(sig.args().unwrap().key(), "ui.theme"); +} diff --git a/justfile b/justfile index 052c47e..ce4ee69 100644 --- a/justfile +++ b/justfile @@ -22,5 +22,9 @@ lint: deny: cargo deny check +# интеграционные тесты на session-шине (нужен dbus: brew install dbus / в Lima) +test-integration: + dbus-run-session -- cargo test --workspace -- --ignored + # полный локальный гейт ci: lint test deny