all repos — grayfriday @ fb56a7e01e0e5f67a4854838504c2565d6224236

blackfriday fork with a few changes

helpers_test.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
 23type TestParams struct {
 24	Options
 25	HTMLFlags
 26	HTMLRendererParameters
 27}
 28
 29func execRecoverableTestSuite(t *testing.T, tests []string, params TestParams, suite func(candidate *string)) {
 30	// Catch and report panics. This is useful when running 'go test -v' on
 31	// the integration server. When developing, though, crash dump is often
 32	// preferable, so recovery can be easily turned off with doRecover = false.
 33	var candidate string
 34	const doRecover = true
 35	if doRecover {
 36		defer func() {
 37			if err := recover(); err != nil {
 38				t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err)
 39			}
 40		}()
 41	}
 42	suite(&candidate)
 43}
 44
 45func runMarkdown(input string, params TestParams) string {
 46	params.HTMLRendererParameters.Flags = params.HTMLFlags
 47	renderer := NewHTMLRenderer(params.HTMLRendererParameters)
 48	return string(Markdown([]byte(input), renderer, params.Options))
 49}
 50
 51// doTests runs full document tests using MarkdownCommon configuration.
 52func doTests(t *testing.T, tests []string) {
 53	doTestsParam(t, tests, TestParams{
 54		Options: DefaultOptions,
 55		HTMLRendererParameters: HTMLRendererParameters{
 56			Flags: CommonHTMLFlags,
 57		},
 58	})
 59}
 60
 61func doTestsBlock(t *testing.T, tests []string, extensions Extensions) {
 62	doTestsParam(t, tests, TestParams{
 63		Options:   Options{Extensions: extensions},
 64		HTMLFlags: UseXHTML,
 65	})
 66}
 67
 68func doTestsParam(t *testing.T, tests []string, params TestParams) {
 69	execRecoverableTestSuite(t, tests, params, func(candidate *string) {
 70		for i := 0; i+1 < len(tests); i += 2 {
 71			input := tests[i]
 72			*candidate = input
 73			expected := tests[i+1]
 74			actual := runMarkdown(*candidate, params)
 75			if actual != expected {
 76				t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
 77					*candidate, expected, actual)
 78			}
 79
 80			// now test every substring to stress test bounds checking
 81			if !testing.Short() {
 82				for start := 0; start < len(input); start++ {
 83					for end := start + 1; end <= len(input); end++ {
 84						*candidate = input[start:end]
 85						runMarkdown(*candidate, params)
 86					}
 87				}
 88			}
 89		}
 90	})
 91}
 92
 93func doTestsInline(t *testing.T, tests []string) {
 94	doTestsInlineParam(t, tests, TestParams{})
 95}
 96
 97func doLinkTestsInline(t *testing.T, tests []string) {
 98	doTestsInline(t, tests)
 99
100	prefix := "http://localhost"
101	params := HTMLRendererParameters{AbsolutePrefix: prefix}
102	transformTests := transformLinks(tests, prefix)
103	doTestsInlineParam(t, transformTests, TestParams{
104		HTMLRendererParameters: params,
105	})
106	doTestsInlineParam(t, transformTests, TestParams{
107		HTMLFlags:              UseXHTML,
108		HTMLRendererParameters: params,
109	})
110}
111
112func doSafeTestsInline(t *testing.T, tests []string) {
113	doTestsInlineParam(t, tests, TestParams{HTMLFlags: Safelink})
114
115	// All the links in this test should not have the prefix appended, so
116	// just rerun it with different parameters and the same expectations.
117	prefix := "http://localhost"
118	params := HTMLRendererParameters{AbsolutePrefix: prefix}
119	transformTests := transformLinks(tests, prefix)
120	doTestsInlineParam(t, transformTests, TestParams{
121		HTMLFlags:              Safelink,
122		HTMLRendererParameters: params,
123	})
124}
125
126func doTestsInlineParam(t *testing.T, tests []string, params TestParams) {
127	params.Options.Extensions |= Autolink
128	params.Options.Extensions |= Strikethrough
129	params.HTMLFlags |= UseXHTML
130	doTestsParam(t, tests, params)
131}
132
133func transformLinks(tests []string, prefix string) []string {
134	newTests := make([]string, len(tests))
135	anchorRe := regexp.MustCompile(`<a href="/(.*?)"`)
136	imgRe := regexp.MustCompile(`<img src="/(.*?)"`)
137	for i, test := range tests {
138		if i%2 == 1 {
139			test = anchorRe.ReplaceAllString(test, `<a href="`+prefix+`/$1"`)
140			test = imgRe.ReplaceAllString(test, `<img src="`+prefix+`/$1"`)
141		}
142		newTests[i] = test
143	}
144	return newTests
145}
146
147func doTestsReference(t *testing.T, files []string, flag Extensions) {
148	params := TestParams{Options: Options{Extensions: flag}}
149	execRecoverableTestSuite(t, files, params, func(candidate *string) {
150		for _, basename := range files {
151			filename := filepath.Join("testdata", basename+".text")
152			inputBytes, err := ioutil.ReadFile(filename)
153			if err != nil {
154				t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
155				continue
156			}
157			input := string(inputBytes)
158
159			filename = filepath.Join("testdata", basename+".html")
160			expectedBytes, err := ioutil.ReadFile(filename)
161			if err != nil {
162				t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
163				continue
164			}
165			expected := string(expectedBytes)
166
167			actual := string(runMarkdown(input, params))
168			if actual != expected {
169				t.Errorf("\n    [%#v]\nExpected[%#v]\nActual  [%#v]",
170					basename+".text", expected, actual)
171			}
172
173			// now test every prefix of every input to check for
174			// bounds checking
175			if !testing.Short() {
176				start, max := 0, len(input)
177				for end := start + 1; end <= max; end++ {
178					*candidate = input[start:end]
179					runMarkdown(*candidate, params)
180				}
181			}
182		}
183	})
184}