173 lines
4.5 KiB
Go
173 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func must[T any](t T, err error) T {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return t
|
|
}
|
|
|
|
var defaultOptions options = options{
|
|
tongue: " ",
|
|
eyes: "oo",
|
|
leftEye: "o",
|
|
rightEye: "o",
|
|
wrapWidth: 40,
|
|
}
|
|
|
|
func TestGenerateCow(t *testing.T) {
|
|
type args struct {
|
|
cow string
|
|
say string
|
|
opt options
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
expected string
|
|
}{
|
|
{
|
|
name: "basic cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "test text",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/basic.cow"))),
|
|
},
|
|
{
|
|
name: "single-paragraph test",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "test\ntext",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/one_paragraph.cow"))),
|
|
},
|
|
{
|
|
name: "multiline with wordwrap test",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "this is a long block of text.\nIt goes over many lines! It'll even word-wrap for us.",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/longer_multiline.cow"))),
|
|
},
|
|
{
|
|
name: "two-paragraph multiline with wordwrap test",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "this is a long block of text.\n\nIt goes over many lines! It'll even word-wrap for us.",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/two_paragraph_multiline.cow"))),
|
|
},
|
|
{
|
|
name: "offset bubble",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/dragon-and-cow.cow"))),
|
|
say: "this is a long block of text.\nIt goes over many lines! It'll even word-wrap for us.",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/dragon.cow"))),
|
|
},
|
|
{
|
|
name: "leading space cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: " text",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/leading_space.cow"))),
|
|
},
|
|
{
|
|
name: "extra spaces cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "some text",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/extra_spaces.cow"))),
|
|
},
|
|
{
|
|
name: "vertical tab cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "some\vtext",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/extra_spaces.cow"))),
|
|
},
|
|
{
|
|
name: "a word that's too long cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: "00000000000000000000000000000000000000000000000000 11",
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/too_long.cow"))),
|
|
},
|
|
{
|
|
name: "fortune cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: `Most people eat as though they were fattening themselves for market.
|
|
-- E.W. Howe`,
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/fortune.cow"))),
|
|
},
|
|
{
|
|
name: "trailing space cow",
|
|
args: args{
|
|
cow: string(must(os.ReadFile("./cows/default.cow"))),
|
|
say: `test `,
|
|
opt: defaultOptions,
|
|
},
|
|
expected: string(must(os.ReadFile("./testdata/trailing_space.cow"))),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
out := generateCow(tt.args.cow, tt.args.say, tt.args.opt)
|
|
if out != tt.expected {
|
|
t.Logf("expected: \n%v", tt.expected)
|
|
t.Logf("got: \n%v", out)
|
|
t.Fatal()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// fuzz testing requires perl to be installed and in the PATH
|
|
func FuzzCow(f *testing.F) {
|
|
cowString := string(must(os.ReadFile("./cows/default.cow")))
|
|
f.Add("phrase")
|
|
f.Add("phrase with many many words in it so that we get a word-wrap situation")
|
|
f.Fuzz(func(t *testing.T, phrase string) {
|
|
if strings.TrimSpace(phrase) != phrase || phrase == "" {
|
|
// uninteresting degenerate cases where there's a bug in the perl
|
|
t.Skip()
|
|
}
|
|
res := generateCow(cowString, phrase, options{tongue: " ", eyes: "oo", wrapWidth: 40})
|
|
cmd := exec.Command("perl", "./perl/cowsay", "-f", "./perl/cows/default.cow")
|
|
cmd.Stdin = strings.NewReader(phrase)
|
|
var out strings.Builder
|
|
cmd.Stdout = &out
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if res != out.String() {
|
|
t.Errorf("mismatch between perl and go.\nPerl:\n%s\ngo:\n%s", out.String(), res)
|
|
}
|
|
})
|
|
}
|