github.com/aretext/aretext@v1.3.0/menu/search_test.go (about)

     1  package menu
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestSearch(t *testing.T) {
    11  	testCases := []struct {
    12  		name              string
    13  		query             string
    14  		items             []Item
    15  		emptyQueryShowAll bool
    16  		expected          []Item
    17  	}{
    18  		{
    19  			name:     "no items, empty query",
    20  			query:    "",
    21  			items:    nil,
    22  			expected: nil,
    23  		},
    24  		{
    25  			name:              "no items, empty query with emptyQueryShowAll true",
    26  			query:             "",
    27  			emptyQueryShowAll: true,
    28  			items:             nil,
    29  			expected:          []Item{},
    30  		},
    31  		{
    32  			name:     "no items, nonempty query",
    33  			query:    "a",
    34  			items:    nil,
    35  			expected: []Item{},
    36  		},
    37  		{
    38  			name:  "some items, empty query",
    39  			query: "",
    40  			items: []Item{
    41  				{Name: "a"},
    42  				{Name: "b"},
    43  				{Name: "c"},
    44  			},
    45  			expected: nil,
    46  		},
    47  		{
    48  			name:              "some items, empty query with emptyQueryShowAll true",
    49  			query:             "",
    50  			emptyQueryShowAll: true,
    51  			items: []Item{
    52  				{Name: "a"},
    53  				{Name: "b"},
    54  				{Name: "c"},
    55  			},
    56  			expected: []Item{
    57  				{Name: "a"},
    58  				{Name: "b"},
    59  				{Name: "c"},
    60  			},
    61  		},
    62  		{
    63  			name:  "exact match for alias",
    64  			query: "w",
    65  			items: []Item{
    66  				{Name: "write one"},
    67  				{Name: "write two", Aliases: []string{"w"}},
    68  				{Name: "write three"},
    69  			},
    70  			expected: []Item{
    71  				{Name: "write two", Aliases: []string{"w"}},
    72  				{Name: "write one"},
    73  				{Name: "write three"},
    74  			},
    75  		},
    76  		{
    77  			name:  "case-insensitive match for alias",
    78  			query: "W",
    79  			items: []Item{
    80  				{Name: "write one"},
    81  				{Name: "write two", Aliases: []string{"w"}},
    82  				{Name: "write three"},
    83  				{Name: "Write capitalized"},
    84  			},
    85  			expected: []Item{
    86  				{Name: "write two", Aliases: []string{"w"}},
    87  				{Name: "Write capitalized"},
    88  				{Name: "write one"},
    89  				{Name: "write three"},
    90  			},
    91  		},
    92  		{
    93  			name:  "commands",
    94  			query: "togle", // deliberate typo, should still fuzzy-match "toggle"
    95  			items: []Item{
    96  				{Name: "quit"},
    97  				{Name: "force quit"},
    98  				{Name: "save document"},
    99  				{Name: "force save document"},
   100  				{Name: "force reload"},
   101  				{Name: "find and open"},
   102  				{Name: "open next document"},
   103  				{Name: "toggle tab expand"},
   104  				{Name: "toggle line numbers"},
   105  			},
   106  			expected: []Item{
   107  				{Name: "toggle tab expand"},
   108  				{Name: "toggle line numbers"},
   109  			},
   110  		},
   111  		{
   112  			name:  "paths",
   113  			query: "firs",
   114  			items: []Item{
   115  				{Name: "foo/first.txt"},
   116  				{Name: "foo/second.txt"},
   117  				{Name: "bar/first.txt"},
   118  				{Name: "bar/second.txt"},
   119  			},
   120  			expected: []Item{
   121  				{Name: "bar/first.txt"},
   122  				{Name: "foo/first.txt"},
   123  			},
   124  		},
   125  		{
   126  			name:  "non-ascii unicode",
   127  			query: "๐“ฏ๐“ธ๐“ธ",
   128  			items: []Item{
   129  				{Name: "๐“ฏ๐“ธ๐“ธ"},
   130  				{Name: "แตฆโ‚แตฃ"},
   131  				{Name: "ไนƒ๏พ‘ไน™"},
   132  			},
   133  			expected: []Item{
   134  				{Name: "๐“ฏ๐“ธ๐“ธ"},
   135  			},
   136  		},
   137  	}
   138  
   139  	for _, tc := range testCases {
   140  		t.Run(tc.name, func(t *testing.T) {
   141  			s := NewSearch(tc.items, tc.emptyQueryShowAll)
   142  			s.Execute(tc.query)
   143  			assert.Equal(t, tc.expected, s.Results())
   144  		})
   145  	}
   146  }
   147  
   148  func BenchmarkSearch(b *testing.B) {
   149  	s := NewSearch(fakeItems(1000, "foo/bar/baz/bat/test"), false)
   150  	for i := 0; i < b.N; i++ {
   151  		if i%2 == 0 {
   152  			s.Execute("foo")
   153  		} else {
   154  			s.Execute("bar")
   155  		}
   156  		s.Results()
   157  	}
   158  }
   159  
   160  func BenchmarkIncrementalSearch(b *testing.B) {
   161  	s := NewSearch(fakeItems(1000, "foo/bar/baz/bat/test"), false)
   162  	q := "test/123"
   163  	for i := 0; i < b.N; i++ {
   164  		for i := 1; i < len(q); i++ {
   165  			s.Execute(q[0:i])
   166  		}
   167  		s.Results()
   168  	}
   169  }
   170  
   171  func fakeItems(n int, prefix string) []Item {
   172  	items := make([]Item, 0, n)
   173  	for i := 0; i < n; i++ {
   174  		name := fmt.Sprintf("%s/%d.txt", prefix, i)
   175  		items = append(items, Item{Name: name})
   176  	}
   177  	return items
   178  }