| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use crate::{ |
| common_utils::common::macros::{fx_err_and_bail, with_line}, |
| light::types::{SerializableGroupInfo, SerializableInfo, SerializableRgb}, |
| }; |
| use anyhow::Error; |
| use fidl_fuchsia_hardware_light::{LightMarker, LightProxy, Rgb}; |
| use fuchsia_syslog::macros::*; |
| use glob::glob; |
| use parking_lot::{RwLock, RwLockUpgradableReadGuard}; |
| |
| /// Perform Light operations. |
| /// |
| /// Note this object is shared among all threads created by server. |
| /// |
| #[derive(Debug)] |
| pub struct LightFacade { |
| proxy: RwLock<Option<LightProxy>>, |
| } |
| |
| impl LightFacade { |
| pub fn new() -> Self { |
| Self { proxy: RwLock::new(None) } |
| } |
| |
| #[cfg(test)] |
| fn new_with_proxy(proxy: LightProxy) -> Self { |
| Self { proxy: RwLock::new(Some(proxy)) } |
| } |
| |
| fn get_proxy(&self) -> Result<LightProxy, Error> { |
| let tag = "LightFacade::get_proxy"; |
| |
| let lock = self.proxy.upgradable_read(); |
| if let Some(proxy) = lock.as_ref() { |
| Ok(proxy.clone()) |
| } else { |
| let (proxy, server) = match fidl::endpoints::create_proxy::<LightMarker>() { |
| Ok(r) => r, |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("Failed to get light proxy {:?}", e) |
| ), |
| }; |
| |
| let found_path = glob("/dev/class/light/*")?.filter_map(|entry| entry.ok()).next(); |
| match found_path { |
| Some(path) => { |
| fdio::service_connect(path.to_string_lossy().as_ref(), server.into_channel())?; |
| *RwLockUpgradableReadGuard::upgrade(lock) = Some(proxy.clone()); |
| Ok(proxy) |
| } |
| None => fx_err_and_bail!(&with_line!(tag), format_err!("Failed to find device")), |
| } |
| } |
| } |
| |
| pub async fn get_num_lights(&self) -> Result<u32, Error> { |
| Ok(self.get_proxy()?.get_num_lights().await?) |
| } |
| |
| pub async fn get_num_light_groups(&self) -> Result<u32, Error> { |
| Ok(self.get_proxy()?.get_num_light_groups().await?) |
| } |
| |
| pub async fn get_info(&self, index: u32) -> Result<SerializableInfo, Error> { |
| let tag = "LightFacade::get_info"; |
| match self.get_proxy()?.get_info(index).await? { |
| Ok(r) => Ok(SerializableInfo::new(&r)), |
| Err(e) => fx_err_and_bail!(&with_line!(tag), format_err!("GetInfo failed {:?}", e)), |
| } |
| } |
| |
| pub async fn get_current_simple_value(&self, index: u32) -> Result<bool, Error> { |
| let tag = "LightFacade::get_current_simple_value"; |
| match self.get_proxy()?.get_current_simple_value(index).await? { |
| Ok(r) => Ok(r), |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("GetCurrentSimpleValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn set_simple_value(&self, index: u32, value: bool) -> Result<(), Error> { |
| let tag = "LightFacade::set_simple_value"; |
| match self.get_proxy()?.set_simple_value(index, value).await? { |
| Ok(r) => Ok(r), |
| Err(e) => { |
| fx_err_and_bail!(&with_line!(tag), format_err!("SetSimpleValue failed {:?}", e)) |
| } |
| } |
| } |
| |
| pub async fn get_current_brightness_value(&self, index: u32) -> Result<f64, Error> { |
| let tag = "LightFacade::get_current_brightness_value"; |
| match self.get_proxy()?.get_current_brightness_value(index).await? { |
| Ok(r) => Ok(r), |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("GetCurrentBrightnessValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn set_brightness_value(&self, index: u32, value: f64) -> Result<(), Error> { |
| let tag = "LightFacade::set_brightness_value"; |
| match self.get_proxy()?.set_brightness_value(index, value).await? { |
| Ok(r) => Ok(r), |
| Err(e) => { |
| fx_err_and_bail!(&with_line!(tag), format_err!("SetBrightnessValue failed {:?}", e)) |
| } |
| } |
| } |
| |
| pub async fn get_current_rgb_value(&self, index: u32) -> Result<SerializableRgb, Error> { |
| let tag = "LightFacade::get_current_rgb_value"; |
| match self.get_proxy()?.get_current_rgb_value(index).await? { |
| Ok(r) => Ok(SerializableRgb::new(&r)), |
| Err(e) => { |
| fx_err_and_bail!(&with_line!(tag), format_err!("GetCurrentRgbValue failed {:?}", e)) |
| } |
| } |
| } |
| |
| pub async fn set_rgb_value(&self, index: u32, value: SerializableRgb) -> Result<(), Error> { |
| let tag = "LightFacade::set_rgb_value"; |
| let mut rgb = Rgb { red: value.red, green: value.green, blue: value.blue }; |
| match self.get_proxy()?.set_rgb_value(index, &mut rgb).await? { |
| Ok(r) => Ok(r), |
| Err(e) => fx_err_and_bail!(&with_line!(tag), format_err!("SetRgbValue failed {:?}", e)), |
| } |
| } |
| |
| pub async fn get_group_info(&self, index: u32) -> Result<SerializableGroupInfo, Error> { |
| let tag = "LightFacade::get_group_info"; |
| match self.get_proxy()?.get_group_info(index).await? { |
| Ok(r) => Ok(SerializableGroupInfo::new(&r)), |
| Err(e) => { |
| fx_err_and_bail!(&with_line!(tag), format_err!("GetGroupInfo failed {:?}", e)) |
| } |
| } |
| } |
| |
| pub async fn get_group_current_simple_value(&self, index: u32) -> Result<Vec<bool>, Error> { |
| let tag = "LightFacade::get_group_current_simple_value"; |
| match self.get_proxy()?.get_group_current_simple_value(index).await? { |
| Ok(r) => match r { |
| Some(v) => Ok(v), |
| None => fx_err_and_bail!(&with_line!(tag), format_err!("Expected a vector")), |
| }, |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("GetGroupCurrentSimpleValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn set_group_simple_value(&self, index: u32, value: Vec<bool>) -> Result<(), Error> { |
| let tag = "LightFacade::set_group_simple_value"; |
| match self.get_proxy()?.set_group_simple_value(index, &mut value.into_iter()).await? { |
| Ok(_) => Ok(()), |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("SetGroupSimpleValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn get_group_current_brightness_value(&self, index: u32) -> Result<Vec<f64>, Error> { |
| let tag = "LightFacade::get_group_current_brightness_value"; |
| match self.get_proxy()?.get_group_current_brightness_value(index).await? { |
| Ok(r) => match r { |
| Some(v) => Ok(v), |
| None => fx_err_and_bail!(&with_line!(tag), format_err!("Expected a vector")), |
| }, |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("GetGroupCurrentBrightnessValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn set_group_brightness_value( |
| &self, |
| index: u32, |
| value: Vec<f64>, |
| ) -> Result<(), Error> { |
| let tag = "LightFacade::set_group_brightness_value"; |
| match self.get_proxy()?.set_group_brightness_value(index, &value).await? { |
| Ok(_) => Ok(()), |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("SetGroupBrightnessValue failed {:?}", e) |
| ), |
| } |
| } |
| |
| pub async fn get_group_current_rgb_value( |
| &self, |
| index: u32, |
| ) -> Result<Vec<SerializableRgb>, Error> { |
| let tag = "LightFacade::get_group_current_rgb_value"; |
| let values = match self.get_proxy()?.get_group_current_rgb_value(index).await? { |
| Ok(r) => match r { |
| Some(v) => v, |
| None => fx_err_and_bail!(&with_line!(tag), format_err!("Expected a vector")), |
| }, |
| Err(e) => fx_err_and_bail!( |
| &with_line!(tag), |
| format_err!("GetGroupCurrentRgbValue failed {:?}", e) |
| ), |
| }; |
| let ret = values |
| .into_iter() |
| .map(|x| SerializableRgb { red: x.red, green: x.green, blue: x.blue }) |
| .collect::<Vec<_>>(); |
| Ok(ret) |
| } |
| |
| pub async fn set_group_rgb_value( |
| &self, |
| index: u32, |
| value: Vec<SerializableRgb>, |
| ) -> Result<(), Error> { |
| let tag = "LightFacade::set_group_rgb_value"; |
| let mut rgb = value |
| .into_iter() |
| .map(|x| Rgb { red: x.red, green: x.green, blue: x.blue }) |
| .collect::<Vec<Rgb>>(); |
| match self.get_proxy()?.set_group_rgb_value(index, &mut rgb.iter_mut()).await? { |
| Ok(_) => Ok(()), |
| Err(e) => { |
| fx_err_and_bail!(&with_line!(tag), format_err!("SetGroupRgbValue failed {:?}", e)) |
| } |
| } |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| use crate::light::types::SerializableCapability; |
| use fidl_fuchsia_hardware_light::{Capability, GroupInfo, Info, LightError, LightRequest, Rgb}; |
| use futures::{future::Future, join, stream::StreamExt}; |
| use matches::assert_matches; |
| |
| struct MockLightBuilder { |
| expected: Vec<Box<dyn FnOnce(LightRequest) + Send + 'static>>, |
| } |
| |
| impl MockLightBuilder { |
| fn new() -> Self { |
| Self { expected: vec![] } |
| } |
| |
| fn push(mut self, request: impl FnOnce(LightRequest) + Send + 'static) -> Self { |
| self.expected.push(Box::new(request)); |
| self |
| } |
| |
| fn expect_get_num_lights(self, count: u32) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetNumLights { responder } => responder.send(count).unwrap(), |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_num_light_groups(self, count: u32) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetNumLightGroups { responder } => responder.send(count).unwrap(), |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_info(self, idx: u32, res: Result<SerializableInfo, LightError>) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetInfo { index, responder } => { |
| assert_eq!(idx, index); |
| responder |
| .send(&mut res.map(|info| Info { |
| name: info.name.clone(), |
| capability: Capability::from(info.capability), |
| })) |
| .unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_current_simple_value(self, idx: u32, res: Result<bool, LightError>) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetCurrentSimpleValue { index, responder } => { |
| assert_eq!(idx, index); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_simple_value(self, idx: u32, val: bool, res: Result<(), LightError>) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetSimpleValue { index, value, responder } => { |
| assert_eq!(idx, index); |
| assert_eq!(val, value); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_current_brightness_value( |
| self, |
| idx: u32, |
| res: Result<f64, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetCurrentBrightnessValue { index, responder } => { |
| assert_eq!(idx, index); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_brightness_value( |
| self, |
| idx: u32, |
| val: f64, |
| res: Result<(), LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetBrightnessValue { index, value, responder } => { |
| assert_eq!(idx, index); |
| assert_eq!(val, value); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_current_rgb_value( |
| self, |
| idx: u32, |
| res: Result<SerializableRgb, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetCurrentRgbValue { index, responder } => { |
| assert_eq!(idx, index); |
| responder |
| .send(&mut res.map(|rgb| Rgb { |
| red: rgb.red, |
| green: rgb.green, |
| blue: rgb.blue, |
| })) |
| .unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_rgb_value( |
| self, |
| idx: u32, |
| val: SerializableRgb, |
| res: Result<(), LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetRgbValue { index, value, responder } => { |
| assert_eq!(idx, index); |
| assert_eq!(val, SerializableRgb::new(&value)); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_group_info( |
| self, |
| id: u32, |
| res: Result<SerializableGroupInfo, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetGroupInfo { group_id, responder } => { |
| assert_eq!(id, group_id); |
| responder |
| .send(&mut res.map(|info| GroupInfo { |
| name: info.name.clone(), |
| count: info.count, |
| capability: Capability::from(info.capability), |
| })) |
| .unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_group_current_simple_value( |
| self, |
| id: u32, |
| res: Result<Vec<bool>, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetGroupCurrentSimpleValue { group_id, responder } => { |
| assert_eq!(id, group_id); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_group_simple_value( |
| self, |
| id: u32, |
| vals: Vec<bool>, |
| res: Result<(), LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetGroupSimpleValue { group_id, values, responder } => { |
| assert_eq!(id, group_id); |
| assert_eq!(vals, values); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_group_current_brightness_value( |
| self, |
| id: u32, |
| res: Result<Vec<f64>, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetGroupCurrentBrightnessValue { group_id, responder } => { |
| assert_eq!(id, group_id); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_group_brightness_value( |
| self, |
| id: u32, |
| vals: Vec<f64>, |
| res: Result<(), LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetGroupBrightnessValue { group_id, values, responder } => { |
| assert_eq!(id, group_id); |
| assert_eq!(vals, values); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_get_group_current_rgb_value( |
| self, |
| id: u32, |
| res: Result<Option<Vec<SerializableRgb>>, LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::GetGroupCurrentRgbValue { group_id, responder } => { |
| assert_eq!(id, group_id); |
| responder |
| .send(&mut res.map(|opt| { |
| opt.map(|vec| { |
| vec.iter().map(|x| Into::into(x.clone())).collect::<Vec<_>>() |
| }) |
| })) |
| .unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn expect_set_group_rgb_value( |
| self, |
| id: u32, |
| vals: Vec<SerializableRgb>, |
| res: Result<(), LightError>, |
| ) -> Self { |
| self.push(move |req| match req { |
| LightRequest::SetGroupRgbValue { group_id, values, responder } => { |
| assert_eq!(id, group_id); |
| assert_eq!(vals, values.iter().map(|x| Into::into(*x)).collect::<Vec<_>>()); |
| responder.send(&mut res.map(Into::into)).unwrap() |
| } |
| req => panic!("unexpected request: {:?}", req), |
| }) |
| } |
| |
| fn build(self) -> (LightFacade, impl Future<Output = ()>) { |
| let (proxy, mut stream) = |
| fidl::endpoints::create_proxy_and_stream::<LightMarker>().unwrap(); |
| let fut = async move { |
| for expected in self.expected { |
| expected(stream.next().await.unwrap().unwrap()); |
| } |
| assert_matches!(stream.next().await, None); |
| }; |
| |
| (LightFacade::new_with_proxy(proxy), fut) |
| } |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_num_lights_ok() { |
| let (facade, lights) = MockLightBuilder::new().expect_get_num_lights(3).build(); |
| let test = async move { |
| assert_matches!(facade.get_num_lights().await, Ok(3)); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_num_light_groups_ok() { |
| let (facade, lights) = MockLightBuilder::new().expect_get_num_light_groups(5).build(); |
| let test = async move { |
| assert_matches!(facade.get_num_light_groups().await, Ok(5)); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_info_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_info( |
| 4, |
| Ok(SerializableInfo { |
| name: "test_light".to_string(), |
| capability: SerializableCapability::Rgb, |
| }), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_info(4).await, |
| Ok(info) if info == SerializableInfo { |
| name: "test_light".to_string(), |
| capability: SerializableCapability::Rgb |
| } |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_current_simple_value_ok() { |
| let (facade, lights) = |
| MockLightBuilder::new().expect_get_current_simple_value(2, Ok(true)).build(); |
| let test = async move { |
| assert_matches!(facade.get_current_simple_value(2).await, Ok(true)); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_simple_value_ok() { |
| let (facade, lights) = |
| MockLightBuilder::new().expect_set_simple_value(1, false, Ok(())).build(); |
| let test = async move { |
| assert_matches!(facade.set_simple_value(1, false).await, Ok(())); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_current_brightness_value_ok() { |
| let (facade, lights) = |
| MockLightBuilder::new().expect_get_current_brightness_value(0, Ok(0.3321)).build(); |
| let test = async move { |
| assert_matches!(facade.get_current_brightness_value(0).await, Ok(v) if v == 0.3321); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_brightness_value_ok() { |
| let (facade, lights) = |
| MockLightBuilder::new().expect_set_brightness_value(1, 0.2515, Ok(())).build(); |
| let test = async move { |
| assert_matches!(facade.set_brightness_value(1, 0.2515).await, Ok(())); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_current_rgb_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_current_rgb_value( |
| 4, |
| Ok(SerializableRgb { red: 0.21, green: 0.94, blue: 0.59 }), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_current_rgb_value(4).await, |
| Ok(rgb) if rgb == SerializableRgb { red: 0.21, green: 0.94, blue: 0.59 } |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_rgb_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_set_rgb_value( |
| 3, |
| SerializableRgb { red: 0.33, green: 0.45, blue: 0.155 }, |
| Ok(()), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade |
| .set_rgb_value(3, SerializableRgb { red: 0.33, green: 0.45, blue: 0.155 }) |
| .await, |
| Ok(()) |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_group_info_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_group_info( |
| 2, |
| Ok(SerializableGroupInfo { |
| name: "test_light_group".to_string(), |
| count: 5, |
| capability: SerializableCapability::Brightness, |
| }), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_group_info(2).await, |
| Ok(info) if info == SerializableGroupInfo { |
| name: "test_light_group".to_string(), |
| count: 5, |
| capability: SerializableCapability::Brightness |
| } |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_group_current_simple_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_group_current_simple_value(0, Ok(vec![false, true, false])) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_group_current_simple_value(0).await, |
| Ok(v) if v == vec![false, true, false] |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_group_simple_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_set_group_simple_value(3, vec![true, true, false], Ok(())) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.set_group_simple_value(3, vec![true, true, false]).await, |
| Ok(()) |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_group_current_brightness_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_group_current_brightness_value(1, Ok(vec![0.46, 0.2, 0.77, 0.315, 0.8])) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_group_current_brightness_value(1).await, |
| Ok(v) if v == vec![0.46, 0.2, 0.77, 0.315, 0.8] |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_group_brightness_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_set_group_brightness_value(2, vec![0.0, 0.96, 0.37, 0.63], Ok(())) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.set_group_brightness_value(2, vec![0.0, 0.96, 0.37, 0.63]).await, |
| Ok(()) |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn get_group_current_rgb_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_get_group_current_rgb_value( |
| 0, |
| Ok(Some(vec![ |
| SerializableRgb { red: 0.24, green: 0.41, blue: 0.121 }, |
| SerializableRgb { red: 0.83, green: 0.23, blue: 0.155 }, |
| ])), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade.get_group_current_rgb_value(0).await, |
| Ok(v) if v == vec![ |
| SerializableRgb { red: 0.24, green: 0.41, blue: 0.121 }, |
| SerializableRgb { red: 0.83, green: 0.23, blue: 0.155 } |
| ] |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| |
| #[fuchsia_async::run_singlethreaded(test)] |
| async fn set_group_rgb_value_ok() { |
| let (facade, lights) = MockLightBuilder::new() |
| .expect_set_group_rgb_value( |
| 1, |
| vec![ |
| SerializableRgb { red: 0.0, green: 0.3, blue: 0.3 }, |
| SerializableRgb { red: 0.111, green: 0.222, blue: 0.11 }, |
| SerializableRgb { red: 0.194, green: 0.9, blue: 0.70 }, |
| ], |
| Ok(()), |
| ) |
| .build(); |
| let test = async move { |
| assert_matches!( |
| facade |
| .set_group_rgb_value( |
| 1, |
| vec![ |
| SerializableRgb { red: 0.0, green: 0.3, blue: 0.3 }, |
| SerializableRgb { red: 0.111, green: 0.222, blue: 0.11 }, |
| SerializableRgb { red: 0.194, green: 0.9, blue: 0.70 } |
| ] |
| ) |
| .await, |
| Ok(()) |
| ); |
| }; |
| |
| join!(lights, test); |
| } |
| } |