843 lines · 23.1 KB · Rust
RawDownload
// Copyright 2025 FastLabs Developers//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////     http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. use crate::{ErrorWithSource, fixup_paths, new_tree_error};use gix_error::OptionExt;use gix_error::ResultExt;use gix_error::{ErrorExt, message};use gix_error::{Exn, Message}; #[test]fn raise_chain() {    let e1 = message("E1").raise();    let e2 = e1.raise(message("E2"));    let e3 = e2.raise(message("E3"));    let e4 = e3.raise(message("E4"));    let e5 = e4.raise(message("E5"));    insta::assert_debug_snapshot!(e5, "raised errors render newest context first", @r"    E5    |    └─ E4    |    └─ E3    |    └─ E2    |    └─ E1    ");    insta::assert_compact_debug_snapshot!(&e5, "raised frames retain their caller locations", @"    E5, at gix-error/tests/error/exn.rs:27    |    └─ E4, at gix-error/tests/error/exn.rs:26    |    └─ E3, at gix-error/tests/error/exn.rs:25    |    └─ E2, at gix-error/tests/error/exn.rs:24    |    └─ E1, at gix-error/tests/error/exn.rs:23    ");     let e = e5.erased();    insta::assert_debug_snapshot!(e, "type erasure preserves the rendered error chain", @r"    E5    |    └─ E4    |    └─ E3    |    └─ E2    |    └─ E1    ");    insta::assert_snapshot!(format!("{e:#}"), "alternate display exposes erased message types", @r#"    Message("E5")    |    └─ Message("E4")        |        └─ Message("E3")            |            └─ Message("E2")                |                └─ Message("E1")    "#);    insta::assert_snapshot!(format!("{e:}"), "standard display shows only the top message", @"E5");     insta::assert_compact_debug_snapshot!(&e, "type erasure preserves caller locations", @"    E5, at gix-error/tests/error/exn.rs:27    |    └─ E4, at gix-error/tests/error/exn.rs:26    |    └─ E3, at gix-error/tests/error/exn.rs:25    |    └─ E2, at gix-error/tests/error/exn.rs:24    |    └─ E1, at gix-error/tests/error/exn.rs:23    ");     // Double-erase    let e = e.erased();    insta::assert_debug_snapshot!(e, "repeated erasure preserves the rendered chain", @r"    E5    |    └─ E4    |    └─ E3    |    └─ E2    |    └─ E1    ");     insta::assert_snapshot!(format!("{e:#}"), "repeated erasure preserves alternate display", @r#"    Message("E5")    |    └─ Message("E4")        |        └─ Message("E3")            |            └─ Message("E2")                |                └─ Message("E1")    "#);    assert_eq!(        e.into_error().probable_cause().to_string(),        "E1",        "linear chains are just followed"    );} #[test]fn and_raise() {    let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");    let exn = io_err.and_raise(message("could not read config"));    insta::assert_debug_snapshot!(exn, "and_raise links context above its source", @r"    could not read config    |    └─ file not found    ");     let io_err2 = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");    let exn2 = io_err2.raise().raise(message("could not read config"));    assert_eq!(        format!("{exn:#?}"),        format!("{exn2:#?}"),        "and_raise is equivalent to raise().raise() (compare with {{:#?}} to omit locations)"    );} #[test]fn raise_all() {    let e = message("Top").raise_all(        (1..5).map(|idx| message!("E{}", idx).raise_all((0..idx).map(|sidx| message!("E{}-{}", idx, sidx)))),    );    insta::assert_debug_snapshot!(e, "raise_all preserves nested child order", @r"    Top    |    └─ E1    |   |    |   └─ E1-0    |    └─ E2    |   |    |   └─ E2-0    |   |    |   └─ E2-1    |    └─ E3    |   |    |   └─ E3-0    |   |    |   └─ E3-1    |   |    |   └─ E3-2    |    └─ E4        |        └─ E4-0        |        └─ E4-1        |        └─ E4-2        |        └─ E4-3    ");    insta::assert_compact_debug_snapshot!(&e, "raise_all retains every caller location", @"    Top, at gix-error/tests/error/exn.rs:141    |    └─ E1, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E1-0, at gix-error/tests/error/exn.rs:142    |    └─ E2, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E2-0, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E2-1, at gix-error/tests/error/exn.rs:142    |    └─ E3, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E3-0, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E3-1, at gix-error/tests/error/exn.rs:142    |   |    |   └─ E3-2, at gix-error/tests/error/exn.rs:142    |    └─ E4, at gix-error/tests/error/exn.rs:142        |        └─ E4-0, at gix-error/tests/error/exn.rs:142        |        └─ E4-1, at gix-error/tests/error/exn.rs:142        |        └─ E4-2, at gix-error/tests/error/exn.rs:142        |        └─ E4-3, at gix-error/tests/error/exn.rs:142    ");     let e = e.chain_all((1..3).map(|idx| message!("SE{}", idx)));    insta::assert_debug_snapshot!(e, "chain_all appends sibling frames", @r"    Top    |    └─ E1    |   |    |   └─ E1-0    |    └─ E2    |   |    |   └─ E2-0    |   |    |   └─ E2-1    |    └─ E3    |   |    |   └─ E3-0    |   |    |   └─ E3-1    |   |    |   └─ E3-2    |    └─ E4    |   |    |   └─ E4-0    |   |    |   └─ E4-1    |   |    |   └─ E4-2    |   |    |   └─ E4-3    |    └─ SE1    |    └─ SE2    ");     insta::assert_snapshot!(format!("{:#}", e), "alternate display preserves the full error tree", @r#"    Message("Top")    |    └─ Message("E1")    |   |    |   └─ Message("E1-0")    |    └─ Message("E2")    |   |    |   └─ Message("E2-0")    |   |    |   └─ Message("E2-1")    |    └─ Message("E3")    |   |    |   └─ Message("E3-0")    |   |    |   └─ Message("E3-1")    |   |    |   └─ Message("E3-2")    |    └─ Message("E4")    |   |    |   └─ Message("E4-0")    |   |    |   └─ Message("E4-1")    |   |    |   └─ Message("E4-2")    |   |    |   └─ Message("E4-3")    |    └─ Message("SE1")    |    └─ Message("SE2")    "#);    let _this_should_compile = message("Top-untyped").raise_all((1..5).map(|idx| message!("E{}", idx).raise_erased()));     assert_eq!(        e.into_error().probable_cause().to_string(),        "Top",        "sometimes the cause is too ambiguous"    );} #[test]fn inverse_error_call_chain() {    let e1 = message("E1").raise();    let e2 = e1.chain(message("E2"));    let e3 = e2.chain(message("E3"));    let e4 = e3.chain(message("E4"));    let e5 = e4.chain(message("E5"));    insta::assert_debug_snapshot!(e5, "chain appends errors in call order", @r"    E1    |    └─ E2    |    └─ E3    |    └─ E4    |    └─ E5    ");    insta::assert_compact_debug_snapshot!(&e5, "chain retains caller locations in call order", @"    E1, at gix-error/tests/error/exn.rs:290    |    └─ E2, at gix-error/tests/error/exn.rs:291    |    └─ E3, at gix-error/tests/error/exn.rs:292    |    └─ E4, at gix-error/tests/error/exn.rs:293    |    └─ E5, at gix-error/tests/error/exn.rs:294    ");     insta::assert_snapshot!(format!("{e5:#}"), "alternate display follows chained order", @r#"    Message("E1")    |    └─ Message("E2")    |    └─ Message("E3")    |    └─ Message("E4")    |    └─ Message("E5")    "#);     assert_eq!(e5.into_error().probable_cause().to_string(), "E5");} #[test]fn error_tree() {    let mut err = new_tree_error();    insta::assert_debug_snapshot!(err, "tree errors preserve their hierarchy", @r"    E6    |    └─ E5    |   |    |   └─ E3    |   |   |    |   |   └─ E1    |   |    |   └─ E10    |   |   |    |   |   └─ E9    |   |    |   └─ E12    |       |    |       └─ E11    |    └─ E4    |   |    |   └─ E2    |    └─ E8        |        └─ E7    ");    insta::assert_compact_debug_snapshot!(&err, "tree errors retain caller locations", @"    E6, at gix-error/tests/error/main.rs:26    |    └─ E5, at gix-error/tests/error/main.rs:18    |   |    |   └─ E3, at gix-error/tests/error/main.rs:10    |   |   |    |   |   └─ E1, at gix-error/tests/error/main.rs:9    |   |    |   └─ E10, at gix-error/tests/error/main.rs:13    |   |   |    |   |   └─ E9, at gix-error/tests/error/main.rs:12    |   |    |   └─ E12, at gix-error/tests/error/main.rs:16    |       |    |       └─ E11, at gix-error/tests/error/main.rs:15    |    └─ E4, at gix-error/tests/error/main.rs:21    |   |    |   └─ E2, at gix-error/tests/error/main.rs:20    |    └─ E8, at gix-error/tests/error/main.rs:24        |        └─ E7, at gix-error/tests/error/main.rs:23    ");    insta::assert_debug_snapshot!(err.frame().iter_frames().map(ToString::to_string).collect::<Vec<_>>(), "frame iteration is breadth-first", @r#"    [        "E6",        "E5",        "E4",        "E8",        "E3",        "E10",        "E12",        "E2",        "E7",        "E1",        "E9",        "E11",    ]    "#);     let new_e = message("E-New").raise_all(err.drain_children());    insta::assert_debug_snapshot!(new_e, "drained children retain their subtrees", @r"    E-New    |    └─ E5    |   |    |   └─ E3    |   |   |    |   |   └─ E1    |   |    |   └─ E10    |   |   |    |   |   └─ E9    |   |    |   └─ E12    |       |    |       └─ E11    |    └─ E4    |   |    |   └─ E2    |    └─ E8        |        └─ E7    ");    insta::assert_snapshot!(err, "draining children leaves the root frame", @"E6");} #[test]fn result_ext() {    let result: Result<(), Message> = Err(message("An error"));    let result = result.or_raise(|| message("Another error"));    insta::assert_compact_debug_snapshot!(result.unwrap_err(), "or_raise records context and source at the call site", @"    Another error, at gix-error/tests/error/exn.rs:435    |    └─ An error, at gix-error/tests/error/exn.rs:435    ");} #[test]fn option_ext() {    let result: Option<()> = None;    let result = result.ok_or_raise(|| message("An error"));    insta::assert_compact_debug_snapshot!(result.unwrap_err(), "ok_or_raise records the failure call site", @"An error, at gix-error/tests/error/exn.rs:446");} #[test]fn from_message() {    fn foo() -> Result<(), Exn<Message>> {        Err(message("An error"))?;        Ok(())    }     let result = foo();    insta::assert_compact_debug_snapshot!(result.unwrap_err(), "question-mark conversion records the propagation site", @"An error, at gix-error/tests/error/exn.rs:453");} #[test]fn new_with_source() {    let e = Exn::new(ErrorWithSource("top", message("source")));    insta::assert_debug_snapshot!(e, "Exn::new retains the standard error source", @r"    top    |    └─ source    ");} #[test]fn bail() {    fn foo() -> Result<(), Exn<Message>> {        gix_error::bail!(message("An error"));    }     let result = foo();    insta::assert_compact_debug_snapshot!(result.unwrap_err(), "bail records the invocation site", @"An error, at gix-error/tests/error/exn.rs:474");} #[test]fn ensure_ok() {    fn foo() -> Result<(), Exn<Message>> {        gix_error::ensure!(true, message("An error"));        Ok(())    }     foo().unwrap();} #[test]fn ensure_fail() {    fn foo() -> Result<(), Exn<Message>> {        gix_error::ensure!(false, message("An error"));        Ok(())    }     let result = foo();    insta::assert_compact_debug_snapshot!(result.unwrap_err(), "ensure failure records the invocation site", @"An error, at gix-error/tests/error/exn.rs:494");}

Lines 1–500 of 843.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t