1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-30 05:59:39 +02:00
sap-jenkins-library/cmd/npmExecuteLint_test.go
Kevin Hudemann 60fa1d5bbf
Add Java-/Typescript linting capabilities (#1636)
This change adds linting support for Java-/TypeScript projects based on the checkDefaultLint and checkUserLint steps from Cloud SDK Pipeline.

Following options are supported:

1. Define a linting script named ci-lint in the package.json file(s) of the project
2. Provide a configuration for ESLint as part of the project
3. If none of the above: ESLint is executed with a general purpose configuration.

Co-authored-by: Daniel Kurzynski <daniel.kurzynski@sap.com>
2020-06-22 10:12:28 +02:00

172 lines
7.7 KiB
Go

package cmd
import (
"errors"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/SAP/jenkins-library/pkg/npm"
"github.com/stretchr/testify/assert"
"path/filepath"
"testing"
)
type mockLintUtilsBundle struct {
*mock.FilesMock
execRunner *mock.ExecMockRunner
}
func (u *mockLintUtilsBundle) getExecRunner() execRunner {
return u.execRunner
}
func (u *mockLintUtilsBundle) getGeneralPurposeConfig(configURL string) {
u.AddFile(filepath.Join(".pipeline", ".eslintrc.json"), []byte(`abc`))
}
func newLintMockUtilsBundle() mockLintUtilsBundle {
utils := mockLintUtilsBundle{FilesMock: &mock.FilesMock{}, execRunner: &mock.ExecMockRunner{}}
return utils
}
func TestNpmExecuteLint(t *testing.T) {
t.Run("Call with ci-lint script and one package.json", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"scripts\": { \"ci-lint\": \"\" } }"))
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
config := npmExecuteLintOptions{}
npmExecutor := npmExecutorMock{utils: npmUtils, config: npmConfig{runScripts: []string{"ci-lint"}, runOptions: []string{"--silent"}}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
assert.NoError(t, err)
})
t.Run("Call default with ESLint config from user", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile(".eslintrc.json", []byte("{\"name\": \"Test\" }"))
config := npmExecuteLintOptions{}
config.DefaultNpmRegistry = "foo.bar"
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
npmExecutor := npm.Execute{Utils: &npmUtils, Options: npm.ExecutorOptions{}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
if assert.NoError(t, err) {
if assert.Equal(t, 3, len(lintUtils.execRunner.Calls)) {
assert.Equal(t, mock.ExecCall{Exec: "npx", Params: []string{"eslint", ".", "-f", "checkstyle", "-o", "./0_defaultlint.xml", "--ignore-pattern", "node_modules/", "--ignore-pattern", ".eslintrc.js"}}, lintUtils.execRunner.Calls[2])
}
}
})
t.Run("Call default with two ESLint configs from user", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile(".eslintrc.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile(filepath.Join("src", ".eslintrc.json"), []byte("{\"name\": \"Test\" }"))
config := npmExecuteLintOptions{}
config.DefaultNpmRegistry = "foo.bar"
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
npmExecutor := npm.Execute{Utils: &npmUtils, Options: npm.ExecutorOptions{}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
if assert.NoError(t, err) {
if assert.Equal(t, 4, len(lintUtils.execRunner.Calls)) {
assert.Equal(t, mock.ExecCall{Exec: "npx", Params: []string{"eslint", ".", "-f", "checkstyle", "-o", "./0_defaultlint.xml", "--ignore-pattern", "node_modules/", "--ignore-pattern", ".eslintrc.js"}}, lintUtils.execRunner.Calls[2])
assert.Equal(t, mock.ExecCall{Exec: "npx", Params: []string{"eslint", "src/**/*.js", "-f", "checkstyle", "-o", "./1_defaultlint.xml", "--ignore-pattern", "node_modules/", "--ignore-pattern", ".eslintrc.js"}}, lintUtils.execRunner.Calls[3])
}
}
})
t.Run("Default without ESLint config", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"name\": \"Test\" }"))
config := npmExecuteLintOptions{}
config.DefaultNpmRegistry = "foo.bar"
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
npmExecutor := npm.Execute{Utils: &npmUtils, Options: npm.ExecutorOptions{}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
if assert.NoError(t, err) {
if assert.Equal(t, 4, len(lintUtils.execRunner.Calls)) {
assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"install", "eslint@^7.0.0", "typescript@^3.7.4", "@typescript-eslint/parser@^3.0.0", "@typescript-eslint/eslint-plugin@^3.0.0"}}, lintUtils.execRunner.Calls[2])
assert.Equal(t, mock.ExecCall{Exec: "npx", Params: []string{"--no-install", "eslint", ".", "--ext", ".js,.jsx,.ts,.tsx", "-c", ".pipeline/.eslintrc.json", "-f", "checkstyle", "-o", "./defaultlint.xml", "--ignore-pattern", ".eslintrc.js"}}, lintUtils.execRunner.Calls[3])
}
}
})
t.Run("Call with ci-lint script and failOnError", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"scripts\": { \"ci-lint\": \"\" } }"))
lintUtils.execRunner = &mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"npm run ci-lint --silent": errors.New("exit 1")}}
config := npmExecuteLintOptions{}
config.FailOnError = true
config.DefaultNpmRegistry = "foo.bar"
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
npmUtils.FilesMock = lintUtils.FilesMock
npmExecutor := npm.Execute{Utils: &npmUtils, Options: npm.ExecutorOptions{}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
if assert.EqualError(t, err, "ci-lint script execution failed with error: failed to run npm script ci-lint: exit 1. This might be the result of severe linting findings, or some other issue while executing the script. Please examine the linting results in the UI, the cilint.xml file, if available, or the log above. ") {
if assert.Equal(t, 3, len(lintUtils.execRunner.Calls)) {
assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"run", "ci-lint", "--silent"}}, lintUtils.execRunner.Calls[2])
}
}
})
t.Run("Call default with ESLint config from user and failOnError", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile(".eslintrc.json", []byte("{\"name\": \"Test\" }"))
lintUtils.execRunner = &mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"eslint . -f checkstyle -o ./0_defaultlint.xml --ignore-pattern node_modules/ --ignore-pattern .eslintrc.js": errors.New("exit 1")}}
config := npmExecuteLintOptions{}
config.FailOnError = true
config.DefaultNpmRegistry = "foo.bar"
npmUtils := newNpmMockUtilsBundle()
npmUtils.execRunner = lintUtils.execRunner
npmExecutor := npm.Execute{Utils: &npmUtils, Options: npm.ExecutorOptions{}}
err := runNpmExecuteLint(&npmExecutor, &lintUtils, &config)
if assert.EqualError(t, err, "Lint execution failed. This might be the result of severe linting findings, problems with the provided ESLint configuration (.eslintrc.json), or another issue. Please examine the linting results in the UI or in 0_defaultlint.xml, if available, or the log above. ") {
if assert.Equal(t, 3, len(lintUtils.execRunner.Calls)) {
assert.Equal(t, mock.ExecCall{Exec: "npx", Params: []string{"eslint", ".", "-f", "checkstyle", "-o", "./0_defaultlint.xml", "--ignore-pattern", "node_modules/", "--ignore-pattern", ".eslintrc.js"}}, lintUtils.execRunner.Calls[2])
}
}
})
t.Run("Find ESLint configs", func(t *testing.T) {
lintUtils := newLintMockUtilsBundle()
lintUtils.AddFile("package.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile(".eslintrc.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile("src/.eslintrc.json", []byte("{\"name\": \"Test\" }"))
lintUtils.AddFile("node_modules/.eslintrc.json", []byte("{\"name\": \"Test\" }")) // should be filtered out
lintUtils.AddFile(".pipeline/.eslintrc.json", []byte("{\"name\": \"Test\" }")) // should be filtered out
eslintConfigs := findEslintConfigs(&lintUtils)
if assert.Equal(t, 2, len(eslintConfigs)) {
assert.Contains(t, eslintConfigs, ".eslintrc.json")
assert.Contains(t, eslintConfigs, filepath.Join("src", ".eslintrc.json"))
}
})
}