Решение на Трета задача - Четене на командни аргументи от Мая Терзиева

Обратно към всички решения

Към профила на Мая Терзиева

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 8 успешни тест(а)
  • 7 неуспешни тест(а)

Код

class CommandParser
def initialize(command)
@command = command
@arguments = []
@options = []
@options_with_parameter = []
end
def argument(name, &block)
@arguments << Argument.new(name, block)
end
def option(short_name, name, description, &block)
@options << Option.new(short_name, name, description, block)
end
def option_with_parameter(short_name, name, description, parameter, &block)
@options_with_parameter <<
OptionWithParameter.new(short_name, name, description, parameter, block)
end
def parse(command_runner, parameters)
arguments = parameters.select { |p| !p.start_with? '-' }
parse_arguments(command_runner, arguments)
options = parameters - arguments
parse_options(command_runner, options)
end
private
def parse_arguments(command_runner, arguments)
arguments.each_with_index do |argument, index|
@arguments[index].parse(command_runner, argument)
end
end
def parse_options(command_runner, options)
options.each do |option|
name, value = split_name_and_value(option)
if value.to_s == ''
defined = @options.select { |o| o.name? name }.first
defined.parse(command_runner) if defined
else
defined = @options_with_parameter.select { |o| o.name? name }.first
defined.parse(command_runner, value) if defined
end
end
end
def split_name_and_value(option)
if option.start_with? "--"
option.split("=")
else
[option[0..1], option[2..-1]]
end
end
end
class Argument
def initialize(name, block)
@name = name
@block = block
end
def parse(command_runner, value)
@block.call command_runner, value
end
end
class Option
def initialize(short_name, name, description, block)
@short_name = "-#{short_name}"
@name = "--#{name}"
@description = description
@block = block
end
def parse(command_runner)
@block.call command_runner, true
end
def name?(name)
(@name == name) || (@short_name == name)
end
end
class OptionWithParameter < Option
def initialize(short_name, name, description, parameter, block)
super(short_name, name, description, block)
@parameter = parameter
end
def parse(command_runner, value)
@block.call command_runner, value
end
end

Лог от изпълнението

.......FFFFFF.F

Failures:

  1) CommandParser#help shows basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7ff42e50>
     # /tmp/d20161113-27983-1bo585q/spec.rb:104:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) CommandParser#help shows single argument
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FILE]'
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7ff3d928>
     # /tmp/d20161113-27983-1bo585q/spec.rb:110:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) CommandParser#help shows multiple arguments
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]'
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7ff22f60>
     # /tmp/d20161113-27983-1bo585q/spec.rb:118:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) CommandParser#help shows single option help
     Failure/Error: parser.help.lines.map(&:chomp).drop(1)
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7ff07210>
     # /tmp/d20161113-27983-1bo585q/spec.rb:19:in `options_help_messages'
     # /tmp/d20161113-27983-1bo585q/spec.rb:125:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  5) CommandParser#help shows multiple options help
     Failure/Error: parser.help.lines.map(&:chomp).drop(1)
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7fefd9b8>
     # /tmp/d20161113-27983-1bo585q/spec.rb:19:in `options_help_messages'
     # /tmp/d20161113-27983-1bo585q/spec.rb:137:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  6) CommandParser#help shows options with parameter
     Failure/Error: parser.help.lines.map(&:chomp).drop(1)
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7feef868>
     # /tmp/d20161113-27983-1bo585q/spec.rb:19:in `options_help_messages'
     # /tmp/d20161113-27983-1bo585q/spec.rb:148:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  7) CommandParser when having options with and without values and parameters generates a correct help usage
     Failure/Error: header = parser.help.lines.first.chomp
     NoMethodError:
       undefined method `help' for #<CommandParser:0x007fec7fe96128>
     # /tmp/d20161113-27983-1bo585q/spec.rb:181:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.00835 seconds
15 examples, 7 failures

Failed examples:

rspec /tmp/d20161113-27983-1bo585q/spec.rb:103 # CommandParser#help shows basic usage message
rspec /tmp/d20161113-27983-1bo585q/spec.rb:107 # CommandParser#help shows single argument
rspec /tmp/d20161113-27983-1bo585q/spec.rb:113 # CommandParser#help shows multiple arguments
rspec /tmp/d20161113-27983-1bo585q/spec.rb:121 # CommandParser#help shows single option help
rspec /tmp/d20161113-27983-1bo585q/spec.rb:130 # CommandParser#help shows multiple options help
rspec /tmp/d20161113-27983-1bo585q/spec.rb:143 # CommandParser#help shows options with parameter
rspec /tmp/d20161113-27983-1bo585q/spec.rb:180 # CommandParser when having options with and without values and parameters generates a correct help usage

История (1 версия и 0 коментара)

Мая обнови решението на 09.11.2016 16:46 (преди над 7 години)

+class CommandParser
+ def initialize(command)
+ @command = command
+ @arguments = []
+ @options = []
+ @options_with_parameter = []
+ end
+
+ def argument(name, &block)
+ @arguments << Argument.new(name, block)
+ end
+
+ def option(short_name, name, description, &block)
+ @options << Option.new(short_name, name, description, block)
+ end
+
+ def option_with_parameter(short_name, name, description, parameter, &block)
+ @options_with_parameter <<
+ OptionWithParameter.new(short_name, name, description, parameter, block)
+ end
+
+ def parse(command_runner, parameters)
+ arguments = parameters.select { |p| !p.start_with? '-' }
+ parse_arguments(command_runner, arguments)
+
+ options = parameters - arguments
+ parse_options(command_runner, options)
+ end
+
+ private
+
+ def parse_arguments(command_runner, arguments)
+ arguments.each_with_index do |argument, index|
+ @arguments[index].parse(command_runner, argument)
+ end
+ end
+
+ def parse_options(command_runner, options)
+ options.each do |option|
+ name, value = split_name_and_value(option)
+
+ if value.to_s == ''
+ defined = @options.select { |o| o.name? name }.first
+ defined.parse(command_runner) if defined
+ else
+ defined = @options_with_parameter.select { |o| o.name? name }.first
+ defined.parse(command_runner, value) if defined
+ end
+ end
+ end
+
+ def split_name_and_value(option)
+ if option.start_with? "--"
+ option.split("=")
+ else
+ [option[0..1], option[2..-1]]
+ end
+ end
+end
+
+class Argument
+ def initialize(name, block)
+ @name = name
+ @block = block
+ end
+
+ def parse(command_runner, value)
+ @block.call command_runner, value
+ end
+end
+
+class Option
+ def initialize(short_name, name, description, block)
+ @short_name = "-#{short_name}"
+ @name = "--#{name}"
+ @description = description
+ @block = block
+ end
+
+ def parse(command_runner)
+ @block.call command_runner, true
+ end
+
+ def name?(name)
+ (@name == name) || (@short_name == name)
+ end
+end
+
+class OptionWithParameter < Option
+ def initialize(short_name, name, description, parameter, block)
+ super(short_name, name, description, block)
+ @parameter = parameter
+ end
+
+ def parse(command_runner, value)
+ @block.call command_runner, value
+ end
+end