github.com/gohugoio/hugo@v0.88.1/hugolib/js_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 hugolib
    15  
    16  import (
    17  	"fmt"
    18  	"os"
    19  	"path/filepath"
    20  	"runtime"
    21  	"testing"
    22  
    23  	"github.com/gohugoio/hugo/common/hexec"
    24  	"github.com/gohugoio/hugo/config"
    25  
    26  	"github.com/gohugoio/hugo/htesting"
    27  
    28  	qt "github.com/frankban/quicktest"
    29  
    30  	"github.com/gohugoio/hugo/hugofs"
    31  
    32  	"github.com/gohugoio/hugo/common/loggers"
    33  )
    34  
    35  func TestJSBuildWithNPM(t *testing.T) {
    36  	if !htesting.IsCI() {
    37  		t.Skip("skip (relative) long running modules test when running locally")
    38  	}
    39  
    40  	wd, _ := os.Getwd()
    41  	defer func() {
    42  		os.Chdir(wd)
    43  	}()
    44  
    45  	c := qt.New(t)
    46  
    47  	mainJS := `
    48  	import "./included";
    49  	import { toCamelCase } from "to-camel-case";
    50  	
    51  	console.log("main");
    52  	console.log("To camel:", toCamelCase("space case"));
    53  `
    54  	includedJS := `
    55  	console.log("included");
    56  	
    57  	`
    58  
    59  	jsxContent := `
    60  import * as React from 'react'
    61  import * as ReactDOM from 'react-dom'
    62  
    63   ReactDOM.render(
    64     <h1>Hello, world!</h1>,
    65     document.getElementById('root')
    66   );
    67  `
    68  
    69  	tsContent := `function greeter(person: string) {
    70      return "Hello, " + person;
    71  }
    72  
    73  let user = [0, 1, 2];
    74  
    75  document.body.textContent = greeter(user);`
    76  
    77  	packageJSON := `{
    78    "scripts": {},
    79  
    80    "dependencies": {
    81      "to-camel-case": "1.0.0"
    82    }
    83  }
    84  `
    85  
    86  	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-test-js-npm")
    87  	c.Assert(err, qt.IsNil)
    88  	defer clean()
    89  
    90  	v := config.New()
    91  	v.Set("workingDir", workDir)
    92  	v.Set("disableKinds", []string{"taxonomy", "term", "page"})
    93  	b := newTestSitesBuilder(t).WithLogger(loggers.NewWarningLogger())
    94  
    95  	// Need to use OS fs for this.
    96  	b.Fs = hugofs.NewDefault(v)
    97  	b.WithWorkingDir(workDir)
    98  	b.WithViper(v)
    99  	b.WithContent("p1.md", "")
   100  
   101  	b.WithTemplates("index.html", `
   102  {{ $options := dict "minify" false "externals" (slice "react" "react-dom") }}
   103  {{ $js := resources.Get "js/main.js" | js.Build $options }}
   104  JS:  {{ template "print" $js }}
   105  {{ $jsx := resources.Get "js/myjsx.jsx" | js.Build $options }}
   106  JSX: {{ template "print" $jsx }}
   107  {{ $ts := resources.Get "js/myts.ts" | js.Build (dict "sourcemap" "inline")}}
   108  TS: {{ template "print" $ts }}
   109  {{ $ts2 := resources.Get "js/myts.ts" | js.Build (dict "sourcemap" "external" "TargetPath" "js/myts2.js")}}
   110  TS2: {{ template "print" $ts2 }}
   111  {{ define "print" }}RelPermalink: {{.RelPermalink}}|MIME: {{ .MediaType }}|Content: {{ .Content | safeJS }}{{ end }}
   112  
   113  `)
   114  
   115  	jsDir := filepath.Join(workDir, "assets", "js")
   116  	fmt.Println(workDir)
   117  	b.Assert(os.MkdirAll(jsDir, 0777), qt.IsNil)
   118  	b.Assert(os.Chdir(workDir), qt.IsNil)
   119  	b.WithSourceFile("package.json", packageJSON)
   120  	b.WithSourceFile("assets/js/main.js", mainJS)
   121  	b.WithSourceFile("assets/js/myjsx.jsx", jsxContent)
   122  	b.WithSourceFile("assets/js/myts.ts", tsContent)
   123  
   124  	b.WithSourceFile("assets/js/included.js", includedJS)
   125  
   126  	cmd, err := hexec.SafeCommand("npm", "install")
   127  	b.Assert(err, qt.IsNil)
   128  	out, err := cmd.CombinedOutput()
   129  	b.Assert(err, qt.IsNil, qt.Commentf(string(out)))
   130  
   131  	b.Build(BuildCfg{})
   132  
   133  	b.AssertFileContent("public/js/myts.js", `//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJz`)
   134  	b.AssertFileContent("public/js/myts2.js.map", `"version": 3,`)
   135  	b.AssertFileContent("public/index.html", `
   136  console.log(&#34;included&#34;);
   137  if (hasSpace.test(string))
   138  var React = __toModule(__require(&#34;react&#34;));
   139  function greeter(person) {
   140  `)
   141  }
   142  
   143  func TestJSBuild(t *testing.T) {
   144  	if !htesting.IsCI() {
   145  		t.Skip("skip (relative) long running modules test when running locally")
   146  	}
   147  
   148  	if runtime.GOOS == "windows" {
   149  		// TODO(bep) we really need to get this working on Travis.
   150  		t.Skip("skip npm test on Windows")
   151  	}
   152  
   153  	wd, _ := os.Getwd()
   154  	defer func() {
   155  		os.Chdir(wd)
   156  	}()
   157  
   158  	c := qt.New(t)
   159  
   160  	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-test-js-mod")
   161  	c.Assert(err, qt.IsNil)
   162  	defer clean()
   163  
   164  	tomlConfig := fmt.Sprintf(`
   165  baseURL = "https://example.org"
   166  workingDir = %q
   167  
   168  disableKinds = ["page", "section", "term", "taxonomy"]
   169  
   170  [module]
   171  [[module.imports]]
   172  path="github.com/gohugoio/hugoTestProjectJSModImports"
   173  
   174  
   175  
   176  `, workDir)
   177  
   178  	b := newTestSitesBuilder(t)
   179  	b.Fs = hugofs.NewDefault(config.New())
   180  	b.WithWorkingDir(workDir).WithConfigFile("toml", tomlConfig).WithLogger(loggers.NewInfoLogger())
   181  	b.WithSourceFile("go.mod", `module github.com/gohugoio/tests/testHugoModules
   182          
   183  go 1.15
   184          
   185  require github.com/gohugoio/hugoTestProjectJSModImports v0.9.0 // indirect
   186  
   187  `)
   188  
   189  	b.WithContent("p1.md", "").WithNothingAdded()
   190  
   191  	b.WithSourceFile("package.json", `{
   192   "dependencies": {
   193    "date-fns": "^2.16.1"
   194   }
   195  }`)
   196  
   197  	b.Assert(os.Chdir(workDir), qt.IsNil)
   198  	cmd, _ := hexec.SafeCommand("npm", "install")
   199  	_, err = cmd.CombinedOutput()
   200  	b.Assert(err, qt.IsNil)
   201  
   202  	b.Build(BuildCfg{})
   203  
   204  	b.AssertFileContent("public/js/main.js", `
   205  greeting: "greeting configured in mod2"
   206  Hello1 from mod1: $
   207  return "Hello2 from mod1";
   208  var Hugo = "Rocks!";
   209  Hello3 from mod2. Date from date-fns: ${today}
   210  Hello from lib in the main project
   211  Hello5 from mod2.
   212  var myparam = "Hugo Rocks!";
   213  shim cwd
   214  `)
   215  
   216  	// React JSX, verify the shimming.
   217  	b.AssertFileContent("public/js/like.js", `@v0.9.0/assets/js/shims/react.js
   218  module.exports = window.ReactDOM;
   219  `)
   220  }