wand/tools/execwand_test.go

203 lines
4.4 KiB
Go
Raw Permalink Normal View History

2025-12-30 16:52:10 +01:00
package tools
import (
"bytes"
"code.squareroundforest.org/arpio/notation"
"fmt"
"os"
"path/filepath"
"testing"
)
func TestExec(t *testing.T) {
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
cacheDir := filepath.Join(wd, "../internal/tests/tmpdir")
selfReplace := filepath.Join(wd, "..")
baseOpt := ExecOptions{
ClearCache: true,
CacheDir: cacheDir,
ReplaceModule: []string{fmt.Sprintf("%s=%s", selfPkg, selfReplace)},
}
t.Run("stdin", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBufferString("strings.Split 1,2,3 ,")
o := baseOpt
o.Import = []string{"strings"}
if err := execInput(o, in, &stdout, &stderr); err != nil {
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.String() != "1\n2\n3\n" {
t.Fatal(stdout.String())
}
})
t.Run("stdin multiple lines", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBufferString("strings.Split 1,2,3 ,\nstrings.Split 4,5,6 ,")
o := baseOpt
o.Import = []string{"strings"}
if err := execInput(o, in, &stdout, &stderr); err != nil {
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.String() != "1\n2\n3\n4\n5\n6\n" {
t.Fatal(stdout.String())
}
})
t.Run("args", func(t *testing.T) {
var stdin, stdout, stderr bytes.Buffer
o := baseOpt
o.Import = []string{"strings"}
if err := execInput(o, &stdin, &stdout, &stderr, "strings.Split", "1,2,3", ","); err != nil {
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.String() != "1\n2\n3\n" {
t.Fatal(stdout.String())
}
})
t.Run("inline import", func(t *testing.T) {
var stdin, stdout, stderr bytes.Buffer
o := baseOpt
o.Import = []string{".=strings"}
if err := execInput(o, &stdin, &stdout, &stderr, "Split", "1,2,3", ","); err != nil {
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.String() != "1\n2\n3\n" {
t.Fatal(stdout.String())
}
})
t.Run("named import", func(t *testing.T) {
var stdin, stdout, stderr bytes.Buffer
o := baseOpt
o.Import = []string{"str=strings"}
if err := execInput(o, &stdin, &stdout, &stderr, "str.Split", "1,2,3", ","); err != nil {
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.String() != "1\n2\n3\n" {
t.Fatal(stdout.String())
}
})
t.Run("io args", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBuffer([]byte{0, 1, 2})
o := baseOpt
o.Import = []string{"io", "bytes"}
expr := `func(in io.Reader) (out io.Reader) {
out = bytes.NewBuffer(nil)
buf := make([]byte, 1)
for {
n, err := in.Read(buf)
if n == 1 {
buf[0] = buf[0] * 2
out.(io.Writer).Write(buf)
}
if err != nil {
return out
}
}
return out
}`
if err := execInput(o, in, &stdout, &stderr, expr); err != nil {
t.Log(stderr.String())
t.Fatal(err)
}
if stderr.String() != "" {
t.Fatal(stderr.String())
}
if stdout.Len() != 3 || stdout.Bytes()[0] != 0 || stdout.Bytes()[1] != 2 || stdout.Bytes()[2] != 4 {
t.Fatal(notation.Sprint(stdout.Bytes()))
}
})
t.Run("escape", func(t *testing.T) {
t.Run("full", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBufferString("'func(a string) { println(a) }' 'foo'")
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
t.Log(stderr.String())
t.Fatal(err)
}
if stderr.String() != "foo\n" {
t.Fatal(stderr.String())
}
if stdout.String() != "" {
t.Fatal(stdout.String())
}
})
t.Run("one", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBufferString("'func(a string) { println(a) }' foo\\ bar")
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
t.Log(stderr.String())
t.Fatal(err)
}
if stderr.String() != "foo bar\n" {
t.Fatal(stderr.String())
}
if stdout.String() != "" {
t.Fatal(stdout.String())
}
})
t.Run("one and partial", func(t *testing.T) {
var stdout, stderr bytes.Buffer
in := bytes.NewBufferString("'func(a string) { println(a) }' \"\\'foo\\'\"")
if err := execInput(baseOpt, in, &stdout, &stderr); err != nil {
t.Log(stderr.String())
t.Fatal(err)
}
if stderr.String() != "'foo'\n" {
t.Fatal(stderr.String())
}
if stdout.String() != "" {
t.Fatal(stdout.String())
}
})
})
}