...

Source file src/github.com/yuin/goldmark/extra_test.go

Documentation: github.com/yuin/goldmark

     1  package goldmark_test
     2  
     3  import (
     4  	"bytes"
     5  	"os"
     6  	"strconv"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	. "github.com/yuin/goldmark"
    12  	"github.com/yuin/goldmark/ast"
    13  	"github.com/yuin/goldmark/parser"
    14  	"github.com/yuin/goldmark/renderer/html"
    15  	"github.com/yuin/goldmark/testutil"
    16  )
    17  
    18  var testTimeoutMultiplier = 1.0
    19  
    20  func init() {
    21  	m, err := strconv.ParseFloat(os.Getenv("GOLDMARK_TEST_TIMEOUT_MULTIPLIER"), 64)
    22  	if err == nil {
    23  		testTimeoutMultiplier = m
    24  	}
    25  }
    26  
    27  func TestExtras(t *testing.T) {
    28  	markdown := New(WithRendererOptions(
    29  		html.WithXHTML(),
    30  		html.WithUnsafe(),
    31  	))
    32  	testutil.DoTestCaseFile(markdown, "_test/extra.txt", t, testutil.ParseCliCaseArg()...)
    33  }
    34  
    35  func TestEndsWithNonSpaceCharacters(t *testing.T) {
    36  	markdown := New(WithRendererOptions(
    37  		html.WithXHTML(),
    38  		html.WithUnsafe(),
    39  	))
    40  	source := []byte("```\na\n```")
    41  	var b bytes.Buffer
    42  	err := markdown.Convert(source, &b)
    43  	if err != nil {
    44  		t.Error(err.Error())
    45  	}
    46  	if b.String() != "<pre><code>a\n</code></pre>\n" {
    47  		t.Errorf("%s \n---------\n %s", source, b.String())
    48  	}
    49  }
    50  
    51  func TestWindowsNewLine(t *testing.T) {
    52  	markdown := New(WithRendererOptions(
    53  		html.WithXHTML(),
    54  	))
    55  	source := []byte("a  \r\nb\n")
    56  	var b bytes.Buffer
    57  	err := markdown.Convert(source, &b)
    58  	if err != nil {
    59  		t.Error(err.Error())
    60  	}
    61  	if b.String() != "<p>a<br />\nb</p>\n" {
    62  		t.Errorf("%s\n---------\n%s", source, b.String())
    63  	}
    64  
    65  	source = []byte("a\\\r\nb\r\n")
    66  	var b2 bytes.Buffer
    67  	err = markdown.Convert(source, &b2)
    68  	if err != nil {
    69  		t.Error(err.Error())
    70  	}
    71  	if b2.String() != "<p>a<br />\nb</p>\n" {
    72  		t.Errorf("\n%s\n---------\n%s", source, b2.String())
    73  	}
    74  }
    75  
    76  type myIDs struct {
    77  }
    78  
    79  func (s *myIDs) Generate(value []byte, kind ast.NodeKind) []byte {
    80  	return []byte("my-id")
    81  }
    82  
    83  func (s *myIDs) Put(value []byte) {
    84  }
    85  
    86  func TestAutogeneratedIDs(t *testing.T) {
    87  	ctx := parser.NewContext(parser.WithIDs(&myIDs{}))
    88  	markdown := New(WithParserOptions(parser.WithAutoHeadingID()))
    89  	source := []byte("# Title1\n## Title2")
    90  	var b bytes.Buffer
    91  	err := markdown.Convert(source, &b, parser.WithContext(ctx))
    92  	if err != nil {
    93  		t.Error(err.Error())
    94  	}
    95  	if b.String() != `<h1 id="my-id">Title1</h1>
    96  <h2 id="my-id">Title2</h2>
    97  ` {
    98  		t.Errorf("%s\n---------\n%s", source, b.String())
    99  	}
   100  }
   101  
   102  func nowMillis() int64 {
   103  	// TODO: replace UnixNano to UnixMillis(drops Go1.16 support)
   104  	return time.Now().UnixNano() / 1000000
   105  }
   106  
   107  func TestDeepNestedLabelPerformance(t *testing.T) {
   108  	if testing.Short() {
   109  		t.Skip("skipping performance test in short mode")
   110  	}
   111  	markdown := New(WithRendererOptions(
   112  		html.WithXHTML(),
   113  		html.WithUnsafe(),
   114  	))
   115  
   116  	started := nowMillis()
   117  	n := 50000
   118  	source := []byte(strings.Repeat("[", n) + strings.Repeat("]", n))
   119  	var b bytes.Buffer
   120  	_ = markdown.Convert(source, &b)
   121  	finished := nowMillis()
   122  	if (finished - started) > int64(5000*testTimeoutMultiplier) {
   123  		t.Error("Parsing deep nested labels took too long")
   124  	}
   125  }
   126  
   127  func TestManyProcessingInstructionPerformance(t *testing.T) {
   128  	if testing.Short() {
   129  		t.Skip("skipping performance test in short mode")
   130  	}
   131  	markdown := New(WithRendererOptions(
   132  		html.WithXHTML(),
   133  		html.WithUnsafe(),
   134  	))
   135  
   136  	started := nowMillis()
   137  	n := 50000
   138  	source := []byte("a " + strings.Repeat("<?", n))
   139  	var b bytes.Buffer
   140  	_ = markdown.Convert(source, &b)
   141  	finished := nowMillis()
   142  	if (finished - started) > int64(5000*testTimeoutMultiplier) {
   143  		t.Error("Parsing processing instructions took too long")
   144  	}
   145  }
   146  
   147  func TestManyCDATAPerformance(t *testing.T) {
   148  	if testing.Short() {
   149  		t.Skip("skipping performance test in short mode")
   150  	}
   151  	markdown := New(WithRendererOptions(
   152  		html.WithXHTML(),
   153  		html.WithUnsafe(),
   154  	))
   155  
   156  	started := nowMillis()
   157  	n := 50000
   158  	source := []byte(strings.Repeat("a <![CDATA[", n))
   159  	var b bytes.Buffer
   160  	_ = markdown.Convert(source, &b)
   161  	finished := nowMillis()
   162  	if (finished - started) > int64(5000*testTimeoutMultiplier) {
   163  		t.Error("Parsing processing instructions took too long")
   164  	}
   165  }
   166  
   167  func TestManyDeclPerformance(t *testing.T) {
   168  	if testing.Short() {
   169  		t.Skip("skipping performance test in short mode")
   170  	}
   171  	markdown := New(WithRendererOptions(
   172  		html.WithXHTML(),
   173  		html.WithUnsafe(),
   174  	))
   175  
   176  	started := nowMillis()
   177  	n := 50000
   178  	source := []byte(strings.Repeat("a <!A ", n))
   179  	var b bytes.Buffer
   180  	_ = markdown.Convert(source, &b)
   181  	finished := nowMillis()
   182  	if (finished - started) > int64(5000*testTimeoutMultiplier) {
   183  		t.Error("Parsing processing instructions took too long")
   184  	}
   185  }
   186  
   187  func TestManyCommentPerformance(t *testing.T) {
   188  	if testing.Short() {
   189  		t.Skip("skipping performance test in short mode")
   190  	}
   191  	markdown := New(WithRendererOptions(
   192  		html.WithXHTML(),
   193  		html.WithUnsafe(),
   194  	))
   195  
   196  	started := nowMillis()
   197  	n := 50000
   198  	source := []byte(strings.Repeat("a <!-- ", n))
   199  	var b bytes.Buffer
   200  	_ = markdown.Convert(source, &b)
   201  	finished := nowMillis()
   202  	if (finished - started) > int64(5000*testTimeoutMultiplier) {
   203  		t.Error("Parsing processing instructions took too long")
   204  	}
   205  }
   206  
   207  func TestDangerousURLStringCase(t *testing.T) {
   208  	markdown := New()
   209  
   210  	source := []byte(`[Basic](javascript:alert('Basic'))
   211  [CaseInsensitive](JaVaScRiPt:alert('CaseInsensitive'))
   212  `)
   213  	expected := []byte(`<p><a href="">Basic</a>
   214  <a href="">CaseInsensitive</a></p>
   215  `)
   216  	var b bytes.Buffer
   217  	_ = markdown.Convert(source, &b)
   218  	if !bytes.Equal(expected, b.Bytes()) {
   219  		t.Error("Dangerous URL should ignore cases:\n" + string(testutil.DiffPretty(expected, b.Bytes())))
   220  	}
   221  }
   222  

View as plain text