question 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d3a0d376bc7b786a49fd2def503783d20b3faba4
4
- data.tar.gz: b5c4c650182334f747a56f2afac3edf8af9825d4
3
+ metadata.gz: 663229bc3195354972ced413cb6299ab39dcd242
4
+ data.tar.gz: e75dda15df55b7f7455525fb8d4b024241ac6227
5
5
  SHA512:
6
- metadata.gz: 57062767899bae46121b0c5c6d96f1b711fc3084c0fbd75a1be1f4fff8e873b308bd7aa5fe845642a07be83b858e7bafe284979c7bcb3b9fc0b5e21f81d7867d
7
- data.tar.gz: 8ae38cbddfffb390264432f21af1bbc4872c642927abde1a4a5a230046816295486d2ccfcfd36f84871ce170118e54f187554fda399a081989ebb0d73ad2938e
6
+ metadata.gz: e49c381bae23ff13be2a3cc506f4b6e973b29ddff3103038c8f09310097f17238f3091f34c15d9b01a07ab319b2a577bb3d3f5529305ece15c08b59f4476f248
7
+ data.tar.gz: c37c13bfce998409f1617aa8bc3595c66019e70e8e54ee514fc41b3656c9332982a988ab12d3c6aee4592d6a40ac7ebc1385c3a245c991fca151848d6f3ce5dd
data/README.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Question
2
2
 
3
+ Inspired by [Inquirer.js](https://github.com/SBoudrias/Inquirer.js/)
4
+
5
+ ### Checkbox List
6
+
7
+ ![http://cl.ly/image/3h1G1a1S3X0A/Image%202015-01-14%20at%2012.51.16%20PM.png](http://cl.ly/image/3h1G1a1S3X0A/Image%202015-01-14%20at%2012.51.16%20PM.png)
8
+
9
+ ### List
10
+ ![http://cl.ly/image/0s1E0S2f0c3M/Image%202015-01-14%20at%2012.51.45%20PM.png](http://cl.ly/image/0s1E0S2f0c3M/Image%202015-01-14%20at%2012.51.45%20PM.png)
11
+
12
+ ### Input
13
+ ![http://cl.ly/image/1c3i2d3e3z2v/Image%202015-01-14%20at%2012.52.01%20PM.png](http://cl.ly/image/1c3i2d3e3z2v/Image%202015-01-14%20at%2012.52.01%20PM.png)
14
+
15
+ ### Confirm
16
+ ![http://cl.ly/image/2H0e101H1q3W/Image%202015-01-14%20at%2012.52.26%20PM.png](http://cl.ly/image/2H0e101H1q3W/Image%202015-01-14%20at%2012.52.26%20PM.png)
17
+
18
+ ### End Result
3
19
  ![https://s3.amazonaws.com/f.cl.ly/items/2K3w1Y0F2T2o1505191J/Image%202015-01-14%20at%2012.35.04%20PM.png](https://s3.amazonaws.com/f.cl.ly/items/2K3w1Y0F2T2o1505191J/Image%202015-01-14%20at%2012.35.04%20PM.png)
4
20
 
5
21
  ## Installation
data/examples/example.rb CHANGED
@@ -1,24 +1,16 @@
1
- require "pp"
1
+ $:.unshift File.expand_path("../../lib", __FILE__)
2
2
 
3
+ require "pp"
3
4
  require "question"
4
5
 
5
6
  choices = [
6
7
  { label: "red", value: {r: 255, g: 0, b: 0} },
7
8
  { label: "blue", value: "#0000FF" },
8
- { label: "green", value: "green" }
9
+ "green" # You can also just pass a String or Number
9
10
  ]
10
11
 
11
- question = Question::CheckboxList.new("What colors do you like", choices, default: choices[1..-1])
12
- pp question.ask
13
-
14
- question = Question::List.new("What is your FAVORITE color", choices)
15
- pp question.ask
16
-
17
- question = Question::Input.new("What is your name?", default: ENV["USER"])
18
- pp question.ask
19
-
20
- question = Question::Password.new("Enter something secret")
21
- pp question.ask
22
-
23
- question = Question::Confirm.new("Do you understand")
24
- pp question.ask
12
+ pp Question.checkbox_list("What colors do you like", choices, default: choices[1..-1])
13
+ pp Question.list("What is your FAVORITE color", choices)
14
+ pp Question.input("What is your name?", default: ENV["USER"])
15
+ pp Question.password("Enter something secret")
16
+ pp Question.confirm("Do you understand")
@@ -1,12 +1,24 @@
1
1
  module Question
2
2
  class CheckboxList
3
- def initialize(question, choices, default: nil)
3
+ def initialize(question, choices, default: [])
4
4
  @question = question
5
5
  @choices = choices
6
6
  @active_index = 0
7
- @selected_choices = default || []
8
7
  @finished = false
9
8
  @modified = false
9
+
10
+ default_values = default.map { |choice| value_for_choice(choice) }
11
+ @selected_choices = choices.select do |choice|
12
+ default_values.include? value_for_choice(choice)
13
+ end
14
+ end
15
+
16
+ def label_for_choice(choice)
17
+ choice.is_a?(Hash) ? choice[:label] : choice
18
+ end
19
+
20
+ def value_for_choice(choice)
21
+ choice.is_a?(Hash) ? choice[:value] : choice
10
22
  end
11
23
 
12
24
  def ask
@@ -18,19 +30,20 @@ module Question
18
30
  render # render the results a final time and clear the screen
19
31
  end
20
32
 
21
- @selected_choices
33
+ @selected_choices.map { |choice| value_for_choice(choice) }
22
34
  end
23
35
 
24
36
  def handle_input
25
- case TTY.input
37
+ input = TTY.input
38
+ case input
26
39
  when TTY::CODE::SIGINT
27
40
  exit 130
28
41
  when TTY::CODE::RETURN
29
42
  @finished = true
30
- when TTY::CODE::DOWN
43
+ when TTY::CODE::DOWN, TTY::CODE::CTRL_J, TTY::CODE::CTRL_N
31
44
  @active_index += 1
32
45
  @active_index = 0 if @active_index >= @choices.length
33
- when TTY::CODE::UP
46
+ when TTY::CODE::UP, TTY::CODE::CTRL_K, TTY::CODE::CTRL_P
34
47
  @active_index -= 1
35
48
  @active_index = @choices.length - 1 if @active_index < 0
36
49
  when TTY::CODE::SPACE
@@ -50,15 +63,15 @@ module Question
50
63
 
51
64
  def render
52
65
  TTY.clear
53
- print "? ".colorize(:cyan)
66
+ print "? ".cyan
54
67
  print @question
55
68
  print ": "
56
69
  if @finished
57
- print @selected_choices.map { |choice| choice[:label] }.join(", ").colorize(:green)
70
+ print @selected_choices.map { |choice| label_for_choice(choice) }.join(", ").green
58
71
  elsif @modified
59
- print @selected_choices.map { |choice| choice[:label] }.join(", ")
72
+ print @selected_choices.map { |choice| label_for_choice(choice) }.join(", ")
60
73
  else
61
- print instructions.colorize(:light_white)
74
+ print instructions.light_white
62
75
  end
63
76
  print "\n"
64
77
 
@@ -67,12 +80,12 @@ module Question
67
80
  print index == @active_index ? TTY::UI::SELECTED : TTY::UI::UNSELECTED
68
81
  print " "
69
82
  if @selected_choices.include?(choice)
70
- print TTY::UI::CHECKBOX_CHECKED.colorize(:green)
83
+ print TTY::UI::CHECKBOX_CHECKED.green
71
84
  else
72
- print TTY::UI::CHECKBOX_UNCHECKED.colorize(:red)
85
+ print TTY::UI::CHECKBOX_UNCHECKED.red
73
86
  end
74
87
  print " "
75
- print choice[:label]
88
+ print label_for_choice(choice)
76
89
  print "\n"
77
90
  end
78
91
  end
@@ -11,9 +11,9 @@ module Question
11
11
  print TTY::CODE::SAVE
12
12
  question = colorized_question
13
13
  if @default
14
- question += "(Y/n) ".colorize(:light_white)
14
+ question += "(Y/n) ".light_white
15
15
  else
16
- question += "(y/N) ".colorize(:light_white)
16
+ question += "(y/N) ".light_white
17
17
  end
18
18
 
19
19
  # Use readline so keyboard shortcuts like alt-backspace work
@@ -36,12 +36,12 @@ module Question
36
36
  def render
37
37
  TTY.clear
38
38
  print colorized_question
39
- print (@answer ? "Yes" : "No").colorize(:blue)
39
+ print (@answer ? "Yes" : "No").green
40
40
  print "\n"
41
41
  end
42
42
 
43
43
  def colorized_question
44
- colorized_question = "? ".colorize(:cyan)
44
+ colorized_question = "? ".cyan
45
45
  colorized_question += @question
46
46
  colorized_question += ": "
47
47
  end
@@ -10,7 +10,7 @@ module Question
10
10
  def ask
11
11
  print TTY::CODE::SAVE
12
12
  question = colorized_question
13
- question += "(#{@default}) ".colorize(:light_white) if @default
13
+ question += "(#{@default}) ".light_white if @default
14
14
 
15
15
  # Use readline so keyboard shortcuts like alt-backspace work
16
16
  @answer = Readline.readline(question, true)
@@ -25,12 +25,12 @@ module Question
25
25
  def render
26
26
  TTY.clear
27
27
  print colorized_question
28
- print @answer.colorize(:blue)
28
+ print @answer.green
29
29
  print "\n"
30
30
  end
31
31
 
32
32
  def colorized_question
33
- colorized_question = "? ".colorize(:cyan)
33
+ colorized_question = "? ".cyan
34
34
  colorized_question += @question
35
35
  colorized_question += ": "
36
36
  end
data/lib/question/list.rb CHANGED
@@ -7,16 +7,24 @@ module Question
7
7
  @finished = false
8
8
  end
9
9
 
10
+ def label_for_choice(choice)
11
+ choice.is_a?(Hash) ? choice[:label] : choice
12
+ end
13
+
14
+ def value_for_choice(choice)
15
+ choice.is_a?(Hash) ? choice[:value] : choice
16
+ end
17
+
10
18
  def ask
11
19
  TTY.interactive do
12
20
  while !@finished
13
21
  render
14
22
  handle_input
15
23
  end
16
- render # render the results a final time and clear the screen
24
+ render
17
25
  end
18
26
 
19
- @choices[@active_index]
27
+ value_for_choice(@choices[@active_index])
20
28
  end
21
29
 
22
30
  def handle_input
@@ -35,26 +43,30 @@ module Question
35
43
  end
36
44
 
37
45
  def instructions
38
- "(Press <enter> when to make selection)"
46
+ "(Press <enter> to select item)"
39
47
  end
40
48
 
41
49
  def render
42
50
  TTY.clear
43
- print "? ".colorize(:cyan)
51
+ print "? ".cyan
44
52
  print @question
45
53
  print ": "
46
54
  if @finished
47
- print @choices[@active_index][:label].colorize(:green)
55
+ print label_for_choice(@choices[@active_index]).green
48
56
  else
49
- print instructions.colorize(:light_white)
57
+ print instructions.light_black
50
58
  end
51
59
  print "\n"
52
60
 
53
61
  unless @finished
54
62
  @choices.each_with_index do |choice, index|
55
- print index == @active_index ? TTY::UI::SELECTED : TTY::UI::UNSELECTED
63
+ print index == @active_index ? TTY::UI::SELECTED.green : TTY::UI::UNSELECTED
56
64
  print " "
57
- print choice[:label]
65
+ if index == @active_index
66
+ print label_for_choice(choice).green
67
+ else
68
+ print label_for_choice(choice)
69
+ end
58
70
  print "\n"
59
71
  end
60
72
  end
@@ -35,10 +35,10 @@ module Question
35
35
  def render
36
36
  obscured_password = TTY::UI::SECURE * @answer.length
37
37
  TTY.clear
38
- print "? ".colorize(:cyan)
38
+ print "? ".cyan
39
39
  print @question
40
40
  print ": "
41
- print @finished ? obscured_password.colorize(:blue) : obscured_password
41
+ print @finished ? obscured_password.green : obscured_password
42
42
  print "\n"
43
43
  end
44
44
  end
data/lib/question/tty.rb CHANGED
@@ -12,7 +12,12 @@ module Question
12
12
  LEFT = "\e[D"
13
13
  BACKSPACE = "\b"
14
14
  DELETE = "\e[3"
15
- SIGINT = "\003"
15
+
16
+ CTRL_J = "\x0A"
17
+ CTRL_N = "\x0E"
18
+ CTRL_K = "\x0B"
19
+ CTRL_P = "\x10"
20
+ SIGINT = "\x03"
16
21
 
17
22
  HIDE = "\e[?25l"
18
23
  SHOW = "\e[?25h"
@@ -1,3 +1,3 @@
1
1
  module Question
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/question.rb CHANGED
@@ -14,4 +14,23 @@ require "question/password"
14
14
  require "question/confirm"
15
15
 
16
16
  module Question
17
+ def self.checkbox_list(*args)
18
+ CheckboxList.new(*args).ask
19
+ end
20
+
21
+ def self.list(*args)
22
+ List.new(*args).ask
23
+ end
24
+
25
+ def self.input(*args)
26
+ Input.new(*args).ask
27
+ end
28
+
29
+ def self.password(*args)
30
+ Password.new(*args).ask
31
+ end
32
+
33
+ def self.confirm(*args)
34
+ Confirm.new(*args).ask
35
+ end
17
36
  end
@@ -2,3 +2,10 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'question'
3
3
 
4
4
  require 'minitest/autorun'
5
+
6
+ def fake_input(input, &block)
7
+ input_proc = proc { input.shift }
8
+ $stdin.stub :getch, input_proc do
9
+ block.call
10
+ end
11
+ end
@@ -3,33 +3,47 @@ require 'minitest_helper'
3
3
  describe Question do
4
4
  describe "CheckboxList" do
5
5
  it "returns checked choices" do
6
-
7
6
  message = "How are you feeling"
8
7
  choices = [
9
8
  { label: "good", value: {sub: 1} },
10
9
  { label: "neutral", value: 0 },
11
- { label: "horrible", value: [1,2,3] }
10
+ "horrible"
12
11
  ]
13
12
 
14
- # Fake input
15
13
  input = [
16
14
  Question::TTY::CODE::UP,
17
15
  Question::TTY::CODE::SPACE,
18
16
  Question::TTY::CODE::DOWN,
19
17
  Question::TTY::CODE::SPACE,
18
+ Question::TTY::CODE::DOWN,
19
+ Question::TTY::CODE::SPACE,
20
20
  Question::TTY::CODE::RETURN
21
21
  ]
22
- input_proc = Proc.new { input.shift }
23
-
24
- result = $stdin.stub :getch, input_proc do
25
- question = Question::CheckboxList.new(message, choices)
26
- question.ask()
27
- end
22
+ result = fake_input(input) { Question.checkbox_list(message, choices, default: [0]) }
28
23
 
29
24
  assert_equal result, [
30
- { label: "horrible", value: [1,2,3] },
31
- { label: "good", value: {sub: 1} }
25
+ "horrible",
26
+ {sub: 1}
32
27
  ]
33
28
  end
34
29
  end
30
+
31
+ describe "List" do
32
+ it "returns checked choices" do
33
+
34
+ message = "How are you feeling"
35
+ choices = [
36
+ { label: "good", value: {sub: 1} },
37
+ { label: "neutral", value: 0 },
38
+ "horrible"
39
+ ]
40
+
41
+ choices.each_with_index do |choice, index|
42
+ input = [Question::TTY::CODE::RETURN]
43
+ index.times { input.unshift Question::TTY::CODE::DOWN }
44
+ result = fake_input(input) { Question.list(message, choices) }
45
+ assert_equal result, choice.is_a?(Hash) ? choice[:value] : choice
46
+ end
47
+ end
48
+ end
35
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: question
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - probablycorey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-14 00:00:00.000000000 Z
11
+ date: 2015-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler