use shep_core::config::AppConfig;
use shep_core::protocol::{ProcessInfo, Response, SheepConfigView};
use shep_core::status::ProcStatus;
use crate::lookout::app::{App, Control, KeyPress, Msg, Sent};
use super::flock::with_selection;
pub fn sheep_config_view() -> SheepConfigView {
sheep_config_view_parking(vec!["kill_signal".to_string()])
}
pub(super) fn sheep_config_view_parking(pending: Vec<String>) -> SheepConfigView {
let mut config = AppConfig {
name: "web".to_string(),
script: "./srv".to_string(),
args: vec!["--port".to_string(), "8080".to_string()],
max_restarts: 32,
instances: 3,
..AppConfig::default()
};
config
.env
.insert("DB_HOST".to_string(), "db.internal".to_string());
config
.env
.insert("LOG_LEVEL".to_string(), "debug".to_string());
SheepConfigView::new(
config,
vec!["max_restarts".to_string(), "reuse_port".to_string()],
pending,
)
}
pub fn app_in_sheep_pane_with_env(env: &[(&str, &str)]) -> App {
let mut app = with_selection(
ProcessInfo::builder(9, "web", ProcStatus::Online)
.pid(Some(48_000))
.build(),
);
app.set_control_for_tests(Control::Allowed);
app.update(Msg::Key(KeyPress::Edit));
let mut config = AppConfig {
name: "web".to_string(),
..AppConfig::default()
};
for (key, value) in env {
config.env.insert((*key).to_string(), (*value).to_string());
}
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(SheepConfigView::new(
config,
Vec::new(),
Vec::new(),
)))),
});
app
}
#[track_caller]
pub fn select_env_key(app: &mut App, key: &str) {
let pane = app.config_pane().expect("the pane is open");
let index = pane
.rows()
.iter()
.position(|row| match row {
crate::lookout::pane::PaneRow::Env(env_index) => {
pane.env_key_names().get(*env_index).map(String::as_str) == Some(key)
}
crate::lookout::pane::PaneRow::Field(_) | crate::lookout::pane::PaneRow::AddEnv => {
false
}
})
.unwrap_or_else(|| panic!("no env key named {key}"));
app.update(Msg::Key(KeyPress::SelectFirst));
for _ in 0..index {
app.update(Msg::Key(KeyPress::SelectDown));
}
}
pub fn type_into_the_open_editor(app: &mut App, text: &str) {
app.update(Msg::Key(KeyPress::Confirm));
for character in text.chars() {
app.update(Msg::Key(KeyPress::TextChar(character)));
}
app.update(Msg::Key(KeyPress::TextApply));
}
pub fn app_in_sheep_pane_with_control() -> App {
let mut app = with_selection(
ProcessInfo::builder(9, "web", ProcStatus::Online)
.pid(Some(48_000))
.build(),
);
app.set_control_for_tests(Control::Allowed);
app.update(Msg::Key(KeyPress::Edit));
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(sheep_config_view()))),
});
app
}
pub fn app_in_sheep_pane_with_a_parked_field() -> App {
app_in_sheep_pane_with_control()
}
pub fn app_in_sheep_pane_with_two_parked_fields() -> App {
app_in_sheep_pane_parking(vec!["kill_signal".to_string(), "script".to_string()])
}
pub fn app_in_sheep_pane_with_nothing_parked() -> App {
app_in_sheep_pane_parking(Vec::new())
}
fn app_in_sheep_pane_parking(pending: Vec<String>) -> App {
let mut app = with_selection(
ProcessInfo::builder(9, "web", ProcStatus::Online)
.pid(Some(48_000))
.build(),
);
app.set_control_for_tests(Control::Allowed);
app.update(Msg::Key(KeyPress::Edit));
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(sheep_config_view_parking(
pending,
)))),
});
app
}
pub fn app_in_sheep_pane() -> App {
let mut app = with_selection(
ProcessInfo::builder(9, "web", ProcStatus::Online)
.pid(Some(48_000))
.build(),
);
app.update(Msg::Key(KeyPress::Edit));
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(sheep_config_view()))),
});
app
}
pub fn app_in_sheep_pane_read_only() -> App {
let mut app = app_in_sheep_pane();
app.set_control_for_tests(Control::ReadOnly);
app
}
pub fn app_in_sheep_pane_on_a_stopped_sheep() -> App {
let mut app = with_selection(ProcessInfo::builder(9, "web", ProcStatus::Stopped).build());
app.set_control_for_tests(Control::Allowed);
app.update(Msg::Key(KeyPress::Edit));
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(sheep_config_view_parking(
Vec::new(),
)))),
});
app
}
pub fn app_in_sheep_pane_on_a_draining_sheep() -> App {
let mut app = with_selection(ProcessInfo::builder(9, "web", ProcStatus::Stopping).build());
app.set_control_for_tests(Control::Allowed);
app.update(Msg::Key(KeyPress::Edit));
app.update(Msg::Replied {
sent: Sent::SheepConfig {
name: "web".to_string(),
},
result: Ok(Response::SheepConfig(Box::new(sheep_config_view_parking(
Vec::new(),
)))),
});
app
}
pub fn file_edit(app: &mut App, key: &str, value: &str) {
app.set_control_for_tests(Control::Allowed);
select_field(app, key);
app.update(Msg::Key(KeyPress::Confirm));
for _ in 0..64 {
app.update(Msg::Key(KeyPress::TextBackspace));
}
for character in value.chars() {
app.update(Msg::Key(KeyPress::TextChar(character)));
}
app.update(Msg::Key(KeyPress::TextApply));
}
pub fn select_field(app: &mut App, key: &str) {
let pane = app.config_pane().expect("the pane is open");
let group = pane
.fields()
.by_key(key)
.unwrap_or_else(|| panic!("no field named {key}"))
.group
.clone();
if let Some(group) = group
&& let Some(position) = shep_core::config::GROUP_ORDER
.iter()
.position(|known| *known == group)
{
let digit = u8::try_from(position + 1).expect("nine groups fit a u8");
app.update(Msg::Key(KeyPress::Group(digit)));
}
let pane = app.config_pane().expect("the pane is open");
let index = pane
.rows()
.iter()
.position(|row| match row {
crate::lookout::pane::PaneRow::Field(field_index) => {
pane.fields().fields()[*field_index].key == key
}
crate::lookout::pane::PaneRow::Env(_) | crate::lookout::pane::PaneRow::AddEnv => false,
})
.unwrap_or_else(|| panic!("{key} is not in the active group's rows"));
app.update(Msg::Key(KeyPress::SelectFirst));
for _ in 0..index {
app.update(Msg::Key(KeyPress::SelectDown));
}
}
pub fn app_in_sheep_pane_with_two_edits() -> App {
let mut app = app_in_sheep_pane_with_nothing_parked();
for (key, typed) in [("cwd", "/srv/web"), ("max_memory", "40")] {
select_field(&mut app, key);
app.update(Msg::Key(KeyPress::Confirm));
for _ in 0..64 {
app.update(Msg::Key(KeyPress::TextBackspace));
}
for character in typed.chars() {
app.update(Msg::Key(KeyPress::TextChar(character)));
}
app.update(Msg::Key(KeyPress::TextApply));
}
assert_eq!(
app.config_pane().expect("the pane is open").edits().len(),
2,
"the fixture files two edits"
);
app
}
pub fn app_in_sheep_pane_with_one_edit() -> App {
let mut app = app_in_sheep_pane_with_nothing_parked();
file_edit(&mut app, "cwd", "/srv/web");
assert_eq!(
app.config_pane().expect("the pane is open").edits().len(),
1,
"the fixture files one edit"
);
app
}
pub fn app_with_plain_palette_in_sheep_pane() -> App {
app_in_sheep_pane()
}