diff options
Diffstat (limited to 'third_party/rust/codespan-reporting/tests/support')
-rw-r--r-- | third_party/rust/codespan-reporting/tests/support/color_buffer.rs | 137 | ||||
-rw-r--r-- | third_party/rust/codespan-reporting/tests/support/mod.rs | 31 |
2 files changed, 168 insertions, 0 deletions
diff --git a/third_party/rust/codespan-reporting/tests/support/color_buffer.rs b/third_party/rust/codespan-reporting/tests/support/color_buffer.rs new file mode 100644 index 0000000000..b51360ce63 --- /dev/null +++ b/third_party/rust/codespan-reporting/tests/support/color_buffer.rs @@ -0,0 +1,137 @@ +use std::io; +use std::io::prelude::*; +use termcolor::{ColorSpec, WriteColor}; + +// Color tester from: +// https://github.com/wycats/language-reporting/blob/b021c87e0d4916b5f32756151bf215c220eee52d/crates/render-tree/src/stylesheet/accumulator.rs + +/// A facility for creating visually inspectable representations of colored output +/// so they can be easily tested. +/// +/// A new color is represented as `{style}` and a reset is represented by `{/}`. +/// +/// Attributes are printed in this order: +/// +/// - Foreground color as `fg:Color` +/// - Background color as `bg:Color` +/// - Bold as `bold` +/// - Underline as `underline` +/// - Intense as `bright` +/// +/// For example, the style "intense, bold red foreground" would be printed as: +/// +/// ```text +/// {fg:Red bold intense} +/// ``` +/// +/// Since this implementation attempts to make it possible to faithfully +/// understand what real WriteColor implementations would do, it tries +/// to approximate the contract in the WriteColor trait: "Subsequent +/// writes to this write will use these settings until either reset is +/// called or new color settings are set.") +/// +/// - If set_color is called with a style, `{...}` is emitted containing the +/// color attributes. +/// - If set_color is called with no style, `{/}` is emitted +/// - If reset is called, `{/}` is emitted. +pub struct ColorBuffer { + buf: Vec<u8>, + color: ColorSpec, +} + +impl ColorBuffer { + pub fn new() -> ColorBuffer { + ColorBuffer { + buf: Vec::new(), + color: ColorSpec::new(), + } + } + + pub fn into_string(self) -> String { + String::from_utf8(self.buf).unwrap() + } +} + +impl io::Write for ColorBuffer { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.buf.extend(buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl WriteColor for ColorBuffer { + fn supports_color(&self) -> bool { + true + } + + fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { + #![allow(unused_assignments)] + + if self.color == *spec { + return Ok(()); + } else { + self.color = spec.clone(); + } + + if spec.is_none() { + write!(self, "{{/}}")?; + return Ok(()); + } else { + write!(self, "{{")?; + } + + let mut first = true; + + fn write_first(first: bool, write: &mut ColorBuffer) -> io::Result<bool> { + if !first { + write!(write, " ")?; + } + + Ok(false) + }; + + if let Some(fg) = spec.fg() { + first = write_first(first, self)?; + write!(self, "fg:{:?}", fg)?; + } + + if let Some(bg) = spec.bg() { + first = write_first(first, self)?; + write!(self, "bg:{:?}", bg)?; + } + + if spec.bold() { + first = write_first(first, self)?; + write!(self, "bold")?; + } + + if spec.underline() { + first = write_first(first, self)?; + write!(self, "underline")?; + } + + if spec.intense() { + first = write_first(first, self)?; + write!(self, "bright")?; + } + + write!(self, "}}")?; + + Ok(()) + } + + fn reset(&mut self) -> io::Result<()> { + let color = self.color.clone(); + + if color != ColorSpec::new() { + write!(self, "{{/}}")?; + self.color = ColorSpec::new(); + } + + Ok(()) + } +} diff --git a/third_party/rust/codespan-reporting/tests/support/mod.rs b/third_party/rust/codespan-reporting/tests/support/mod.rs new file mode 100644 index 0000000000..4f7313ac36 --- /dev/null +++ b/third_party/rust/codespan-reporting/tests/support/mod.rs @@ -0,0 +1,31 @@ +use codespan_reporting::diagnostic::Diagnostic; +use codespan_reporting::files::Files; +use codespan_reporting::term::{emit, Config}; +use termcolor::{Buffer, WriteColor}; + +mod color_buffer; + +use self::color_buffer::ColorBuffer; + +pub struct TestData<'files, F: Files<'files>> { + pub files: F, + pub diagnostics: Vec<Diagnostic<F::FileId>>, +} + +impl<'files, F: Files<'files>> TestData<'files, F> { + fn emit<W: WriteColor>(&'files self, mut writer: W, config: &Config) -> W { + for diagnostic in &self.diagnostics { + emit(&mut writer, config, &self.files, &diagnostic).unwrap(); + } + writer + } + + pub fn emit_color(&'files self, config: &Config) -> String { + self.emit(ColorBuffer::new(), &config).into_string() + } + + pub fn emit_no_color(&'files self, config: &Config) -> String { + let buffer = self.emit(Buffer::no_color(), &config); + String::from_utf8_lossy(buffer.as_slice()).into_owned() + } +} |