highline 1.6.2 → 1.6.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.
@@ -70,11 +70,29 @@ class HighLine
70
70
  def []( color_tag )
71
71
  @scheme[to_symbol(color_tag)]
72
72
  end
73
+
74
+ # Retrieve the original form of the scheme
75
+ def definition( color_tag )
76
+ style = @scheme[to_symbol(color_tag)]
77
+ style && style.list
78
+ end
79
+
80
+ # Retrieve the keys in the scheme
81
+ def keys
82
+ @scheme.keys
83
+ end
73
84
 
74
85
  # Allow the scheme to be set like a Hash.
75
86
  def []=( color_tag, constants )
76
- @scheme[to_symbol(color_tag)] = constants.map { |c| to_constant(c) }
87
+ @scheme[to_symbol(color_tag)] = HighLine::Style.new(:name=>color_tag.to_s.downcase.to_sym,
88
+ :list=>constants, :no_index=>true)
89
+ end
90
+
91
+ # Retrieve the color scheme hash (in original definition format)
92
+ def to_hash
93
+ @scheme.inject({}) { |hsh, pair| key, value = pair; hsh[key] = value.list; hsh }
77
94
  end
95
+
78
96
 
79
97
  private
80
98
 
@@ -86,7 +104,7 @@ class HighLine
86
104
  # Return a normalized representation of a color setting.
87
105
  def to_constant( v )
88
106
  v = v.to_s if v.is_a?(Symbol)
89
- if v.is_a?(String) then
107
+ if v.is_a?(::String) then
90
108
  HighLine.const_get(v.upcase)
91
109
  else
92
110
  v
@@ -178,7 +178,7 @@ class HighLine
178
178
  @index = style
179
179
 
180
180
  # Default settings.
181
- if @index == :none or @index.is_a?(String)
181
+ if @index == :none or @index.is_a?(::String)
182
182
  @index_suffix = " "
183
183
  @select_by = :name
184
184
  end
@@ -289,6 +289,7 @@ class HighLine
289
289
  # Pathname:: Same as File, save that a Pathname object is
290
290
  # returned.
291
291
  # String:: Answer is converted with Kernel.String().
292
+ # HighLine::String:: Answer is converted with HighLine::String()
292
293
  # Regexp:: Answer is fed to Regexp.new().
293
294
  # Symbol:: The method to_sym() is called on answer and
294
295
  # the result returned.
@@ -301,6 +302,8 @@ class HighLine
301
302
  def convert( answer_string )
302
303
  if @answer_type.nil?
303
304
  answer_string
305
+ elsif @answer_type == HighLine::String
306
+ HighLine::String(answer_string)
304
307
  elsif [Float, Integer, String].include?(@answer_type)
305
308
  Kernel.send(@answer_type.to_s.to_sym, answer_string)
306
309
  elsif @answer_type == Symbol
