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

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

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

Резултати

  • 1 точка от тестове
  • 0 бонус точки
  • 1 точка общо
  • 2 успешни тест(а)
  • 13 неуспешни тест(а)

Код

class CommandParser
attr_accessor :command_name, :options, :arguments
def initialize(command_name)
@command_name = command_name
@options = []
@arguments = []
@option_with_parameters = []
end
def argument(arg, &block)
@arguments.push(Argument.new(arg, &block))
end
def option(short_name, long_name, summary, &block)
@options.push(Option.new(short_name, long_name, summary, &block))
end
def option_with_parameter(short_name, long_name, sum, value, &block)
@option_with_parameters
.push(OptionWithParameter.new(short_name, long_name, sum, value, &block))
end
def parse(command_runner, argv)
a = 0
argv.each do |arg|
if argument?(arg)
@arguments[a += 1].block.call(command_runner, arg)
elsif option = get_option(arg)
option.block.call(command_runner, true)
elsif option = get_option_with_parameter(arg)
option.block.call(command_runner, arg)
end
end
end
def help
str = "Usage: #{command_name} \r\n"
@arguments.each { |arg| str + "[#{arg}]\r\n" }
@options.each do |opt|
str += "-#{opt.short_name} --#{opt.long_name} #{opt.summary}\r\n"
end
@option_with_parameters.each do |opt|
str += "-#{opt.short_name} --#{opt.long_name}=#{opt.parameter}"
str += " #{opt.summary}\r\n"
end
str
end
private
def argument?(arg)
arg[0] != '-'
end
def get_option(arg)
@options.first { |o| o.short_name == arg || o.long_name == arg }
end
def get_option_with_parameter(arg)
@option_with_parameters.first do |o|
o.short_name == arg || o.long_name == arg
end
end
end
class Option
attr_accessor :short_name, :long_name, :summary, :block
def initialize(short_name, long_name, summary, &block)
@short_name = short_name
@long_name = long_name
@summary = summary
@block = block
end
end
class Argument
attr_accessor :argument, :block
def initialize(argument, &block)
@argument = argument
@block = block
end
end
class OptionWithParameter
attr_accessor :short_name, :long_name, :summary, :block, :parameter
def initialize(short_name, long_name, summary, parameter, &block)
@short_name = short_name
@long_name = long_name
@summary = summary
@parameter = parameter
@block = block
end
end

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

Programming/ruby
FF..FFFFFFFFFFF

