all repos — grayfriday @ 15e052e478acfe5aa596444d7b42831519705802

blackfriday fork with a few changes

test_helpers.go (view raw)

  1//
  2// Blackfriday Markdown Processor
  3// Available at http://github.com/russross/blackfriday
  4//
  5// Copyright © 2011 Russ Ross <russ@russross.com>.
  6// Distributed under the Simplified BSD License.
  7// See README.md for details.
  8//
  9
 10//
 11// Helper functions for unit testing
 12//
 13
 14package blackfriday
 15
 16import (
 17	"io/ioutil"
 18	"path/filepath"
 19	"regexp"
 20	"testing"
 21)
 22
 23func runMarkdownBlockWithRenderer(input string, extensions Extensions, renderer Renderer) string {
 24	return string(Markdown([]byte(input), renderer, extensions))
 25}
 26
 27func runMarkdownBlock(input string, extensions Extensions) string {
 28	renderer := HTMLRenderer(UseXHTML, extensions, "", "")
 29	return runMarkdownBlockWithRenderer(input, extensions, renderer)
 30}
 31
 32func runnerWithRendererParameters(parameters HTMLRendererParameters) func(string, Extensions) string {
 33	return func(input string, extensions Extensions) string {
 34		renderer := HTMLRendererWithParameters(UseXHTML, extensions, "", "", parameters)
 35		return runMarkdownBlockWithRenderer(input, extensions, renderer)
 36	}
 37}
 38
 39func doTestsBlock(t *testing.T, tests []string, extensions Extensions) {
 40	doTestsBlockWithRunner(t, tests, extensions, runMarkdownBlock)
 41}
 42
 43func doTestsBlockWithRunner(t *testing.T, tests []string, extensions Extensions, runner func(string, Extensions) string) {
 44	// catch and report panics
 45	var candidate string
 46	defer func() {
 47		if err := recover(); err != nil {
 48			t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err)
 49		}
 50	}()
 51
 52	for i := 0; i+1 < len(tests); i += 2 {
 53		input := tests[i]
 54		candidate = input
 55		expected := tests[i+1]
 56		actual := runner(candidate, extensions)
 57		if actual != expected {
 58			t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
 59				candidate, expected, actual)
 60		}
 61
 62		// now test every substring to stress test bounds checking
 63		if !testing.Short() {
 64			for start := 0; start < len(input); start++ {
 65				for end := start + 1; end <= len(input); end++ {
 66					candidate = input[start:end]
 67					_ = runMarkdownBlock(candidate, extensions)
 68				}
 69			}
 70		}
 71	}
 72}
 73
 74func runMarkdownInline(input string, opts Options, htmlFlags HTMLFlags, params HTMLRendererParameters) string {
 75	opts.Extensions |= Autolink
 76	opts.Extensions |= Strikethrough
 77
 78	htmlFlags |= UseXHTML
 79
 80	renderer := HTMLRendererWithParameters(htmlFlags, opts.Extensions, "", "", params)
 81
 82	return string(MarkdownOptions([]byte(input), renderer, opts))
 83}
 84
 85func doTestsInline(t *testing.T, tests []string) {
 86	doTestsInlineParam(t, tests, Options{}, 0, HTMLRendererParameters{})
 87}
 88
 89func doLinkTestsInline(t *testing.T, tests []string) {
 90	doTestsInline(t, tests)
 91
 92	prefix := "http://localhost"
 93	params := HTMLRendererParameters{AbsolutePrefix: prefix}
 94	transformTests := transformLinks(tests, prefix)
 95	doTestsInlineParam(t, transformTests, Options{}, 0, params)
 96	doTestsInlineParam(t, transformTests, Options{}, CommonHtmlFlags, params)
 97}
 98
 99func doSafeTestsInline(t *testing.T, tests []string) {
100	doTestsInlineParam(t, tests, Options{}, Safelink, HTMLRendererParameters{})
101
102	// All the links in this test should not have the prefix appended, so
103	// just rerun it with different parameters and the same expectations.
104	prefix := "http://localhost"
105	params := HTMLRendererParameters{AbsolutePrefix: prefix}
106	transformTests := transformLinks(tests, prefix)
107	doTestsInlineParam(t, transformTests, Options{}, Safelink, params)
108}
109
110func doTestsInlineParam(t *testing.T, tests []string, opts Options, htmlFlags HTMLFlags, params HTMLRendererParameters) {
111	// catch and report panics
112	var candidate string
113	defer func() {
114		if err := recover(); err != nil {
115			t.Errorf("\npanic while processing [%#v] (%v)\n", candidate, err)
116		}
117	}()
118
119	for i := 0; i+1 < len(tests); i += 2 {
120		input := tests[i]
121		candidate = input
122		expected := tests[i+1]
123		actual := runMarkdownInline(candidate, opts, htmlFlags, params)
124		if actual != expected {
125			t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
126				candidate, expected, actual)
127		}
128
129		// now test every substring to stress test bounds checking
130		if !testing.Short() {
131			for start := 0; start < len(input); start++ {
132				for end := start + 1; end <= len(input); end++ {
133					candidate = input[start:end]
134					_ = runMarkdownInline(candidate, opts, htmlFlags, params)
135				}
136			}
137		}
138	}
139}
140
141func transformLinks(tests []string, prefix string) []string {
142	newTests := make([]string, len(tests))
143	anchorRe := regexp.MustCompile(`<a href="/(.*?)"`)
144	imgRe := regexp.MustCompile(`<img src="/(.*?)"`)
145	for i, test := range tests {
146		if i%2 == 1 {
147			test = anchorRe.ReplaceAllString(test, `<a href="`+prefix+`/$1"`)
148			test = imgRe.ReplaceAllString(test, `<img src="`+prefix+`/$1"`)
149		}
150		newTests[i] = test
151	}
152	return newTests
153}
154
155func runMarkdownReference(input string, flag Extensions) string {
156	renderer := HTMLRenderer(0, flag, "", "")
157	return string(Markdown([]byte(input), renderer, flag))
158}
159
160func doTestsReference(t *testing.T, files []string, flag Extensions) {
161	// catch and report panics
162	var candidate string
163	defer func() {
164		if err := recover(); err != nil {
165			t.Errorf("\npanic while processing [%#v]\n", candidate)
166		}
167	}()
168
169	for _, basename := range files {
170		filename := filepath.Join("testdata", basename+".text")
171		inputBytes, err := ioutil.ReadFile(filename)
172		if err != nil {
173			t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
174			continue
175		}
176		input := string(inputBytes)
177
178		filename = filepath.Join("testdata", basename+".html")
179		expectedBytes, err := ioutil.ReadFile(filename)
180		if err != nil {
181			t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
182			continue
183		}
184		expected := string(expectedBytes)
185
186		// fmt.Fprintf(os.Stderr, "processing %s ...", filename)
187		actual := string(runMarkdownReference(input, flag))
188		if actual != expected {
189			t.Errorf("\n    [%#v]\nExpected[%#v]\nActual  [%#v]",
190				basename+".text", expected, actual)
191		}
192		// fmt.Fprintf(os.Stderr, " ok\n")
193
194		// now test every prefix of every input to check for
195		// bounds checking
196		if !testing.Short() {
197			start, max := 0, len(input)
198			for end := start + 1; end <= max; end++ {
199				candidate = input[start:end]
200				// fmt.Fprintf(os.Stderr, "  %s %d:%d/%d\n", filename, start, end, max)
201				_ = runMarkdownReference(candidate, flag)
202			}
203		}
204	}
205}