github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/markup/goldmark/codeblocks/integration_test.go (about)

     1  // Copyright 2022 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package codeblocks_test
    15  
    16  import (
    17  	"path/filepath"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/gohugoio/hugo/hugolib"
    22  )
    23  
    24  func TestCodeblocks(t *testing.T) {
    25  	t.Parallel()
    26  
    27  	files := `
    28  -- config.toml --
    29  [markup]
    30    [markup.highlight]
    31      anchorLineNos = false
    32      codeFences = true
    33      guessSyntax = false
    34      hl_Lines = ''
    35      lineAnchors = ''
    36      lineNoStart = 1
    37      lineNos = false
    38      lineNumbersInTable = true
    39      noClasses = false
    40      style = 'monokai'
    41      tabWidth = 4
    42  -- layouts/_default/_markup/render-codeblock-goat.html --
    43  {{ $diagram := diagrams.Goat .Inner }}
    44  Goat SVG:{{ substr $diagram.Wrapped 0 100 | safeHTML }}  }}|
    45  Goat Attribute: {{ .Attributes.width}}|
    46  -- layouts/_default/_markup/render-codeblock-go.html --
    47  Go Code: {{ .Inner | safeHTML }}|
    48  Go Language: {{ .Type }}|
    49  -- layouts/_default/single.html --
    50  {{ .Content }}
    51  -- content/p1.md --
    52  ---
    53  title: "p1"
    54  ---
    55  
    56  ## Ascii Diagram
    57  
    58  §§§goat { width="600" }
    59  --->
    60  §§§
    61  
    62  ## Go Code
    63  
    64  §§§go
    65  fmt.Println("Hello, World!");
    66  §§§
    67  
    68  ## Golang Code
    69  
    70  §§§golang
    71  fmt.Println("Hello, Golang!");
    72  §§§
    73  
    74  ## Bash Code
    75  
    76  §§§bash { linenos=inline,hl_lines=[2,"5-6"],linenostart=32 class=blue }
    77  echo "l1";
    78  echo "l2";
    79  echo "l3";
    80  echo "l4";
    81  echo "l5";
    82  echo "l6";
    83  echo "l7";
    84  echo "l8";
    85  §§§
    86  `
    87  
    88  	b := hugolib.NewIntegrationTestBuilder(
    89  		hugolib.IntegrationTestConfig{
    90  			T:           t,
    91  			TxtarString: files,
    92  			NeedsOsFS:   false,
    93  		},
    94  	).Build()
    95  
    96  	b.AssertFileContent("public/p1/index.html", `
    97  Goat SVG:<svg class='diagram'
    98  Goat Attribute: 600|
    99  
   100  Go Language: go|
   101  Go Code: fmt.Println("Hello, World!");
   102  
   103  Go Code: fmt.Println("Hello, Golang!");
   104  Go Language: golang|
   105  
   106  
   107  	`,
   108  		"Goat SVG:<svg class='diagram' xmlns='http://www.w3.org/2000/svg' version='1.1' height='25' width='40'",
   109  		"Goat Attribute: 600|",
   110  		"<h2 id=\"go-code\">Go Code</h2>\nGo Code: fmt.Println(\"Hello, World!\");\n|\nGo Language: go|",
   111  		"<h2 id=\"golang-code\">Golang Code</h2>\nGo Code: fmt.Println(\"Hello, Golang!\");\n|\nGo Language: golang|",
   112  		"<h2 id=\"bash-code\">Bash Code</h2>\n<div class=\"highlight blue\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"ln\">32</span><span class=\"cl\"><span class=\"nb\">echo</span> <span class=\"s2\">&#34;l1&#34;</span><span class=\"p\">;</span>\n</span></span><span class=\"line hl\"><span class=\"ln\">33</span>",
   113  	)
   114  }
   115  
   116  func TestHighlightCodeblock(t *testing.T) {
   117  	t.Parallel()
   118  
   119  	files := `
   120  -- config.toml --
   121  [markup]
   122  [markup.highlight]
   123  anchorLineNos = false
   124  codeFences = true
   125  guessSyntax = false
   126  hl_Lines = ''
   127  lineAnchors = ''
   128  lineNoStart = 1
   129  lineNos = false
   130  lineNumbersInTable = true
   131  noClasses = false
   132  style = 'monokai'
   133  tabWidth = 4
   134  -- layouts/_default/_markup/render-codeblock.html --
   135  {{ $result := transform.HighlightCodeBlock . }}
   136  Inner: |{{ $result.Inner | safeHTML }}|
   137  Wrapped: |{{ $result.Wrapped | safeHTML }}|
   138  -- layouts/_default/single.html --
   139  {{ .Content }}
   140  -- content/p1.md --
   141  ---
   142  title: "p1"
   143  ---
   144  
   145  ## Go Code
   146  
   147  §§§go
   148  fmt.Println("Hello, World!");
   149  §§§
   150  
   151  `
   152  
   153  	b := hugolib.NewIntegrationTestBuilder(
   154  		hugolib.IntegrationTestConfig{
   155  			T:           t,
   156  			TxtarString: files,
   157  			NeedsOsFS:   false,
   158  		},
   159  	).Build()
   160  
   161  	b.AssertFileContent("public/p1/index.html",
   162  		"Inner: |<span class=\"line\"><span class=\"cl\"><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nf\">Println</span><span class=\"p\">(</span><span class=\"s\">&#34;Hello, World!&#34;</span><span class=\"p\">);</span></span></span>|",
   163  		"Wrapped: |<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-go\" data-lang=\"go\"><span class=\"line\"><span class=\"cl\"><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nf\">Println</span><span class=\"p\">(</span><span class=\"s\">&#34;Hello, World!&#34;</span><span class=\"p\">);</span></span></span></code></pre></div>|",
   164  	)
   165  }
   166  
   167  func TestCodeblocksBugs(t *testing.T) {
   168  	t.Parallel()
   169  
   170  	files := `
   171  -- config.toml --
   172  -- layouts/_default/_markup/render-codeblock.html --
   173  {{ .Position | safeHTML }}
   174  -- layouts/_default/single.html --
   175  {{ .Content }}
   176  -- content/p1.md --
   177  ---
   178  title: "p1"
   179  ---
   180  
   181  ## Issue 9627
   182  
   183  §§§text
   184  {{</* foo */>}}
   185  §§§
   186  
   187  `
   188  
   189  	b := hugolib.NewIntegrationTestBuilder(
   190  		hugolib.IntegrationTestConfig{
   191  			T:           t,
   192  			TxtarString: files,
   193  			NeedsOsFS:   false,
   194  		},
   195  	).Build()
   196  
   197  	b.AssertFileContent("public/p1/index.html", `
   198  # Issue 9627: For the Position in code blocks we try to match the .Inner with the original source. This isn't always possible.
   199  p1.md:0:0
   200  	`,
   201  	)
   202  }
   203  
   204  func TestCodeChomp(t *testing.T) {
   205  	t.Parallel()
   206  
   207  	files := `
   208  -- config.toml --
   209  -- content/p1.md --
   210  ---
   211  title: "p1"
   212  ---
   213  
   214  §§§bash
   215  echo "p1";
   216  §§§
   217  -- layouts/_default/single.html --
   218  {{ .Content }}
   219  -- layouts/_default/_markup/render-codeblock.html --
   220  |{{ .Inner | safeHTML }}|
   221  
   222  `
   223  
   224  	b := hugolib.NewIntegrationTestBuilder(
   225  		hugolib.IntegrationTestConfig{
   226  			T:           t,
   227  			TxtarString: files,
   228  			NeedsOsFS:   false,
   229  		},
   230  	).Build()
   231  
   232  	b.AssertFileContent("public/p1/index.html", "|echo \"p1\";|")
   233  }
   234  
   235  func TestCodePosition(t *testing.T) {
   236  	t.Parallel()
   237  
   238  	files := `
   239  -- config.toml --
   240  -- content/p1.md --
   241  ---
   242  title: "p1"
   243  ---
   244  
   245  ##   Code
   246  
   247  §§§
   248  echo "p1";
   249  §§§
   250  -- layouts/_default/single.html --
   251  {{ .Content }}
   252  -- layouts/_default/_markup/render-codeblock.html --
   253  Position: {{ .Position | safeHTML }}
   254  
   255  
   256  `
   257  
   258  	b := hugolib.NewIntegrationTestBuilder(
   259  		hugolib.IntegrationTestConfig{
   260  			T:           t,
   261  			TxtarString: files,
   262  		},
   263  	).Build()
   264  
   265  	b.AssertFileContent("public/p1/index.html", filepath.FromSlash("Position: \"/content/p1.md:7:1\""))
   266  }
   267  
   268  // Issue 10118
   269  func TestAttributes(t *testing.T) {
   270  	t.Parallel()
   271  
   272  	files := `
   273  -- config.toml --
   274  -- content/p1.md --
   275  ---
   276  title: "p1"
   277  ---
   278  
   279  ## Issue 10118
   280  
   281  §§§ {foo="bar"}
   282  Hello, World!
   283  §§§
   284  
   285  -- layouts/_default/single.html --
   286  {{ .Content }}
   287  -- layouts/_default/_markup/render-codeblock.html --
   288  Attributes: {{ .Attributes }}|Type: {{ .Type }}|
   289  `
   290  
   291  	b := hugolib.NewIntegrationTestBuilder(
   292  		hugolib.IntegrationTestConfig{
   293  			T:           t,
   294  			TxtarString: files,
   295  		},
   296  	).Build()
   297  
   298  	b.AssertFileContent("public/p1/index.html", "<h2 id=\"issue-10118\">Issue 10118</h2>\nAttributes: map[foo:bar]|Type: |")
   299  }
   300  
   301  // Issue 9571
   302  func TestAttributesChroma(t *testing.T) {
   303  	t.Parallel()
   304  
   305  	files := `
   306  -- config.toml --
   307  -- content/p1.md --
   308  ---
   309  title: "p1"
   310  ---
   311  
   312  ##   Code
   313  
   314  §§§LANGUAGE {style=monokai}
   315  echo "p1";
   316  §§§
   317  -- layouts/_default/single.html --
   318  {{ .Content }}
   319  -- layouts/_default/_markup/render-codeblock.html --
   320  Attributes: {{ .Attributes }}|Options: {{ .Options }}|
   321  
   322  
   323  `
   324  	testLanguage := func(language, expect string) {
   325  		b := hugolib.NewIntegrationTestBuilder(
   326  			hugolib.IntegrationTestConfig{
   327  				T:           t,
   328  				TxtarString: strings.ReplaceAll(files, "LANGUAGE", language),
   329  			},
   330  		).Build()
   331  
   332  		b.AssertFileContent("public/p1/index.html", expect)
   333  	}
   334  
   335  	testLanguage("bash", "Attributes: map[]|Options: map[style:monokai]|")
   336  	testLanguage("hugo", "Attributes: map[style:monokai]|Options: map[]|")
   337  }
   338  
   339  func TestPanics(t *testing.T) {
   340  
   341  	files := `
   342  -- config.toml --
   343  [markup]
   344  [markup.goldmark]
   345  [markup.goldmark.parser]
   346  autoHeadingID = true
   347  autoHeadingIDType = "github"
   348  [markup.goldmark.parser.attribute]
   349  block = true
   350  title = true
   351  -- content/p1.md --
   352  ---
   353  title: "p1"
   354  ---
   355  
   356  BLOCK
   357  
   358  Common
   359  
   360  -- layouts/_default/single.html --
   361  {{ .Content }}
   362  
   363  
   364  `
   365  
   366  	for _, test := range []struct {
   367  		name     string
   368  		markdown string
   369  	}{
   370  		{"issue-9819", "asdf\n: {#myid}"},
   371  	} {
   372  		test := test
   373  		t.Run(test.name, func(t *testing.T) {
   374  			t.Parallel()
   375  			b := hugolib.NewIntegrationTestBuilder(
   376  				hugolib.IntegrationTestConfig{
   377  					T:           t,
   378  					TxtarString: strings.ReplaceAll(files, "BLOCK", test.markdown),
   379  				},
   380  			).Build()
   381  
   382  			b.AssertFileContent("public/p1/index.html", "Common")
   383  		})
   384  	}
   385  
   386  }