Skip to content

Commit

Permalink
Default flag options to false
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed May 30, 2019
1 parent c735bff commit dd195b9
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 81 deletions.
14 changes: 14 additions & 0 deletions lib/cri/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ def run_this(opts_and_args, parent_opts = {})
local_opts = parser.options
global_opts = parent_opts.merge(parser.options)

# Set defaults
all_opt_defns.each do |opt_defn|
key = (opt_defn.long || opt_defn.short).to_sym

next if opt_defn.default.nil?
next if global_opts.key?(key)

global_opts[key] = opt_defn.default
end

# Handle options
handle_options(local_opts)
args = handle_errors_while { parser.gen_argument_list }
Expand All @@ -359,6 +369,10 @@ def run_this(opts_and_args, parent_opts = {})
block.call(global_opts, args, self)
end

def all_opt_defns
supercommand ? supercommand.all_opt_defns.merge(option_definitions) : option_definitions
end

# @return [String] The help text for this command
#
# @option params [Boolean] :verbose true if the help output should be
Expand Down
2 changes: 2 additions & 0 deletions lib/cri/option_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def initialize(params = {})
if @default && @argument == :forbidden
raise ArgumentError, 'a default value cannot be specified for flag options'
end

@default = false if @argument == :forbidden
end

def to_h
Expand Down
16 changes: 0 additions & 16 deletions lib/cri/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ def run
end
end

add_defaults

self
ensure
@running = false
Expand All @@ -133,10 +131,6 @@ def gen_argument_list

private

def add_defaults
@option_defns.each { |d| add_default_option(d) }
end

def handle_dashdash(elem)
add_argument(elem)
@no_more_options = true
Expand Down Expand Up @@ -223,16 +217,6 @@ def add_option(option_defn, value, transform: true)
delegate&.option_added(key, value, self)
end

def add_default_option(option_defn)
key = key_for(option_defn)
return if options.key?(key)

value = option_defn.default
return unless value

add_option(option_defn, value, transform: false)
end

def transform_value(option_defn, value)
transformer = option_defn.transform

Expand Down
82 changes: 75 additions & 7 deletions test/test_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def test_invoke_simple_without_opts_or_args
simple_cmd.run(%w[])
end

assert_equal ['Awesome moo!', '', ''], lines(out)
assert_equal ['Awesome moo!', '', 'ddd=false,eee=false'], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -135,7 +135,7 @@ def test_invoke_simple_with_args
simple_cmd.run(%w[abc xyz])
end

assert_equal ['Awesome moo!', 'abc,xyz', ''], lines(out)
assert_equal ['Awesome moo!', 'abc,xyz', 'ddd=false,eee=false'], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -144,7 +144,7 @@ def test_invoke_simple_with_opts
simple_cmd.run(%w[-c -b x])
end

