hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

pageparser_intro_test.go (5518B)

    1 // Copyright 2018 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package pageparser
   15 
   16 import (
   17 	"fmt"
   18 	"reflect"
   19 	"strings"
   20 	"testing"
   21 )
   22 
   23 type lexerTest struct {
   24 	name  string
   25 	input string
   26 	items []Item
   27 }
   28 
   29 func nti(tp ItemType, val string) Item {
   30 	return Item{tp, 0, []byte(val), false}
   31 }
   32 
   33 var (
   34 	tstJSON                = `{ "a": { "b": "\"Hugo\"}" } }`
   35 	tstFrontMatterTOML     = nti(TypeFrontMatterTOML, "foo = \"bar\"\n")
   36 	tstFrontMatterYAML     = nti(TypeFrontMatterYAML, "foo: \"bar\"\n")
   37 	tstFrontMatterYAMLCRLF = nti(TypeFrontMatterYAML, "foo: \"bar\"\r\n")
   38 	tstFrontMatterJSON     = nti(TypeFrontMatterJSON, tstJSON+"\r\n")
   39 	tstSomeText            = nti(tText, "\nSome text.\n")
   40 	tstSummaryDivider      = nti(TypeLeadSummaryDivider, "<!--more-->\n")
   41 	tstNewline             = nti(tText, "\n")
   42 
   43 	tstORG = `
   44 #+TITLE: T1
   45 #+AUTHOR: A1
   46 #+DESCRIPTION: D1
   47 `
   48 	tstFrontMatterORG = nti(TypeFrontMatterORG, tstORG)
   49 )
   50 
   51 var crLfReplacer = strings.NewReplacer("\r", "#", "\n", "$")
   52 
   53 // TODO(bep) a way to toggle ORG mode vs the rest.
   54 var frontMatterTests = []lexerTest{
   55 	{"empty", "", []Item{tstEOF}},
   56 	{"Byte order mark", "\ufeff\nSome text.\n", []Item{nti(TypeIgnore, "\ufeff"), tstSomeText, tstEOF}},
   57 	{"HTML Document", `  <html>  `, []Item{nti(tError, "plain HTML documents not supported")}},
   58 	{"HTML Document with shortcode", `<html>{{< sc1 >}}</html>`, []Item{nti(tError, "plain HTML documents not supported")}},
   59 	{"No front matter", "\nSome text.\n", []Item{tstSomeText, tstEOF}},
   60 	{"YAML front matter", "---\nfoo: \"bar\"\n---\n\nSome text.\n", []Item{tstFrontMatterYAML, tstSomeText, tstEOF}},
   61 	{"YAML empty front matter", "---\n---\n\nSome text.\n", []Item{nti(TypeFrontMatterYAML, ""), tstSomeText, tstEOF}},
   62 	{"YAML commented out front matter", "<!--\n---\nfoo: \"bar\"\n---\n-->\nSome text.\n", []Item{nti(TypeIgnore, "<!--\n"), tstFrontMatterYAML, nti(TypeIgnore, "-->"), tstSomeText, tstEOF}},
   63 	{"YAML commented out front matter, no end", "<!--\n---\nfoo: \"bar\"\n---\nSome text.\n", []Item{nti(TypeIgnore, "<!--\n"), tstFrontMatterYAML, nti(tError, "starting HTML comment with no end")}},
   64 	// Note that we keep all bytes as they are, but we need to handle CRLF
   65 	{"YAML front matter CRLF", "---\r\nfoo: \"bar\"\r\n---\n\nSome text.\n", []Item{tstFrontMatterYAMLCRLF, tstSomeText, tstEOF}},
   66 	{"TOML front matter", "+++\nfoo = \"bar\"\n+++\n\nSome text.\n", []Item{tstFrontMatterTOML, tstSomeText, tstEOF}},
   67 	{"JSON front matter", tstJSON + "\r\n\nSome text.\n", []Item{tstFrontMatterJSON, tstSomeText, tstEOF}},
   68 	{"ORG front matter", tstORG + "\nSome text.\n", []Item{tstFrontMatterORG, tstSomeText, tstEOF}},
   69 	{"Summary divider ORG", tstORG + "\nSome text.\n# more\nSome text.\n", []Item{tstFrontMatterORG, tstSomeText, nti(TypeLeadSummaryDivider, "# more\n"), nti(tText, "Some text.\n"), tstEOF}},
   70 	{"Summary divider", "+++\nfoo = \"bar\"\n+++\n\nSome text.\n<!--more-->\nSome text.\n", []Item{tstFrontMatterTOML, tstSomeText, tstSummaryDivider, nti(tText, "Some text.\n"), tstEOF}},
   71 	{"Summary divider same line", "+++\nfoo = \"bar\"\n+++\n\nSome text.<!--more-->Some text.\n", []Item{tstFrontMatterTOML, nti(tText, "\nSome text."), nti(TypeLeadSummaryDivider, "<!--more-->"), nti(tText, "Some text.\n"), tstEOF}},
   72 	// https://github.com/gohugoio/hugo/issues/5402
   73 	{"Summary and shortcode, no space", "+++\nfoo = \"bar\"\n+++\n\nSome text.\n<!--more-->{{< sc1 >}}\nSome text.\n", []Item{tstFrontMatterTOML, tstSomeText, nti(TypeLeadSummaryDivider, "<!--more-->"), tstLeftNoMD, tstSC1, tstRightNoMD, tstSomeText, tstEOF}},
   74 	// https://github.com/gohugoio/hugo/issues/5464
   75 	{"Summary and shortcode only", "+++\nfoo = \"bar\"\n+++\n{{< sc1 >}}\n<!--more-->\n{{< sc2 >}}", []Item{tstFrontMatterTOML, tstLeftNoMD, tstSC1, tstRightNoMD, tstNewline, tstSummaryDivider, tstLeftNoMD, tstSC2, tstRightNoMD, tstEOF}},
   76 }
   77 
   78 func TestFrontMatter(t *testing.T) {
   79 	t.Parallel()
   80 	for i, test := range frontMatterTests {
   81 		items := collect([]byte(test.input), false, lexIntroSection)
   82 		if !equal(items, test.items) {
   83 			got := crLfReplacer.Replace(fmt.Sprint(items))
   84 			expected := crLfReplacer.Replace(fmt.Sprint(test.items))
   85 			t.Errorf("[%d] %s: got\n\t%v\nexpected\n\t%v", i, test.name, got, expected)
   86 		}
   87 	}
   88 }
   89 
   90 func collectWithConfig(input []byte, skipFrontMatter bool, stateStart stateFunc, cfg Config) (items []Item) {
   91 	l := newPageLexer(input, stateStart, cfg)
   92 	l.run()
   93 	t := l.newIterator()
   94 
   95 	for {
   96 		item := t.Next()
   97 		items = append(items, item)
   98 		if item.Type == tEOF || item.Type == tError {
   99 			break
  100 		}
  101 	}
  102 	return
  103 }
  104 
  105 func collect(input []byte, skipFrontMatter bool, stateStart stateFunc) (items []Item) {
  106 	var cfg Config
  107 
  108 	return collectWithConfig(input, skipFrontMatter, stateStart, cfg)
  109 }
  110 
  111 // no positional checking, for now ...
  112 func equal(i1, i2 []Item) bool {
  113 	if len(i1) != len(i2) {
  114 		return false
  115 	}
  116 	for k := range i1 {
  117 		if i1[k].Type != i2[k].Type {
  118 			return false
  119 		}
  120 
  121 		if !reflect.DeepEqual(i1[k].Val, i2[k].Val) {
  122 			return false
  123 		}
  124 	}
  125 	return true
  126 }