200 lines
8.2 KiB
Go
200 lines
8.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
|
|
commandkit "gitea.maximumdirect.net/eric/CommandKit"
|
|
)
|
|
|
|
func TestAliasesReachCoreExampleCommand(t *testing.T) {
|
|
app, err := newApp()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, test := range []struct {
|
|
name string
|
|
args []string
|
|
entered string
|
|
canonical string
|
|
greeting string
|
|
}{
|
|
{name: "command shortcut and scoped flag", args: []string{"hello", "--times=0", "--tag", "one"}, entered: "hello", canonical: "workspace greet", greeting: "count=explicit 0; tags=explicit [one]"},
|
|
{name: "group shortcut", args: []string{"ws", "greet", "--count=2"}, entered: "ws greet", canonical: "workspace greet", greeting: "count=explicit 2"},
|
|
{name: "canonical command", args: []string{"workspace", "greet"}, entered: "workspace greet", canonical: "workspace greet", greeting: "count=default 1 (not supplied)"},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
var output bytes.Buffer
|
|
outcome := app.Execute(context.Background(), test.args, commandkit.Streams{Out: &output, Err: io.Discard})
|
|
if outcome.Kind != commandkit.OutcomeSuccess {
|
|
t.Fatalf("Execute(%q) = %#v; output %q", test.args, outcome, output.String())
|
|
}
|
|
for _, fragment := range []string{
|
|
test.greeting,
|
|
"entered=\"" + test.entered + "\"",
|
|
"canonical=\"" + test.canonical + "\"",
|
|
} {
|
|
if !strings.Contains(output.String(), fragment) {
|
|
t.Errorf("output %q does not contain %q", output.String(), fragment)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGlobalHelpAliasDoesNotRunCoreExampleCommand(t *testing.T) {
|
|
app, err := newApp()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var output bytes.Buffer
|
|
outcome := app.Execute(context.Background(), []string{"hello", "--hlep"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
|
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "--hlep → --help") || strings.Contains(output.String(), "Hello;") {
|
|
t.Fatalf("help alias outcome/output = (%#v, %q)", outcome, output.String())
|
|
}
|
|
output.Reset()
|
|
outcome = app.Execute(context.Background(), []string{"ws", "--help"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
|
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "greet") || strings.Contains(output.String(), "Hello;") {
|
|
t.Fatalf("group shortcut help outcome/output = (%#v, %q)", outcome, output.String())
|
|
}
|
|
}
|
|
|
|
func TestReportingExampleModes(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
args []string
|
|
wantOutput []string
|
|
wantDiag []string
|
|
omitDiag []string
|
|
}{
|
|
{
|
|
name: "ordinary result",
|
|
args: []string{"report", "demo"},
|
|
wantOutput: []string{"Prepared a local report from one fixture."},
|
|
omitDiag: []string{"Optional fixture warning", "Using deterministic local data.", "Loaded one local fixture.", "DEBUG:"},
|
|
},
|
|
{
|
|
name: "progress selected",
|
|
args: []string{"report", "demo", "--progress"},
|
|
wantOutput: []string{"Prepared a local report from one fixture."},
|
|
wantDiag: []string{"Loaded one local fixture."},
|
|
omitDiag: []string{"WARN:", "Using deterministic local data.", "DEBUG:"},
|
|
},
|
|
{
|
|
name: "verbose messages",
|
|
args: []string{"report", "demo", "--verbose"},
|
|
wantOutput: []string{"Prepared a local report from one fixture."},
|
|
wantDiag: []string{"WARN: Optional fixture warning", "The sample contains an optional note.", "Using deterministic local data.", "Summary", "Processed one local fixture."},
|
|
omitDiag: []string{"Loaded one local fixture.", "DEBUG:"},
|
|
},
|
|
{
|
|
name: "debug messages",
|
|
args: []string{"report", "demo", "--debug"},
|
|
wantOutput: []string{"Prepared a local report from one fixture."},
|
|
wantDiag: []string{"WARN: Optional fixture warning", "Using deterministic local data.", "Loaded one local fixture.", "DEBUG: Selected the built-in reporting example.", "Processed one local fixture."},
|
|
},
|
|
{
|
|
name: "quiet suppresses result and messages",
|
|
args: []string{"report", "demo", "--quiet"},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
outcome, output, diagnostics := executeExample(t, test.args...)
|
|
if outcome.Kind != commandkit.OutcomeSuccess {
|
|
t.Fatalf("Execute(%q) = %#v", test.args, outcome)
|
|
}
|
|
for _, fragment := range test.wantOutput {
|
|
if !strings.Contains(output, fragment) {
|
|
t.Errorf("output %q does not contain %q", output, fragment)
|
|
}
|
|
}
|
|
for _, fragment := range test.wantDiag {
|
|
if !strings.Contains(diagnostics, fragment) {
|
|
t.Errorf("diagnostics %q does not contain %q", diagnostics, fragment)
|
|
}
|
|
}
|
|
for _, fragment := range test.omitDiag {
|
|
if strings.Contains(diagnostics, fragment) {
|
|
t.Errorf("diagnostics %q unexpectedly contain %q", diagnostics, fragment)
|
|
}
|
|
}
|
|
if test.name == "quiet suppresses result and messages" && (output != "" || diagnostics != "") {
|
|
t.Errorf("quiet output/diagnostics = (%q, %q), want both empty", output, diagnostics)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReportingExampleScenarios(t *testing.T) {
|
|
t.Run("silent recovery retains cause", func(t *testing.T) {
|
|
outcome, output, diagnostics := executeExample(t, "report", "recover")
|
|
if outcome.Kind != commandkit.OutcomeSuccess || !errors.Is(outcome.Cause, errRecoveredFixture) {
|
|
t.Fatalf("outcome = %#v, want successful recovery with original cause", outcome)
|
|
}
|
|
if output != "" || diagnostics != "" {
|
|
t.Fatalf("recovery output/diagnostics = (%q, %q), want silent recovery", output, diagnostics)
|
|
}
|
|
})
|
|
|
|
t.Run("warning without cause", func(t *testing.T) {
|
|
outcome, _, diagnostics := executeExample(t, "report", "warn", "--verbose")
|
|
if outcome.Kind != commandkit.OutcomeSuccess || outcome.Cause != nil {
|
|
t.Fatalf("outcome = %#v, want success without cause", outcome)
|
|
}
|
|
if !strings.Contains(diagnostics, "WARN: The local operation completed with a warning.") {
|
|
t.Fatalf("diagnostics = %q, want explicit warning", diagnostics)
|
|
}
|
|
})
|
|
|
|
t.Run("warning with independent cause", func(t *testing.T) {
|
|
outcome, _, diagnostics := executeExample(t, "report", "warn-error", "--verbose")
|
|
if outcome.Kind != commandkit.OutcomeSuccess || !errors.Is(outcome.Cause, errWarningFixture) {
|
|
t.Fatalf("outcome = %#v, want successful warning with original cause", outcome)
|
|
}
|
|
if !strings.Contains(diagnostics, "WARN: The local operation completed with a warning.") || strings.Contains(diagnostics, errWarningFixture.Error()) {
|
|
t.Fatalf("diagnostics = %q, want warning text without cause text", diagnostics)
|
|
}
|
|
})
|
|
|
|
t.Run("terminal explanation without cause", func(t *testing.T) {
|
|
outcome, _, diagnostics := executeExample(t, "report", "fail", "--quiet")
|
|
if outcome.Kind != commandkit.OutcomeOperational || outcome.Status == 0 || outcome.Cause != nil {
|
|
t.Fatalf("outcome = %#v, want terminal failure without cause", outcome)
|
|
}
|
|
if outcome.Explanation.Message != "The selected local operation could not be completed." || !strings.Contains(diagnostics, outcome.Explanation.Message) {
|
|
t.Fatalf("explanation/diagnostics = (%q, %q)", outcome.Explanation.Message, diagnostics)
|
|
}
|
|
})
|
|
|
|
t.Run("partial output keeps cause independent", func(t *testing.T) {
|
|
outcome, output, diagnostics := executeExample(t, "report", "partial")
|
|
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.Cause, errPartialFixture) {
|
|
t.Fatalf("outcome = %#v, want terminal failure with original cause", outcome)
|
|
}
|
|
if !strings.Contains(output, "Partial local report: first section complete.") {
|
|
t.Fatalf("output = %q, want completed first section", output)
|
|
}
|
|
if outcome.Explanation.Message != "The local report stopped after partial output." || !strings.Contains(diagnostics, outcome.Explanation.Message) {
|
|
t.Fatalf("explanation/diagnostics = (%q, %q)", outcome.Explanation.Message, diagnostics)
|
|
}
|
|
if strings.Contains(diagnostics, errPartialFixture.Error()) {
|
|
t.Errorf("diagnostics %q unexpectedly contain cause text", diagnostics)
|
|
}
|
|
})
|
|
}
|
|
|
|
func executeExample(t *testing.T, args ...string) (commandkit.Outcome, string, string) {
|
|
t.Helper()
|
|
app, err := newApp()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var output, diagnostics bytes.Buffer
|
|
outcome := app.Execute(context.Background(), args, commandkit.Streams{Out: &output, Err: &diagnostics})
|
|
return outcome, output.String(), diagnostics.String()
|
|
}
|