Skip to content

Commit

Permalink
improve tests (#162)
Browse files Browse the repository at this point in the history
* parallelize tests

* update goldens

* add missing tests
  • Loading branch information
ktr0731 committed Oct 23, 2022
1 parent 0ffa9a7 commit 3ecdbfe
Show file tree
Hide file tree
Showing 33 changed files with 559 additions and 396 deletions.
10 changes: 5 additions & 5 deletions example/go.mod
Expand Up @@ -12,13 +12,13 @@ require (

require (
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.4.0 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/gdamore/tcell/v2 v2.5.3 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/text v0.3.7 // indirect
)
26 changes: 12 additions & 14 deletions example/go.sum
@@ -1,36 +1,34 @@
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM=
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gdamore/tcell/v2 v2.5.3 h1:b9XQrT6QGbgI7JvZOJXFNczOQeIYbo8BfeSMzt2sAV0=
github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00 h1:Rl8NelBe+n7SuLbJyw13ho7CGWUt2BjGGKIoreCWQ/c=
github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 h1:saXMvIOKvRFwbOMicHXr0B1uwoxq9dGmLe5ExMES6c4=
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
224 changes: 152 additions & 72 deletions fuzzyfinder_test.go
Expand Up @@ -118,100 +118,162 @@ func TestReal(t *testing.T) {
}

func TestFind(t *testing.T) {
t.Parallel()

cases := map[string]struct {
events []tcell.Event
opts []fuzzyfinder.Option
}{
"initial": {},
"input lo": {runes("lo")},
"input glow": {runes("glow")},
"arrow up-down": {keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyDown, rune(tcell.KeyDown), tcell.ModNone},
}...)},
"arrow left-right": {append(runes("ゆるふわ樹海"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyRight, rune(tcell.KeyRight), tcell.ModNone},
}...)...)},
"backspace": {append(runes("adr .-"), keys([]input{
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
}...)...)},
"backspace empty": {keys(input{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone})},
"backspace2": {append(runes("オレンジ"), keys([]input{
{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone},
{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone},
}...)...)},
"arrow left backspace": {append(runes("オレンジ"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
}...)...)},
"delete": {append(runes("オレンジ"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyDelete, rune(tcell.KeyDelete), tcell.ModNone},
}...)...)},
"delete empty": {keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyDelete, rune(tcell.KeyDelete), tcell.ModNone},
}...)},
"ctrl-e": {append(runes("恋をしたのは"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyCtrlE, 'E', tcell.ModCtrl},
}...)...)},
"ctrl-w": {append(runes("ハロ / ハワユ"), keys(input{tcell.KeyCtrlW, 'W', tcell.ModCtrl})...)},
"ctrl-w empty": {keys(input{tcell.KeyCtrlW, 'W', tcell.ModCtrl})},
"ctrl-u": {append(runes("恋をしたのは"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyCtrlU, 'U', tcell.ModCtrl},
{tcell.KeyRight, rune(tcell.KeyRight), tcell.ModNone},
}...)...)},
"long item": {keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
}...)},
"paging": {keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
}...)},
"tab doesn't work": {keys(input{tcell.KeyTab, rune(tcell.KeyTab), tcell.ModNone})},
"backspace doesnt change x if cursorX is 0": {append(runes("a"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
{tcell.KeyCtrlF, 'F', tcell.ModCtrl},
}...)...)},
"input lo": {events: runes("lo")},
"input glow": {events: runes("glow")},
"arrow up-down": {
events: keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyDown, rune(tcell.KeyDown), tcell.ModNone},
}...)},
"arrow left-right": {
events: append(runes("ゆるふわ樹海"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyRight, rune(tcell.KeyRight), tcell.ModNone},
}...)...),
},
"backspace": {
events: append(runes("adr .-"), keys([]input{
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
}...)...),
},
"backspace empty": {events: keys(input{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone})},
"backspace2": {
events: append(runes("オレンジ"), keys([]input{
{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone},
{tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone},
}...)...),
},
"arrow left backspace": {
events: append(runes("オレンジ"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
}...)...),
},
"delete": {
events: append(runes("オレンジ"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyDelete, rune(tcell.KeyDelete), tcell.ModNone},
}...)...),
},
"delete empty": {
events: keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyDelete, rune(tcell.KeyDelete), tcell.ModNone},
}...),
},
"ctrl-e": {
events: append(runes("恋をしたのは"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyCtrlE, 'E', tcell.ModCtrl},
}...)...),
},
"ctrl-w": {events: append(runes("ハロ / ハワユ"), keys(input{tcell.KeyCtrlW, 'W', tcell.ModCtrl})...)},
"ctrl-w empty": {events: keys(input{tcell.KeyCtrlW, 'W', tcell.ModCtrl})},
"ctrl-u": {
events: append(runes("恋をしたのは"), keys([]input{
{tcell.KeyLeft, rune(tcell.KeyLeft), tcell.ModNone},
{tcell.KeyCtrlU, 'U', tcell.ModCtrl},
{tcell.KeyRight, rune(tcell.KeyRight), tcell.ModNone},
}...)...),
},
"pg-up": {
events: keys([]input{
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
}...),
},
"pg-up twice": {
events: keys([]input{
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
}...),
},
"pg-dn": {
events: keys([]input{
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
{tcell.KeyPgDn, rune(tcell.KeyPgDn), tcell.ModNone},
}...),
},
"pg-dn twice": {
events: keys([]input{
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
{tcell.KeyPgUp, rune(tcell.KeyPgUp), tcell.ModNone},
{tcell.KeyPgDn, rune(tcell.KeyPgDn), tcell.ModNone},
{tcell.KeyPgDn, rune(tcell.KeyPgDn), tcell.ModNone},
}...),
},
"long item": {
events: keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
}...),
},
"paging": {
events: keys([]input{
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
{tcell.KeyUp, rune(tcell.KeyUp), tcell.ModNone},
}...),
},
"tab doesn't work": {events: keys(input{tcell.KeyTab, rune(tcell.KeyTab), tcell.ModNone})},
"backspace doesnt change x if cursorX is 0": {
events: append(runes("a"), keys([]input{
{tcell.KeyCtrlA, 'A', tcell.ModCtrl},
{tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone},
{tcell.KeyCtrlF, 'F', tcell.ModCtrl},
}...)...),
},
"cursor begins at top": {opts: []fuzzyfinder.Option{fuzzyfinder.WithCursorPosition(fuzzyfinder.CursorPositionTop)}},
"header line": {opts: []fuzzyfinder.Option{fuzzyfinder.WithHeader("Search?")}},
"header line which exceeds max charaters": {opts: []fuzzyfinder.Option{fuzzyfinder.WithHeader("Waht do you want to search for?")}},
}

