From 199816fddd6f16b4a3e9a737530c7738f0da1b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 14 Aug 2017 08:42:30 +0200 Subject: [PATCH] hugolib: Extract replaceDivider logic To its own function and add a test and a benchmark for it. --- hugolib/page.go | 36 +++++++++++++++++++---------- hugolib/page_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/hugolib/page.go b/hugolib/page.go index 0120d6ef0..b5d13d4db 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -484,26 +484,38 @@ var ( internalSummaryDivider = []byte("HUGOMORE42") ) -// We have to replace the with something that survives all the -// rendering engines. -// TODO(bep) inline replace -func (p *Page) replaceDivider(content []byte) []byte { - summaryDivider := helpers.SummaryDivider - // TODO(bep) handle better. - if p.Ext() == "org" || p.Markup == "org" { - summaryDivider = []byte("# more") - } - sections := bytes.Split(content, summaryDivider) +// replaceDivider replaces the with an internal value and returns +// whether the contentis truncated or not. +// Note: The content slice will be modified if needed. +func replaceDivider(content, from, to []byte) ([]byte, bool) { + sections := bytes.Split(content, from) // If the raw content has nothing but whitespace after the summary // marker then the page shouldn't be marked as truncated. This check // is simplest against the raw content because different markup engines // (rst and asciidoc in particular) add div and p elements after the // summary marker. - p.Truncated = (len(sections) == 2 && + truncated := (len(sections) == 2 && len(bytes.Trim(sections[1], " \n\r")) > 0) - return bytes.Join(sections, internalSummaryDivider) + return bytes.Join(sections, to), truncated + +} + +// We have to replace the 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. diff --git a/hugolib/page_test.go b/hugolib/page_test.go index 5c5c06b07..cc2ab9662 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -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) { t.Parallel()