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.
- 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
|