blob: eec465ecb7c091ed030d44e1b2fb5d3112f8d565 [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package jiri
import (
"context"
"errors"
"io"
"os"
"path/filepath"
"strings"
"testing"
"go.fuchsia.dev/jiri/cmdline"
)
func TestFromContext(t *testing.T) {
checkout := &Checkout{Root: "/root"}
ctx := WithCheckout(t.Context(), checkout)
if got := CheckoutFromContext(ctx); got != checkout {
t.Errorf("CheckoutFromContext() = %p, want %p", got, checkout)
}
other := &Checkout{Root: "/other"}
if got := CheckoutFromContext(WithCheckout(ctx, other)); got != other {
t.Errorf("CheckoutFromContext() after re-attaching = %p, want %p", got, other)
}
}
func TestFromContextWithoutCheckout(t *testing.T) {
if got := CheckoutFromContext(t.Context()); got != nil {
t.Errorf("CheckoutFromContext(t.Context()) = %p, want nil", got)
}
}
func TestEnvVarsFallbackToOSEnviron(t *testing.T) {
t.Setenv("JIRI_TEST_ENVVARS_FALLBACK", "expected_val")
if got := EnvVars(t.Context())["JIRI_TEST_ENVVARS_FALLBACK"]; got != "expected_val" {
t.Errorf("EnvVars(t.Context())[JIRI_TEST_ENVVARS_FALLBACK] = %q, want %q", got, "expected_val")
}
}
func TestWithStdoutAndStderr(t *testing.T) {
var origOut, origErr, newOut, newErr strings.Builder
ctx := cmdline.AddEnvToContext(t.Context(), &cmdline.Env{
Stdout: &origOut,
Stderr: &origErr,
Vars: map[string]string{"FOO": "bar"},
})
derived := WithStderr(WithStdout(ctx, &newOut), &newErr)
if Stdout(derived) != &newOut || Stderr(derived) != &newErr {
t.Errorf("derived ctx doesn't use the overridden streams")
}
if Stdout(ctx) != &origOut || Stderr(ctx) != &origErr {
t.Errorf("overriding streams changed the original ctx")
}
if got := EnvVars(derived)["FOO"]; got != "bar" {
t.Errorf("EnvVars(derived)[FOO] = %q, want %q", got, "bar")
}
}
func TestUsageErrorf(t *testing.T) {
var stderr strings.Builder
ctx := cmdline.AddEnvToContext(t.Context(), &cmdline.Env{Stderr: io.Discard})
ctx = WithStderr(ctx, &stderr)
err := UsageErrorf(ctx, "bad flag %q", "-x")
if !errors.Is(err, cmdline.ErrUsage) {
t.Errorf("UsageErrorf() = %s, want %s", err, cmdline.ErrUsage)
}
if !strings.Contains(stderr.String(), `bad flag "-x"`) {
t.Errorf("stderr = %q, want it to contain the message", stderr.String())
}
}
func TestNewContextPrependsBinDirToPath(t *testing.T) {
root := t.TempDir()
if err := os.Mkdir(filepath.Join(root, RootMetaDir), 0o755); err != nil {
t.Fatal(err)
}
const origPath = "/usr/bin"
newCtx := func(t *testing.T, vars map[string]string) context.Context {
t.Helper()
ctx := cmdline.AddEnvToContext(t.Context(), &cmdline.Env{
Stdout: io.Discard,
Stderr: io.Discard,
Vars: vars,
})
ctx, err := NewContext(ctx, TopLevelFlags{Root: root, Jobs: 1, Color: "never"})
if err != nil {
t.Fatalf("NewContext failed: %s", err)
}
return ctx
}
t.Run("prepends", func(t *testing.T) {
t.Setenv("PATH", origPath)
vars := map[string]string{"PATH": origPath}
ctx := newCtx(t, vars)
binDir := CheckoutFromContext(ctx).BinDir()
want := binDir + string(os.PathListSeparator) + origPath
if got := EnvVars(ctx)["PATH"]; got != want {
t.Errorf("EnvVars(ctx)[PATH] = %q, want %q", got, want)
}
if got := os.Getenv("PATH"); got != want {
t.Errorf("os PATH = %q, want %q", got, want)
}
if vars["PATH"] != origPath {
t.Errorf("original env vars were modified: PATH = %q", vars["PATH"])
}
})
t.Run("preserved", func(t *testing.T) {
t.Setenv("PATH", origPath)
ctx := newCtx(t, map[string]string{"PATH": origPath, PreservePathEnv: "1"})
if got := EnvVars(ctx)["PATH"]; got != origPath {
t.Errorf("EnvVars(ctx)[PATH] = %q, want %q", got, origPath)
}
if got := os.Getenv("PATH"); got != origPath {
t.Errorf("os PATH = %q, want %q", got, origPath)
}
})
}