hugo

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

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

minifiers_test.go (6941B)

    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 minifiers
   15 
   16 import (
   17 	"bytes"
   18 	"encoding/json"
   19 	"strings"
   20 	"testing"
   21 
   22 	qt "github.com/frankban/quicktest"
   23 	"github.com/gohugoio/hugo/config"
   24 	"github.com/gohugoio/hugo/media"
   25 	"github.com/gohugoio/hugo/output"
   26 	"github.com/tdewolff/minify/v2/html"
   27 )
   28 
   29 func TestNew(t *testing.T) {
   30 	c := qt.New(t)
   31 	v := config.NewWithTestDefaults()
   32 	m, _ := New(media.DefaultTypes, output.DefaultFormats, v)
   33 
   34 	var rawJS string
   35 	var minJS string
   36 	rawJS = " var  foo =1 ;   foo ++  ;  "
   37 	minJS = "var foo=1;foo++"
   38 
   39 	var rawJSON string
   40 	var minJSON string
   41 	rawJSON = "  { \"a\" : 123 , \"b\":2,  \"c\": 5 } "
   42 	minJSON = "{\"a\":123,\"b\":2,\"c\":5}"
   43 
   44 	for _, test := range []struct {
   45 		tp                media.Type
   46 		rawString         string
   47 		expectedMinString string
   48 	}{
   49 		{media.CSSType, " body { color: blue; }  ", "body{color:blue}"},
   50 		{media.RSSType, " <hello>  Hugo!   </hello>  ", "<hello>Hugo!</hello>"}, // RSS should be handled as XML
   51 		{media.JSONType, rawJSON, minJSON},
   52 		{media.JavascriptType, rawJS, minJS},
   53 		// JS Regex minifiers
   54 		{media.Type{MainType: "application", SubType: "ecmascript"}, rawJS, minJS},
   55 		{media.Type{MainType: "application", SubType: "javascript"}, rawJS, minJS},
   56 		{media.Type{MainType: "application", SubType: "x-javascript"}, rawJS, minJS},
   57 		{media.Type{MainType: "application", SubType: "x-ecmascript"}, rawJS, minJS},
   58 		{media.Type{MainType: "text", SubType: "ecmascript"}, rawJS, minJS},
   59 		{media.Type{MainType: "text", SubType: "javascript"}, rawJS, minJS},
   60 		{media.Type{MainType: "text", SubType: "x-javascript"}, rawJS, minJS},
   61 		{media.Type{MainType: "text", SubType: "x-ecmascript"}, rawJS, minJS},
   62 		// JSON Regex minifiers
   63 		{media.Type{MainType: "application", SubType: "json"}, rawJSON, minJSON},
   64 		{media.Type{MainType: "application", SubType: "x-json"}, rawJSON, minJSON},
   65 		{media.Type{MainType: "application", SubType: "ld+json"}, rawJSON, minJSON},
   66 		{media.Type{MainType: "text", SubType: "json"}, rawJSON, minJSON},
   67 		{media.Type{MainType: "text", SubType: "x-json"}, rawJSON, minJSON},
   68 		{media.Type{MainType: "text", SubType: "ld+json"}, rawJSON, minJSON},
   69 	} {
   70 		var b bytes.Buffer
   71 
   72 		c.Assert(m.Minify(test.tp, &b, strings.NewReader(test.rawString)), qt.IsNil)
   73 		c.Assert(b.String(), qt.Equals, test.expectedMinString)
   74 	}
   75 }
   76 
   77 func TestConfigureMinify(t *testing.T) {
   78 	c := qt.New(t)
   79 	v := config.NewWithTestDefaults()
   80 	v.Set("minify", map[string]any{
   81 		"disablexml": true,
   82 		"tdewolff": map[string]any{
   83 			"html": map[string]any{
   84 				"keepwhitespace": true,
   85 			},
   86 		},
   87 	})
   88 	m, _ := New(media.DefaultTypes, output.DefaultFormats, v)
   89 
   90 	for _, test := range []struct {
   91 		tp                media.Type
   92 		rawString         string
   93 		expectedMinString string
   94 		errorExpected     bool
   95 	}{
   96 		{media.HTMLType, "<hello> Hugo! </hello>", "<hello> Hugo! </hello>", false},            // configured minifier
   97 		{media.CSSType, " body { color: blue; }  ", "body{color:blue}", false},                 // default minifier
   98 		{media.XMLType, " <hello>  Hugo!   </hello>  ", " <hello>  Hugo!   </hello>  ", false}, // disable Xml minification
   99 	} {
  100 		var b bytes.Buffer
  101 		if !test.errorExpected {
  102 			c.Assert(m.Minify(test.tp, &b, strings.NewReader(test.rawString)), qt.IsNil)
  103 			c.Assert(b.String(), qt.Equals, test.expectedMinString)
  104 		} else {
  105 			err := m.Minify(test.tp, &b, strings.NewReader(test.rawString))
  106 			c.Assert(err, qt.ErrorMatches, "minifier does not exist for mimetype")
  107 		}
  108 	}
  109 }
  110 
  111 func TestJSONRoundTrip(t *testing.T) {
  112 	c := qt.New(t)
  113 	v := config.NewWithTestDefaults()
  114 	m, _ := New(media.DefaultTypes, output.DefaultFormats, v)
  115 
  116 	for _, test := range []string{`{
  117     "glossary": {
  118         "title": "example glossary",
  119 		"GlossDiv": {
  120             "title": "S",
  121 			"GlossList": {
  122                 "GlossEntry": {
  123                     "ID": "SGML",
  124 					"SortAs": "SGML",
  125 					"GlossTerm": "Standard Generalized Markup Language",
  126 					"Acronym": "SGML",
  127 					"Abbrev": "ISO 8879:1986",
  128 					"GlossDef": {
  129                         "para": "A meta-markup language, used to create markup languages such as DocBook.",
  130 						"GlossSeeAlso": ["GML", "XML"]
  131                     },
  132 					"GlossSee": "markup"
  133                 }
  134             }
  135         }
  136     }
  137 }`} {
  138 
  139 		var b bytes.Buffer
  140 		m1 := make(map[string]any)
  141 		m2 := make(map[string]any)
  142 		c.Assert(json.Unmarshal([]byte(test), &m1), qt.IsNil)
  143 		c.Assert(m.Minify(media.JSONType, &b, strings.NewReader(test)), qt.IsNil)
  144 		c.Assert(json.Unmarshal(b.Bytes(), &m2), qt.IsNil)
  145 		c.Assert(m1, qt.DeepEquals, m2)
  146 	}
  147 }
  148 
  149 func TestBugs(t *testing.T) {
  150 	c := qt.New(t)
  151 	v := config.NewWithTestDefaults()
  152 	m, _ := New(media.DefaultTypes, output.DefaultFormats, v)
  153 
  154 	for _, test := range []struct {
  155 		tp                media.Type
  156 		rawString         string
  157 		expectedMinString string
  158 	}{
  159 		// https://github.com/gohugoio/hugo/issues/5506
  160 		{media.CSSType, " body { color: rgba(000, 000, 000, 0.7); }", "body{color:rgba(0,0,0,.7)}"},
  161 		// https://github.com/gohugoio/hugo/issues/8332
  162 		{media.HTMLType, "<i class='fas fa-tags fa-fw'></i> Tags", `<i class='fas fa-tags fa-fw'></i> Tags`},
  163 	} {
  164 		var b bytes.Buffer
  165 
  166 		c.Assert(m.Minify(test.tp, &b, strings.NewReader(test.rawString)), qt.IsNil)
  167 		c.Assert(b.String(), qt.Equals, test.expectedMinString)
  168 	}
  169 }
  170 
  171 // Renamed to Precision in v2.7.0. Check that we support both.
  172 func TestDecodeConfigDecimalIsNowPrecision(t *testing.T) {
  173 	c := qt.New(t)
  174 	v := config.NewWithTestDefaults()
  175 	v.Set("minify", map[string]any{
  176 		"disablexml": true,
  177 		"tdewolff": map[string]any{
  178 			"css": map[string]any{
  179 				"decimal": 3,
  180 			},
  181 			"svg": map[string]any{
  182 				"decimal": 3,
  183 			},
  184 		},
  185 	})
  186 
  187 	conf, err := decodeConfig(v)
  188 
  189 	c.Assert(err, qt.IsNil)
  190 	c.Assert(conf.Tdewolff.CSS.Precision, qt.Equals, 3)
  191 
  192 }
  193 
  194 // Issue 9456
  195 func TestDecodeConfigKeepWhitespace(t *testing.T) {
  196 	c := qt.New(t)
  197 	v := config.NewWithTestDefaults()
  198 	v.Set("minify", map[string]any{
  199 		"tdewolff": map[string]any{
  200 			"html": map[string]any{
  201 				"keepEndTags": false,
  202 			},
  203 		},
  204 	})
  205 
  206 	conf, err := decodeConfig(v)
  207 
  208 	c.Assert(err, qt.IsNil)
  209 	c.Assert(conf.Tdewolff.HTML, qt.DeepEquals,
  210 		html.Minifier{
  211 			KeepComments:            false,
  212 			KeepConditionalComments: true,
  213 			KeepDefaultAttrVals:     true,
  214 			KeepDocumentTags:        true,
  215 			KeepEndTags:             false,
  216 			KeepQuotes:              false,
  217 			KeepWhitespace:          false},
  218 	)
  219 
  220 }