88a8aecdd4
For example when failing to decode toml, display the context around the error and the location of the problem.
173 lines
4.1 KiB
Go
173 lines
4.1 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/pelletier/go-toml/v2"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func processMain(args []string, input io.Reader, stdout, stderr io.Writer, f ConvertFn) int {
|
|
p := Program{Fn: f}
|
|
return p.main(args, input, stdout, stderr)
|
|
}
|
|
|
|
func TestProcessMainStdin(t *testing.T) {
|
|
stdout := new(bytes.Buffer)
|
|
stderr := new(bytes.Buffer)
|
|
input := strings.NewReader("this is the input")
|
|
|
|
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
|
return nil
|
|
})
|
|
|
|
assert.Equal(t, 0, exit)
|
|
assert.Empty(t, stdout.String())
|
|
assert.Empty(t, stderr.String())
|
|
}
|
|
|
|
func TestProcessMainStdinErr(t *testing.T) {
|
|
stdout := new(bytes.Buffer)
|
|
stderr := new(bytes.Buffer)
|
|
input := strings.NewReader("this is the input")
|
|
|
|
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
|
return fmt.Errorf("something bad")
|
|
})
|
|
|
|
assert.Equal(t, -1, exit)
|
|
assert.Empty(t, stdout.String())
|
|
assert.NotEmpty(t, stderr.String())
|
|
}
|
|
|
|
func TestProcessMainStdinDecodeErr(t *testing.T) {
|
|
stdout := new(bytes.Buffer)
|
|
stderr := new(bytes.Buffer)
|
|
input := strings.NewReader("this is the input")
|
|
|
|
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
|
var v interface{}
|
|
return toml.Unmarshal([]byte(`qwe = 001`), &v)
|
|
})
|
|
|
|
assert.Equal(t, -1, exit)
|
|
assert.Empty(t, stdout.String())
|
|
assert.Contains(t, stderr.String(), "error occurred at")
|
|
}
|
|
|
|
func TestProcessMainFileExists(t *testing.T) {
|
|
tmpfile, err := ioutil.TempFile("", "example")
|
|
require.NoError(t, err)
|
|
defer os.Remove(tmpfile.Name())
|
|
_, err = tmpfile.Write([]byte(`some data`))
|
|
require.NoError(t, err)
|
|
|
|
stdout := new(bytes.Buffer)
|
|
stderr := new(bytes.Buffer)
|
|
|
|
exit := processMain([]string{tmpfile.Name()}, nil, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
|
return nil
|
|
})
|
|
|
|
assert.Equal(t, 0, exit)
|
|
assert.Empty(t, stdout.String())
|
|
assert.Empty(t, stderr.String())
|
|
}
|
|
|
|
func TestProcessMainFileDoesNotExist(t *testing.T) {
|
|
stdout := new(bytes.Buffer)
|
|
stderr := new(bytes.Buffer)
|
|
|
|
exit := processMain([]string{"/lets/hope/this/does/not/exist"}, nil, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
|
return nil
|
|
})
|
|
|
|
assert.Equal(t, -1, exit)
|
|
assert.Empty(t, stdout.String())
|
|
assert.NotEmpty(t, stderr.String())
|
|
}
|
|
|
|
func TestProcessMainFilesInPlace(t *testing.T) {
|
|
dir, err := ioutil.TempDir("", "")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(dir)
|
|
|
|
path1 := path.Join(dir, "file1")
|
|
path2 := path.Join(dir, "file2")
|
|
|
|
err = ioutil.WriteFile(path1, []byte("content 1"), 0600)
|
|
require.NoError(t, err)
|
|
err = ioutil.WriteFile(path2, []byte("content 2"), 0600)
|
|
require.NoError(t, err)
|
|
|
|
p := Program{
|
|
Fn: dummyFileFn,
|
|
Inplace: true,
|
|
}
|
|
|
|
exit := p.main([]string{path1, path2}, os.Stdin, os.Stdout, os.Stderr)
|
|
|
|
require.Equal(t, 0, exit)
|
|
|
|
v1, err := ioutil.ReadFile(path1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "1", string(v1))
|
|
|
|
v2, err := ioutil.ReadFile(path2)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "2", string(v2))
|
|
}
|
|
|
|
func TestProcessMainFilesInPlaceErrRead(t *testing.T) {
|
|
p := Program{
|
|
Fn: dummyFileFn,
|
|
Inplace: true,
|
|
}
|
|
|
|
exit := p.main([]string{"/this/path/is/invalid"}, os.Stdin, os.Stdout, os.Stderr)
|
|
|
|
require.Equal(t, -1, exit)
|
|
}
|
|
|
|
func TestProcessMainFilesInPlaceFailFn(t *testing.T) {
|
|
dir, err := ioutil.TempDir("", "")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(dir)
|
|
|
|
path1 := path.Join(dir, "file1")
|
|
|
|
err = ioutil.WriteFile(path1, []byte("content 1"), 0600)
|
|
require.NoError(t, err)
|
|
|
|
p := Program{
|
|
Fn: func(io.Reader, io.Writer) error { return fmt.Errorf("oh no") },
|
|
Inplace: true,
|
|
}
|
|
|
|
exit := p.main([]string{path1}, os.Stdin, os.Stdout, os.Stderr)
|
|
|
|
require.Equal(t, -1, exit)
|
|
|
|
v1, err := ioutil.ReadFile(path1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "content 1", string(v1))
|
|
}
|
|
|
|
func dummyFileFn(r io.Reader, w io.Writer) error {
|
|
b, err := ioutil.ReadAll(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
v := strings.SplitN(string(b), " ", 2)[1]
|
|
_, err = w.Write([]byte(v))
|
|
return err
|
|
}
|