tile38/tests/mock_io_test.go

151 lines
2.8 KiB
Go
Raw Normal View History

2022-09-23 17:30:03 +03:00
package tests
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
2022-09-23 21:40:48 +03:00
"time"
2022-09-23 17:30:03 +03:00
"github.com/tidwall/gjson"
)
type IO struct {
2022-09-23 21:40:48 +03:00
args []any
json bool
out any
sleep bool
dur time.Duration
2022-09-24 23:41:36 +03:00
cfile string
cln int
2022-09-23 17:30:03 +03:00
}
func Do(args ...any) *IO {
2022-09-24 23:41:36 +03:00
_, cfile, cln, _ := runtime.Caller(1)
return &IO{args: args, cfile: cfile, cln: cln}
2022-09-23 17:30:03 +03:00
}
func (cmd *IO) JSON() *IO {
cmd.json = true
return cmd
}
2022-09-23 19:04:01 +03:00
func (cmd *IO) Str(s string) *IO {
2022-09-23 17:30:03 +03:00
cmd.out = s
return cmd
}
2022-09-24 01:29:46 +03:00
func (cmd *IO) Func(fn func(s string) error) *IO {
2022-09-23 17:30:03 +03:00
cmd.out = func(s string) error {
if cmd.json {
if !gjson.Valid(s) {
return errors.New("invalid json")
}
}
return fn(s)
}
return cmd
}
func (cmd *IO) OK() *IO {
2022-09-24 01:29:46 +03:00
return cmd.Func(func(s string) error {
2022-09-23 17:30:03 +03:00
if cmd.json {
if gjson.Get(s, "ok").Type != gjson.True {
return errors.New("not ok")
}
} else if s != "OK" {
return errors.New("not ok")
}
return nil
})
}
2022-09-23 19:04:01 +03:00
func (cmd *IO) Err(msg string) *IO {
2022-09-24 01:29:46 +03:00
return cmd.Func(func(s string) error {
2022-09-23 17:51:05 +03:00
if cmd.json {
if gjson.Get(s, "ok").Type != gjson.False {
return errors.New("ok=true")
}
if gjson.Get(s, "err").String() != msg {
return fmt.Errorf("expected '%s', got '%s'",
msg, gjson.Get(s, "err").String())
}
} else {
s = strings.TrimPrefix(s, "ERR ")
if s != msg {
return fmt.Errorf("expected '%s', got '%s'", msg, s)
}
}
return nil
})
}
2022-09-23 21:40:48 +03:00
func Sleep(duration time.Duration) *IO {
return &IO{sleep: true, dur: duration}
}
2022-09-23 17:30:03 +03:00
func (cmd *IO) deepError(index int, err error) error {
2022-09-24 23:41:36 +03:00
frag := "(?)"
bdata, _ := os.ReadFile(cmd.cfile)
2022-09-23 17:30:03 +03:00
data := string(bdata)
2022-09-24 23:41:36 +03:00
ln := 1
2022-09-23 17:30:03 +03:00
for i := 0; i < len(data); i++ {
if data[i] == '\n' {
2022-09-24 23:41:36 +03:00
ln++
if ln == cmd.cln {
data = data[i+1:]
i = strings.IndexByte(data, '(')
if i != -1 {
j := strings.IndexByte(data[i:], ')')
if j != -1 {
frag = string(data[i : j+i+1])
2022-09-23 17:30:03 +03:00
}
}
break
}
}
}
2022-09-24 23:41:36 +03:00
fsig := fmt.Sprintf("%s:%d", filepath.Base(cmd.cfile), cmd.cln)
emsg := err.Error()
2022-09-23 17:30:03 +03:00
if strings.HasPrefix(emsg, "expected ") &&
strings.Contains(emsg, ", got ") {
emsg = "" +
" EXPECTED: " + strings.Split(emsg, ", got ")[0][9:] + "\n" +
" GOT: " +
strings.Split(emsg, ", got ")[1]
} else {
emsg = "" +
" ERROR: " + emsg
}
return fmt.Errorf("\n%s: entry[%d]\n COMMAND: %s\n%s",
2022-09-24 23:41:36 +03:00
fsig, index+1, frag, emsg)
2022-09-23 17:30:03 +03:00
}
func (mc *mockServer) doIOTest(index int, cmd *IO) error {
2022-09-23 21:40:48 +03:00
if cmd.sleep {
time.Sleep(cmd.dur)
return nil
}
2022-09-23 17:30:03 +03:00
// switch json mode if desired
if cmd.json {
if !mc.ioJSON {
if _, err := mc.Do("OUTPUT", "json"); err != nil {
return err
}
mc.ioJSON = true
}
} else {
if mc.ioJSON {
if _, err := mc.Do("OUTPUT", "resp"); err != nil {
return err
}
mc.ioJSON = false
}
}
err := mc.DoExpect(cmd.out, cmd.args[0].(string), cmd.args[1:]...)
if err != nil {
return cmd.deepError(index, err)
}
return nil
}