package cli import ( "archive/tar" "strings" "testing" "tsne.dev/hopper/internal/log" ) // verbosityArchive is a small release with one immutable asset and one mutable // entry point, enough to exercise action lines and the summary. func verbosityArchive(t *testing.T) string { return makeArchive(t, []tarEntry{ {name: "index.html", body: ""}, {name: "assets/app.abc.js", body: "console.log(1)"}, // A symlink triggers an always-on warning regardless of mode. {name: "assets/link.js", typeflag: tar.TypeSymlink, linkname: "app.abc.js"}, }) } func TestPushDefaultOutput(t *testing.T) { arc := verbosityArchive(t) fc := newFakeAPI() out, errb := captureLogs(t) if err := runPush(arc, fc); err != nil { t.Fatalf("push: %v", err) } stdout := out.String() if !strings.Contains(stdout, "uploading assets/app.abc.js") { t.Fatalf("default output missing action line: %q", stdout) } if !strings.Contains(stdout, "uploaded: 2") { t.Fatalf("default output missing summary: %q", stdout) } if !strings.Contains(errb.String(), "Warning:") { t.Fatalf("warning missing from stderr: %q", errb.String()) } } func TestPushQuietOnlySummaryAndWarnings(t *testing.T) { arc := verbosityArchive(t) fc := newFakeAPI() out, errb := captureLogs(t) log.SetQuiet(true) if err := runPush(arc, fc); err != nil { t.Fatalf("push: %v", err) } stdout := out.String() if strings.Contains(stdout, "uploading") { t.Fatalf("quiet must suppress action lines: %q", stdout) } if !strings.Contains(stdout, "uploaded: 2") { t.Fatalf("quiet must keep summary: %q", stdout) } if !strings.Contains(errb.String(), "Warning:") { t.Fatalf("quiet must keep warnings on stderr: %q", errb.String()) } } func TestPushQuietWinsOverVerbose(t *testing.T) { arc := verbosityArchive(t) fc := newFakeAPI() out, errb := captureLogs(t) log.SetVerbose(true) log.SetQuiet(true) if err := runPush(arc, fc); err != nil { t.Fatalf("push: %v", err) } stdout := out.String() if strings.Contains(stdout, "uploading") { t.Fatalf("quiet+verbose must suppress action lines: %q", stdout) } if !strings.Contains(stdout, "uploaded: 2") { t.Fatalf("quiet+verbose must keep summary: %q", stdout) } if !strings.Contains(errb.String(), "Warning:") { t.Fatalf("quiet+verbose must keep warnings: %q", errb.String()) } } func TestLogStreamRouting(t *testing.T) { out, errb := captureLogs(t) log.Print("normal") log.PrintImportant("summary") log.Warn("careful") log.Error("boom") stdout := out.String() stderr := errb.String() if !strings.Contains(stdout, "normal") || !strings.Contains(stdout, "summary") { t.Fatalf("stdout missing normal output: %q", stdout) } if strings.Contains(stdout, "careful") || strings.Contains(stdout, "boom") { t.Fatalf("warnings/errors leaked to stdout: %q", stdout) } if !strings.Contains(stderr, "Warning: careful") || !strings.Contains(stderr, "Error: boom") { t.Fatalf("stderr missing warning/error: %q", stderr) } }