all repos — grayfriday @ 607478a8ce5e5da6d7ab19469b507912ef20eccd

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