152 lines
3.2 KiB
Go
152 lines
3.2 KiB
Go
package main
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"bufio"
|
||
|
|
"bytes"
|
||
|
|
"errors"
|
||
|
|
"slices"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestCleanInput(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
cases := []struct {
|
||
|
|
name string
|
||
|
|
input string
|
||
|
|
expected []string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "it should split words at whitepspace",
|
||
|
|
input: "stevan reece freeborn",
|
||
|
|
expected: []string{"stevan", "reece", "freeborn"},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "it should trim leading and or training whitespace",
|
||
|
|
input: " hello world ",
|
||
|
|
expected: []string{"hello", "world"},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "it should normalize words to lowercase",
|
||
|
|
input: "got to catch them ALL",
|
||
|
|
expected: []string{"got", "to", "catch", "them", "all"},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, c := range cases {
|
||
|
|
t.Run(c.name, func(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
result := cleanInput(c.input)
|
||
|
|
|
||
|
|
if slices.Equal(result, c.expected) {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Errorf("received %v but expected %v", result, c.expected)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
type erroringInputScanner struct {
|
||
|
|
timesCalled int
|
||
|
|
}
|
||
|
|
|
||
|
|
func (m *erroringInputScanner) Err() error {
|
||
|
|
if m.timesCalled == 0 {
|
||
|
|
m.timesCalled += 1
|
||
|
|
return errors.New("oh no!")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (m *erroringInputScanner) Text() string {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
|
||
|
|
func (m *erroringInputScanner) Scan() bool {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunRepl(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
cases := []struct {
|
||
|
|
name string
|
||
|
|
input string
|
||
|
|
expected string
|
||
|
|
getScanner func(*strings.Reader) inputScanner
|
||
|
|
sanitizer func(string) []string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "it should print custom prompt",
|
||
|
|
input: "",
|
||
|
|
expected: "Pokedex > ",
|
||
|
|
getScanner: func(r *strings.Reader) inputScanner {
|
||
|
|
return bufio.NewScanner(r)
|
||
|
|
},
|
||
|
|
sanitizer: cleanInput,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "it should print appropriate error message when scan fails",
|
||
|
|
input: "",
|
||
|
|
expected: "Pokedex > Sorry I didn't get that.",
|
||
|
|
getScanner: func(r *strings.Reader) inputScanner {
|
||
|
|
return &erroringInputScanner{}
|
||
|
|
},
|
||
|
|
sanitizer: cleanInput,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "it should print appropriate error message when sanitizer returns no words",
|
||
|
|
input: "Hi! my command is hello\n",
|
||
|
|
expected: "Pokedex > Sorry I couldn't understand that.",
|
||
|
|
getScanner: func(r *strings.Reader) inputScanner {
|
||
|
|
return bufio.NewScanner(r)
|
||
|
|
},
|
||
|
|
sanitizer: func(s string) []string {
|
||
|
|
return []string{}
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "it should print expected message for unknown command",
|
||
|
|
input: "STFU please\n",
|
||
|
|
expected: "Unknown command",
|
||
|
|
getScanner: func(r *strings.Reader) inputScanner {
|
||
|
|
return bufio.NewScanner(r)
|
||
|
|
},
|
||
|
|
sanitizer: cleanInput,
|
||
|
|
},
|
||
|
|
// TODO: Need to refactor after considering os.exit call
|
||
|
|
// {
|
||
|
|
// name: "it should execute command if found",
|
||
|
|
// input: "EXIT\n",
|
||
|
|
// expected: "Closing the Pokedex... Goodbye!\n",
|
||
|
|
// getScanner: func(r *strings.Reader) inputScanner {
|
||
|
|
// return bufio.NewScanner(r)
|
||
|
|
// },
|
||
|
|
// sanitizer: cleanInput,
|
||
|
|
// },
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, c := range cases {
|
||
|
|
t.Run(c.name, func(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
in := strings.NewReader(c.input)
|
||
|
|
out := new(bytes.Buffer)
|
||
|
|
|
||
|
|
runREPL(c.getScanner(in), out, c.sanitizer)
|
||
|
|
|
||
|
|
result := out.String()
|
||
|
|
|
||
|
|
if strings.Contains(result, c.expected) {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Errorf("expected %q to contain %q", result, c.expected)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|