mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-11 22:53:00 +00:00
chore(lint): fix all clippy warnings including --tests
Resolve every clippy warning across the workspace when running with --tests enabled. Previously only library code was lint-clean; test code had accumulated issues that were invisible without --tests. Fixes: - redundant_closure_for_method_calls: |s| s.as_source() -> InterpString::as_source (effective_settings, resolve_cli/root/server/features, run_event/record_serde, materialize_run) — add InterpString imports where needed - absolute_paths: inline fabro_types::settings::* paths -> use imports; add #![allow(clippy::absolute_paths)] to fabro-cli and fabro-server IT test harnesses (matching the existing pattern in integration.rs) - bool_assert_comparison: assert_eq!(x, true) -> assert!(x) - needless_raw_string_hashes: r#"..."# -> r"..." where no inner quotes - field_reassign_with_default: mut + field assign -> struct literal with ..Default - match_same_arms: merge Timeout | Disconnected arms in attach.rs - needless_pass_by_value: signal_rx by ref in attach.rs - unreadable_literal: 9999999999 -> 9_999_999_999 - default_trait_access: Default::default() -> BTreeMap::default() - items_after_statements: move use to function top - large_futures: allow in integration.rs test module (test-only, not prod) - filter_map_bool_then: .filter_map(bool::then) -> .filter().map() Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
42f8ec271b
commit
76089bd8aa
30 changed files with 140 additions and 104 deletions
|
|
@ -1080,15 +1080,21 @@ mod tests {
|
|||
};
|
||||
let certs_dir = fabro_util::Home::from_env().certs_dir();
|
||||
assert_eq!(
|
||||
tls.cert.as_ref().map(|c| c.as_source()),
|
||||
tls.cert
|
||||
.as_ref()
|
||||
.map(fabro_types::settings::InterpString::as_source),
|
||||
Some(certs_dir.join("server.crt").to_string_lossy().into_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
tls.key.as_ref().map(|c| c.as_source()),
|
||||
tls.key
|
||||
.as_ref()
|
||||
.map(fabro_types::settings::InterpString::as_source),
|
||||
Some(certs_dir.join("server.key").to_string_lossy().into_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
tls.ca.as_ref().map(|c| c.as_source()),
|
||||
tls.ca
|
||||
.as_ref()
|
||||
.map(fabro_types::settings::InterpString::as_source),
|
||||
Some(certs_dir.join("ca.crt").to_string_lossy().into_owned())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -488,6 +488,7 @@ fn install_signal_handlers(
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::absolute_paths)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ fn wait_for_output_signal(
|
|||
child: &mut std::process::Child,
|
||||
stdout: &mut impl Read,
|
||||
stderr_reader: std::thread::JoinHandle<Vec<u8>>,
|
||||
signal_rx: mpsc::Receiver<()>,
|
||||
signal_rx: &mpsc::Receiver<()>,
|
||||
needle: &str,
|
||||
) -> std::thread::JoinHandle<Vec<u8>> {
|
||||
let deadline = Instant::now() + SHARED_DAEMON_TIMEOUT;
|
||||
|
|
@ -96,8 +96,7 @@ fn wait_for_output_signal(
|
|||
.take()
|
||||
.expect("stderr reader should still be available");
|
||||
}
|
||||
Err(mpsc::RecvTimeoutError::Timeout) => {}
|
||||
Err(mpsc::RecvTimeoutError::Disconnected) => {}
|
||||
Err(mpsc::RecvTimeoutError::Timeout | mpsc::RecvTimeoutError::Disconnected) => {}
|
||||
}
|
||||
|
||||
if let Some(status) = child.try_wait().expect("attach should stay alive") {
|
||||
|
|
@ -252,8 +251,13 @@ fn attach_before_completion_streams_to_finished_state() {
|
|||
|
||||
stderr_bytes
|
||||
});
|
||||
let stderr_reader =
|
||||
wait_for_output_signal(&mut child, &mut stdout, stderr_reader, signal_rx, "✓ start");
|
||||
let stderr_reader = wait_for_output_signal(
|
||||
&mut child,
|
||||
&mut stdout,
|
||||
stderr_reader,
|
||||
&signal_rx,
|
||||
"✓ start",
|
||||
);
|
||||
gate.release();
|
||||
let status = child.wait().expect("attach should exit");
|
||||
let mut stdout_bytes = Vec::new();
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ fn run_model_name(settings: &SettingsLayer) -> Option<String> {
|
|||
.model
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
}
|
||||
|
||||
fn run_model_provider(settings: &SettingsLayer) -> Option<String> {
|
||||
|
|
@ -71,7 +71,7 @@ fn run_model_provider(settings: &SettingsLayer) -> Option<String> {
|
|||
.model
|
||||
.provider
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
}
|
||||
|
||||
fn run_inputs(settings: &SettingsLayer) -> &std::collections::HashMap<String, toml::Value> {
|
||||
|
|
@ -102,8 +102,7 @@ fn run_hooks(settings: &SettingsLayer) -> &[fabro_types::settings::run::HookEntr
|
|||
settings
|
||||
.run
|
||||
.as_ref()
|
||||
.map(|run| run.hooks.as_slice())
|
||||
.unwrap_or(&[])
|
||||
.map_or(&[], |run| run.hooks.as_slice())
|
||||
}
|
||||
|
||||
fn run_agent_mcps(
|
||||
|
|
@ -410,6 +409,7 @@ fn settings_local_merges_cli_and_project_defaults() {
|
|||
|
||||
#[test]
|
||||
fn settings_local_workflow_name_applies_run_overlay_and_deep_merges() {
|
||||
use fabro_types::settings::run::McpEntryLayer;
|
||||
let context = test_context!();
|
||||
let project = setup_settings_fixture(&context);
|
||||
|
||||
|
|
@ -423,8 +423,6 @@ fn settings_local_workflow_name_applies_run_overlay_and_deep_merges() {
|
|||
.stdout
|
||||
.clone();
|
||||
|
||||
use fabro_types::settings::run::McpEntryLayer;
|
||||
|
||||
let cfg = parse_settings(&output);
|
||||
assert_eq!(run_goal_inline(&cfg).as_deref(), Some("demo goal"));
|
||||
assert_eq!(run_model_name(&cfg).as_deref(), Some("run-model"));
|
||||
|
|
@ -456,7 +454,7 @@ fn settings_local_workflow_name_applies_run_overlay_and_deep_merges() {
|
|||
shared_hook
|
||||
.script
|
||||
.as_ref()
|
||||
.map(|s| s.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("echo run")
|
||||
);
|
||||
|
|
@ -470,7 +468,10 @@ fn settings_local_workflow_name_applies_run_overlay_and_deep_merges() {
|
|||
match mcps.get("shared").expect("shared mcp") {
|
||||
McpEntryLayer::Stdio { command, .. } => {
|
||||
let command = command.as_ref().expect("command");
|
||||
let parts: Vec<String> = command.iter().map(|c| c.as_source()).collect();
|
||||
let parts: Vec<String> = command
|
||||
.iter()
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.collect();
|
||||
assert_eq!(parts, vec!["echo".to_string(), "run".to_string()]);
|
||||
}
|
||||
other => panic!("unexpected MCP transport: {other:?}"),
|
||||
|
|
@ -486,15 +487,21 @@ fn settings_local_workflow_name_applies_run_overlay_and_deep_merges() {
|
|||
// run.sandbox.env stays sticky merge-by-key per R71.
|
||||
let env = &sandbox.env;
|
||||
assert_eq!(
|
||||
env.get("CLI_ONLY").map(|v| v.as_source()).as_deref(),
|
||||
env.get("CLI_ONLY")
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("1")
|
||||
);
|
||||
assert_eq!(
|
||||
env.get("RUN_ONLY").map(|v| v.as_source()).as_deref(),
|
||||
env.get("RUN_ONLY")
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("1")
|
||||
);
|
||||
assert_eq!(
|
||||
env.get("SHARED").map(|v| v.as_source()).as_deref(),
|
||||
env.get("SHARED")
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("run")
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,8 +373,8 @@ fn create_persists_requested_overrides_into_store() {
|
|||
"no_retro": !resolved_run.execution.retros,
|
||||
"verbose": cli_settings.output.verbosity == fabro_types::settings::cli::OutputVerbosity::Verbose,
|
||||
"llm": {
|
||||
"model": resolved_run.model.name.as_ref().map(|value| value.as_source()),
|
||||
"provider": resolved_run.model.provider.as_ref().map(|value| value.as_source()),
|
||||
"model": resolved_run.model.name.as_ref().map(fabro_types::settings::InterpString::as_source),
|
||||
"provider": resolved_run.model.provider.as_ref().map(fabro_types::settings::InterpString::as_source),
|
||||
},
|
||||
"sandbox": {
|
||||
"provider": resolved_run.sandbox.provider,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::absolute_paths)]
|
||||
|
||||
mod cmd;
|
||||
mod scenario;
|
||||
mod support;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ mod tests {
|
|||
use crate::parse::parse_settings_layer;
|
||||
use fabro_types::settings::InterpString;
|
||||
use fabro_types::settings::SettingsLayer;
|
||||
use fabro_types::settings::run::RunGoalLayer;
|
||||
use fabro_types::settings::server::{ServerLayer, ServerSchedulerLayer, ServerStorageLayer};
|
||||
|
||||
use super::{EffectiveSettingsLayers, EffectiveSettingsMode, resolve_settings};
|
||||
|
|
@ -236,7 +237,7 @@ shared = "user"
|
|||
.as_ref()
|
||||
.and_then(|run| run.model.as_ref())
|
||||
.and_then(|model| model.name.as_ref())
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("project-model")
|
||||
);
|
||||
|
|
@ -299,7 +300,7 @@ provider = "openai"
|
|||
|
||||
assert_eq!(
|
||||
match settings.run.as_ref().and_then(|run| run.goal.as_ref()) {
|
||||
Some(fabro_types::settings::run::RunGoalLayer::Inline(value)) => {
|
||||
Some(RunGoalLayer::Inline(value)) => {
|
||||
Some(value.as_source())
|
||||
}
|
||||
_ => None,
|
||||
|
|
@ -313,7 +314,7 @@ provider = "openai"
|
|||
.as_ref()
|
||||
.and_then(|run| run.model.as_ref())
|
||||
.and_then(|model| model.name.as_ref())
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("workflow-model")
|
||||
);
|
||||
|
|
@ -323,7 +324,7 @@ provider = "openai"
|
|||
.as_ref()
|
||||
.and_then(|run| run.model.as_ref())
|
||||
.and_then(|model| model.provider.as_ref())
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("openai")
|
||||
);
|
||||
|
|
@ -331,16 +332,18 @@ provider = "openai"
|
|||
|
||||
#[test]
|
||||
fn cli_and_server_domains_from_fabro_toml_are_inert_under_remote_mode() {
|
||||
let mut server_settings = fabro_types::settings::SettingsLayer::default();
|
||||
server_settings.server = Some(ServerLayer {
|
||||
storage: Some(ServerStorageLayer {
|
||||
root: Some(InterpString::parse("/srv/fabro")),
|
||||
let server_settings = SettingsLayer {
|
||||
server: Some(ServerLayer {
|
||||
storage: Some(ServerStorageLayer {
|
||||
root: Some(InterpString::parse("/srv/fabro")),
|
||||
}),
|
||||
scheduler: Some(ServerSchedulerLayer {
|
||||
max_concurrent_runs: Some(9),
|
||||
}),
|
||||
..ServerLayer::default()
|
||||
}),
|
||||
scheduler: Some(ServerSchedulerLayer {
|
||||
max_concurrent_runs: Some(9),
|
||||
}),
|
||||
..ServerLayer::default()
|
||||
});
|
||||
..SettingsLayer::default()
|
||||
};
|
||||
|
||||
let project_with_server = layer(
|
||||
r#"
|
||||
|
|
@ -372,13 +375,13 @@ root = "/tmp/should-be-inert"
|
|||
.as_ref()
|
||||
.and_then(|server| server.storage.as_ref())
|
||||
.and_then(|storage| storage.root.as_ref())
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("/srv/fabro")
|
||||
);
|
||||
assert_eq!(
|
||||
match settings.run.as_ref().and_then(|run| run.goal.as_ref()) {
|
||||
Some(fabro_types::settings::run::RunGoalLayer::Inline(value)) => {
|
||||
Some(RunGoalLayer::Inline(value)) => {
|
||||
Some(value.as_source())
|
||||
}
|
||||
_ => None,
|
||||
|
|
@ -390,16 +393,18 @@ root = "/tmp/should-be-inert"
|
|||
|
||||
#[test]
|
||||
fn local_daemon_mode_only_applies_server_owned_overrides() {
|
||||
let mut server_settings = fabro_types::settings::SettingsLayer::default();
|
||||
server_settings.server = Some(ServerLayer {
|
||||
storage: Some(ServerStorageLayer {
|
||||
root: Some(InterpString::parse("/srv/fabro")),
|
||||
let server_settings = SettingsLayer {
|
||||
server: Some(ServerLayer {
|
||||
storage: Some(ServerStorageLayer {
|
||||
root: Some(InterpString::parse("/srv/fabro")),
|
||||
}),
|
||||
scheduler: Some(ServerSchedulerLayer {
|
||||
max_concurrent_runs: Some(7),
|
||||
}),
|
||||
..ServerLayer::default()
|
||||
}),
|
||||
scheduler: Some(ServerSchedulerLayer {
|
||||
max_concurrent_runs: Some(7),
|
||||
}),
|
||||
..ServerLayer::default()
|
||||
});
|
||||
..SettingsLayer::default()
|
||||
};
|
||||
|
||||
let settings = resolve_settings(
|
||||
EffectiveSettingsLayers::default(),
|
||||
|
|
@ -414,7 +419,7 @@ root = "/tmp/should-be-inert"
|
|||
.as_ref()
|
||||
.and_then(|server| server.storage.as_ref())
|
||||
.and_then(|storage| storage.root.as_ref())
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("/srv/fabro")
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use fabro_config::parse_settings_layer;
|
||||
use fabro_config::resolve_cli_from_file;
|
||||
use fabro_types::settings::SettingsLayer;
|
||||
use fabro_types::settings::cli::{CliTargetSettings, OutputFormat, OutputVerbosity};
|
||||
use fabro_types::settings::run::AgentPermissions;
|
||||
use fabro_types::settings::{InterpString, SettingsLayer};
|
||||
|
||||
#[test]
|
||||
fn resolves_cli_defaults_from_empty_settings() {
|
||||
|
|
@ -77,11 +77,11 @@ level = "debug"
|
|||
.model
|
||||
.provider
|
||||
.as_ref()
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("openai".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
cli.exec.model.name.as_ref().map(|value| value.as_source()),
|
||||
cli.exec.model.name.as_ref().map(InterpString::as_source),
|
||||
Some("gpt-5".to_string())
|
||||
);
|
||||
assert_eq!(cli.exec.agent.permissions, Some(AgentPermissions::ReadOnly));
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ fn resolves_features_defaults_from_empty_settings() {
|
|||
#[test]
|
||||
fn resolves_session_sandboxes_flag() {
|
||||
let settings: SettingsLayer = parse_settings_layer(
|
||||
r#"
|
||||
r"
|
||||
_version = 1
|
||||
|
||||
[features]
|
||||
session_sandboxes = true
|
||||
"#,
|
||||
",
|
||||
)
|
||||
.expect("fixture should parse");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use fabro_config::effective_settings::{EffectiveSettingsLayers, EffectiveSettingsMode};
|
||||
use fabro_config::parse_settings_layer;
|
||||
use fabro_types::settings::SettingsLayer;
|
||||
use fabro_types::settings::{InterpString, SettingsLayer};
|
||||
|
||||
fn parse(source: &str) -> SettingsLayer {
|
||||
parse_settings_layer(source).expect("fixture should parse")
|
||||
|
|
@ -13,10 +13,10 @@ fn resolves_root_settings_defaults() {
|
|||
|
||||
assert_eq!(settings.project.directory, "fabro/");
|
||||
assert_eq!(settings.workflow.graph, "workflow.fabro");
|
||||
assert_eq!(settings.run.execution.retros, true);
|
||||
assert_eq!(settings.cli.updates.check, true);
|
||||
assert!(settings.run.execution.retros);
|
||||
assert!(settings.cli.updates.check);
|
||||
assert_eq!(settings.server.scheduler.max_concurrent_runs, 5);
|
||||
assert_eq!(settings.features.session_sandboxes, false);
|
||||
assert!(!settings.features.session_sandboxes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -100,7 +100,7 @@ name = "gpt-5"
|
|||
.model
|
||||
.provider
|
||||
.as_ref()
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("openai".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
@ -109,7 +109,7 @@ name = "gpt-5"
|
|||
.model
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("gpt-5".to_string())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ fn resolves_server_defaults_from_empty_settings() {
|
|||
settings.storage.root.as_source(),
|
||||
Home::from_env().storage_dir().to_string_lossy()
|
||||
);
|
||||
assert_eq!(settings.web.enabled, true);
|
||||
assert!(settings.web.enabled);
|
||||
assert_eq!(settings.web.url.as_source(), "http://localhost:3000");
|
||||
assert_eq!(settings.scheduler.max_concurrent_runs, 5);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ impl Interviewer for ControlInterviewer {
|
|||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokio::task;
|
||||
|
||||
use crate::{AnswerValue, QuestionType};
|
||||
|
||||
use super::*;
|
||||
|
|
@ -180,7 +182,7 @@ mod tests {
|
|||
|
||||
let ask_interviewer = Arc::clone(&interviewer);
|
||||
let ask = tokio::spawn(async move { ask_interviewer.ask(question).await });
|
||||
tokio::task::yield_now().await;
|
||||
task::yield_now().await;
|
||||
|
||||
interviewer.interrupt_all().await;
|
||||
|
||||
|
|
@ -208,7 +210,7 @@ mod tests {
|
|||
|
||||
let ask_interviewer = Arc::clone(&interviewer);
|
||||
let ask = tokio::spawn(async move { ask_interviewer.ask(question).await });
|
||||
tokio::task::yield_now().await;
|
||||
task::yield_now().await;
|
||||
|
||||
interviewer.cancel_all().await;
|
||||
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ mod tests {
|
|||
#[test]
|
||||
fn fail_closed_when_all_strategies_disabled() {
|
||||
let file = settings(
|
||||
r#"
|
||||
r"
|
||||
_version = 1
|
||||
|
||||
[server.auth.api.jwt]
|
||||
|
|
@ -490,7 +490,7 @@ enabled = false
|
|||
|
||||
[server.auth.api.mtls]
|
||||
enabled = false
|
||||
"#,
|
||||
",
|
||||
);
|
||||
let err =
|
||||
resolve_auth_mode_with_lookup(&file, empty_lookup).expect_err("should refuse startup");
|
||||
|
|
@ -1008,7 +1008,7 @@ enabled = true
|
|||
avatar_url: "https://example.com/avatar.png".to_string(),
|
||||
user_url: "https://github.com/brynary".to_string(),
|
||||
github_id: 1,
|
||||
exp: 9999999999,
|
||||
exp: 9_999_999_999,
|
||||
});
|
||||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
|
|
|
|||
|
|
@ -992,7 +992,7 @@ app_id = "snapshotted-app-id"
|
|||
.github
|
||||
.app_id
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("snapshotted-app-id")
|
||||
);
|
||||
|
|
|
|||
|
|
@ -725,19 +725,19 @@ mod tests {
|
|||
.as_ref()
|
||||
.and_then(|server| server.storage.as_ref())
|
||||
.and_then(|storage| storage.root.as_ref())
|
||||
.map(|value| value.as_source());
|
||||
.map(fabro_types::settings::InterpString::as_source);
|
||||
assert_eq!(storage_root.as_deref(), Some("/srv/fabro-storage"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_runtime_settings_enables_web_from_cli_flag() {
|
||||
let base = parse_settings(
|
||||
r#"
|
||||
r"
|
||||
_version = 1
|
||||
|
||||
[server.web]
|
||||
enabled = false
|
||||
"#,
|
||||
",
|
||||
);
|
||||
let args = ServeArgs {
|
||||
bind: None,
|
||||
|
|
|
|||
|
|
@ -7586,7 +7586,7 @@ level = "debug"
|
|||
.model
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("claude-sonnet-4-5"),
|
||||
);
|
||||
|
|
@ -7596,7 +7596,7 @@ level = "debug"
|
|||
.github
|
||||
.app_id
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("12345"),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -793,7 +793,10 @@ mod tests {
|
|||
.as_ref()
|
||||
.expect("[server.integrations.github] should be present");
|
||||
assert_eq!(
|
||||
github.app_id.as_ref().map(|s| s.as_source()),
|
||||
github
|
||||
.app_id
|
||||
.as_ref()
|
||||
.map(fabro_types::settings::InterpString::as_source),
|
||||
Some("123".to_string())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,12 +122,12 @@ async fn web_enabled_serves_web_only_routes() {
|
|||
#[tokio::test]
|
||||
async fn web_disabled_returns_404_for_web_routes_and_keeps_machine_api() {
|
||||
let settings: SettingsLayer = parse_settings_layer(
|
||||
r#"
|
||||
r"
|
||||
_version = 1
|
||||
|
||||
[server.web]
|
||||
enabled = false
|
||||
"#,
|
||||
",
|
||||
)
|
||||
.expect("settings fixture should parse");
|
||||
let app = build_router_with_options(
|
||||
|
|
@ -179,12 +179,12 @@ enabled = false
|
|||
#[tokio::test]
|
||||
async fn web_disabled_ignores_demo_header_dispatch() {
|
||||
let settings: SettingsLayer = parse_settings_layer(
|
||||
r#"
|
||||
r"
|
||||
_version = 1
|
||||
|
||||
[server.web]
|
||||
enabled = false
|
||||
"#,
|
||||
",
|
||||
)
|
||||
.expect("settings fixture should parse");
|
||||
let app = build_router_with_options(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::absolute_paths)]
|
||||
|
||||
mod api;
|
||||
mod helpers;
|
||||
mod openapi_conformance;
|
||||
|
|
|
|||
|
|
@ -269,15 +269,14 @@ async fn cancel_at_human_gate_persists_cancelled_terminal_event() {
|
|||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter_map(|event| {
|
||||
(event["event"] == "run.failed").then(|| {
|
||||
(
|
||||
event["properties"]["reason"]
|
||||
.as_str()
|
||||
.map(ToOwned::to_owned),
|
||||
event["properties"]["error"].as_str().map(ToOwned::to_owned),
|
||||
)
|
||||
})
|
||||
.filter(|&event| event["event"] == "run.failed")
|
||||
.map(|event| {
|
||||
(
|
||||
event["properties"]["reason"]
|
||||
.as_str()
|
||||
.map(ToOwned::to_owned),
|
||||
event["properties"]["error"].as_str().map(ToOwned::to_owned),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ mod tests {
|
|||
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let url = format!("ws://{}", addr);
|
||||
let url = format!("ws://{addr}");
|
||||
|
||||
let registry = registry();
|
||||
let submissions = Arc::new(Mutex::new(Vec::new()));
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ fn parse_object_path(raw: &str) -> Result<ObjectPath> {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use futures::stream;
|
||||
use object_store::memory::InMemory;
|
||||
|
||||
use fabro_types::fixtures;
|
||||
|
|
@ -324,7 +325,7 @@ mod tests {
|
|||
&run_id,
|
||||
&node,
|
||||
filename,
|
||||
futures::stream::iter(vec![
|
||||
stream::iter(vec![
|
||||
Ok(Bytes::from_static(b"hello ")),
|
||||
Ok(Bytes::from_static(b"world")),
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ use std::collections::BTreeMap;
|
|||
|
||||
use fabro_types::graph::Graph;
|
||||
use fabro_types::run_event::run::RunCreatedProps;
|
||||
use fabro_types::settings::InterpString;
|
||||
use fabro_types::settings::SettingsLayer;
|
||||
use fabro_types::settings::run::{RunGoalLayer, RunLayer};
|
||||
use fabro_types::settings::server::{
|
||||
GithubIntegrationLayer, ServerIntegrationsLayer, ServerLayer, ServerStorageLayer,
|
||||
};
|
||||
use fabro_types::settings::{InterpString, SettingsLayer};
|
||||
|
||||
fn templated_settings() -> SettingsLayer {
|
||||
SettingsLayer {
|
||||
|
|
@ -78,7 +79,7 @@ fn run_created_props_round_trip_templated_settings() {
|
|||
.as_ref()
|
||||
.and_then(|server| server.storage.as_ref())
|
||||
.and_then(|storage| storage.root.as_ref())
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("${env.FABRO_STORAGE}".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
@ -89,7 +90,7 @@ fn run_created_props_round_trip_templated_settings() {
|
|||
.and_then(|server| server.integrations.as_ref())
|
||||
.and_then(|integrations| integrations.github.as_ref())
|
||||
.and_then(|github| github.app_id.as_ref())
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("${env.GITHUB_APP_ID}".to_string())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ use std::path::PathBuf;
|
|||
use fabro_types::fixtures;
|
||||
use fabro_types::graph::Graph;
|
||||
use fabro_types::run::RunRecord;
|
||||
use fabro_types::settings::InterpString;
|
||||
use fabro_types::settings::SettingsLayer;
|
||||
use fabro_types::settings::run::{RunGoalLayer, RunLayer};
|
||||
use fabro_types::settings::server::{
|
||||
GithubIntegrationLayer, ServerIntegrationsLayer, ServerLayer, ServerStorageLayer,
|
||||
};
|
||||
use fabro_types::settings::{InterpString, SettingsLayer};
|
||||
|
||||
fn templated_settings() -> SettingsLayer {
|
||||
SettingsLayer {
|
||||
|
|
@ -78,7 +79,7 @@ fn run_record_round_trips_templated_settings() {
|
|||
.as_ref()
|
||||
.and_then(|server| server.storage.as_ref())
|
||||
.and_then(|storage| storage.root.as_ref())
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("${env.FABRO_STORAGE}".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
@ -89,7 +90,7 @@ fn run_record_round_trips_templated_settings() {
|
|||
.and_then(|server| server.integrations.as_ref())
|
||||
.and_then(|integrations| integrations.github.as_ref())
|
||||
.and_then(|github| github.app_id.as_ref())
|
||||
.map(|value| value.as_source()),
|
||||
.map(InterpString::as_source),
|
||||
Some("${env.GITHUB_APP_ID}".to_string())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3441,7 +3441,7 @@ mod tests {
|
|||
graph: serde_json::to_value(Graph::new("test")).unwrap(),
|
||||
workflow_source: None,
|
||||
workflow_config: None,
|
||||
labels: Default::default(),
|
||||
labels: BTreeMap::default(),
|
||||
run_dir: "/tmp/run".to_string(),
|
||||
working_directory: "/tmp/run".to_string(),
|
||||
host_repo_path: None,
|
||||
|
|
|
|||
|
|
@ -810,7 +810,7 @@ mod tests {
|
|||
.model
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("claude-sonnet-4-6")
|
||||
);
|
||||
|
|
@ -820,7 +820,7 @@ mod tests {
|
|||
.model
|
||||
.provider
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(fabro_types::settings::InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("anthropic")
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1187,11 +1187,11 @@ mod tests {
|
|||
PathBuf::from("children/review.fabro"),
|
||||
BundledWorkflow {
|
||||
logical_path: PathBuf::from("children/review.fabro"),
|
||||
source: r#"digraph Review {
|
||||
source: r"digraph Review {
|
||||
start [shape=Mdiamond]
|
||||
exit [shape=Msquare]
|
||||
start -> exit
|
||||
}"#
|
||||
}"
|
||||
.to_string(),
|
||||
files: HashMap::new(),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -137,9 +137,9 @@ fn load_run_checkpoint(run_dir: &Path) -> Result<Checkpoint, Box<dyn std::error:
|
|||
unreachable!()
|
||||
})?
|
||||
};
|
||||
return state
|
||||
state
|
||||
.checkpoint
|
||||
.ok_or_else(|| "checkpoint should exist in run store".into());
|
||||
.ok_or_else(|| "checkpoint should exist in run store".into())
|
||||
}
|
||||
|
||||
async fn create_env() -> DaytonaSandbox {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
clippy::get_unwrap,
|
||||
clippy::ignore_without_reason,
|
||||
clippy::items_after_statements,
|
||||
clippy::large_futures,
|
||||
clippy::manual_let_else,
|
||||
clippy::print_stderr,
|
||||
clippy::unnecessary_box_returns,
|
||||
|
|
@ -169,9 +170,9 @@ fn load_run_checkpoint(run_dir: &Path) -> Result<Checkpoint, Box<dyn std::error:
|
|||
unreachable!()
|
||||
})?
|
||||
};
|
||||
return state
|
||||
state
|
||||
.checkpoint
|
||||
.ok_or_else(|| "checkpoint should exist in run store".into());
|
||||
.ok_or_else(|| "checkpoint should exist in run store".into())
|
||||
}
|
||||
|
||||
fn save_checkpoint(path: &Path, checkpoint: &Checkpoint) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use fabro_graphviz::graph::Graph;
|
||||
use fabro_graphviz::parser;
|
||||
use fabro_model::Catalog;
|
||||
use fabro_types::settings::run::{RunGoalLayer, RunLayer, RunModelLayer, RunPullRequestLayer};
|
||||
use fabro_types::settings::{InterpString, SettingsLayer};
|
||||
use fabro_workflow::run_materialization::materialize_run;
|
||||
|
||||
fn graph(source: &str) -> Graph {
|
||||
fabro_graphviz::parser::parse(source).expect("graph should parse")
|
||||
parser::parse(source).expect("graph should parse")
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -32,7 +33,7 @@ fn materialize_run_applies_graph_and_catalog_defaults() {
|
|||
..SettingsLayer::default()
|
||||
};
|
||||
|
||||
let materialized = materialize_run(settings, &graph(source), &Catalog::builtin());
|
||||
let materialized = materialize_run(settings, &graph(source), Catalog::builtin());
|
||||
let resolved = fabro_config::resolve_run_from_file(&materialized).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -40,7 +41,7 @@ fn materialize_run_applies_graph_and_catalog_defaults() {
|
|||
.model
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("claude-sonnet-4-6")
|
||||
);
|
||||
|
|
@ -49,7 +50,7 @@ fn materialize_run_applies_graph_and_catalog_defaults() {
|
|||
.model
|
||||
.provider
|
||||
.as_ref()
|
||||
.map(|value| value.as_source())
|
||||
.map(InterpString::as_source)
|
||||
.as_deref(),
|
||||
Some("anthropic")
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue