Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactoring of cli and command_line_parser classes

  • Loading branch information...
commit 9dd94182dfa0c35db294abb2bb237cbc433c2cb7 1 parent df0d76f
@thbishop authored
View
153 lib/fission/cli.rb
@@ -10,16 +10,12 @@ class CLI
# Fission::CLI.new
#
# Returns a Fission::CLI object.
- def initialize(args=ARGV)
- @args = args
+ def initialize(args=ARGV, parser=CommandLineParser)
+ @args = args ||= ARGV
- setup_options_parser
+ @parser = parser.new @args
- gather_commands_and_summaries
-
- parse_options
-
- determine_command_to_execute
+ parse_arguments
end
# Internal: Execute the determined command.
@@ -34,147 +30,16 @@ def execute
end
private
- # Internal: Determines the command that has been provided. If it is
- # determined that an invalid command is provided, then the help/usage will
- # be displayed and it will exit.
+ # Internal: Parses the arguments using the parser.
#
# Examples:
#
- # @cli.determine_command_to_execute
- #
- # Returns nothing. This will set the @cmd instance variable to an instance
- # of the appropriate command class (assuming it is valid).
- def determine_command_to_execute
- if @commands.include? @args.first
- @cmd = Command.const_get(@args.first.capitalize).new @args.drop 1
- elsif is_snapshot_command?
- klass = @args.take(2).map {|c| c.capitalize}.join('')
- @cmd = Command.const_get(klass).new @args.drop 2
- else
- show_all_help
- exit 1
- end
- end
-
- # Internal: Sets up the base option parser.
- #
- # Examples:
- #
- # @cli.setup_option_parser
- #
- # Returns nothing. This will set the @option_parser instance variable.
- def setup_options_parser
- @options_parser = OptionParser.new do |opts|
- opts.banner = "\nUsage: fission [options] COMMAND [arguments]"
-
- opts.on_head('-v', '--version', 'Output the version of fission') do
- ui.output VERSION
- exit 0
- end
-
- opts.on_head('-h', '--help', 'Displays this message') do
- show_all_help
- exit 0
- end
- end
- end
-
- # Internal: Parse the options.
- #
- # Examples:
- #
- # @cli.parse_options
- #
- # Returns nothing. This will display an error, the help/usage, and exit if
- # there are any invalid options found.
- def parse_options
- @options_parser.order! @args
- rescue OptionParser::InvalidOption => e
- ui.output e
- show_all_help
- exit 1
- end
-
- # Internal: Determines if the provided command is a snapshot related
- # command. This will use the @args instance variable to make the
- # determination.
- #
- # Examples
- #
- # @cli.is_snapshot_command? ['foo', 'bar']
- # # => false
- #
- # @cli.is_snapshot_command? ['snapshot', 'list']
- # # => true
- #
- # Returns a Boolean of whether a snapshot command was given or not.
- def is_snapshot_command?
- @args.first == 'snapshot' &&
- @args.count > 1 &&
- @commands.include?(@args.take(2).join(' '))
- end
-
- # Internal: Provides the help of all of the known commands.
- #
- # Examples
- #
- # @cli.commands_help
- #
- # Outputs the summary text for all known commands.
- def commands_help
- longest_cmd = @commands.inject do |longest, cmd_name|
- longest.length > cmd_name.length ? longest : cmd_name
- end
-
- ui.output "\nCommands:"
-
- @command_names_and_summaries.each_pair do |name, summary|
- ui.output_printf "%-#{longest_cmd.length}s %s\n", name, summary
- end
- end
-
- # Internal: Determines all of the available commands and their summaries.
- #
- # Examples
- #
- # @cli.command_names_and_summaries
- # # => { 'clone' => 'Clones a VM', 'stop' => 'Stops a VM' }
- #
- # Returns nothing. This will set the @command_names_and_summaries instance
- # variable with the result.
- def gather_commands_and_summaries
- @command_names_and_summaries = Command.descendants.inject({}) do |result, klass|
- cmd = klass.new
- result[cmd.command_name] = cmd.summary
- result
- end
-
- @commands = @command_names_and_summaries.keys.sort
- end
-
- # Internal: Outputs the usage as well as the known commands and their
- # summaries.
- #
- # Examples
- #
- # @cli.show_all_help
- # # => 'fission options command arguments ....'
+ # @cli.parse_arguments
#
# Returns nothing.
- def show_all_help
- ui.output @options_parser
- commands_help
- end
-
- # Internal: Helper method for outputting text to the ui
- #
- # Examples
- #
- # @cli.ui.output 'foo'
- #
- # Returns a UI instance.
- def ui
- @ui ||= UI.new
+ def parse_arguments
+ @parser.parse
+ @cmd = @parser.command
end
end
View
24 lib/fission/command_line_parser.rb
@@ -23,7 +23,9 @@ def initialize(args=ARGV)
end
# Internal: Parses the command line arguments. If the arguments are
- # invalid, the appropriate help will be output and then will exit.
+ # invalid, the appropriate help will be output and then will exit. If the
+ # arguments are valid, then the @command variable will be set to a new
+ # instance of the determined command class.
#
# Examples:
#
@@ -34,12 +36,26 @@ def parse
@options_parser.order! @args
determine_command_provided
+ self
rescue OptionParser::InvalidOption => e
ui.output e
show_all_help
exit 1
end
+ # Internal: Accessor for an instance of the determined command. This is set
+ # by running the parse method.
+ #
+ # Examples:
+ #
+ # @command_line_parser.command
+ #
+ # Returns an instance of the determined command if the arguments are valid.
+ # Returns nil if the parse command has not yet been run.
+ def command
+ @command
+ end
+
private
# Internal: Sets up the base option parser.
#
@@ -110,14 +126,14 @@ def gather_commands_and_summaries
#
# @cli.determine_command_to_execute
#
- # Returns nothing. This will set the @cmd instance variable to an instance
+ # Returns nothing. This will set the @command instance variable to an instance
# of the appropriate command class (assuming it is valid).
def determine_command_provided
if @commands.include? @args.first
- @cmd = Command.const_get(@args.first.capitalize).new @args.drop 1
+ @command = Command.const_get(@args.first.capitalize).new @args.drop 1
elsif is_snapshot_command?
klass = @args.take(2).map {|c| c.capitalize}.join('')
- @cmd = Command.const_get(klass).new @args.drop 2
+ @command = Command.const_get(klass).new @args.drop 2
else
show_all_help
exit 1
View
222 spec/fission/cli_spec.rb
@@ -4,211 +4,47 @@
before do
@string_io = StringIO.new
Fission::CLI.any_instance.stub(:ui).and_return(Fission::UI.new(@string_io))
+ @parser = mock 'parser'
+ @parser.stub :parse
+ @parser.stub :command
end
describe 'initialize' do
- describe 'with no arguments' do
- it 'should output the usage info' do
- lambda { Fission::CLI.new }.should raise_error SystemExit
- @string_io.string.should match /Usage/
- end
- end
-
- describe 'with -v or --version arguments' do
- ['-v', '--version'].each do |arg|
- it "should output the version with #{arg}" do
- lambda { Fission::CLI.new [arg] }.should raise_error SystemExit
+ it 'should create a parse object using ARGV' do
+ Fission::CommandLineParser.should_receive(:new).with(ARGV).
+ and_return(@parser)
- @string_io.string.should match /#{Fission::VERSION}/
- end
- end
+ Fission::CLI.new
end
- describe '-h or --help argument' do
- ['-h', '--help'].each do |arg|
- it "should output the usage info with #{arg}" do
- lambda { Fission::CLI.new [arg] }.should raise_error SystemExit
-
- @string_io.string.should match /Usage/
- end
- end
- end
+ it 'should create a parse object with the provided args' do
+ Fission::CommandLineParser.should_receive(:new).with(['foo']).
+ and_return(@parser)
- describe 'with an invalid sub command' do
- it 'should display the help' do
- lambda {
- Fission::CLI.new(['foo', 'bar']).execute
- }.should raise_error SystemExit
+ Fission::CLI.new ['foo']
- @string_io.string.should match /Usage/
- end
end
- describe 'with a valid sub command' do
- before do
- @cmd_mock = mock('cmd')
- @cmd_mock.should_receive(:execute)
- @cmd_mock.stub(:summary)
- end
-
- describe 'clone' do
- before do
- @cmd_mock.stub(:command_name).and_return('clone')
- Fission::Command::Clone.should_receive(:new).and_return(@cmd_mock)
- end
-
- it "should try to clone the vm" do
- Fission::Command::Clone.should_receive(:new).with(['foo', 'bar']).
- and_return(@cmd_mock)
- Fission::CLI.new(['clone', 'foo', 'bar']).execute
-
- end
-
- it 'should try to clone the vm and start it' do
- Fission::Command::Clone.should_receive(:new).
- with(['foo', 'bar', '--start']).
- and_return(@cmd_mock)
- Fission::CLI.new(['clone', 'foo', 'bar', '--start']).execute
- end
- end
-
- describe 'snapshot create' do
- before do
- @cmd_mock.stub(:command_name).and_return('snapshot create')
- Fission::Command::SnapshotCreate.should_receive(:new).
- and_return(@cmd_mock)
- end
-
- it "should create a snapshot" do
- Fission::Command::SnapshotCreate.should_receive(:new).
- with(['foo', 'snap1']).
- and_return(@cmd_mock)
- Fission::CLI.new(['snapshot', 'create', 'foo', 'snap1']).execute
- end
- end
-
- describe 'snapshot list' do
- before do
- @cmd_mock.stub(:command_name).and_return('snapshot list')
- Fission::Command::SnapshotList.should_receive(:new).
- and_return(@cmd_mock)
- end
-
- it "should list the snapshots" do
- Fission::Command::SnapshotList.should_receive(:new).
- with([]).
- and_return(@cmd_mock)
- Fission::CLI.new(['snapshot', 'list']).execute
- end
- end
-
- describe 'snapshot revert' do
- before do
- @cmd_mock.stub(:command_name).and_return('snapshot revert')
- Fission::Command::SnapshotRevert.should_receive(:new).
- and_return(@cmd_mock)
- end
-
- it "should revert to the snapshots" do
- Fission::Command::SnapshotRevert.should_receive(:new).
- with(['foo', 'snap1']).
- and_return(@cmd_mock)
- Fission::CLI.new(['snapshot', 'revert', 'foo', 'snap1']).execute
- end
- end
-
- describe 'start' do
- before do
- @cmd_mock.stub(:command_name).and_return('start')
- Fission::Command::Start.should_receive(:new).
- and_return(@cmd_mock)
- end
-
- it "should try to start the vm" do
- Fission::Command::Start.should_receive(:new).
- with(['foo']).
- and_return(@cmd_mock)
- Fission::CLI.new(['start', 'foo']).execute
- end
-
- it 'should try to start the vm headless' do
- Fission::Command::Start.should_receive(:new).
- with(['foo', '--headless']).
- and_return(@cmd_mock)
- Fission::CLI.new(['start', 'foo', '--headless']).execute
- end
- end
-
- describe 'status' do
- before do
- @cmd_mock.stub(:command_name).and_return('status')
- Fission::Command::Status.should_receive(:new).and_return(@cmd_mock)
- end
-
- it "should try to get the status for all VMs" do
- Fission::Command::Status.should_receive(:new).
- with([]).
- and_return(@cmd_mock)
- Fission::CLI.new(['status']).execute
- end
- end
-
- describe 'stop' do
- before do
- @cmd_mock.stub(:command_name).and_return('stop')
- Fission::Command::Stop.should_receive(:new).and_return(@cmd_mock)
- end
-
- it "should try to stop the vm" do
- Fission::Command::Stop.should_receive(:new).
- with(['foo']).
- and_return(@cmd_mock)
- Fission::CLI.new(['stop', 'foo']).execute
- end
- end
-
- describe 'suspend' do
- before do
- @cmd_mock.stub(:command_name).and_return('suspend')
- Fission::Command::Suspend.should_receive(:new).and_return(@cmd_mock)
- end
-
- it "should try to suspend the vm" do
- Fission::Command::Suspend.should_receive(:new).
- with(['foo']).
- and_return(@cmd_mock)
- Fission::CLI.new(['suspend', 'foo']).execute
- end
-
- it 'should try to suspend all of vms' do
- Fission::Command::Suspend.should_receive(:new).
- with(['--all']).
- and_return(@cmd_mock)
- Fission::CLI.new(['suspend', '--all']).execute
- end
- end
-
- describe 'delete' do
- before do
- @cmd_mock.stub(:command_name).and_return('delete')
- Fission::Command::Delete.should_receive(:new).and_return(@cmd_mock)
- end
-
- it "should try to delete the vm" do
- Fission::Command::Delete.should_receive(:new).
- with(['foo']).
- and_return(@cmd_mock)
- Fission::CLI.new(['delete', 'foo']).execute
- end
+ it 'should create a parse object using our parser' do
+ @parser.should_receive(:new).with(ARGV).and_return(@parser)
+ Fission::CLI.new nil, @parser
+ end
- it 'should try to force delete the vm' do
- Fission::Command::Delete.should_receive(:new).
- with(['foo', '--force']).
- and_return(@cmd_mock)
- Fission::CLI.new(['delete', 'foo', '--force']).execute
- end
- end
+ it 'should parse the arguments using the parser' do
+ @parser.should_receive(:new).with(ARGV).and_return(@parser)
+ @parser.should_receive :parse
+ Fission::CLI.new nil, @parser
end
+ end
+ describe 'execute' do
+ it 'should execute the parsed command' do
+ @cmd_mock = mock ('cmd')
+ @cmd_mock.should_receive :execute
+ @parser.stub(:new).and_return(@parser)
+ @parser.stub(:command).and_return(@cmd_mock)
+ Fission::CLI.new(nil, @parser).execute
+ end
end
+
end
View
184 spec/fission/command_line_parser_spec.rb
@@ -9,8 +9,13 @@
end
describe 'initialize' do
+ it 'should set command to nil' do
+ Fission::CommandLineParser.new.command.should be_nil
+ end
+ end
- context 'with no arguments' do
+ describe 'parse' do
+ context 'with no initial arguments' do
it 'should output the usage info' do
lambda {
Fission::CommandLineParser.new([]).parse
@@ -19,7 +24,7 @@
end
end
- context 'with -v or --version argumetns' do
+ context 'with -v or --version initial arguments' do
['-v', '--version'].each do |arg|
it "should output the version with #{arg}" do
lambda {
@@ -31,7 +36,7 @@
end
end
- context 'with -h or --help argument' do
+ context 'with -h or --help initial arguments' do
['-h', '--help'].each do |arg|
it "should output the usage info with #{arg}" do
lambda {
@@ -54,20 +59,191 @@
end
context 'with a valid sub command' do
+ before do
+ @cmd_mock = mock 'command', :summary => ''
+ end
[ ['clone'],
['delete'],
- ['delete', 'foo'],
['snapshot', 'create'],
['snapshot', 'list'],
['snapshot', 'revert'],
['start'],
+ ['status'],
['stop'],
['suspend']
].each do |command|
it "should accept #{command}" do
Fission::CommandLineParser.new(command).parse
end
+
+ it "should populate @command with an instance of the '#{command.join(' ')}' class" do
+ klass = command.map { |c| c.capitalize }.join('')
+ parser = Fission::CommandLineParser.new(command).parse
+ parser.command.should be_an_instance_of Fission::Command.const_get klass
+ end
+ end
+
+ context 'clone' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('clone')
+ Fission::Command::Clone.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Clone.should_receive(:new).
+ with(['foo', 'bar'])
+ Fission::CommandLineParser.new(['clone', 'foo', 'bar']).parse
+ end
+
+ context 'with --start' do
+ it 'should create the command with the start option' do
+ Fission::Command::Clone.should_receive(:new).
+ with(['foo', 'bar', '--start'])
+ Fission::CommandLineParser.new(['clone', 'foo', 'bar', '--start']).parse
+ end
+ end
+
+ end
+
+ context 'delete' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('delete')
+ Fission::Command::Delete.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Delete.should_receive(:new).
+ with(['foo'])
+ Fission::CommandLineParser.new(['delete', 'foo']).parse
+ end
+
+ context 'with --force' do
+ it 'should create the command with the force option' do
+ Fission::Command::Delete.should_receive(:new).
+ with(['foo', '--force'])
+ Fission::CommandLineParser.new(['delete', 'foo', '--force']).parse
+ end
+ end
+
+ end
+
+ context 'snapshot create' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('snapshot create')
+ Fission::Command::SnapshotCreate.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::SnapshotCreate.should_receive(:new).
+ with(['foo', 'bar'])
+ Fission::CommandLineParser.new(['snapshot', 'create', 'foo', 'bar']).parse
+ end
+ end
+
+ context 'snapshot list' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('snapshot list')
+ Fission::Command::SnapshotList.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::SnapshotList.should_receive(:new).
+ with(['foo'])
+ Fission::CommandLineParser.new(['snapshot', 'list', 'foo']).parse
+ end
+ end
+
+ context 'snapshot revert' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('snapshot revert')
+ Fission::Command::SnapshotRevert.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::SnapshotRevert.should_receive(:new).
+ with(['foo', 'bar'])
+ Fission::CommandLineParser.new(['snapshot', 'revert', 'foo', 'bar']).parse
+ end
+ end
+
+ context 'start' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('start')
+ Fission::Command::Start.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Start.should_receive(:new).
+ with(['foo'])
+ Fission::CommandLineParser.new(['start', 'foo']).parse
+ end
+
+ context 'with --headless' do
+ it 'should create the command with the force option' do
+ Fission::Command::Start.should_receive(:new).
+ with(['foo', '--headless'])
+ Fission::CommandLineParser.new(['start', 'foo', '--headless']).parse
+ end
+ end
+
+ end
+
+ context 'status' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('status')
+ Fission::Command::Status.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Status.should_receive(:new).
+ with([])
+ Fission::CommandLineParser.new(['status']).parse
+ end
+ end
+
+ context 'stop' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('stop')
+ Fission::Command::Stop.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Stop.should_receive(:new).
+ with(['foo'])
+ Fission::CommandLineParser.new(['stop', 'foo']).parse
+ end
+
+ context 'with --force' do
+ it 'should create the command with the force option' do
+ Fission::Command::Stop.should_receive(:new).
+ with(['foo', '--force'])
+ Fission::CommandLineParser.new(['stop', 'foo', '--force']).parse
+ end
+ end
+
+ end
+
+ context 'suspend' do
+ before do
+ @cmd_mock.stub(:command_name).and_return('suspend')
+ Fission::Command::Suspend.should_receive(:new).and_return(@cmd_mock)
+ end
+
+ it 'should create the command' do
+ Fission::Command::Suspend.should_receive(:new).
+ with(['foo'])
+ Fission::CommandLineParser.new(['suspend', 'foo']).parse
+ end
+
+ context 'with --all' do
+ it 'should create the command with the all option' do
+ Fission::Command::Suspend.should_receive(:new).
+ with(['--all'])
+ Fission::CommandLineParser.new(['suspend', '--all']).parse
+ end
+ end
+
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.