summaryrefslogtreecommitdiff
path: root/internal/hexaicli/simulation_test.go
blob: 4c3533ded68eaa87e0c1a2a8b8ed73389aeeb535 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package hexaicli

import (
	"bytes"
	"context"
	"strings"
	"testing"

	"codeberg.org/snonux/hexai/internal/appconfig"
	"codeberg.org/snonux/hexai/internal/llm"
)

func TestParseTPSSimulation(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name    string
		value   string
		wantMin float64
		wantMax float64
		wantErr bool
	}{
		{name: "single value", value: "12", wantMin: 12, wantMax: 12},
		{name: "dash range", value: "8-16", wantMin: 8, wantMax: 16},
		{name: "colon range", value: "4:9", wantMin: 4, wantMax: 9},
		{name: "empty", value: "", wantErr: true},
		{name: "zero", value: "0", wantErr: true},
		{name: "reversed", value: "20-10", wantErr: true},
		{name: "invalid", value: "fast", wantErr: true},
	}

	for _, tc := range tests {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			spec, err := parseTPSSimulation(tc.value)
			if tc.wantErr {
				if err == nil {
					t.Fatalf("expected error for %q", tc.value)
				}
				return
			}
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if spec.min != tc.wantMin || spec.max != tc.wantMax {
				t.Fatalf("unexpected spec: %+v", spec)
			}
		})
	}
}

func TestReadSimulationInput_DefaultsToSampleText(t *testing.T) {
	restore, f := setStdin(t, "")
	defer restore()

	input, err := readSimulationInput(f, nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if !strings.Contains(input, "Hexai TPS simulation mode") {
		t.Fatalf("expected default simulation text, got %q", input)
	}
}

func TestRun_TPSSimulationBypassesClientSetup(t *testing.T) {
	oldNew := newClientFromApp
	defer func() { newClientFromApp = oldNew }()
	newClientFromApp = func(appconfig.App) (llm.Client, error) {
		t.Fatalf("client setup should not be called in TPS simulation mode")
		return nil, nil
	}

	var out, errb bytes.Buffer
	ctx := WithCLITPSSimulation(context.Background(), "1000000")
	if err := Run(ctx, []string{"simulated", "output"}, strings.NewReader(""), &out, &errb); err != nil {
		t.Fatalf("Run returned error: %v", err)
	}
	if out.String() != "simulated output" {
		t.Fatalf("unexpected simulation output: %q", out.String())
	}
	if errb.Len() != 0 {
		t.Fatalf("expected empty stderr, got %q", errb.String())
	}
}

func TestRun_TPSSimulationUsesStdin(t *testing.T) {
	oldNew := newClientFromApp
	defer func() { newClientFromApp = oldNew }()
	newClientFromApp = func(appconfig.App) (llm.Client, error) {
		t.Fatalf("client setup should not be called in TPS simulation mode")
		return nil, nil
	}

	restore, f := setStdin(t, "from-stdin")
	defer restore()

	var out, errb bytes.Buffer
	ctx := WithCLITPSSimulation(context.Background(), "1000000")
	if err := Run(ctx, nil, f, &out, &errb); err != nil {
		t.Fatalf("Run returned error: %v", err)
	}
	if out.String() != "from-stdin" {
		t.Fatalf("unexpected simulation output: %q", out.String())
	}
	if errb.Len() != 0 {
		t.Fatalf("expected empty stderr, got %q", errb.String())
	}
}