curses_menu 0.0.1 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,411 @@
1
+ describe CursesMenu do
2
+
3
+ it 'displays a single string' do
4
+ test_menu do |menu|
5
+ menu.item 'Simple string'
6
+ end
7
+ assert_line 3, 'Simple string'
8
+ end
9
+
10
+ it 'displays a single string in UTF-8' do
11
+ test_menu do |menu|
12
+ menu.item 'Simple string - 単純な文字列'
13
+ end
14
+ # Ruby curses does not handle wide characters correctly in the inch method.
15
+ # This test is pending a better support for UTF-8.
16
+ # cf https://github.com/ruby/curses/issues/65
17
+ # TODO: Uncomment when Ruby curses will be fixed.
18
+ # rubocop:disable Style/AsciiComments
19
+ # assert_line 3, 'Simple string - 単純な文字列'
20
+ # rubocop:enable Style/AsciiComments
21
+ assert_line 3, /^Simple string - .+$/
22
+ end
23
+
24
+ it 'displays a single string in a CursesRow' do
25
+ test_menu do |menu|
26
+ menu.item CursesMenu::CursesRow.new({ cell: { text: 'Simple string' } })
27
+ end
28
+ assert_line 3, 'Simple string'
29
+ end
30
+
31
+ it 'displays a different color' do
32
+ test_menu do |menu|
33
+ menu.item CursesMenu::CursesRow.new(
34
+ {
35
+ cell: {
36
+ text: 'Selected colored string',
37
+ color_pair: CursesMenu::COLORS_GREEN
38
+ }
39
+ }
40
+ )
41
+ menu.item CursesMenu::CursesRow.new(
42
+ {
43
+ cell: {
44
+ text: 'Non-selected colored string',
45
+ color_pair: CursesMenu::COLORS_GREEN
46
+ }
47
+ }
48
+ )
49
+ end
50
+ assert_colored_line 3, 'Selected colored string', :COLORS_MENU_ITEM_SELECTED
51
+ assert_colored_line 4, 'Non-selected colored string', :COLORS_GREEN
52
+ end
53
+
54
+ it 'adds prefixes' do
55
+ test_menu do |menu|
56
+ menu.item CursesMenu::CursesRow.new(
57
+ {
58
+ cell: {
59
+ text: 'Simple string',
60
+ begin_with: 'PRE'
61
+ }
62
+ }
63
+ )
64
+ end
65
+ assert_line 3, 'PRESimple string'
66
+ end
67
+
68
+ it 'adds suffixes' do
69
+ test_menu do |menu|
70
+ menu.item CursesMenu::CursesRow.new(
71
+ {
72
+ cell: {
73
+ text: 'Simple string',
74
+ end_with: 'POST'
75
+ }
76
+ }
77
+ )
78
+ end
79
+ assert_line 3, 'Simple stringPOST'
80
+ end
81
+
82
+ it 'limits fixed-size strings that exceed size' do
83
+ test_menu do |menu|
84
+ menu.item CursesMenu::CursesRow.new(
85
+ {
86
+ cell: {
87
+ text: 'Simple string',
88
+ fixed_size: 5
89
+ }
90
+ }
91
+ )
92
+ end
93
+ assert_line 3, 'Simpl'
94
+ end
95
+
96
+ it 'pads fixed-size strings that do not exceed size' do
97
+ test_menu do |menu|
98
+ menu.item CursesMenu::CursesRow.new(
99
+ {
100
+ cell: {
101
+ text: 'Simple string',
102
+ fixed_size: 15,
103
+ pad: '*'
104
+ }
105
+ }
106
+ )
107
+ end
108
+ assert_line 3, 'Simple string**'
109
+ end
110
+
111
+ it 'pads fixed-size strings that do not exceed size with multi-chars padding' do
112
+ test_menu do |menu|
113
+ menu.item CursesMenu::CursesRow.new(
114
+ {
115
+ cell: {
116
+ text: 'Simple string',
117
+ fixed_size: 20,
118
+ pad: '12345'
119
+ }
120
+ }
121
+ )
122
+ end
123
+ assert_line 3, 'Simple string1234512'
124
+ end
125
+
126
+ it 'does not pad fixed-size strings that exceed size' do
127
+ test_menu do |menu|
128
+ menu.item CursesMenu::CursesRow.new(
129
+ {
130
+ cell: {
131
+ text: 'Simple string',
132
+ fixed_size: 5,
133
+ pad: '*'
134
+ }
135
+ }
136
+ )
137
+ end
138
+ assert_line 3, 'Simpl'
139
+ end
140
+
141
+ it 'left-justifies fixed-size strings that do not exceed size' do
142
+ test_menu do |menu|
143
+ menu.item CursesMenu::CursesRow.new(
144
+ {
145
+ cell: {
146
+ text: 'Simple string',
147
+ fixed_size: 15,
148
+ pad: '*',
149
+ justify: :left
150
+ }
151
+ }
152
+ )
153
+ end
154
+ assert_line 3, 'Simple string**'
155
+ end
156
+
157
+ it 'right-justifies fixed-size strings that do not exceed size' do
158
+ test_menu do |menu|
159
+ menu.item CursesMenu::CursesRow.new(
160
+ {
161
+ cell: {
162
+ text: 'Simple string',
163
+ fixed_size: 15,
164
+ pad: '*',
165
+ justify: :right
166
+ }
167
+ }
168
+ )
169
+ end
170
+ assert_line 3, '**Simple string'
171
+ end
172
+
173
+ it 'never truncates prefixes when size exceeds fixed size' do
174
+ test_menu do |menu|
175
+ menu.item CursesMenu::CursesRow.new(
176
+ {
177
+ cell: {
178
+ text: 'Simple string',
179
+ fixed_size: 15,
180
+ begin_with: 'PRE'
181
+ }
182
+ }
183
+ )
184
+ end
185
+ assert_line 3, 'PRESimple strin'
186
+ end
187
+
188
+ it 'never truncates suffixes when size exceeds fixed size' do
189
+ test_menu do |menu|
190
+ menu.item CursesMenu::CursesRow.new(
191
+ {
192
+ cell: {
193
+ text: 'Simple string',
194
+ fixed_size: 15,
195
+ end_with: 'POST'
196
+ }
197
+ }
198
+ )
199
+ end
200
+ assert_line 3, 'Simple striPOST'
201
+ end
202
+
203
+ it 'never truncates prefixes and suffixes when size exceeds fixed size' do
204
+ test_menu do |menu|
205
+ menu.item CursesMenu::CursesRow.new(
206
+ {
207
+ cell: {
208
+ text: 'Simple string',
209
+ fixed_size: 15,
210
+ begin_with: 'PRE',
211
+ end_with: 'POST'
212
+ }
213
+ }
214
+ )
215
+ end
216
+ assert_line 3, 'PRESimple sPOST'
217
+ end
218
+
219
+ it 'displays several cells' do
220
+ test_menu do |menu|
221
+ menu.item CursesMenu::CursesRow.new(
222
+ {
223
+ cell_1: { text: 'Cell 1' },
224
+ cell_2: { text: 'Cell 2' },
225
+ cell_3: { text: 'Cell 3' }
226
+ }
227
+ )
228
+ end
229
+ assert_line 3, 'Cell 1 Cell 2 Cell 3'
230
+ end
231
+
232
+ it 'displays several cells with a different separator' do
233
+ test_menu do |menu|
234
+ menu.item CursesMenu::CursesRow.new(
235
+ {
236
+ cell_1: { text: 'Cell 1' },
237
+ cell_2: { text: 'Cell 2' },
238
+ cell_3: { text: 'Cell 3' }
239
+ },
240
+ separator: 'SEP'
241
+ )
242
+ end
243
+ assert_line 3, 'Cell 1SEPCell 2SEPCell 3'
244
+ end
245
+
246
+ it 'does not exceed line when several cells are too long' do
247
+ nbr_visible_chars = Curses.stdscr.maxx
248
+ nbr_chars_per_cell = nbr_visible_chars / 3 + 1
249
+ test_menu do |menu|
250
+ menu.item CursesMenu::CursesRow.new(
251
+ {
252
+ cell_1: { text: '1' * nbr_chars_per_cell },
253
+ cell_2: { text: '2' * nbr_chars_per_cell },
254
+ cell_3: { text: '3' * nbr_chars_per_cell },
255
+ cell_4: { text: '4' * nbr_chars_per_cell }
256
+ }
257
+ )
258
+ menu.item 'Menu item 2'
259
+ end
260
+ assert_line 3, "#{'1' * nbr_chars_per_cell} #{'2' * nbr_chars_per_cell} #{'3' * (nbr_visible_chars - 2 * nbr_chars_per_cell - 3)}"
261
+ assert_line 4, 'Menu item 2'
262
+ end
263
+
264
+ it 'does not exceed line when several cells are too long due to separators' do
265
+ nbr_visible_chars = Curses.stdscr.maxx
266
+ nbr_chars_per_cell = nbr_visible_chars / 3 + 1
267
+ test_menu do |menu|
268
+ menu.item CursesMenu::CursesRow.new(
269
+ {
270
+ cell_1: { text: '1' * nbr_chars_per_cell },
271
+ cell_3: { text: '3' * nbr_chars_per_cell }
272
+ },
273
+ separator: '2' * nbr_chars_per_cell
274
+ )
275
+ menu.item 'Menu item 2'
276
+ end
277
+ assert_line 3, "#{'1' * nbr_chars_per_cell}#{'2' * nbr_chars_per_cell}#{'3' * (nbr_visible_chars - 2 * nbr_chars_per_cell - 1)}"
278
+ assert_line 4, 'Menu item 2'
279
+ end
280
+
281
+ it 'displays several cells with different properties' do
282
+ test_menu do |menu|
283
+ menu.item CursesMenu::CursesRow.new(
284
+ {
285
+ cell_1: {
286
+ text: 'Cell 1',
287
+ begin_with: 'PRE'
288
+ },
289
+ cell_2: {
290
+ text: 'Cell 2',
291
+ color_pair: CursesMenu::COLORS_GREEN,
292
+ end_with: 'POST'
293
+ },
294
+ cell_3: {
295
+ text: 'Cell 3',
296
+ fixed_size: 10,
297
+ pad: '*',
298
+ justify: :right
299
+ },
300
+ cell_4: {
301
+ text: 'Cell 4',
302
+ fixed_size: 2
303
+ },
304
+ cell_5: {
305
+ text: 'Cell 5',
306
+ fixed_size: 10,
307
+ pad: '='
308
+ }
309
+ }
310
+ )
311
+ end
312
+ # TODO: Find a way to test colors
313
+ assert_line 3, 'PRECell 1 Cell 2POST ****Cell 3 Ce Cell 5===='
314
+ end
315
+
316
+ it 'can reorder cells' do
317
+ row = CursesMenu::CursesRow.new(
318
+ {
319
+ cell_1: { text: 'Cell 1' },
320
+ cell_2: { text: 'Cell 2' },
321
+ cell_3: { text: 'Cell 3' }
322
+ }
323
+ )
324
+ row.cells_order(%i[cell_3 cell_2 cell_1])
325
+ test_menu { |menu| menu.item row }
326
+ assert_line 3, 'Cell 3 Cell 2 Cell 1'
327
+ end
328
+
329
+ it 'can reorder cells and ignore unknown ones' do
330
+ row = CursesMenu::CursesRow.new(
331
+ {
332
+ cell_1: { text: 'Cell 1' },
333
+ cell_2: { text: 'Cell 2' },
334
+ cell_3: { text: 'Cell 3' }
335
+ }
336
+ )
337
+ row.cells_order(%i[cell_4 cell_3 cell_5 cell_2 cell_1])
338
+ test_menu { |menu| menu.item row }
339
+ assert_line 3, 'Cell 3 Cell 2 Cell 1'
340
+ end
341
+
342
+ it 'can reorder cells and create unknown ones' do
343
+ row = CursesMenu::CursesRow.new(
344
+ {
345
+ cell_1: { text: 'Cell 1' },
346
+ cell_2: { text: 'Cell 2' },
347
+ cell_3: { text: 'Cell 3' }
348
+ }
349
+ )
350
+ row.cells_order(%i[cell_4 cell_3 cell_5 cell_2 cell_1], unknown_cells: 'Cell X')
351
+ test_menu { |menu| menu.item row }
352
+ assert_line 3, 'Cell X Cell 3 Cell X Cell 2 Cell 1'
353
+ end
354
+
355
+ it 'can reorder cells and create unknown ones with properties' do
356
+ row = CursesMenu::CursesRow.new(
357
+ {
358
+ cell_1: { text: 'Cell 1' },
359
+ cell_2: { text: 'Cell 2' },
360
+ cell_3: { text: 'Cell 3' }
361
+ }
362
+ )
363
+ row.cells_order(
364
+ %i[cell_4 cell_3 cell_5 cell_2 cell_1],
365
+ unknown_cells: {
366
+ text: 'Cell X',
367
+ begin_with: '{',
368
+ end_with: '}'
369
+ }
370
+ )
371
+ test_menu { |menu| menu.item row }
372
+ assert_line 3, '{Cell X} Cell 3 {Cell X} Cell 2 Cell 1'
373
+ end
374
+
375
+ it 'can change cells properties' do
376
+ row = CursesMenu::CursesRow.new(
377
+ {
378
+ cell_1: {
379
+ text: 'Cell 1',
380
+ begin_with: 'PRE',
381
+ end_with: 'POST'
382
+ },
383
+ cell_2: {
384
+ text: 'Cell 2'
385
+ },
386
+ cell_3: {
387
+ text: 'Cell 3',
388
+ fixed_size: 10,
389
+ pad: '*'
390
+ }
391
+ }
392
+ )
393
+ row.change_cells(
394
+ {
395
+ cell_1: {
396
+ begin_with: 'PRE2'
397
+ },
398
+ cell_2: {
399
+ fixed_size: 2
400
+ },
401
+ cell_3: {
402
+ text: 'Cell X',
403
+ pad: '-='
404
+ }
405
+ }
406
+ )
407
+ test_menu { |menu| menu.item row }
408
+ assert_line 3, 'PRE2Cell 1POST Ce Cell X-=-='
409
+ end
410
+
411
+ end
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ describe 'Coding guidelines' do
4
+
5
+ it 'makes sure code style follow Rubocop guides' do
6
+ rubocop_report = JSON.parse(`bundle exec rubocop --format json`)
7
+ expect(rubocop_report['summary']['offense_count']).to(
8
+ eq(0),
9
+ proc do
10
+ # Format a great error message to help
11
+ wrong_files = rubocop_report['files'].reject { |file_info| file_info['offenses'].empty? }
12
+ <<~EO_ERROR
13
+ #{wrong_files.size} files have Rubocop issues:
14
+ #{
15
+ wrong_files.map do |file_info|
16
+ offenses = file_info['offenses'].map { |offense_info| "L#{offense_info['location']['start_line']}: #{offense_info['cop_name']} - #{offense_info['message']}" }
17
+ "* #{file_info['path']}:#{
18
+ if offenses.size == 1
19
+ " #{offenses.first}"
20
+ else
21
+ " #{offenses.size} offenses:\n#{offenses.map { |offense| " - #{offense}" }.join("\n")}"
22
+ end
23
+ }"
24
+ end.join("\n")
25
+ }
26
+ EO_ERROR
27
+ end
28
+ )
29
+ end
30
+
31
+ end
@@ -0,0 +1,95 @@
1
+ describe CursesMenu do
2
+
3
+ it 'does not span items on more than 1 line' do
4
+ nbr_visible_chars = Curses.stdscr.maxx
5
+ test_menu do |menu|
6
+ menu.item '1' * nbr_visible_chars * 2
7
+ menu.item 'Menu item 2'
8
+ end
9
+ assert_line 3, '1' * (nbr_visible_chars - 1)
10
+ assert_line 4, 'Menu item 2'
11
+ end
12
+
13
+ it 'scrolls by using right key' do
14
+ nbr_visible_chars = Curses.stdscr.maxx
15
+ test_menu(keys: [Curses::KEY_RIGHT, Curses::KEY_RIGHT, Curses::KEY_RIGHT]) do |menu|
16
+ menu.item "abcde#{'1' * (nbr_visible_chars - 5)}23456789"
17
+ end
18
+ assert_line 3, "de#{'1' * (nbr_visible_chars - 5)}23"
19
+ end
20
+
21
+ it 'scrolls by using left key' do
22
+ nbr_visible_chars = Curses.stdscr.maxx
23
+ test_menu(keys: [Curses::KEY_RIGHT, Curses::KEY_RIGHT, Curses::KEY_RIGHT, Curses::KEY_LEFT]) do |menu|
24
+ menu.item "abcde#{'1' * (nbr_visible_chars - 5)}23456789"
25
+ end
26
+ assert_line 3, "cde#{'1' * (nbr_visible_chars - 5)}2"
27
+ end
28
+
29
+ it 'scrolls by using down key' do
30
+ nbr_visible_items = Curses.stdscr.maxy - 5
31
+ test_menu(keys: [Curses::KEY_NPAGE, Curses::KEY_DOWN, Curses::KEY_DOWN]) do |menu|
32
+ (nbr_visible_items * 2).times do |idx|
33
+ menu.item "Menu item #{idx}"
34
+ end
35
+ end
36
+ assert_line 3, 'Menu item 2'
37
+ assert_line(-3, "Menu item #{nbr_visible_items + 1}")
38
+ end
39
+
40
+ it 'scrolls by using up key' do
41
+ nbr_visible_items = Curses.stdscr.maxy - 5
42
+ test_menu(keys: [Curses::KEY_END, Curses::KEY_PPAGE, Curses::KEY_UP, Curses::KEY_UP]) do |menu|
43
+ (nbr_visible_items * 2).times do |idx|
44
+ menu.item "Menu item #{idx}"
45
+ end
46
+ end
47
+ assert_line 3, "Menu item #{nbr_visible_items - 2}"
48
+ assert_line(-3, "Menu item #{2 * nbr_visible_items - 3}")
49
+ end
50
+
51
+ it 'scrolls by using page down key' do
52
+ nbr_visible_items = Curses.stdscr.maxy - 5
53
+ test_menu(keys: [Curses::KEY_NPAGE, Curses::KEY_NPAGE]) do |menu|
54
+ (nbr_visible_items * 3).times do |idx|
55
+ menu.item "Menu item #{idx}"
56
+ end
57
+ end
58
+ assert_line 3, "Menu item #{nbr_visible_items - 1}"
59
+ assert_line(-3, "Menu item #{nbr_visible_items * 2 - 2}")
60
+ end
61
+
62
+ it 'scrolls by using page up key' do
63
+ nbr_visible_items = Curses.stdscr.maxy - 5
64
+ test_menu(keys: [Curses::KEY_END, Curses::KEY_PPAGE, Curses::KEY_PPAGE]) do |menu|
65
+ (nbr_visible_items * 3).times do |idx|
66
+ menu.item "Menu item #{idx}"
67
+ end
68
+ end
69
+ assert_line 3, "Menu item #{nbr_visible_items + 2 - 1}"
70
+ assert_line(-3, "Menu item #{nbr_visible_items * 2}")
71
+ end
72
+
73
+ it 'scrolls by using end key' do
74
+ nbr_visible_items = Curses.stdscr.maxy - 5
75
+ test_menu(keys: [Curses::KEY_END]) do |menu|
76
+ (nbr_visible_items * 2).times do |idx|
77
+ menu.item "Menu item #{idx}"
78
+ end
79
+ end
80
+ assert_line 3, "Menu item #{nbr_visible_items}"
81
+ assert_line(-3, "Menu item #{nbr_visible_items * 2 - 1}")
82
+ end
83
+
84
+ it 'scrolls by using home key' do
85
+ nbr_visible_items = Curses.stdscr.maxy - 5
86
+ test_menu(keys: [Curses::KEY_END, Curses::KEY_HOME]) do |menu|
87
+ (nbr_visible_items * 3).times do |idx|
88
+ menu.item "Menu item #{idx}"
89
+ end
90
+ end
91
+ assert_line 3, 'Menu item 0'
92
+ assert_line(-3, "Menu item #{nbr_visible_items - 1}")
93
+ end
94
+
95
+ end