github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/resources/resource_transformers/postcss/integration_test.go (about) 1 // Copyright 2021 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_test 15 16 import ( 17 "fmt" 18 "path/filepath" 19 "strings" 20 "testing" 21 22 jww "github.com/spf13/jwalterweatherman" 23 24 qt "github.com/frankban/quicktest" 25 "github.com/gohugoio/hugo/htesting" 26 "github.com/gohugoio/hugo/hugofs" 27 "github.com/gohugoio/hugo/hugolib" 28 ) 29 30 const postCSSIntegrationTestFiles = ` 31 -- assets/css/components/a.css -- 32 /* A comment. */ 33 /* Another comment. */ 34 class-in-a { 35 color: blue; 36 } 37 38 -- assets/css/components/all.css -- 39 @import "a.css"; 40 @import "b.css"; 41 -- assets/css/components/b.css -- 42 @import "a.css"; 43 44 class-in-b { 45 color: blue; 46 } 47 48 -- assets/css/styles.css -- 49 @tailwind base; 50 @tailwind components; 51 @tailwind utilities; 52 @import "components/all.css"; 53 h1 { 54 @apply text-2xl font-bold; 55 } 56 57 -- config.toml -- 58 disablekinds = ['taxonomy', 'term', 'page'] 59 baseURL = "https://example.com" 60 [build] 61 useResourceCacheWhen = 'never' 62 -- content/p1.md -- 63 -- data/hugo.toml -- 64 slogan = "Hugo Rocks!" 65 -- i18n/en.yaml -- 66 hello: 67 other: "Hello" 68 -- i18n/fr.yaml -- 69 hello: 70 other: "Bonjour" 71 -- layouts/index.html -- 72 {{ $options := dict "inlineImports" true }} 73 {{ $styles := resources.Get "css/styles.css" | resources.PostCSS $options }} 74 Styles RelPermalink: {{ $styles.RelPermalink }} 75 {{ $cssContent := $styles.Content }} 76 Styles Content: Len: {{ len $styles.Content }}| 77 -- package.json -- 78 { 79 "scripts": {}, 80 81 "devDependencies": { 82 "postcss-cli": "7.1.0", 83 "tailwindcss": "1.2.0" 84 } 85 } 86 -- postcss.config.js -- 87 console.error("Hugo Environment:", process.env.HUGO_ENVIRONMENT ); 88 console.error("Hugo PublishDir:", process.env.HUGO_PUBLISHDIR ); 89 // https://github.com/gohugoio/hugo/issues/7656 90 console.error("package.json:", process.env.HUGO_FILE_PACKAGE_JSON ); 91 console.error("PostCSS Config File:", process.env.HUGO_FILE_POSTCSS_CONFIG_JS ); 92 93 module.exports = { 94 plugins: [ 95 require('tailwindcss') 96 ] 97 } 98 99 ` 100 101 func TestTransformPostCSS(t *testing.T) { 102 if !htesting.IsCI() { 103 t.Skip("Skip long running test when running locally") 104 } 105 106 c := qt.New(t) 107 tempDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-integration-test") 108 c.Assert(err, qt.IsNil) 109 c.Cleanup(clean) 110 111 for _, s := range []string{"never", "always"} { 112 113 repl := strings.NewReplacer( 114 "https://example.com", 115 "https://example.com/foo", 116 "useResourceCacheWhen = 'never'", 117 fmt.Sprintf("useResourceCacheWhen = '%s'", s), 118 ) 119 120 files := repl.Replace(postCSSIntegrationTestFiles) 121 122 b := hugolib.NewIntegrationTestBuilder( 123 hugolib.IntegrationTestConfig{ 124 T: c, 125 NeedsOsFS: true, 126 NeedsNpmInstall: true, 127 LogLevel: jww.LevelInfo, 128 WorkingDir: tempDir, 129 TxtarString: files, 130 }).Build() 131 132 b.AssertFileContent("public/index.html", ` 133 Styles RelPermalink: /foo/css/styles.css 134 Styles Content: Len: 770917| 135 `) 136 137 if s == "never" { 138 b.AssertLogContains("Hugo Environment: production") 139 b.AssertLogContains("Hugo PublishDir: " + filepath.Join(tempDir, "public")) 140 } 141 } 142 143 } 144 145 // 9880 146 func TestTransformPostCSSError(t *testing.T) { 147 if !htesting.IsCI() { 148 t.Skip("Skip long running test when running locally") 149 } 150 151 c := qt.New(t) 152 153 s, err := hugolib.NewIntegrationTestBuilder( 154 hugolib.IntegrationTestConfig{ 155 T: c, 156 NeedsOsFS: true, 157 NeedsNpmInstall: true, 158 TxtarString: strings.ReplaceAll(postCSSIntegrationTestFiles, "color: blue;", "@apply foo;"), // Syntax error 159 }).BuildE() 160 161 s.AssertIsFileError(err) 162 c.Assert(err.Error(), qt.Contains, "a.css:4:2") 163 164 } 165 166 // #9895 167 func TestTransformPostCSSImportError(t *testing.T) { 168 if !htesting.IsCI() { 169 t.Skip("Skip long running test when running locally") 170 } 171 172 c := qt.New(t) 173 174 s, err := hugolib.NewIntegrationTestBuilder( 175 hugolib.IntegrationTestConfig{ 176 T: c, 177 NeedsOsFS: true, 178 NeedsNpmInstall: true, 179 LogLevel: jww.LevelInfo, 180 TxtarString: strings.ReplaceAll(postCSSIntegrationTestFiles, `@import "components/all.css";`, `@import "components/doesnotexist.css";`), 181 }).BuildE() 182 183 s.AssertIsFileError(err) 184 c.Assert(err.Error(), qt.Contains, "styles.css:4:3") 185 c.Assert(err.Error(), qt.Contains, filepath.FromSlash(`failed to resolve CSS @import "css/components/doesnotexist.css"`)) 186 187 } 188 189 func TestTransformPostCSSImporSkipInlineImportsNotFound(t *testing.T) { 190 if !htesting.IsCI() { 191 t.Skip("Skip long running test when running locally") 192 } 193 194 c := qt.New(t) 195 196 files := strings.ReplaceAll(postCSSIntegrationTestFiles, `@import "components/all.css";`, `@import "components/doesnotexist.css";`) 197 files = strings.ReplaceAll(files, `{{ $options := dict "inlineImports" true }}`, `{{ $options := dict "inlineImports" true "skipInlineImportsNotFound" true }}`) 198 199 s := hugolib.NewIntegrationTestBuilder( 200 hugolib.IntegrationTestConfig{ 201 T: c, 202 NeedsOsFS: true, 203 NeedsNpmInstall: true, 204 LogLevel: jww.LevelInfo, 205 TxtarString: files, 206 }).Build() 207 208 s.AssertFileContent("public/css/styles.css", `@import "components/doesnotexist.css";`) 209 210 } 211 212 // Issue 9787 213 func TestTransformPostCSSResourceCacheWithPathInBaseURL(t *testing.T) { 214 if !htesting.IsCI() { 215 t.Skip("Skip long running test when running locally") 216 } 217 218 c := qt.New(t) 219 tempDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-integration-test") 220 c.Assert(err, qt.IsNil) 221 c.Cleanup(clean) 222 223 for i := 0; i < 2; i++ { 224 files := postCSSIntegrationTestFiles 225 226 if i == 1 { 227 files = strings.ReplaceAll(files, "https://example.com", "https://example.com/foo") 228 files = strings.ReplaceAll(files, "useResourceCacheWhen = 'never'", " useResourceCacheWhen = 'always'") 229 } 230 231 b := hugolib.NewIntegrationTestBuilder( 232 hugolib.IntegrationTestConfig{ 233 T: c, 234 NeedsOsFS: true, 235 NeedsNpmInstall: true, 236 LogLevel: jww.LevelInfo, 237 TxtarString: files, 238 WorkingDir: tempDir, 239 }).Build() 240 241 b.AssertFileContent("public/index.html", ` 242 Styles Content: Len: 770917 243 `) 244 245 } 246 247 }