Files

152 lines
3.2 KiB
Go
Raw Permalink Normal View History

2026-07-26 10:54:19 -05:00
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)
})
}
}