tty-prompt 0.20.0 → 0.21.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 (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