curses_menu 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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