test(wfe-yaml): coverage pass to 90%+ and fix duration parsing bug
Added 51 tests: compiler hooks/parallel/error behavior (20),
validation error paths (15), shell integration tests (7),
lib.rs file loading (5), interpolation edge cases (4).
Fixed parse_duration_ms: "ms" suffix was unreachable because
strip_suffix('s') matched first. Now checks "ms" before "s".
Coverage: 40% → 90.3%. 326 total workspace tests.
This commit is contained in:
104
wfe-yaml/tests/lib_tests.rs
Normal file
104
wfe-yaml/tests/lib_tests.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
|
||||
use wfe_yaml::{load_workflow, load_workflow_from_str};
|
||||
|
||||
#[test]
|
||||
fn load_workflow_from_file() {
|
||||
let yaml = r#"
|
||||
workflow:
|
||||
id: file-load-wf
|
||||
version: 1
|
||||
steps:
|
||||
- name: hello
|
||||
type: shell
|
||||
config:
|
||||
run: echo hello
|
||||
"#;
|
||||
// Write to a temp file manually.
|
||||
let path = std::path::Path::new("/tmp/wfe_test_load_workflow.yaml");
|
||||
let mut file = std::fs::File::create(path).unwrap();
|
||||
file.write_all(yaml.as_bytes()).unwrap();
|
||||
file.flush().unwrap();
|
||||
|
||||
let compiled = load_workflow(path, &HashMap::new()).unwrap();
|
||||
assert_eq!(compiled.definition.id, "file-load-wf");
|
||||
assert_eq!(compiled.definition.version, 1);
|
||||
assert_eq!(compiled.definition.steps.len(), 1);
|
||||
|
||||
// Clean up.
|
||||
let _ = std::fs::remove_file(path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_workflow_from_nonexistent_file_returns_error() {
|
||||
let path = std::path::Path::new("/tmp/nonexistent_wfe_test_file_12345.yaml");
|
||||
let result = load_workflow(path, &HashMap::new());
|
||||
assert!(result.is_err());
|
||||
let err = match result { Err(e) => e.to_string(), Ok(_) => panic!("expected error") };
|
||||
assert!(
|
||||
err.contains("IO error") || err.contains("No such file"),
|
||||
"Expected IO error, got: {err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_workflow_from_str_with_invalid_yaml_returns_error() {
|
||||
let yaml = "this is not valid yaml: [[[";
|
||||
let result = load_workflow_from_str(yaml, &HashMap::new());
|
||||
assert!(result.is_err());
|
||||
let err = match result { Err(e) => e.to_string(), Ok(_) => panic!("expected error") };
|
||||
assert!(
|
||||
err.contains("YAML parse error"),
|
||||
"Expected YAML parse error, got: {err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_workflow_from_str_with_interpolation() {
|
||||
let yaml = r#"
|
||||
workflow:
|
||||
id: interp-wf
|
||||
version: 1
|
||||
steps:
|
||||
- name: greet
|
||||
type: shell
|
||||
config:
|
||||
run: echo ((message))
|
||||
"#;
|
||||
let mut config = HashMap::new();
|
||||
config.insert("message".to_string(), serde_json::json!("hello world"));
|
||||
|
||||
let compiled = load_workflow_from_str(yaml, &config).unwrap();
|
||||
let step = compiled
|
||||
.definition
|
||||
.steps
|
||||
.iter()
|
||||
.find(|s| s.name.as_deref() == Some("greet"))
|
||||
.unwrap();
|
||||
|
||||
let shell_config: wfe_yaml::executors::shell::ShellConfig =
|
||||
serde_json::from_value(step.step_config.clone().unwrap()).unwrap();
|
||||
assert_eq!(shell_config.run, "echo hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_workflow_from_str_with_unresolved_variable_returns_error() {
|
||||
let yaml = r#"
|
||||
workflow:
|
||||
id: unresolved-wf
|
||||
version: 1
|
||||
steps:
|
||||
- name: step1
|
||||
type: shell
|
||||
config:
|
||||
run: echo ((missing))
|
||||
"#;
|
||||
let result = load_workflow_from_str(yaml, &HashMap::new());
|
||||
assert!(result.is_err());
|
||||
let err = match result { Err(e) => e.to_string(), Ok(_) => panic!("expected error") };
|
||||
assert!(
|
||||
err.contains("missing"),
|
||||
"Expected unresolved variable error, got: {err}"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user