Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to fully disable url output (for tests) #136

Closed
CAD97 opened this issue Mar 18, 2022 · 2 comments · Fixed by #137
Closed

Add option to fully disable url output (for tests) #136

CAD97 opened this issue Mar 18, 2022 · 2 comments · Fixed by #137

Comments

@CAD97
Copy link
Contributor

CAD97 commented Mar 18, 2022

As an example snapshot test:

---
source: tests/snapshots.rs
assertion_line: 30
expression: "crate::target=warn/[0-9]/"
---
tracing_filter::simple::Error::MultipleSlash (https://docs.rs/tracing-filter/0.0.0-dev/tracing-filter/enum.Error.html#variant.MultipleSlash)

  × logging spec has too many `/`s
   ╭────
 1crate::target=warn/[0-9]/
   ·                    ───┬──
   ·                       │ ╰── this `/` is not allowed ...
   ·                       ╰── ... in this regex filter
   ╰────
  help: regex filters may not contain `/`

Because I've used #[diagnostic(url(docsrs))], the docsrs URL is embedded into the diagnostic, and the output is version-dependent. This means that bumping the version number will also require re-blessing all of the snapshot tests with the new version number.

I'm already directly using GraphicalReportHandler to get (hopefully) environment-independent formatting with no ANSI codes

impl fmt::Display for DisplayDiagnostic<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        miette::GraphicalReportHandler::new_themed(miette::GraphicalTheme::unicode_nocolor())
            .with_links(false)
            .render_report(f, self.0)
            .or_else(|_| write!(f, "failed to pretty-print {:#?}", self.0))
    }
}

but it'd be nice to be able to also completely remove the URL for test purposes.

This would add a new flag to GraphicalReportHandler, with_urls(urls: bool), which would fully disable reporting of Diagnostic::url.

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 18, 2022

You can get partway there with a wrapper diagnostic to strip the URLs

#[derive(Debug, Error)]
#[error(transparent)]
struct StripDiagnosticUrl<T>(T);

impl<T: Diagnostic> Diagnostic for StripDiagnosticUrl<T> {
    fn code<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        self.0.code()
    }

    fn severity(&self) -> Option<miette::Severity> {
        self.0.severity()
    }

    fn help<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        self.0.help()
    }

    fn url<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        None
    }

    fn source_code(&self) -> Option<&dyn miette::SourceCode> {
        self.0.source_code()
    }

    fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {
        self.0.labels()
    }

    fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a>> {
        self.0.related()
    }
}

but this doesn't strip the URLs from related diagnostics, and I don't think there's a way to transform Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a> to strip the URLs from the iterated diagnostics. Specifically, there's no1 way to produce fn(&dyn miette::Diagnostic) -> &dyn miette::Diagnostic that wraps the diagnostic with a modification.

Footnotes

  1. other than Box::leak

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 18, 2022

For the purpose of tests, leaking is probably fine, so here's a full interim solution:

#[derive(Debug, Error)]
#[error(transparent)]
struct StripDiagnosticUrl<'a>(&'a dyn Diagnostic);

impl Diagnostic for StripDiagnosticUrl<'_> {
    fn code<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        self.0.code()
    }

    fn severity(&self) -> Option<miette::Severity> {
        self.0.severity()
    }

    fn help<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        self.0.help()
    }

    fn url<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
        None
    }

    fn source_code(&self) -> Option<&dyn miette::SourceCode> {
        self.0.source_code()
    }

    fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {
        self.0.labels()
    }

    fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a>> {
        self.0.related().map(
            |iter| -> Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a> {
                Box::new(
                    // leakage is sad but required to strip URLs from the test output [zkat/miette#136]
                    iter.map(|d| -> &dyn Diagnostic { Box::leak(Box::new(StripDiagnosticUrl(d))) }),
                )
            },
        )
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant