Skip to content

Commit

Permalink
Add param conversion to parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Mar 28, 2020
1 parent e32c757 commit 392c131
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 38 deletions.
1 change: 0 additions & 1 deletion lib/tty/option.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require_relative "option/arity_dsl"
require_relative "option/converter"
require_relative "option/conversions"
require_relative "option/dsl"
require_relative "option/parser"
Expand Down
34 changes: 19 additions & 15 deletions lib/tty/option/parser/arguments.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative "../param_conversion"

module TTY
module Option
class Parser
Expand Down Expand Up @@ -185,21 +187,23 @@ def record_error(type, message, arg = nil)
#
# @api private
def assign_argument(arg, values)
case values.size
when 0
if arg.default?
case arg.default
when Proc
@parsed[arg.name] = @defaults[arg.name]
else
@parsed[arg.name] = @defaults[arg.name]
end
end
when 1
@parsed[arg.name] = values.first
else
@parsed[arg.name] = values
end
val = case values.size
when 0
if arg.default?
case arg.default
when Proc
@defaults[arg.name]
else
@defaults[arg.name]
end
end
when 1
values.first
else
values
end

@parsed[arg.name] = ParamConversion[arg, val]
end
end # Arguments
end # Parser
Expand Down
6 changes: 4 additions & 2 deletions lib/tty/option/parser/environments.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative "../param_conversion"

module TTY
module Option
class Parser
Expand Down Expand Up @@ -95,12 +97,12 @@ def env_var?(value)
def assign_envvar(env_arg, value)
if env_arg.multiple?
if env_arg.arity < 0 || (@parsed[env_arg.name] || []).size < env_arg.arity
(@parsed[env_arg.name] ||= []) << value
(@parsed[env_arg.name] ||= []) << ParamConversion[env_arg, value]
else
@remaining << "#{env_arg.var}=#{value}"
end
else
@parsed[env_arg.name] = value
@parsed[env_arg.name] = ParamConversion[env_arg, value]
end
end
end # Environments
Expand Down
6 changes: 4 additions & 2 deletions lib/tty/option/parser/keywords.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative "../param_conversion"

module TTY
module Option
class Parser
Expand Down Expand Up @@ -95,12 +97,12 @@ def keyword?(value)
def assign_keyword(kwarg, value)
if kwarg.multiple?
if kwarg.arity < 0 || (@parsed[kwarg.name] || []).size < kwarg.arity
(@parsed[kwarg.name] ||= []) << value
(@parsed[kwarg.name] ||= []) << ParamConversion[kwarg, value]
else
@remaining << "#{kwarg.name}=#{value}"
end
else
@parsed[kwarg.name] = value
@parsed[kwarg.name] = ParamConversion[kwarg, value]
end
end
end # Keywords
Expand Down
71 changes: 54 additions & 17 deletions spec/unit/parse_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ def new_command(&block)
"expected argument :foo to appear at least 3 times but " \
"appeared 2 times")
end

it "reads one or more value and converts to map" do
cmd = new_command do
argument :foo do
arity one_or_more
convert :int_map
end
end

cmd.parse(%w[a:1 b:2 c:3])

expect(cmd.params[:foo]).to eq({a: 1, b: 2, c: 3})
end
end

context "keyword" do
Expand All @@ -163,44 +176,68 @@ def new_command(&block)
cmd.parse(%w[foo=x bar=12 foo=y])

expect(cmd.params[:foo]).to eq(%w[x y])
expect(cmd.params[:bar]).to eq("12")
expect(cmd.params[:bar]).to eq(12)
end

it "collects multiple keyword occurences and converts" do
cmd = new_command do
keyword(:foo) do
arity 2
convert :int
end

keyword(:bar) do
convert :int
end
end

cmd.parse(%w[foo=11 bar=12 foo=13])

expect(cmd.params[:foo]).to eq([11, 13])
expect(cmd.params[:bar]).to eq(12)
end
end

context "env" do
it "reads an env variable from command line" do
cmd = new_command do
env :foo
env(:foo) { convert :int }

env :bar
env(:bar) { convert :bools }

env(:baz) { var "FOOBAR" }
env(:baz) do
var "FOOBAR"
convert :sym
end

env(:qux) { default "x" }
env(:qux) do
default "x"
convert ->(val) { val.upcase }
end
end

cmd.parse(%w[FOOBAR=foobar BAR=true FOO=12])
cmd.parse(%w[FOOBAR=foobar BAR=t,f,t FOO=12])

expect(cmd.params[:foo]).to eq("12")
expect(cmd.params[:bar]).to eq("true")
expect(cmd.params[:baz]).to eq("foobar")
expect(cmd.params[:qux]).to eq("x")
expect(cmd.params[:foo]).to eq(12)
expect(cmd.params[:bar]).to eq([true, false, true])
expect(cmd.params[:baz]).to eq(:foobar)
expect(cmd.params[:qux]).to eq("X")
end

it "reads an env variable from ENV hash" do
cmd = new_command do
env :foo
env :foo, convert: :int

env :bar
env :bar, convert: :bools

env :baz, variable: "FOOBAR"
env :baz, variable: "FOOBAR", convert: :sym
end

cmd.parse([], {"FOO" => "12", "BAR" => "true", "FOOBAR" => "foobar"})
cmd.parse([], {"FOO" => "12", "BAR" => "t,f,t", "FOOBAR" => "foobar"})

expect(cmd.params[:foo]).to eq("12")
expect(cmd.params[:bar]).to eq("true")
expect(cmd.params[:baz]).to eq("foobar")
expect(cmd.params[:foo]).to eq(12)
expect(cmd.params[:bar]).to eq([true, false, true])
expect(cmd.params[:baz]).to eq(:foobar)
end
end
end
9 changes: 9 additions & 0 deletions spec/unit/parser/arguments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,13 @@ def parse(argv, args, **config)
expect(rest).to eq([])
end
end

context "when :convert" do
it "converts an argument to a list" do
params, rest = parse(%w[a,b,c], arg(:foo, convert: :list))

expect(params[:foo]).to eq(%w[a b c])
expect(rest).to eq([])
end
end
end
11 changes: 10 additions & 1 deletion spec/unit/parser/environments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,20 @@ def parse(argv, env, envs, **config)
expect(rest).to eq([])
end

it "defaults an env var" do
it "defaults an env var to proc result" do
params, rest = parse([], {}, env(:foo, default: -> { "bar" }))

expect(params[:foo]).to eq("bar")
expect(rest).to eq([])
end
end

context "when :convert" do
it "converts an argument to a list" do
params, rest = parse(%w[FOO=a,b,c], {}, env(:foo, convert: :list))

expect(params[:foo]).to eq(%w[a b c])
expect(rest).to eq([])
end
end
end
9 changes: 9 additions & 0 deletions spec/unit/parser/keywords_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,13 @@ def parse(argv, kwargs, **config)
expect(rest).to eq([])
end
end

context "when :convert" do
it "converts an argument to a list" do
params, rest = parse(%w[foo=a,b,c], keyword(:foo, convert: :list))

expect(params[:foo]).to eq(%w[a b c])
expect(rest).to eq([])
end
end
end

0 comments on commit 392c131

Please sign in to comment.