golang.org/x/tools/gopls@v0.15.3/internal/golang/comment_go118_test.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !go1.19
     6  // +build !go1.19
     7  
     8  package golang
     9  
    10  import (
    11  	"bytes"
    12  	"reflect"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  // This file is a copy of go/doc/comment_test.go with the exception for
    18  // the test cases for TestEmphasize and TestCommentEscape
    19  
    20  var headingTests = []struct {
    21  	line string
    22  	ok   bool
    23  }{
    24  	{"Section", true},
    25  	{"A typical usage", true},
    26  	{"ΔΛΞ is Greek", true},
    27  	{"Foo 42", true},
    28  	{"", false},
    29  	{"section", false},
    30  	{"A typical usage:", false},
    31  	{"This code:", false},
    32  	{"δ is Greek", false},
    33  	{"Foo §", false},
    34  	{"Fermat's Last Sentence", true},
    35  	{"Fermat's", true},
    36  	{"'sX", false},
    37  	{"Ted 'Too' Bar", false},
    38  	{"Use n+m", false},
    39  	{"Scanning:", false},
    40  	{"N:M", false},
    41  }
    42  
    43  func TestIsHeading(t *testing.T) {
    44  	for _, tt := range headingTests {
    45  		if h := heading(tt.line); (len(h) > 0) != tt.ok {
    46  			t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok)
    47  		}
    48  	}
    49  }
    50  
    51  var blocksTests = []struct {
    52  	in   string
    53  	out  []block
    54  	text string
    55  }{
    56  	{
    57  		in: `Para 1.
    58  Para 1 line 2.
    59  
    60  Para 2.
    61  
    62  Section
    63  
    64  Para 3.
    65  
    66  	pre
    67  	pre1
    68  
    69  Para 4.
    70  
    71  	pre
    72  	pre1
    73  
    74  	pre2
    75  
    76  Para 5.
    77  
    78  
    79  	pre
    80  
    81  
    82  	pre1
    83  	pre2
    84  
    85  Para 6.
    86  	pre
    87  	pre2
    88  `,
    89  		out: []block{
    90  			{opPara, []string{"Para 1.\n", "Para 1 line 2.\n"}},
    91  			{opPara, []string{"Para 2.\n"}},
    92  			{opHead, []string{"Section"}},
    93  			{opPara, []string{"Para 3.\n"}},
    94  			{opPre, []string{"pre\n", "pre1\n"}},
    95  			{opPara, []string{"Para 4.\n"}},
    96  			{opPre, []string{"pre\n", "pre1\n", "\n", "pre2\n"}},
    97  			{opPara, []string{"Para 5.\n"}},
    98  			{opPre, []string{"pre\n", "\n", "\n", "pre1\n", "pre2\n"}},
    99  			{opPara, []string{"Para 6.\n"}},
   100  			{opPre, []string{"pre\n", "pre2\n"}},
   101  		},
   102  		text: `.   Para 1. Para 1 line 2.
   103  
   104  .   Para 2.
   105  
   106  
   107  .   Section
   108  
   109  .   Para 3.
   110  
   111  $	pre
   112  $	pre1
   113  
   114  .   Para 4.
   115  
   116  $	pre
   117  $	pre1
   118  
   119  $	pre2
   120  
   121  .   Para 5.
   122  
   123  $	pre
   124  
   125  
   126  $	pre1
   127  $	pre2
   128  
   129  .   Para 6.
   130  
   131  $	pre
   132  $	pre2
   133  `,
   134  	},
   135  	{
   136  		in: "Para.\n\tshould not be ``escaped''",
   137  		out: []block{
   138  			{opPara, []string{"Para.\n"}},
   139  			{opPre, []string{"should not be ``escaped''"}},
   140  		},
   141  		text: ".   Para.\n\n$	should not be ``escaped''",
   142  	},
   143  	{
   144  		in: "// A very long line of 46 char for line wrapping.",
   145  		out: []block{
   146  			{opPara, []string{"// A very long line of 46 char for line wrapping."}},
   147  		},
   148  		text: `.   // A very long line of 46 char for line
   149  .   // wrapping.
   150  `,
   151  	},
   152  	{
   153  		in: `/* A very long line of 46 char for line wrapping.
   154  A very long line of 46 char for line wrapping. */`,
   155  		out: []block{
   156  			{opPara, []string{"/* A very long line of 46 char for line wrapping.\n", "A very long line of 46 char for line wrapping. */"}},
   157  		},
   158  		text: `.   /* A very long line of 46 char for line
   159  .   wrapping. A very long line of 46 char
   160  .   for line wrapping. */
   161  `,
   162  	},
   163  }
   164  
   165  func TestBlocks(t *testing.T) {
   166  	for i, tt := range blocksTests {
   167  		b := blocks(tt.in)
   168  		if !reflect.DeepEqual(b, tt.out) {
   169  			t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, b, tt.out)
   170  		}
   171  	}
   172  }
   173  
   174  // This has been modified from go/doc to use markdown links instead of html ones
   175  // and use markdown escaping instead oh html
   176  var emphasizeTests = []struct {
   177  	in, out string
   178  }{
   179  	{"", ""},
   180  	{"http://[::1]:8080/foo.txt", `[http\:\/\/\[\:\:1\]\:8080\/foo\.txt](http://[::1]:8080/foo.txt)`},
   181  	{"before (https://www.google.com) after", `before \([https\:\/\/www\.google\.com](https://www.google.com)\) after`},
   182  	{"before https://www.google.com:30/x/y/z:b::c. After", `before [https\:\/\/www\.google\.com\:30\/x\/y\/z\:b\:\:c](https://www.google.com:30/x/y/z:b::c)\. After`},
   183  	{"http://www.google.com/path/:;!-/?query=%34b#093124", `[http\:\/\/www\.google\.com\/path\/\:\;\!\-\/\?query\=\%34b\#093124](http://www.google.com/path/:;!-/?query=%34b#093124)`},
   184  	{"http://www.google.com/path/:;!-/?query=%34bar#093124", `[http\:\/\/www\.google\.com\/path\/\:\;\!\-\/\?query\=\%34bar\#093124](http://www.google.com/path/:;!-/?query=%34bar#093124)`},
   185  	{"http://www.google.com/index.html! After", `[http\:\/\/www\.google\.com\/index\.html](http://www.google.com/index.html)\! After`},
   186  	{"http://www.google.com/", `[http\:\/\/www\.google\.com\/](http://www.google.com/)`},
   187  	{"https://www.google.com/", `[https\:\/\/www\.google\.com\/](https://www.google.com/)`},
   188  	{"http://www.google.com/path.", `[http\:\/\/www\.google\.com\/path](http://www.google.com/path)\.`},
   189  	{"http://en.wikipedia.org/wiki/Camellia_(cipher)", `[http\:\/\/en\.wikipedia\.org\/wiki\/Camellia\_\(cipher\)](http://en.wikipedia.org/wiki/Camellia_\(cipher\))`},
   190  	{"(http://www.google.com/)", `\([http\:\/\/www\.google\.com\/](http://www.google.com/)\)`},
   191  	{"http://gmail.com)", `[http\:\/\/gmail\.com](http://gmail.com)\)`},
   192  	{"((http://gmail.com))", `\(\([http\:\/\/gmail\.com](http://gmail.com)\)\)`},
   193  	{"http://gmail.com ((http://gmail.com)) ()", `[http\:\/\/gmail\.com](http://gmail.com) \(\([http\:\/\/gmail\.com](http://gmail.com)\)\) \(\)`},
   194  	{"Foo bar http://example.com/ quux!", `Foo bar [http\:\/\/example\.com\/](http://example.com/) quux\!`},
   195  	{"Hello http://example.com/%2f/ /world.", `Hello [http\:\/\/example\.com\/\%2f\/](http://example.com/%2f/) \/world\.`},
   196  	{"Lorem http: ipsum //host/path", `Lorem http\: ipsum \/\/host\/path`},
   197  	{"javascript://is/not/linked", `javascript\:\/\/is\/not\/linked`},
   198  	{"http://foo", `[http\:\/\/foo](http://foo)`},
   199  	{"art by [[https://www.example.com/person/][Person Name]]", `art by \[\[[https\:\/\/www\.example\.com\/person\/](https://www.example.com/person/)\]\[Person Name\]\]`},
   200  	{"please visit (http://golang.org/)", `please visit \([http\:\/\/golang\.org\/](http://golang.org/)\)`},
   201  	{"please visit http://golang.org/hello())", `please visit [http\:\/\/golang\.org\/hello\(\)](http://golang.org/hello\(\))\)`},
   202  	{"http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD", `[http\:\/\/git\.qemu\.org\/\?p\=qemu\.git\;a\=blob\;f\=qapi\-schema\.json\;hb\=HEAD](http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD)`},
   203  	{"https://foo.bar/bal/x(])", `[https\:\/\/foo\.bar\/bal\/x\(](https://foo.bar/bal/x\()\]\)`},
   204  	{"foo [ http://bar(])", `foo \[ [http\:\/\/bar\(](http://bar\()\]\)`},
   205  }
   206  
   207  func TestEmphasize(t *testing.T) {
   208  	for i, tt := range emphasizeTests {
   209  		var buf bytes.Buffer
   210  		emphasize(&buf, tt.in, true)
   211  		out := buf.String()
   212  		if out != tt.out {
   213  			t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, out, tt.out)
   214  		}
   215  	}
   216  }
   217  
   218  func TestCommentEscape(t *testing.T) {
   219  	//ldquo -> ulquo and rdquo -> urquo
   220  	commentTests := []struct {
   221  		in, out string
   222  	}{
   223  		{"typically invoked as ``go tool asm'',", "typically invoked as " + ulquo + "go tool asm" + urquo + ","},
   224  		{"For more detail, run ``go help test'' and ``go help testflag''", "For more detail, run " + ulquo + "go help test" + urquo + " and " + ulquo + "go help testflag" + urquo}}
   225  	for i, tt := range commentTests {
   226  		var buf strings.Builder
   227  		commentEscape(&buf, tt.in, true)
   228  		out := buf.String()
   229  		if out != tt.out {
   230  			t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, out, tt.out)
   231  		}
   232  	}
   233  }
   234  
   235  func TestCommentToMarkdown(t *testing.T) {
   236  	tests := []struct {
   237  		in, out string
   238  	}{
   239  		{
   240  			in:  "F declaration.\n",
   241  			out: "F declaration\\.\n",
   242  		},
   243  		{
   244  			in: `
   245  F declaration. Lorem ipsum dolor sit amet.
   246  Etiam mattis eros at orci mollis molestie.
   247  `,
   248  			out: `
   249  F declaration\. Lorem ipsum dolor sit amet\.
   250  Etiam mattis eros at orci mollis molestie\.
   251  `,
   252  		},
   253  		{
   254  			in: `
   255  F declaration.
   256  
   257  Lorem ipsum dolor sit amet.
   258  Sed id dui turpis.
   259  
   260  
   261  
   262  
   263  Aenean tempus velit non auctor eleifend.
   264  Aenean efficitur a sem id ultricies.
   265  
   266  
   267  Phasellus efficitur mauris et viverra bibendum.
   268  `,
   269  			out: `
   270  F declaration\.
   271  
   272  Lorem ipsum dolor sit amet\.
   273  Sed id dui turpis\.
   274  
   275  Aenean tempus velit non auctor eleifend\.
   276  Aenean efficitur a sem id ultricies\.
   277  
   278  Phasellus efficitur mauris et viverra bibendum\.
   279  `,
   280  		},
   281  		{
   282  			in: `
   283  F declaration.
   284  
   285  Aenean tempus velit non auctor eleifend.
   286  
   287  Section
   288  
   289  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
   290  
   291    func foo() {}
   292  
   293  
   294    func bar() {}
   295  
   296  Fusce lorem lacus.
   297  
   298      func foo() {}
   299  
   300      func bar() {}
   301  
   302  Maecenas in lobortis lectus.
   303  
   304  	func foo() {}
   305  
   306  	func bar() {}
   307  
   308  Phasellus efficitur mauris et viverra bibendum.
   309  `,
   310  			out: `
   311  F declaration\.
   312  
   313  Aenean tempus velit non auctor eleifend\.
   314  
   315  ### Section
   316  
   317  Lorem ipsum dolor sit amet, consectetur adipiscing elit\.
   318  
   319      func foo() {}
   320  
   321  
   322      func bar() {}
   323  
   324  Fusce lorem lacus\.
   325  
   326      func foo() {}
   327  
   328      func bar() {}
   329  
   330  Maecenas in lobortis lectus\.
   331  
   332      func foo() {}
   333  
   334      func bar() {}
   335  
   336  Phasellus efficitur mauris et viverra bibendum\.
   337  `,
   338  		},
   339  		{
   340  			in: `
   341  F declaration.
   342  
   343  	func foo() {
   344  		fmt.Println("foo")
   345  	}
   346  	func bar() {
   347  		fmt.Println("bar")
   348  	}
   349  `,
   350  			out: `
   351  F declaration\.
   352  
   353      func foo() {
   354      	fmt.Println("foo")
   355      }
   356      func bar() {
   357      	fmt.Println("bar")
   358      }
   359  `,
   360  		},
   361  	}
   362  	for i, tt := range tests {
   363  		// Comments start with new lines for better readability. So, we should trim them.
   364  		tt.in = strings.TrimPrefix(tt.in, "\n")
   365  		tt.out = strings.TrimPrefix(tt.out, "\n")
   366  
   367  		if out := CommentToMarkdown(tt.in, nil); out != tt.out {
   368  			t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, out, tt.out)
   369  		}
   370  	}
   371  }