1package tk
2
3import (
4	"testing"
5	"time"
6
7	"src.elv.sh/pkg/cli/term"
8	"src.elv.sh/pkg/ui"
9)
10
11var comboBoxRenderTests = []renderTest{
12	{
13		Name: "rendering codearea and listbox",
14		Given: NewComboBox(ComboBoxSpec{
15			CodeArea: CodeAreaSpec{
16				State: CodeAreaState{
17					Buffer: CodeBuffer{Content: "filter", Dot: 6}}},
18			ListBox: ListBoxSpec{
19				State: ListBoxState{Items: TestItems{NItems: 2}}}}),
20		Width: 10, Height: 24,
21		Want: term.NewBufferBuilder(10).
22			Write("filter").SetDotHere().
23			Newline().Write("item 0    ", ui.Inverse).
24			Newline().Write("item 1"),
25	},
26	{
27		Name: "calling filter before rendering",
28		Given: NewComboBox(ComboBoxSpec{
29			CodeArea: CodeAreaSpec{
30				State: CodeAreaState{
31					Buffer: CodeBuffer{Content: "filter", Dot: 6}}},
32			OnFilter: func(w ComboBox, filter string) {
33				w.ListBox().Reset(TestItems{NItems: 2}, 0)
34			}}),
35		Width: 10, Height: 24,
36		Want: term.NewBufferBuilder(10).
37			Write("filter").SetDotHere().
38			Newline().Write("item 0    ", ui.Inverse).
39			Newline().Write("item 1"),
40	},
41}
42
43func TestComboBox_Render(t *testing.T) {
44	testRender(t, comboBoxRenderTests)
45}
46
47func TestComboBox_Handle(t *testing.T) {
48	var onFilterCalled bool
49	var lastFilter string
50	w := NewComboBox(ComboBoxSpec{
51		OnFilter: func(w ComboBox, filter string) {
52			onFilterCalled = true
53			lastFilter = filter
54		},
55		ListBox: ListBoxSpec{
56			State: ListBoxState{Items: TestItems{NItems: 2}}}})
57
58	handled := w.Handle(term.K(ui.Down))
59	if !handled {
60		t.Errorf("listbox did not handle")
61	}
62	if w.ListBox().CopyState().Selected != 1 {
63		t.Errorf("listbox state not changed")
64	}
65
66	handled = w.Handle(term.K('a'))
67	if !handled {
68		t.Errorf("codearea did not handle letter key")
69	}
70	if w.CodeArea().CopyState().Buffer.Content != "a" {
71		t.Errorf("codearea state not changed")
72	}
73	if lastFilter != "a" {
74		t.Errorf("OnFilter not called when codearea content changed")
75	}
76
77	onFilterCalled = false
78	handled = w.Handle(term.PasteSetting(true))
79	if !handled {
80		t.Errorf("codearea did not handle PasteSetting")
81	}
82	if onFilterCalled {
83		t.Errorf("OnFilter called when codearea content did not change")
84	}
85	w.Handle(term.PasteSetting(false))
86
87	handled = w.Handle(term.K('D', ui.Ctrl))
88	if handled {
89		t.Errorf("key unhandled by codearea and listbox got handled")
90	}
91}
92
93func TestRefilter(t *testing.T) {
94	onFilter := make(chan string, 100)
95	w := NewComboBox(ComboBoxSpec{
96		OnFilter: func(w ComboBox, filter string) {
97			onFilter <- filter
98		}})
99	<-onFilter // Ignore the initial OnFilter call.
100	w.CodeArea().MutateState(func(s *CodeAreaState) { s.Buffer.Content = "new" })
101	w.Refilter()
102	select {
103	case f := <-onFilter:
104		if f != "new" {
105			t.Errorf("OnFilter called with %q, want 'new'", f)
106		}
107	case <-time.After(time.Second):
108		t.Errorf("OnFilter not called by Refilter")
109	}
110}
111