fix(aura-cli): unknown-key refusal cites the op index; two diagnostics hints
Harvest sweep, batch 1 of 6.
- graph build's unknown-key refusal now parses the op-list element-by-
element and attributes any per-element parse fault as 'op N (kind):',
immune to serde's deny-unknown-fields token position landing on the
following element (RED-first: the misattribution was pinned failing
before the fix).
- the UnsupportedVersion refusal names the full accepted range
('versions 1..=2'), not just the ceiling.
- a bare unresolved type id inside a data-only project now carries the
same Rust-escalation pointer as the namespaced form ('aura nodes new');
outside any project a bare id stays hint-free (a std-name typo is the
likelier cause there).
closes #336
refs #341
This commit is contained in:
@@ -482,6 +482,26 @@ fn graph_build_rejects_an_unknown_op_field() {
|
||||
assert!(stderr.contains("params"), "names the unknown key: {stderr}");
|
||||
}
|
||||
|
||||
/// Property (#336): the unknown-key refusal cites the OFFENDING element's own op
|
||||
/// index, not serde's `deny_unknown_fields` token position, which (for an
|
||||
/// internally-tagged enum) surfaces only once the parser has consumed the whole
|
||||
/// object and lands on the START OF THE FOLLOWING element. With the typo'd key at
|
||||
/// index 1 (of 3), a line/column-based message would mislead toward index 2;
|
||||
/// this pins the op-list's own coordinate instead.
|
||||
#[test]
|
||||
fn graph_build_unknown_op_field_names_the_offending_op_index() {
|
||||
let doc = r#"[
|
||||
{"op":"source","role":"price","kind":"F64"},
|
||||
{"op":"add","type":"Const","params":{"value":{"F64":1.0}}},
|
||||
{"op":"expose","from":"const.value","as":"bias"}
|
||||
]"#;
|
||||
let (stderr, code) = run_code(&["graph", "build"], doc);
|
||||
assert_eq!(code, Some(1), "unknown op field is a content fault -> exit 1; stderr: {stderr}");
|
||||
assert!(stderr.contains("op 1"), "names the offending element's own op index (1): {stderr}");
|
||||
assert!(!stderr.contains("op 2"), "must not attribute the fault to the following element: {stderr}");
|
||||
assert!(stderr.contains("params"), "still names the unknown key: {stderr}");
|
||||
}
|
||||
|
||||
/// Property (exit-code partition, #175 iteration 2): within the SAME `graph
|
||||
/// introspect` subcommand, an invalid `--node <T>` flag VALUE is a USAGE error (a
|
||||
/// command-line fault the user must fix in argv) — exit 2 — distinct from bad stdin
|
||||
@@ -1898,6 +1918,25 @@ fn graph_build_hints_attach_for_namespaced_ids_in_a_data_only_project() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Property (#341 item 5): the BARE counterpart of the test above — the
|
||||
/// consumer least likely to know yet that new logic is Rust (and therefore
|
||||
/// least likely to namespace their type) is the one who most needs the
|
||||
/// escalation pointer, not the one least likely to get it. Same data-only
|
||||
/// project, same unresolved-type refusal, no `::` in the type id this time.
|
||||
#[test]
|
||||
fn graph_build_hints_attach_for_a_bare_unresolved_type_in_a_data_only_project() {
|
||||
let dir = temp_cwd("graph-build-dataonly-bare-hint");
|
||||
std::fs::write(dir.join("Aura.toml"), "").expect("write bare Aura.toml");
|
||||
let ops = r#"[{"op":"add","type":"ThirdCandle","name":"n"}]"#;
|
||||
let (stdout, stderr, code) = run_in_stdin(&dir, &["graph", "build"], ops);
|
||||
assert_ne!(code, Some(0), "an unresolvable bare type refuses: {stderr}");
|
||||
assert!(stdout.is_empty(), "no blueprint emitted on a fault: {stdout}");
|
||||
assert!(
|
||||
stderr.contains("aura nodes new"),
|
||||
"the bare-form refusal now carries the same escalation pointer as the namespaced one: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Property (#284): the `tap` op-script op, driven through the real `aura
|
||||
/// graph build` process (not an in-crate call to `build_from_str`), resolves
|
||||
/// a name-addressed interior wire (`"fast.value"`, session node 0 / output
|
||||
|
||||
Reference in New Issue
Block a user