spec/unit/multi_select_spec.rb in tty-prompt-0.18.1 vs spec/unit/multi_select_spec.rb in tty-prompt-0.19.0
- old
+ new
@@ -1,29 +1,33 @@
# frozen_string_literal: true
RSpec.describe TTY::Prompt do
let(:symbols) { TTY::Prompt::Symbols.symbols }
+ let(:up_down) { "#{symbols[:arrow_up]}/#{symbols[:arrow_down]}" }
+ let(:left_right) { "#{symbols[:arrow_left]}/#{symbols[:arrow_right]}"}
def output_helper(prompt, choices, active, selected, options = {})
raise ":init requires :hint" if options[:init] && options[:hint].nil?
hint = options[:hint]
init = options.fetch(:init, false)
enum = options[:enum]
out = []
out << "\e[?25l" if init
out << prompt << " "
+ out << "(max. #{options[:max]}) " if options[:max]
out << selected.join(', ')
+ out << " " if init && !selected.empty?
out << "\e[90m" if init
out << (init ? "(#{hint})\e[0m" : " (#{hint})") if hint
out << "\n"
out << choices.map.with_index do |choice, i|
name = choice.is_a?(Hash) ? choice[:name] : choice
disabled = choice.is_a?(Hash) ? choice[:disabled] : false
num = (i + 1).to_s + enum if enum
- prefix = name == active ? "#{symbols[:pointer]} " : " "
+ prefix = name == active ? "#{symbols[:marker]} " : " "
prefix += if disabled
"\e[31m#{symbols[:cross]}\e[0m #{num}#{name} #{disabled}"
elsif selected.include?(name)
"\e[32m#{symbols[:radio_on]}\e[0m #{num}#{name}"
else
@@ -46,125 +50,134 @@
it "selects nothing when return pressed immediately" do
prompt = TTY::TestPrompt.new
choices = %i(vodka beer wine whisky bourbon)
prompt.input << "\r"
prompt.input.rewind
+
expect(prompt.multi_select("Select drinks?", choices)). to eq([])
- expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+
+ expected_output = [
+ "\e[?25lSelect drinks? \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \n\e[?25h"
- ].join)
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
end
it "selects item when space pressed" do
prompt = TTY::TestPrompt.new
choices = %w(vodka beer wine whisky bourbon)
prompt.input << " \r"
prompt.input.rewind
expect(prompt.multi_select("Select drinks?", choices)). to eq(['vodka'])
- expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+
+ expected_output = [
+ "\e[?25lSelect drinks? \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? vodka\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
- ].join)
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
end
it "selects item when space pressed but doesn't echo item if echo: false" do
prompt = TTY::TestPrompt.new
choices = %w(vodka beer wine whisky bourbon)
prompt.input << " \r"
prompt.input.rewind
expect(prompt.multi_select("Select drinks?", choices, echo: false)). to eq(['vodka'])
- expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+
+ expected_output = [
+ "\e[?25lSelect drinks? \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \n\e[?25h"
- ].join)
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
end
it "sets choice custom values" do
prompt = TTY::TestPrompt.new
choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
prompt.input << " \r"
prompt.input.rewind
expect(prompt.multi_select("Select drinks?", choices)).to eq([1])
- expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+ expected_output = [
+ "\e[?25lSelect drinks? \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? vodka\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
- ].join)
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
end
it "sets choice name and value through DSL" do
prompt = TTY::TestPrompt.new
prompt.input << " \r"
prompt.input.rewind
value = prompt.multi_select("Select drinks?") do |menu|
+ menu.symbols marker: '>', radio_off: '-', radio_on: '='
menu.enum ')'
menu.choice :vodka, {score: 1}
menu.choice :beer, 2
menu.choice :wine, 3
menu.choices whisky: 4, bourbon: 5
end
expect(value).to eq([{score: 1}])
expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? \e[90m(Use arrow or number (1-5) keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} 1) vodka\n",
- " #{symbols[:radio_off]} 2) beer\n",
- " #{symbols[:radio_off]} 3) wine\n",
- " #{symbols[:radio_off]} 4) whisky\n",
- " #{symbols[:radio_off]} 5) bourbon",
+ "\e[?25lSelect drinks? \e[90m(Use #{up_down} arrow or number (1-5) keys, press Space to select and Enter to finish)\e[0m\n",
+ "> - 1) vodka\n",
+ " - 2) beer\n",
+ " - 3) wine\n",
+ " - 4) whisky\n",
+ " - 5) bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? vodka\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m 1) vodka\n",
- " #{symbols[:radio_off]} 2) beer\n",
- " #{symbols[:radio_off]} 3) wine\n",
- " #{symbols[:radio_off]} 4) whisky\n",
- " #{symbols[:radio_off]} 5) bourbon",
+ "> \e[32m=\e[0m 1) vodka\n",
+ " - 2) beer\n",
+ " - 3) wine\n",
+ " - 4) whisky\n",
+ " - 5) bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
].join)
end
@@ -181,16 +194,16 @@
menu.choice :whisky, {score: 40}
menu.choice :bourbon, {score: 50}
end
expect(value).to match_array([{score: 20}, {score: 50}])
expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? beer, bourbon \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "\e[?25lSelect drinks? beer, bourbon \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
" #{symbols[:radio_off]} vodka\n",
" \e[32m#{symbols[:radio_on]}\e[0m beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m bourbon",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \e[32mbeer, bourbon\e[0m\n\e[?25h",
].join)
end
@@ -229,12 +242,12 @@
choices = %w(vodka beer wine whisky bourbon)
prompt.input << "\r"
prompt.input.rewind
expect(prompt.multi_select("Select drinks?", choices)). to eq([])
expect(prompt.output.string).to eq([
- "\e[?25l[?] Select drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+ "\e[?25l[?] Select drinks? \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
@@ -245,14 +258,14 @@
it "changes selected item color & marker" do
prompt = TTY::TestPrompt.new
choices = %w(vodka beer wine whisky bourbon)
prompt.input << "\r"
prompt.input.rewind
- options = {default: [1], active_color: :blue, marker: '>'}
+ options = {default: [1], active_color: :blue, symbols: {marker: '>'}}
expect(prompt.multi_select("Select drinks?", choices, options)). to eq(['vodka'])
expect(prompt.output.string).to eq([
- "\e[?25lSelect drinks? vodka \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "\e[?25lSelect drinks? vodka \e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
"> \e[34m#{symbols[:radio_on]}\e[0m vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
@@ -264,99 +277,221 @@
it "changes help text" do
prompt = TTY::TestPrompt.new
choices = %w(vodka beer wine whisky bourbon)
prompt.input << "\r"
prompt.input.rewind
- expect(prompt.multi_select("Select drinks?", choices, help: '(Bash keyboard)')). to eq([])
- expect(prompt.output.string).to eq([
+
+ answer = prompt.multi_select("Select drinks?", choices, help: '(Bash keyboard)')
+
+ expect(answer).to eq([])
+ expected_output = [
"\e[?25lSelect drinks? \e[90m(Bash keyboard)\e[0m\n",
- "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} vodka\n",
" #{symbols[:radio_off]} beer\n",
" #{symbols[:radio_off]} wine\n",
" #{symbols[:radio_off]} whisky\n",
" #{symbols[:radio_off]} bourbon",
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
"Select drinks? \n\e[?25h"
- ].join)
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
end
- it "paginates long selections" do
- prompt = TTY::TestPrompt.new
- choices = %w(A B C D E F G H)
- prompt.input << "\r"
- prompt.input.rewind
- value = prompt.multi_select("What letter?", choices, per_page: 3, default: 4)
- expect(value).to eq(['D'])
- expect(prompt.output.string).to eq([
- "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
- " #{symbols[:radio_off]} E\n",
- " #{symbols[:radio_off]} F\n",
- "\e[90m(Move up or down to reveal more choices)\e[0m",
- "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
- "What letter? \e[32mD\e[0m\n\e[?25h",
- ].join)
- end
+ context "when paginated" do
+ it "paginates long selections" do
+ prompt = TTY::TestPrompt.new
+ choices = %w(A B C D E F G H)
+ prompt.input << "\r"
+ prompt.input.rewind
- it "paginates choices as hash object" do
- prompt = TTY::TestPrompt.new
- choices = {A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7, H: 8}
- prompt.input << "\r"
- prompt.input.rewind
- value = prompt.multi_select("What letter?", choices, default: 4, per_page: 3)
- expect(value).to eq([4])
- expect(prompt.output.string).to eq([
- "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
- " #{symbols[:radio_off]} E\n",
- " #{symbols[:radio_off]} F\n",
- "\e[90m(Move up or down to reveal more choices)\e[0m",
- "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
- "What letter? \e[32mD\e[0m\n\e[?25h",
- ].join)
- end
+ answer = prompt.multi_select("What letter?", choices, per_page: 3, default: 4)
- it "paginates long selections through DSL" do
- prompt = TTY::TestPrompt.new
- choices = %w(A B C D E F G H)
- prompt.input << "\r"
- prompt.input.rewind
- value = prompt.multi_select("What letter?") do |menu|
- menu.per_page 3
- menu.page_help '(Wiggle thy finger up or down to see more)'
- menu.default 4
- menu.choices choices
- end
- expect(value).to eq(['D'])
- expect(prompt.output.string).to eq([
- "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
- " #{symbols[:radio_off]} E\n",
- " #{symbols[:radio_off]} F\n",
- "\e[90m(Wiggle thy finger up or down to see more)\e[0m",
- "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
- "What letter? \e[32mD\e[0m\n\e[?25h",
- ].join)
- end
+ expect(answer).to eq(['D'])
+ expected_output = [
+ "\e[?25lWhat letter? D \e[90m(Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
+ " #{symbols[:radio_off]} E\n",
+ " #{symbols[:radio_off]} F",
+ "\e[2K\e[1G\e[1A" * 3,
+ "\e[2K\e[1G",
+ "What letter? \e[32mD\e[0m\n\e[?25h",
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
+ end
- it "doesn't paginate short selections" do
- prompt = TTY::TestPrompt.new
- choices = %w(A B C D)
- prompt.input << "\r"
- prompt.input.rewind
- value = prompt.multi_select("What letter?", choices, per_page: 4, default: 1)
- expect(value).to eq(['A'])
+ it "paginates choices as hash object" do
+ prompt = TTY::TestPrompt.new
+ choices = {A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7, H: 8}
+ prompt.input << "\r"
+ prompt.input.rewind
- expect(prompt.output.string).to eq([
- "\e[?25lWhat letter? A \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
- "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m A\n",
- " #{symbols[:radio_off]} B\n",
- " #{symbols[:radio_off]} C\n",
- " #{symbols[:radio_off]} D",
- "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
- "What letter? \e[32mA\e[0m\n\e[?25h",
- ].join)
+ answer = prompt.multi_select("What letter?", choices, default: 4, per_page: 3)
+
+ expect(answer).to eq([4])
+ expected_output = [
+ "\e[?25lWhat letter? D ",
+ "\e[90m(Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
+ " #{symbols[:radio_off]} E\n",
+ " #{symbols[:radio_off]} F",
+ "\e[2K\e[1G\e[1A" * 3, "\e[2K\e[1G",
+ "What letter? \e[32mD\e[0m\n\e[?25h",
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
+ end
+
+ it "paginates long selections through DSL" do
+ prompt = TTY::TestPrompt.new
+ choices = %w(A B C D E F G H)
+ prompt.input << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What letter?") do |menu|
+ menu.per_page 3
+ menu.default 4
+ menu.choices choices
+ end
+
+ expect(answer).to eq(['D'])
+ expected_output = [
+ "\e[?25lWhat letter? D ",
+ "\e[90m(Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
+ " #{symbols[:radio_off]} E\n",
+ " #{symbols[:radio_off]} F",
+ "\e[2K\e[1G\e[1A" * 3,
+ "\e[2K\e[1G",
+ "What letter? \e[32mD\e[0m\n\e[?25h",
+ ].join
+ expect(prompt.output.string).to eq(expected_output)
+ end
+
+ it "doesn't paginate short selections" do
+ prompt = TTY::TestPrompt.new
+ choices = %w(A B C D)
+ prompt.input << "\r"
+ prompt.input.rewind
+ value = prompt.multi_select("What letter?", choices, per_page: 4, default: 1)
+ expect(value).to eq(['A'])
+
+ expect(prompt.output.string).to eq([
+ "\e[?25lWhat letter? A ",
+ "\e[90m(Use #{up_down} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m A\n",
+ " #{symbols[:radio_off]} B\n",
+ " #{symbols[:radio_off]} C\n",
+ " #{symbols[:radio_off]} D",
+ "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
+ "What letter? \e[32mA\e[0m\n\e[?25h",
+ ].join)
+ end
+
+ it "navigates evenly paged output with right arrow until end of selection" do
+ prompt = TTY::TestPrompt.new
+ choices = ('1'..'12').to_a
+ prompt.on(:keypress) { |e| prompt.trigger(:keyright) if e.value == "l" }
+ prompt.input << "l" << "l" << "l" << " " << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What number?", choices, per_page: 4)
+
+ expect(answer).to eq(["9"])
+
+ expected_output = [
+ output_helper("What number?", choices[0..3], "1", [], init: true,
+ hint: "Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish"),
+ output_helper("What number?", choices[4..7], "5", []),
+ output_helper("What number?", choices[8..11], "9", []),
+ output_helper("What number?", choices[8..11], "9", []),
+ output_helper("What number?", choices[8..11], "9", ["9"]),
+ "What number? \e[32m9\e[0m\n\e[?25h",
+ ].join
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
+
+ it "navigates unevenly paged output with right arrow until the end of selection" do
+ prompt = TTY::TestPrompt.new
+ choices = ('1'..'10').to_a
+ prompt.on(:keypress) { |e| prompt.trigger(:keyright) if e.value == "l" }
+ prompt.input << "l" << "l" << "l" << " " << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What number?", choices, default: 4, per_page: 4)
+
+ expect(answer).to eq(['4', '10'])
+
+ expected_output = [
+ output_helper("What number?", choices[3..6], "4", ["4"], init: true,
+ hint: "Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish"),
+ output_helper("What number?", choices[4..7], "8", ["4"]),
+ output_helper("What number?", choices[8..9], "10", ["4"]),
+ output_helper("What number?", choices[8..9], "10", ["4"]),
+ output_helper("What number?", choices[8..9], "10", ["4", "10"]),
+ "What number? \e[32m4, 10\e[0m\n\e[?25h",
+ ].join
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
+
+ it "navigates left and right" do
+ prompt = TTY::TestPrompt.new
+ choices = ('1'..'10').to_a
+ prompt.on(:keypress) { |e|
+ prompt.trigger(:keyright) if e.value == "l"
+ prompt.trigger(:keyleft) if e.value == "h"
+ }
+ prompt.input << "l" << "l" << "h" << " " << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What number?", choices, default: 2, per_page: 4)
+
+ expect(answer).to eq(['2', '6'])
+
+ expected_output = [
+ output_helper("What number?", choices[0..3], "2", ["2"], init: true,
+ hint: "Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish"),
+ output_helper("What number?", choices[4..7], "6", ["2"]),
+ output_helper("What number?", choices[8..9], "10", ["2"]),
+ output_helper("What number?", choices[4..7], "6", ["2"]),
+ output_helper("What number?", choices[4..7], "6", ["2", "6"]),
+ "What number? \e[32m2, 6\e[0m\n\e[?25h",
+ ].join
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
+
+ it "combines up/down navigation with left/right" do
+ prompt = TTY::TestPrompt.new
+ choices = ('1'..'11').to_a
+ prompt.on(:keypress) { |e|
+ prompt.trigger(:keyup) if e.value == "k"
+ prompt.trigger(:keydown) if e.value == "j"
+ prompt.trigger(:keyright) if e.value == "l"
+ prompt.trigger(:keyleft) if e.value == "h"
+ }
+ prompt.input << "j" << "l" << "k" << "k" << "h" << " " << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What number?", choices, default: 2, per_page: 4)
+
+ expect(answer).to eq(['2', '1'])
+
+ expected_output = [
+ output_helper("What number?", choices[0..3], "2", ["2"], init: true,
+ hint: "Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish"),
+ output_helper("What number?", choices[0..3], "3", ["2"]),
+ output_helper("What number?", choices[4..7], "7", ["2"]),
+ output_helper("What number?", choices[4..7], "6", ["2"]),
+ output_helper("What number?", choices[3..6], "5", ["2"]),
+ output_helper("What number?", choices[0..3], "1", ["2"]),
+ output_helper("What number?", choices[0..3], "1", ["2", "1"]),
+ "What number? \e[32m2, 1\e[0m\n\e[?25h",
+ ].join
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
end
context "with :cycle" do
it "doesn't cycle by default" do
prompt = TTY::TestPrompt.new
@@ -368,11 +503,11 @@
value = prompt.multi_select("What letter?", choices)
expect(value).to eq(["C"])
expect(prompt.output.string).to eq(
output_helper("What letter?", choices, "A", [], init: true,
- hint: "Use arrow keys, press Space to select and Enter to finish") +
+ hint: "Use #{up_down} arrow keys, press Space to select and Enter to finish") +
output_helper("What letter?", choices, "B", []) +
output_helper("What letter?", choices, "C", []) +
output_helper("What letter?", choices, "C", []) +
output_helper("What letter?", choices, "C", ["C"]) +
"What letter? \e[32mC\e[0m\n\e[?25h"
@@ -383,22 +518,82 @@
prompt = TTY::TestPrompt.new
choices = %w(A B C)
prompt.on(:keypress) { |e| prompt.trigger(:keydown) if e.value == "j" }
prompt.input << "j" << "j" << "j" << " " << "\r"
prompt.input.rewind
+
value = prompt.multi_select("What letter?", choices, cycle: true)
+
expect(value).to eq(["A"])
expect(prompt.output.string).to eq(
output_helper("What letter?", choices, "A", [], init: true,
- hint: "Use arrow keys, press Space to select and Enter to finish") +
+ hint: "Use #{up_down} arrow keys, press Space to select and Enter to finish") +
output_helper("What letter?", choices, "B", []) +
output_helper("What letter?", choices, "C", []) +
output_helper("What letter?", choices, "A", []) +
output_helper("What letter?", choices, "A", ["A"]) +
"What letter? \e[32mA\e[0m\n\e[?25h"
)
end
+
+ it "cycles choices using left/right arrows" do
+ prompt = TTY::TestPrompt.new
+ choices = ('1'..'10').to_a
+ prompt.on(:keypress) { |e|
+ prompt.trigger(:keyright) if e.value == "l"
+ prompt.trigger(:keyleft) if e.value == "h"
+ }
+ prompt.input << "l" << "l" << "l" << "h" << " " << "\r"
+ prompt.input.rewind
+
+ answer = prompt.multi_select("What number?", choices, default: 2, per_page: 4, cycle: true)
+
+ expect(answer).to eq(['2', '10'])
+
+ expected_output = [
+ "\e[?25lWhat number? 2 ",
+ "\e[90m(Use #{up_down} and #{left_right} arrow keys, press Space to select and Enter to finish)\e[0m\n",
+ " #{symbols[:radio_off]} 1\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m 2\n",
+ " #{symbols[:radio_off]} 3\n",
+ " #{symbols[:radio_off]} 4",
+ "\e[2K\e[1G\e[1A" * 4,
+ "\e[2K\e[1G",
+ "What number? 2\n",
+ " #{symbols[:radio_off]} 5\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} 6\n",
+ " #{symbols[:radio_off]} 7\n",
+ " #{symbols[:radio_off]} 8",
+ "\e[2K\e[1G\e[1A" * 4,
+ "\e[2K\e[1G",
+ "What number? 2\n",
+ " #{symbols[:radio_off]} 9\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} 10",
+ "\e[2K\e[1G\e[1A" * 2,
+ "\e[2K\e[1G",
+ "What number? 2\n",
+ " #{symbols[:radio_off]} 1\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m 2\n",
+ " #{symbols[:radio_off]} 3\n",
+ " #{symbols[:radio_off]} 4",
+ "\e[2K\e[1G\e[1A" * 4,
+ "\e[2K\e[1G",
+ "What number? 2\n",
+ " #{symbols[:radio_off]} 9\n",
+ "#{symbols[:marker]} #{symbols[:radio_off]} 10",
+ "\e[2K\e[1G\e[1A" * 2,
+ "\e[2K\e[1G",
+ "What number? 2, 10\n",
+ " #{symbols[:radio_off]} 9\n",
+ "#{symbols[:marker]} \e[32m#{symbols[:radio_on]}\e[0m 10",
+ "\e[2K\e[1G\e[1A" * 2,
+ "\e[2K\e[1G",
+ "What number? \e[32m2, 10\e[0m\n\e[?25h",
+ ].join
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
end
context "with filter" do
it "doesn't lose the selection when switching between filters" do
prompt = TTY::TestPrompt.new
@@ -411,11 +606,12 @@
answer = prompt.multi_select("What size?", %w(Tiny Medium Large Huge), filter: true)
expect(answer).to eql(%w(Tiny Large))
expected_prompt_output =
- output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(), init: true, hint: "Use arrow keys, press Space to select and Enter to finish, and letter keys to filter") +
+ output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(), init: true,
+ hint: "Use #{up_down} arrow keys, press Space to select and Enter to finish, and letter keys to filter") +
output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(Tiny)) +
output_helper("What size?", %w(Large), "Large", %w(Tiny), hint: 'Filter: "a"') +
output_helper("What size?", %w(Large), "Large", %w(Tiny Large), hint: 'Filter: "a"') +
output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(Tiny Large)) +
exit_message("What size?", %w(Tiny Large))
@@ -465,11 +661,12 @@
answer = prompt.multi_select("What letter?", choices)
expect(answer).to eq(%w[D E])
expected_output =
- output_helper("What letter?", choices, "A", [], init: true, hint: "Use arrow keys, press Space to select and Enter to finish") +
+ output_helper("What letter?", choices, "A", [], init: true,
+ hint: "Use #{up_down} arrow keys, press Space to select and Enter to finish") +
output_helper("What letter?", choices, "D", []) +
output_helper("What letter?", choices, "D", %w[D]) +
output_helper("What letter?", choices, "E", %w[D]) +
output_helper("What letter?", choices, "E", %w[D E]) +
exit_message("What letter?", %w[D E])
@@ -498,13 +695,46 @@
menu.choice :bourbon, 5
end
expect(answer).to eq([1])
expected_output =
- output_helper("Select drinks?", choices, "vodka", [], init: true, enum: ') ', hint: "Use arrow or number (1-5) keys, press Space to select and Enter to finish") +
+ output_helper("Select drinks?", choices, "vodka", [], init: true, enum: ') ',
+ hint: "Use #{up_down} arrow or number (1-5) keys, press Space to select and Enter to finish") +
output_helper("Select drinks?", choices, "vodka", [], enum: ') ') +
output_helper("Select drinks?", choices, "vodka", %w[vodka], enum: ') ') +
exit_message("Select drinks?", %w[vodka])
+
+ expect(prompt.output.string).to eq(expected_output)
+ end
+ end
+
+ context "with :max" do
+ it "limits number of choices" do
+ prompt = TTY::TestPrompt.new
+ choices = %w(A B C)
+ prompt.on(:keypress) { |e|
+ prompt.trigger(:keyup) if e.value == "k"
+ prompt.trigger(:keydown) if e.value == "j"
+ }
+ prompt.input << " " << "j" << " " << "j" << " " << "k" << " " << "j" << " " << "\r"
+ prompt.input.rewind
+
+ value = prompt.multi_select("What letter?", choices, max: 2, per_page: 100)
+ expect(value).to eq(["A", "C"])
+
+ expected_output =
+ output_helper("What letter?", choices, "A", [], init: true, max: 2,
+ hint: "Use #{up_down} arrow keys, press Space to select and Enter to finish") +
+ output_helper("What letter?", choices, "A", %w[A], max: 2) +
+ output_helper("What letter?", choices, "B", %w[A], max: 2) +
+ output_helper("What letter?", choices, "B", %w[A B], max: 2) +
+ output_helper("What letter?", choices, "C", %w[A B], max: 2) +
+ output_helper("What letter?", choices, "C", %w[A B], max: 2) +
+ output_helper("What letter?", choices, "B", %w[A B], max: 2) +
+ output_helper("What letter?", choices, "B", %w[A], max: 2) +
+ output_helper("What letter?", choices, "C", %w[A], max: 2) +
+ output_helper("What letter?", choices, "C", %w[A C], max: 2) +
+ exit_message("What letter?", %w[A C])
expect(prompt.output.string).to eq(expected_output)
end
end
end