github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/resources/resource_transformers/postcss/postcss_test.go (about)

     1  // Copyright 2020 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 postcss
    15  
    16  import (
    17  	"regexp"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/gohugoio/hugo/htesting/hqt"
    22  
    23  	"github.com/gohugoio/hugo/common/loggers"
    24  	"github.com/gohugoio/hugo/helpers"
    25  
    26  	"github.com/spf13/afero"
    27  
    28  	qt "github.com/frankban/quicktest"
    29  )
    30  
    31  // Issue 6166
    32  func TestDecodeOptions(t *testing.T) {
    33  	c := qt.New(t)
    34  	opts1, err := decodeOptions(map[string]any{
    35  		"no-map": true,
    36  	})
    37  
    38  	c.Assert(err, qt.IsNil)
    39  	c.Assert(opts1.NoMap, qt.Equals, true)
    40  
    41  	opts2, err := decodeOptions(map[string]any{
    42  		"noMap": true,
    43  	})
    44  
    45  	c.Assert(err, qt.IsNil)
    46  	c.Assert(opts2.NoMap, qt.Equals, true)
    47  }
    48  
    49  func TestShouldImport(t *testing.T) {
    50  	c := qt.New(t)
    51  	var imp *importResolver
    52  
    53  	for _, test := range []struct {
    54  		input  string
    55  		expect bool
    56  	}{
    57  		{input: `@import "navigation.css";`, expect: true},
    58  		{input: `@import "navigation.css"; /* Using a string */`, expect: true},
    59  		{input: `@import "navigation.css"`, expect: true},
    60  		{input: `@import 'navigation.css';`, expect: true},
    61  		{input: `@import url("navigation.css");`, expect: false},
    62  		{input: `@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,400i,800,800i&display=swap');`, expect: false},
    63  		{input: `@import "printstyle.css" print;`, expect: false},
    64  	} {
    65  		c.Assert(imp.shouldImport(test.input), qt.Equals, test.expect)
    66  	}
    67  }
    68  
    69  func TestImportResolver(t *testing.T) {
    70  	c := qt.New(t)
    71  	fs := afero.NewMemMapFs()
    72  
    73  	writeFile := func(name, content string) {
    74  		c.Assert(afero.WriteFile(fs, name, []byte(content), 0777), qt.IsNil)
    75  	}
    76  
    77  	writeFile("a.css", `@import "b.css";
    78  @import "c.css";
    79  A_STYLE1
    80  A_STYLE2
    81  `)
    82  
    83  	writeFile("b.css", `B_STYLE`)
    84  	writeFile("c.css", "@import \"d.css\"\nC_STYLE")
    85  	writeFile("d.css", "@import \"a.css\"\n\nD_STYLE")
    86  	writeFile("e.css", "E_STYLE")
    87  
    88  	mainStyles := strings.NewReader(`@import "a.css";
    89  @import "b.css";
    90  LOCAL_STYLE
    91  @import "c.css";
    92  @import "e.css";`)
    93  
    94  	imp := newImportResolver(
    95  		mainStyles,
    96  		"styles.css",
    97  		Options{},
    98  		fs, loggers.NewErrorLogger(),
    99  	)
   100  
   101  	r, err := imp.resolve()
   102  	c.Assert(err, qt.IsNil)
   103  	rs := helpers.ReaderToString(r)
   104  	result := regexp.MustCompile(`\n+`).ReplaceAllString(rs, "\n")
   105  
   106  	c.Assert(result, hqt.IsSameString, `B_STYLE
   107  D_STYLE
   108  C_STYLE
   109  A_STYLE1
   110  A_STYLE2
   111  LOCAL_STYLE
   112  E_STYLE`)
   113  
   114  	dline := imp.linemap[3]
   115  	c.Assert(dline, qt.DeepEquals, fileOffset{
   116  		Offset:   1,
   117  		Filename: "d.css",
   118  	})
   119  }
   120  
   121  func BenchmarkImportResolver(b *testing.B) {
   122  	c := qt.New(b)
   123  	fs := afero.NewMemMapFs()
   124  
   125  	writeFile := func(name, content string) {
   126  		c.Assert(afero.WriteFile(fs, name, []byte(content), 0777), qt.IsNil)
   127  	}
   128  
   129  	writeFile("a.css", `@import "b.css";
   130  @import "c.css";
   131  A_STYLE1
   132  A_STYLE2
   133  `)
   134  
   135  	writeFile("b.css", `B_STYLE`)
   136  	writeFile("c.css", "@import \"d.css\"\nC_STYLE"+strings.Repeat("\nSTYLE", 12))
   137  	writeFile("d.css", "@import \"a.css\"\n\nD_STYLE"+strings.Repeat("\nSTYLE", 55))
   138  	writeFile("e.css", "E_STYLE")
   139  
   140  	mainStyles := `@import "a.css";
   141  @import "b.css";
   142  LOCAL_STYLE
   143  @import "c.css";
   144  @import "e.css";
   145  @import "missing.css";`
   146  
   147  	logger := loggers.NewErrorLogger()
   148  
   149  	for i := 0; i < b.N; i++ {
   150  		b.StopTimer()
   151  		imp := newImportResolver(
   152  			strings.NewReader(mainStyles),
   153  			"styles.css",
   154  			Options{},
   155  			fs, logger,
   156  		)
   157  
   158  		b.StartTimer()
   159  
   160  		_, err := imp.resolve()
   161  		if err != nil {
   162  			b.Fatal(err)
   163  		}
   164  
   165  	}
   166  }