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