Fix parsing edge case of frontmatter
When the frontmatter contains a - (or other delimiter) close to the closing frontmatter delimiter, frontmatter detection would fail.
This commit is contained in:
parent
a82efe5bb1
commit
d8e1834910
8 changed files with 100 additions and 68 deletions
|
@ -19,10 +19,10 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/spf13/hugo/parser"
|
||||||
helper "github.com/spf13/hugo/template"
|
helper "github.com/spf13/hugo/template"
|
||||||
"github.com/spf13/hugo/template/bundle"
|
"github.com/spf13/hugo/template/bundle"
|
||||||
"github.com/theplant/blackfriday"
|
"github.com/theplant/blackfriday"
|
||||||
"github.com/spf13/hugo/parser"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"launchpad.net/goyaml"
|
"launchpad.net/goyaml"
|
||||||
|
|
|
@ -10,13 +10,8 @@ import (
|
||||||
|
|
||||||
var EMPTY_PAGE = ""
|
var EMPTY_PAGE = ""
|
||||||
|
|
||||||
var SIMPLE_PAGE = `---
|
var SIMPLE_PAGE = "---\ntitle: Simple\n---\nSimple Page\n"
|
||||||
title: Simple
|
var INVALID_FRONT_MATTER_MISSING = "This is a test"
|
||||||
---
|
|
||||||
Simple Page
|
|
||||||
`
|
|
||||||
|
|
||||||
var INVALID_FRONT_MATTER_MISSING = `This is a test`
|
|
||||||
|
|
||||||
var INVALID_FRONT_MATTER_SHORT_DELIM = `
|
var INVALID_FRONT_MATTER_SHORT_DELIM = `
|
||||||
--
|
--
|
||||||
|
@ -95,7 +90,7 @@ type and layout set`
|
||||||
var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
|
var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
|
||||||
title: Simple
|
title: Simple
|
||||||
---
|
---
|
||||||
Simple Page
|
Summary Next Line
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
Some more text
|
Some more text
|
||||||
|
@ -104,7 +99,7 @@ Some more text
|
||||||
var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE = `---
|
var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE = `---
|
||||||
title: Simple
|
title: Simple
|
||||||
---
|
---
|
||||||
Simple Page<!--more-->
|
Summary Same Line<!--more-->
|
||||||
|
|
||||||
Some more text
|
Some more text
|
||||||
`
|
`
|
||||||
|
@ -144,7 +139,7 @@ func checkPageTitle(t *testing.T, page *Page, title string) {
|
||||||
|
|
||||||
func checkPageContent(t *testing.T, page *Page, content string) {
|
func checkPageContent(t *testing.T, page *Page, content string) {
|
||||||
if page.Content != template.HTML(content) {
|
if page.Content != template.HTML(content) {
|
||||||
t.Fatalf("Page content is: %s. Expected %s", page.Content, content)
|
t.Fatalf("Page content mismatch\nexp: %q\ngot: %q", content, page.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,8 +185,8 @@ func TestPageWithDelimiter(t *testing.T) {
|
||||||
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
|
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
|
||||||
}
|
}
|
||||||
checkPageTitle(t, p, "Simple")
|
checkPageTitle(t, p, "Simple")
|
||||||
checkPageContent(t, p, "<p>Simple Page</p>\n\n<p>Some more text</p>\n")
|
checkPageContent(t, p, "<p>Summary Next Line</p>\n\n<p>Some more text</p>\n")
|
||||||
checkPageSummary(t, p, "<p>Simple Page</p>\n")
|
checkPageSummary(t, p, "<p>Summary Next Line</p>\n")
|
||||||
checkPageType(t, p, "page")
|
checkPageType(t, p, "page")
|
||||||
checkPageLayout(t, p, "page/single.html")
|
checkPageLayout(t, p, "page/single.html")
|
||||||
|
|
||||||
|
@ -203,8 +198,8 @@ func TestPageWithMoreTag(t *testing.T) {
|
||||||
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
|
t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
|
||||||
}
|
}
|
||||||
checkPageTitle(t, p, "Simple")
|
checkPageTitle(t, p, "Simple")
|
||||||
checkPageContent(t, p, "<p>Simple Page</p>\n\n<p>Some more text</p>\n")
|
checkPageContent(t, p, "<p>Summary Same Line</p>\n\n<p>Some more text</p>\n")
|
||||||
checkPageSummary(t, p, "<p>Simple Page</p>\n")
|
checkPageSummary(t, p, "<p>Summary Same Line</p>\n")
|
||||||
checkPageType(t, p, "page")
|
checkPageType(t, p, "page")
|
||||||
checkPageLayout(t, p, "page/single.html")
|
checkPageLayout(t, p, "page/single.html")
|
||||||
}
|
}
|
||||||
|
@ -243,7 +238,7 @@ func TestDegenerateInvalidFrontMatterShortDelim(t *testing.T) {
|
||||||
err string
|
err string
|
||||||
}{
|
}{
|
||||||
{INVALID_FRONT_MATTER_SHORT_DELIM, "Unable to locate frontmatter"},
|
{INVALID_FRONT_MATTER_SHORT_DELIM, "Unable to locate frontmatter"},
|
||||||
{INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "EOF"},
|
{INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "Unable to read frontmatter at filepos 45: EOF"},
|
||||||
{INVALID_FRONT_MATTER_MISSING, "Unable to locate frontmatter"},
|
{INVALID_FRONT_MATTER_MISSING, "Unable to locate frontmatter"},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package hugolib
|
package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"bitbucket.org/pkg/inflect"
|
"bitbucket.org/pkg/inflect"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -25,6 +24,7 @@ import (
|
||||||
"github.com/spf13/hugo/transform"
|
"github.com/spf13/hugo/transform"
|
||||||
"github.com/spf13/nitro"
|
"github.com/spf13/nitro"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -68,18 +68,18 @@ func PrintErr(str string, a ...interface{}) {
|
||||||
//
|
//
|
||||||
// 5. The entire collection of files is written to disk.
|
// 5. The entire collection of files is written to disk.
|
||||||
type Site struct {
|
type Site struct {
|
||||||
Config Config
|
Config Config
|
||||||
Pages Pages
|
Pages Pages
|
||||||
Tmpl bundle.Template
|
Tmpl bundle.Template
|
||||||
Indexes IndexList
|
Indexes IndexList
|
||||||
Source source.Input
|
Source source.Input
|
||||||
Sections Index
|
Sections Index
|
||||||
Info SiteInfo
|
Info SiteInfo
|
||||||
Shortcodes map[string]ShortcodeFunc
|
Shortcodes map[string]ShortcodeFunc
|
||||||
timer *nitro.B
|
timer *nitro.B
|
||||||
Transformer *transform.Transformer
|
Transformer *transform.Transformer
|
||||||
Target target.Output
|
Target target.Output
|
||||||
Alias target.AliasPublisher
|
Alias target.AliasPublisher
|
||||||
}
|
}
|
||||||
|
|
||||||
type SiteInfo struct {
|
type SiteInfo struct {
|
||||||
|
|
|
@ -10,7 +10,12 @@ import (
|
||||||
|
|
||||||
const SLUG_DOC_1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - sd1/foo/\n - sd2\n - sd3/\n - sd4.html\n---\nslug doc 1 content\n"
|
const SLUG_DOC_1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - sd1/foo/\n - sd2\n - sd3/\n - sd4.html\n---\nslug doc 1 content\n"
|
||||||
|
|
||||||
const SLUG_DOC_2 = "---\ntitle: slug doc 2\nslug: slug-doc-2\n---\nslug doc 2 content\n"
|
const SLUG_DOC_2 = `---
|
||||||
|
title: slug doc 2
|
||||||
|
slug: slug-doc-2
|
||||||
|
---
|
||||||
|
slug doc 2 content
|
||||||
|
`
|
||||||
|
|
||||||
const INDEX_TEMPLATE = "{{ range .Data.Pages }}.{{ end }}"
|
const INDEX_TEMPLATE = "{{ range .Data.Pages }}.{{ end }}"
|
||||||
|
|
||||||
|
@ -58,7 +63,7 @@ func (t *InMemoryAliasTarget) Publish(label string, permalink template.HTML) (er
|
||||||
|
|
||||||
var urlFakeSource = []byteSource{
|
var urlFakeSource = []byteSource{
|
||||||
{"content/blue/doc1.md", []byte(SLUG_DOC_1)},
|
{"content/blue/doc1.md", []byte(SLUG_DOC_1)},
|
||||||
// {"content/blue/doc2.md", []byte(SLUG_DOC_2)},
|
{"content/blue/doc2.md", []byte(SLUG_DOC_2)},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPageCount(t *testing.T) {
|
func TestPageCount(t *testing.T) {
|
||||||
|
@ -95,7 +100,7 @@ func TestPageCount(t *testing.T) {
|
||||||
t.Errorf("No indexed rendered. %v", target.files)
|
t.Errorf("No indexed rendered. %v", target.files)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "<html><head></head><body>.</body></html>"
|
expected := "<html><head></head><body>..</body></html>"
|
||||||
if string(blueIndex) != expected {
|
if string(blueIndex) != expected {
|
||||||
t.Errorf("Index template does not match expected: %q, got: %q", expected, string(blueIndex))
|
t.Errorf("Index template does not match expected: %q, got: %q", expected, string(blueIndex))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
@ -164,22 +164,34 @@ func determineDelims(firstLine []byte) (left, right []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatter, err error) {
|
func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatter, err error) {
|
||||||
var level int = 0
|
var (
|
||||||
var sameDelim = bytes.Equal(left, right)
|
c byte
|
||||||
|
level int = 0
|
||||||
|
bytesRead int = 0
|
||||||
|
sameDelim = bytes.Equal(left, right)
|
||||||
|
)
|
||||||
|
|
||||||
wr := new(bytes.Buffer)
|
wr := new(bytes.Buffer)
|
||||||
for {
|
for {
|
||||||
c, err := r.ReadByte()
|
if c, err = r.ReadByte(); err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("Unable to read frontmatter at filepos %d: %s", bytesRead, err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
bytesRead += 1
|
||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
case left[0]:
|
case left[0]:
|
||||||
match, err := matches(r, wr, []byte{c}, left)
|
var (
|
||||||
if err != nil {
|
buf []byte = []byte{c}
|
||||||
|
remaining []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
if remaining, err = r.Peek(len(left) - 1); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if match {
|
|
||||||
|
buf = append(buf, remaining...)
|
||||||
|
|
||||||
|
if bytes.Equal(buf, left) {
|
||||||
if sameDelim {
|
if sameDelim {
|
||||||
if level == 0 {
|
if level == 0 {
|
||||||
level = 1
|
level = 1
|
||||||
|
@ -190,6 +202,19 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatt
|
||||||
level += 1
|
level += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err = wr.Write([]byte{c}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if level == 0 {
|
||||||
|
if _, err = r.Read(remaining); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, err = wr.Write(remaining); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
case right[0]:
|
case right[0]:
|
||||||
match, err := matches(r, wr, []byte{c}, right)
|
match, err := matches(r, wr, []byte{c}, right)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -216,6 +241,10 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatt
|
||||||
return nil, errors.New("Could not find front matter.")
|
return nil, errors.New("Could not find front matter.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matches_quick(buf, expected []byte) (ok bool, err error) {
|
||||||
|
return bytes.Equal(expected, buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
func matches(r *bufio.Reader, wr io.Writer, c, expected []byte) (ok bool, err error) {
|
func matches(r *bufio.Reader, wr io.Writer, c, expected []byte) (ok bool, err error) {
|
||||||
if len(expected) == 1 {
|
if len(expected) == 1 {
|
||||||
if _, err = wr.Write(c); err != nil {
|
if _, err = wr.Write(c); err != nil {
|
||||||
|
@ -223,16 +252,13 @@ func matches(r *bufio.Reader, wr io.Writer, c, expected []byte) (ok bool, err er
|
||||||
}
|
}
|
||||||
return bytes.Equal(c, expected), nil
|
return bytes.Equal(c, expected), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, len(expected)-1)
|
buf := make([]byte, len(expected)-1)
|
||||||
if _, err = r.Read(buf); err != nil {
|
if buf, err = r.Peek(len(expected) - 1); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = append(c, buf...)
|
buf = append(c, buf...)
|
||||||
if _, err = wr.Write(buf); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes.Equal(expected, buf), nil
|
return bytes.Equal(expected, buf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,15 @@ var (
|
||||||
CONTENT_INCOMPLETE_BEG_FM_DELIM = "--\ntitle: incomplete beg fm delim\n---\nincomplete frontmatter delim"
|
CONTENT_INCOMPLETE_BEG_FM_DELIM = "--\ntitle: incomplete beg fm delim\n---\nincomplete frontmatter delim"
|
||||||
CONTENT_INCOMPLETE_END_FM_DELIM = "---\ntitle: incomplete end fm delim\n--\nincomplete frontmatter delim"
|
CONTENT_INCOMPLETE_END_FM_DELIM = "---\ntitle: incomplete end fm delim\n--\nincomplete frontmatter delim"
|
||||||
CONTENT_MISSING_END_FM_DELIM = "---\ntitle: incomplete end fm delim\nincomplete frontmatter delim"
|
CONTENT_MISSING_END_FM_DELIM = "---\ntitle: incomplete end fm delim\nincomplete frontmatter delim"
|
||||||
|
CONTENT_SLUG_WORKING = "---\ntitle: slug doc 2\nslug: slug-doc-2\n\n---\nslug doc 2 content"
|
||||||
|
CONTENT_SLUG_WORKING_VARIATION = "---\ntitle: slug doc 3\nslug: slug-doc 3\n---\nslug doc 3 content"
|
||||||
|
CONTENT_SLUG_BUG = "---\ntitle: slug doc 2\nslug: slug-doc-2\n---\nslug doc 2 content"
|
||||||
CONTENT_FM_NO_DOC = "---\ntitle: no doc\n---"
|
CONTENT_FM_NO_DOC = "---\ntitle: no doc\n---"
|
||||||
CONTENT_WITH_JS_FM = "{\n \"categories\": \"d\",\n \"tags\": [\n \"a\", \n \"b\", \n \"c\"\n ]\n}\nJSON Front Matter with tags and categories"
|
CONTENT_WITH_JS_FM = "{\n \"categories\": \"d\",\n \"tags\": [\n \"a\", \n \"b\", \n \"c\"\n ]\n}\nJSON Front Matter with tags and categories"
|
||||||
)
|
)
|
||||||
|
|
||||||
var lineEndings = []string{"\n", "\r\n"}
|
var lineEndings = []string{"\n", "\r\n"}
|
||||||
var delimiters = []string{"-", "+"}
|
var delimiters = []string{"---", "+++"}
|
||||||
|
|
||||||
func pageMust(p Page, err error) *page {
|
func pageMust(p Page, err error) *page {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,13 +86,13 @@ func checkPageFrontMatterContent(t *testing.T, p *page, frontMatter string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !bytes.Equal(p.frontmatter, []byte(frontMatter)) {
|
if !bytes.Equal(p.frontmatter, []byte(frontMatter)) {
|
||||||
t.Errorf("expected frontmatter %q, got %q", frontMatter, p.frontmatter)
|
t.Errorf("frontmatter mismatch\nexp: %q\ngot: %q", frontMatter, p.frontmatter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkPageContent(t *testing.T, p *page, expected string) {
|
func checkPageContent(t *testing.T, p *page, expected string) {
|
||||||
if !bytes.Equal(p.content, []byte(expected)) {
|
if !bytes.Equal(p.content, []byte(expected)) {
|
||||||
t.Errorf("expected content %q, got %q", expected, p.content)
|
t.Errorf("content mismatch\nexp: %q\ngot: %q", expected, p.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ func TestStandaloneCreatePageFrom(t *testing.T) {
|
||||||
frontMatter string
|
frontMatter string
|
||||||
bodycontent string
|
bodycontent string
|
||||||
}{
|
}{
|
||||||
|
|
||||||
{CONTENT_NO_FRONTMATTER, true, true, "", "a page with no front matter"},
|
{CONTENT_NO_FRONTMATTER, true, true, "", "a page with no front matter"},
|
||||||
{CONTENT_WITH_FRONTMATTER, true, false, "---\ntitle: front matter\n---\n", "Content with front matter"},
|
{CONTENT_WITH_FRONTMATTER, true, false, "---\ntitle: front matter\n---\n", "Content with front matter"},
|
||||||
{CONTENT_HTML_NODOCTYPE, false, true, "", "<html>\n\t<body>\n\t</body>\n</html>"},
|
{CONTENT_HTML_NODOCTYPE, false, true, "", "<html>\n\t<body>\n\t</body>\n</html>"},
|
||||||
|
@ -109,6 +113,9 @@ func TestStandaloneCreatePageFrom(t *testing.T) {
|
||||||
{CONTENT_LWS_HTML, false, true, "", "<html><body></body></html>"},
|
{CONTENT_LWS_HTML, false, true, "", "<html><body></body></html>"},
|
||||||
{CONTENT_LWS_LF_HTML, false, true, "", "<html><body></body></html>"},
|
{CONTENT_LWS_LF_HTML, false, true, "", "<html><body></body></html>"},
|
||||||
{CONTENT_WITH_JS_FM, true, false, "{\n \"categories\": \"d\",\n \"tags\": [\n \"a\", \n \"b\", \n \"c\"\n ]\n}", "JSON Front Matter with tags and categories"},
|
{CONTENT_WITH_JS_FM, true, false, "{\n \"categories\": \"d\",\n \"tags\": [\n \"a\", \n \"b\", \n \"c\"\n ]\n}", "JSON Front Matter with tags and categories"},
|
||||||
|
{CONTENT_SLUG_WORKING, true, false, "---\ntitle: slug doc 2\nslug: slug-doc-2\n\n---\n", "slug doc 2 content"},
|
||||||
|
{CONTENT_SLUG_WORKING_VARIATION, true, false, "---\ntitle: slug doc 3\nslug: slug-doc 3\n---\n", "slug doc 3 content"},
|
||||||
|
{CONTENT_SLUG_BUG, true, false, "---\ntitle: slug doc 2\nslug: slug-doc-2\n---\n", "slug doc 2 content"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -224,6 +231,7 @@ func TestExtractFrontMatter(t *testing.T) {
|
||||||
{"---\nralb\n---\n", []byte("---\nralb\n---\n"), true},
|
{"---\nralb\n---\n", []byte("---\nralb\n---\n"), true},
|
||||||
{"---\nminc\n---\ncontent", []byte("---\nminc\n---\n"), true},
|
{"---\nminc\n---\ncontent", []byte("---\nminc\n---\n"), true},
|
||||||
{"---\ncnim\n---\ncontent\n", []byte("---\ncnim\n---\n"), true},
|
{"---\ncnim\n---\ncontent\n", []byte("---\ncnim\n---\n"), true},
|
||||||
|
{"---\ntitle: slug doc 2\nslug: slug-doc-2\n---\ncontent\n", []byte("---\ntitle: slug doc 2\nslug: slug-doc-2\n---\n"), true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -231,8 +239,8 @@ func TestExtractFrontMatter(t *testing.T) {
|
||||||
test.frontmatter = strings.Replace(test.frontmatter, "\n", ending, -1)
|
test.frontmatter = strings.Replace(test.frontmatter, "\n", ending, -1)
|
||||||
test.extracted = bytes.Replace(test.extracted, []byte("\n"), []byte(ending), -1)
|
test.extracted = bytes.Replace(test.extracted, []byte("\n"), []byte(ending), -1)
|
||||||
for _, delim := range delimiters {
|
for _, delim := range delimiters {
|
||||||
test.frontmatter = strings.Replace(test.frontmatter, "-", delim, -1)
|
test.frontmatter = strings.Replace(test.frontmatter, "---", delim, -1)
|
||||||
test.extracted = bytes.Replace(test.extracted, []byte("-"), []byte(delim), -1)
|
test.extracted = bytes.Replace(test.extracted, []byte("---"), []byte(delim), -1)
|
||||||
line, err := peekLine(bufio.NewReader(strings.NewReader(test.frontmatter)))
|
line, err := peekLine(bufio.NewReader(strings.NewReader(test.frontmatter)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -245,8 +253,7 @@ func TestExtractFrontMatter(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !bytes.Equal(fm, test.extracted) {
|
if !bytes.Equal(fm, test.extracted) {
|
||||||
t.Logf("\n%q\n", string(test.frontmatter))
|
t.Errorf("Frontmatter did not match:\nexp: %q\ngot: %q", string(test.extracted), fm)
|
||||||
t.Errorf("Expected front matter %q. got %q", string(test.extracted), fm)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,8 +292,7 @@ func TestExtractFrontMatterDelim(t *testing.T) {
|
||||||
}
|
}
|
||||||
if !bytes.Equal(fm, []byte(test.extracted)) {
|
if !bytes.Equal(fm, []byte(test.extracted)) {
|
||||||
t.Logf("\n%q\n", string(test.frontmatter))
|
t.Logf("\n%q\n", string(test.frontmatter))
|
||||||
t.Errorf("Expected front matter %q. got %q", string(test.extracted), fm)
|
t.Errorf("Frontmatter did not match:\nexp: %q\ngot: %q", string(test.extracted), fm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package transform
|
package transform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
htmltran "code.google.com/p/go-html-transform/html/transform"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
htmltran "code.google.com/p/go-html-transform/html/transform"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Transformer struct {
|
type Transformer struct {
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
package transform
|
package transform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"strings"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
const H5_JS_CONTENT_DOUBLE_QUOTE = "<!DOCTYPE html><html><head><script src=\"foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href='/foobar'>foobar</a>. Follow up</article></body></html>"
|
const H5_JS_CONTENT_DOUBLE_QUOTE = "<!DOCTYPE html><html><head><script src=\"foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href='/foobar'>foobar</a>. Follow up</article></body></html>"
|
||||||
const H5_JS_CONTENT_SINGLE_QUOTE = "<!DOCTYPE html><html><head><script src='foobar.js'></script></head><body><nav><h1>title</h1></nav><article>content <a href='/foobar'>foobar</a>. Follow up</article></body></html>"
|
const H5_JS_CONTENT_SINGLE_QUOTE = "<!DOCTYPE html><html><head><script src='foobar.js'></script></head><body><nav><h1>title</h1></nav><article>content <a href='/foobar'>foobar</a>. Follow up</article></body></html>"
|
||||||
const H5_JS_CONTENT_ABS_URL = "<!DOCTYPE html><html><head><script src=\"http://user@host:10234/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"https://host/foobar\">foobar</a>. Follow up</article></body></html>"
|
const H5_JS_CONTENT_ABS_URL = "<!DOCTYPE html><html><head><script src=\"http://user@host:10234/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"https://host/foobar\">foobar</a>. Follow up</article></body></html>"
|
||||||
|
|
||||||
// URL doesn't recognize authorities. BUG?
|
// URL doesn't recognize authorities. BUG?
|
||||||
//const H5_JS_CONTENT_ABS_URL = "<!DOCTYPE html><html><head><script src=\"//host/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"https://host/foobar\">foobar</a>. Follow up</article></body></html>"
|
//const H5_JS_CONTENT_ABS_URL = "<!DOCTYPE html><html><head><script src=\"//host/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"https://host/foobar\">foobar</a>. Follow up</article></body></html>"
|
||||||
|
|
||||||
const CORRECT_OUTPUT_SRC_HREF = "<!DOCTYPE html><html><head><script src=\"http://base/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"http://base/foobar\">foobar</a>. Follow up</article></body></html>"
|
const CORRECT_OUTPUT_SRC_HREF = "<!DOCTYPE html><html><head><script src=\"http://base/foobar.js\"></script></head><body><nav><h1>title</h1></nav><article>content <a href=\"http://base/foobar\">foobar</a>. Follow up</article></body></html>"
|
||||||
|
|
||||||
|
|
||||||
func TestAbsUrlify(t *testing.T) {
|
func TestAbsUrlify(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
content string
|
content string
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{H5_JS_CONTENT_DOUBLE_QUOTE, CORRECT_OUTPUT_SRC_HREF},
|
{H5_JS_CONTENT_DOUBLE_QUOTE, CORRECT_OUTPUT_SRC_HREF},
|
||||||
|
@ -29,13 +29,13 @@ func TestAbsUrlify(t *testing.T) {
|
||||||
tr := &Transformer{
|
tr := &Transformer{
|
||||||
BaseURL: "http://base",
|
BaseURL: "http://base",
|
||||||
}
|
}
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
err := tr.Apply(strings.NewReader(test.content), out)
|
err := tr.Apply(strings.NewReader(test.content), out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %s", err)
|
t.Errorf("Unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
if test.expected != string(out.Bytes()) {
|
if test.expected != string(out.Bytes()) {
|
||||||
t.Errorf("Expected:\n%s\nGot:\n%s", test.expected, string(out.Bytes()))
|
t.Errorf("Expected:\n%s\nGot:\n%s", test.expected, string(out.Bytes()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue