diff --git a/executor.go b/executor.go index a439b96c..ad8cd654 100644 --- a/executor.go +++ b/executor.go @@ -4,6 +4,7 @@ import ( "context" "io" "os" + "path/filepath" "sync" "time" @@ -119,7 +120,12 @@ type dirOption struct { } func (o *dirOption) ApplyToExecutor(e *Executor) { - e.Dir = o.dir + absDir, err := filepath.Abs(o.dir) + if err != nil { + e.Dir = o.dir + return + } + e.Dir = absDir } // WithTempDir sets the temporary directory that will be used by [Executor] for diff --git a/executor_test.go b/executor_test.go index 0e4d667c..9c836938 100644 --- a/executor_test.go +++ b/executor_test.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "testing" "github.com/sebdah/goldie/v2" @@ -15,6 +16,7 @@ import ( "github.com/go-task/task/v3" "github.com/go-task/task/v3/experiments" "github.com/go-task/task/v3/internal/filepathext" + "github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile/ast" ) @@ -34,7 +36,12 @@ type ( task string vars map[string]any input string + nodeDir string + nodeEntrypoint string + nodeInsecure bool + readerOpts []taskfile.ReaderOption executorOpts []task.ExecutorOption + wantReaderError bool wantSetupError bool wantRunError bool wantStatusError bool @@ -47,8 +54,9 @@ type ( func NewExecutorTest(t *testing.T, opts ...ExecutorTestOption) { t.Helper() tt := &ExecutorTest{ - task: "default", - vars: map[string]any{}, + task: "default", + vars: map[string]any{}, + nodeDir: ".", TaskTest: TaskTest{ experiments: map[*experiments.Experiment]int{}, fixtureTemplateData: map[string]any{}, @@ -145,11 +153,52 @@ func (tt *ExecutorTest) run(t *testing.T) { f := func(t *testing.T) { t.Helper() var buf bytes.Buffer + ctx := context.Background() - opts := append( + // Create a new root node for the given entrypoint + node, err := taskfile.NewRootNode( + tt.nodeEntrypoint, + tt.nodeDir, + tt.nodeInsecure, + ) + require.NoError(t, err) + + // Create a golden fixture file for the output + g := goldie.New(t, + goldie.WithFixtureDir(filepath.Join(node.Dir(), "testdata")), + ) + + // Set up a temporary directory for the taskfile reader and task executor + tempDir, err := task.NewTempDir(node.Dir()) + require.NoError(t, err) + tt.readerOpts = append(tt.readerOpts, taskfile.WithTempDir(tempDir.Remote)) + + // Set up the taskfile reader + reader := taskfile.NewReader(tt.readerOpts...) + graph, err := reader.Read(ctx, node) + if tt.wantReaderError { + require.Error(t, err) + tt.writeFixtureErrReader(t, g, err) + tt.writeFixtureBuffer(t, g, buf) + return + } else { + require.NoError(t, err) + } + + executorOpts := slices.Concat( + // Apply the node directory and temp directory to the executor options + // by default, but allow them to by overridden by the test options + []task.ExecutorOption{ + task.WithDir(node.Dir()), + task.WithTempDir(tempDir), + }, + // Apply the executor options from the test tt.executorOpts, - task.WithStdout(&buf), - task.WithStderr(&buf), + // Force the input/output streams to be set to the test buffer + []task.ExecutorOption{ + task.WithStdout(&buf), + task.WithStderr(&buf), + }, ) // If the test has input, create a reader for it and add it to the @@ -157,19 +206,12 @@ func (tt *ExecutorTest) run(t *testing.T) { if tt.input != "" { var reader bytes.Buffer reader.WriteString(tt.input) - opts = append(opts, task.WithStdin(&reader)) + executorOpts = append(executorOpts, task.WithStdin(&reader)) } // Set up the task executor - e := task.NewExecutor(opts...) - - // Create a golden fixture file for the output - g := goldie.New(t, - goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")), - ) - - // Call setup and check for errors - if err := e.Setup(); tt.wantSetupError { + executor, err := task.NewExecutor(graph, executorOpts...) + if tt.wantSetupError { require.Error(t, err) tt.writeFixtureErrSetup(t, g, err) tt.writeFixtureBuffer(t, g, buf) @@ -189,8 +231,7 @@ func (tt *ExecutorTest) run(t *testing.T) { } // Run the task and check for errors - ctx := context.Background() - if err := e.Run(ctx, call); tt.wantRunError { + if err := executor.Run(ctx, call); tt.wantRunError { require.Error(t, err) tt.writeFixtureErrRun(t, g, err) tt.writeFixtureBuffer(t, g, buf) @@ -201,7 +242,7 @@ func (tt *ExecutorTest) run(t *testing.T) { // If the status flag is set, run the status check if tt.wantStatusError { - if err := e.Status(ctx, call); err != nil { + if err := executor.Status(ctx, call); err != nil { tt.writeFixtureStatus(t, g, err.Error()) } } @@ -220,19 +261,16 @@ func (tt *ExecutorTest) run(t *testing.T) { func TestEmptyTask(t *testing.T) { t.Parallel() NewExecutorTest(t, - WithExecutorOptions( - task.WithDir("testdata/empty_task"), - ), + WithNodeDir("testdata/empty_task"), + WithExecutorOptions(), ) } func TestEmptyTaskfile(t *testing.T) { t.Parallel() NewExecutorTest(t, - WithExecutorOptions( - task.WithDir("testdata/empty_taskfile"), - ), - WithSetupError(), + WithNodeDir("testdata/empty_taskfile"), + WithReaderError(), WithFixtureTemplating(), ) } @@ -241,15 +279,15 @@ func TestEnv(t *testing.T) { t.Setenv("QUX", "from_os") NewExecutorTest(t, WithName("env precedence disabled"), + WithNodeDir("testdata/env"), WithExecutorOptions( - task.WithDir("testdata/env"), task.WithSilent(true), ), ) NewExecutorTest(t, WithName("env precedence enabled"), + WithNodeDir("testdata/env"), WithExecutorOptions( - task.WithDir("testdata/env"), task.WithSilent(true), ), WithExperiment(&experiments.EnvPrecedence, 1), @@ -259,8 +297,8 @@ func TestEnv(t *testing.T) { func TestVars(t *testing.T) { t.Parallel() NewExecutorTest(t, + WithNodeDir("testdata/vars"), WithExecutorOptions( - task.WithDir("testdata/vars"), task.WithSilent(true), ), ) @@ -270,25 +308,19 @@ func TestRequires(t *testing.T) { t.Parallel() NewExecutorTest(t, WithName("required var missing"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("missing-var"), WithRunError(), ) NewExecutorTest(t, WithName("required var ok"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("missing-var"), WithVar("FOO", "bar"), ) NewExecutorTest(t, WithName("fails validation"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("validation-var"), WithVar("ENV", "dev"), WithVar("FOO", "bar"), @@ -296,48 +328,37 @@ func TestRequires(t *testing.T) { ) NewExecutorTest(t, WithName("passes validation"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("validation-var"), WithVar("FOO", "one"), WithVar("ENV", "dev"), ) NewExecutorTest(t, WithName("required var missing + fails validation"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("validation-var"), WithRunError(), ) NewExecutorTest(t, WithName("required var missing + fails validation"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("validation-var-dynamic"), WithVar("FOO", "one"), WithVar("ENV", "dev"), ) NewExecutorTest(t, WithName("require before compile"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("require-before-compile"), WithRunError(), ) NewExecutorTest(t, WithName("var defined in task"), - WithExecutorOptions( - task.WithDir("testdata/requires"), - ), + WithNodeDir("testdata/requires"), WithTask("var-defined-in-task"), ) } -// TODO: mock fs func TestSpecialVars(t *testing.T) { t.Parallel() @@ -358,12 +379,13 @@ func TestSpecialVars(t *testing.T) { "included:print-taskfile-dir", } - for _, dir := range []string{dir, subdir} { + for _, executorDir := range []string{dir, subdir} { for _, test := range tests { + name := fmt.Sprintf("%s-%s", executorDir, test) NewExecutorTest(t, - WithName(fmt.Sprintf("%s-%s", dir, test)), + WithName(name), + WithNodeDir(executorDir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), task.WithVersionCheck(true), ), @@ -377,8 +399,8 @@ func TestSpecialVars(t *testing.T) { func TestConcurrency(t *testing.T) { t.Parallel() NewExecutorTest(t, + WithNodeDir("testdata/concurrency"), WithExecutorOptions( - task.WithDir("testdata/concurrency"), task.WithConcurrency(1), ), WithPostProcessFn(PPSortedLines), @@ -388,8 +410,8 @@ func TestConcurrency(t *testing.T) { func TestParams(t *testing.T) { t.Parallel() NewExecutorTest(t, + WithNodeDir("testdata/params"), WithExecutorOptions( - task.WithDir("testdata/params"), task.WithSilent(true), ), WithPostProcessFn(PPSortedLines), @@ -399,15 +421,14 @@ func TestParams(t *testing.T) { func TestDeps(t *testing.T) { t.Parallel() NewExecutorTest(t, + WithNodeDir("testdata/deps"), WithExecutorOptions( - task.WithDir("testdata/deps"), task.WithSilent(true), ), WithPostProcessFn(PPSortedLines), ) } -// TODO: mock fs func TestStatus(t *testing.T) { t.Parallel() @@ -430,8 +451,8 @@ func TestStatus(t *testing.T) { // gen-foo creates foo.txt, and will always fail it's status check. NewExecutorTest(t, WithName("run gen-foo 1 silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-foo"), @@ -442,8 +463,8 @@ func TestStatus(t *testing.T) { // only exists after the first run. NewExecutorTest(t, WithName("run gen-bar 1 silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-bar"), @@ -452,8 +473,8 @@ func TestStatus(t *testing.T) { // if e.Verbose is set to true. NewExecutorTest(t, WithName("run gen-baz silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-silent-baz"), @@ -468,8 +489,8 @@ func TestStatus(t *testing.T) { // Run gen-bar a second time to produce a checksum file that matches bar.txt NewExecutorTest(t, WithName("run gen-bar 2 silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-bar"), @@ -477,8 +498,8 @@ func TestStatus(t *testing.T) { // Run gen-bar a third time, to make sure we've triggered the status check. NewExecutorTest(t, WithName("run gen-bar 3 silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-bar"), @@ -490,8 +511,8 @@ func TestStatus(t *testing.T) { require.NoError(t, err) NewExecutorTest(t, WithName("run gen-bar 4 silent"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithSilent(true), ), WithTask("gen-bar"), @@ -499,56 +520,44 @@ func TestStatus(t *testing.T) { // all: not up-to-date NewExecutorTest(t, WithName("run gen-foo 2"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-foo"), ) // status: not up-to-date NewExecutorTest(t, WithName("run gen-foo 3"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-foo"), ) // sources: not up-to-date NewExecutorTest(t, WithName("run gen-bar 5"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-bar"), ) // all: up-to-date NewExecutorTest(t, WithName("run gen-bar 6"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-bar"), ) // sources: not up-to-date, no output produced. NewExecutorTest(t, WithName("run gen-baz 2"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-silent-baz"), ) // up-to-date, no output produced NewExecutorTest(t, WithName("run gen-baz 3"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("gen-silent-baz"), ) // up-to-date, output produced due to Verbose mode. NewExecutorTest(t, WithName("run gen-baz 4 verbose"), + WithNodeDir(dir), WithExecutorOptions( - task.WithDir(dir), task.WithVerbose(true), ), WithTask("gen-silent-baz"), @@ -561,32 +570,24 @@ func TestPrecondition(t *testing.T) { const dir = "testdata/precondition" NewExecutorTest(t, WithName("a precondition has been met"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("foo"), ) NewExecutorTest(t, WithName("a precondition was not met"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("impossible"), WithRunError(), ) NewExecutorTest(t, WithName("precondition in dependency fails the task"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("depends_on_impossible"), WithRunError(), ) NewExecutorTest(t, WithName("precondition in cmd fails the task"), - WithExecutorOptions( - task.WithDir(dir), - ), + WithNodeDir(dir), WithTask("executes_failing_task_as_cmd"), WithRunError(), ) @@ -597,25 +598,21 @@ func TestAlias(t *testing.T) { NewExecutorTest(t, WithName("alias"), - WithExecutorOptions( - task.WithDir("testdata/alias"), - ), + WithNodeDir("testdata/alias"), WithTask("f"), ) NewExecutorTest(t, WithName("duplicate alias"), - WithExecutorOptions( - task.WithDir("testdata/alias"), - ), + WithNodeDir("testdata/alias"), WithTask("x"), WithRunError(), ) NewExecutorTest(t, WithName("alias summary"), + WithNodeDir("testdata/alias"), WithExecutorOptions( - task.WithDir("testdata/alias"), task.WithSummary(true), ), WithTask("f"), @@ -627,16 +624,14 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("up to date"), - WithExecutorOptions( - task.WithDir("testdata/label_uptodate"), - ), + WithNodeDir("testdata/label_uptodate"), WithTask("foo"), ) NewExecutorTest(t, WithName("summary"), + WithNodeDir("testdata/label_summary"), WithExecutorOptions( - task.WithDir("testdata/label_summary"), task.WithSummary(true), ), WithTask("foo"), @@ -644,26 +639,20 @@ func TestLabel(t *testing.T) { NewExecutorTest(t, WithName("status"), - WithExecutorOptions( - task.WithDir("testdata/label_status"), - ), + WithNodeDir("testdata/label_status"), WithTask("foo"), WithStatusError(), ) NewExecutorTest(t, WithName("var"), - WithExecutorOptions( - task.WithDir("testdata/label_var"), - ), + WithNodeDir("testdata/label_var"), WithTask("foo"), ) NewExecutorTest(t, WithName("label in summary"), - WithExecutorOptions( - task.WithDir("testdata/label_summary"), - ), + WithNodeDir("testdata/label_summary"), WithTask("foo"), ) } @@ -690,8 +679,8 @@ func TestPromptInSummary(t *testing.T) { opts := []ExecutorTestOption{ WithName(test.name), + WithNodeDir("testdata/prompt"), WithExecutorOptions( - task.WithDir("testdata/prompt"), task.WithAssumeTerm(true), ), WithTask("foo"), @@ -709,8 +698,8 @@ func TestPromptWithIndirectTask(t *testing.T) { t.Parallel() NewExecutorTest(t, + WithNodeDir("testdata/prompt"), WithExecutorOptions( - task.WithDir("testdata/prompt"), task.WithAssumeTerm(true), ), WithTask("bar"), @@ -723,8 +712,8 @@ func TestPromptAssumeYes(t *testing.T) { NewExecutorTest(t, WithName("--yes flag should skip prompt"), + WithNodeDir("testdata/prompt"), WithExecutorOptions( - task.WithDir("testdata/prompt"), task.WithAssumeTerm(true), task.WithAssumeYes(true), ), @@ -734,8 +723,8 @@ func TestPromptAssumeYes(t *testing.T) { NewExecutorTest(t, WithName("task should raise errors.TaskCancelledError"), + WithNodeDir("testdata/prompt"), WithExecutorOptions( - task.WithDir("testdata/prompt"), task.WithAssumeTerm(true), ), WithTask("foo"), @@ -772,8 +761,8 @@ func TestForCmds(t *testing.T) { for _, test := range tests { opts := []ExecutorTestOption{ WithName(test.name), + WithNodeDir("testdata/for/cmds"), WithExecutorOptions( - task.WithDir("testdata/for/cmds"), task.WithSilent(true), task.WithForce(true), ), @@ -815,8 +804,8 @@ func TestForDeps(t *testing.T) { for _, test := range tests { opts := []ExecutorTestOption{ WithName(test.name), + WithNodeDir("testdata/for/deps"), WithExecutorOptions( - task.WithDir("testdata/for/deps"), task.WithSilent(true), task.WithForce(true), // Force output of each dep to be grouped together to prevent interleaving @@ -861,8 +850,8 @@ func TestReference(t *testing.T) { for _, test := range tests { NewExecutorTest(t, WithName(test.name), + WithNodeDir("testdata/var_references"), WithExecutorOptions( - task.WithDir("testdata/var_references"), task.WithSilent(true), task.WithForce(true), ), @@ -929,8 +918,8 @@ func TestVarInheritance(t *testing.T) { for _, test := range tests { NewExecutorTest(t, WithName(test.name), + WithNodeDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)), WithExecutorOptions( - task.WithDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)), task.WithSilent(true), task.WithForce(true), ), @@ -944,26 +933,20 @@ func TestFuzzyModel(t *testing.T) { NewExecutorTest(t, WithName("fuzzy"), - WithExecutorOptions( - task.WithDir("testdata/fuzzy"), - ), + WithNodeDir("testdata/fuzzy"), WithTask("instal"), WithRunError(), ) NewExecutorTest(t, WithName("not-fuzzy"), - WithExecutorOptions( - task.WithDir("testdata/fuzzy"), - ), + WithNodeDir("testdata/fuzzy"), WithTask("install"), ) NewExecutorTest(t, WithName("intern"), - WithExecutorOptions( - task.WithDir("testdata/fuzzy"), - ), + WithNodeDir("testdata/fuzzy"), WithTask("intern"), WithRunError(), ) @@ -974,17 +957,13 @@ func TestIncludeChecksum(t *testing.T) { NewExecutorTest(t, WithName("correct"), - WithExecutorOptions( - task.WithDir("testdata/includes_checksum/correct"), - ), + WithNodeDir("testdata/includes_checksum/correct"), ) NewExecutorTest(t, WithName("incorrect"), - WithExecutorOptions( - task.WithDir("testdata/includes_checksum/incorrect"), - ), - WithSetupError(), + WithNodeDir("testdata/includes_checksum/incorrect"), + WithReaderError(), WithFixtureTemplating(), ) } diff --git a/formatter_test.go b/formatter_test.go index 7221ff76..acfdf954 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -2,7 +2,9 @@ package task_test import ( "bytes" + "context" "path/filepath" + "slices" "testing" "github.com/sebdah/goldie/v2" @@ -10,6 +12,7 @@ import ( "github.com/go-task/task/v3" "github.com/go-task/task/v3/experiments" + "github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile/ast" ) @@ -26,12 +29,17 @@ type ( // running `task gen:fixtures`. FormatterTest struct { TaskTest - task string - vars map[string]any - executorOpts []task.ExecutorOption - listOptions task.ListOptions - wantSetupError bool - wantListError bool + task string + vars map[string]any + nodeDir string + nodeEntrypoint string + nodeInsecure bool + readerOpts []taskfile.ReaderOption + executorOpts []task.ExecutorOption + listOptions task.ListOptions + wantReaderError bool + wantSetupError bool + wantListError bool } ) @@ -41,8 +49,9 @@ type ( func NewFormatterTest(t *testing.T, opts ...FormatterTestOption) { t.Helper() tt := &FormatterTest{ - task: "default", - vars: map[string]any{}, + task: "default", + vars: map[string]any{}, + nodeDir: ".", TaskTest: TaskTest{ experiments: map[*experiments.Experiment]int{}, fixtureTemplateData: map[string]any{}, @@ -114,23 +123,57 @@ func (tt *FormatterTest) run(t *testing.T) { f := func(t *testing.T) { t.Helper() var buf bytes.Buffer + ctx := context.Background() - opts := append( - tt.executorOpts, - task.WithStdout(&buf), - task.WithStderr(&buf), + // Create a new root node for the given entrypoint + node, err := taskfile.NewRootNode( + tt.nodeEntrypoint, + tt.nodeDir, + tt.nodeInsecure, ) - - // Set up the task executor - e := task.NewExecutor(opts...) + require.NoError(t, err) // Create a golden fixture file for the output g := goldie.New(t, - goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")), + goldie.WithFixtureDir(filepath.Join(node.Dir(), "testdata")), ) - // Call setup and check for errors - if err := e.Setup(); tt.wantSetupError { + // Set up a temporary directory for the taskfile reader and task executor + tempDir, err := task.NewTempDir(node.Dir()) + require.NoError(t, err) + tt.readerOpts = append(tt.readerOpts, taskfile.WithTempDir(tempDir.Remote)) + + // Set up the taskfile reader + reader := taskfile.NewReader(tt.readerOpts...) + graph, err := reader.Read(ctx, node) + if tt.wantReaderError { + require.Error(t, err) + tt.writeFixtureErrReader(t, g, err) + tt.writeFixtureBuffer(t, g, buf) + return + } else { + require.NoError(t, err) + } + + executorOpts := slices.Concat( + // Apply the node directory and temp directory to the executor options + // by default, but allow them to by overridden by the test options + []task.ExecutorOption{ + task.WithDir(node.Dir()), + task.WithTempDir(tempDir), + }, + // Apply the executor options from the test + tt.executorOpts, + // Force the input/output streams to be set to the test buffer + []task.ExecutorOption{ + task.WithStdout(&buf), + task.WithStderr(&buf), + }, + ) + + // Set up the task executor + executor, err := task.NewExecutor(graph, executorOpts...) + if tt.wantSetupError { require.Error(t, err) tt.writeFixtureErrSetup(t, g, err) tt.writeFixtureBuffer(t, g, buf) @@ -146,7 +189,7 @@ func (tt *FormatterTest) run(t *testing.T) { } // Run the formatter and check for errors - if _, err := e.ListTasks(tt.listOptions); tt.wantListError { + if _, err := executor.ListTasks(tt.listOptions); tt.wantListError { require.Error(t, err) tt.writeFixtureErrList(t, g, err) tt.writeFixtureBuffer(t, g, buf) @@ -170,9 +213,7 @@ func TestNoLabelInList(t *testing.T) { t.Parallel() NewFormatterTest(t, - WithExecutorOptions( - task.WithDir("testdata/label_list"), - ), + WithNodeDir("testdata/label_list"), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, }), @@ -184,9 +225,7 @@ func TestListAllShowsNoDesc(t *testing.T) { t.Parallel() NewFormatterTest(t, - WithExecutorOptions( - task.WithDir("testdata/list_mixed_desc"), - ), + WithNodeDir("testdata/list_mixed_desc"), WithListOptions(task.ListOptions{ ListAllTasks: true, }), @@ -198,9 +237,7 @@ func TestListCanListDescOnly(t *testing.T) { t.Parallel() NewFormatterTest(t, - WithExecutorOptions( - task.WithDir("testdata/list_mixed_desc"), - ), + WithNodeDir("testdata/list_mixed_desc"), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, }), @@ -211,9 +248,7 @@ func TestListDescInterpolation(t *testing.T) { t.Parallel() NewFormatterTest(t, - WithExecutorOptions( - task.WithDir("testdata/list_desc_interpolation"), - ), + WithNodeDir("testdata/list_desc_interpolation"), WithListOptions(task.ListOptions{ ListOnlyTasksWithDescriptions: true, }), @@ -224,9 +259,7 @@ func TestJsonListFormat(t *testing.T) { t.Parallel() NewFormatterTest(t, - WithExecutorOptions( - task.WithDir("testdata/json_list_format"), - ), + WithNodeDir("testdata/json_list_format"), WithListOptions(task.ListOptions{ FormatTaskListAsJSON: true, }), diff --git a/task_test.go b/task_test.go index 927ff29f..56821ede 100644 --- a/task_test.go +++ b/task_test.go @@ -111,6 +111,17 @@ func (tt *TaskTest) writeFixtureBuffer( tt.writeFixture(t, g, "", buff.Bytes()) } +// writeFixtureErrSetup is a wrapper for writing the output of an error during +// the setup phase of the task to a fixture file. +func (tt *TaskTest) writeFixtureErrReader( + t *testing.T, + g *goldie.Goldie, + err error, +) { + t.Helper() + tt.writeFixture(t, g, "err-reader", []byte(err.Error())) +} + // writeFixtureErrSetup is a wrapper for writing the output of an error during // the setup phase of the task to a fixture file. func (tt *TaskTest) writeFixtureErrSetup( @@ -142,6 +153,57 @@ func (opt *nameTestOption) applyToFormatterTest(t *FormatterTest) { t.name = opt.name } +// WithNodeDir sets the directory to be used for the test node. +func WithNodeDir(dir string) TestOption { + return &nodeDirTestOption{dir: dir} +} + +type nodeDirTestOption struct { + dir string +} + +func (opt *nodeDirTestOption) applyToExecutorTest(t *ExecutorTest) { + t.nodeDir = opt.dir +} + +func (opt *nodeDirTestOption) applyToFormatterTest(t *FormatterTest) { + t.nodeDir = opt.dir +} + +// WithNodeEntrypoint sets the entrypoint to be used for the test node. +func WithNodeEntrypoint(entrypoint string) TestOption { + return &nodeEntrypointTestOption{entrypoint: entrypoint} +} + +type nodeEntrypointTestOption struct { + entrypoint string +} + +func (opt *nodeEntrypointTestOption) applyToExecutorTest(t *ExecutorTest) { + t.nodeEntrypoint = opt.entrypoint +} + +func (opt *nodeEntrypointTestOption) applyToFormatterTest(t *FormatterTest) { + t.nodeEntrypoint = opt.entrypoint +} + +// WithNodeInsecure sets the insecure flag to be used for the test node. +func WithNodeInsecure(insecure bool) TestOption { + return &nodeInsecureTestOption{insecure: insecure} +} + +type nodeInsecureTestOption struct { + insecure bool +} + +func (opt *nodeInsecureTestOption) applyToExecutorTest(t *ExecutorTest) { + t.nodeInsecure = opt.insecure +} + +func (opt *nodeInsecureTestOption) applyToFormatterTest(t *FormatterTest) { + t.nodeInsecure = opt.insecure +} + // WithTask sets the name of the task to run. This should be used when the task // to run is not the default task. func WithTask(task string) TestOption { @@ -236,6 +298,22 @@ func (opt *postProcessFnTestOption) applyToFormatterTest(t *FormatterTest) { t.postProcessFns = append(t.postProcessFns, opt.fn) } +// WithReaderError sets the test to expect an error during the reader phase of the +// task execution. A fixture will be created with the output of any errors. +func WithReaderError() TestOption { + return &readerErrorTestOption{} +} + +type readerErrorTestOption struct{} + +func (opt *readerErrorTestOption) applyToExecutorTest(t *ExecutorTest) { + t.wantReaderError = true +} + +func (opt *readerErrorTestOption) applyToFormatterTest(t *FormatterTest) { + t.wantReaderError = true +} + // WithSetupError sets the test to expect an error during the setup phase of the // task execution. A fixture will be created with the output of any errors. func WithSetupError() TestOption { diff --git a/testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-setup.golden b/testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-reader.golden similarity index 100% rename from testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-setup.golden rename to testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-reader.golden diff --git a/testdata/includes_checksum/incorrect/testdata/TestIncludeChecksum-incorrect-err-setup.golden b/testdata/includes_checksum/incorrect/testdata/TestIncludeChecksum-incorrect-err-reader.golden similarity index 100% rename from testdata/includes_checksum/incorrect/testdata/TestIncludeChecksum-incorrect-err-setup.golden rename to testdata/includes_checksum/incorrect/testdata/TestIncludeChecksum-incorrect-err-reader.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-root-dir.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-root-dir.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-root-dir.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-root-dir.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile-dir.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile-dir.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile-dir.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile-dir.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-taskfile.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-root-dir.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-root-dir.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-root-dir.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-root-dir.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-dir.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-dir.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-dir.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-dir.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile-dir.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile-dir.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile-dir.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile-dir.golden diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile.golden similarity index 100% rename from testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile.golden rename to testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-subdir-print-taskfile.golden