Skip to content

Instantly share code, notes, and snippets.

@DanielVartanov
Created May 13, 2020 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielVartanov/2dd8f776ad019064213e51763b2e7256 to your computer and use it in GitHub Desktop.
Save DanielVartanov/2dd8f776ad019064213e51763b2e7256 to your computer and use it in GitHub Desktop.
let(:app) do
CLIWrapper.new do |stdin, stdout|
prompt = TTY::Prompt.new(input: stdin, output: stdout)
prompt.yes?('Do you like Ruby?')
prompt.collect do
key(:name).ask('Name?')
key(:age).ask('Age?', convert: :int)
end
prompt.select("Choose your destiny?", %w(Scorpion Kano Jax))
# ...
end
end
before { app.run! }
it 'asks a series of questions' do
expect(app.stdout.string).to end_with('Do you like Ruby? (Y/n) ')
app.stdin.puts 'y'
app.resume_execution!
expect(app.stdout.string).to end_with('Name? ')
app.stdin.puts 'John'
app.resume_execution!
expect(app.stdout.string).to end_with('Age? ')
app.stdin.puts '22'
app.resume_execution!
expect(app.stdout.string).to end_with(
"Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select)
‣ Scorpion
Kano
Jax")
app.stdin.puts "\e[B\e[B" # arrow down twice
app.resume_execution!
# ...
end
class CLIWrapper
def initialize(&block)
@stdout = StringIO.new
@stdin_reader, @stdin_writer = IO.pipe
@fiber = Fiber.new do
block.call(@stdin_reader, @stdout)
end
@stdin_reader.singleton_class.define_method(:getc) do
char = read_nonblock(1, exception: false)
if char.is_a?(String)
char
else
Fiber.yield
getc
end
end
end
def resume_execution!
@fiber.resume
end
alias run! resume_execution!
def stdin
@stdin_writer
end
def stdout
@stdout
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment