highline 1.6.2 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +24 -0
- data/Rakefile +4 -4
- data/lib/highline.rb +283 -130
- data/lib/highline/color_scheme.rb +20 -2
- data/lib/highline/menu.rb +1 -1
- data/lib/highline/question.rb +3 -0
- data/lib/highline/string_extensions.rb +98 -0
- data/lib/highline/style.rb +184 -0
- data/test/string_methods.rb +34 -0
- data/test/tc_color_scheme.rb +42 -0
- data/test/tc_highline.rb +133 -4
- data/test/tc_string_extension.rb +22 -0
- data/test/tc_string_highline.rb +40 -0
- data/test/tc_style.rb +569 -0
- data/test/ts_all.rb +3 -0
- metadata +32 -30
@@ -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)] =
|
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
|
data/lib/highline/menu.rb
CHANGED
data/lib/highline/question.rb
CHANGED
@@ -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
|
data/test/tc_color_scheme.rb
CHANGED
@@ -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
|
data/test/tc_highline.rb
CHANGED
@@ -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
|