use crate::error::Error;
use super::legacy::split_fix;
use super::*;
#[test]
fn severity_labels() {
assert_eq!(Severity::Error.label(), "error");
assert_eq!(Severity::Warning.label(), "warning");
assert_eq!(Severity::Note.label(), "note");
}
#[test]
fn severity_display_matches_label() {
assert_eq!(format!("{}", Severity::Error), "error");
assert_eq!(format!("{}", Severity::Warning), "warning");
assert_eq!(format!("{}", Severity::Note), "note");
}
#[test]
fn split_fix_basic() {
let (msg, fix) =
split_fix("IR inlining cycle at operation `foo`. Fix: do the thing.".to_owned());
assert_eq!(msg, "IR inlining cycle at operation `foo`");
assert_eq!(fix.as_deref(), Some("do the thing"));
}
#[test]
fn split_fix_absent() {
let (msg, fix) = split_fix("no fix hint".to_owned());
assert_eq!(msg, "no fix hint");
assert!(fix.is_none());
}
#[test]
fn render_inline_cycle() {
let err = Error::InlineCycle {
op_id: "foo".to_owned(),
};
let diag = Diagnostic::from(&err);
assert_eq!(diag.severity, Severity::Error);
assert_eq!(diag.code.as_str(), "E-INLINE-CYCLE");
assert!(diag.location.is_some());
assert_eq!(diag.location.as_ref().unwrap().op_id.as_ref(), "foo");
assert!(diag.suggested_fix.is_some());
let rendered = diag.render_human();
assert!(rendered.starts_with("error[E-INLINE-CYCLE]:"));
assert!(rendered.contains("op `foo`"));
assert!(rendered.contains("help:"));
}
#[test]
fn json_round_trip() {
let diag = Diagnostic::error("E-TEST", "boom")
.with_location(OpLocation::op("math.add").with_operand(1))
.with_fix("do the thing")
.with_doc_url("https://docs.vyre.dev/E-TEST");
let j = diag.to_json().expect("diagnostic must serialize");
let back: Diagnostic = serde_json::from_str(&j).unwrap();
assert_eq!(back, diag);
}
#[test]
fn every_error_variant_classifies() {
let samples = [
Error::InlineCycle { op_id: "a".into() },
Error::InlineUnknownOp { op_id: "a".into() },
Error::InlineNonInlinable { op_id: "a".into() },
Error::InlineArgCountMismatch {
op_id: "a".into(),
expected: 1,
got: 2,
},
Error::InlineNoOutput { op_id: "a".into() },
Error::InlineOutputCountMismatch {
op_id: "a".into(),
got: 2,
},
Error::WireFormatValidation {
message: "bad bytes".into(),
},
Error::Lowering {
message: "bad lower".into(),
},
Error::Interp {
message: "bad interp".into(),
},
Error::Gpu {
message: "bad gpu".into(),
},
Error::DecodeConfig {
message: "bad cfg".into(),
},
Error::Decode {
message: "bad decode".into(),
},
Error::Decompress {
message: "bad decomp".into(),
},
Error::Dfa {
message: "bad dfa".into(),
},
Error::Dataflow {
message: "bad dataflow".into(),
},
Error::Prefix {
message: "bad prefix".into(),
},
Error::Csr {
message: "bad csr".into(),
},
Error::Serialization {
message: "bad ser".into(),
},
Error::RuleEval {
message: "bad rule".into(),
},
Error::VersionMismatch {
expected: 3,
found: 1,
},
Error::UnknownDialect {
name: "math".into(),
requested: "1.0".into(),
},
Error::UnknownOp {
dialect: "math".into(),
op: "add".into(),
},
];
for err in samples {
let diag = Diagnostic::from(&err);
assert!(diag.code.as_str().starts_with("E-"));
assert!(!diag.message.is_empty());
assert_eq!(diag.severity, Severity::Error);
let _ = diag.render_human();
assert!(diag.to_json().is_ok(), "diagnostic must serialize");
}
}
#[test]
fn warning_and_note_constructors() {
let w = Diagnostic::warning("W-DEPRECATED", "x is deprecated");
assert_eq!(w.severity, Severity::Warning);
assert!(w.render_human().starts_with("warning[W-DEPRECATED]:"));
let n = Diagnostic::note("N-INFO", "fyi");
assert_eq!(n.severity, Severity::Note);
assert!(n.render_human().starts_with("note[N-INFO]:"));
}
#[test]
fn operand_and_attr_location_render() {
let diag = Diagnostic::error("E-X", "boom")
.with_location(OpLocation::op("math.add").with_operand(2).with_attr("mode"));
let r = diag.render_human();
assert!(r.contains("op `math.add` operand[2] attr `mode`"));
}
#[test]
fn op_location_display_matches_human_anchor() {
let loc = OpLocation::op("math.add").with_operand(2).with_attr("mode");
assert_eq!(
format!("{}", loc),
"op `math.add` operand[2] attr `mode`"
);
}
#[test]
fn op_location_display_without_optional_fields() {
let loc = OpLocation::op("math.add");
assert_eq!(format!("{}", loc), "op `math.add`");
}