6 describe Application do
8 Application.intialize_application_options
9 @argv_backup = ARGV.clone
12 describe "#application_options" do
13 it "should return the application options" do
14 Application.application_options.should == {:description => nil,
17 :exclude_arg_sections => []}
22 it "should set the application option" do
23 Application["foo"] = "bar"
24 Application.application_options["foo"].should == "bar"
29 it "should set the application option" do
30 Application[:cli_arguments].should == []
34 describe "#intialize_application_options" do
35 it "should initialize application options correctly" do
36 Application.intialize_application_options.should == {:description => nil,
39 :exclude_arg_sections => []}
43 describe "#description" do
44 it "should set the description correctly" do
45 Application.description "meh"
46 Application[:description].should == "meh"
51 it "should set the usage correctly" do
52 Application.usage "meh"
53 Application.usage "foo"
55 Application[:usage].should == ["meh", "foo"]
59 describe "#exclude_argument_sections" do
60 it "should set the excluded sections correctly" do
61 Application.exclude_argument_sections "common", "rpc", "filter"
62 Application[:exclude_arg_sections].should == ["common", "rpc", "filter"]
63 Application.exclude_argument_sections ["common", "rpc", "filter"]
64 Application[:exclude_arg_sections].should == ["common", "rpc", "filter"]
67 it "should detect unknown sections" do
68 expect { Application.exclude_argument_sections "rspec" }.to raise_error("Unknown CLI argument section rspec")
73 it "should add an option correctly" do
74 Application.option :test,
75 :description => "description",
76 :arguments => "--config CONFIG",
80 args = Application[:cli_arguments].first
81 args.delete(:validate)
83 args.should == {:name=>:test,
84 :arguments=>"--config CONFIG",
87 :description=>"description"}
90 it "should set correct defaults" do
91 Application.option :test, {}
93 args = Application[:cli_arguments].first
94 args.delete(:validate)
96 args.should == {:name=>:test,
104 describe "#validate_option" do
105 it "should pass validations" do
107 a.validate_option(Proc.new {|v| v == 1}, "key", 1)
110 it "should print an error to STDERR on error" do
111 IO.any_instance.expects(:puts).with("Validation of key failed: failed").at_least_once
112 Application.any_instance.stubs("exit").returns(true)
115 a.validate_option(Proc.new {|v| "failed"}, "key", 1)
118 it "should exit on valdation error" do
119 IO.any_instance.expects(:puts).at_least_once
120 Application.any_instance.stubs("exit").returns(true)
123 a.validate_option(Proc.new {|v| "failed"}, "key", 1)
127 describe "#application_parse_options" do
128 it "should pass the requested help value to the clioptions method" do
131 app = Application.new
132 app.expects(:clioptions).with(true)
133 app.application_parse_options(true)
136 @argv_backup.each{|a| ARGV << a}
139 it "should support creating arrays of values" do
140 Application.any_instance.stubs("main").returns(true)
142 Application.option :foo,
143 :description => "meh",
144 :arguments => "--foo [FOO]",
148 ARGV << "--foo=bar" << "--foo=baz"
152 a.configuration.should == {:foo=>["bar", "baz"]}
155 @argv_backup.each{|a| ARGV << a}
158 it "should support boolean options" do
159 Application.any_instance.stubs("main").returns(true)
161 Application.option :foo,
162 :description => "meh",
163 :arguments => "--foo",
171 a.configuration.should == {:foo=>true}
174 @argv_backup.each{|a| ARGV << a}
177 it "should support unsetting boolean options" do
178 Application.any_instance.stubs("main").returns(true)
180 Application.option :foo,
181 :description => "meh",
182 :arguments => "--[no-]foo",
190 a.configuration.should == {:foo=>false}
193 @argv_backup.each{|a| ARGV << a}
196 it "should set the application description as head" do
197 OptionParser.any_instance.stubs(:define_head).with("meh")
201 Application.description "meh"
202 Application.new.application_parse_options
205 @argv_backup.each{|a| ARGV << a}
208 it "should set the application usage as a banner" do
209 OptionParser.any_instance.stubs(:banner).with("meh")
213 Application.usage "meh"
214 Application.new.application_parse_options
217 @argv_backup.each{|a| ARGV << a}
220 it "should support validation" do
221 IO.any_instance.expects(:puts).with("Validation of foo failed: failed").at_least_once
222 Application.any_instance.stubs("exit").returns(true)
223 Application.any_instance.stubs("main").returns(true)
225 Application.option :foo,
226 :description => "meh",
229 :arguments => "--foo [FOO]",
230 :validate => Proc.new {|v| "failed"}
239 @argv_backup.each{|a| ARGV << a}
242 it "should support default values" do
243 Application.any_instance.stubs("main").returns(true)
245 Application.option :foo,
246 :description => "meh",
249 :arguments => "--foo [FOO]"
253 a.configuration.should == {:foo => "meh"}
256 it "should enforce required options" do
257 Application.any_instance.stubs("exit").returns(true)
258 Application.any_instance.stubs("main").returns(true)
259 OptionParser.any_instance.stubs("parse!").returns(true)
260 IO.any_instance.expects(:puts).with(anything).at_least_once
261 IO.any_instance.expects(:puts).with("The foo option is mandatory").at_least_once
266 Application.option :foo,
267 :description => "meh",
269 :arguments => "--foo [FOO]"
274 @argv_backup.each{|a| ARGV << a}
277 it "should call post_option_parser" do
278 OptionParser.any_instance.stubs("parse!").returns(true)
279 Application.any_instance.stubs("post_option_parser").returns(true).at_least_once
280 Application.any_instance.stubs("main").returns(true)
285 Application.option :foo,
286 :description => "meh",
287 :arguments => "--foo [FOO]"
292 @argv_backup.each{|a| ARGV << a}
295 it "should create an application option" do
296 OptionParser.any_instance.stubs("parse!").returns(true)
297 OptionParser.any_instance.expects(:on).with(anything, anything, anything, anything).at_least_once
298 OptionParser.any_instance.expects(:on).with('--foo [FOO]', String, 'meh').at_least_once
299 Application.any_instance.stubs("main").returns(true)
304 Application.option :foo,
305 :description => "meh",
306 :arguments => "--foo [FOO]"
311 @argv_backup.each{|a| ARGV << a}
315 describe "#initialize" do
316 it "should parse the command line options at application run" do
317 Application.any_instance.expects("application_parse_options").once
318 Application.any_instance.stubs("main").returns(true)
324 describe "#application_options" do
325 it "sshould return the application options" do
326 Application.new.application_options.should == Application.application_options
330 describe "#application_description" do
331 it "should provide the right description" do
332 Application.description "Foo"
333 Application.new.application_description.should == "Foo"
337 describe "#application_usage" do
338 it "should provide the right usage" do
339 Application.usage "Foo"
340 Application.new.application_usage.should == ["Foo"]
344 describe "#application_cli_arguments" do
345 it "should provide the right usage" do
346 Application.option :foo,
347 :description => "meh",
348 :arguments => "--foo [FOO]"
350 args = Application.new.application_cli_arguments.first
352 # need to remove this cos we cant validate procs for equality afaik
353 args.delete(:validate)
355 args.should == {:description=>"meh",
357 :arguments=>"--foo [FOO]",
364 it "should generate help using the full user supplied options" do
365 app = Application.new
366 app.expects(:clioptions).with(true).once
372 it "should detect applications without a #main" do
373 IO.any_instance.expects(:puts).with("Applications need to supply a 'main' method")
377 }.to raise_error(SystemExit)
380 it "should raise SystemExit exceptions for exit events" do
382 connector.expects(:disconnect)
383 PluginManager.expects("[]").with("connector_plugin").returns(connector)
386 a.expects(:main).raises(SystemExit)
390 }.to raise_error(SystemExit)
394 describe "#configuration" do
395 it "should return the correct configuration" do
396 Application.any_instance.stubs("main").returns(true)
401 Application.option :foo,
402 :description => "meh",
403 :arguments => "--foo [FOO]"
408 a.configuration.should == {:foo => "bar"}
411 @argv_backup.each{|a| ARGV << a}
417 @stats = {:discoverytime => 0, :discovered => 0, :failcount => 0, :responses => 0, :okcount => 0}
420 it "should exit with code 0 if discovery was done and all responses passed" do
421 app = Application.new
423 @stats[:discoverytime] = 2
424 @stats[:discovered] = 2
425 @stats[:responses] = 2
428 app.halt_code(@stats).should == 0
431 it "should exit with code 0 if no discovery were done but responses were received" do
432 app = Application.new
434 @stats[:responses] = 1
436 @stats[:discovered] = 1
438 app.halt_code(@stats).should == 0
441 it "should exit with code 1 if discovery info is missing" do
442 app = Application.new
444 app.halt_code({}).should == 1
447 it "should exit with code 1 if no nodes were discovered and discovery was done" do
448 app = Application.new
450 @stats[:discoverytime] = 2
452 app.halt_code(@stats).should == 1
455 it "should exit with code 2 if a request failed for some nodes" do
456 app = Application.new
458 @stats[:discovered] = 2
459 @stats[:failcount] = 1
460 @stats[:discoverytime] = 2
461 @stats[:responses] = 2
463 app.halt_code(@stats).should == 2
466 it "should exit with code 2 when no discovery were done and there were failure results" do
467 app = Application.new
469 @stats[:discovered] = 1
470 @stats[:failcount] = 1
471 @stats[:discoverytime] = 0
472 @stats[:responses] = 1
474 app.halt_code(@stats).should == 2
477 it "should exit with code 3 if no responses were received after discovery" do
478 app = Application.new
480 @stats[:discovered] = 1
481 @stats[:discoverytime] = 2
483 app.halt_code(@stats).should == 3
486 it "should exit with code 4 if no discovery was done and no responses were received" do
487 app = Application.new
489 app.halt_code(@stats).should == 4
493 describe "#disconnect" do
494 it "should disconnect from the connector plugin" do
496 connector.expects(:disconnect)
497 PluginManager.expects("[]").with("connector_plugin").returns(connector)
499 Application.new.disconnect
503 describe "#clioptions" do
504 it "should pass the excluded argument section" do
506 oparser.stubs(:parse)
508 Application.exclude_argument_sections "rpc"
510 Optionparser.expects(:new).with({:verbose => false, :progress_bar => true}, "filter", ["rpc"]).returns(oparser)
512 Application.new.clioptions(false)
515 it "should add the RPC options" do
517 oparser.stubs(:parse).yields(oparser, {})
518 oparser.stubs(:banner=)
519 oparser.stubs(:define_tail)
521 Optionparser.stubs(:new).with({:verbose => false, :progress_bar => true}, "filter", []).returns(oparser)
522 RPC::Helpers.expects(:add_simplerpc_options).with(oparser, {})
524 Application.new.clioptions(false)
527 it "should support bypassing the RPC options" do
529 oparser.stubs(:parse).yields(oparser, {})
530 oparser.stubs(:banner=)
531 oparser.stubs(:define_tail)
533 Application.exclude_argument_sections "rpc"
535 Optionparser.stubs(:new).with({:verbose => false, :progress_bar => true}, "filter", ["rpc"]).returns(oparser)
536 RPC::Helpers.expects(:add_simplerpc_options).never
538 Application.new.clioptions(false)
541 it "should return the help text if requested" do
543 parser.expects(:help)
546 oparser.stubs(:parse).yields(oparser, {})
547 oparser.stubs(:banner=)
548 oparser.stubs(:define_tail)
549 oparser.expects(:parser).returns(parser)
551 Optionparser.stubs(:new).with({:verbose => false, :progress_bar => true}, "filter", []).returns(oparser)
552 RPC::Helpers.expects(:add_simplerpc_options).with(oparser, {})
554 Application.new.clioptions(true)
558 describe "#application_failure" do
560 @app = Application.new
563 it "on SystemExit it should disconnect and exit without backtraces or error messages" do
564 @app.expects(:disconnect)
565 expect { @app.application_failure(SystemExit.new) }.to raise_error(SystemExit)
568 it "should print a single line error message" do
570 @app.stubs(:disconnect)
571 @app.stubs(:exit).with(1)
572 @app.stubs(:options).returns({})
574 Config.instance.stubs(:color).returns(false)
576 e.stubs(:backtrace).returns([])
577 e.stubs(:to_s).returns("rspec")
579 out.expects(:puts).with(regexp_matches(/rspec application failed to run/))
581 @app.application_failure(e, out)
584 it "should print a backtrace if options are unset or verbose is enabled" do
586 @app.stubs(:disconnect)
587 @app.stubs(:exit).with(1)
588 @app.stubs(:options).returns(nil)
590 Config.instance.stubs(:color).returns(false)
592 e.stubs(:backtrace).returns(["rspec"])
593 e.stubs(:to_s).returns("rspec")
595 @app.expects(:options).returns({:verbose => true}).times(3)
596 out.expects(:puts).with(regexp_matches(/ application failed to run/))
597 out.expects(:puts).with(regexp_matches(/from rspec <---/))
598 out.expects(:puts).with(regexp_matches(/rspec.+Mocha::Mock/))
600 @app.application_failure(e, out)
606 @app = Application.new
609 it "should parse the application options, run main and disconnect" do
610 @app.expects(:application_parse_options)
612 @app.expects(:disconnect)
617 it "should allow the application plugin to validate configuration variables" do
618 @app.expects("respond_to?").with(:validate_configuration).returns(true)
619 @app.expects(:validate_configuration).once
621 @app.stubs(:application_parse_options)
623 @app.stubs(:disconnect)
628 it "should start the sleeper thread on windows" do
629 Util.expects("windows?").returns(true)
630 Util.expects(:setup_windows_sleeper).once
632 @app.stubs(:application_parse_options)
634 @app.stubs(:disconnect)
639 it "should catch handle exit() correctly" do
640 @app.expects(:main).raises(SystemExit)
641 @app.expects(:disconnect).once
643 expect { @app.run }.to raise_error(SystemExit)
646 it "should catch all exceptions and process them correctly" do
647 @app.expects(:main).raises("rspec")
648 @app.expects(:application_failure).once