for name, c := range cases {
c := c

t.Run(name, func(t *testing.T) {
t.Parallel()

events := c.events

f, term := fuzzyfinder.NewWithMockedTerminal()
events = append(events, key(input{tcell.KeyEsc, rune(tcell.KeyEsc), tcell.ModNone}))
term.SetEventsV2(events...)

opts := append(
c.opts,
fuzzyfinder.WithPreviewWindow(func(i, width, height int) string {
if i == -1 {
return "not found"
}
return "Name: " + tracks[i].Name + "\nArtist: " + tracks[i].Artist
}),
fuzzyfinder.WithMode(fuzzyfinder.ModeCaseSensitive),
)

assertWithGolden(t, func(t *testing.T) string {
_, err := f.Find(
tracks,
func(i int) string {
return tracks[i].Name
},
fuzzyfinder.WithPreviewWindow(func(i, width, height int) string {
if i == -1 {
return "not found"
}
return "Name: " + tracks[i].Name + "\nArtist: " + tracks[i].Artist
}),
fuzzyfinder.WithMode(fuzzyfinder.ModeCaseSensitive),
opts...,
)
if !errors.Is(err, fuzzyfinder.ErrAbort) {
t.Fatalf("Find must return ErrAbort, but got '%s'", err)
Expand All @@ -225,6 +287,8 @@ func TestFind(t *testing.T) {
}

func TestFind_hotReload(t *testing.T) {
t.Parallel()

f, term := fuzzyfinder.NewWithMockedTerminal()
events := append(runes("adrena"), keys(input{tcell.KeyEsc, rune(tcell.KeyEsc), tcell.ModNone})...)
term.SetEventsV2(events...)
Expand Down Expand Up @@ -261,6 +325,8 @@ func TestFind_hotReload(t *testing.T) {
}

func TestFind_hotReloadLock(t *testing.T) {
t.Parallel()

f, term := fuzzyfinder.NewWithMockedTerminal()
events := append(runes("adrena"), keys(input{tcell.KeyEsc, rune(tcell.KeyEsc), tcell.ModNone})...)
term.SetEventsV2(events...)
Expand Down Expand Up @@ -295,6 +361,8 @@ func TestFind_hotReloadLock(t *testing.T) {
}

func TestFind_enter(t *testing.T) {
t.Parallel()

cases := map[string]struct {
events []tcell.Event
expected int
Expand All @@ -307,6 +375,8 @@ func TestFind_enter(t *testing.T) {
c := c

t.Run(name, func(t *testing.T) {
t.Parallel()

events := c.events

f, term := fuzzyfinder.NewWithMockedTerminal()
Expand All @@ -331,7 +401,11 @@ func TestFind_enter(t *testing.T) {
}

func TestFind_error(t *testing.T) {
t.Parallel()

t.Run("not a slice", func(t *testing.T) {
t.Parallel()

f := fuzzyfinder.New()
_, err := f.Find("", func(i int) string { return "" })
if err == nil {
Expand All @@ -340,6 +414,8 @@ func TestFind_error(t *testing.T) {
})

t.Run("itemFunc is nil", func(t *testing.T) {
t.Parallel()

f := fuzzyfinder.New()
_, err := f.Find([]string{}, nil)
if err == nil {
Expand All @@ -349,6 +425,8 @@ func TestFind_error(t *testing.T) {
}

func TestFindMulti(t *testing.T) {
t.Parallel()

cases := map[string]struct {
events []tcell.Event
expected []int
Expand Down Expand Up @@ -378,6 +456,8 @@ func TestFindMulti(t *testing.T) {
c := c

t.Run(name, func(t *testing.T) {
t.Parallel()

events := c.events

f, term := fuzzyfinder.NewWithMockedTerminal()
Expand Down

0 comments on commit 3ecdbfe

Please sign in to comment.