okami.mom/glamour
git clone https://git.nkp.pet/okami.mom/glamour
cf874d7
main
1package glamour 2 3import ( 4"bytes" 5"errors" 6"fmt" 7"io" 8"os" 9"regexp" 10"strings" 11"testing" 12 13"charm.land/glamour/v2/styles" 14"github.com/charmbracelet/x/exp/golden" 15) 16 17const markdown = "testdata/readme.markdown.in" 18 19func TestTermRendererWriter (t * testing.T ) { 20r ,err := NewTermRenderer ( 21WithStandardStyle (styles .DarkStyle ), 22 ) 23if err != nil { 24t .Fatal (err ) 25 } 26 27in ,err := os .ReadFile (markdown ) 28if err != nil { 29t .Fatal (err ) 30 } 31 32_ ,err = r .Write (in ) 33if err != nil { 34t .Fatal (err ) 35 } 36err = r .Close () 37if err != nil { 38t .Fatal (err ) 39 } 40 41b ,err := io .ReadAll (r ) 42if err != nil { 43t .Fatal (err ) 44 } 45 46golden .RequireEqual (t ,b ) 47} 48 49func TestTermRenderer (t * testing.T ) { 50r ,err := NewTermRenderer ( 51WithStandardStyle ("dark" ), 52 ) 53if err != nil { 54t .Fatal (err ) 55 } 56 57in ,err := os .ReadFile (markdown ) 58if err != nil { 59t .Fatal (err ) 60 } 61 62b ,err := r .Render (string (in )) 63if err != nil { 64t .Fatal (err ) 65 } 66 67golden .RequireEqual (t , []byte (b )) 68} 69 70func TestWithEmoji (t * testing.T ) { 71r ,err := NewTermRenderer ( 72WithEmoji (), 73 ) 74if err != nil { 75t .Fatal (err ) 76 } 77 78b ,err := r .Render (":+1:" ) 79if err != nil { 80t .Fatal (err ) 81 } 82b = strings .TrimSpace (b ) 83 84// Thumbs up unicode character 85td := "\U0001f44d" 86 87if td != b { 88t .Errorf ("Rendered output doesn't match!\nExpected: `\n%s`\nGot: `\n%s`\n" ,td ,b ) 89 } 90} 91 92func TestWithPreservedNewLines (t * testing.T ) { 93r ,err := NewTermRenderer ( 94WithPreservedNewLines (), 95 ) 96if err != nil { 97t .Fatal (err ) 98 } 99 100in ,err := os .ReadFile ("testdata/preserved_newline.in" ) 101if err != nil { 102t .Fatal (err ) 103 } 104 105b ,err := r .Render (string (in )) 106if err != nil { 107t .Fatal (err ) 108 } 109 110golden .RequireEqual (t , []byte (b )) 111} 112 113func TestStyles (t * testing.T ) { 114_ ,err := NewTermRenderer () 115if err != nil { 116t .Fatal (err ) 117 } 118 119_ ,err = NewTermRenderer ( 120WithStandardStyle (styles .DarkStyle ), 121 ) 122if err != nil { 123t .Fatal (err ) 124 } 125 126_ ,err = NewTermRenderer ( 127WithEnvironmentConfig (), 128 ) 129if err != nil { 130t .Fatal (err ) 131 } 132} 133 134// TestCustomStyle checks the expected errors with custom styling. We need to 135// support built-in styles and custom style sheets. 136func TestCustomStyle (t * testing.T ) { 137md := "testdata/example.md" 138tests := []struct { 139name string 140stylePath string 141err error 142expected string 143 }{ 144 {name :"style exists" ,stylePath :"testdata/custom.style" ,err :nil ,expected :"testdata/custom.style" }, 145 {name :"style doesn't exist" ,stylePath :"testdata/notfound.style" ,err :os .ErrNotExist ,expected :styles .DarkStyle }, 146 {name :"style is empty" ,stylePath :"" ,err :nil ,expected :styles .DarkStyle }, 147 } 148 149for _ ,tc := range tests { 150t .Run (tc .name ,func (t * testing.T ) { 151t .Setenv ("GLAMOUR_STYLE" ,tc .stylePath ) 152g ,err := NewTermRenderer ( 153WithEnvironmentConfig (), 154 ) 155if ! errors .Is (err ,tc .err ) { 156t .Fatal (err ) 157 } 158if ! errors .Is (tc .err ,os .ErrNotExist ) { 159w ,err := NewTermRenderer (WithStylePath (tc .expected )) 160if err != nil { 161t .Fatal (err ) 162 } 163text ,_ := os .ReadFile (md ) 164want ,err := w .RenderBytes (text ) 165got ,err := g .RenderBytes (text ) 166if ! bytes .Equal (want ,got ) { 167t .Error ("Wrong style used" ) 168 } 169 } 170 }) 171 } 172} 173 174func TestRenderHelpers (t * testing.T ) { 175in ,err := os .ReadFile (markdown ) 176if err != nil { 177t .Fatal (err ) 178 } 179 180b ,err := Render (string (in ),"dark" ) 181if err != nil { 182t .Error (err ) 183 } 184 185golden .RequireEqual (t , []byte (b )) 186} 187 188func TestCapitalization (t * testing.T ) { 189p := true 190style := styles .DarkStyleConfig 191style .H1 .Upper = & p 192style .H2 .Title = & p 193style .H3 .Lower = & p 194 195r ,err := NewTermRenderer ( 196WithStyles (style ), 197 ) 198if err != nil { 199t .Fatal (err ) 200 } 201 202b ,err := r .Render ("# everything is uppercase\n## everything is titled\n### everything is lowercase" ) 203if err != nil { 204t .Fatal (err ) 205 } 206 207golden .RequireEqual (t , []byte (b )) 208} 209 210func FuzzData (f * testing.F ) { 211f .Fuzz (func (t * testing.T ,data []byte ) { 212func ()int { 213_ ,err := RenderBytes (data ,styles .DarkStyle ) 214if err != nil { 215return 0 216 } 217return 1 218 }() 219 }) 220} 221 222func TestTableAscii (t * testing.T ) { 223markdown := strings .TrimSpace (` 224| Header A | Header B | 225| --------- | --------- | 226| Cell 1 | Cell 2 | 227| Cell 3 | Cell 4 | 228| Cell 5 | Cell 6 | 229` ) 230 231renderer ,err := NewTermRenderer ( 232WithStyles (styles .ASCIIStyleConfig ), 233WithWordWrap (80 ), 234 ) 235if err != nil { 236t .Fatal (err ) 237 } 238 239result ,err := renderer .Render (markdown ) 240if err != nil { 241t .Fatal (err ) 242 } 243 244nonAsciiRegexp := regexp .MustCompile (`[^\x00-\x7f]+` ) 245nonAsciiChars := nonAsciiRegexp .FindAllString (result ,- 1 ) 246if len (nonAsciiChars )> 0 { 247t .Errorf ("Non-ASCII characters found in output: %v" ,nonAsciiChars ) 248 } 249} 250 251func ExampleASCIIStyleConfig () { 252markdown := strings .TrimSpace (` 253| Header A | Header B | 254| --------- | --------- | 255| Cell 1 | Cell 2 | 256| Cell 3 | Cell 4 | 257| Cell 5 | Cell 6 | 258` ) 259 260renderer ,err := NewTermRenderer ( 261WithStyles (styles .ASCIIStyleConfig ), 262WithWordWrap (80 ), 263 ) 264if err != nil { 265return 266 } 267 268result ,err := renderer .Render (markdown ) 269if err != nil { 270return 271 } 272result = strings .ReplaceAll (result ," " ,"." ) 273fmt .Println (result ) 274 275// Output: 276// .............................................................................. 277// ...Header.A.............................|.Header.B............................ 278// ..--------------------------------------|------------------------------------- 279// ...Cell.1...............................|.Cell.2.............................. 280// ...Cell.3...............................|.Cell.4.............................. 281// ...Cell.5...............................|.Cell.6.............................. 282} 283 284func TestWithChromaFormatterDefault (t * testing.T ) { 285r ,err := NewTermRenderer ( 286WithStandardStyle (styles .DarkStyle ), 287 ) 288if err != nil { 289t .Fatal (err ) 290 } 291 292in ,err := os .ReadFile ("testdata/TestWithChromaFormatter.md" ) 293if err != nil { 294t .Fatal (err ) 295 } 296 297b ,err := r .Render (string (in )) 298if err != nil { 299t .Fatal (err ) 300 } 301 302golden .RequireEqual (t , []byte (b )) 303} 304 305func TestWithChromaFormatterCustom (t * testing.T ) { 306r ,err := NewTermRenderer ( 307WithStandardStyle (styles .DarkStyle ), 308WithChromaFormatter ("terminal16" ), 309 ) 310if err != nil { 311t .Fatal (err ) 312 } 313 314in ,err := os .ReadFile ("testdata/TestWithChromaFormatter.md" ) 315if err != nil { 316t .Fatal (err ) 317 } 318 319b ,err := r .Render (string (in )) 320if err != nil { 321t .Fatal (err ) 322 } 323 324golden .RequireEqual (t , []byte (b )) 325}