tty-prompt 0.12.0 → 0.13.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -3
  3. data/CHANGELOG.md +12 -0
  4. data/README.md +3 -3
  5. data/appveyor.yml +2 -0
  6. data/lib/tty/prompt/keypress.rb +7 -4
  7. data/lib/tty/prompt/reader.rb +1 -1
  8. data/lib/tty/prompt/reader/win_api.rb +14 -0
  9. data/lib/tty/prompt/reader/win_console.rb +9 -2
  10. data/lib/tty/prompt/timeout.rb +44 -23
  11. data/lib/tty/prompt/version.rb +1 -1
  12. data/tty-prompt.gemspec +6 -3
  13. metadata +21 -131
  14. data/spec/spec_helper.rb +0 -45
  15. data/spec/unit/ask_spec.rb +0 -132
  16. data/spec/unit/choice/eql_spec.rb +0 -22
  17. data/spec/unit/choice/from_spec.rb +0 -29
  18. data/spec/unit/choices/add_spec.rb +0 -12
  19. data/spec/unit/choices/each_spec.rb +0 -13
  20. data/spec/unit/choices/find_by_spec.rb +0 -10
  21. data/spec/unit/choices/new_spec.rb +0 -10
  22. data/spec/unit/choices/pluck_spec.rb +0 -9
  23. data/spec/unit/collect_spec.rb +0 -33
  24. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  25. data/spec/unit/converters/convert_char_spec.rb +0 -11
  26. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  27. data/spec/unit/converters/convert_date_spec.rb +0 -34
  28. data/spec/unit/converters/convert_file_spec.rb +0 -17
  29. data/spec/unit/converters/convert_number_spec.rb +0 -39
  30. data/spec/unit/converters/convert_path_spec.rb +0 -18
  31. data/spec/unit/converters/convert_range_spec.rb +0 -22
  32. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  33. data/spec/unit/converters/convert_string_spec.rb +0 -21
  34. data/spec/unit/converters/on_error_spec.rb +0 -9
  35. data/spec/unit/distance/distance_spec.rb +0 -73
  36. data/spec/unit/enum_paginator_spec.rb +0 -65
  37. data/spec/unit/enum_select_spec.rb +0 -310
  38. data/spec/unit/error_spec.rb +0 -20
  39. data/spec/unit/evaluator_spec.rb +0 -67
  40. data/spec/unit/expand_spec.rb +0 -198
  41. data/spec/unit/keypress_spec.rb +0 -58
  42. data/spec/unit/mask_spec.rb +0 -132
  43. data/spec/unit/multi_select_spec.rb +0 -319
  44. data/spec/unit/multiline_spec.rb +0 -77
  45. data/spec/unit/new_spec.rb +0 -20
  46. data/spec/unit/ok_spec.rb +0 -10
  47. data/spec/unit/paginator_spec.rb +0 -63
  48. data/spec/unit/question/checks_spec.rb +0 -97
  49. data/spec/unit/question/default_spec.rb +0 -31
  50. data/spec/unit/question/echo_spec.rb +0 -38
  51. data/spec/unit/question/in_spec.rb +0 -115
  52. data/spec/unit/question/initialize_spec.rb +0 -12
  53. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  54. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  55. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  56. data/spec/unit/question/modify_spec.rb +0 -41
  57. data/spec/unit/question/required_spec.rb +0 -92
  58. data/spec/unit/question/validate_spec.rb +0 -115
  59. data/spec/unit/question/validation/call_spec.rb +0 -31
  60. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  61. data/spec/unit/reader/history_spec.rb +0 -172
  62. data/spec/unit/reader/key_event_spec.rb +0 -86
  63. data/spec/unit/reader/line_spec.rb +0 -110
  64. data/spec/unit/reader/publish_keypress_event_spec.rb +0 -94
  65. data/spec/unit/reader/read_keypress_spec.rb +0 -80
  66. data/spec/unit/reader/read_line_spec.rb +0 -68
  67. data/spec/unit/reader/read_multiline_spec.rb +0 -60
  68. data/spec/unit/result_spec.rb +0 -40
  69. data/spec/unit/say_spec.rb +0 -67
  70. data/spec/unit/select_spec.rb +0 -359
  71. data/spec/unit/slider_spec.rb +0 -96
  72. data/spec/unit/statement/initialize_spec.rb +0 -15
  73. data/spec/unit/suggest_spec.rb +0 -28
  74. data/spec/unit/warn_spec.rb +0 -21
  75. data/spec/unit/yes_no_spec.rb +0 -235
@@ -1,97 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it "passes range check" do
8
- question = described_class.new(prompt)
9
- question.in 1..10
10
-
11
- result = TTY::Prompt::Question::Checks::CheckRange.call(question, 2)
12
-
13
- expect(result).to eq([2])
14
- end
15
-
16
- it "fails range check" do
17
- question = described_class.new(prompt, messages: TTY::Prompt.messages)
18
- question.in 1..10
19
-
20
- result = TTY::Prompt::Question::Checks::CheckRange.call(question, 11)
21
-
22
- expect(result).to eq([11, ["Value 11 must be within the range 1..10"]])
23
- end
24
-
25
- it "fails range check" do
26
- question = described_class.new(prompt)
27
- question.in 1..10, 'Outside of range!'
28
-
29
- result = TTY::Prompt::Question::Checks::CheckRange.call(question, 11)
30
-
31
- expect(result).to eq([11, ['Outside of range!']])
32
- end
33
-
34
- it "passes validation check" do
35
- question = described_class.new(prompt)
36
- question.validate(/\A\d{5}\Z/)
37
-
38
- result = TTY::Prompt::Question::Checks::CheckValidation.call(question, '12345')
39
-
40
- expect(result).to eq(['12345'])
41
- end
42
-
43
- it "fails validation check" do
44
- question = described_class.new(prompt, messages: TTY::Prompt.messages)
45
- question.validate(/\A\d{5}\Z/)
46
-
47
- result = TTY::Prompt::Question::Checks::CheckValidation.call(question, '123')
48
-
49
- expect(result).to eq(['123', ['Your answer is invalid (must match /\\A\\d{5}\\Z/)']])
50
- end
51
-
52
- it "fails validation check with inlined custom message" do
53
- question = described_class.new(prompt)
54
- question.validate(/\A\w+@\w+\.\w+\Z/, 'Invalid email address')
55
-
56
- result = TTY::Prompt::Question::Checks::CheckValidation.call(question, 'piotr@com')
57
-
58
- expect(result).to eq(['piotr@com', ['Invalid email address']])
59
- end
60
-
61
- it "fails validation check with custom message" do
62
- question = described_class.new(prompt)
63
- question.validate(/\A\w+@\w+\.\w+\Z/)
64
- question.messages[:valid?] = 'Invalid email address'
65
-
66
- result = TTY::Prompt::Question::Checks::CheckValidation.call(question, 'piotr@com')
67
-
68
- expect(result).to eq(['piotr@com', ['Invalid email address']])
69
- end
70
-
71
- it "passes required check" do
72
- question = described_class.new(prompt)
73
- question.required true
74
-
75
- result = TTY::Prompt::Question::Checks::CheckRequired.call(question, 'Piotr')
76
-
77
- expect(result).to eq(['Piotr'])
78
- end
79
-
80
- it "fails required check" do
81
- question = described_class.new(prompt, messages: TTY::Prompt.messages)
82
- question.required true
83
-
84
- result = TTY::Prompt::Question::Checks::CheckRequired.call(question, nil)
85
-
86
- expect(result).to eq([nil, ['Value must be provided']])
87
- end
88
-
89
- it "fails required check with custom message" do
90
- question = described_class.new(prompt)
91
- question.required true, 'Required input'
92
-
93
- result = TTY::Prompt::Question::Checks::CheckRequired.call(question, nil)
94
-
95
- expect(result).to eq([nil, ['Required input']])
96
- end
97
- end
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#default' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it 'uses default value' do
8
- name = 'Anonymous'
9
- prompt.input << "\n"
10
- prompt.input.rewind
11
- answer = prompt.ask('What is your name?', default: name)
12
- expect(answer).to eq(name)
13
- expect(prompt.output.string).to eq([
14
- "What is your name? \e[90m(Anonymous)\e[0m ",
15
- "\e[2K\e[1GWhat is your name? \e[90m(Anonymous)\e[0m \n",
16
- "\e[1A\e[2K\e[1G",
17
- "What is your name? \e[32mAnonymous\e[0m\n"
18
- ].join)
19
- end
20
-
21
- it 'uses default value in block' do
22
- name = 'Anonymous'
23
- answer = prompt.ask('What is your name?') { |q| q.default(name) }
24
- expect(answer).to eq(name)
25
- expect(prompt.output.string).to eq([
26
- "What is your name? \e[90m(Anonymous)\e[0m ",
27
- "\e[1A\e[2K\e[1G",
28
- "What is your name? \e[32mAnonymous\e[0m\n"
29
- ].join)
30
- end
31
- end
@@ -1,38 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#echo' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it 'asks with echo on' do
8
- prompt.input << "password"
9
- prompt.input.rewind
10
- answer = prompt.ask("What is your password?") { |q| q.echo(true) }
11
- expect(answer).to eql("password")
12
- expect(prompt.output.string).to eq([
13
- "What is your password? ",
14
- "\e[2K\e[1GWhat is your password? p",
15
- "\e[2K\e[1GWhat is your password? pa",
16
- "\e[2K\e[1GWhat is your password? pas",
17
- "\e[2K\e[1GWhat is your password? pass",
18
- "\e[2K\e[1GWhat is your password? passw",
19
- "\e[2K\e[1GWhat is your password? passwo",
20
- "\e[2K\e[1GWhat is your password? passwor",
21
- "\e[2K\e[1GWhat is your password? password",
22
- "\e[1A\e[2K\e[1G",
23
- "What is your password? \e[32mpassword\e[0m\n"
24
- ].join)
25
- end
26
-
27
- it 'asks with echo off' do
28
- prompt.input << "password"
29
- prompt.input.rewind
30
- answer = prompt.ask("What is your password?", echo: false)
31
- expect(answer).to eql("password")
32
- expect(prompt.output.string).to eq([
33
- "What is your password? ",
34
- "\e[2K\e[1G",
35
- "What is your password? \n"
36
- ].join)
37
- end
38
- end
@@ -1,115 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#in' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it "reads range from option" do
8
- prompt.input << '8'
9
- prompt.input.rewind
10
-
11
- answer = prompt.ask("How do you like it on scale 1-10?", in: '1-10')
12
-
13
- expect(answer).to eq('8')
14
- end
15
-
16
- it 'reads number within string range' do
17
- prompt.input << '8'
18
- prompt.input.rewind
19
-
20
- answer = prompt.ask("How do you like it on scale 1-10?") do |q|
21
- q.in('1-10')
22
- end
23
-
24
- expect(answer).to eq('8')
25
- expect(prompt.output.string).to eq([
26
- "How do you like it on scale 1-10? ",
27
- "\e[2K\e[1GHow do you like it on scale 1-10? 8",
28
- "\e[1A\e[2K\e[1G",
29
- "How do you like it on scale 1-10? \e[32m8\e[0m\n",
30
- ].join)
31
- end
32
-
33
- it 'reads number within digit range' do
34
- prompt.input << '8.1'
35
- prompt.input.rewind
36
-
37
- answer = prompt.ask("How do you like it on scale 1-10?") do |q|
38
- q.in(1.0..11.5)
39
- end
40
-
41
- expect(answer).to eq('8.1')
42
- expect(prompt.output.string).to eq([
43
- "How do you like it on scale 1-10? ",
44
- "\e[2K\e[1GHow do you like it on scale 1-10? 8",
45
- "\e[2K\e[1GHow do you like it on scale 1-10? 8.",
46
- "\e[2K\e[1GHow do you like it on scale 1-10? 8.1",
47
- "\e[1A\e[2K\e[1G",
48
- "How do you like it on scale 1-10? \e[32m8.1\e[0m\n",
49
- ].join)
50
- end
51
-
52
- it 'reads letters within range' do
53
- prompt.input << 'E'
54
- prompt.input.rewind
55
-
56
- answer = prompt.ask("Your favourite vitamin? (A-K)") do |q|
57
- q.in('A-K')
58
- end
59
-
60
- expect(answer).to eq('E')
61
- expect(prompt.output.string).to eq([
62
- "Your favourite vitamin? (A-K) ",
63
- "\e[2K\e[1GYour favourite vitamin? (A-K) E",
64
- "\e[1A\e[2K\e[1G",
65
- "Your favourite vitamin? (A-K) \e[32mE\e[0m\n"
66
- ].join)
67
- end
68
-
69
- it "provides default error message when wrong input" do
70
- prompt.input << "A\n2\n"
71
- prompt.input.rewind
72
-
73
- answer = prompt.ask("How spicy on scale? (1-5)", in: '1-5')
74
-
75
- expect(answer).to eq('2')
76
- expect(prompt.output.string).to eq([
77
- "How spicy on scale? (1-5) ",
78
- "\e[2K\e[1GHow spicy on scale? (1-5) A",
79
- "\e[2K\e[1GHow spicy on scale? (1-5) A\n",
80
- "\e[31m>>\e[0m Value A must be within the range 1..5\e[1A",
81
- "\e[2K\e[1G",
82
- "How spicy on scale? (1-5) ",
83
- "\e[2K\e[1GHow spicy on scale? (1-5) 2",
84
- "\e[2K\e[1GHow spicy on scale? (1-5) 2\n",
85
- "\e[2K\e[1G",
86
- "\e[1A\e[2K\e[1G",
87
- "How spicy on scale? (1-5) \e[32m2\e[0m\n"
88
- ].join)
89
- end
90
-
91
- it "overwrites default error message when wrong input" do
92
- prompt.input << "A\n2\n"
93
- prompt.input.rewind
94
-
95
- answer = prompt.ask("How spicy on scale? (1-5)") do |q|
96
- q.in '1-5'
97
- q.messages[:range?] = 'Ohh dear what is this %{value} doing in %{in}?'
98
- end
99
-
100
- expect(answer).to eq('2')
101
- expect(prompt.output.string).to eq([
102
- "How spicy on scale? (1-5) ",
103
- "\e[2K\e[1GHow spicy on scale? (1-5) A",
104
- "\e[2K\e[1GHow spicy on scale? (1-5) A\n",
105
- "\e[31m>>\e[0m Ohh dear what is this A doing in 1..5?\e[1A",
106
- "\e[2K\e[1G",
107
- "How spicy on scale? (1-5) ",
108
- "\e[2K\e[1GHow spicy on scale? (1-5) 2",
109
- "\e[2K\e[1GHow spicy on scale? (1-5) 2\n",
110
- "\e[2K\e[1G",
111
- "\e[1A\e[2K\e[1G",
112
- "How spicy on scale? (1-5) \e[32m2\e[0m\n"
113
- ].join)
114
- end
115
- end
@@ -1,12 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#initialize' do
4
-
5
- subject(:question) { described_class.new(TTY::TestPrompt.new)}
6
-
7
- it { expect(question.echo).to eq(true) }
8
-
9
- it { expect(question.modifier).to eq([]) }
10
-
11
- it { expect(question.validation).to eq(TTY::Prompt::Question::UndefinedSetting) }
12
- end
@@ -1,24 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question::Modifier, '#apply_to' do
4
- let(:string) { "text to be modified"}
5
-
6
- it "doesn't apply modifiers" do
7
- modifier = described_class.new([])
8
- expect(modifier.apply_to(string)).to eq(string)
9
- end
10
-
11
- it 'combines whitespace & letter case modifications' do
12
- modifiers = [:collapse, :capitalize]
13
- modifier = described_class.new(modifiers)
14
- modified = modifier.apply_to(string)
15
- expect(modified).to eq('Text to be modified')
16
- end
17
-
18
- it 'combines letter case & whitespace modifications' do
19
- modifiers = [:up, :collapse]
20
- modifier = described_class.new(modifiers)
21
- modified = modifier.apply_to(string)
22
- expect(modified).to eq('TEXT TO BE MODIFIED')
23
- end
24
- end
@@ -1,41 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question::Modifier, '#letter_case' do
4
- context "string" do
5
- let(:string) { 'text to modify' }
6
-
7
- it "changes to uppercase" do
8
- modified = described_class.letter_case(:up, string)
9
- expect(modified).to eq('TEXT TO MODIFY')
10
- end
11
-
12
- it "changes to lower case" do
13
- modified = described_class.letter_case(:down, string)
14
- expect(modified).to eq('text to modify')
15
- end
16
-
17
- it "capitalizes text" do
18
- modified = described_class.letter_case(:capitalize, string)
19
- expect(modified).to eq('Text to modify')
20
- end
21
- end
22
-
23
- context "nil (empty user input)" do
24
- let(:string) { nil }
25
-
26
- example "up returns nil" do
27
- modified = described_class.letter_case(:up, string)
28
- expect(modified).to be_nil
29
- end
30
-
31
- example "down returns nil" do
32
- modified = described_class.letter_case(:down, string)
33
- expect(modified).to be_nil
34
- end
35
-
36
- example "capitalize returns nil" do
37
- modified = described_class.letter_case(:capitalize, string)
38
- expect(modified).to be_nil
39
- end
40
- end
41
- end
@@ -1,51 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question::Modifier, '#whitespace' do
4
- context "string with whitespaces" do
5
- let(:string) { " text\t \n to\t modify\r\n" }
6
-
7
- it "trims whitespace" do
8
- modified = described_class.whitespace(:trim, string)
9
- expect(modified).to eq("text\t \n to\t modify")
10
- end
11
-
12
- it "chomps whitespace" do
13
- modified = described_class.whitespace(:chomp, string)
14
- expect(modified).to eq(" text\t \n to\t modify")
15
- end
16
-
17
- it "collapses text" do
18
- modified = described_class.whitespace(:collapse, string)
19
- expect(modified).to eq(" text to modify ")
20
- end
21
-
22
- it "removes whitespace" do
23
- modified = described_class.whitespace(:remove, string)
24
- expect(modified).to eq("texttomodify")
25
- end
26
- end
27
-
28
- context "nil (empty user input)" do
29
- let(:string) { nil }
30
-
31
- example "trim returns nil" do
32
- modified = described_class.whitespace(:trim, string)
33
- expect(modified).to be_nil
34
- end
35
-
36
- example "chomp returns nil" do
37
- modified = described_class.whitespace(:chomp, string)
38
- expect(modified).to be_nil
39
- end
40
-
41
- example "collapse returns nil" do
42
- modified = described_class.whitespace(:collapse, string)
43
- expect(modified).to be_nil
44
- end
45
-
46
- example "remove returns nil" do
47
- modified = described_class.whitespace(:remove, string)
48
- expect(modified).to be_nil
49
- end
50
- end
51
- end
@@ -1,41 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#modify' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it 'preserves answer for unkown modification' do
8
- prompt.input << 'piotr'
9
- prompt.input.rewind
10
- answer = prompt.ask("What is your name?") { |q| q.modify(:none) }
11
- expect(answer).to eq('piotr')
12
- end
13
-
14
- it 'converts to upper case' do
15
- prompt.input << 'piotr'
16
- prompt.input.rewind
17
- answer = prompt.ask("What is your name?") { |q| q.modify(:upcase) }
18
- expect(answer).to eq('PIOTR')
19
- end
20
-
21
- it 'trims whitespace' do
22
- prompt.input << " Some white\t space\t \there! \n"
23
- prompt.input.rewind
24
- answer = prompt.ask('Enter some text: ') { |q| q.modify(:trim) }
25
- expect(answer).to eq("Some white\t space\t \there!")
26
- end
27
-
28
- it 'collapses whitespace' do
29
- prompt.input << " Some white\t space\t \there! \n"
30
- prompt.input.rewind
31
- answer = prompt.ask('Enter some text: ') { |q| q.modify(:collapse) }
32
- expect(answer).to eq(' Some white space here! ')
33
- end
34
-
35
- it 'strips and collapses whitespace' do
36
- prompt.input << " Some white\t space\t \there! \n"
37
- prompt.input.rewind
38
- answer = prompt.ask('Enter some text: ') { |q| q.modify(:strip, :collapse) }
39
- expect(answer).to eq('Some white space here!')
40
- end
41
- end