github.com/neohugo/neohugo@v0.123.8/resources/resource_transformers/postcss/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  	"runtime"
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/bep/logg"
    24  	qt "github.com/frankban/quicktest"
    25  	"github.com/neohugo/neohugo/htesting"
    26  	"github.com/neohugo/neohugo/hugofs"
    27  	"github.com/neohugo/neohugo/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:        logg.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  // 9880
   145  func TestTransformPostCSSError(t *testing.T) {
   146  	if !htesting.IsCI() {
   147  		t.Skip("Skip long running test when running locally")
   148  	}
   149  
   150  	if runtime.GOOS == "windows" {
   151  		// TODO(bep) This has started to fail on Windows with Go 1.19 on GitHub Actions for some mysterious reason.
   152  		t.Skip("Skip on Windows")
   153  	}
   154  
   155  	c := qt.New(t)
   156  
   157  	s, err := hugolib.NewIntegrationTestBuilder(
   158  		hugolib.IntegrationTestConfig{
   159  			T:               c,
   160  			NeedsOsFS:       true,
   161  			NeedsNpmInstall: true,
   162  			TxtarString:     strings.ReplaceAll(postCSSIntegrationTestFiles, "color: blue;", "@apply foo;"), // Syntax error
   163  		}).BuildE()
   164  
   165  	//nolint
   166  	s.AssertIsFileError(err)
   167  	c.Assert(err.Error(), qt.Contains, "a.css:4:2")
   168  }
   169  
   170  func TestTransformPostCSSNotInstalledError(t *testing.T) {
   171  	if !htesting.IsCI() {
   172  		t.Skip("Skip long running test when running locally")
   173  	}
   174  
   175  	c := qt.New(t)
   176  
   177  	s, err := hugolib.NewIntegrationTestBuilder(
   178  		hugolib.IntegrationTestConfig{
   179  			T:           c,
   180  			NeedsOsFS:   true,
   181  			TxtarString: postCSSIntegrationTestFiles,
   182  		}).BuildE()
   183  
   184  	s.AssertIsFileError(err) // nolint
   185  	c.Assert(err.Error(), qt.Contains, `binary with name "npx" not found`)
   186  }
   187  
   188  // #9895
   189  func TestTransformPostCSSImportError(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  	s, err := hugolib.NewIntegrationTestBuilder(
   197  		hugolib.IntegrationTestConfig{
   198  			T:               c,
   199  			NeedsOsFS:       true,
   200  			NeedsNpmInstall: true,
   201  			LogLevel:        logg.LevelInfo,
   202  			TxtarString:     strings.ReplaceAll(postCSSIntegrationTestFiles, `@import "components/all.css";`, `@import "components/doesnotexist.css";`),
   203  		}).BuildE()
   204  
   205  	//nolint
   206  	s.AssertIsFileError(err)
   207  	c.Assert(err.Error(), qt.Contains, "styles.css:4:3")
   208  	c.Assert(err.Error(), qt.Contains, filepath.FromSlash(`failed to resolve CSS @import "/css/components/doesnotexist.css"`))
   209  }
   210  
   211  func TestTransformPostCSSImporSkipInlineImportsNotFound(t *testing.T) {
   212  	if !htesting.IsCI() {
   213  		t.Skip("Skip long running test when running locally")
   214  	}
   215  
   216  	c := qt.New(t)
   217  
   218  	files := strings.ReplaceAll(postCSSIntegrationTestFiles, `@import "components/all.css";`, `@import "components/doesnotexist.css";`)
   219  	files = strings.ReplaceAll(files, `{{ $options := dict "inlineImports" true }}`, `{{ $options := dict "inlineImports" true "skipInlineImportsNotFound" true }}`)
   220  
   221  	s := hugolib.NewIntegrationTestBuilder(
   222  		hugolib.IntegrationTestConfig{
   223  			T:               c,
   224  			NeedsOsFS:       true,
   225  			NeedsNpmInstall: true,
   226  			LogLevel:        logg.LevelInfo,
   227  			TxtarString:     files,
   228  		}).Build()
   229  
   230  	s.AssertFileContent("public/css/styles.css", `@import "components/doesnotexist.css";`)
   231  }
   232  
   233  // Issue 9787
   234  func TestTransformPostCSSResourceCacheWithPathInBaseURL(t *testing.T) {
   235  	if !htesting.IsCI() {
   236  		t.Skip("Skip long running test when running locally")
   237  	}
   238  
   239  	c := qt.New(t)
   240  	tempDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-integration-test")
   241  	c.Assert(err, qt.IsNil)
   242  	c.Cleanup(clean)
   243  
   244  	for i := 0; i < 2; i++ {
   245  		files := postCSSIntegrationTestFiles
   246  
   247  		if i == 1 {
   248  			files = strings.ReplaceAll(files, "https://example.com", "https://example.com/foo")
   249  			files = strings.ReplaceAll(files, "useResourceCacheWhen = 'never'", "	useResourceCacheWhen = 'always'")
   250  		}
   251  
   252  		b := hugolib.NewIntegrationTestBuilder(
   253  			hugolib.IntegrationTestConfig{
   254  				T:               c,
   255  				NeedsOsFS:       true,
   256  				NeedsNpmInstall: true,
   257  				LogLevel:        logg.LevelInfo,
   258  				TxtarString:     files,
   259  				WorkingDir:      tempDir,
   260  			}).Build()
   261  
   262  		b.AssertFileContent("public/index.html", `
   263  Styles Content: Len: 770917
   264  `)
   265  
   266  	}
   267  }