2017-03-16 02:15:27 +02:00
|
|
|
package task_test
|
|
|
|
|
|
|
|
import (
|
2017-05-17 19:37:11 +02:00
|
|
|
"bytes"
|
2017-07-12 11:30:28 +02:00
|
|
|
"fmt"
|
2017-03-25 15:51:30 +02:00
|
|
|
"io/ioutil"
|
2017-03-16 02:15:27 +02:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2017-03-25 15:51:30 +02:00
|
|
|
"strings"
|
2017-03-16 02:15:27 +02:00
|
|
|
"testing"
|
2017-06-16 16:24:01 +02:00
|
|
|
|
|
|
|
"github.com/go-task/task"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2017-03-16 02:15:27 +02:00
|
|
|
)
|
|
|
|
|
2017-07-20 09:05:37 +02:00
|
|
|
// fileContentTest provides a basic reusable test-case for running a Taskfile
|
|
|
|
// and inspect generated files.
|
|
|
|
type fileContentTest struct {
|
|
|
|
Dir string
|
|
|
|
Target string
|
|
|
|
TrimSpace bool
|
|
|
|
Files map[string]string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fct fileContentTest) name(file string) string {
|
|
|
|
return fmt.Sprintf("target=%q,file=%q", fct.Target, file)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fct fileContentTest) Run(t *testing.T) {
|
|
|
|
for f := range fct.Files {
|
|
|
|
_ = os.Remove(filepath.Join(fct.Dir, f))
|
|
|
|
}
|
|
|
|
|
|
|
|
e := &task.Executor{
|
|
|
|
Dir: fct.Dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
|
|
|
}
|
|
|
|
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
|
|
|
|
assert.NoError(t, e.Run(fct.Target), "e.Run(target)")
|
|
|
|
|
|
|
|
for name, expectContent := range fct.Files {
|
|
|
|
t.Run(fct.name(name), func(t *testing.T) {
|
|
|
|
b, err := ioutil.ReadFile(filepath.Join(fct.Dir, name))
|
|
|
|
assert.NoError(t, err, "Error reading file")
|
|
|
|
s := string(b)
|
|
|
|
if fct.TrimSpace {
|
|
|
|
s = strings.TrimSpace(s)
|
|
|
|
}
|
|
|
|
assert.Equal(t, expectContent, s, "unexpected file content")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-08-16 13:04:58 +02:00
|
|
|
func TestEnv(t *testing.T) {
|
|
|
|
tt := fileContentTest{
|
|
|
|
Dir: "testdata/env",
|
|
|
|
Target: "default",
|
|
|
|
TrimSpace: false,
|
|
|
|
Files: map[string]string{
|
|
|
|
"env.txt": "GOOS='linux' GOARCH='amd64' CGO_ENABLED='0'\n",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
tt.Run(t)
|
|
|
|
}
|
|
|
|
|
2017-07-20 09:05:37 +02:00
|
|
|
func TestVars(t *testing.T) {
|
|
|
|
tt := fileContentTest{
|
|
|
|
Dir: "testdata/vars",
|
|
|
|
Target: "default",
|
|
|
|
TrimSpace: true,
|
|
|
|
Files: map[string]string{
|
|
|
|
// hello task:
|
|
|
|
"foo.txt": "foo",
|
|
|
|
"bar.txt": "bar",
|
|
|
|
"baz.txt": "baz",
|
|
|
|
"tmpl_foo.txt": "foo",
|
|
|
|
"tmpl_bar.txt": "<no value>",
|
|
|
|
"tmpl_foo2.txt": "foo2",
|
|
|
|
"tmpl_bar2.txt": "bar2",
|
|
|
|
"shtmpl_foo.txt": "foo",
|
|
|
|
"shtmpl_foo2.txt": "foo2",
|
|
|
|
"nestedtmpl_foo.txt": "{{.FOO}}",
|
|
|
|
"nestedtmpl_foo2.txt": "foo2",
|
|
|
|
"foo2.txt": "foo2",
|
|
|
|
"bar2.txt": "bar2",
|
|
|
|
"baz2.txt": "baz2",
|
|
|
|
"tmpl2_foo.txt": "<no value>",
|
|
|
|
"tmpl2_foo2.txt": "foo2",
|
|
|
|
"tmpl2_bar.txt": "<no value>",
|
|
|
|
"tmpl2_bar2.txt": "<no value>",
|
|
|
|
"shtmpl2_foo.txt": "<no value>",
|
|
|
|
"shtmpl2_foo2.txt": "foo2",
|
|
|
|
"nestedtmpl2_foo2.txt": "{{.FOO2}}",
|
|
|
|
"equal.txt": "foo=bar",
|
|
|
|
"override.txt": "bar",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
tt.Run(t)
|
|
|
|
// Ensure identical results when running hello task directly.
|
|
|
|
tt.Target = "hello"
|
|
|
|
tt.Run(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVarsInvalidTmpl(t *testing.T) {
|
|
|
|
const (
|
|
|
|
dir = "testdata/vars"
|
|
|
|
target = "invalid-var-tmpl"
|
|
|
|
expectError = "template: :1: unexpected EOF"
|
|
|
|
)
|
|
|
|
|
|
|
|
e := &task.Executor{
|
|
|
|
Dir: dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
|
|
|
}
|
|
|
|
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
|
|
|
|
assert.EqualError(t, e.Run(target), expectError, "e.Run(target)")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParams(t *testing.T) {
|
|
|
|
tt := fileContentTest{
|
|
|
|
Dir: "testdata/params",
|
|
|
|
Target: "default",
|
|
|
|
TrimSpace: false,
|
|
|
|
Files: map[string]string{
|
|
|
|
"hello.txt": "Hello\n",
|
|
|
|
"world.txt": "World\n",
|
|
|
|
"exclamation.txt": "!\n",
|
|
|
|
"dep1.txt": "Dependence1\n",
|
|
|
|
"dep2.txt": "Dependence2\n",
|
|
|
|
"spanish.txt": "¡Holla mundo!\n",
|
|
|
|
"spanish-dep.txt": "¡Holla dependencia!\n",
|
|
|
|
"portuguese.txt": "Olá, mundo!\n",
|
|
|
|
"portuguese2.txt": "Olá, mundo!\n",
|
|
|
|
"german.txt": "Welt!\n",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
tt.Run(t)
|
|
|
|
}
|
|
|
|
|
2017-03-16 02:15:27 +02:00
|
|
|
func TestDeps(t *testing.T) {
|
|
|
|
const dir = "testdata/deps"
|
|
|
|
|
|
|
|
files := []string{
|
|
|
|
"d1.txt",
|
|
|
|
"d2.txt",
|
|
|
|
"d3.txt",
|
|
|
|
"d11.txt",
|
|
|
|
"d12.txt",
|
|
|
|
"d13.txt",
|
|
|
|
"d21.txt",
|
|
|
|
"d22.txt",
|
|
|
|
"d23.txt",
|
|
|
|
"d31.txt",
|
|
|
|
"d32.txt",
|
|
|
|
"d33.txt",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, f := range files {
|
2017-03-25 15:52:41 +02:00
|
|
|
_ = os.Remove(filepath.Join(dir, f))
|
2017-03-16 02:15:27 +02:00
|
|
|
}
|
|
|
|
|
2017-06-16 16:24:01 +02:00
|
|
|
e := &task.Executor{
|
2017-07-01 20:32:13 +02:00
|
|
|
Dir: dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
2017-03-16 02:15:27 +02:00
|
|
|
}
|
2017-06-16 16:24:01 +02:00
|
|
|
assert.NoError(t, e.ReadTaskfile())
|
|
|
|
assert.NoError(t, e.Run("default"))
|
2017-03-16 02:15:27 +02:00
|
|
|
|
|
|
|
for _, f := range files {
|
|
|
|
f = filepath.Join(dir, f)
|
|
|
|
if _, err := os.Stat(f); err != nil {
|
|
|
|
t.Errorf("File %s should exists", f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-25 15:51:30 +02:00
|
|
|
|
2017-03-25 20:26:42 +02:00
|
|
|
func TestTaskCall(t *testing.T) {
|
|
|
|
const dir = "testdata/task_call"
|
|
|
|
|
|
|
|
files := []string{
|
|
|
|
"foo.txt",
|
|
|
|
"bar.txt",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, f := range files {
|
|
|
|
_ = os.Remove(filepath.Join(dir, f))
|
|
|
|
}
|
|
|
|
|
2017-06-16 16:24:01 +02:00
|
|
|
e := &task.Executor{
|
2017-07-01 20:32:13 +02:00
|
|
|
Dir: dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
2017-03-25 20:26:42 +02:00
|
|
|
}
|
2017-06-16 16:24:01 +02:00
|
|
|
assert.NoError(t, e.ReadTaskfile())
|
|
|
|
assert.NoError(t, e.Run("default"))
|
2017-03-25 20:26:42 +02:00
|
|
|
|
|
|
|
for _, f := range files {
|
|
|
|
if _, err := os.Stat(filepath.Join(dir, f)); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-17 19:37:11 +02:00
|
|
|
|
|
|
|
func TestStatus(t *testing.T) {
|
|
|
|
const dir = "testdata/status"
|
|
|
|
var file = filepath.Join(dir, "foo.txt")
|
|
|
|
|
|
|
|
_ = os.Remove(file)
|
|
|
|
|
|
|
|
if _, err := os.Stat(file); err == nil {
|
|
|
|
t.Errorf("File should not exists: %v", err)
|
|
|
|
}
|
2017-07-01 20:32:13 +02:00
|
|
|
|
|
|
|
e := &task.Executor{
|
|
|
|
Dir: dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
2017-05-17 19:37:11 +02:00
|
|
|
}
|
2017-07-01 20:32:13 +02:00
|
|
|
assert.NoError(t, e.ReadTaskfile())
|
|
|
|
assert.NoError(t, e.Run("gen-foo"))
|
|
|
|
|
2017-05-17 19:37:11 +02:00
|
|
|
if _, err := os.Stat(file); err != nil {
|
|
|
|
t.Errorf("File should exists: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
buff := bytes.NewBuffer(nil)
|
2017-07-01 20:32:13 +02:00
|
|
|
e.Stdout, e.Stderr = buff, buff
|
|
|
|
assert.NoError(t, e.Run("gen-foo"))
|
|
|
|
|
2017-05-17 19:37:11 +02:00
|
|
|
if buff.String() != `task: Task "gen-foo" is up to date`+"\n" {
|
|
|
|
t.Errorf("Wrong output message: %s", buff.String())
|
|
|
|
}
|
|
|
|
}
|
2017-05-17 20:38:46 +02:00
|
|
|
|
2017-07-12 11:30:28 +02:00
|
|
|
func TestGenerates(t *testing.T) {
|
|
|
|
var srcTask = "sub/src.txt"
|
|
|
|
var relTask = "rel.txt"
|
|
|
|
var absTask = "abs.txt"
|
|
|
|
|
|
|
|
// This test does not work with a relative dir.
|
|
|
|
dir, err := filepath.Abs("testdata/generates")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
var srcFile = filepath.Join(dir, srcTask)
|
|
|
|
|
|
|
|
for _, task := range []string{srcTask, relTask, absTask} {
|
|
|
|
path := filepath.Join(dir, task)
|
|
|
|
_ = os.Remove(path)
|
|
|
|
if _, err := os.Stat(path); err == nil {
|
|
|
|
t.Errorf("File should not exists: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buff := bytes.NewBuffer(nil)
|
|
|
|
e := &task.Executor{
|
|
|
|
Dir: dir,
|
|
|
|
Stdout: buff,
|
|
|
|
Stderr: buff,
|
|
|
|
}
|
|
|
|
assert.NoError(t, e.ReadTaskfile())
|
|
|
|
|
|
|
|
for _, task := range []string{relTask, absTask} {
|
|
|
|
var destFile = filepath.Join(dir, task)
|
|
|
|
var upToDate = fmt.Sprintf("task: Task \"%s\" is up to date\n", srcTask) +
|
|
|
|
fmt.Sprintf("task: Task \"%s\" is up to date\n", task)
|
|
|
|
|
|
|
|
// Run task for the first time.
|
|
|
|
assert.NoError(t, e.Run(task))
|
|
|
|
|
|
|
|
if _, err := os.Stat(srcFile); err != nil {
|
|
|
|
t.Errorf("File should exists: %v", err)
|
|
|
|
}
|
|
|
|
if _, err := os.Stat(destFile); err != nil {
|
|
|
|
t.Errorf("File should exists: %v", err)
|
|
|
|
}
|
|
|
|
// Ensure task was not incorrectly found to be up-to-date on first run.
|
|
|
|
if buff.String() == upToDate {
|
|
|
|
t.Errorf("Wrong output message: %s", buff.String())
|
|
|
|
}
|
|
|
|
buff.Reset()
|
|
|
|
|
|
|
|
// Re-run task to ensure it's now found to be up-to-date.
|
|
|
|
assert.NoError(t, e.Run(task))
|
|
|
|
if buff.String() != upToDate {
|
|
|
|
t.Errorf("Wrong output message: %s", buff.String())
|
|
|
|
}
|
|
|
|
buff.Reset()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-17 20:38:46 +02:00
|
|
|
func TestInit(t *testing.T) {
|
|
|
|
const dir = "testdata/init"
|
|
|
|
var file = filepath.Join(dir, "Taskfile.yml")
|
|
|
|
|
|
|
|
_ = os.Remove(file)
|
|
|
|
if _, err := os.Stat(file); err == nil {
|
|
|
|
t.Errorf("Taskfile.yml should not exists")
|
|
|
|
}
|
|
|
|
|
2017-07-31 00:29:49 +02:00
|
|
|
if err := task.InitTaskfile(ioutil.Discard, dir); err != nil {
|
2017-05-17 20:38:46 +02:00
|
|
|
t.Error(err)
|
|
|
|
}
|
2017-07-01 20:32:13 +02:00
|
|
|
|
2017-05-17 20:38:46 +02:00
|
|
|
if _, err := os.Stat(file); err != nil {
|
|
|
|
t.Errorf("Taskfile.yml should exists")
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 20:30:50 +02:00
|
|
|
|
2017-07-08 18:33:55 +02:00
|
|
|
func TestCyclicDep(t *testing.T) {
|
|
|
|
const dir = "testdata/cyclic"
|
|
|
|
|
|
|
|
e := task.Executor{
|
|
|
|
Dir: dir,
|
|
|
|
Stdout: ioutil.Discard,
|
|
|
|
Stderr: ioutil.Discard,
|
|
|
|
}
|
|
|
|
assert.NoError(t, e.ReadTaskfile())
|
|
|
|
assert.IsType(t, &task.MaximumTaskCallExceededError{}, e.Run("task-1"))
|
|
|
|
}
|