Repository navigation
Expand file tree
/
Copy pathinput_test.go
More file actions
155 lines (143 loc) · 4.55 KB
/
Copy pathinput_test.go
File metadata and controls
155 lines (143 loc) · 4.55 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestChooseInput(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "t.json")
require.NoError(t, os.WriteFile(file, []byte(`{"b":1}`), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "keys"), []byte(`{}`), 0o644))
t.Chdir(dir)
const (
tty = "tty"
devNull = "/dev/null"
pipe = "pipe" // empty pipe, pipe with data or open pipe: all look the same here
)
tests := []struct {
name string
stdin string
args []string
want inputSource
}{
{"tty no args", tty, nil, inputUsage},
{"tty file", tty, []string{"t.json", ".b"}, inputFile},
{"tty missing file", tty, []string{"missing.json"}, inputFile},
{"tty bare identifier file", tty, []string{"keys"}, inputFile},
{"dev null no args", devNull, nil, inputUsage},
{"dev null file", devNull, []string{"t.json", ".b"}, inputFile},
{"pipe no args", pipe, nil, inputStdin},
{"pipe file", pipe, []string{"t.json", ".b"}, inputFile},
{"pipe file only", pipe, []string{"t.json"}, inputFile},
{"pipe absolute file", pipe, []string{file, ".b"}, inputFile},
{"pipe code", pipe, []string{".name"}, inputStdin},
{"pipe nonexistent path", pipe, []string{"missing.json", ".b"}, inputStdin},
{"pipe directory", pipe, []string{dir}, inputStdin},
{"pipe dot directory", pipe, []string{"."}, inputStdin},
{"pipe bare identifier file", pipe, []string{"keys"}, inputStdin},
{"pipe dotted bare identifier file", pipe, []string{"./keys"}, inputFile},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := chooseInput(tt.stdin == tty, tt.stdin == pipe, tt.args, os.Stat)
require.Equal(t, tt.want, got)
})
}
}
// TestMain lets tests run the fx binary by re-executing the test binary.
func TestMain(m *testing.M) {
if os.Getenv("FX_TEST_RUN_MAIN") == "1" {
args := strings.Fields(os.Getenv("FX_TEST_ARGS"))
if argv, ok := os.LookupEnv("FX_TEST_ARGV"); ok {
args = strings.Split(argv, argvSep) // Args may contain spaces.
}
os.Args = append([]string{"fx"}, args...)
main()
os.Exit(0)
}
os.Exit(m.Run())
}
func runFx(t *testing.T, stdin func(cmd *exec.Cmd), args ...string) (string, error) {
cmd := exec.Command(os.Args[0], "-test.run=^$")
cmd.Env = append(os.Environ(), "FX_TEST_RUN_MAIN=1", "FX_TEST_ARGS="+strings.Join(args, " "))
stdin(cmd)
done := make(chan struct{})
var out []byte
var err error
go func() {
out, err = cmd.CombinedOutput()
close(done)
}()
select {
case <-done:
case <-time.After(10 * time.Second):
_ = cmd.Process.Kill()
t.Fatal("fx hung")
}
return strings.TrimSpace(string(out)), err
}
func TestFileArgWithNonTtyStdin(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "t.json")
require.NoError(t, os.WriteFile(file, []byte(`{"b":1}`), 0o644))
tests := []struct {
name string
stdin func(t *testing.T, cmd *exec.Cmd)
}{
{"dev null", func(t *testing.T, cmd *exec.Cmd) {
f, err := os.Open(os.DevNull)
require.NoError(t, err)
t.Cleanup(func() { f.Close() })
cmd.Stdin = f
}},
{"empty pipe", func(t *testing.T, cmd *exec.Cmd) {
cmd.Stdin = strings.NewReader("")
}},
{"pipe with data", func(t *testing.T, cmd *exec.Cmd) {
cmd.Stdin = strings.NewReader(`{"x":1}`)
}},
{"pipe left open", func(t *testing.T, cmd *exec.Cmd) {
r, w, err := os.Pipe()
require.NoError(t, err)
t.Cleanup(func() { r.Close(); w.Close() })
cmd.Stdin = r
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out, err := runFx(t, func(cmd *exec.Cmd) { tt.stdin(t, cmd) }, file, ".b")
require.NoError(t, err, out)
require.Equal(t, "1", out)
})
}
}
func TestEmptyInputExitsNonZero(t *testing.T) {
dir := t.TempDir()
for _, input := range []string{"", " \n\t\r\n"} {
file := filepath.Join(dir, "t.json")
require.NoError(t, os.WriteFile(file, []byte(input), 0o644))
for _, args := range [][]string{{"."}, {".a"}} {
out, err := runFx(t, func(cmd *exec.Cmd) {
cmd.Stdin = strings.NewReader(input)
}, args...)
require.Error(t, err, "stdin %q, args %v", input, args)
require.Equal(t, errEmptyInput.Error(), out)
out, err = runFx(t, func(cmd *exec.Cmd) {}, append([]string{file}, args...)...)
require.Error(t, err, "file %q, args %v", input, args)
require.Equal(t, errEmptyInput.Error(), out)
}
}
}
func TestPipedStdinStillWorks(t *testing.T) {
out, err := runFx(t, func(cmd *exec.Cmd) {
cmd.Stdin = io.NopCloser(strings.NewReader(`{"name":"fx"}`))
}, ".name")
require.NoError(t, err, out)
require.Equal(t, "fx", out)
}