assert_equal ['Awesome moo!', '', 'bbb=x,ccc=true'], lines(out)
assert_equal ['Awesome moo!', '', 'bbb=x,ccc=true,ddd=false,eee=false'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -216,7 +216,7 @@ def test_invoke_simple_with_opt_with_block
simple_cmd.run(%w[-a 123])
end

assert_equal ['moo:123', 'Awesome moo!', '', 'aaa=123'], lines(out)
assert_equal ['moo:123', 'Awesome moo!', '', 'aaa=123,ddd=false,eee=false'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -246,7 +246,7 @@ def test_invoke_nested_with_correct_command_name
nested_cmd.run(%w[sub])
end

assert_equal ['Sub-awesome!', '', ''], lines(out)
assert_equal ['Sub-awesome!', '', 'ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -297,7 +297,7 @@ def test_invoke_nested_with_alias
nested_cmd.run(%w[sup])
end

assert_equal ['Sub-awesome!', '', ''], lines(out)
assert_equal ['Sub-awesome!', '', 'ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -306,7 +306,7 @@ def test_invoke_nested_with_options_before_command
nested_cmd.run(%w[-a 666 sub])
end

assert_equal ['super:666', 'Sub-awesome!', '', 'aaa=666'], lines(out)
assert_equal ['super:666', 'Sub-awesome!', '', 'aaa=666,ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -895,5 +895,73 @@ def test_propagate_options_two_levels_down
assert_equal ['test? true!'], lines(out)
assert_equal [], lines(err)
end

def test_flag_defaults_to_false
cmd = Cri::Command.define do
name 'a'
option :f, :force2, 'push with force', argument: :forbidden

run do |opts, _args, _cmd|
puts "Force? #{opts[:force2].inspect}!"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Force? false!'], lines(out)
assert_equal [], lines(err)
end

def test_required_option_defaults_to_given_value
cmd = Cri::Command.define do
name 'a'
option :a, :animal, 'specify animal', argument: :required, default: 'cow'

run do |opts, _args, _cmd|
puts "Animal = #{opts[:animal]}"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Animal = cow'], lines(out)
assert_equal [], lines(err)
end

def test_optional_option_defaults_to_given_value
cmd = Cri::Command.define do
name 'a'
option :a, :animal, 'specify animal', argument: :optional, default: 'cow'

run do |opts, _args, _cmd|
puts "Animal = #{opts[:animal]}"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Animal = cow'], lines(out)
assert_equal [], lines(err)
end

def test_required_option_defaults_to_given_value_with_transform
cmd = Cri::Command.define do
name 'a'
option :a, :animal, 'specify animal', argument: :required, transform: ->(a) { a.upcase }, default: 'cow'

run do |opts, _args, _cmd|
puts "Animal = #{opts[:animal]}"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Animal = cow'], lines(out)
assert_equal [], lines(err)
end
end
end
28 changes: 14 additions & 14 deletions test/test_command_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ def test_create_command
expected_option_definitions =
Set.new(
[
{ short: 'a', long: 'aaa', desc: 'opt a', argument: :optional, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'b', long: 'bbb', desc: 'opt b', argument: :required, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'c', long: 'ccc', desc: 'opt c', argument: :optional, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'd', long: 'ddd', desc: 'opt d', argument: :forbidden, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'e', long: 'eee', desc: 'opt e', argument: :forbidden, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'f', long: 'fff', desc: 'opt f', argument: :forbidden, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
{ short: 'a', long: 'aaa', desc: 'opt a', argument: :optional, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'b', long: 'bbb', desc: 'opt b', argument: :required, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'c', long: 'ccc', desc: 'opt c', argument: :optional, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'd', long: 'ddd', desc: 'opt d', argument: :forbidden, multiple: false, hidden: false, block: nil, default: false, transform: nil },
{ short: 'e', long: 'eee', desc: 'opt e', argument: :forbidden, multiple: false, hidden: false, block: nil, default: false, transform: nil },
{ short: 'f', long: 'fff', desc: 'opt f', argument: :forbidden, multiple: false, hidden: true, block: nil, default: false, transform: nil },
],
)
actual_option_definitions = Set.new(command.option_definitions.map(&:to_h))
Expand Down Expand Up @@ -80,8 +80,8 @@ def test_optional_options
expected_option_definitions =
Set.new(
[
{ short: 's', long: nil, desc: 'short', argument: :forbidden, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: nil, long: 'long', desc: 'long', argument: :forbidden, multiple: false, hidden: false, block: nil, default: nil, transform: nil },
{ short: 's', long: nil, desc: 'short', argument: :forbidden, multiple: false, hidden: false, block: nil, default: false, transform: nil },
{ short: nil, long: 'long', desc: 'long', argument: :forbidden, multiple: false, hidden: false, block: nil, default: false, transform: nil },
],
)
actual_option_definitions = Set.new(command.option_definitions.map(&:to_h))
Expand All @@ -104,9 +104,9 @@ def test_multiple
expected_option_definitions =
Set.new(
[
{ short: 'f', long: 'flag', desc: 'flag', argument: :forbidden, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'r', long: 'required', desc: 'req', argument: :required, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'o', long: 'optional', desc: 'opt', argument: :optional, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'f', long: 'flag', desc: 'flag', argument: :forbidden, multiple: true, hidden: false, block: nil, default: false, transform: nil },
{ short: 'r', long: 'required', desc: 'req', argument: :required, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
{ short: 'o', long: 'optional', desc: 'opt', argument: :optional, multiple: true, hidden: false, block: nil, default: nil, transform: nil },
],
)
actual_option_definitions = Set.new(command.option_definitions.map(&:to_h))
Expand All @@ -129,9 +129,9 @@ def test_hidden
expected_option_definitions =
Set.new(
[
{ short: 'f', long: 'flag', desc: 'flag', argument: :forbidden, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
{ short: 'r', long: 'required', desc: 'req', argument: :required, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
{ short: 'o', long: 'optional', desc: 'opt', argument: :optional, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
{ short: 'f', long: 'flag', desc: 'flag', argument: :forbidden, multiple: false, hidden: true, block: nil, default: false, transform: nil },
{ short: 'r', long: 'required', desc: 'req', argument: :required, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
{ short: 'o', long: 'optional', desc: 'opt', argument: :optional, multiple: false, hidden: true, block: nil, default: nil, transform: nil },
],
)
actual_option_definitions = Set.new(command.option_definitions.map(&:to_h))
Expand Down
44 changes: 0 additions & 44 deletions test/test_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,6 @@ def test_parse_with_multiple_options
assert_equal(3, parser.options[:verbose].size)
end

def test_parse_with_default_required_unspecified
input = %w[foo]
opt_defns = [
{ long: 'animal', short: 'a', argument: :required, default: 'donkey' },
].map { |hash| make_opt_defn(hash) }

parser = Cri::Parser.new(input, opt_defns, [], false).run

assert_equal({ animal: 'donkey' }, parser.options)
assert_equal(['foo'], parser.gen_argument_list.to_a)
end

def test_parse_with_default_required_no_value
input = %w[foo -a]
opt_defns = [
Expand All @@ -319,18 +307,6 @@ def test_parse_with_default_required_value
assert_equal(['foo'], parser.gen_argument_list.to_a)
end

def test_parse_with_default_optional_unspecified
input = %w[foo]
opt_defns = [
{ long: 'animal', short: 'a', argument: :optional, default: 'donkey' },
].map { |hash| make_opt_defn(hash) }

parser = Cri::Parser.new(input, opt_defns, [], false).run

assert_equal({ animal: 'donkey' }, parser.options)
assert_equal(['foo'], parser.gen_argument_list.to_a)
end

def test_parse_with_default_optional_no_value
input = %w[foo -a]
opt_defns = [
Expand Down Expand Up @@ -451,26 +427,6 @@ def call(str)
assert_equal([], parser.gen_argument_list.to_a)
end

def test_parse_with_transform_default
port = Class.new do
def call(str)
raise unless str.is_a?(String)

Integer(str)
end
end.new

input = %w[]
opt_defns = [
{ long: 'port', short: 'p', argument: :required, default: 8080, transform: port },
].map { |hash| make_opt_defn(hash) }

parser = Cri::Parser.new(input, opt_defns, [], false).run

assert_equal({ port: 8080 }, parser.options)
assert_equal([], parser.gen_argument_list.to_a)
end

def test_parse_with_transform_exception
input = %w[--port one_hundred_and_twenty_three]
opt_defns = [
Expand Down

0 comments on commit dd195b9

Please sign in to comment.