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