hugo

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

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

layout_test.go (26665B)

    1 // Copyright 2017-present 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 output
   15 
   16 import (
   17 	"fmt"
   18 	"reflect"
   19 	"strings"
   20 	"testing"
   21 
   22 	"github.com/gohugoio/hugo/media"
   23 
   24 	qt "github.com/frankban/quicktest"
   25 	"github.com/kylelemons/godebug/diff"
   26 )
   27 
   28 func TestLayout(t *testing.T) {
   29 	c := qt.New(t)
   30 
   31 	noExtNoDelimMediaType := media.WithDelimiterAndSuffixes(media.TextType, "", "")
   32 	noExtMediaType := media.WithDelimiterAndSuffixes(media.TextType, ".", "")
   33 
   34 	var (
   35 		ampType = Format{
   36 			Name:      "AMP",
   37 			MediaType: media.HTMLType,
   38 			BaseName:  "index",
   39 		}
   40 
   41 		htmlFormat = HTMLFormat
   42 
   43 		noExtDelimFormat = Format{
   44 			Name:      "NEM",
   45 			MediaType: noExtNoDelimMediaType,
   46 			BaseName:  "_redirects",
   47 		}
   48 
   49 		noExt = Format{
   50 			Name:      "NEX",
   51 			MediaType: noExtMediaType,
   52 			BaseName:  "next",
   53 		}
   54 	)
   55 
   56 	for _, this := range []struct {
   57 		name             string
   58 		layoutDescriptor LayoutDescriptor
   59 		layoutOverride   string
   60 		format           Format
   61 		expect           []string
   62 	}{
   63 		{
   64 			"Home",
   65 			LayoutDescriptor{Kind: "home"},
   66 			"", ampType,
   67 			[]string{
   68 				"index.amp.html",
   69 				"home.amp.html",
   70 				"list.amp.html",
   71 				"index.html",
   72 				"home.html",
   73 				"list.html",
   74 				"_default/index.amp.html",
   75 				"_default/home.amp.html",
   76 				"_default/list.amp.html",
   77 				"_default/index.html",
   78 				"_default/home.html",
   79 				"_default/list.html",
   80 			},
   81 		},
   82 		{
   83 			"Home baseof",
   84 			LayoutDescriptor{Kind: "home", Baseof: true},
   85 			"", ampType,
   86 			[]string{
   87 				"index-baseof.amp.html",
   88 				"home-baseof.amp.html",
   89 				"list-baseof.amp.html",
   90 				"baseof.amp.html",
   91 				"index-baseof.html",
   92 				"home-baseof.html",
   93 				"list-baseof.html",
   94 				"baseof.html",
   95 				"_default/index-baseof.amp.html",
   96 				"_default/home-baseof.amp.html",
   97 				"_default/list-baseof.amp.html",
   98 				"_default/baseof.amp.html",
   99 				"_default/index-baseof.html",
  100 				"_default/home-baseof.html",
  101 				"_default/list-baseof.html",
  102 				"_default/baseof.html",
  103 			},
  104 		},
  105 		{
  106 			"Home, HTML",
  107 			LayoutDescriptor{Kind: "home"},
  108 			"", htmlFormat,
  109 			// We will eventually get to index.html. This looks stuttery, but makes the lookup logic easy to understand.
  110 			[]string{
  111 				"index.html.html",
  112 				"home.html.html",
  113 				"list.html.html",
  114 				"index.html",
  115 				"home.html",
  116 				"list.html",
  117 				"_default/index.html.html",
  118 				"_default/home.html.html",
  119 				"_default/list.html.html",
  120 				"_default/index.html",
  121 				"_default/home.html",
  122 				"_default/list.html",
  123 			},
  124 		},
  125 		{
  126 			"Home, HTML, baseof",
  127 			LayoutDescriptor{Kind: "home", Baseof: true},
  128 			"", htmlFormat,
  129 			[]string{
  130 				"index-baseof.html.html",
  131 				"home-baseof.html.html",
  132 				"list-baseof.html.html",
  133 				"baseof.html.html",
  134 				"index-baseof.html",
  135 				"home-baseof.html",
  136 				"list-baseof.html",
  137 				"baseof.html",
  138 				"_default/index-baseof.html.html",
  139 				"_default/home-baseof.html.html",
  140 				"_default/list-baseof.html.html",
  141 				"_default/baseof.html.html",
  142 				"_default/index-baseof.html",
  143 				"_default/home-baseof.html",
  144 				"_default/list-baseof.html",
  145 				"_default/baseof.html",
  146 			},
  147 		},
  148 		{
  149 			"Home, french language",
  150 			LayoutDescriptor{Kind: "home", Lang: "fr"},
  151 			"", ampType,
  152 			[]string{
  153 				"index.fr.amp.html",
  154 				"home.fr.amp.html",
  155 				"list.fr.amp.html",
  156 				"index.amp.html",
  157 				"home.amp.html",
  158 				"list.amp.html",
  159 				"index.fr.html",
  160 				"home.fr.html",
  161 				"list.fr.html",
  162 				"index.html",
  163 				"home.html",
  164 				"list.html",
  165 				"_default/index.fr.amp.html",
  166 				"_default/home.fr.amp.html",
  167 				"_default/list.fr.amp.html",
  168 				"_default/index.amp.html",
  169 				"_default/home.amp.html",
  170 				"_default/list.amp.html",
  171 				"_default/index.fr.html",
  172 				"_default/home.fr.html",
  173 				"_default/list.fr.html",
  174 				"_default/index.html",
  175 				"_default/home.html",
  176 				"_default/list.html",
  177 			},
  178 		},
  179 		{
  180 			"Home, no ext or delim",
  181 			LayoutDescriptor{Kind: "home"},
  182 			"", noExtDelimFormat,
  183 			[]string{
  184 				"index.nem",
  185 				"home.nem",
  186 				"list.nem",
  187 				"_default/index.nem",
  188 				"_default/home.nem",
  189 				"_default/list.nem",
  190 			},
  191 		},
  192 		{
  193 			"Home, no ext",
  194 			LayoutDescriptor{Kind: "home"},
  195 			"", noExt,
  196 			[]string{
  197 				"index.nex",
  198 				"home.nex",
  199 				"list.nex",
  200 				"_default/index.nex",
  201 				"_default/home.nex",
  202 				"_default/list.nex",
  203 			},
  204 		},
  205 		{
  206 			"Page, no ext or delim",
  207 			LayoutDescriptor{Kind: "page"},
  208 			"", noExtDelimFormat,
  209 			[]string{"_default/single.nem"},
  210 		},
  211 		{
  212 			"Section",
  213 			LayoutDescriptor{Kind: "section", Section: "sect1"},
  214 			"", ampType,
  215 			[]string{
  216 				"sect1/sect1.amp.html",
  217 				"sect1/section.amp.html",
  218 				"sect1/list.amp.html",
  219 				"sect1/sect1.html",
  220 				"sect1/section.html",
  221 				"sect1/list.html",
  222 				"section/sect1.amp.html",
  223 				"section/section.amp.html",
  224 				"section/list.amp.html",
  225 				"section/sect1.html",
  226 				"section/section.html",
  227 				"section/list.html",
  228 				"_default/sect1.amp.html",
  229 				"_default/section.amp.html",
  230 				"_default/list.amp.html",
  231 				"_default/sect1.html",
  232 				"_default/section.html",
  233 				"_default/list.html",
  234 			},
  235 		},
  236 		{
  237 			"Section, baseof",
  238 			LayoutDescriptor{Kind: "section", Section: "sect1", Baseof: true},
  239 			"", ampType,
  240 			[]string{
  241 				"sect1/sect1-baseof.amp.html",
  242 				"sect1/section-baseof.amp.html",
  243 				"sect1/list-baseof.amp.html",
  244 				"sect1/baseof.amp.html",
  245 				"sect1/sect1-baseof.html",
  246 				"sect1/section-baseof.html",
  247 				"sect1/list-baseof.html",
  248 				"sect1/baseof.html",
  249 				"section/sect1-baseof.amp.html",
  250 				"section/section-baseof.amp.html",
  251 				"section/list-baseof.amp.html",
  252 				"section/baseof.amp.html",
  253 				"section/sect1-baseof.html",
  254 				"section/section-baseof.html",
  255 				"section/list-baseof.html",
  256 				"section/baseof.html",
  257 				"_default/sect1-baseof.amp.html",
  258 				"_default/section-baseof.amp.html",
  259 				"_default/list-baseof.amp.html",
  260 				"_default/baseof.amp.html",
  261 				"_default/sect1-baseof.html",
  262 				"_default/section-baseof.html",
  263 				"_default/list-baseof.html",
  264 				"_default/baseof.html",
  265 			},
  266 		},
  267 		{
  268 			"Section, baseof, French, AMP",
  269 			LayoutDescriptor{Kind: "section", Section: "sect1", Lang: "fr", Baseof: true},
  270 			"", ampType,
  271 			[]string{
  272 				"sect1/sect1-baseof.fr.amp.html",
  273 				"sect1/section-baseof.fr.amp.html",
  274 				"sect1/list-baseof.fr.amp.html",
  275 				"sect1/baseof.fr.amp.html",
  276 				"sect1/sect1-baseof.amp.html",
  277 				"sect1/section-baseof.amp.html",
  278 				"sect1/list-baseof.amp.html",
  279 				"sect1/baseof.amp.html",
  280 				"sect1/sect1-baseof.fr.html",
  281 				"sect1/section-baseof.fr.html",
  282 				"sect1/list-baseof.fr.html",
  283 				"sect1/baseof.fr.html",
  284 				"sect1/sect1-baseof.html",
  285 				"sect1/section-baseof.html",
  286 				"sect1/list-baseof.html",
  287 				"sect1/baseof.html",
  288 				"section/sect1-baseof.fr.amp.html",
  289 				"section/section-baseof.fr.amp.html",
  290 				"section/list-baseof.fr.amp.html",
  291 				"section/baseof.fr.amp.html",
  292 				"section/sect1-baseof.amp.html",
  293 				"section/section-baseof.amp.html",
  294 				"section/list-baseof.amp.html",
  295 				"section/baseof.amp.html",
  296 				"section/sect1-baseof.fr.html",
  297 				"section/section-baseof.fr.html",
  298 				"section/list-baseof.fr.html",
  299 				"section/baseof.fr.html",
  300 				"section/sect1-baseof.html",
  301 				"section/section-baseof.html",
  302 				"section/list-baseof.html",
  303 				"section/baseof.html",
  304 				"_default/sect1-baseof.fr.amp.html",
  305 				"_default/section-baseof.fr.amp.html",
  306 				"_default/list-baseof.fr.amp.html",
  307 				"_default/baseof.fr.amp.html",
  308 				"_default/sect1-baseof.amp.html",
  309 				"_default/section-baseof.amp.html",
  310 				"_default/list-baseof.amp.html",
  311 				"_default/baseof.amp.html",
  312 				"_default/sect1-baseof.fr.html",
  313 				"_default/section-baseof.fr.html",
  314 				"_default/list-baseof.fr.html",
  315 				"_default/baseof.fr.html",
  316 				"_default/sect1-baseof.html",
  317 				"_default/section-baseof.html",
  318 				"_default/list-baseof.html",
  319 				"_default/baseof.html",
  320 			},
  321 		},
  322 		{
  323 			"Section with layout",
  324 			LayoutDescriptor{Kind: "section", Section: "sect1", Layout: "mylayout"},
  325 			"", ampType,
  326 			[]string{
  327 				"sect1/mylayout.amp.html",
  328 				"sect1/sect1.amp.html",
  329 				"sect1/section.amp.html",
  330 				"sect1/list.amp.html",
  331 				"sect1/mylayout.html",
  332 				"sect1/sect1.html",
  333 				"sect1/section.html",
  334 				"sect1/list.html",
  335 				"section/mylayout.amp.html",
  336 				"section/sect1.amp.html",
  337 				"section/section.amp.html",
  338 				"section/list.amp.html",
  339 				"section/mylayout.html",
  340 				"section/sect1.html",
  341 				"section/section.html",
  342 				"section/list.html",
  343 				"_default/mylayout.amp.html",
  344 				"_default/sect1.amp.html",
  345 				"_default/section.amp.html",
  346 				"_default/list.amp.html",
  347 				"_default/mylayout.html",
  348 				"_default/sect1.html",
  349 				"_default/section.html",
  350 				"_default/list.html",
  351 			},
  352 		},
  353 		{
  354 			"Term, French, AMP",
  355 			LayoutDescriptor{Kind: "term", Section: "tags", Lang: "fr"},
  356 			"", ampType,
  357 			[]string{
  358 				"term/term.fr.amp.html",
  359 				"term/tags.fr.amp.html",
  360 				"term/taxonomy.fr.amp.html",
  361 				"term/list.fr.amp.html",
  362 				"term/term.amp.html",
  363 				"term/tags.amp.html",
  364 				"term/taxonomy.amp.html",
  365 				"term/list.amp.html",
  366 				"term/term.fr.html",
  367 				"term/tags.fr.html",
  368 				"term/taxonomy.fr.html",
  369 				"term/list.fr.html",
  370 				"term/term.html",
  371 				"term/tags.html",
  372 				"term/taxonomy.html",
  373 				"term/list.html",
  374 				"taxonomy/term.fr.amp.html",
  375 				"taxonomy/tags.fr.amp.html",
  376 				"taxonomy/taxonomy.fr.amp.html",
  377 				"taxonomy/list.fr.amp.html",
  378 				"taxonomy/term.amp.html",
  379 				"taxonomy/tags.amp.html",
  380 				"taxonomy/taxonomy.amp.html",
  381 				"taxonomy/list.amp.html",
  382 				"taxonomy/term.fr.html",
  383 				"taxonomy/tags.fr.html",
  384 				"taxonomy/taxonomy.fr.html",
  385 				"taxonomy/list.fr.html",
  386 				"taxonomy/term.html",
  387 				"taxonomy/tags.html",
  388 				"taxonomy/taxonomy.html",
  389 				"taxonomy/list.html",
  390 				"tags/term.fr.amp.html",
  391 				"tags/tags.fr.amp.html",
  392 				"tags/taxonomy.fr.amp.html",
  393 				"tags/list.fr.amp.html",
  394 				"tags/term.amp.html",
  395 				"tags/tags.amp.html",
  396 				"tags/taxonomy.amp.html",
  397 				"tags/list.amp.html",
  398 				"tags/term.fr.html",
  399 				"tags/tags.fr.html",
  400 				"tags/taxonomy.fr.html",
  401 				"tags/list.fr.html",
  402 				"tags/term.html",
  403 				"tags/tags.html",
  404 				"tags/taxonomy.html",
  405 				"tags/list.html",
  406 				"_default/term.fr.amp.html",
  407 				"_default/tags.fr.amp.html",
  408 				"_default/taxonomy.fr.amp.html",
  409 				"_default/list.fr.amp.html",
  410 				"_default/term.amp.html",
  411 				"_default/tags.amp.html",
  412 				"_default/taxonomy.amp.html",
  413 				"_default/list.amp.html",
  414 				"_default/term.fr.html",
  415 				"_default/tags.fr.html",
  416 				"_default/taxonomy.fr.html",
  417 				"_default/list.fr.html",
  418 				"_default/term.html",
  419 				"_default/tags.html",
  420 				"_default/taxonomy.html",
  421 				"_default/list.html",
  422 			},
  423 		},
  424 		{
  425 			"Term, baseof, French, AMP",
  426 			LayoutDescriptor{Kind: "term", Section: "tags", Lang: "fr", Baseof: true},
  427 			"", ampType,
  428 			[]string{
  429 				"term/term-baseof.fr.amp.html",
  430 				"term/tags-baseof.fr.amp.html",
  431 				"term/taxonomy-baseof.fr.amp.html",
  432 				"term/list-baseof.fr.amp.html",
  433 				"term/baseof.fr.amp.html",
  434 				"term/term-baseof.amp.html",
  435 				"term/tags-baseof.amp.html",
  436 				"term/taxonomy-baseof.amp.html",
  437 				"term/list-baseof.amp.html",
  438 				"term/baseof.amp.html",
  439 				"term/term-baseof.fr.html",
  440 				"term/tags-baseof.fr.html",
  441 				"term/taxonomy-baseof.fr.html",
  442 				"term/list-baseof.fr.html",
  443 				"term/baseof.fr.html",
  444 				"term/term-baseof.html",
  445 				"term/tags-baseof.html",
  446 				"term/taxonomy-baseof.html",
  447 				"term/list-baseof.html",
  448 				"term/baseof.html",
  449 				"taxonomy/term-baseof.fr.amp.html",
  450 				"taxonomy/tags-baseof.fr.amp.html",
  451 				"taxonomy/taxonomy-baseof.fr.amp.html",
  452 				"taxonomy/list-baseof.fr.amp.html",
  453 				"taxonomy/baseof.fr.amp.html",
  454 				"taxonomy/term-baseof.amp.html",
  455 				"taxonomy/tags-baseof.amp.html",
  456 				"taxonomy/taxonomy-baseof.amp.html",
  457 				"taxonomy/list-baseof.amp.html",
  458 				"taxonomy/baseof.amp.html",
  459 				"taxonomy/term-baseof.fr.html",
  460 				"taxonomy/tags-baseof.fr.html",
  461 				"taxonomy/taxonomy-baseof.fr.html",
  462 				"taxonomy/list-baseof.fr.html",
  463 				"taxonomy/baseof.fr.html",
  464 				"taxonomy/term-baseof.html",
  465 				"taxonomy/tags-baseof.html",
  466 				"taxonomy/taxonomy-baseof.html",
  467 				"taxonomy/list-baseof.html",
  468 				"taxonomy/baseof.html",
  469 				"tags/term-baseof.fr.amp.html",
  470 				"tags/tags-baseof.fr.amp.html",
  471 				"tags/taxonomy-baseof.fr.amp.html",
  472 				"tags/list-baseof.fr.amp.html",
  473 				"tags/baseof.fr.amp.html",
  474 				"tags/term-baseof.amp.html",
  475 				"tags/tags-baseof.amp.html",
  476 				"tags/taxonomy-baseof.amp.html",
  477 				"tags/list-baseof.amp.html",
  478 				"tags/baseof.amp.html",
  479 				"tags/term-baseof.fr.html",
  480 				"tags/tags-baseof.fr.html",
  481 				"tags/taxonomy-baseof.fr.html",
  482 				"tags/list-baseof.fr.html",
  483 				"tags/baseof.fr.html",
  484 				"tags/term-baseof.html",
  485 				"tags/tags-baseof.html",
  486 				"tags/taxonomy-baseof.html",
  487 				"tags/list-baseof.html",
  488 				"tags/baseof.html",
  489 				"_default/term-baseof.fr.amp.html",
  490 				"_default/tags-baseof.fr.amp.html",
  491 				"_default/taxonomy-baseof.fr.amp.html",
  492 				"_default/list-baseof.fr.amp.html",
  493 				"_default/baseof.fr.amp.html",
  494 				"_default/term-baseof.amp.html",
  495 				"_default/tags-baseof.amp.html",
  496 				"_default/taxonomy-baseof.amp.html",
  497 				"_default/list-baseof.amp.html",
  498 				"_default/baseof.amp.html",
  499 				"_default/term-baseof.fr.html",
  500 				"_default/tags-baseof.fr.html",
  501 				"_default/taxonomy-baseof.fr.html",
  502 				"_default/list-baseof.fr.html",
  503 				"_default/baseof.fr.html",
  504 				"_default/term-baseof.html",
  505 				"_default/tags-baseof.html",
  506 				"_default/taxonomy-baseof.html",
  507 				"_default/list-baseof.html",
  508 				"_default/baseof.html",
  509 			},
  510 		},
  511 		{
  512 			"Term",
  513 			LayoutDescriptor{Kind: "term", Section: "tags"},
  514 			"", ampType,
  515 			[]string{
  516 				"term/term.amp.html",
  517 				"term/tags.amp.html",
  518 				"term/taxonomy.amp.html",
  519 				"term/list.amp.html",
  520 				"term/term.html",
  521 				"term/tags.html",
  522 				"term/taxonomy.html",
  523 				"term/list.html",
  524 				"taxonomy/term.amp.html",
  525 				"taxonomy/tags.amp.html",
  526 				"taxonomy/taxonomy.amp.html",
  527 				"taxonomy/list.amp.html",
  528 				"taxonomy/term.html",
  529 				"taxonomy/tags.html",
  530 				"taxonomy/taxonomy.html",
  531 				"taxonomy/list.html",
  532 				"tags/term.amp.html",
  533 				"tags/tags.amp.html",
  534 				"tags/taxonomy.amp.html",
  535 				"tags/list.amp.html",
  536 				"tags/term.html",
  537 				"tags/tags.html",
  538 				"tags/taxonomy.html",
  539 				"tags/list.html",
  540 				"_default/term.amp.html",
  541 				"_default/tags.amp.html",
  542 				"_default/taxonomy.amp.html",
  543 				"_default/list.amp.html",
  544 				"_default/term.html",
  545 				"_default/tags.html",
  546 				"_default/taxonomy.html",
  547 				"_default/list.html",
  548 			},
  549 		},
  550 		{
  551 			"Taxonomy",
  552 			LayoutDescriptor{Kind: "taxonomy", Section: "categories"},
  553 			"", ampType,
  554 			[]string{
  555 				"categories/categories.terms.amp.html",
  556 				"categories/terms.amp.html",
  557 				"categories/taxonomy.amp.html",
  558 				"categories/list.amp.html",
  559 				"categories/categories.terms.html",
  560 				"categories/terms.html",
  561 				"categories/taxonomy.html",
  562 				"categories/list.html",
  563 				"taxonomy/categories.terms.amp.html",
  564 				"taxonomy/terms.amp.html",
  565 				"taxonomy/taxonomy.amp.html",
  566 				"taxonomy/list.amp.html",
  567 				"taxonomy/categories.terms.html",
  568 				"taxonomy/terms.html",
  569 				"taxonomy/taxonomy.html",
  570 				"taxonomy/list.html",
  571 				"_default/categories.terms.amp.html",
  572 				"_default/terms.amp.html",
  573 				"_default/taxonomy.amp.html",
  574 				"_default/list.amp.html",
  575 				"_default/categories.terms.html",
  576 				"_default/terms.html",
  577 				"_default/taxonomy.html",
  578 				"_default/list.html",
  579 			},
  580 		},
  581 		{
  582 			"Page",
  583 			LayoutDescriptor{Kind: "page"},
  584 			"", ampType,
  585 			[]string{
  586 				"_default/single.amp.html",
  587 				"_default/single.html",
  588 			},
  589 		},
  590 		{
  591 			"Page, baseof",
  592 			LayoutDescriptor{Kind: "page", Baseof: true},
  593 			"", ampType,
  594 			[]string{
  595 				"_default/single-baseof.amp.html",
  596 				"_default/baseof.amp.html",
  597 				"_default/single-baseof.html",
  598 				"_default/baseof.html",
  599 			},
  600 		},
  601 		{
  602 			"Page with layout",
  603 			LayoutDescriptor{Kind: "page", Layout: "mylayout"},
  604 			"", ampType,
  605 			[]string{
  606 				"_default/mylayout.amp.html",
  607 				"_default/single.amp.html",
  608 				"_default/mylayout.html",
  609 				"_default/single.html",
  610 			},
  611 		},
  612 		{
  613 			"Page with layout, baseof",
  614 			LayoutDescriptor{Kind: "page", Layout: "mylayout", Baseof: true},
  615 			"", ampType,
  616 			[]string{
  617 				"_default/mylayout-baseof.amp.html",
  618 				"_default/single-baseof.amp.html",
  619 				"_default/baseof.amp.html",
  620 				"_default/mylayout-baseof.html",
  621 				"_default/single-baseof.html",
  622 				"_default/baseof.html",
  623 			},
  624 		},
  625 		{
  626 			"Page with layout and type",
  627 			LayoutDescriptor{Kind: "page", Layout: "mylayout", Type: "myttype"},
  628 			"", ampType,
  629 			[]string{
  630 				"myttype/mylayout.amp.html",
  631 				"myttype/single.amp.html",
  632 				"myttype/mylayout.html",
  633 				"myttype/single.html",
  634 				"_default/mylayout.amp.html",
  635 				"_default/single.amp.html",
  636 				"_default/mylayout.html",
  637 				"_default/single.html",
  638 			},
  639 		},
  640 		{
  641 			"Page baseof with layout and type",
  642 			LayoutDescriptor{Kind: "page", Layout: "mylayout", Type: "myttype", Baseof: true},
  643 			"", ampType,
  644 			[]string{
  645 				"myttype/mylayout-baseof.amp.html",
  646 				"myttype/single-baseof.amp.html",
  647 				"myttype/baseof.amp.html",
  648 				"myttype/mylayout-baseof.html",
  649 				"myttype/single-baseof.html",
  650 				"myttype/baseof.html",
  651 				"_default/mylayout-baseof.amp.html",
  652 				"_default/single-baseof.amp.html",
  653 				"_default/baseof.amp.html",
  654 				"_default/mylayout-baseof.html",
  655 				"_default/single-baseof.html",
  656 				"_default/baseof.html",
  657 			},
  658 		},
  659 		{
  660 			"Page baseof with layout and type in French",
  661 			LayoutDescriptor{Kind: "page", Layout: "mylayout", Type: "myttype", Lang: "fr", Baseof: true},
  662 			"", ampType,
  663 			[]string{
  664 				"myttype/mylayout-baseof.fr.amp.html",
  665 				"myttype/single-baseof.fr.amp.html",
  666 				"myttype/baseof.fr.amp.html",
  667 				"myttype/mylayout-baseof.amp.html",
  668 				"myttype/single-baseof.amp.html",
  669 				"myttype/baseof.amp.html",
  670 				"myttype/mylayout-baseof.fr.html",
  671 				"myttype/single-baseof.fr.html",
  672 				"myttype/baseof.fr.html",
  673 				"myttype/mylayout-baseof.html",
  674 				"myttype/single-baseof.html",
  675 				"myttype/baseof.html",
  676 				"_default/mylayout-baseof.fr.amp.html",
  677 				"_default/single-baseof.fr.amp.html",
  678 				"_default/baseof.fr.amp.html",
  679 				"_default/mylayout-baseof.amp.html",
  680 				"_default/single-baseof.amp.html",
  681 				"_default/baseof.amp.html",
  682 				"_default/mylayout-baseof.fr.html",
  683 				"_default/single-baseof.fr.html",
  684 				"_default/baseof.fr.html",
  685 				"_default/mylayout-baseof.html",
  686 				"_default/single-baseof.html",
  687 				"_default/baseof.html",
  688 			},
  689 		},
  690 		{
  691 			"Page with layout and type with subtype",
  692 			LayoutDescriptor{Kind: "page", Layout: "mylayout", Type: "myttype/mysubtype"},
  693 			"", ampType,
  694 			[]string{
  695 				"myttype/mysubtype/mylayout.amp.html",
  696 				"myttype/mysubtype/single.amp.html",
  697 				"myttype/mysubtype/mylayout.html",
  698 				"myttype/mysubtype/single.html",
  699 				"_default/mylayout.amp.html",
  700 				"_default/single.amp.html",
  701 				"_default/mylayout.html",
  702 				"_default/single.html",
  703 			},
  704 		},
  705 		// RSS
  706 		{
  707 			"RSS Home",
  708 			LayoutDescriptor{Kind: "home"},
  709 			"", RSSFormat,
  710 			[]string{
  711 				"index.rss.xml",
  712 				"home.rss.xml",
  713 				"rss.xml",
  714 				"list.rss.xml",
  715 				"index.xml",
  716 				"home.xml",
  717 				"list.xml",
  718 				"_default/index.rss.xml",
  719 				"_default/home.rss.xml",
  720 				"_default/rss.xml",
  721 				"_default/list.rss.xml",
  722 				"_default/index.xml",
  723 				"_default/home.xml",
  724 				"_default/list.xml",
  725 				"_internal/_default/rss.xml",
  726 			},
  727 		},
  728 		{
  729 			"RSS Home, baseof",
  730 			LayoutDescriptor{Kind: "home", Baseof: true},
  731 			"", RSSFormat,
  732 			[]string{
  733 				"index-baseof.rss.xml",
  734 				"home-baseof.rss.xml",
  735 				"list-baseof.rss.xml",
  736 				"baseof.rss.xml",
  737 				"index-baseof.xml",
  738 				"home-baseof.xml",
  739 				"list-baseof.xml",
  740 				"baseof.xml",
  741 				"_default/index-baseof.rss.xml",
  742 				"_default/home-baseof.rss.xml",
  743 				"_default/list-baseof.rss.xml",
  744 				"_default/baseof.rss.xml",
  745 				"_default/index-baseof.xml",
  746 				"_default/home-baseof.xml",
  747 				"_default/list-baseof.xml",
  748 				"_default/baseof.xml",
  749 			},
  750 		},
  751 		{
  752 			"RSS Section",
  753 			LayoutDescriptor{Kind: "section", Section: "sect1"},
  754 			"", RSSFormat,
  755 			[]string{
  756 				"sect1/sect1.rss.xml",
  757 				"sect1/section.rss.xml",
  758 				"sect1/rss.xml",
  759 				"sect1/list.rss.xml",
  760 				"sect1/sect1.xml",
  761 				"sect1/section.xml",
  762 				"sect1/list.xml",
  763 				"section/sect1.rss.xml",
  764 				"section/section.rss.xml",
  765 				"section/rss.xml",
  766 				"section/list.rss.xml",
  767 				"section/sect1.xml",
  768 				"section/section.xml",
  769 				"section/list.xml",
  770 				"_default/sect1.rss.xml",
  771 				"_default/section.rss.xml",
  772 				"_default/rss.xml",
  773 				"_default/list.rss.xml",
  774 				"_default/sect1.xml",
  775 				"_default/section.xml",
  776 				"_default/list.xml",
  777 				"_internal/_default/rss.xml",
  778 			},
  779 		},
  780 		{
  781 			"RSS Term",
  782 			LayoutDescriptor{Kind: "term", Section: "tag"},
  783 			"", RSSFormat,
  784 			[]string{
  785 				"term/term.rss.xml",
  786 				"term/tag.rss.xml",
  787 				"term/taxonomy.rss.xml",
  788 				"term/rss.xml",
  789 				"term/list.rss.xml",
  790 				"term/term.xml",
  791 				"term/tag.xml",
  792 				"term/taxonomy.xml",
  793 				"term/list.xml",
  794 				"taxonomy/term.rss.xml",
  795 				"taxonomy/tag.rss.xml",
  796 				"taxonomy/taxonomy.rss.xml",
  797 				"taxonomy/rss.xml",
  798 				"taxonomy/list.rss.xml",
  799 				"taxonomy/term.xml",
  800 				"taxonomy/tag.xml",
  801 				"taxonomy/taxonomy.xml",
  802 				"taxonomy/list.xml",
  803 				"tag/term.rss.xml",
  804 				"tag/tag.rss.xml",
  805 				"tag/taxonomy.rss.xml",
  806 				"tag/rss.xml",
  807 				"tag/list.rss.xml",
  808 				"tag/term.xml",
  809 				"tag/tag.xml",
  810 				"tag/taxonomy.xml",
  811 				"tag/list.xml",
  812 				"_default/term.rss.xml",
  813 				"_default/tag.rss.xml",
  814 				"_default/taxonomy.rss.xml",
  815 				"_default/rss.xml",
  816 				"_default/list.rss.xml",
  817 				"_default/term.xml",
  818 				"_default/tag.xml",
  819 				"_default/taxonomy.xml",
  820 				"_default/list.xml",
  821 				"_internal/_default/rss.xml",
  822 			},
  823 		},
  824 		{
  825 			"RSS Taxonomy",
  826 			LayoutDescriptor{Kind: "taxonomy", Section: "tag"},
  827 			"", RSSFormat,
  828 			[]string{
  829 				"tag/tag.terms.rss.xml",
  830 				"tag/terms.rss.xml",
  831 				"tag/taxonomy.rss.xml",
  832 				"tag/rss.xml",
  833 				"tag/list.rss.xml",
  834 				"tag/tag.terms.xml",
  835 				"tag/terms.xml",
  836 				"tag/taxonomy.xml",
  837 				"tag/list.xml",
  838 				"taxonomy/tag.terms.rss.xml",
  839 				"taxonomy/terms.rss.xml",
  840 				"taxonomy/taxonomy.rss.xml",
  841 				"taxonomy/rss.xml",
  842 				"taxonomy/list.rss.xml",
  843 				"taxonomy/tag.terms.xml",
  844 				"taxonomy/terms.xml",
  845 				"taxonomy/taxonomy.xml",
  846 				"taxonomy/list.xml",
  847 				"_default/tag.terms.rss.xml",
  848 				"_default/terms.rss.xml",
  849 				"_default/taxonomy.rss.xml",
  850 				"_default/rss.xml",
  851 				"_default/list.rss.xml",
  852 				"_default/tag.terms.xml",
  853 				"_default/terms.xml",
  854 				"_default/taxonomy.xml",
  855 				"_default/list.xml",
  856 				"_internal/_default/rss.xml",
  857 			},
  858 		},
  859 		{
  860 			"Home plain text",
  861 			LayoutDescriptor{Kind: "home"},
  862 			"", JSONFormat,
  863 			[]string{
  864 				"index.json.json",
  865 				"home.json.json",
  866 				"list.json.json",
  867 				"index.json",
  868 				"home.json",
  869 				"list.json",
  870 				"_default/index.json.json",
  871 				"_default/home.json.json",
  872 				"_default/list.json.json",
  873 				"_default/index.json",
  874 				"_default/home.json",
  875 				"_default/list.json",
  876 			},
  877 		},
  878 		{
  879 			"Page plain text",
  880 			LayoutDescriptor{Kind: "page"},
  881 			"", JSONFormat,
  882 			[]string{
  883 				"_default/single.json.json",
  884 				"_default/single.json",
  885 			},
  886 		},
  887 		{
  888 			"Reserved section, shortcodes",
  889 			LayoutDescriptor{Kind: "section", Section: "shortcodes", Type: "shortcodes"},
  890 			"", ampType,
  891 			[]string{
  892 				"section/shortcodes.amp.html",
  893 				"section/section.amp.html",
  894 				"section/list.amp.html",
  895 				"section/shortcodes.html",
  896 				"section/section.html",
  897 				"section/list.html",
  898 				"_default/shortcodes.amp.html",
  899 				"_default/section.amp.html",
  900 				"_default/list.amp.html",
  901 				"_default/shortcodes.html",
  902 				"_default/section.html",
  903 				"_default/list.html",
  904 			},
  905 		},
  906 		{
  907 			"Reserved section, partials",
  908 			LayoutDescriptor{Kind: "section", Section: "partials", Type: "partials"},
  909 			"", ampType,
  910 			[]string{
  911 				"section/partials.amp.html",
  912 				"section/section.amp.html",
  913 				"section/list.amp.html",
  914 				"section/partials.html",
  915 				"section/section.html",
  916 				"section/list.html",
  917 				"_default/partials.amp.html",
  918 				"_default/section.amp.html",
  919 				"_default/list.amp.html",
  920 				"_default/partials.html",
  921 				"_default/section.html",
  922 				"_default/list.html",
  923 			},
  924 		},
  925 		// This is currently always HTML only
  926 		{
  927 			"404, HTML",
  928 			LayoutDescriptor{Kind: "404"},
  929 			"", htmlFormat,
  930 			[]string{
  931 				"404.html.html",
  932 				"404.html",
  933 			},
  934 		},
  935 		{
  936 			"404, HTML baseof",
  937 			LayoutDescriptor{Kind: "404", Baseof: true},
  938 			"", htmlFormat,
  939 			[]string{
  940 				"404-baseof.html.html",
  941 				"baseof.html.html",
  942 				"404-baseof.html",
  943 				"baseof.html",
  944 				"_default/404-baseof.html.html",
  945 				"_default/baseof.html.html",
  946 				"_default/404-baseof.html",
  947 				"_default/baseof.html",
  948 			},
  949 		},
  950 		{
  951 			"Content hook",
  952 			LayoutDescriptor{Kind: "render-link", RenderingHook: true, Layout: "mylayout", Section: "blog"},
  953 			"", ampType,
  954 			[]string{
  955 				"blog/_markup/render-link.amp.html",
  956 				"blog/_markup/render-link.html",
  957 				"_default/_markup/render-link.amp.html",
  958 				"_default/_markup/render-link.html",
  959 			},
  960 		},
  961 	} {
  962 		c.Run(this.name, func(c *qt.C) {
  963 			l := NewLayoutHandler()
  964 
  965 			layouts, err := l.For(this.layoutDescriptor, this.format)
  966 
  967 			c.Assert(err, qt.IsNil)
  968 			c.Assert(layouts, qt.Not(qt.IsNil), qt.Commentf(this.layoutDescriptor.Kind))
  969 
  970 			if !reflect.DeepEqual(layouts, this.expect) {
  971 				r := strings.NewReplacer(
  972 					"[", "\t\"",
  973 					"]", "\",",
  974 					" ", "\",\n\t\"",
  975 				)
  976 				fmtGot := r.Replace(fmt.Sprintf("%v", layouts))
  977 				fmtExp := r.Replace(fmt.Sprintf("%v", this.expect))
  978 
  979 				c.Fatalf("got %d items, expected %d:\nGot:\n\t%v\nExpected:\n\t%v\nDiff:\n%s", len(layouts), len(this.expect), layouts, this.expect, diff.Diff(fmtExp, fmtGot))
  980 
  981 			}
  982 		})
  983 	}
  984 }
  985 
  986 func BenchmarkLayout(b *testing.B) {
  987 	descriptor := LayoutDescriptor{Kind: "taxonomy", Section: "categories"}
  988 	l := NewLayoutHandler()
  989 
  990 	for i := 0; i < b.N; i++ {
  991 		_, err := l.For(descriptor, HTMLFormat)
  992 		if err != nil {
  993 			panic(err)
  994 		}
  995 	}
  996 }
  997 
  998 func BenchmarkLayoutUncached(b *testing.B) {
  999 	for i := 0; i < b.N; i++ {
 1000 		descriptor := LayoutDescriptor{Kind: "taxonomy", Section: "categories"}
 1001 		l := NewLayoutHandler()
 1002 
 1003 		_, err := l.For(descriptor, HTMLFormat)
 1004 		if err != nil {
 1005 			panic(err)
 1006 		}
 1007 	}
 1008 }