hugolib: Extract replaceDivider logic

To its own function and add a test and a benchmark for it.
This commit is contained in:
Bjørn Erik Pedersen 2017-08-14 08:42:30 +02:00
parent 919bc9210a
commit 199816fddd
2 changed files with 78 additions and 12 deletions

View file

@ -484,26 +484,38 @@ var (
internalSummaryDivider = []byte("HUGOMORE42") internalSummaryDivider = []byte("HUGOMORE42")
) )
// We have to replace the <!--more--> with something that survives all the // replaceDivider replaces the <!--more--> with an internal value and returns
// rendering engines. // whether the contentis truncated or not.
// TODO(bep) inline replace // Note: The content slice will be modified if needed.
func (p *Page) replaceDivider(content []byte) []byte { func replaceDivider(content, from, to []byte) ([]byte, bool) {
summaryDivider := helpers.SummaryDivider sections := bytes.Split(content, from)
// TODO(bep) handle better.
if p.Ext() == "org" || p.Markup == "org" {
summaryDivider = []byte("# more")
}
sections := bytes.Split(content, summaryDivider)
// If the raw content has nothing but whitespace after the summary // If the raw content has nothing but whitespace after the summary
// marker then the page shouldn't be marked as truncated. This check // marker then the page shouldn't be marked as truncated. This check
// is simplest against the raw content because different markup engines // is simplest against the raw content because different markup engines
// (rst and asciidoc in particular) add div and p elements after the // (rst and asciidoc in particular) add div and p elements after the
// summary marker. // summary marker.
p.Truncated = (len(sections) == 2 && truncated := (len(sections) == 2 &&
len(bytes.Trim(sections[1], " \n\r")) > 0) len(bytes.Trim(sections[1], " \n\r")) > 0)
return bytes.Join(sections, internalSummaryDivider) return bytes.Join(sections, to), truncated
}
// We have to replace the <!--more--> with something that survives all the
// rendering engines.
func (p *Page) replaceDivider(content []byte) []byte {
summaryDivider := helpers.SummaryDivider
// TODO(bep) handle better.
if p.Ext() == "org" || p.Markup == "org" {
summaryDivider = []byte("# more")
}
replaced, truncated := replaceDivider(content, summaryDivider, internalSummaryDivider)
p.Truncated = truncated
return replaced
} }
// Returns the page as summary and main if a user defined split is provided. // Returns the page as summary and main if a user defined split is provided.

View file

@ -1096,6 +1096,60 @@ func TestSliceToLower(t *testing.T) {
} }
} }
func TestReplaceDivider(t *testing.T) {
t.Parallel()
tests := []struct {
content string
from string
to string
expectedContent string
expectedTruncated bool
}{
{"none", "a", "b", "none", false},
{"summary divider content", "divider", "HUGO", "summary HUGO content", true},
{"summary\n\ndivider", "divider", "HUGO", "summary\n\nHUGO", false},
{"summary\n\ndivider\n\r", "divider", "HUGO", "summary\n\nHUGO\n\r", false},
}
for i, test := range tests {
replaced, truncated := replaceDivider([]byte(test.content), []byte(test.from), []byte(test.to))
if truncated != test.expectedTruncated {
t.Fatalf("[%d] Expected truncated to be %t, was %t", i, test.expectedTruncated, truncated)
}
if string(replaced) != test.expectedContent {
t.Fatalf("[%d] Expected content to be %q, was %q", i, test.expectedContent, replaced)
}
}
}
func BenchmarkReplaceDivider(b *testing.B) {
divider := "HUGO_DIVIDER"
from, to := []byte(divider), []byte("HUGO_REPLACED")
withDivider := make([][]byte, b.N)
noDivider := make([][]byte, b.N)
for i := 0; i < b.N; i++ {
withDivider[i] = []byte(strings.Repeat("Summary ", 5) + "\n" + divider + "\n" + strings.Repeat("Word ", 300))
noDivider[i] = []byte(strings.Repeat("Word ", 300))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, t1 := replaceDivider(withDivider[i], from, to)
_, t2 := replaceDivider(noDivider[i], from, to)
if !t1 {
b.Fatal("Should be truncated")
}
if t2 {
b.Fatal("Should not be truncated")
}
}
}
func TestPagePaths(t *testing.T) { func TestPagePaths(t *testing.T) {
t.Parallel() t.Parallel()