Skip to main content

yosh_plugin_manager/test_host/
variables.rs

1//! In-memory `yosh:plugin/variables` host imports backed by
2//! `TestState.vars` / `TestState.exported`. Gated on
3//! CAP_VARIABLES_READ and CAP_VARIABLES_WRITE.
4
5use super::TestState;
6use crate::generated::yosh::plugin::types::ErrorCode;
7use yosh_plugin_api::{CAP_VARIABLES_READ, CAP_VARIABLES_WRITE};
8
9pub fn host_get(state: &TestState, name: &str) -> Result<Option<String>, ErrorCode> {
10    if state.caps & CAP_VARIABLES_READ == 0 {
11        return Err(ErrorCode::Denied);
12    }
13    Ok(state.vars.get(name).cloned())
14}
15
16pub fn host_set(state: &mut TestState, name: &str, value: &str) -> Result<(), ErrorCode> {
17    if state.caps & CAP_VARIABLES_WRITE == 0 {
18        return Err(ErrorCode::Denied);
19    }
20    state.vars.insert(name.to_string(), value.to_string());
21    state.set_log.push((name.to_string(), value.to_string()));
22    Ok(())
23}
24
25pub fn host_export_env(state: &mut TestState, name: &str, value: &str) -> Result<(), ErrorCode> {
26    if state.caps & CAP_VARIABLES_WRITE == 0 {
27        return Err(ErrorCode::Denied);
28    }
29    state.vars.insert(name.to_string(), value.to_string());
30    state.exported.insert(name.to_string());
31    state.export_log.push((name.to_string(), value.to_string()));
32    Ok(())
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn get_denied_without_cap() {
41        let s = TestState::with_caps(0);
42        assert_eq!(host_get(&s, "FOO"), Err(ErrorCode::Denied));
43    }
44
45    #[test]
46    fn get_returns_none_for_unset() {
47        let s = TestState::with_caps(CAP_VARIABLES_READ);
48        assert_eq!(host_get(&s, "FOO"), Ok(None));
49    }
50
51    #[test]
52    fn get_returns_value_when_set() {
53        let mut s = TestState::with_caps(CAP_VARIABLES_READ);
54        s.vars.insert("FOO".into(), "bar".into());
55        assert_eq!(host_get(&s, "FOO"), Ok(Some("bar".into())));
56    }
57
58    #[test]
59    fn set_denied_without_cap() {
60        let mut s = TestState::with_caps(CAP_VARIABLES_READ);
61        assert_eq!(host_set(&mut s, "FOO", "bar"), Err(ErrorCode::Denied));
62        assert!(s.set_log.is_empty());
63    }
64
65    #[test]
66    fn set_records_log() {
67        let mut s = TestState::with_caps(CAP_VARIABLES_WRITE);
68        host_set(&mut s, "FOO", "bar").unwrap();
69        assert_eq!(s.vars.get("FOO").map(|s| s.as_str()), Some("bar"));
70        assert_eq!(s.set_log, vec![("FOO".into(), "bar".into())]);
71    }
72
73    #[test]
74    fn export_env_records_export_set() {
75        let mut s = TestState::with_caps(CAP_VARIABLES_WRITE);
76        host_export_env(&mut s, "PATH", "/bin").unwrap();
77        assert!(s.exported.contains("PATH"));
78        assert_eq!(s.export_log, vec![("PATH".into(), "/bin".into())]);
79    }
80}