all repos — grayfriday @ 20aa62138747b9f9960dda392d3f3475e587db06

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
 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	params.HTMLRendererParameters.Extensions = params.Options.Extensions
 48	renderer := NewHTMLRenderer(params.HTMLRendererParameters)
 49	return string(Markdown([]byte(input), renderer, params.Options))
 50}
 51
 52func doTestsBlock(t *testing.T, tests []string, extensions Extensions) {
 53	doTestsParam(t, tests, TestParams{
 54		Options:   Options{Extensions: extensions},
 55		HTMLFlags: UseXHTML,
 56	})
 57}
 58
 59func doTestsParam(t *testing.T, tests []string, params TestParams) {
 60	execRecoverableTestSuite(t, tests, params, func(candidate *string) {
 61		for i := 0; i+1 < len(tests); i += 2 {
 62			input := tests[i]
 63			*candidate = input
 64			expected := tests[i+1]
 65			actual := runMarkdown(*candidate, params)
 66			if actual != expected {
 67				t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
 68					*candidate, expected, actual)
 69			}
 70
 71			// now test every substring to stress test bounds checking
 72			if !testing.Short() {
 73				for start := 0; start < len(input); start++ {
 74					for end := start + 1; end <= len(input); end++ {
 75						*candidate = input[start:end]
 76						runMarkdown(*candidate, params)
 77					}
 78				}
 79			}
 80		}
 81	})
 82}
 83
 84func doTestsInline(t *testing.T, tests []string) {
 85	doTestsInlineParam(t, tests, TestParams{})
 86}
 87
 88func doLinkTestsInline(t *testing.T, tests []string) {
 89	doTestsInline(t, tests)
 90
 91	prefix := "http://localhost"
 92	params := HTMLRendererParameters{AbsolutePrefix: prefix}
 93	transformTests := transformLinks(tests, prefix)
 94	doTestsInlineParam(t, transformTests, TestParams{
 95		HTMLRendererParameters: params,
 96	})
 97	doTestsInlineParam(t, transformTests, TestParams{
 98		HTMLFlags:              CommonHtmlFlags,
 99		HTMLRendererParameters: params,
100	})
101}
102
103func doSafeTestsInline(t *testing.T, tests []string) {
104	doTestsInlineParam(t, tests, TestParams{HTMLFlags: Safelink})
105
106	// All the links in this test should not have the prefix appended, so
107	// just rerun it with different parameters and the same expectations.
108	prefix := "http://localhost"
109	params := HTMLRendererParameters{AbsolutePrefix: prefix}
110	transformTests := transformLinks(tests, prefix)
111	doTestsInlineParam(t, transformTests, TestParams{
112		HTMLFlags:              Safelink,
113		HTMLRendererParameters: params,
114	})
115}
116
117func doTestsInlineParam(t *testing.T, tests []string, params TestParams) {
118	params.Options.Extensions |= Autolink
119	params.Options.Extensions |= Strikethrough
120	params.HTMLFlags |= UseXHTML
121	doTestsParam(t, tests, params)
122}
123
124func transformLinks(tests []string, prefix string) []string {
125	newTests := make([]string, len(tests))
126	anchorRe := regexp.MustCompile(`<a href="/(.*?)"`)
127	imgRe := regexp.MustCompile(`<img src="/(.*?)"`)
128	for i, test := range tests {
129		if i%2 == 1 {
130			test = anchorRe.ReplaceAllString(test, `<a href="`+prefix+`/$1"`)
131			test = imgRe.ReplaceAllString(test, `<img src="`+prefix+`/$1"`)
132		}
133		newTests[i] = test
134	}
135	return newTests
136}
137
138func doTestsReference(t *testing.T, files []string, flag Extensions) {
139	params := TestParams{Options: Options{Extensions: flag}}
140	execRecoverableTestSuite(t, files, params, func(candidate *string) {
141		for _, basename := range files {
142			filename := filepath.Join("testdata", basename+".text")
143			inputBytes, err := ioutil.ReadFile(filename)
144			if err != nil {
145				t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
146				continue
147			}
148			input := string(inputBytes)
149
150			filename = filepath.Join("testdata", basename+".html")
151			expectedBytes, err := ioutil.ReadFile(filename)
152			if err != nil {
153				t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
154				continue
155			}
156			expected := string(expectedBytes)
157
158			actual := string(runMarkdown(input, params))
159			if actual != expected {
160				t.Errorf("\n    [%#v]\nExpected[%#v]\nActual  [%#v]",
161					basename+".text", expected, actual)
162			}
163
164			// now test every prefix of every input to check for
165			// bounds checking
166			if !testing.Short() {
167				start, max := 0, len(input)
168				for end := start + 1; end <= max; end++ {
169					*candidate = input[start:end]
170					runMarkdown(*candidate, params)
171				}
172			}
173		}
174	})
175}