blob: 5832898369f76aed554c177cc51314279711a8da [file] [edit]
// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package checks
import (
"io/ioutil"
"os"
"path/filepath"
"sort"
"testing"
"time"
"github.com/maruel/pre-commit-go/internal"
"github.com/maruel/pre-commit-go/scm"
"github.com/maruel/ut"
)
func TestCheckPrerequisite(t *testing.T) {
// Runs all checks, they should all pass.
t.Parallel()
ut.AssertEqual(t, true, (&CheckPrerequisite{HelpCommand: []string{"go", "version"}, ExpectedExitCode: 0}).IsPresent())
ut.AssertEqual(t, false, (&CheckPrerequisite{HelpCommand: []string{"go", "version"}, ExpectedExitCode: 1}).IsPresent())
}
func TestChecksSuccess(t *testing.T) {
// Runs all checks, they should all pass.
t.Parallel()
if testing.Short() {
t.SkipNow()
}
td, err := ioutil.TempDir("", "pre-commit-go")
ut.AssertEqual(t, nil, err)
defer func() {
if err := internal.RemoveAll(td); err != nil {
t.Fail()
}
}()
change := setup(t, td, goodFiles)
for _, name := range getKnownChecks() {
c := KnownChecks[name]()
switch name {
case "custom":
c = &Custom{
Description: "foo",
Command: []string{"go", "version"},
CheckExitCode: true,
Prerequisites: []CheckPrerequisite{
{
HelpCommand: []string{"go", "version"},
ExpectedExitCode: 0,
URL: "example.com.local",
},
},
}
case "copyright":
cop := c.(*Copyright)
cop.Header = "// Foo"
case "coverage":
cov := c.(*Coverage)
cov.Global.MinCoverage = 100
cov.Global.MaxCoverage = 100
cov.PerDirDefault.MinCoverage = 100
cov.PerDirDefault.MaxCoverage = 100
}
if err := c.Run(change, &Options{MaxDuration: 1}); err != nil {
t.Errorf("%s failed: %s", c.GetName(), err)
}
}
}
func TestChecksFailure(t *testing.T) {
// Runs all checks, they should all fail.
t.Parallel()
if testing.Short() {
t.SkipNow()
}
td, err := ioutil.TempDir("", "pre-commit-go")
ut.AssertEqual(t, nil, err)
defer func() {
if err := internal.RemoveAll(td); err != nil {
t.Fail()
}
}()
change := setup(t, td, badFiles)
for _, name := range getKnownChecks() {
c := KnownChecks[name]()
switch name {
case "build":
// This check is obsolete.
continue
case "custom":
c = &Custom{
Description: "foo",
Command: []string{"go", "invalid"},
CheckExitCode: true,
Prerequisites: []CheckPrerequisite{
{
HelpCommand: []string{"go", "version"},
ExpectedExitCode: 0,
URL: "example.com.local",
},
},
}
case "copyright":
cop := c.(*Copyright)
cop.Header = "// Expected header"
case "coverage":
cov := c.(*Coverage)
cov.Global.MinCoverage = 100
cov.Global.MaxCoverage = 100
cov.PerDirDefault.MinCoverage = 100
cov.PerDirDefault.MaxCoverage = 100
}
if err := c.Run(change, &Options{MaxDuration: 1}); err == nil {
t.Errorf("%s didn't fail but was expected to", c.GetName())
}
}
}
func TestChecksDescriptions(t *testing.T) {
t.Parallel()
for _, name := range getKnownChecks() {
c := KnownChecks[name]()
ut.AssertEqual(t, true, c.GetDescription() != "")
c.GetPrerequisites()
}
}
func TestCustom(t *testing.T) {
t.Parallel()
p := []CheckPrerequisite{
{
HelpCommand: []string{"go", "version"},
ExpectedExitCode: 0,
URL: "example.com.local",
},
}
c := &Custom{
Description: "foo",
Command: []string{"go", "version"},
Prerequisites: p,
}
ut.AssertEqual(t, "foo", c.GetDescription())
ut.AssertEqual(t, p, c.GetPrerequisites())
}
// Private stuff.
// This set of files passes all the tests.
var goodFiles = map[string]string{
"foo.go": `// Foo
package foo
// Foo returns 1.
func Foo() int {
return 1
}
`,
"foo_test.go": `// Foo
package foo
import "testing"
func TestSuccess(t *testing.T) {
if Foo() != 1 {
t.Fail()
}
}
`,
}
// This set of files fails all the tests.
var badFiles = map[string]string{
"foo.go": "// Foo\n\n// +build: incorrect\n\npackage foo\n" + `
import "errors"
// bad description.
func MissingDesc() {
// Error starts with upper case and ends with a dot.
return errors.New("Bad error.")
}
func main() {
}
`,
"foo_test.go": `// Foo
package foo
import "testing"
func TestFail(t *testing.T) {
t.Fail()
}
`,
}
func init() {
if IsContinuousIntegration() {
// The reason it's being done is that "go test" starts before prerequisites
// are installed. But since we are testing prerequisites, this runs in
// conflict. Wait for prerequisites to be installed.
loop := true
for loop {
loop = false
for _, name := range getKnownChecks() {
for _, p := range KnownChecks[name]().GetPrerequisites() {
if !p.IsPresent() {
time.Sleep(10 * time.Millisecond)
loop = true
break
}
}
}
}
}
}
func setup(t *testing.T, td string, files map[string]string) scm.Change {
fooDir := filepath.Join(td, "src", "foo")
ut.AssertEqual(t, nil, os.MkdirAll(fooDir, 0700))
for f, c := range files {
p := filepath.Join(fooDir, f)
ut.AssertEqual(t, nil, os.MkdirAll(filepath.Dir(p), 0700))
ut.AssertEqual(t, nil, ioutil.WriteFile(p, []byte(c), 0600))
}
out, code, err := internal.Capture(fooDir, nil, "git", "init")
ut.AssertEqualf(t, 0, code, out)
ut.AssertEqual(t, nil, err)
// It's important to add the files to the index, otherwise they will be
// ignored.
out, code, err = internal.Capture(fooDir, nil, "git", "add", ".")
ut.AssertEqualf(t, 0, code, out)
ut.AssertEqual(t, nil, err)
repo, err := scm.GetRepo(fooDir, td)
ut.AssertEqual(t, nil, err)
change, err := repo.Between(scm.Current, scm.Initial, nil)
ut.AssertEqual(t, nil, err)
ut.AssertEqual(t, true, change != nil)
return change
}
func getKnownChecks() []string {
names := make([]string, 0, len(KnownChecks))
for name := range KnownChecks {
names = append(names, name)
}
sort.Strings(names)
return names
}