Решение на Трета задача - Четене на командни аргументи от Александър Ойнаков

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

Към профила на Александър Ойнаков

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 9 успешни тест(а)
  • 6 неуспешни тест(а)

Код

class Argument
attr_reader :name
def initialize(name, block)
@name = name
@block = block
end
def call(runner, value)
@block.call(runner, value)
end
end
class Option
attr_reader :short, :long, :description
def initialize(short, long, description, block)
@short = short
@long = long
@description = description
@block = block
end
def call(runner)
@block.call(runner, true)
end
def check?(name)
name == @short || name == @long
end
end
class OptionWithParameter
attr_reader :short, :long, :description, :placeholder
def initialize(short, long, description, placeholder, block)
@short = short
@long = long
@description = description
@placeholder = placeholder
@block = block
end
def check?(name)
name == @short || name == @long
end
def call(runner, value)
@block.call(runner, value)
end
end
def read_options_with_parameter(command_runner, options_with_parameter)
options_with_parameter.each do |name|
if name[1] == '-'
parts = name.split('=')
else
name_of_the_option = name.slice(0..1)
value = name.slice(2..-1)
parts = [name_of_the_option, value]
end
option_with_parameter_block_call(command_runner, parts)
end
end
def remove_dashes(options)
options.each do |opt|
opt.slice!(0) if opt.chr == '-'
opt.slice!(0) if opt.chr == '-'
end
end
def call_methods(command_runner, argv)
options = argv.select { |x| x.start_with?('-') && !x.include?('.rb') }
options_with_parameter =
argv.select { |x| x.start_with?('-') && x.include?('.rb') }
read_options(command_runner, options)
read_options_with_parameter(command_runner, options_with_parameter)
arguments = argv - options - options_with_parameter
read_arguments(command_runner, arguments)
end
def option_with_parameter_block_call(command_runner, parts)
remove_dashes(parts)
matching = @option_with_parameter.select { |opt| opt.check?(parts[0]) }
matching[0].call(command_runner, parts[1]) unless matching.empty?
end
def read_options(command_runner, options)
remove_dashes(options)
options.each do |name|
matching = @options.select { |opt| opt.check?(name) }
matching[0].call(command_runner) unless matching.empty?
end
end
def read_arguments(command_runner, arguments)
@arguments.zip(arguments).each do |arg, value|
arg.call(command_runner, value)
end
end
def argument_pusher(array_arg)
@arguments.each do |arg|
array_arg.push("[#{arg.name}]")
end
end
def option_pusher(array_opt)
@options.each do |opt|
array_opt.push("\r\n -#{opt.short}, --#{opt.long} #{opt.description}")
end
end
def option_with_parameter_pusher(array_param)
@option_with_parameter.each do |opt|
array_param.push(
"\r\n -#{opt.short}, --#{opt.long}="\
"#{opt.placeholder} #{opt.description}"
)
end
end
class CommandParser
def initialize(name)
@name = name
@arguments = []
@options = []
@option_with_parameter = []
end
def argument(name, &block)
@arguments.push(Argument.new(name, block))
end
def option(short, long, description, &block)
@options.push(Option.new(short, long, description, block))
end
def option_with_parameter(short, long, description, placeholder, &block)
@option_with_parameter
.push(OptionWithParameter
.new(short, long, description, placeholder, block)
)
end
def help
array_arg = []
array_opt = []
array_param = []
argument_pusher(array_arg)
option_pusher(array_opt)
option_with_parameter_pusher(array_param)
"Usage: #{@name} #{array_arg.join(" ")}"\
"#{array_opt.join(" ")}"\
"#{array_param.join(" ")}"
end
def parse(command_runner, argv)
call_methods(command_runner, argv)
end
end

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

.....FFF...F.FF

Failures:

  1) CommandParser#option_with_parameter parses a option with parameter in short format
     Failure/Error: expect(command_runner[:sort]).to eq 'time'
       
       expected: "time"
            got: :default
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -"time"
       +:default
     # /tmp/d20161113-27983-9ji95s/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)>'

  2) CommandParser#option_with_parameter parses a option with parameter in long format
     Failure/Error: expect(command_runner[:sort]).to eq 'time'
       
       expected: "time"
            got: :default
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -"time"
       +:default
     # /tmp/d20161113-27983-9ji95s/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)>'

  3) CommandParser#help shows basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
       
       expected: "Usage: ls"
            got: "Usage: ls "
       
       (compared using ==)
     # /tmp/d20161113-27983-9ji95s/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)>'

  4) 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 ."]
       the extra elements were:        ["    -a, --all do not ignore entries starting with . "]
     # /tmp/d20161113-27983-9ji95s/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)>'

  5) CommandParser when having options with and without values and parameters parses all the options and arguments correctly
     Failure/Error: expect(command_runner[:sort]).to eq 'size'
       
       expected: "size"
            got: :default
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -"size"
       +:default
     # /tmp/d20161113-27983-9ji95s/spec.rb:177: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 when having options with and without values and parameters generates a correct help usage
     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", "    -s, --sort=WORD sort by WORD instead of name"]
       actual collection contained:    ["    -a, --all do not ignore entries starting with . ", "    -d, --directory list directories themselves, not their contents", "    -s, --sort=WORD sort by WORD instead of name"]
       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-9ji95s/spec.rb:184: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.01096 seconds
