Implement `ask' recipe keyword
This commit is contained in:
parent
70109615c8
commit
7e062e06a1
22
features/recipes/ask.feature
Normal file
22
features/recipes/ask.feature
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Feature: `ask' recipe keyword
|
||||||
|
|
||||||
|
Scenario: prompts user with a list of choices on standard output
|
||||||
|
Given a recipe with:
|
||||||
|
"""
|
||||||
|
task :ask_letter do
|
||||||
|
letter = ask 'Which letter?', %w[A B]
|
||||||
|
|
||||||
|
echo letter
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
When I execute the recipe interactively
|
||||||
|
And I type "1"
|
||||||
|
Then the output must contain:
|
||||||
|
"""
|
||||||
|
Which letter?
|
||||||
|
0: A
|
||||||
|
1: B
|
||||||
|
Choice:
|
||||||
|
B
|
||||||
|
"""
|
||||||
|
And the exit status must be 0
|
@ -10,3 +10,7 @@ When(/^I successfully execute the recipe$/) do
|
|||||||
step 'I execute the recipe'
|
step 'I execute the recipe'
|
||||||
assert_exit_status(0)
|
assert_exit_status(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
When(/^I execute the recipe interactively$/) do
|
||||||
|
run_interactive('producer recipe.rb')
|
||||||
|
end
|
||||||
|
@ -14,6 +14,7 @@ require 'producer/core/condition'
|
|||||||
require 'producer/core/condition/dsl'
|
require 'producer/core/condition/dsl'
|
||||||
require 'producer/core/env'
|
require 'producer/core/env'
|
||||||
require 'producer/core/errors'
|
require 'producer/core/errors'
|
||||||
|
require 'producer/core/prompter'
|
||||||
require 'producer/core/recipe'
|
require 'producer/core/recipe'
|
||||||
require 'producer/core/recipe/dsl'
|
require 'producer/core/recipe/dsl'
|
||||||
require 'producer/core/remote'
|
require 'producer/core/remote'
|
||||||
|
21
lib/producer/core/prompter.rb
Normal file
21
lib/producer/core/prompter.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
module Producer
|
||||||
|
module Core
|
||||||
|
class Prompter
|
||||||
|
attr_reader :input, :output
|
||||||
|
|
||||||
|
def initialize(input, output)
|
||||||
|
@input = input
|
||||||
|
@output = output
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt(question, choices)
|
||||||
|
cs = choices.each_with_index.inject('') do |m, (c, i)|
|
||||||
|
m += "#{i}: #{c}\n"
|
||||||
|
end
|
||||||
|
output.puts "#{question}\n#{cs}Choice:"
|
||||||
|
choice = input.gets
|
||||||
|
choices[choice.to_i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -32,6 +32,10 @@ module Producer
|
|||||||
@condition = Condition.evaluate(@env, &block) if block
|
@condition = Condition.evaluate(@env, &block) if block
|
||||||
@condition
|
@condition
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ask(question, choices, prompter: Prompter)
|
||||||
|
prompter.new(env.input, env.output).prompt(question, choices)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
41
spec/producer/core/prompter_spec.rb
Normal file
41
spec/producer/core/prompter_spec.rb
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
module Producer::Core
|
||||||
|
describe Prompter do
|
||||||
|
let(:input) { StringIO.new }
|
||||||
|
let(:output) { StringIO.new }
|
||||||
|
let(:env) { Env.new(input: input, output: output) }
|
||||||
|
subject(:prompter) { Prompter.new(input, output) }
|
||||||
|
|
||||||
|
describe '#initialize' do
|
||||||
|
it 'assigns the given input' do
|
||||||
|
expect(prompter.input).to be input
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'assigns the given output' do
|
||||||
|
expect(prompter.output).to be output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#prompt' do
|
||||||
|
let(:question) { 'Which letter?' }
|
||||||
|
let(:choices) { %w[A B] }
|
||||||
|
|
||||||
|
it 'prompts choices' do
|
||||||
|
prompter.prompt question, choices
|
||||||
|
expect(output.string).to eq <<-eoh.gsub /^\s+\|/, ''
|
||||||
|
|#{question}
|
||||||
|
|0: A
|
||||||
|
|1: B
|
||||||
|
|Choice:
|
||||||
|
eoh
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns value for entry chosen by user' do
|
||||||
|
input.puts '1'
|
||||||
|
input.rewind
|
||||||
|
expect(prompter.prompt question, choices).to eq 'B'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||||||
module Producer::Core
|
module Producer::Core
|
||||||
describe Task::DSL do
|
describe Task::DSL do
|
||||||
let(:block) { proc {} }
|
let(:block) { proc {} }
|
||||||
let(:env) { double 'env' }
|
let(:env) { Env.new }
|
||||||
subject(:dsl) { Task::DSL.new(env, &block) }
|
subject(:dsl) { Task::DSL.new(env, &block) }
|
||||||
|
|
||||||
%w[echo sh file_write].each do |action|
|
%w[echo sh file_write].each do |action|
|
||||||
@ -82,5 +82,25 @@ module Producer::Core
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#ask' do
|
||||||
|
let(:question) { 'Which letter?' }
|
||||||
|
let(:choices) { %w[A B] }
|
||||||
|
let(:prompter_class) { double('prompter class').as_null_object }
|
||||||
|
subject(:ask) { dsl.ask question, choices,
|
||||||
|
prompter: prompter_class }
|
||||||
|
|
||||||
|
it 'builds a prompter' do
|
||||||
|
expect(prompter_class).to receive(:new).with(env.input, env.output)
|
||||||
|
ask
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prompts and returns the choice' do
|
||||||
|
prompter = double 'prompter'
|
||||||
|
allow(prompter_class).to receive(:new) { prompter }
|
||||||
|
allow(prompter).to receive(:prompt) { :choice }
|
||||||
|
expect(ask).to eq :choice
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user