highline 2.0.0.pre.develop.2 → 2.0.0.pre.develop.4

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.
@@ -4,6 +4,7 @@ require 'forwardable'
4
4
 
5
5
  class HighLine
6
6
  class Question
7
+ # It provides all answer conversion flow.
7
8
  class AnswerConverter
8
9
  extend Forwardable
9
10
 
@@ -11,10 +12,19 @@ class HighLine
11
12
  :answer, :answer=, :check_range,
12
13
  :directory, :answer_type, :choices_complete
13
14
 
15
+ # It should be initialized with a Question object.
16
+ # The class will get the answer from {Question#answer}
17
+ # and then convert it to the proper {Question#answer_type}.
18
+ # It is mainly used by {Question#convert}
19
+ #
20
+ # @param question [Question]
14
21
  def initialize(question)
15
22
  @question = question
16
23
  end
17
24
 
25
+ # Based on the given Question object's settings,
26
+ # it makes the conversion and returns the answer.
27
+ # @return [Object] the converted answer.
18
28
  def convert
19
29
  return unless answer_type
20
30
 
@@ -23,6 +33,7 @@ class HighLine
23
33
  answer
24
34
  end
25
35
 
36
+ # @return [HighLine::String] answer converted to a HighLine::String
26
37
  def to_string
27
38
  HighLine::String(answer)
28
39
  end
@@ -33,37 +44,45 @@ class HighLine
33
44
  HighLine::String(answer)
34
45
  end
35
46
 
47
+ # @return [Integer] answer converted to an Integer
36
48
  def to_integer
37
49
  Kernel.send(:Integer, answer)
38
50
  end
39
51
 
52
+ # @return [Float] answer converted to a Float
40
53
  def to_float
41
54
  Kernel.send(:Float, answer)
42
55
  end
43
56
 
57
+ # @return [Symbol] answer converted to an Symbol
44
58
  def to_symbol
45
59
  answer.to_sym
46
60
  end
47
61
 
62
+ # @return [Regexp] answer converted to a Regexp
48
63
  def to_regexp
49
64
  Regexp.new(answer)
50
65
  end
51
66
 
67
+ # @return [File] answer converted to a File
52
68
  def to_file
53
69
  self.answer = choices_complete(answer)
54
70
  File.open(File.join(directory.to_s, answer.last))
55
71
  end
56
72
 
73
+ # @return [Pathname] answer converted to an Pathname
57
74
  def to_pathname
58
75
  self.answer = choices_complete(answer)
59
76
  Pathname.new(File.join(directory.to_s, answer.last))
60
77
  end
61
78
 
79
+ # @return [Array] answer converted to an Array
62
80
  def to_array
63
81
  self.answer = choices_complete(answer)
64
82
  answer.last
65
83
  end
66
84
 
85
+ # @return [Proc] answer converted to an Proc
67
86
  def to_proc
68
87
  answer_type.call(answer)
69
88
  end
@@ -1,9 +1,17 @@
1
1
  class HighLine
2
+ # Deals with the task of "asking" a question
2
3
  class QuestionAsker
4
+ # @return [Question] question to be asked
3
5
  attr_reader :question
4
6
 
5
7
  include CustomErrors
6
8
 
9
+ # To do its work QuestionAsker needs a Question
10
+ # to be asked and a HighLine context where to
11
+ # direct output.
12
+ #
13
+ # @param question [Question] question to be asked
14
+ # @param highline [HighLine] context
7
15
  def initialize(question, highline)
8
16
  @question = question
9
17
  @highline = highline
@@ -12,6 +20,7 @@ class HighLine
12
20
  #
13
21
  # Gets just one answer, as opposed to #gather_answers
14
22
  #
23
+ # @return [String] answer
15
24
  def ask_once
16
25
  question.show_question(@highline)
17
26
 
@@ -25,19 +34,8 @@ class HighLine
25
34
  raise NoConfirmationQuestionError unless @highline.send(:confirm, question)
26
35
  end
27
36
 
28
- rescue NoConfirmationQuestionError
29
- explain_error(nil)
30
- retry
31
-
32
- rescue NotInRangeQuestionError
33
- explain_error(:not_in_range)
34
- retry
35
-
36
- rescue NotValidQuestionError
37
- explain_error(:not_valid)
38
- retry
39
-
40
- rescue QuestionError
37
+ rescue ExplainableError => e
38
+ explain_error(e.explanation_key)
41
39
  retry
42
40
 
43
41
  rescue ArgumentError => error
@@ -54,11 +52,8 @@ class HighLine
54
52
  else
55
53
  raise
56
54
  end
57
-
58
- rescue NoAutoCompleteMatch
59
- explain_error(:no_completion)
60
- retry
61
55
  end
56
+
62
57
  question.answer
63
58
  end
64
59
 
@@ -68,6 +63,7 @@ class HighLine
68
63
  # Collects an Array/Hash full of answers as described in
69
64
  # HighLine::Question.gather().
70
65
  #
66
+ # @return [Array, Hash] answers
71
67
  def gather_answers
72
68
  original_question_template = question.template
73
69
  verify_match = question.verify_match
@@ -87,12 +83,17 @@ class HighLine
87
83
  question.verify_match ? @highline.send(:last_answer, answers) : answers
88
84
  end
89
85
 
86
+ # Gather multiple integer values based on {Question#gather} count
87
+ # @return [Array] answers
90
88
  def gather_integer
91
89
  gather_with_array do |answers|
92
90
  (question.gather-1).times { answers << ask_once }
93
91
  end
94
92
  end
95
93
 
94
+ # Gather multiple values until any of them matches the
95
+ # {Question#gather} Regexp.
96
+ # @return [Array] answers
96
97
  def gather_regexp
97
98
  gather_with_array do |answers|
98
99
  answers << ask_once until answer_matches_regex(answers.last)
@@ -100,6 +101,9 @@ class HighLine
100
101
  end
101
102
  end
102
103
 
104
+ # Gather multiple values and store them on a Hash
105
+ # with keys provided by the Hash on {Question#gather}
106
+ # @return [Hash]
103
107
  def gather_hash
104
108
  answers = {}
105
109
 
@@ -10,12 +10,15 @@
10
10
  #
11
11
  # adapted from https://gist.github.com/194554
12
12
 
13
+
13
14
  class HighLine
14
15
 
15
16
  # Simulates Highline input for use in tests.
16
17
  class Simulate
17
18
 
18
19
  # Creates a simulator with an array of Strings as a script
20
+ # @param strings [Array<String>] preloaded string to be used
21
+ # as input buffer when simulating.
19
22
  def initialize(strings)
20
23
  @strings = strings
21
24
  end
@@ -40,7 +43,13 @@ class HighLine
40
43
  false
41
44
  end
42
45
 
43
- # A wrapper method that temporarily replaces the Highline instance in $terminal with an instance of this object for the duration of the block
46
+ # A wrapper method that temporarily replaces the Highline
47
+ # instance in $terminal with an instance of this object
48
+ # for the duration of the block
49
+ #
50
+ # @param strings [String] preloaded string buffer that
51
+ # will feed the input operations when simulating.
52
+
44
53
  def self.with(*strings)
45
54
  @input = $terminal.instance_variable_get :@input
46
55
  $terminal.instance_variable_set :@input, new(strings)
@@ -4,55 +4,79 @@ require 'highline/wrapper'
4
4
  require 'highline/paginator'
5
5
  require 'highline/template_renderer'
6
6
 
7
- class HighLine::Statement
8
- attr_reader :source, :highline
9
- attr_reader :template_string
10
-
11
- def initialize(source, highline)
12
- @highline = highline
13
- @source = source
14
- @template_string = stringfy(source)
15
- end
7
+ class HighLine
8
+ # This class handles proper formatting based
9
+ # on a HighLine context, applying wrapping,
10
+ # pagination, indentation and color rendering
11
+ # when necessary. It's used by {HighLine#render_statement}
12
+ # @see HighLine#render_statement
13
+ class Statement
14
+ # The source object to be stringfied and formatted.
15
+ attr_reader :source
16
16
 
17
- def statement
18
- @statement ||= format_statement
19
- end
17
+ # The HighLine context
18
+ # @return [HighLine]
19
+ attr_reader :highline
20
20
 
21
- def to_s
22
- statement
23
- end
21
+ # The stringfied source object
22
+ # @return [String]
23
+ attr_reader :template_string
24
24
 
25
- private
25
+ # It needs the input String and the HighLine context
26
+ # @param source [#to_s]
27
+ # @param highline [HighLine] context
28
+ def initialize(source, highline)
29
+ @highline = highline
30
+ @source = source
31
+ @template_string = stringfy(source)
32
+ end
26
33
 
27
- def stringfy(template_string)
28
- String(template_string || "").dup
29
- end
34
+ # Returns the formated statement.
35
+ # Applies wrapping, pagination, indentation and color rendering
36
+ # based on HighLine instance settings.
37
+ # @return [String] formated statement
38
+ def statement
39
+ @statement ||= format_statement
40
+ end
30
41
 
31
- def format_statement
32
- return template_string unless template_string.length > 0
42
+ # (see #statement)
43
+ # Delegates to {#statement}
44
+ def to_s
45
+ statement
46
+ end
33
47
 
34
- statement = render_template
48
+ private
35
49
 
36
- statement = HighLine::Wrapper.wrap(statement, highline.wrap_at)
37
- statement = HighLine::Paginator.new(highline).page_print(statement)
50
+ def stringfy(template_string)
51
+ String(template_string || "").dup
52
+ end
38
53
 
39
- statement = statement.gsub(/\n(?!$)/,"\n#{highline.indentation}") if highline.multi_indent
40
- statement
41
- end
54
+ def format_statement
55
+ return template_string unless template_string.length > 0
42
56
 
43
- def render_template
44
- # Assigning to a local var so it may be
45
- # used inside instance eval block
57
+ statement = render_template
46
58
 
47
- template_renderer = TemplateRenderer.new(template, source, highline)
48
- template_renderer.render
49
- end
59
+ statement = HighLine::Wrapper.wrap(statement, highline.wrap_at)
60
+ statement = HighLine::Paginator.new(highline).page_print(statement)
50
61
 
51
- def template
52
- @template ||= ERB.new(template_string, nil, "%")
53
- end
62
+ statement = statement.gsub(/\n(?!$)/,"\n#{highline.indentation}") if highline.multi_indent
63
+ statement
64
+ end
65
+
66
+ def render_template
67
+ # Assigning to a local var so it may be
68
+ # used inside instance eval block
69
+
70
+ template_renderer = TemplateRenderer.new(template, source, highline)
71
+ template_renderer.render
72
+ end
73
+
74
+ def template
75
+ @template ||= ERB.new(template_string, nil, "%")
76
+ end
54
77
 
55
- def self.const_missing(constant)
56
- HighLine.const_get(constant)
78
+ def self.const_missing(constant)
79
+ HighLine.const_get(constant)
80
+ end
57
81
  end
58
82
  end
@@ -2,32 +2,33 @@
2
2
 
3
3
  require "highline/string_extensions"
4
4
 
5
- #
6
- # HighLine::String is a subclass of String with convenience methods added for colorization.
7
- #
8
- # Available convenience methods include:
9
- # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
10
- # * colors e.g. highline_string.magenta
11
- # * RGB colors e.g. highline_string.rgb_ff6000
12
- # or highline_string.rgb(255,96,0)
13
- # * background colors e.g. highline_string.on_magenta
14
- # * RGB background colors e.g. highline_string.on_rgb_ff6000
15
- # or highline_string.on_rgb(255,96,0)
16
- # * styles e.g. highline_string.underline
17
- #
18
- # Additionally, convenience methods can be chained, for instance the following are equivalent:
19
- # highline_string.bright_blue.blink.underline
20
- # highline_string.color(:bright_blue, :blink, :underline)
21
- # HighLine.color(highline_string, :bright_blue, :blink, :underline)
22
- #
23
- # For those less squeamish about possible conflicts, the same convenience methods can be
24
- # added to the built-in String class, as follows:
25
- #
26
- # require 'highline'
27
- # Highline.colorize_strings
28
- #
29
-
30
5
  class HighLine
6
+
7
+ #
8
+ # HighLine::String is a subclass of String with convenience methods added for colorization.
9
+ #
10
+ # Available convenience methods include:
11
+ # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
12
+ # * colors e.g. highline_string.magenta
13
+ # * RGB colors e.g. highline_string.rgb_ff6000
14
+ # or highline_string.rgb(255,96,0)
15
+ # * background colors e.g. highline_string.on_magenta
16
+ # * RGB background colors e.g. highline_string.on_rgb_ff6000
17
+ # or highline_string.on_rgb(255,96,0)
18
+ # * styles e.g. highline_string.underline
19
+ #
20
+ # Additionally, convenience methods can be chained, for instance the following are equivalent:
21
+ # highline_string.bright_blue.blink.underline
22
+ # highline_string.color(:bright_blue, :blink, :underline)
23
+ # HighLine.color(highline_string, :bright_blue, :blink, :underline)
24
+ #
25
+ # For those less squeamish about possible conflicts, the same convenience methods can be
26
+ # added to the built-in String class, as follows:
27
+ #
28
+ # require 'highline'
29
+ # Highline.colorize_strings
30
+ #
31
+
31
32
  class String < ::String
32
33
  include StringExtensions
33
34
  end
@@ -1,40 +1,30 @@
1
1
  # coding: utf-8
2
2
 
3
3
  class HighLine
4
+ # Returns a HighLine::String from any given String.
5
+ # @param s [String]
6
+ # @return [HighLine::String] from the given string.
4
7
  def self.String(s)
5
8
  HighLine::String.new(s)
6
9
  end
7
10
 
8
- # HighLine extensions for String class
9
- # Included by HighLine::String
11
+ # HighLine extensions for String class.
12
+ # Included by HighLine::String.
10
13
  module StringExtensions
14
+ # Included hook. Actions to take when being included.
15
+ # @param base [Class, Module] base class
11
16
  def self.included(base)
12
- HighLine::COLORS.each do |color|
13
- color = color.downcase
14
- base.class_eval <<-END
15
- undef :#{color} if method_defined? :#{color}
16
- def #{color}
17
- color(:#{color})
18
- end
19
- END
20
-
21
- base.class_eval <<-END
22
- undef :on_#{color} if method_defined? :on_#{color}
23
- def on_#{color}
24
- on(:#{color})
25
- end
26
- END
27
- HighLine::STYLES.each do |style|
28
- style = style.downcase
29
- base.class_eval <<-END
30
- undef :#{style} if method_defined? :#{style}
31
- def #{style}
32
- color(:#{style})
33
- end
34
- END
35
- end
36
- end
17
+ define_builtin_style_methods(base)
18
+ define_style_support_methods(base)
19
+ end
37
20
 
21
+ # At include time, it defines all basic style
22
+ # support method like #color, #on, #uncolor,
23
+ # #rgb, #on_rgb and the #method_missing callback
24
+ # @return [void]
25
+ # @param base [Class, Module] the base class/module
26
+ #
27
+ def self.define_style_support_methods(base)
38
28
  base.class_eval do
39
29
  undef :color if method_defined? :color
40
30
  undef :foreground if method_defined? :foreground
@@ -55,19 +45,17 @@ class HighLine
55
45
 
56
46
  undef :rgb if method_defined? :rgb
57
47
  def rgb(*colors)
58
- color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
59
- raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
48
+ color_code = setup_color_code(*colors)
60
49
  color("rgb_#{color_code}".to_sym)
61
50
  end
62
51
 
63
52
  undef :on_rgb if method_defined? :on_rgb
64
53
  def on_rgb(*colors)
65
- color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
66
- raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
54
+ color_code = setup_color_code(*colors)
67
55
  color("on_rgb_#{color_code}".to_sym)
68
56
  end
69
57
 
70
- # TODO Chain existing method_missing
58
+ # @todo Chain existing method_missing?
71
59
  undef :method_missing if method_defined? :method_missing
72
60
  def method_missing(method, *args, &blk)
73
61
  if method.to_s =~ /^(on_)?rgb_([0-9a-fA-F]{6})$/
@@ -76,10 +64,50 @@ class HighLine
76
64
  raise NoMethodError, "undefined method `#{method}' for #<#{self.class}:#{'%#x'%self.object_id}>"
77
65
  end
78
66
  end
67
+
68
+ private
69
+
70
+ def setup_color_code(*colors)
71
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
72
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
73
+ color_code
74
+ end
75
+ end
76
+ end
77
+
78
+ # At include time, it defines all basic builtin styles.
79
+ # @param base [Class, Module] base Class/Module
80
+ def self.define_builtin_style_methods(base)
81
+ HighLine::COLORS.each do |color|
82
+ color = color.downcase
83
+ base.class_eval <<-END
84
+ undef :#{color} if method_defined? :#{color}
85
+ def #{color}
86
+ color(:#{color})
87
+ end
88
+ END
89
+
90
+ base.class_eval <<-END
91
+ undef :on_#{color} if method_defined? :on_#{color}
92
+ def on_#{color}
93
+ on(:#{color})
94
+ end
95
+ END
96
+
97
+ HighLine::STYLES.each do |style|
98
+ style = style.downcase
99
+ base.class_eval <<-END
100
+ undef :#{style} if method_defined? :#{style}
101
+ def #{style}
102
+ color(:#{style})
103
+ end
104
+ END
105
+ end
79
106
  end
80
107
  end
81
108
  end
82
109
 
110
+ # Adds color support to the base String class
83
111
  def self.colorize_strings
84
112
  ::String.send(:include, StringExtensions)
85
113
  end