summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/knife/client_bulk_delete.rb2
-rw-r--r--lib/chef/knife/cookbook_bulk_delete.rb2
-rw-r--r--lib/chef/knife/core/ui.rb53
-rw-r--r--spec/unit/knife/client_bulk_delete_spec.rb4
-rw-r--r--spec/unit/knife/core/ui_spec.rb161
5 files changed, 142 insertions, 80 deletions
diff --git a/lib/chef/knife/client_bulk_delete.rb b/lib/chef/knife/client_bulk_delete.rb
index 1e1d6af190..f2be772759 100644
--- a/lib/chef/knife/client_bulk_delete.rb
+++ b/lib/chef/knife/client_bulk_delete.rb
@@ -71,7 +71,7 @@ class Chef
else
ui.msg("The following validators will be deleted:")
print_clients(validators)
- if ui.confirm("Are you sure you want to delete these validators", true, false)
+ if ui.confirm_without_exit("Are you sure you want to delete these validators")
destroy_clients(validators)
end
end
diff --git a/lib/chef/knife/cookbook_bulk_delete.rb b/lib/chef/knife/cookbook_bulk_delete.rb
index f8ad74d856..65fa888486 100644
--- a/lib/chef/knife/cookbook_bulk_delete.rb
+++ b/lib/chef/knife/cookbook_bulk_delete.rb
@@ -49,7 +49,7 @@ class Chef
ui.msg ""
unless config[:yes]
- ui.confirm("Do you really want to delete these cookbooks? (Y/N) ", false)
+ ui.confirm("Do you really want to delete these cookbooks")
if config[:purge]
ui.msg("Files that are common to multiple cookbooks are shared, so purging the files may break other cookbooks.")
diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb
index 5b86150fee..ff2545cfed 100644
--- a/lib/chef/knife/core/ui.rb
+++ b/lib/chef/knife/core/ui.rb
@@ -205,38 +205,61 @@ class Chef
output(format_for_display(object)) if config[:print_after]
end
- def confirm(question, append_instructions=true, default_choice=nil)
- return true if config[:yes]
-
+ def confirmation_instructions(default_choice)
case default_choice
- when 'Y', 'y'
- instructions = '? (Y/n)'
- when 'N', 'n'
- instructions = '? (y/N)'
+ when true
+ '? (Y/n)'
+ when false
+ '? (y/N)'
else
- instructions = '? (Y/N)'
+ '? (Y/N)'
end
+ end
+
+ # See confirm method for argument information
+ def confirm_without_exit(question, append_instructions=true, default_choice=nil)
+ return true if config[:yes]
stdout.print question
- stdout.print instructions if append_instructions
+ stdout.print confirmation_instructions(default_choice) if append_instructions
+
answer = stdin.readline
answer.chomp!
- answer == '' ? answer = default_choice : answer
+
case answer
when "Y", "y"
true
when "N", "n"
self.msg("You said no, so I'm done here.")
- if should_exit
- exit 3
+ false
+ when ""
+ unless default_choice.nil?
+ default_choice
else
- false
+ self.msg("I have no idea what to do with '#{answer}'")
+ self.msg("Just say Y or N, please.")
+ confirm_without_exit(question, append_instructions, default_choice)
end
else
- self.msg("I have no idea what to do with #{answer}")
+ self.msg("I have no idea what to do with '#{answer}'")
self.msg("Just say Y or N, please.")
- confirm(question)
+ confirm_without_exit(question, append_instructions, default_choice)
+ end
+ end
+
+ #
+ # Not the ideal signature for a function but we need to stick with this
+ # for now until we get a chance to break our API in Chef 12.
+ #
+ # question => Question to print before asking for confirmation
+ # append_instructions => Should print '? (Y/N)' as instructions
+ # default_choice => Set to true for 'Y', and false for 'N' as default answer
+ #
+ def confirm(question, append_instructions=true, default_choice=nil)
+ unless confirm_without_exit(question, append_instructions, default_choice)
+ exit 3
end
+ true
end
end
diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb
index f490851cbc..7df7d02e9b 100644
--- a/spec/unit/knife/client_bulk_delete_spec.rb
+++ b/spec/unit/knife/client_bulk_delete_spec.rb
@@ -28,6 +28,7 @@ describe Chef::Knife::ClientBulkDelete do
k.config = option_args
k.ui.stub(:stdout).and_return(stdout_io)
k.ui.stub(:confirm).and_return(knife_confirm)
+ k.ui.stub(:confirm_without_exit).and_return(knife_confirm)
k
}
@@ -132,7 +133,8 @@ describe Chef::Knife::ClientBulkDelete do
end
it "should confirm twice" do
- knife.ui.should_receive(:confirm).twice
+ knife.ui.should_receive(:confirm).once
+ knife.ui.should_receive(:confirm_without_exit).once
knife.run
end
diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb
index 74b3906067..9044bc2f2f 100644
--- a/spec/unit/knife/core/ui_spec.rb
+++ b/spec/unit/knife/core/ui_spec.rb
@@ -406,95 +406,132 @@ EOM
end
describe "confirm" do
- before(:each) do
- @question = "monkeys rule"
- @stdout = StringIO.new
- @ui.stub(:stdout).and_return(@stdout)
- @ui.stdin.stub(:readline).and_return("y")
+ let(:stdout) {StringIO.new}
+ let(:output) {stdout.string}
+
+ let(:question) { "monkeys rule" }
+ let(:answer) { 'y' }
+
+ let(:default_choice) { nil }
+ let(:append_instructions) { true }
+
+ def run_confirm
+ @ui.stub(:stdout).and_return(stdout)
+ @ui.stdin.stub(:readline).and_return(answer)
+ @ui.confirm(question, append_instructions, default_choice)
end
- it "should return true if you answer Y" do
- @ui.stdin.stub(:readline).and_return("Y")
- @ui.confirm(@question).should == true
+ def run_confirm_without_exit
+ @ui.stub(:stdout).and_return(stdout)
+ @ui.stdin.stub(:readline).and_return(answer)
+ @ui.confirm_without_exit(question, append_instructions, default_choice)
end
- it "should return true if you answer y" do
- @ui.stdin.stub(:readline).and_return("y")
- @ui.confirm(@question).should == true
+ shared_examples_for "confirm with positive answer" do
+ it "confirm should return true" do
+ run_confirm.should be_true
+ end
+
+ it "confirm_without_exit should return true" do
+ run_confirm_without_exit.should be_true
+ end
end
- it "should exit 3 if you answer N" do
- @ui.stdin.stub(:readline).and_return("N")
- lambda {
- @ui.confirm(@question)
- }.should raise_error(SystemExit) { |e| e.status.should == 3 }
+ shared_examples_for "confirm with negative answer" do
+ it "confirm should exit 3" do
+ lambda {
+ run_confirm
+ }.should raise_error(SystemExit) { |e| e.status.should == 3 }
+ end
+
+ it "confirm_without_exit should return false" do
+ run_confirm_without_exit.should be_false
+ end
end
- it "should exit 3 if you answer n" do
- @ui.stdin.stub(:readline).and_return("n")
- lambda {
- @ui.confirm(@question)
- }.should raise_error(SystemExit) { |e| e.status.should == 3 }
+ describe "with default choice set to true" do
+ let(:default_choice) { true }
+
+ it "should show 'Y/n' in the instructions" do
+ run_confirm
+ output.should include("Y/n")
+ end
+
+ describe "with empty answer" do
+ let(:answer) { "" }
+
+ it_behaves_like "confirm with positive answer"
+ end
+
+ describe "with answer N " do
+ let(:answer) { "N" }
+
+ it_behaves_like "confirm with negative answer"
+ end
end
- describe "with 'Y' as a default choice" do
- it 'should return true if you answer default' do
- @ui.stdin.stub(:readline).and_return("\n")
- @ui.confirm(@question, false, 'Y').should == true
+ describe "with default choice set to false" do
+ let(:default_choice) { false }
+
+ it "should show 'y/N' in the instructions" do
+ run_confirm
+ output.should include("y/N")
+ end
+
+ describe "with empty answer" do
+ let(:answer) { "" }
+
+ it_behaves_like "confirm with negative answer"
end
- it "should show 'Y' as the default in the instructions" do
- out = StringIO.new
- @ui.stdin.stub(:readline).and_return("\n")
- @ui.stub(:stdout).and_return(out)
- @ui.confirm(@question, true, 'Y').should == true
- out.string.should == "#{@question}? (Y/n)"
+ describe "with answer N " do
+ let(:answer) { "Y" }
+
+ it_behaves_like "confirm with positive answer"
end
end
- describe "with 'N' as a default choice" do
- it 'should exit 3 if you answer default' do
- @ui.stdin.stub(:readline).and_return("\n")
- lambda {
- @ui.confirm(@question, false, 'N')
- }.should raise_error(SystemExit) { |e| e.status.should == 3 }
+ ["Y", "y"].each do |answer|
+ describe "with answer #{answer}" do
+ let(:answer) { answer }
+
+ it_behaves_like "confirm with positive answer"
end
+ end
- it "should show 'N' as the default in the instructions" do
- out = StringIO.new
- @ui.stdin.stub(:readline).and_return("\n")
- @ui.stub(:stdout).and_return(out)
- lambda {
- @ui.confirm(@question, true, 'N')
- }.should raise_error(SystemExit) { |e| e.status.should == 3 }
- out.string.should == "#{@question}? (y/N)You said no, so I'm done here.\n"
+ ["N", "n"].each do |answer|
+ describe "with answer #{answer}" do
+ let(:answer) { answer }
+
+ it_behaves_like "confirm with negative answer"
end
end
describe "with --y or --yes passed" do
it "should return true" do
@ui.config[:yes] = true
- @ui.confirm(@question).should == true
+ run_confirm.should be_true
+ output.should eq("")
end
end
+ end
- describe "when asking for free-form user input" do
- it "asks a question and returns the answer provided by the user" do
- out = StringIO.new
- @ui.stub(:stdout).and_return(out)
- @ui.stub(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
- @ui.ask_question("your chef server URL?").should == "http://mychefserver.example.com"
- out.string.should == "your chef server URL?"
- end
-
- it "suggests a default setting and returns the default when the user's response only contains whitespace" do
- out = StringIO.new
- @ui.stub(:stdout).and_return(out)
- @ui.stub(:stdin).and_return(StringIO.new(" \n"))
- @ui.ask_question("your chef server URL? ", :default => 'http://localhost:4000').should == "http://localhost:4000"
- out.string.should == "your chef server URL? [http://localhost:4000] "
- end
+ describe "when asking for free-form user input" do
+ it "asks a question and returns the answer provided by the user" do
+ out = StringIO.new
+ @ui.stub(:stdout).and_return(out)
+ @ui.stub(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
+ @ui.ask_question("your chef server URL?").should == "http://mychefserver.example.com"
+ out.string.should == "your chef server URL?"
end
+ it "suggests a default setting and returns the default when the user's response only contains whitespace" do
+ out = StringIO.new
+ @ui.stub(:stdout).and_return(out)
+ @ui.stub(:stdin).and_return(StringIO.new(" \n"))
+ @ui.ask_question("your chef server URL? ", :default => 'http://localhost:4000').should == "http://localhost:4000"
+ out.string.should == "your chef server URL? [http://localhost:4000] "
+ end
end
+
end