Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

11 changed files with 266 additions and 456 deletions

22
.gitignore vendored
View File

@ -1,5 +1,17 @@
/.yardoc/ *.gem
/coverage/ *.rbc
/doc/ .bundle
/pkg/ .config
/rdoc/ .yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp

1
.rspec
View File

@ -1,2 +1 @@
--color --color
--require spec_helper

View File

@ -1,46 +0,0 @@
PATH
remote: .
specs:
yawpa (1.2.0)
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.3)
docile (1.1.5)
json (2.1.0)
rake (12.0.0)
rdoc (5.1.0)
rspec (3.6.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
rspec-mocks (~> 3.6.0)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
simplecov (0.15.0)
docile (~> 1.1.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
yard (0.9.9)
PLATFORMS
ruby
DEPENDENCIES
rake
rdoc
rspec
simplecov
yard
yawpa!
BUNDLED WITH
1.10.6

152
README.md
View File

@ -2,124 +2,64 @@
Yet Another Way to Parse Arguments is an argument-parsing library for Ruby. Yet Another Way to Parse Arguments is an argument-parsing library for Ruby.
[![Gem Version](https://badge.fury.io/rb/yawpa.png)](http://badge.fury.io/rb/yawpa)
## Features ## Features
- POSIX or non-POSIX mode (supports subcommands using POSIX mode) - POSIX or non-POSIX mode (supports subcommands using POSIX mode)
- Options can require an arbitrary number of parameters - Options can require an arbitrary number of parameters
- Options can be defined with a range specifying the allowed number of parameters - Options can be defined with a range specifying the allowed number of parameters
## Installation
Add this line to your application's Gemfile:
gem 'yawpa'
And then execute:
$ bundle
Or install it yourself as:
$ gem install yawpa
## Example 1 ## Example 1
```ruby require 'yawpa'
require "yawpa"
options = { options = {
version: {}, version: {},
verbose: {short: "v"}, verbose: {short: 'v'},
get: {nargs: 1}, get: {nargs: 1},
set: {nargs: 2}, set: {nargs: 2},
} }
opts, args = Yawpa.parse(ARGV, options) opts, args = Yawpa.parse(ARGV, options)
opts.each_pair do |opt, val| opts.each_pair do |opt, val|
end end
```
## Example 2 ## Example 2
```ruby require 'yawpa'
require "yawpa"
options = { options = {
version: {}, version: {},
help: {short: "h"}, help: {short: 'h'},
} }
opts, args = Yawpa.parse(ARGV, options, posix_order: true) opts, args = Yawpa.parse(ARGV, options, posix_order: true)
if opts[:version] if opts[:version]
puts "my app, version 1.2.3" puts "my app, version 1.2.3"
end end
if args[0] == "subcommand" if args[0] == 'subcommand'
subcommand_options = { subcommand_options = {
"server": {nargs: (1..2), short: "s"}, 'server': {nargs: (1..2), short: 's'},
"dst": {nargs: 1, short: "d"}, 'dst': {nargs: 1, short: 'd'},
} }
opts, args = Yawpa.parse(args, subcommand_options) opts, args = Yawpa.parse(args, subcommand_options)
end end
```
## Using Yawpa.parse() ## Contributing
```ruby 1. Fork it
opts, args = Yawpa.parse(params, options, flags = {}) 2. Create your feature branch (`git checkout -b my-new-feature`)
``` 3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
Parse input parameters looking for options according to rules given in flags 5. Create new Pull Request
- `params` is the list of program parameters to parse.
- `options` is a hash containing the long option names as keys, and hashes
containing special flags for the options as values (example below).
Possible values:
- `nil`: No special flags for this option (equivalent to `{}`)
- `:boolean`: The option is a toggleable boolean option (equivalent to
`{boolean: true}`)
- `Hash`: Possible option flags:
- `:short`: specify a short option letter to associate with the long option
- `:nargs`: specify an exact number or range of possible numbers of
arguments to the option
- `:boolean`: if true, specify that the option is a toggleable boolean
option and allow a prefix of "no" to turn it off.
- `flags` is optional. It supports the following keys:
- `:posix_order`: Stop processing parameters when a non-option is seen.
Set this to `true` if you want to implement subcommands.
An ArgumentParsingException will be raised if an unknown option is observed
or insufficient arguments are present for an option.
### Example `options`
```ruby
{
version: nil,
verbose: {short: 'v'},
server: {nargs: (1..2)},
username: {nargs: 1},
password: {nargs: 1},
color: :boolean,
}
```
The keys of the `options` hash can be either strings or symbols.
Possible option flags:
- `:short`: specify a short option letter to associate with the long option
- `:nargs`: specify an exact number or range of possible numbers of
arguments to the option
- `:boolean`: if true, specify that the option is a toggleable boolean
option and allow a prefix of "no" to turn it off.
### Return values
The returned `opts` value will be a hash with the observed options as
keys and any option arguments as values.
The returned `args` will be an array of the unprocessed parameters (if
`:posix_order` was passed in `flags`, this array might contain further
options that were not processed after observing a non-option parameters).
## Release Notes
### v1.2.0
- Always return non-frozen strings
### v1.1.0
- Add `:boolean` option flag.
- Support `nil` or `:boolean` as shortcut option configuration values.
- Update documentation to YARD.
- Update specs to RSpec 3.
### v1.0.0
- Initial Release

13
Rakefile Normal file
View File

@ -0,0 +1,13 @@
require "bundler/gem_tasks"
require 'rspec/core/rake_task'
require "rdoc/task"
RSpec::Core::RakeTask.new('spec')
task :default => :spec
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Yet Another Way to Parse Arguments'
rdoc.rdoc_files.include('lib/**/*.rb')
end

View File

@ -1,18 +0,0 @@
require "bundler"
begin
Bundler.setup(:default, :development)
rescue Bundler::BundlerError => e
raise LoadError.new("Unable to setup Bundler; you might need to `bundle install`: #{e.message}")
end
require "bundler/gem_tasks"
require 'rspec/core/rake_task'
require "yard"
RSpec::Core::RakeTask.new('spec')
task :default => :spec
YARD::Rake::YardocTask.new do |yard|
yard.options = ["--title", "Yet Another Way to Parse Arguments"]
yard.files = ["lib/**/*.rb"]
end

View File

@ -7,196 +7,156 @@ require "yawpa/version"
# it just provides a simple functional interface for parsing options, # it just provides a simple functional interface for parsing options,
# supporting subcommands and arbitrary numbers of arguments for each option. # supporting subcommands and arbitrary numbers of arguments for each option.
# #
# Features: # == Features
#
# - POSIX or non-POSIX mode (supports subcommands using POSIX mode) # - POSIX or non-POSIX mode (supports subcommands using POSIX mode)
# - Options can require an arbitrary number of parameters # - Options can require an arbitrary number of parameters
# - Options can be defined with a range specifying the allowed number of # - Options can be defined with a range specifying the allowed number of parameters
# parameters
module Yawpa module Yawpa
# Exception class raised when an unknown option is observed
# Exception class raised when an unknown option is observed.
class ArgumentParsingException < Exception; end class ArgumentParsingException < Exception; end
class << self module_function
# :call-seq:
# Parse input parameters looking for options according to rules given in # opts, args = parse(params, options, flags = {})
# flags. #
# Syntax: # Parse input parameters looking for options according to rules given in flags
# opts, args = parse(params, options, flags = {}) #
# # - +params+ is the list of program parameters to parse.
# An ArgumentParsingException will be raised if an unknown option is # - +options+ is a hash containing the long option names as keys, and hashes
# observed or insufficient arguments are present for an option. # containing special flags for the options as values (example below).
# # - +flags+ is optional. It supports the following keys:
# Example +options+: # - +:posix_order+: Stop processing parameters when a non-option is seen.
# # Set this to +true+ if you want to implement subcommands.
# { #
# version: nil, # An ArgumentParsingException will be raised if an unknown option is observed
# verbose: {short: 'v'}, # or insufficient arguments are present for an option.
# server: {nargs: (1..2)}, #
# username: {nargs: 1}, # == Example +options+
# password: {nargs: 1}, #
# color: :boolean, # {
# } # version: {},
# # verbose: {short: 'v'},
# The keys of the +options+ Hash can be either strings or symbols. # server: {nargs: (1..2)},
# # username: {nargs: 1},
# # password: {nargs: 1},
# @param params [Array] # }
# List of program parameters to parse. #
# @param options [Hash] # The keys of the +options+ hash can be either strings or symbols.
# Hash containing the long option names as keys, and values containing #
# special flags for the options as values (examples above). # Options that have no special flags should have an empty hash as the value.
# Possible values: #
# +nil+:: No special flags for this option (equivalent to +{}+) # Possible option flags:
# +:boolean+:: # - +:short+: specify a short option letter to associate with the long option
# The option is a toggleable boolean option (equivalent to # - +:nargs+: specify an exact number or range of possible numbers of
# +{boolean: true}+) # arguments to the option
# Hash:: #
# Possible option flags: # == Return values
# - +:short+: specify a short option letter to associate with the long #
# option # The returned +opts+ value will be a hash with the observed options as
# - +:nargs+: specify an exact number or range of possible numbers of # keys and any option arguments as values.
# arguments to the option # The returned +args+ will be an array of the unprocessed parameters (if
# - +:boolean+: if true, specify that the option is a toggleable # +:posix_order+ was passed in +flags+, this array might contain further
# boolean option and allow a prefix of "no" to turn it off. # options that were not processed after observing a non-option parameters.
# @param flags [Hash] def parse(params, options, flags = {})
# Optional flags dictating how {.parse} should do its job. options = _massage_options(options)
# @option flags [Boolean] :posix_order opts = {}
# Stop processing parameters when a non-option argument is seen. args = []
# Set this to +true+ if you want to implement subcommands. i = 0
# while i < params.length
# @return [Array] param = params[i]
# Two-element array containing +opts+ and +args+ return values. if param =~ /^--([^=]+)(?:=(.+))?$/
# +opts+:: param_name, val = $1, $2
# The returned +opts+ value will be a Hash with the observed if options[param_name].nil?
# options as keys and any option arguments as values. raise ArgumentParsingException.new("Unknown option '#{param_name}'")
# +args+:: end
# The returned +args+ will be an Array of the unprocessed opt_config = options[param_name]
# parameters (if +:posix_order+ was passed in +flags+, this array might param_key = opt_config[:key]
# contain further options that were not processed after observing a if opt_config[:nargs].last == 0
# non-option parameters). opts[param_key] = true
def parse(params, options, flags = {}) else
options = _massage_options(options) opts[param_key] = []
opts = {} i += _gather(opt_config[:nargs], i + 1, params, val, param_key, opts[param_key])
args = [] end
i = 0 elsif param =~ /^-(.+)$/
while i < params.length short_flags = $1
param = params[i] short_idx = 0
if param =~ /^--([^=]+)(?:=(.+))?$/ while short_idx < short_flags.length
param_name, val = $1, $2 opt_config = _find_opt_config_by_short_name(options, short_flags[short_idx])
bool_val = true if opt_config.nil?
if options[param_name].nil? raise ArgumentParsingException.new("Unknown option '-#{short_flags[short_idx]}'")
if param_name =~ /^no(.*)$/
test_param_name = $1
if options[test_param_name]
param_name = test_param_name
bool_val = false
end
end
end end
opt_config = options[param_name]
raise ArgumentParsingException.new("Unknown option '#{param_name}'") unless opt_config
param_key = opt_config[:key] param_key = opt_config[:key]
if opt_config[:boolean] if opt_config[:nargs].last == 0
opts[param_key] = bool_val
elsif opt_config[:nargs].last == 0
opts[param_key] = true opts[param_key] = true
else else
opts[param_key] = [] opts[param_key] = []
i += _gather(opt_config[:nargs], i + 1, params, val, param_key, opts[param_key]) i += _gather(opt_config[:nargs], i + 1, params, short_flags[short_idx + 1, short_flags.length], param_key, opts[param_key])
break
end end
elsif param =~ /^-(.+)$/ short_idx += 1
short_flags = $1
short_idx = 0
while short_idx < short_flags.length
opt_config = _find_opt_config_by_short_name(options, short_flags[short_idx])
if opt_config.nil?
raise ArgumentParsingException.new("Unknown option '-#{short_flags[short_idx]}'")
end
param_key = opt_config[:key]
if opt_config[:nargs].last == 0
opts[param_key] = true
else
opts[param_key] = []
i += _gather(opt_config[:nargs],
i + 1,
params,
short_flags[short_idx + 1, short_flags.length],
param_key,
opts[param_key])
break
end
short_idx += 1
end
elsif flags[:posix_order]
args = params[i, params.length].map(&:dup)
break
else
args << params[i].dup
end end
i += 1 elsif flags[:posix_order]
args = params[i, params.length]
break
else
args << params[i]
end end
i += 1
# Condense 1-element arrays of option values to just the element itself
opts.each_key do |k|
if opts[k].is_a?(Array) and opts[k].length == 1
opts[k] = opts[k].first
end
end
return [opts, args]
end end
private # Condense 1-element arrays of option values to just the element itself
opts.each_key do |k|
# Internal helper method to gather arguments for an option if opts[k].class == Array and opts[k].length == 1
def _gather(nargs, start_idx, params, initial, param_key, result) opts[k] = opts[k].first
n_gathered = 0
if initial and initial != ''
result << initial
n_gathered += 1
end
num_indices_used = 0
index = start_idx
while n_gathered < nargs.last and
index < params.length and
params[index][0] != '-' do
result << params[index].dup
index += 1
num_indices_used += 1
n_gathered += 1
end
if n_gathered < nargs.first
raise ArgumentParsingException.new("Not enough arguments supplied for option '#{param_key}'")
end
num_indices_used
end
# Internal helper method to format the options in a consistent format
def _massage_options(options)
{}.tap do |newopts|
options.each_pair do |k, v|
v = {} if v.nil?
v = {boolean: true} if v == :boolean
newkey = k.to_s
newopts[newkey] = {key: k}
nargs = v[:nargs] || 0
nargs = (nargs..nargs) if nargs.is_a?(Integer)
newopts[newkey][:nargs] = nargs
newopts[newkey][:short] = v[:short] || ''
newopts[newkey][:boolean] = v[:boolean]
end
end end
end end
# Internal helper method to find an option configuration by short name return [opts, args]
def _find_opt_config_by_short_name(options, short_name)
options.each_pair do |k, v|
return v if v[:short] == short_name
end
nil
end
end end
# Internal helper method to gather arguments for an option
def _gather(nargs, start_idx, params, initial, param_key, result) # :nodoc:
n_gathered = 0
if initial and initial != ''
result << initial
n_gathered += 1
end
num_indices_used = 0
index = start_idx
while n_gathered < nargs.last and
index < params.length and
params[index][0] != '-' do
result << params[index]
index += 1
num_indices_used += 1
n_gathered += 1
end
if n_gathered < nargs.first
raise ArgumentParsingException.new("Not enough arguments supplied for option '#{param_key}'")
end
num_indices_used
end
# Internal helper method to format the options in a consistent format
def _massage_options(options) # :nodoc:
{}.tap do |newopts|
options.each_pair do |k, v|
newkey = k.to_s
newopts[newkey] = {key: k}
nargs = v[:nargs] || 0
nargs = (nargs..nargs) if nargs.class == Fixnum
newopts[newkey][:nargs] = nargs
newopts[newkey][:short] = v[:short] || ''
end
end
end
# Internal helper method to find an option configuration by short name
def _find_opt_config_by_short_name(options, short_name) # :nodoc:
options.each_pair do |k, v|
return v if v[:short] == short_name
end
nil
end
end end

View File

@ -1,4 +1,4 @@
module Yawpa module Yawpa
# gem version # gem version
VERSION = "1.3.0" VERSION = "1.0.0"
end end

View File

@ -1,7 +1,5 @@
require "simplecov" require 'bundler/setup'
require 'yawpa'
SimpleCov.start do RSpec.configure do |config|
add_filter "/spec/"
end end
require "yawpa"

View File

@ -1,31 +1,33 @@
require 'spec_helper'
describe Yawpa do describe Yawpa do
describe ".parse" do describe 'parse' do
it "returns everything as arguments when no options present" do it "returns everything as arguments when no options present" do
options = { } options = { }
params = ['one', 'two', 'three', 'four'] params = ['one', 'two', 'three', 'four']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts).to eq({}) opts.should eq({})
expect(args).to eq(params) args.should eq(params)
end end
it "raises an exception when an invalid option is passed" do it "raises an exception when an invalid option is passed" do
options = { } options = { }
params = ['one', '--option', 'two'] params = ['one', '--option', 'two']
expect { Yawpa.parse(params, options) }.to raise_error(Yawpa::ArgumentParsingException, /Unknown option/) expect { Yawpa.parse(params, options) }.to raise_error
end end
it "returns boolean options which are set" do it "returns boolean options which are set" do
options = { options = {
one: {}, one: {},
two: nil, two: {},
three: {}, three: {},
} }
params = ['--one', 'arg', '--two', 'arg2'] params = ['--one', 'arg', '--two', 'arg2']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts.include?(:one)).to be_truthy opts.include?(:one).should be_true
expect(opts.include?(:two)).to be_truthy opts.include?(:two).should be_true
expect(opts.include?(:three)).to be_falsey opts.include?(:three).should be_false
expect(args).to eq(['arg', 'arg2']) args.should eq(['arg', 'arg2'])
end end
it "returns an option's value when nargs = 1" do it "returns an option's value when nargs = 1" do
@ -34,8 +36,8 @@ describe Yawpa do
} }
params = ['--opt', 'val', 'arg'] params = ['--opt', 'val', 'arg']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:opt]).to eq('val') opts[:opt].should eq('val')
expect(args).to eq(['arg']) args.should eq(['arg'])
end end
it "returns an option's values when nargs = 2" do it "returns an option's values when nargs = 2" do
@ -44,8 +46,8 @@ describe Yawpa do
} }
params = ['--opt', 'val1', 'val2'] params = ['--opt', 'val1', 'val2']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:opt]).to eq(['val1', 'val2']) opts[:opt].should eq(['val1', 'val2'])
expect(args).to be_empty args.should be_empty
end end
it "raises an exception when not enough arguments for an option are given" do it "raises an exception when not enough arguments for an option are given" do
@ -53,7 +55,7 @@ describe Yawpa do
opt: {nargs: 2}, opt: {nargs: 2},
} }
params = ['--opt', 'val'] params = ['--opt', 'val']
expect { Yawpa.parse(params, options) }.to raise_error(Yawpa::ArgumentParsingException, /Not enough arguments supplied/) expect { Yawpa.parse(params, options) }.to raise_error
end end
it "uses --opt=val syntax for an option's value" do it "uses --opt=val syntax for an option's value" do
@ -62,8 +64,8 @@ describe Yawpa do
} }
params = ['--opt=thevalue', 'arg'] params = ['--opt=thevalue', 'arg']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:opt]).to eq('thevalue') opts[:opt].should eq('thevalue')
expect(args).to eq(['arg']) args.should eq(['arg'])
end end
it "uses --opt=val for the first option argument when nargs > 1" do it "uses --opt=val for the first option argument when nargs > 1" do
@ -72,8 +74,8 @@ describe Yawpa do
} }
params = ['--opt=val1', 'val2', 'arg'] params = ['--opt=val1', 'val2', 'arg']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:opt]).to eq(['val1', 'val2']) opts[:opt].should eq(['val1', 'val2'])
expect(args).to eq(['arg']) args.should eq(['arg'])
end end
it "returns the last set value when an option is passed twice" do it "returns the last set value when an option is passed twice" do
@ -82,8 +84,8 @@ describe Yawpa do
} }
params = ['--opt', 'val1', 'arg1', '--opt', 'val2', 'arg2'] params = ['--opt', 'val1', 'arg1', '--opt', 'val2', 'arg2']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:opt]).to eq('val2') opts[:opt].should eq('val2')
expect(args).to eq(['arg1', 'arg2']) args.should eq(['arg1', 'arg2'])
end end
it "accepts strings as keys for option configuration" do it "accepts strings as keys for option configuration" do
@ -92,8 +94,8 @@ describe Yawpa do
} }
params = ['xxx', '--crazy-option', 'yyy', 'zzz'] params = ['xxx', '--crazy-option', 'yyy', 'zzz']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts['crazy-option']).to eq('yyy') opts['crazy-option'].should eq('yyy')
expect(args).to eq(['xxx', 'zzz']) args.should eq(['xxx', 'zzz'])
end end
it "accepts short options corresponding to a long option" do it "accepts short options corresponding to a long option" do
@ -102,8 +104,8 @@ describe Yawpa do
} }
params = ['-o', 'qqq'] params = ['-o', 'qqq']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:option]).to be_truthy opts[:option].should be_true
expect(args).to eq(['qqq']) args.should eq(['qqq'])
end end
it "returns option argument at next position for a short option" do it "returns option argument at next position for a short option" do
@ -112,8 +114,8 @@ describe Yawpa do
} }
params = ['-o', 'val', 'rrr'] params = ['-o', 'val', 'rrr']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:option]).to eq('val') opts[:option].should eq('val')
expect(args).to eq(['rrr']) args.should eq(['rrr'])
end end
it "returns option argument immediately following short option" do it "returns option argument immediately following short option" do
@ -122,8 +124,8 @@ describe Yawpa do
} }
params = ['-oval', 'rrr'] params = ['-oval', 'rrr']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:option]).to eq('val') opts[:option].should eq('val')
expect(args).to eq(['rrr']) args.should eq(['rrr'])
end end
it "handles globbed-together short options" do it "handles globbed-together short options" do
@ -135,11 +137,11 @@ describe Yawpa do
} }
params = ['-abc', 'xyz'] params = ['-abc', 'xyz']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:a]).to be_truthy opts[:a].should be_true
expect(opts[:b]).to be_truthy opts[:b].should be_true
expect(opts[:c]).to be_truthy opts[:c].should be_true
expect(opts[:d]).to be_nil opts[:d].should be_nil
expect(args).to eq(['xyz']) args.should eq(['xyz'])
end end
it "handles globbed-together short options with values following" do it "handles globbed-together short options with values following" do
@ -151,11 +153,11 @@ describe Yawpa do
} }
params = ['-abcfoo', 'bar'] params = ['-abcfoo', 'bar']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:a]).to be_truthy opts[:a].should be_true
expect(opts[:b]).to be_truthy opts[:b].should be_true
expect(opts[:c]).to eq('foo') opts[:c].should eq('foo')
expect(opts[:d]).to be_nil opts[:d].should be_nil
expect(args).to eq(['bar']) args.should eq(['bar'])
end end
it "handles globbed-together short options with multiple values following" do it "handles globbed-together short options with multiple values following" do
@ -167,11 +169,11 @@ describe Yawpa do
} }
params = ['-abcfoo', 'bar', 'baz'] params = ['-abcfoo', 'bar', 'baz']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:a]).to be_truthy opts[:a].should be_true
expect(opts[:b]).to be_truthy opts[:b].should be_true
expect(opts[:c]).to eq(['foo', 'bar', 'baz']) opts[:c].should eq(['foo', 'bar', 'baz'])
expect(opts[:d]).to be_nil opts[:d].should be_nil
expect(args).to be_empty args.should be_empty
end end
it "raises an error on an unknown short option" do it "raises an error on an unknown short option" do
@ -179,7 +181,7 @@ describe Yawpa do
a: {short: 'a'}, a: {short: 'a'},
} }
params = ['-ab'] params = ['-ab']
expect { Yawpa.parse(params, options) }.to raise_error(Yawpa::ArgumentParsingException, /Unknown option/) expect { Yawpa.parse(params, options) }.to raise_error
end end
it "raises an error when not enough arguments are given to short option" do it "raises an error when not enough arguments are given to short option" do
@ -187,7 +189,7 @@ describe Yawpa do
a: {nargs: 1, short: 'a'}, a: {nargs: 1, short: 'a'},
} }
params = ['-a'] params = ['-a']
expect { Yawpa.parse(params, options) }.to raise_error(Yawpa::ArgumentParsingException, /Not enough arguments supplied/) expect { Yawpa.parse(params, options) }.to raise_error
end end
it "overwrites option value when short option used after long" do it "overwrites option value when short option used after long" do
@ -196,66 +198,20 @@ describe Yawpa do
} }
params = ['--option', 'VALUE', '-o', 'NEW_VALUE'] params = ['--option', 'VALUE', '-o', 'NEW_VALUE']
opts, args = Yawpa.parse(params, options) opts, args = Yawpa.parse(params, options)
expect(opts[:option]).to eq('NEW_VALUE') opts[:option].should eq('NEW_VALUE')
expect(args).to be_empty args.should be_empty
end end
it "ignores options after arguments in posix_order mode" do it "ignores options after arguments in posix_order mode" do
options = { options = {
one: {}, one: {},
two: nil, two: {},
} }
params = ['--one', 'arg', '--two'] params = ['--one', 'arg', '--two']
opts, args = Yawpa.parse(params, options, posix_order: true) opts, args = Yawpa.parse(params, options, posix_order: true)
expect(opts[:one]).to be_truthy opts[:one].should be_true
expect(opts[:two]).to be_falsey opts[:two].should be_false
expect(args).to eq(['arg', '--two']) args.should eq(['arg', '--two'])
end
it "supports :boolean option flag" do
options = {
push: :boolean,
pull: {boolean: true},
}
opts, args = Yawpa.parse(%w[hi], options)
expect(opts).to eq({})
expect(args).to eq(%w[hi])
opts, args = Yawpa.parse(%w[--push one two], options)
expect(opts).to eq(push: true)
expect(args).to eq(%w[one two])
opts, args = Yawpa.parse(%w[arg --nopush --pull], options)
expect(opts).to eq(push: false, pull: true)
expect(args).to eq(%w[arg])
end
it "returns non-frozen strings" do
options = {
o1: {nargs: 1, short: "1"},
o2: {nargs: 1, short: "2"},
o3: {nargs: 1, short: "3"},
o4: {nargs: 1, short: "4"},
}
arguments = %w[--o1=one --o2 two -3 three -4four arg].map(&:freeze)
opts, args = Yawpa.parse(arguments, options)
expect(opts[:o1].frozen?).to be_falsey
expect{opts[:o1].sub!(/./, '-')}.to_not raise_error
expect(opts[:o2].frozen?).to be_falsey
expect{opts[:o2].sub!(/./, '-')}.to_not raise_error
expect(opts[:o3].frozen?).to be_falsey
expect{opts[:o3].sub!(/./, '-')}.to_not raise_error
expect(opts[:o4].frozen?).to be_falsey
expect{opts[:o4].sub!(/./, '-')}.to_not raise_error
expect(args[0].frozen?).to be_falsey
expect{args[0].sub!(/./, '-')}.to_not raise_error
opts, args = Yawpa.parse(arguments, options, posix_order: true)
expect(args[0].frozen?).to be_falsey
expect{args[0].sub!(/./, '-')}.to_not raise_error
end end
end end
end end

View File

@ -15,9 +15,5 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"] gem.require_paths = ["lib"]
gem.version = Yawpa::VERSION gem.version = Yawpa::VERSION
gem.add_development_dependency "rspec" gem.add_development_dependency 'rspec'
gem.add_development_dependency "simplecov"
gem.add_development_dependency "rake"
gem.add_development_dependency "rdoc"
gem.add_development_dependency "yard"
end end