From 51a3c72424b426ef6ae235e37b9c4542b415fe0c Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 4 Apr 2020 01:50:19 +0200 Subject: [PATCH] don't run pretty.rs tests --- compiler/reporting/src/report.rs | 140 ++++---- compiler/reporting/src/type_error.rs | 4 +- vendor/pretty/Cargo.toml | 11 - vendor/pretty/src/lib.rs | 500 --------------------------- 4 files changed, 63 insertions(+), 592 deletions(-) diff --git a/compiler/reporting/src/report.rs b/compiler/reporting/src/report.rs index 9bd73c78a1..b7c4f5ab34 100644 --- a/compiler/reporting/src/report.rs +++ b/compiler/reporting/src/report.rs @@ -7,13 +7,8 @@ use roc_types::subs::{Content, Subs}; use roc_types::types::{write_error_type, ErrorType}; use std::path::PathBuf; -// use ven_pretty::termcolor::{Color, ColorChoice, ColorSpec, StandardStream}; use std::fmt; -use ven_pretty::{ - BoxAllocator, BoxDoc, DocAllocator, DocBuilder, FmtWrite, Render, RenderAnnotated, -}; - -type Doc<'a> = DocBuilder<'a, BoxAllocator, Annotation>; +use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated}; /// A textual report. pub struct Report { @@ -210,10 +205,6 @@ pub fn url(str: &str) -> ReportText { ReportText::Url(Box::from(str)) } -pub fn with_indent(n: usize, report_text: ReportText) -> ReportText { - ReportText::Indent(n, Box::new(report_text)) -} - pub const RED_CODE: &str = "\u{001b}[31m"; pub const WHITE_CODE: &str = "\u{001b}[37m"; pub const BLUE_CODE: &str = "\u{001b}[34m"; @@ -228,12 +219,6 @@ pub const UNDERLINE_CODE: &str = "\u{001b}[4m"; pub const RESET_CODE: &str = "\u{001b}[0m"; -struct CiEnv<'a> { - home: ModuleId, - src_lines: &'a [&'a str], - interns: &'a Interns, -} - pub struct CiWrite { style_stack: Vec, upstream: W, @@ -445,11 +430,11 @@ impl ReportText { src_lines: &[&str], interns: &Interns, ) { - let allocator = BoxAllocator; + let alloc = BoxAllocator; let err_msg = ""; - self.pretty::<_>(&allocator, subs, home, src_lines, interns) + self.pretty::<_>(&alloc, subs, home, src_lines, interns) .1 .render_raw(70, &mut CiWrite::new(buf)) .expect(err_msg); @@ -465,11 +450,11 @@ impl ReportText { interns: &Interns, palette: &Palette, ) { - let allocator = BoxAllocator; + let alloc = BoxAllocator; let err_msg = ""; - self.pretty::<_>(&allocator, subs, home, src_lines, interns) + self.pretty::<_>(&alloc, subs, home, src_lines, interns) .1 .render_raw(70, &mut ColorWrite::new(palette, buf)) .expect(err_msg); @@ -479,7 +464,7 @@ impl ReportText { /// monospace font, etc) is done in the CiWrite and ColorWrite `RenderAnnotated` instances. pub fn pretty<'b, D>( self, - allocator: &'b D, + alloc: &'b D, subs: &mut Subs, home: ModuleId, src_lines: &'b [&'b str], @@ -492,30 +477,30 @@ impl ReportText { use ReportText::*; match self { - Plain(string) => allocator + Plain(string) => alloc .text(format!("{}", string)) .annotate(Annotation::PlainText), - EmText(string) => allocator + EmText(string) => alloc .text(format!("{}", string)) .annotate(Annotation::Emphasized), - Url(url) => allocator.text(format!("{}", url)).annotate(Annotation::Url), - Keyword(string) => allocator + Url(url) => alloc.text(format!("{}", url)).annotate(Annotation::Url), + Keyword(string) => alloc .text(format!("{}", string)) .annotate(Annotation::Keyword), - GlobalTag(string) => allocator + GlobalTag(string) => alloc .text(format!("{}", string)) .annotate(Annotation::GlobalTag), - RecordField(string) => allocator + RecordField(string) => alloc .text(format!(".{}", string)) .annotate(Annotation::RecordField), PrivateTag(symbol) => { if symbol.module_id() == home { // Render it unqualified if it's in the current module. - allocator + alloc .text(format!("{}", symbol.ident_string(interns))) .annotate(Annotation::PrivateTag) } else { - allocator + alloc .text(format!( "{}.{}", symbol.module_string(interns), @@ -527,11 +512,11 @@ impl ReportText { Value(symbol) => { if symbol.module_id() == home { // Render it unqualified if it's in the current module. - allocator + alloc .text(format!("{}", symbol.ident_string(interns))) .annotate(Annotation::Symbol) } else { - allocator + alloc .text(format!( "{}.{}", symbol.module_string(interns), @@ -541,55 +526,53 @@ impl ReportText { } } - Module(module_id) => allocator + Module(module_id) => alloc .text(format!("{}", interns.module_name(module_id))) .annotate(Annotation::Module), Type(content) => match content { - Content::FlexVar(_) | Content::RigidVar(_) => allocator + Content::FlexVar(_) | Content::RigidVar(_) => alloc .text(content_to_string(content, subs, home, interns)) .annotate(Annotation::TypeVariable), - Content::Structure(_) => allocator + Content::Structure(_) => alloc .text(content_to_string(content, subs, home, interns)) .annotate(Annotation::Structure), - Content::Alias(_, _, _) => allocator + Content::Alias(_, _, _) => alloc .text(content_to_string(content, subs, home, interns)) .annotate(Annotation::Alias), - Content::Error => allocator.text(content_to_string(content, subs, home, interns)), + Content::Error => alloc.text(content_to_string(content, subs, home, interns)), }, - ErrorType(error_type) => allocator + ErrorType(error_type) => alloc .nil() - .append(allocator.hardline()) + .append(alloc.hardline()) .append( - allocator + alloc .text(write_error_type(home, interns, error_type)) .indent(4), ) - .append(allocator.hardline()), + .append(alloc.hardline()), Indent(n, nested) => { - let rest = nested.pretty(allocator, subs, home, src_lines, interns); - allocator.nil().append(rest).indent(n) + let rest = nested.pretty(alloc, subs, home, src_lines, interns); + alloc.nil().append(rest).indent(n) } Docs(_) => { panic!("TODO implment docs"); } - Concat(report_texts) => allocator.concat( + Concat(report_texts) => alloc.concat( report_texts .into_iter() - .map(|rep| rep.pretty(allocator, subs, home, src_lines, interns)), + .map(|rep| rep.pretty(alloc, subs, home, src_lines, interns)), ), - Stack(report_texts) => allocator.intersperse( + Stack(report_texts) => alloc.intersperse( report_texts .into_iter() - .map(|rep| (rep.pretty(allocator, subs, home, src_lines, interns))), - allocator.hardline(), + .map(|rep| (rep.pretty(alloc, subs, home, src_lines, interns))), + alloc.hardline(), ), - BinOp(bin_op) => allocator - .text(bin_op.to_string()) - .annotate(Annotation::BinOp), + BinOp(bin_op) => alloc.text(bin_op.to_string()).annotate(Annotation::BinOp), Region(region) => { let max_line_number_length = (region.end_line + 1).to_string().len(); let indent = 2; @@ -603,42 +586,42 @@ impl ReportText { let line = src_lines[i as usize]; let rest_of_line = if line.trim().is_empty() { - allocator.nil() + alloc.nil() } else { - allocator + alloc .nil() - .append(allocator.text(line).indent(2)) + .append(alloc.text(line).indent(2)) .annotate(Annotation::CodeBlock) }; - let source_line = allocator + let source_line = alloc .line() .append( - allocator + alloc .text(" ".repeat(max_line_number_length - this_line_number_length)), ) - .append(allocator.text(line_number).annotate(Annotation::LineNumber)) - .append(allocator.text(" ┆").annotate(Annotation::GutterBar)) + .append(alloc.text(line_number).annotate(Annotation::LineNumber)) + .append(alloc.text(" ┆").annotate(Annotation::GutterBar)) .append(rest_of_line); - let highlight_line = allocator + let highlight_line = alloc .line() - .append(allocator.text(" ".repeat(max_line_number_length))) - .append(allocator.text(" ┆").annotate(Annotation::GutterBar)) + .append(alloc.text(" ".repeat(max_line_number_length))) + .append(alloc.text(" ┆").annotate(Annotation::GutterBar)) .append( - allocator + alloc .text(" ".repeat(region.start_col as usize)) .indent(indent), ) .append( - allocator + alloc .text("^".repeat((region.end_col - region.start_col) as usize)) .annotate(Annotation::Error), ); source_line.append(highlight_line) } else { - let mut result = allocator.nil(); + let mut result = alloc.nil(); for i in region.start_line..=region.end_line { let line_number_string = (i + 1).to_string(); let line_number = line_number_string; @@ -646,37 +629,36 @@ impl ReportText { let line = src_lines[i as usize]; let rest_of_line = if !line.trim().is_empty() { - allocator + alloc .text(line) .annotate(Annotation::CodeBlock) .indent(indent) } else { - allocator.nil() + alloc.nil() }; - let source_line = allocator - .line() - .append( - allocator.text( + let source_line = + alloc + .line() + .append(alloc.text( " ".repeat(max_line_number_length - this_line_number_length), - ), - ) - .append(allocator.text(line_number).annotate(Annotation::LineNumber)) - .append(allocator.text(" ┆").annotate(Annotation::GutterBar)) - .append(allocator.text(">").annotate(Annotation::Error)) - .append(rest_of_line); + )) + .append(alloc.text(line_number).annotate(Annotation::LineNumber)) + .append(alloc.text(" ┆").annotate(Annotation::GutterBar)) + .append(alloc.text(">").annotate(Annotation::Error)) + .append(rest_of_line); result = result.append(source_line); } result }; - allocator + alloc .nil() - .append(allocator.line()) + .append(alloc.line()) .append(body) - .append(allocator.line()) - .append(allocator.line()) + .append(alloc.line()) + .append(alloc.line()) } } } diff --git a/compiler/reporting/src/type_error.rs b/compiler/reporting/src/type_error.rs index 3e5619f0d9..8675e6e9a5 100644 --- a/compiler/reporting/src/type_error.rs +++ b/compiler/reporting/src/type_error.rs @@ -1,6 +1,6 @@ use crate::report::{ - global_tag_text, keyword_text, plain_text, private_tag_text, record_field_text, with_indent, - Report, ReportText, + global_tag_text, keyword_text, plain_text, private_tag_text, record_field_text, Report, + ReportText, }; use roc_can::expected::{Expected, PExpected}; use roc_module::symbol::Symbol; diff --git a/vendor/pretty/Cargo.toml b/vendor/pretty/Cargo.toml index 0e3c9cc0fc..2cc21e09b0 100644 --- a/vendor/pretty/Cargo.toml +++ b/vendor/pretty/Cargo.toml @@ -22,14 +22,3 @@ termcolor = { version = "1.1.0", optional = true } tempfile = "3.1.0" difference = "2" criterion = "0.3" - -[[example]] -name = "trees" - -[[example]] -name = "colored" -required-features = ["termcolor"] - -[[bench]] -name = "trees" -harness = false diff --git a/vendor/pretty/src/lib.rs b/vendor/pretty/src/lib.rs index 63a7326f59..1426e6e4ea 100644 --- a/vendor/pretty/src/lib.rs +++ b/vendor/pretty/src/lib.rs @@ -1,142 +1,3 @@ -//! This crate defines a -//! [Wadler-style](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf) -//! pretty-printing API. -//! -//! Start with with the static functions of [Doc](enum.Doc.html). -//! -//! ## Quick start -//! -//! Let's pretty-print simple sexps! We want to pretty print sexps like -//! -//! ```lisp -//! (1 2 3) -//! ``` -//! or, if the line would be too long, like -//! -//! ```lisp -//! ((1) -//! (2 3) -//! (4 5 6)) -//! ``` -//! -//! A _simple symbolic expression_ consists of a numeric _atom_ or a nested ordered _list_ of -//! symbolic expression children. -//! -//! ```rust -//! # use pretty::*; -//! enum SExp { -//! Atom(u32), -//! List(Vec), -//! } -//! use SExp::*; -//! # fn main() { } -//! ``` -//! -//! We define a simple conversion to a [Doc](enum.Doc.html). Atoms are rendered as strings; lists -//! are recursively rendered, with spaces between children where appropriate. Children are -//! [nested]() and [grouped](), allowing them to be laid out in a single line as appropriate. -//! -//! ```rust -//! # use pretty::*; -//! # enum SExp { -//! # Atom(u32), -//! # List(Vec), -//! # } -//! # use SExp::*; -//! impl SExp { -//! /// Return a pretty printed format of self. -//! pub fn to_doc(&self) -> RcDoc<()> { -//! match *self { -//! Atom(ref x) => RcDoc::as_string(x), -//! List(ref xs) => -//! RcDoc::text("(") -//! .append(RcDoc::intersperse(xs.into_iter().map(|x| x.to_doc()), Doc::line()).nest(1).group()) -//! .append(RcDoc::text(")")) -//! } -//! } -//! } -//! # fn main() { } -//! ``` -//! -//! Next, we convert the [Doc](enum.Doc.html) to a plain old string. -//! -//! ```rust -//! # use pretty::*; -//! # enum SExp { -//! # Atom(u32), -//! # List(Vec), -//! # } -//! # use SExp::*; -//! # impl SExp { -//! # /// Return a pretty printed format of self. -//! # pub fn to_doc(&self) -> BoxDoc<()> { -//! # match *self { -//! # Atom(ref x) => BoxDoc::as_string(x), -//! # List(ref xs) => -//! # BoxDoc::text("(") -//! # .append(BoxDoc::intersperse(xs.into_iter().map(|x| x.to_doc()), Doc::line()).nest(1).group()) -//! # .append(BoxDoc::text(")")) -//! # } -//! # } -//! # } -//! impl SExp { -//! pub fn to_pretty(&self, width: usize) -> String { -//! let mut w = Vec::new(); -//! self.to_doc().render(width, &mut w).unwrap(); -//! String::from_utf8(w).unwrap() -//! } -//! } -//! # fn main() { } -//! ``` -//! -//! And finally we can test that the nesting and grouping behaves as we expected. -//! -//! ```rust -//! # use pretty::*; -//! # enum SExp { -//! # Atom(u32), -//! # List(Vec), -//! # } -//! # use SExp::*; -//! # impl SExp { -//! # /// Return a pretty printed format of self. -//! # pub fn to_doc(&self) -> BoxDoc<()> { -//! # match *self { -//! # Atom(ref x) => BoxDoc::as_string(x), -//! # List(ref xs) => -//! # BoxDoc::text("(") -//! # .append(BoxDoc::intersperse(xs.into_iter().map(|x| x.to_doc()), Doc::line()).nest(1).group()) -//! # .append(BoxDoc::text(")")) -//! # } -//! # } -//! # } -//! # impl SExp { -//! # pub fn to_pretty(&self, width: usize) -> String { -//! # let mut w = Vec::new(); -//! # self.to_doc().render(width, &mut w).unwrap(); -//! # String::from_utf8(w).unwrap() -//! # } -//! # } -//! # fn main() { -//! let atom = SExp::Atom(5); -//! assert_eq!("5", atom.to_pretty(10)); -//! let list = SExp::List(vec![SExp::Atom(1), SExp::Atom(2), SExp::Atom(3)]); -//! assert_eq!("(1 2 3)", list.to_pretty(10)); -//! assert_eq!("\ -//! (1 -//! 2 -//! 3)", list.to_pretty(5)); -//! # } -//! ``` -//! -//! ## Advanced usage -//! -//! There's a more efficient pattern that uses the [DocAllocator](trait.DocAllocator.html) trait, as -//! implemented by [BoxAllocator](struct.BoxAllocator.html), to allocate -//! [DocBuilder](struct.DocBuilder.html) instances. See -//! [examples/trees.rs](https://github.com/freebroccolo/pretty.rs/blob/master/examples/trees.rs#L39) -//! for this approach. - #[cfg(feature = "termcolor")] pub extern crate termcolor; @@ -547,13 +408,6 @@ where /// Returns a value which implements `std::fmt::Display` /// - /// ``` - /// use pretty::{Doc, BoxDoc}; - /// let doc = BoxDoc::<()>::group( - /// BoxDoc::text("hello").append(Doc::line()).append(Doc::text("world")) - /// ); - /// assert_eq!(format!("{}", doc.pretty(80)), "hello world"); - /// ``` #[inline] pub fn pretty<'d>(&'d self, width: usize) -> Pretty<'a, 'd, T, A> { Pretty { doc: self, width } @@ -664,24 +518,6 @@ where /// Acts like `line` but behaves like `nil` if grouped on a single line /// - /// ``` - /// use pretty::{Doc, RcDoc}; - /// - /// let doc = RcDoc::<()>::group( - /// RcDoc::text("(") - /// .append( - /// RcDoc::line_() - /// .append(Doc::text("test")) - /// .append(Doc::line()) - /// .append(Doc::text("test")) - /// .nest(2), - /// ) - /// .append(Doc::line_()) - /// .append(Doc::text(")")), - /// ); - /// assert_eq!(doc.pretty(5).to_string(), "(\n test\n test\n)"); - /// assert_eq!(doc.pretty(100).to_string(), "(test test)"); - /// ``` #[inline] fn line_(&'a self) -> DocBuilder<'a, Self, A> { self.hardline().flat_alt(self.nil()) @@ -756,16 +592,6 @@ where /// Allocate a document that acts differently based on the position and page layout /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("prefix ") - /// .append(arena.column(|l| { - /// arena.text("| <- column ").append(arena.as_string(l)).into_doc() - /// })); - /// assert_eq!(doc.1.pretty(80).to_string(), "prefix | <- column 7"); - /// ``` #[inline] fn column(&'a self, f: impl Fn(usize) -> Self::Doc + 'a) -> DocBuilder<'a, Self, A> { DocBuilder(self, Doc::Column(self.alloc_column_fn(f)).into()) @@ -773,16 +599,6 @@ where /// Allocate a document that acts differently based on the current nesting level /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("prefix ") - /// .append(arena.nesting(|l| { - /// arena.text("[Nested: ").append(arena.as_string(l)).append("]").into_doc() - /// }).nest(4)); - /// assert_eq!(doc.1.pretty(80).to_string(), "prefix [Nested: 4]"); - /// ``` #[inline] fn nesting(&'a self, f: impl Fn(usize) -> Self::Doc + 'a) -> DocBuilder<'a, Self, A> { DocBuilder(self, Doc::Nesting(self.alloc_column_fn(f)).into()) @@ -882,28 +698,6 @@ where /// Acts as `self` when laid out on multiple lines and acts as `that` when laid out on a single line. /// - /// ``` - /// use pretty::{Arena, DocAllocator}; - /// - /// let arena = Arena::<()>::new(); - /// let body = arena.line().append("x"); - /// let doc = arena.text("let") - /// .append(arena.line()) - /// .append("x") - /// .group() - /// .append( - /// body.clone() - /// .flat_alt( - /// arena.line() - /// .append("in") - /// .append(body) - /// ) - /// ) - /// .group(); - /// - /// assert_eq!(doc.1.pretty(100).to_string(), "let x in x"); - /// assert_eq!(doc.1.pretty(8).to_string(), "let x\nx"); - /// ``` #[inline] pub fn flat_alt(self, that: E) -> DocBuilder<'a, D, A> where @@ -970,14 +764,6 @@ where /// NOTE: The doc pointer type, `D` may need to be cloned. Consider using cheaply cloneable ptr /// like `RefDoc` or `RcDoc` /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("lorem").append(arena.text(" ")) - /// .append(arena.intersperse(["ipsum", "dolor"].iter().cloned(), arena.line_()).align()); - /// assert_eq!(doc.1.pretty(80).to_string(), "lorem ipsum\n dolor"); - /// ``` #[inline] pub fn align(self) -> DocBuilder<'a, D, A> where @@ -997,17 +783,6 @@ where /// NOTE: The doc pointer type, `D` may need to be cloned. Consider using cheaply cloneable ptr /// like `RefDoc` or `RcDoc` /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("prefix").append(arena.text(" ")) - /// .append(arena.reflow("Indenting these words with nest").hang(4)); - /// assert_eq!( - /// doc.1.pretty(24).to_string(), - /// "prefix Indenting these\n words with\n nest", - /// ); - /// ``` #[inline] pub fn hang(self, adjust: isize) -> DocBuilder<'a, D, A> where @@ -1021,21 +796,6 @@ where /// NOTE: The doc pointer type, `D` may need to be cloned. Consider using cheaply cloneable ptr /// like `RefDoc` or `RcDoc` /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("prefix").append(arena.text(" ")) - /// .append(arena.reflow("The indent function indents these words!").indent(4)); - /// assert_eq!( - /// doc.1.pretty(24).to_string(), - /// " - /// prefix The indent - /// function - /// indents these - /// words!".trim_start(), - /// ); - /// ``` #[inline] pub fn indent(self, adjust: usize) -> DocBuilder<'a, D, A> where @@ -1061,16 +821,6 @@ where /// NOTE: The doc pointer type, `D` may need to be cloned. Consider using cheaply cloneable ptr /// like `RefDoc` or `RcDoc` /// - /// ```rust - /// use pretty::DocAllocator; - /// - /// let arena = pretty::Arena::<()>::new(); - /// let doc = arena.text("prefix ") - /// .append(arena.column(|l| { - /// arena.text("| <- column ").append(arena.as_string(l)).into_doc() - /// })); - /// assert_eq!(doc.1.pretty(80).to_string(), "prefix | <- column 7"); - /// ``` #[inline] pub fn width(self, f: impl Fn(isize) -> D::Doc + 'a) -> DocBuilder<'a, D, A> where @@ -1271,253 +1021,3 @@ impl<'a, A> DocAllocator<'a, A> for Arena<'a, A> { self.alloc_any(f) } } - -#[cfg(test)] -mod tests { - use difference; - - use super::*; - - #[cfg(target_pointer_width = "64")] - #[test] - fn doc_size() { - // Safeguard against accidentally growing Doc - assert_eq!(8 * 3, std::mem::size_of::>()); - } - - macro_rules! test { - ($size:expr, $actual:expr, $expected:expr) => { - let mut s = String::new(); - $actual.render_fmt($size, &mut s).unwrap(); - difference::assert_diff!(&s, $expected, "\n", 0); - }; - ($actual:expr, $expected:expr) => { - test!(70, $actual, $expected) - }; - } - - #[test] - fn box_doc_inference() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("test") - .append(BoxDoc::line()) - .append(BoxDoc::text("test")), - ); - - test!(doc, "test test"); - } - - #[test] - fn newline_in_text() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("test").append( - BoxDoc::line() - .append(BoxDoc::text("\"test\n test\"")) - .nest(4), - ), - ); - - test!(5, doc, "test\n \"test\n test\""); - } - - #[test] - fn forced_newline() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("test") - .append(BoxDoc::hardline()) - .append(BoxDoc::text("test")), - ); - - test!(doc, "test\ntest"); - } - - #[test] - fn space_do_not_reset_pos() { - let doc: BoxDoc<()> = BoxDoc::group(BoxDoc::text("test").append(BoxDoc::line())) - .append(BoxDoc::text("test")) - .append(BoxDoc::group(BoxDoc::line()).append(BoxDoc::text("test"))); - - test!(9, doc, "test test\ntest"); - } - - // Tests that the `BoxDoc::hardline()` does not cause the rest of document to think that it fits on - // a single line but instead breaks on the `BoxDoc::line()` to fit with 6 columns - #[test] - fn newline_does_not_cause_next_line_to_be_to_long() { - let doc: RcDoc<()> = RcDoc::group( - RcDoc::text("test").append(RcDoc::hardline()).append( - RcDoc::text("test") - .append(RcDoc::line()) - .append(RcDoc::text("test")), - ), - ); - - test!(6, doc, "test\ntest\ntest"); - } - - #[test] - fn newline_after_group_does_not_affect_it() { - let arena = Arena::<()>::new(); - let doc = arena.text("x").append(arena.line()).append("y").group(); - - test!(100, doc.append(arena.hardline()).1, "x y\n"); - } - - #[test] - fn block() { - let doc: RcDoc<()> = RcDoc::group( - RcDoc::text("{") - .append( - RcDoc::line() - .append(RcDoc::text("test")) - .append(RcDoc::line()) - .append(RcDoc::text("test")) - .nest(2), - ) - .append(RcDoc::line()) - .append(RcDoc::text("}")), - ); - - test!(5, doc, "{\n test\n test\n}"); - } - - #[test] - fn line_comment() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("{") - .append( - BoxDoc::line() - .append(BoxDoc::text("test")) - .append(BoxDoc::line()) - .append(BoxDoc::text("// a").append(BoxDoc::hardline())) - .append(BoxDoc::text("test")) - .nest(2), - ) - .append(BoxDoc::line()) - .append(BoxDoc::text("}")), - ); - - test!(14, doc, "{\n test\n // a\n test\n}"); - } - - #[test] - fn annotation_no_panic() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("test") - .annotate(()) - .append(BoxDoc::hardline()) - .annotate(()) - .append(BoxDoc::text("test")), - ); - - test!(doc, "test\ntest"); - } - - #[test] - fn union() { - let arg: BoxDoc<()> = BoxDoc::text("("); - let tuple = |line: BoxDoc<'static, ()>| { - line.append(BoxDoc::text("x").append(",").group()) - .append(BoxDoc::line()) - .append(BoxDoc::text("1234567890").append(",").group()) - .nest(2) - .append(BoxDoc::line_()) - .append(")") - }; - - let from = BoxDoc::text("let") - .append(BoxDoc::line()) - .append(BoxDoc::text("x")) - .append(BoxDoc::line()) - .append(BoxDoc::text("=")) - .group(); - - let single = from - .clone() - .append(BoxDoc::line()) - .append(arg.clone()) - .group() - .append(tuple(BoxDoc::line_())) - .group(); - - let hang = from - .clone() - .append(BoxDoc::line()) - .append(arg.clone()) - .group() - .append(tuple(BoxDoc::hardline())) - .group(); - - let break_all = from - .append(BoxDoc::line()) - .append(arg.clone()) - .append(tuple(BoxDoc::line())) - .group() - .nest(2); - - let doc = BoxDoc::group(single.union(hang.union(break_all))); - - test!(doc, "let x = (x, 1234567890,)"); - test!(8, doc, "let x =\n (\n x,\n 1234567890,\n )"); - test!(14, doc, "let x = (\n x,\n 1234567890,\n)"); - } - - #[test] - fn usize_max_value() { - let doc: BoxDoc<()> = BoxDoc::group( - BoxDoc::text("test") - .append(BoxDoc::line()) - .append(BoxDoc::text("test")), - ); - - test!(usize::max_value(), doc, "test test"); - } - - pub struct TestWriter { - upstream: W, - } - - impl TestWriter { - pub fn new(upstream: W) -> Self { - Self { upstream } - } - } - - impl Render for TestWriter - where - W: Render, - { - type Error = W::Error; - - fn write_str(&mut self, s: &str) -> Result { - self.upstream.write_str(s) - } - - fn write_str_all(&mut self, s: &str) -> Result<(), W::Error> { - self.upstream.write_str_all(s) - } - } - - impl RenderAnnotated<()> for TestWriter - where - W: Render, - { - fn push_annotation(&mut self, _: &()) -> Result<(), Self::Error> { - self.upstream.write_str_all("[") - } - - fn pop_annotation(&mut self) -> Result<(), Self::Error> { - self.upstream.write_str_all("]") - } - } - - #[test] - fn annotations() { - let actual = BoxDoc::text("abc").annotate(()).annotate(()); - let mut s = String::new(); - actual - .render_raw(70, &mut TestWriter::new(FmtWrite::new(&mut s))) - .unwrap(); - difference::assert_diff!(&s, "[[abc]]", "\n", 0); - } -}