tty-prompt 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +29 -4
  4. data/lib/tty/prompt.rb +3 -3
  5. data/lib/tty/prompt/multi_list.rb +33 -10
  6. data/lib/tty/prompt/version.rb +1 -1
  7. metadata +11 -175
  8. data/Rakefile +0 -8
  9. data/examples/ask.rb +0 -7
  10. data/examples/ask_blank.rb +0 -9
  11. data/examples/ask_multiline.rb +0 -7
  12. data/examples/ask_valid.rb +0 -12
  13. data/examples/collect.rb +0 -21
  14. data/examples/echo.rb +0 -11
  15. data/examples/enum_select.rb +0 -7
  16. data/examples/enum_select_disabled.rb +0 -16
  17. data/examples/enum_select_paged.rb +0 -9
  18. data/examples/enum_select_wrapped.rb +0 -15
  19. data/examples/expand.rb +0 -29
  20. data/examples/expand_auto.rb +0 -29
  21. data/examples/in.rb +0 -9
  22. data/examples/inputs.rb +0 -10
  23. data/examples/key_events.rb +0 -15
  24. data/examples/keypress.rb +0 -9
  25. data/examples/mask.rb +0 -13
  26. data/examples/multi_select.rb +0 -8
  27. data/examples/multi_select_disabled.rb +0 -17
  28. data/examples/multi_select_disabled_paged.rb +0 -22
  29. data/examples/multi_select_paged.rb +0 -9
  30. data/examples/multi_select_wrapped.rb +0 -15
  31. data/examples/multiline.rb +0 -9
  32. data/examples/pause.rb +0 -9
  33. data/examples/select.rb +0 -24
  34. data/examples/select_disabled.rb +0 -18
  35. data/examples/select_disabled_paged.rb +0 -22
  36. data/examples/select_enum.rb +0 -8
  37. data/examples/select_filtered.rb +0 -11
  38. data/examples/select_paginated.rb +0 -11
  39. data/examples/select_wrapped.rb +0 -15
  40. data/examples/slider.rb +0 -6
  41. data/examples/validation.rb +0 -9
  42. data/examples/yes_no.rb +0 -7
  43. data/spec/spec_helper.rb +0 -61
  44. data/spec/unit/ask_spec.rb +0 -173
  45. data/spec/unit/block_paginator_spec.rb +0 -84
  46. data/spec/unit/choice/eql_spec.rb +0 -22
  47. data/spec/unit/choice/from_spec.rb +0 -130
  48. data/spec/unit/choices/add_spec.rb +0 -12
  49. data/spec/unit/choices/each_spec.rb +0 -13
  50. data/spec/unit/choices/find_by_spec.rb +0 -10
  51. data/spec/unit/choices/new_spec.rb +0 -10
  52. data/spec/unit/choices/pluck_spec.rb +0 -9
  53. data/spec/unit/collect_spec.rb +0 -96
  54. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  55. data/spec/unit/converters/convert_char_spec.rb +0 -11
  56. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  57. data/spec/unit/converters/convert_date_spec.rb +0 -34
  58. data/spec/unit/converters/convert_file_spec.rb +0 -18
  59. data/spec/unit/converters/convert_number_spec.rb +0 -39
  60. data/spec/unit/converters/convert_path_spec.rb +0 -15
  61. data/spec/unit/converters/convert_range_spec.rb +0 -22
  62. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  63. data/spec/unit/converters/convert_string_spec.rb +0 -21
  64. data/spec/unit/converters/on_error_spec.rb +0 -9
  65. data/spec/unit/distance/distance_spec.rb +0 -73
  66. data/spec/unit/enum_select_spec.rb +0 -518
  67. data/spec/unit/error_spec.rb +0 -20
  68. data/spec/unit/evaluator_spec.rb +0 -67
  69. data/spec/unit/expand_spec.rb +0 -290
  70. data/spec/unit/keypress_spec.rb +0 -66
  71. data/spec/unit/mask_spec.rb +0 -140
  72. data/spec/unit/multi_select_spec.rb +0 -741
  73. data/spec/unit/multiline_spec.rb +0 -77
  74. data/spec/unit/new_spec.rb +0 -20
  75. data/spec/unit/ok_spec.rb +0 -10
  76. data/spec/unit/paginator_spec.rb +0 -92
  77. data/spec/unit/question/checks_spec.rb +0 -97
  78. data/spec/unit/question/default_spec.rb +0 -31
  79. data/spec/unit/question/echo_spec.rb +0 -38
  80. data/spec/unit/question/in_spec.rb +0 -115
  81. data/spec/unit/question/initialize_spec.rb +0 -12
  82. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  83. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  84. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  85. data/spec/unit/question/modify_spec.rb +0 -41
  86. data/spec/unit/question/required_spec.rb +0 -92
  87. data/spec/unit/question/validate_spec.rb +0 -115
  88. data/spec/unit/question/validation/call_spec.rb +0 -31
  89. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  90. data/spec/unit/result_spec.rb +0 -40
  91. data/spec/unit/say_spec.rb +0 -67
  92. data/spec/unit/select_spec.rb +0 -942
  93. data/spec/unit/slider_spec.rb +0 -142
  94. data/spec/unit/statement/initialize_spec.rb +0 -15
  95. data/spec/unit/subscribe_spec.rb +0 -22
  96. data/spec/unit/suggest_spec.rb +0 -28
  97. data/spec/unit/timer_spec.rb +0 -29
  98. data/spec/unit/warn_spec.rb +0 -21
  99. data/spec/unit/yes_no_spec.rb +0 -285
  100. data/tasks/console.rake +0 -11
  101. data/tasks/coverage.rake +0 -11
  102. data/tasks/spec.rake +0 -29
  103. data/tty-prompt.gemspec +0 -40
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Choices, '#<<' do
4
- it "adds choice to collection" do
5
- choices = described_class.new
6
- expect(choices).to be_empty
7
- choice = TTY::Prompt::Choice.from([:label, 1])
8
- choices << [:label, 1]
9
- expect(choices.size).to eq(1)
10
- expect(choices.to_ary).to eq([choice])
11
- end
12
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Choices, '.each' do
4
- it "iterates over collection" do
5
- choices = described_class[:large, :medium, :small]
6
- actual = []
7
- choices.each do |choice|
8
- actual << choice.name
9
- end
10
- expect(actual).to eq([:large, :medium, :small])
11
- expect(choices.each).to be_kind_of(Enumerator)
12
- end
13
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Choices, '#find_by' do
4
- it "finds a matching choice by key name" do
5
- collection = [{name: 'large'},{name: 'medium'},{name: 'small'}]
6
- choice = TTY::Prompt::Choice.from(name: 'small')
7
- choices = described_class[*collection]
8
- expect(choices.find_by(:name, 'small')).to eq(choice)
9
- end
10
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Choices, '.new' do
4
- it "creates choices collection" do
5
- choice_1 = TTY::Prompt::Choice.from(:label1)
6
- choice_2 = TTY::Prompt::Choice.from(:label2)
7
- collection = described_class[:label1, :label2]
8
- expect(collection.choices).to eq([choice_1, choice_2])
9
- end
10
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Choices, '#pluck' do
4
- it "plucks choice by key name" do
5
- collection = [{name: 'large'},{name: 'medium'},{name: 'small'}]
6
- choices = described_class[*collection]
7
- expect(choices.pluck(:name)).to eq(['large', 'medium', 'small'])
8
- end
9
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt, '#collect' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- def collect(&block)
8
- prompt = subject
9
- count = 0
10
-
11
- result = prompt.collect do
12
- while prompt.yes?("continue?")
13
- instance_eval(&block)
14
- count += 1
15
- end
16
- end
17
-
18
- result[:count] = count
19
- result
20
- end
21
-
22
- context "when receiving multiple answers" do
23
- let(:colors) { %w(red blue yellow) }
24
-
25
- before do
26
- subject.input << "y\r" + colors.join("\ry\r") + "\rn\r"
27
- subject.input.rewind
28
- end
29
-
30
- it "collects as a list if values method used in chain" do
31
- result = collect { key(:colors).values.ask("color:") }
32
- expect(result[:count]).to eq(3)
33
- expect(result[:colors]).to eq(colors)
34
- end
35
-
36
- it "collects as a list if values method used in chain with block" do
37
- result = collect do
38
- key(:colors).values { key(:name).ask("color:") }
39
- end
40
- expect(result[:count]).to eq(3)
41
- expect(result[:colors]).to eq(colors.map { |c| { name: c } })
42
- end
43
-
44
- context "with multiple keys" do
45
- let(:colors) { ["red\rblue", "yellow\rgreen"] }
46
- let(:expected_pairs) do
47
- colors.map { |s| Hash[%i(hot cold).zip(s.split("\r"))] }
48
- end
49
-
50
- it "collects into the appropriate keys" do
51
- result = collect do
52
- key(:pairs).values do
53
- key(:hot).ask("color:")
54
- key(:cold).ask("color:")
55
- end
56
- end
57
-
58
- expect(result[:count]).to eq(2)
59
- expect(result[:pairs]).to eq(expected_pairs)
60
- end
61
- end
62
-
63
- it "overrides a non-array key on multiple answers" do
64
- result = collect { key(:colors).ask("color:") }
65
- expect(result[:colors]).to eq(colors.last)
66
- expect(result[:count]).to eq(3)
67
- end
68
- end
69
-
70
- it "collects more than one answer" do
71
- prompt.input << "Piotr\r30\rStreet\rCity\r123\r"
72
- prompt.input.rewind
73
-
74
- result = prompt.collect do
75
- key(:name).ask('Name?')
76
-
77
- key(:age).ask('Age?', convert: :int)
78
-
79
- key(:address) do
80
- key(:street).ask('Street?', required: true)
81
- key(:city).ask('City?')
82
- key(:zip).ask('Zip?', validate: /\A\d{3}\Z/)
83
- end
84
- end
85
-
86
- expect(result).to include({
87
- name: 'Piotr',
88
- age: 30,
89
- address: {
90
- street: 'Street',
91
- city: 'City',
92
- zip: '123'
93
- }
94
- })
95
- end
96
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert bool' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new}
6
-
7
- it 'fails to convert boolean' do
8
- prompt.input << 'invalid'
9
- prompt.input.rewind
10
- expect {
11
- prompt.ask("Do you read books?", convert: :bool)
12
- }.to raise_error(TTY::Prompt::ConversionError)
13
- end
14
-
15
- it "handles default values" do
16
- prompt.input << "\n"
17
- prompt.input.rewind
18
- response = prompt.ask('Do you read books?', convert: :bool, default: true)
19
- expect(response).to eql(true)
20
- expect(prompt.output.string).to eq([
21
- "Do you read books? \e[90m(true)\e[0m ",
22
- "\e[2K\e[1GDo you read books? \e[90m(true)\e[0m \n",
23
- "\e[1A\e[2K\e[1G",
24
- "Do you read books? \e[32mtrue\e[0m\n"
25
- ].join)
26
- end
27
-
28
- it "handles default values" do
29
- prompt.input << "\n"
30
- prompt.input.rewind
31
- response = prompt.ask("Do you read books?") { |q|
32
- q.default true
33
- q.convert :bool
34
- }
35
- expect(response).to eq(true)
36
- end
37
-
38
- it 'converts negative boolean' do
39
- prompt.input << 'No'
40
- prompt.input.rewind
41
- response = prompt.ask('Do you read books?', convert: :bool)
42
- expect(response).to eq(false)
43
- end
44
-
45
- it 'converts positive boolean' do
46
- prompt.input << 'Yes'
47
- prompt.input.rewind
48
- response = prompt.ask("Do you read books?", convert: :bool)
49
- expect(response).to eq(true)
50
- end
51
-
52
- it 'converts single positive boolean' do
53
- prompt.input << 'y'
54
- prompt.input.rewind
55
- response = prompt.ask('Do you read books?', convert: :bool)
56
- expect(response).to eq(true)
57
- end
58
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert char' do
4
- it 'reads single character' do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << "abcde"
7
- prompt.input.rewind
8
- response = prompt.ask("What is your favourite letter?", convert: :char)
9
- expect(response).to eq('a')
10
- end
11
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert custom' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it 'converts response with custom conversion' do
8
- prompt.input << "one,two,three\n"
9
- prompt.input.rewind
10
- conversion = proc { |input| input.split(/,\s*/) }
11
- answer = prompt.ask('Ingredients? (comma sep list)', convert: conversion)
12
- expect(answer).to eq(['one','two','three'])
13
- end
14
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert date' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new}
6
-
7
- it 'fails to convert date' do
8
- prompt.input << 'invalid'
9
- prompt.input.rewind
10
- expect {
11
- prompt.ask("When were you born?", convert: :date)
12
- }.to raise_error(TTY::Prompt::ConversionError)
13
- end
14
-
15
- it 'converts date' do
16
- prompt.input << "20th April 1887"
17
- prompt.input.rewind
18
- response = prompt.ask("When were your born?", convert: :date)
19
- expect(response).to be_kind_of(Date)
20
- expect(response.day).to eq(20)
21
- expect(response.month).to eq(4)
22
- expect(response.year).to eq(1887)
23
- end
24
-
25
- it "converts datetime" do
26
- prompt.input << "20th April 1887"
27
- prompt.input.rewind
28
- response = prompt.ask("When were your born?", convert: :datetime)
29
- expect(response).to be_kind_of(DateTime)
30
- expect(response.day).to eq(20)
31
- expect(response.month).to eq(4)
32
- expect(response.year).to eq(1887)
33
- end
34
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert file' do
4
- it "converts to file" do
5
- ::File.write('test.txt', 'foobar')
6
-
7
- prompt = TTY::TestPrompt.new
8
- prompt.input << "test.txt"
9
- prompt.input.rewind
10
-
11
- answer = prompt.ask("Which file to open?", convert: :file)
12
-
13
- expect(::File.basename(answer)).to eq('test.txt')
14
- expect(::File.read(answer)).to eq('foobar')
15
-
16
- ::File.unlink('test.txt') unless Gem.win_platform?
17
- end
18
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert numbers' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- it 'fails to convert integer' do
8
- prompt.input << 'invalid'
9
- prompt.input.rewind
10
- expect {
11
- prompt.ask("What temparture?", convert: :int)
12
- }.to raise_error(TTY::Prompt::ConversionError)
13
- end
14
-
15
- it 'converts integer' do
16
- prompt.input << 35
17
- prompt.input.rewind
18
- answer = prompt.ask("What temperature?", convert: :int)
19
- expect(answer).to be_a(Integer)
20
- expect(answer).to eq(35)
21
- end
22
-
23
- it 'fails to convert float' do
24
- prompt.input << 'invalid'
25
- prompt.input.rewind
26
- expect {
27
- prompt.ask("How tall are you?", convert: :float)
28
- }.to raise_error(TTY::Prompt::ConversionError)
29
- end
30
-
31
- it 'converts float' do
32
- number = 6.666
33
- prompt.input << number
34
- prompt.input.rewind
35
- answer = prompt.ask('How tall are you?', convert: :float)
36
- expect(answer).to be_a(Float)
37
- expect(answer).to eq(number)
38
- end
39
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert path' do
4
- subject(:prompt) { TTY::TestPrompt.new }
5
-
6
- it "converts pathname" do
7
- path = Pathname.new(::File.join(Dir.pwd, 'spec/unit'))
8
- prompt.input << "spec/unit"
9
- prompt.input.rewind
10
-
11
- answer = prompt.ask('File location?', convert: :path)
12
-
13
- expect(answer).to eql(path)
14
- end
15
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert range' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new}
6
-
7
- it 'converts with valid range' do
8
- prompt.input << "20-30"
9
- prompt.input.rewind
10
- answer = prompt.ask("Which age group?", convert: :range)
11
- expect(answer).to be_a(Range)
12
- expect(answer).to eq(20..30)
13
- end
14
-
15
- it "fails to convert to range" do
16
- prompt.input << "abcd"
17
- prompt.input.rewind
18
- expect {
19
- prompt.ask('Which age group?', convert: :range)
20
- }.to raise_error(TTY::Prompt::ConversionError)
21
- end
22
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert regexp' do
4
- it "converts regex" do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << "[a-z]*"
7
- prompt.input.rewind
8
- answer = prompt.ask("Regex?", convert: :regexp)
9
- expect(answer).to be_a(Regexp)
10
- expect(answer).to eq(/[a-z]*/)
11
- end
12
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert string' do
4
- it 'converts string' do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << 'Piotr'
7
- prompt.input.rewind
8
- answer = prompt.ask("What is your name?", convert: :string)
9
- expect(answer).to be_a(String)
10
- expect(answer).to eq('Piotr')
11
- end
12
-
13
- it "converts symbol" do
14
- prompt = TTY::TestPrompt.new
15
- prompt.input << 'Piotr'
16
- prompt.input.rewind
17
- answer = prompt.ask("What is your name?", convert: :symbol)
18
- expect(answer).to be_a(Symbol)
19
- expect(answer).to eq(:Piotr)
20
- end
21
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Converters do
4
- it "enforces block argument" do
5
- expect {
6
- TTY::Prompt::Converters.on_error
7
- }.to raise_error(ArgumentError, 'You need to provide a block argument.')
8
- end
9
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Distance, '.distance' do
4
- let(:object) { described_class.new }
5
-
6
- subject(:distance) { object.distance(*strings) }
7
-
8
- context 'when nil' do
9
- let(:strings) { [nil, nil] }
10
-
11
- it { is_expected.to eql(0) }
12
- end
13
-
14
- context 'when empty' do
15
- let(:strings) { ['', ''] }
16
-
17
- it { is_expected.to eql(0) }
18
- end
19
-
20
- context 'with one non empty' do
21
- let(:strings) { ['abc', ''] }
22
-
23
- it { is_expected.to eql(3) }
24
- end
25
-
26
- context 'when single char' do
27
- let(:strings) { ['a', 'abc'] }
28
-
29
- it { is_expected.to eql(2) }
30
- end
31
-
32
- context 'when similar' do
33
- let(:strings) { ['abc', 'abc'] }
34
-
35
- it { is_expected.to eql(0) }
36
- end
37
-
38
- context 'when similar' do
39
- let(:strings) { ['abc', 'acb'] }
40
-
41
- it { is_expected.to eql(1) }
42
- end
43
-
44
- context 'when end similar' do
45
- let(:strings) { ['saturday', 'sunday'] }
46
-
47
- it { is_expected.to eql(3) }
48
- end
49
-
50
- context 'when contain similar' do
51
- let(:strings) { ['which', 'witch'] }
52
-
53
- it { is_expected.to eql(2) }
54
- end
55
-
56
- context 'when prefix' do
57
- let(:strings) { ['sta', 'status'] }
58
-
59
- it { is_expected.to eql(3) }
60
- end
61
-
62
- context 'when similar' do
63
- let(:strings) { ['smellyfish','jellyfish'] }
64
-
65
- it { is_expected.to eql(2) }
66
- end
67
-
68
- context 'when unicode' do
69
- let(:strings) { ['マラソン五輪代表', 'ララソン五輪代表'] }
70
-
71
- it { is_expected.to eql(1) }
72
- end
73
- end