Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions cmd/batch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4058,3 +4058,74 @@ func TestBatchTemplateApply_LookupError(t *testing.T) {
t.Errorf("expected ExitError for lookup failure, got %d", code)
}
}

// TestBatch_StdinStatError covers the branch where os.Stdin.Stat() fails
// (replaced with a closed file descriptor).
func TestBatch_StdinStatError(t *testing.T) {
var stdout, stderr bytes.Buffer
c := newTestClient("http://should-not-be-called", &stdout, &stderr)

ctx := client.NewContext(t.Context(), c)
cmd := batchCmd
cmd.ResetFlags()
cmd.Flags().String("input", "", "")
cmd.Flags().Int("max-batch", 50, "")
cmd.SetContext(ctx)

// Create a pipe and close it to force a stat error.
pr, pw, _ := os.Pipe()
pw.Close()
pr.Close()

oldStdin := os.Stdin
os.Stdin = pr
defer func() { os.Stdin = oldStdin }()

err := runBatch(cmd, nil)
if err == nil {
t.Fatal("expected error when stdin is closed")
}
aw, ok := err.(*jrerrors.AlreadyWrittenError)
if !ok {
t.Fatalf("expected AlreadyWrittenError, got %T", err)
}
if aw.Code != jrerrors.ExitValidation {
t.Errorf("expected ExitValidation, got %d", aw.Code)
}
}

// TestBatch_StdinReadError covers io.ReadAll failure. A directory fd passes
// Stat() (mode is ModeDir, not ModeCharDevice) but Read returns EISDIR.
func TestBatch_StdinReadError(t *testing.T) {
var stdout, stderr bytes.Buffer
c := newTestClient("http://should-not-be-called", &stdout, &stderr)

ctx := client.NewContext(t.Context(), c)
cmd := batchCmd
cmd.ResetFlags()
cmd.Flags().String("input", "", "")
cmd.Flags().Int("max-batch", 50, "")
cmd.SetContext(ctx)

dir, err := os.Open(t.TempDir())
if err != nil {
t.Fatalf("open dir: %v", err)
}
defer dir.Close()

oldStdin := os.Stdin
os.Stdin = dir
defer func() { os.Stdin = oldStdin }()

err = runBatch(cmd, nil)
if err == nil {
t.Fatal("expected error when stdin is a directory")
}
aw, ok := err.(*jrerrors.AlreadyWrittenError)
if !ok {
t.Fatalf("expected AlreadyWrittenError, got %T", err)
}
if aw.Code != jrerrors.ExitValidation {
t.Errorf("expected ExitValidation, got %d", aw.Code)
}
}
67 changes: 67 additions & 0 deletions cmd/preset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package cmd

import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"

"github.com/spf13/cobra"
)

func TestPresetList_OutputsJSON(t *testing.T) {
Expand Down Expand Up @@ -41,3 +45,66 @@ func TestPresetList_OutputsJSON(t *testing.T) {
}
}
}

// Exercise the preset list command with --jq and --pretty flags and failure paths.

func TestPresetList_WithJQ(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("jq", "", "")
cmd.Flags().Bool("pretty", false, "")
_ = cmd.Flags().Set("jq", "[.[].name]")

if err := presetListCmd.RunE(cmd, nil); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}

func TestPresetList_WithInvalidJQ(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("jq", "", "")
cmd.Flags().Bool("pretty", false, "")
_ = cmd.Flags().Set("jq", "[.invalid")

err := presetListCmd.RunE(cmd, nil)
if err == nil {
t.Fatal("expected jq error")
}
}

func TestPresetList_WithPretty(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("jq", "", "")
cmd.Flags().Bool("pretty", false, "")
_ = cmd.Flags().Set("pretty", "true")

if err := presetListCmd.RunE(cmd, nil); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}

func TestPresetList_PropagatesListError(t *testing.T) {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("XDG_CONFIG_HOME", home)
t.Setenv("APPDATA", home)
for _, p := range []string{
home + "/jr/presets.json",
home + "/Library/Application Support/jr/presets.json",
} {
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(p, []byte("not-json"), 0o600); err != nil {
t.Fatal(err)
}
}

cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("jq", "", "")
cmd.Flags().Bool("pretty", false, "")

err := presetListCmd.RunE(cmd, nil)
if err == nil {
t.Fatal("expected error from preset.List")
}
}
40 changes: 40 additions & 0 deletions cmd/raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,43 @@ func TestRawCmd_BodyAtWithoutFilename(t *testing.T) {
t.Errorf("expected ExitValidation, got %d", aw.Code)
}
}

// TestRawCmd_StdinBody exercises --body - (explicit stdin).
func TestRawCmd_StdinBody(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, 1024)
n, _ := r.Body.Read(body)
if !strings.Contains(string(body[:n]), "piped") {
t.Errorf("expected piped body, got %q", string(body[:n]))
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, `{"ok":true}`)
}))
defer ts.Close()

r, w, err := os.Pipe()
if err != nil {
t.Fatalf("pipe: %v", err)
}
origStdin := os.Stdin
os.Stdin = r
defer func() { os.Stdin = origStdin }()

go func() {
_, _ = w.Write([]byte(`{"from":"piped"}`))
_ = w.Close()
}()

var stdout, stderr bytes.Buffer
c := newTestClient(ts.URL, &stdout, &stderr)
ctx := client.NewContext(t.Context(), c)
cmd := &cobra.Command{Use: "raw"}
cmd.Flags().String("body", "", "")
cmd.Flags().StringArray("query", nil, "")
_ = cmd.Flags().Set("body", "-")
cmd.SetContext(ctx)

if err := runRaw(cmd, []string{"POST", "/test"}); err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
Loading
Loading