@@ -0,0 +1,98 @@
1
+ # Extensions for class String
2
+ #
3
+ # HighLine::String is a subclass of String with convenience methods added for colorization.
4
+ #
5
+ # Available convenience methods include:
6
+ # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
7
+ # * colors e.g. highline_string.magenta
8
+ # * RGB colors e.g. highline_string.rgb_ff6000
9
+ # or highline_string.rgb(255,96,0)
10
+ # * background colors e.g. highline_string.on_magenta
11
+ # * RGB background colors e.g. highline_string.on_rgb_ff6000
12
+ # or highline_string.on_rgb(255,96,0)
13
+ # * styles e.g. highline_string.underline
14
+ #
15
+ # Additionally, convenience methods can be chained, for instance the following are equivalent:
16
+ # highline_string.bright_blue.blink.underline
17
+ # highline_string.color(:bright_blue, :blink, :underline)
18
+ # HighLine.color(highline_string, :bright_blue, :blink, :underline)
19
+ #
20
+ # For those less squeamish about possible conflicts, the same convenience methods can be
21
+ # added to the builtin String class, as follows:
22
+ #
23
+ # require 'highline'
24
+ # Highline.colorize_strings
25
+
26
+ class HighLine
27
+ def self.String(s)
28
+ HighLine::String.new(s)
29
+ end
30
+
31
+ module StringExtensions
32
+ def self.included(base)
33
+ HighLine::COLORS.each do |color|
34
+ base.class_eval <<-END
35
+ def #{color.downcase}
36
+ color(:#{color.downcase})
37
+ end
38
+ END
39
+ base.class_eval <<-END
40
+ def on_#{color.downcase}
41
+ on(:#{color.downcase})
42
+ end
43
+ END
44
+ HighLine::STYLES.each do |style|
45
+ base.class_eval <<-END
46
+ def #{style.downcase}
47
+ color(:#{style.downcase})
48
+ end
49
+ END
50
+ end
51
+ end
52
+
53
+ base.class_eval do
54
+ def color(*args)
55
+ self.class.new(HighLine.color(self, *args))
56
+ end
57
+ alias_method :foreground, :color
58
+
59
+ def on(arg)
60
+ color(('on_' + arg.to_s).to_sym)
61
+ end
62
+
63
+ def uncolor
64
+ self.class.new(HighLine.uncolor(self))
65
+ end
66
+
67
+ def rgb(*colors)
68
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
69
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
70
+ color("rgb_#{color_code}".to_sym)
71
+ end
72
+
73
+ def on_rgb(*colors)
74
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
75
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
76
+ color("on_rgb_#{color_code}".to_sym)
77
+ end
78
+
79
+ # TODO Chain existing method_missing
80
+ def method_missing(method, *args, &blk)
81
+ if method.to_s =~ /^(on_)?rgb_([0-9a-fA-F]{6})$/
82
+ color(method)
83
+ else
84
+ raise NoMethodError, "undefined method `#{method}' for #<#{self.class}:#{'%#x'%self.object_id}>"
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ class HighLine::String < ::String
92
+ include StringExtensions
93
+ end
94
+
95
+ def self.colorize_strings
96
+ ::String.send(:include, StringExtensions)
97
+ end
98
+ end
@@ -0,0 +1,184 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # color_scheme.rb
4
+ #
5
+ # Created by Richard LeBer on 2011-06-27.
6
+ # Copyright 2011. All rights reserved
7
+ #
8
+ # This is Free Software. See LICENSE and COPYING for details
9
+
10
+ class HighLine
11
+
12
+ def self.Style(*args)
13
+ args = args.compact.flatten
14
+ if args.size==1
15
+ arg = args.first
16
+ if arg.is_a?(Style)
17
+ Style.list[arg.name] || Style.index(arg)
18
+ elsif arg.is_a?(::String) && arg =~ /^\e\[/ # arg is a code
19
+ if styles = Style.code_index[arg]
20
+ styles.first
21
+ else
22
+ Style.new(:code=>arg)
23
+ end
24
+ elsif style = Style.list[arg]
25
+ style
26
+ elsif HighLine.color_scheme && HighLine.color_scheme[arg]
27
+ HighLine.color_scheme[arg]
28
+ elsif arg.is_a?(Hash)
29
+ Style.new(arg)
30
+ elsif arg.to_s.downcase =~ /^rgb_([a-f0-9]{6})$/
31
+ Style.rgb($1)
32
+ elsif arg.to_s.downcase =~ /^on_rgb_([a-f0-9]{6})$/
33
+ Style.rgb($1).on
34
+ else
35
+ raise NameError, "#{arg.inspect} is not a defined Style"
36
+ end
37
+ else
38
+ name = args
39
+ Style.list[name] || Style.new(:list=>args)
40
+ end
41
+ end
42
+
43
+ class Style
44
+
45
+ def self.index(style)
46
+ if style.name
47
+ @@styles ||= {}
48
+ @@styles[style.name] = style
49
+ end
50
+ if !style.list
51
+ @@code_index ||= {}
52
+ @@code_index[style.code] ||= []
53
+ @@code_index[style.code].reject!{|indexed_style| indexed_style.name == style.name}
54
+ @@code_index[style.code] << style
55
+ end
56
+ style
57
+ end
58
+
59
+ def self.rgb_hex(*colors)
60
+ colors.map do |color|
61
+ color.is_a?(Numeric) ? '%02x'%color : color.to_s
62
+ end.join
63
+ end
64
+
65
+ def self.rgb_parts(hex)
66
+ hex.scan(/../).map{|part| part.to_i(16)}
67
+ end
68
+
69
+ def self.rgb(*colors)
70
+ hex = rgb_hex(*colors)
71
+ name = ('rgb_' + hex).to_sym
72
+ if style = list[name]
73
+ style
74
+ else
75
+ parts = rgb_parts(hex)
76
+ new(:name=>name, :code=>"\e[38;5;#{rgb_number(parts)}m", :rgb=>parts)
77
+ end
78
+ end
79
+
80
+ def self.rgb_number(*parts)
81
+ parts = parts.flatten
82
+ 16 + parts.inject(0) {|kode, part| kode*6 + (part/256.0*6.0).floor}
83
+ end
84
+
85
+ def self.ansi_rgb_to_hex(ansi_number)
86
+ raise "Invalid ANSI rgb code #{ansi_number}" unless (16..231).include?(ansi_number)
87
+ parts = (ansi_number-16).to_s(6).rjust(3,'0').scan(/./).map{|d| (d.to_i*255.0/6.0).ceil}
88
+ rgb_hex(*parts)
89
+ end
90
+
91
+ def self.list
92
+ @@styles ||= {}
93
+ end
94
+
95
+ def self.code_index
96
+ @@code_index ||= {}
97
+ end
98
+
99
+ def self.uncolor(string)
100
+ string.gsub(/\e\[\d+(;\d+)*m/, '')
101
+ end
102
+
103
+ attr_reader :name, :code, :list
104
+ attr_accessor :rgb, :builtin
105
+
106
+ # Single color/styles have :name, :code, :rgb (possibly), :builtin
107
+ # Compound styles have :name, :list, :builtin
108
+ def initialize(defn = {})
109
+ @definition = defn
110
+ @name = defn[:name]
111
+ @code = defn[:code]
112
+ @rgb = defn[:rgb]
113
+ @list = defn[:list]
114
+ @builtin = defn[:builtin]
115
+ if @rgb
116
+ hex = self.class.rgb_hex(@rgb)
117
+ rgb = self.class.rgb_parts(hex)
118
+ @name ||= 'rgb_' + hex
119
+ elsif @list
120
+ @name ||= @list
121
+ end
122
+ self.class.index self unless defn[:no_index]
123
+ end
124
+
125
+ def dup
126
+ self.class.new(@definition)
127
+ end
128
+
129
+ def to_hash
130
+ @definition
131
+ end
132
+
133
+ def color(string)
134
+ code + string + HighLine::CLEAR
135
+ end
136
+
137
+ def code
138
+ if @list
139
+ @list.map{|element| HighLine.Style(element).code}.join
140
+ else
141
+ @code
142
+ end
143
+ end
144
+
145
+ def red
146
+ @rgb && @rgb[0]
147
+ end
148
+
149
+ def green
150
+ @rgb && @rgb[1]
151
+ end
152
+
153
+ def blue
154
+ @rgb && @rgb[2]
155
+ end
156
+
157
+ def variant(new_name, options={})
158
+ raise "Cannot create a variant of a style list (#{inspect})" if @list
159
+ new_code = options[:code] || code
160
+ if options[:increment]
161
+ raise "Unexpected code in #{inspect}" unless new_code =~ /^(.*?)(\d+)(.*)/
162
+ new_code = $1 + ($2.to_i + options[:increment]).to_s + $3
163
+ end
164
+ new_rgb = options[:rgb] || @rgb
165
+ new_style = self.class.new(self.to_hash.merge(:name=>new_name, :code=>new_code, :rgb=>new_rgb))
166
+ end
167
+
168
+ def on
169
+ new_name = ('on_'+@name.to_s).to_sym
170
+ self.class.list[new_name] ||= variant(new_name, :increment=>10)
171
+ end
172
+
173
+ def bright
174
+ raise "Cannot create a bright variant of a style list (#{inspect})" if @list
175
+ new_name = ('bright_'+@name.to_s).to_sym
176
+ if style = self.class.list[new_name]
177
+ style
178
+ else
179
+ new_rgb = @rgb == [0,0,0] ? [128, 128, 128] : @rgb.map {|color| color==0 ? 0 : [color+128,255].min }
180
+ variant(new_name, :increment=>60, :rgb=>new_rgb)
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # string_methods.rb
4
+ #
5
+ # Created by Richard LeBer 2011-06-27
6
+ #
7
+ # This is Free Software. See LICENSE and COPYING for details.
8
+ #
9
+ # String class convenience methods
10
+
11
+ module StringMethods
12
+ def test_color
13
+ assert_equal("\e[34mstring\e[0m", @string.color(:blue))
14
+ assert_equal("\e[1m\e[47mstring\e[0m", @string.color(:bold,:on_white))
15
+ assert_equal("\e[45mstring\e[0m", @string.on(:magenta))
16
+ assert_equal("\e[36mstring\e[0m", @string.cyan)
17
+ assert_equal("\e[41m\e[5mstring\e[0m\e[0m", @string.blink.on_red)
18
+ assert_equal("\e[38;5;137mstring\e[0m", @string.color(:rgb_906030))
19
+ assert_equal("\e[38;5;101mstring\e[0m", @string.rgb('606030'))
20
+ assert_equal("\e[38;5;107mstring\e[0m", @string.rgb('60','90','30'))
21
+ assert_equal("\e[38;5;107mstring\e[0m", @string.rgb(96,144,48))
22
+ assert_equal("\e[38;5;173mstring\e[0m", @string.rgb_c06030)
23
+ assert_equal("\e[48;5;137mstring\e[0m", @string.color(:on_rgb_906030))
24
+ assert_equal("\e[48;5;101mstring\e[0m", @string.on_rgb('606030'))
25
+ assert_equal("\e[48;5;107mstring\e[0m", @string.on_rgb('60','90','30'))
26
+ assert_equal("\e[48;5;107mstring\e[0m", @string.on_rgb(96,144,48))
27
+ assert_equal("\e[48;5;173mstring\e[0m", @string.on_rgb_c06030)
28
+ end
29
+
30
+ def test_uncolor
31
+ colored_string = HighLine::String("\e[38;5;137mstring\e[0m")
32
+ assert_equal "string", colored_string.uncolor
33
+ end
34
+ end
@@ -46,6 +46,48 @@ class TestColorScheme < Test::Unit::TestCase
46
46
  @terminal.say("This should be <%= color('warning yellow', 'WarNing') %>.")
47
47
  assert_equal("This should be \e[1m\e[33mwarning yellow\e[0m.\n",@output.string)
48
48
  @output.rewind
49
+
50
+ # Check that keys are available, and as expected
51
+ assert_equal ["critical", "error", "warning", "notice", "info", "debug", "row_even", "row_odd"].sort,
52
+ HighLine.color_scheme.keys.sort
53
+
54
+ # Color scheme doesn't care if we use symbols or strings, and is case-insensitive
55
+ warning1 = HighLine.color_scheme[:warning]
56
+ warning2 = HighLine.color_scheme["warning"]
57
+ warning3 = HighLine.color_scheme[:wArning]
58
+ warning4 = HighLine.color_scheme["warniNg"]
59
+ assert_instance_of HighLine::Style, warning1
60
+ assert_instance_of HighLine::Style, warning2
61
+ assert_instance_of HighLine::Style, warning3
62
+ assert_instance_of HighLine::Style, warning4
63
+ assert_equal warning1, warning2
64
+ assert_equal warning1, warning3
65
+ assert_equal warning1, warning4
66
+
67
+ # Nonexistent keys return nil
68
+ assert_nil HighLine.color_scheme[:nonexistent]
69
+
70
+ # Same as above, for definitions
71
+ defn1 = HighLine.color_scheme.definition(:warning)
72
+ defn2 = HighLine.color_scheme.definition("warning")
73
+ defn3 = HighLine.color_scheme.definition(:wArning)
74
+ defn4 = HighLine.color_scheme.definition("warniNg")
75
+ assert_instance_of Array, defn1
76
+ assert_instance_of Array, defn2
77
+ assert_instance_of Array, defn3
78
+ assert_instance_of Array, defn4
79
+ assert_equal [:bold, :yellow], defn1
80
+ assert_equal [:bold, :yellow], defn2
81
+ assert_equal [:bold, :yellow], defn3
82
+ assert_equal [:bold, :yellow], defn4
83
+ assert_nil HighLine.color_scheme.definition(:nonexistent)
84
+
85
+ color_scheme_hash = HighLine.color_scheme.to_hash
86
+ assert_instance_of Hash, color_scheme_hash
87
+ assert_equal ["critical", "error", "warning", "notice", "info", "debug", "row_even", "row_odd"].sort,
88
+ color_scheme_hash.keys.sort
89
+ assert_instance_of Array, HighLine.color_scheme.definition(:warning)
90
+ assert_equal [:bold, :yellow], HighLine.color_scheme.definition(:warning)
49
91
 
50
92
  # turn it back off, should raise an exception
51
93
  HighLine.color_scheme = @old_color_scheme
@@ -198,6 +198,28 @@ class TestHighLine < Test::Unit::TestCase
198
198
 
199
199
  @output.truncate(@output.rewind)
200
200
 
201
+ @terminal.say("This should be <%= NONE %>none<%= CLEAR %>!")
202
+ assert_equal("This should be \e[38mnone\e[0m!\n", @output.string)
203
+
204
+ @output.truncate(@output.rewind)
205
+
206
+ @terminal.say("This should be <%= RGB_906030 %>rgb_906030<%= CLEAR %>!")
207
+ assert_equal("This should be \e[38;5;137mrgb_906030\e[0m!\n", @output.string)
208
+
209
+ @output.truncate(@output.rewind)
210
+
211
+ @terminal.say("This should be <%= ON_RGB_C06030 %>on_rgb_c06030<%= CLEAR %>!")
212
+ assert_equal("This should be \e[48;5;173mon_rgb_c06030\e[0m!\n", @output.string)
213
+
214
+ @output.truncate(@output.rewind)
215
+
216
+ # Does class method work, too?
217
+ @terminal.say("This should be <%= HighLine.color('reverse underlined magenta', :reverse, :underline, :magenta) %>!")
218
+ assert_equal( "This should be \e[7m\e[4m\e[35mreverse underlined magenta\e[0m!\n",
219
+ @output.string )
220
+
221
+ @output.truncate(@output.rewind)
222
+
201
223
  # turn off color
202
224
  old_setting = HighLine.use_color?
203
225
  assert_nothing_raised(Exception) { HighLine.use_color = false }
@@ -205,6 +227,27 @@ class TestHighLine < Test::Unit::TestCase
205
227
  assert_equal("This should be cyan!\n", @output.string)
206
228
  HighLine.use_color = old_setting
207
229
  end
230
+
231
+ def test_uncolor
232
+ # instance method
233
+ assert_equal( "This should be reverse underlined magenta!\n",
234
+ @terminal.uncolor("This should be \e[7m\e[4m\e[35mreverse underlined magenta\e[0m!\n")
235
+ )
236
+
237
+ @output.truncate(@output.rewind)
238
+
239
+ # class method
240
+ assert_equal( "This should be reverse underlined magenta!\n",
241
+ HighLine.uncolor("This should be \e[7m\e[4m\e[35mreverse underlined magenta\e[0m!\n")
242
+ )
243
+
244
+ @output.truncate(@output.rewind)
245
+
246
+ # RGB color
247
+ assert_equal( "This should be rgb_906030!\n",
248
+ @terminal.uncolor("This should be \e[38;5;137mrgb_906030\e[0m!\n")
249
+ )
250
+ end
208
251
 
209
252
  def test_confirm
210
253
  @input << "junk.txt\nno\nsave.txt\ny\n"
@@ -284,6 +327,9 @@ class TestHighLine < Test::Unit::TestCase
284
327
  def test_files
285
328
  @input << "#{File.basename(__FILE__)[0, 5]}\n"
286
329
  @input.rewind
330
+
331
+ assert_equal "tc_hi\n",@input.read
332
+ @input.rewind
287
333
 
288
334
  file = @terminal.ask("Select a file: ", File) do |q|
289
335
  q.directory = File.expand_path(File.dirname(__FILE__))
@@ -342,8 +388,8 @@ class TestHighLine < Test::Unit::TestCase
342
388
  answers )
343
389
  assert_equal("Age: Father's Age: Wife's Age: ", @output.string)
344
390
  end
345
-
346
- def test_lists
391
+
392
+ def test_lists
347
393
  digits = %w{Zero One Two Three Four Five Six Seven Eight Nine}
348
394
  erb_digits = digits.dup
349
395
  erb_digits[erb_digits.index("Five")] = "<%= color('Five', :blue) %%>"
@@ -368,7 +414,7 @@ class TestHighLine < Test::Unit::TestCase
368
414
  @terminal.say("<%= list(#{digits.inspect}, :columns_down, 3) %>")
369
415
  assert_equal( "Zero Four Eight\n" +
370
416
  "One Five Nine \n" +
371
- "Two Six \n" +
417
+ "Two Six \n" +
372
418
  "Three Seven\n",
373
419
  @output.string )
374
420
 
@@ -387,7 +433,7 @@ class TestHighLine < Test::Unit::TestCase
387
433
 
388
434
  @terminal.say("<%= list(#{colums_of_twenty.inspect}, :columns_down) %>")
389
435
  assert_equal( "12345678901234567890 12345678901234567890 " +
390
- "12345678901234567890\n" +
436
+ "12345678901234567890\n" +
391
437
  "12345678901234567890 12345678901234567890\n",
392
438
  @output.string )
393
439
 
@@ -409,6 +455,89 @@ class TestHighLine < Test::Unit::TestCase
409
455
  "12345678901234567890\n" +
410
456
  "12345678901234567890\n",
411
457
  @output.string )
458
+
459
+ @output.truncate(@output.rewind)
460
+
461
+ wide = %w[0123456789 a b c d e f g h i j k l m n o p q r s t u v w x y z]
462
+
463
+ @terminal.say("<%= list( #{wide.inspect}, :uneven_columns_across ) %>")
464
+ assert_equal( "0123456789 a b c d e f g h i j k l m n o " +
465
+ "p q r s t u v w\n" +
466
+ "x y z\n",
467
+ @output.string )
468
+
469
+ @output.truncate(@output.rewind)
470
+
471
+ @terminal.say("<%= list( #{wide.inspect}, :uneven_columns_across, 10 ) %>")
472
+ assert_equal( "0123456789 a b c d e f g h i\n" +
473
+ "j k l m n o p q r s\n" +
474
+ "t u v w x y z\n",
475
+ @output.string )
476
+
477
+ @output.truncate(@output.rewind)
478
+
479
+ @terminal.say("<%= list( #{wide.inspect}, :uneven_columns_down ) %>")
480
+ assert_equal( "0123456789 b d f h j l n p r t v x z\n" +
481
+ "a c e g i k m o q s u w y\n",
482
+ @output.string )
483
+
484
+ @output.truncate(@output.rewind)
485
+
486
+ @terminal.say("<%= list( #{wide.inspect}, :uneven_columns_down, 10 ) %>")
487
+ assert_equal( "0123456789 c f i l o r u x\n" +
488
+ "a d g j m p s v y\n" +
489
+ "b e h k n q t w z\n",
490
+ @output.string )
491
+ end
492
+
493
+ def test_lists_with_zero_items
494
+ modes = [nil, :rows, :inline, :columns_across, :columns_down]
495
+ modes.each do |mode|
496
+ result = @terminal.list([], mode)
497
+ assert_equal("", result)
498
+ end
499
+ end
500
+
501
+ def test_lists_with_one_item
502
+ items = ['Zero']
503
+ modes = { nil => "Zero\n",
504
+ :rows => "Zero\n",
505
+ :inline => "Zero",
506
+ :columns_across => "Zero\n",
507
+ :columns_down => "Zero\n" }
508
+
509
+ modes.each do |mode, expected|
510
+ result = @terminal.list(items, mode)
511
+ assert_equal(expected, result)
512
+ end
513
+ end
514
+
515
+ def test_lists_with_two_items
516
+ items = ['Zero', 'One']
517
+ modes = { nil => "Zero\nOne\n",
518
+ :rows => "Zero\nOne\n",
519
+ :inline => "Zero or One",
520
+ :columns_across => "Zero One \n",
521
+ :columns_down => "Zero One \n" }
522
+
523
+ modes.each do |mode, expected|
524
+ result = @terminal.list(items, mode)
525
+ assert_equal(expected, result)
526
+ end
527
+ end
528
+
529
+ def test_lists_with_three_items
530
+ items = ['Zero', 'One', 'Two']
531
+ modes = { nil => "Zero\nOne\nTwo\n",
532
+ :rows => "Zero\nOne\nTwo\n",
533
+ :inline => "Zero, One or Two",
534
+ :columns_across => "Zero One Two \n",
535
+ :columns_down => "Zero One Two \n" }
536
+
537
+ modes.each do |mode, expected|
538
+ result = @terminal.list(items, mode)
539
+ assert_equal(expected, result)
540
+ end
412
541
  end
413
542
 
414
543
  def test_mode