15 examples, 6 failures

Failed examples:

rspec /tmp/d20161113-27983-9ji95s/spec.rb:83 # CommandParser#option_with_parameter parses a option with parameter in short format
rspec /tmp/d20161113-27983-9ji95s/spec.rb:92 # CommandParser#option_with_parameter parses a option with parameter in long format
rspec /tmp/d20161113-27983-9ji95s/spec.rb:103 # CommandParser#help shows basic usage message
rspec /tmp/d20161113-27983-9ji95s/spec.rb:130 # CommandParser#help shows multiple options help
rspec /tmp/d20161113-27983-9ji95s/spec.rb:168 # CommandParser when having options with and without values and parameters parses all the options and arguments correctly
rspec /tmp/d20161113-27983-9ji95s/spec.rb:180 # CommandParser when having options with and without values and parameters generates a correct help usage

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

Александър обнови решението на 09.11.2016 00:07 (преди над 7 години)

+class Argument
+ attr_reader :name
+ def initialize(name, block)
+ @name = name
+ @block = block
+ end
+
+ def call(runner, value)
+ @block.call(runner, value)
+ end
+end
+
+class Option
+ attr_reader :short, :long, :description
+ def initialize(short, long, description, block)
+ @short = short
+ @long = long
+ @description = description
+ @block = block
+ end
+
+ def call(runner)
+ @block.call(runner, true)
+ end
+
+ def check?(name)
+ name == @short || name == @long
+ end
+end
+
+class OptionWithParameter
+ attr_reader :short, :long, :description, :placeholder
+ def initialize(short, long, description, placeholder, block)
+ @short = short
+ @long = long
+ @description = description
+ @placeholder = placeholder
+ @block = block
+ end
+
+ def check?(name)
+
+ name == @short || name == @long
+ end
+
+ def call(runner, value)
+ @block.call(runner, value)
+ end
+end
+
+def read_options_with_parameter(command_runner, options_with_parameter)
+ options_with_parameter.each do |name|
+ if name[1] == '-'
+ parts = name.split('=')
+ else
+ name_of_the_option = name.slice(0..1)
+ value = name.slice(2..-1)
+ parts = [name_of_the_option, value]
+ end
+ option_with_parameter_block_call(command_runner, parts)
+ end
+end
+
+def remove_dashes(options)
+ options.each do |opt|
+ opt.slice!(0) if opt.chr == '-'
+ opt.slice!(0) if opt.chr == '-'
+ end
+end
+
+ def call_methods(command_runner, argv)
+ options = argv.select { |x| x.start_with?('-') && !x.include?('.rb') }
+ options_with_parameter =
+ argv.select { |x| x.start_with?('-') && x.include?('.rb') }
+ read_options(command_runner, options)
+ read_options_with_parameter(command_runner, options_with_parameter)
+ arguments = argv - options - options_with_parameter
+ read_arguments(command_runner, arguments)
+ end
+
+ def option_with_parameter_block_call(command_runner, parts)
+ remove_dashes(parts)
+ matching = @option_with_parameter.select { |opt| opt.check?(parts[0]) }
+ matching[0].call(command_runner, parts[1]) unless matching.empty?
+ end
+
+ def read_options(command_runner, options)
+ remove_dashes(options)
+ options.each do |name|
+ matching = @options.select { |opt| opt.check?(name) }
+ matching[0].call(command_runner) unless matching.empty?
+ end
+ end
+
+ def read_arguments(command_runner, arguments)
+ @arguments.zip(arguments).each do |arg, value|
+ arg.call(command_runner, value)
+ end
+ end
+
+ def argument_pusher(array_arg)
+ @arguments.each do |arg|
+ array_arg.push("[#{arg.name}]")
+ end
+ end
+
+ def option_pusher(array_opt)
+ @options.each do |opt|
+ array_opt.push(" -#{opt.short}, --#{opt.long} #{opt.description}")
+ end
+ end
+
+ def option_with_parameter_pusher(array_param)
+ @option_with_parameter.each do |opt|
+ array_param.push(
+ " -#{opt.short}, --#{opt.long}=#{opt.placeholder} #{opt.description}"
+ )
+ end
+ end
+class CommandParser
+ def initialize(name)
+ @name = name
+ @arguments = []
+ @options = []
+ @option_with_parameter = []
+ end
+
+ def argument(name, &block)
+ @arguments.push(Argument.new(name, block))
+ end
+
+ def option(short, long, description, &block)
+ @options.push(Option.new(short, long, description, block))
+ end
+
+ def option_with_parameter(short, long, description, placeholder, &block)
+ @option_with_parameter
+ .push(OptionWithParameter
+ .new(short, long, description, placeholder, block)
+ )
+ end
+
+ def help
+ array_arg = []
+ array_opt = []
+ array_param = []
+ argument_pusher(array_arg)
+ option_pusher(array_opt)
+ option_with_parameter_pusher(array_param)
+ "Usage: #{@name} #{array_arg.join(" ")}\r\n"\
+ "#{array_opt.join(" ")}\r\n"\
+ "#{array_param.join(" ")}"
+ end
+
+ def parse(command_runner, argv)
+ call_methods(command_runner, argv)
+ end
+end

