postcss_test.go (3841B)
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 }