Failures:

  1) CommandParser#argument parses a single argument
     Failure/Error: expect(command_runner[:file_name]).to eq 'Programming/ruby'
       
       expected: "Programming/ruby"
            got: nil
       
       (compared using ==)
     # /tmp/d20161113-27983-aa2mnb/spec.rb:34: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#argument parses multiple arguments
     Failure/Error: parser.parse(command_runner, %w(first.rb second.rb other/third.rb))
     NoMethodError:
       undefined method `block' for nil:NilClass
     # /tmp/d20161113-27983-aa2mnb/solution.rb:28:in `block in parse'
     # /tmp/d20161113-27983-aa2mnb/solution.rb:26:in `each'
     # /tmp/d20161113-27983-aa2mnb/solution.rb:26:in `parse'
     # /tmp/d20161113-27983-aa2mnb/spec.rb:42: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#option parses multiple options
     Failure/Error: expect(command_runner[:dir]).to be true
       
       expected #<TrueClass:20> => true
            got #<Symbol:252508> => :default
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       `expect(actual).to eq(expected)` if you don't care about
       object identity in this example.
       
       
       Diff:
       @@ -1,2 +1,2 @@
       -true
       +:default
     # /tmp/d20161113-27983-aa2mnb/spec.rb:77: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#option_with_parameter parses a option with parameter in short format
     Failure/Error: expect(command_runner[:sort]).to eq 'time'
       
       expected: "time"
            got: "-stime"
       
       (compared using ==)
     # /tmp/d20161113-27983-aa2mnb/spec.rb:89: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#option_with_parameter parses a option with parameter in long format
     Failure/Error: expect(command_runner[:sort]).to eq 'time'
       
       expected: "time"
            got: "--sort=time"
       
       (compared using ==)
     # /tmp/d20161113-27983-aa2mnb/spec.rb:98: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 basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
       
       expected: "Usage: ls"
            got: "Usage: ls \r\n"
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -Usage: ls
       +Usage: ls 
     # /tmp/d20161113-27983-aa2mnb/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)>'

  7) CommandParser#help shows single argument
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FILE]'
       
       expected: "Usage: ls [FILE]"
            got: "Usage: ls \r\n"
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -Usage: ls [FILE]
       +Usage: ls 
     # /tmp/d20161113-27983-aa2mnb/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)>'

  8) CommandParser#help shows multiple arguments
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]'
       
       expected: "Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]"
            got: "Usage: ls \r\n"
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]
       +Usage: ls 
     # /tmp/d20161113-27983-aa2mnb/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)>'

  9) CommandParser#help shows single option help
     Failure/Error: expect(options_help_messages(parser)).to match_array([
       expected collection contained:  ["    -a, --all do not ignore entries starting with ."]
       actual collection contained:    ["-a --all do not ignore entries starting with ."]
       the missing elements were:      ["    -a, --all do not ignore entries starting with ."]
       the extra elements were:        ["-a --all do not ignore entries starting with ."]
     # /tmp/d20161113-27983-aa2mnb/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)>'

  10) CommandParser#help shows multiple options help
     Failure/Error: expect(options_help_messages(parser)).to match_array([
       expected collection contained:  ["    -a, --all do not ignore entries starting with .", "    -d, --directory list directories themselves, not their contents"]
       actual collection contained:    ["-a --all do not ignore entries starting with .", "-d --directory list directories themselves, not their contents"]
       the missing elements were:      ["    -a, --all do not ignore entries starting with .", "    -d, --directory list directories themselves, not their contents"]
       the extra elements were:        ["-a --all do not ignore entries starting with .", "-d --directory list directories themselves, not their contents"]
     # /tmp/d20161113-27983-aa2mnb/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)>'

  11) CommandParser#help shows options with parameter
     Failure/Error: expect(options_help_messages(parser)).to match_array([
       expected collection contained:  ["    -s, --sort=WORD sort by WORD instead of name"]
       actual collection contained:    ["-s --sort=WORD sort by WORD instead of name"]
       the missing elements were:      ["    -s, --sort=WORD sort by WORD instead of name"]
       the extra elements were:        ["-s --sort=WORD sort by WORD instead of name"]
     # /tmp/d20161113-27983-aa2mnb/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)>'

  12) CommandParser when having options with and without values and parameters parses all the options and arguments correctly
     Failure/Error: parser.parse(command_runner, %w(--all -d -ssize first.rb second.rb))
     NoMethodError:
       undefined method `block' for nil:NilClass
     # /tmp/d20161113-27983-aa2mnb/solution.rb:28:in `block in parse'
     # /tmp/d20161113-27983-aa2mnb/solution.rb:26:in `each'
     # /tmp/d20161113-27983-aa2mnb/solution.rb:26:in `parse'
     # /tmp/d20161113-27983-aa2mnb/spec.rb:169: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)>'

  13) CommandParser when having options with and without values and parameters generates a correct help usage
     Failure/Error: expect(header).to eq 'Usage: ls [FIRST FILE] [SECOND FILE]'
       
       expected: "Usage: ls [FIRST FILE] [SECOND FILE]"
            got: "Usage: ls "
       
       (compared using ==)
     # /tmp/d20161113-27983-aa2mnb/spec.rb:182: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.03815 seconds
15 examples, 13 failures

Failed examples:

rspec /tmp/d20161113-27983-aa2mnb/spec.rb:26 # CommandParser#argument parses a single argument
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:37 # CommandParser#argument parses multiple arguments
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:69 # CommandParser#option parses multiple options
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:83 # CommandParser#option_with_parameter parses a option with parameter in short format
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:92 # CommandParser#option_with_parameter parses a option with parameter in long format
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:103 # CommandParser#help shows basic usage message
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:107 # CommandParser#help shows single argument
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:113 # CommandParser#help shows multiple arguments
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:121 # CommandParser#help shows single option help
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:130 # CommandParser#help shows multiple options help
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:143 # CommandParser#help shows options with parameter
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:168 # CommandParser when having options with and without values and parameters parses all the options and arguments correctly
rspec /tmp/d20161113-27983-aa2mnb/spec.rb:180 # CommandParser when having options with and without values and parameters generates a correct help usage

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

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

+class CommandParser
+ attr_accessor :command_name, :options, :arguments
+
+ def initialize(command_name)
+ @command_name = command_name
+ @options = []
+ @arguments = []
+ @option_with_parameters = []
+ end
+
+ def argument(arg, &block)
+ @arguments.push(Argument.new(arg, &block))
+ end
+
+ def option(short_name, long_name, summary, &block)
+ @options.push(Option.new(short_name, long_name, summary, &block))
+ end
+
+ def option_with_parameter(short_name, long_name, sum, value, &block)
+ @option_with_parameters
+ .push(OptionWithParameter.new(short_name, long_name, sum, value, &block))
+ end
+
+ def parse(command_runner, argv)
+ a = 0
+ argv.each do |arg|
+ if argument?(arg)
+ @arguments[a += 1].block.call(command_runner, arg)
+ elsif option = get_option(arg)
+ option.block.call(command_runner, true)
+ elsif option = get_option_with_parameter(arg)
+ option.block.call(command_runner, arg)
+ end
+ end
+ end
+
+ def help
+ str = "Usage: #{command_name} \r\n"
+ @arguments.each { |arg| str + "[#{arg}]\r\n" }
+ @options.each do |opt|
+ str += "-#{opt.short_name} --#{opt.long_name} #{opt.summary}\r\n"
+ end
+ @option_with_parameters.each do |opt|
+ str += "-#{opt.short_name} --#{opt.long_name}=#{opt.parameter}"
+ str += " #{opt.summary}\r\n"
+ end
+ str
+ end
+
+ private
+
+ def argument?(arg)
+ arg[0] != '-'
+ end
+
+ def get_option(arg)
+ @options.first { |o| o.short_name == arg || o.long_name == arg }
+ end
+
+ def get_option_with_parameter(arg)
+ @option_with_parameters.first do |o|
+ o.short_name == arg || o.long_name == arg
+ end
+ end
+end
+
+class Option
+ attr_accessor :short_name, :long_name, :summary, :block
+
+ def initialize(short_name, long_name, summary, &block)
+ @short_name = short_name
+ @long_name = long_name
+ @summary = summary
+ @block = block
+ end
+end
+
+class Argument
+ attr_accessor :argument, :block
+
+ def initialize(argument, &block)
+ @argument = argument
+ @block = block
+ end
+end
+
+class OptionWithParameter
+ attr_accessor :short_name, :long_name, :summary, :block, :parameter
+
+ def initialize(short_name, long_name, summary, parameter, &block)
+ @short_name = short_name
+ @long_name = long_name
+ @summary = summary
+ @parameter = parameter
+ @block = block
+ end
+end