Александър обнови решението на 09.11.2016 13:46 (преди над 7 години)

class Argument
attr_reader :name
def initialize(name, block)
@name = name
@block = block
end
def call(runner, value)
@block.call(runner, value)
end
end
class Option
attr_reader :short, :long, :description
def initialize(short, long, description, block)
@short = short
@long = long
@description = description
@block = block
end
def call(runner)
@block.call(runner, true)
end
def check?(name)
name == @short || name == @long
end
end
class OptionWithParameter
attr_reader :short, :long, :description, :placeholder
def initialize(short, long, description, placeholder, block)
@short = short
@long = long
@description = description
@placeholder = placeholder
@block = block
end
def check?(name)
name == @short || name == @long
end
def call(runner, value)
@block.call(runner, value)
end
end
def read_options_with_parameter(command_runner, options_with_parameter)
options_with_parameter.each do |name|
if name[1] == '-'
parts = name.split('=')
else
name_of_the_option = name.slice(0..1)
value = name.slice(2..-1)
parts = [name_of_the_option, value]
end
option_with_parameter_block_call(command_runner, parts)
end
end
def remove_dashes(options)
options.each do |opt|
opt.slice!(0) if opt.chr == '-'
opt.slice!(0) if opt.chr == '-'
end
end
def call_methods(command_runner, argv)
options = argv.select { |x| x.start_with?('-') && !x.include?('.rb') }
options_with_parameter =
argv.select { |x| x.start_with?('-') && x.include?('.rb') }
read_options(command_runner, options)
read_options_with_parameter(command_runner, options_with_parameter)
arguments = argv - options - options_with_parameter
read_arguments(command_runner, arguments)
end
def option_with_parameter_block_call(command_runner, parts)
remove_dashes(parts)
matching = @option_with_parameter.select { |opt| opt.check?(parts[0]) }
matching[0].call(command_runner, parts[1]) unless matching.empty?
end
def read_options(command_runner, options)
remove_dashes(options)
options.each do |name|
matching = @options.select { |opt| opt.check?(name) }
matching[0].call(command_runner) unless matching.empty?
end
end
def read_arguments(command_runner, arguments)
@arguments.zip(arguments).each do |arg, value|
arg.call(command_runner, value)
end
end
def argument_pusher(array_arg)
@arguments.each do |arg|
array_arg.push("[#{arg.name}]")
end
end
def option_pusher(array_opt)
@options.each do |opt|
- array_opt.push(" -#{opt.short}, --#{opt.long} #{opt.description}")
+ array_opt.push("\r\n -#{opt.short}, --#{opt.long} #{opt.description}")
end
end
def option_with_parameter_pusher(array_param)
@option_with_parameter.each do |opt|
array_param.push(
- " -#{opt.short}, --#{opt.long}=#{opt.placeholder} #{opt.description}"
+ "\r\n -#{opt.short}, --#{opt.long}="\
+ "#{opt.placeholder} #{opt.description}"
)
end
end
class CommandParser
def initialize(name)
@name = name
@arguments = []
@options = []
@option_with_parameter = []
end
def argument(name, &block)
@arguments.push(Argument.new(name, block))
end
def option(short, long, description, &block)
@options.push(Option.new(short, long, description, block))
end
def option_with_parameter(short, long, description, placeholder, &block)
@option_with_parameter
.push(OptionWithParameter
.new(short, long, description, placeholder, block)
)
end
def help
array_arg = []
array_opt = []
array_param = []
argument_pusher(array_arg)
option_pusher(array_opt)
option_with_parameter_pusher(array_param)
- "Usage: #{@name} #{array_arg.join(" ")}\r\n"\
- "#{array_opt.join(" ")}\r\n"\
+ "Usage: #{@name} #{array_arg.join(" ")}"\
+ "#{array_opt.join(" ")}"\
"#{array_param.join(" ")}"
end
def parse(command_runner, argv)
call_methods(command_runner, argv)
end
end