optionable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05abcff0632b217f377d6b25eca962591f2e6b0f
4
+ data.tar.gz: c64a040f884e222841a93e796194e3648b17aeab
5
+ SHA512:
6
+ metadata.gz: c9a204f1685ea3090b229f4d54e5c926d99b9810d75cb3d76a3ae28c59da5768363d34942e2a62bddbfbf601f1976aed9ad40de91249b3bd8338815256161a14
7
+ data.tar.gz: f5655b60fb44aaf901a63d2abcf41bd3be2aaca506fb72d0a67dbbbb250eb50df49d0107218ebdbd92b6dbbb684cca70cb8e0eb1c7f4e6fd53d9f72564b97a97
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Durran Jordan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ BSON [![Build Status](https://secure.travis-ci.org/durran/optionable.png?branch=master&.png)](http://travis-ci.org/durran/optionable) [![Code Climate](https://codeclimate.com/github/durran/optionable.png)](https://codeclimate.com/github/durran/optionable) [![Coverage Status](https://coveralls.io/repos/durran/optionable/badge.png?branch=master)](https://coveralls.io/r/durran/optionable?branch=master)
2
+ ====
3
+
4
+ Robust validation of options passed to Ruby methods.
5
+
6
+ Compatibility
7
+ -------------
8
+
9
+ BSON is tested against MRI (1.9.2+), JRuby (1.7.0+), Rubinius (2.0.0+).
10
+
11
+ Installation
12
+ ------------
13
+
14
+ With bundler, add the `optionable` gem to your `Gemfile`.
15
+
16
+ ```ruby
17
+ gem "optionable",
18
+ ```
19
+
20
+ Require the `optionable` gem in your application.
21
+
22
+ ```ruby
23
+ require "optionable"
24
+ ```
25
+
26
+ Usage
27
+ -----
28
+
29
+ Include the optional module in your object, and use the DSL for define what values
30
+ are valid for the specified options. Currently you can match on exact values or
31
+ values of a specific type. Then to validate your options, simply call `validate_strict`
32
+ and pass it the hash of options.
33
+
34
+ ```ruby
35
+ class Parser
36
+ include Optionable
37
+
38
+ option(:streaming).allow(true, false)
39
+ option(:timeout).allow(Optionable.any(Integer))
40
+
41
+ def initialize(options = {})
42
+ validate_strict(options)
43
+ end
44
+ end
45
+ ```
46
+
47
+ If the options are invalid, an `Optionable::Invalid` error will be raised.
48
+
49
+
50
+ API Documentation
51
+ -----------------
52
+
53
+ The [API Documentation](http://rdoc.info/github/durran/optionable/master/frames) is
54
+ located at rdoc.info.
55
+
56
+ Versioning
57
+ ----------
58
+
59
+ This project adheres to the [Semantic Versioning Specification](http://semver.org/).
60
+
61
+ License
62
+ -------
63
+
64
+ Copyright (c) 2013 Durran Jordan
65
+
66
+ Permission is hereby granted, free of charge, to any person obtaining
67
+ a copy of this software and associated documentation files (the
68
+ "Software"), to deal in the Software without restriction, including
69
+ without limitation the rights to use, copy, modify, merge, publish,
70
+ distribute, sublicense, and/or sell copies of the Software, and to
71
+ permit persons to whom the Software is furnished to do so, subject to
72
+ the following conditions:
73
+
74
+ The above copyright notice and this permission notice shall be
75
+ included in all copies or substantial portions of the Software.
76
+
77
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
78
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
79
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
80
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
81
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
82
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
83
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require "rake"
5
+ require "rspec/core/rake_task"
6
+
7
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
+ require "optionable/version"
9
+
10
+ task :gem => :build
11
+ task :build do
12
+ system "gem build optionable.gemspec"
13
+ end
14
+
15
+ task :install => :build do
16
+ system "sudo gem install optionable-#{Optionable::VERSION}.gem"
17
+ end
18
+
19
+ task :release => :build do
20
+ system "git tag -a v#{Optionable::VERSION} -m 'Tagging #{Optionable::VERSION}'"
21
+ system "git push --tags"
22
+ system "gem push optionable-#{Optionable::VERSION}.gem"
23
+ system "rm optionable-#{Optionable::VERSION}.gem"
24
+ end
25
+
26
+ RSpec::Core::RakeTask.new("spec") do |spec|
27
+ spec.pattern = "spec/**/*_spec.rb"
28
+ end
29
+
30
+ task :default => :spec
data/lib/optionable.rb ADDED
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+ require "optionable/any"
3
+ require "optionable/dsl"
4
+ require "optionable/invalid"
5
+ require "optionable/validator"
6
+ require "optionable/version"
7
+
8
+ # This module is to be included in objects that require some nifty options
9
+ # validation.
10
+ #
11
+ # @since 0.0.0
12
+ module Optionable
13
+
14
+ # Validate the provided options against the defined acceptable values.
15
+ #
16
+ # @example Validate the options.
17
+ # optionable.validate_strict(read: "test")
18
+ #
19
+ # @param [ Hash ] options The options to validate.
20
+ #
21
+ # @raise [ Optionable::Invalid ] If the options are wack.
22
+ #
23
+ # @since 0.0.0
24
+ def validate_strict(options)
25
+ (options || {}).each_pair do |key, value|
26
+ validator = optionable_validators[key]
27
+ validator.validate!(value) if validator
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Get the optionable validators from the class.
34
+ #
35
+ # @api private
36
+ #
37
+ # @since 0.0.0
38
+ def optionable_validators
39
+ self.class.optionable_validators
40
+ end
41
+
42
+ class << self
43
+
44
+ # Provides a convenience method for creating a new option acceptance for
45
+ # values of a certain type.
46
+ #
47
+ # @example Create the any type.
48
+ # Optionable.any(Integer)
49
+ #
50
+ # @param [ Class ] type The type of supported value.
51
+ #
52
+ # @since 0.0.0
53
+ def any(type)
54
+ Any.new(type)
55
+ end
56
+
57
+ private
58
+
59
+ # Extend the DSL methods when the module is included.
60
+ #
61
+ # @api private
62
+ #
63
+ # @since 0.0.0
64
+ def included(klass)
65
+ klass.extend(DSL)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ module Optionable
3
+
4
+ # Represents an option that can be of any value of a certain type.
5
+ #
6
+ # @since 0.0.0
7
+ class Any
8
+
9
+ # @!attribute type
10
+ # @return [ Class ] The class type.
11
+ attr_reader :type
12
+
13
+ # Check equality of the value for this type.
14
+ #
15
+ # @example Check if the value equals this type.
16
+ # any == 10
17
+ #
18
+ # @param [ Object ] other The object to check against.
19
+ #
20
+ # @since 0.0.0
21
+ def ==(other)
22
+ other.is_a?(type)
23
+ end
24
+
25
+ # Initialize the new any value object.
26
+ #
27
+ # @example Initialize the any value object.
28
+ # Optionable::Any.new(Integer)
29
+ #
30
+ # @param [ Class ] type The class type.
31
+ #
32
+ # @since 0.0.0
33
+ def initialize(type)
34
+ @type = type
35
+ end
36
+
37
+ # Return the pretty inspected type.
38
+ #
39
+ # @example Get the any as an inspection.
40
+ # any.inspect
41
+ #
42
+ # @return [ String ] any + the class type.
43
+ #
44
+ # @since 0.0.0
45
+ def inspect
46
+ "any #{type}"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ module Optionable
3
+
4
+ # Provides the entry point to the optionable DSL.
5
+ #
6
+ # @since 0.0.0
7
+ module DSL
8
+
9
+ # Defines an option to be validated.
10
+ #
11
+ # @example Define the option.
12
+ # option(:read).allow(:primary, :secondary)
13
+ #
14
+ # @param [ Symbol ] key The name of the option.
15
+ #
16
+ # @return [ Optionable::Validator ] The associated validator for the option.
17
+ #
18
+ # @since 0.0.0
19
+ def option(key)
20
+ optionable_validators[key] ||= Validator.new(key)
21
+ end
22
+
23
+ # Get all the validators for all options.
24
+ #
25
+ # @example Get all the validators.
26
+ # dsl.optionable_validators
27
+ #
28
+ # @return [ Hash<Symbol, Optionable::Validator> ] The validators.
29
+ #
30
+ # @since 0.0.0
31
+ def optionable_validators
32
+ @optionable_validators ||= {}
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ module Optionable
3
+
4
+ # This exception is raised whenever invalid options are found during
5
+ # validation.
6
+ #
7
+ # @since 0.0.0
8
+ class Invalid < RuntimeError
9
+
10
+ # @!attribute key
11
+ # @return [ Symbol ] The name of the option.
12
+ # @!attribute value
13
+ # @return [ Object ] The value provided for the option.
14
+ # @!attribute allowed
15
+ # @return [ Array<Object> ] The allowed values for the option.
16
+ attr_reader :key, :value, :allowed
17
+
18
+ # Initialize the Invalid option exception.
19
+ #
20
+ # @example Initialize the exception.
21
+ # Optionable::Invalid.new(:test, 10, [ 11, 12 ])
22
+ #
23
+ # @param [ Symbol ] key The name of the option.
24
+ # @param [ Object ] value The value provided for the option.
25
+ # @param [ Array<Object> ] allowed The allowed values for the option.
26
+ #
27
+ # @since 0.0.0
28
+ def initialize(key, value, allowed)
29
+ @key = key
30
+ @value = value
31
+ @allowed = allowed
32
+ super(generate_message)
33
+ end
34
+
35
+ private
36
+
37
+ # Generate the message that will be used in the exception.
38
+ #
39
+ # @api private
40
+ #
41
+ # @since 0.0.0
42
+ def generate_message
43
+ "#{value.inspect} is not acceptable for option #{key.inspect}. " +
44
+ "Valid values are: #{allowed.map(&:inspect).join(", ")}."
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ module Optionable
3
+
4
+ # This is responsible for the actual validation of the options.
5
+ #
6
+ # @since 0.0.0
7
+ class Validator
8
+
9
+ # @!attribute key
10
+ # @return [ Symbol ] The name of the option.
11
+ attr_reader :key
12
+
13
+ # Tells the validator what values are acceptable for the option.
14
+ #
15
+ # @example Specify allowed values.
16
+ # validator.allow(:test, :testing)
17
+ #
18
+ # @param [ Array<Object> ] values The allowed values.
19
+ #
20
+ # @return [ Array<Object> ] The full list of allowed values.
21
+ #
22
+ # @since 0.0.0
23
+ def allow(*values)
24
+ allowed_values.concat(values)
25
+ end
26
+
27
+ # Initialize the new validator.
28
+ #
29
+ # @example Initialize the validator.
30
+ # Optionable::Validator.new(:test)
31
+ #
32
+ # @param [ Symbol ] key The name of the option.
33
+ #
34
+ # @since 0.0.0
35
+ def initialize(key)
36
+ @key = key
37
+ end
38
+
39
+ # Validate the provided value against the acceptable values.
40
+ #
41
+ # @example Validate the provided value.
42
+ # validator.validate!("test")
43
+ #
44
+ # @param [ Object ] value The value for the option.
45
+ #
46
+ # @raise [ Optionable::Invalid ] If the value is invalid.
47
+ #
48
+ # @since 0.0.0
49
+ def validate!(value)
50
+ raise Invalid.new(key, value, allowed_values) unless match?(value)
51
+ end
52
+
53
+ private
54
+
55
+ # Get the allowed values for the option.
56
+ #
57
+ # @api private
58
+ #
59
+ # @since 0.0.0
60
+ def allowed_values
61
+ @allowed_values ||= []
62
+ end
63
+
64
+ # Does the value match an allowed value?
65
+ #
66
+ # @api private
67
+ #
68
+ # @since 0.0.0
69
+ def match?(value)
70
+ allowed_values.any? do |allowed|
71
+ value == allowed
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module Optionable
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Optionable::Any do
4
+
5
+ describe "#==" do
6
+
7
+ let(:any) do
8
+ described_class.new(Integer)
9
+ end
10
+
11
+ context "when the value is of the correct type" do
12
+
13
+ it "returns true" do
14
+ expect(any).to eq(10)
15
+ end
16
+ end
17
+
18
+ context "when the value is an incorrect type" do
19
+
20
+ it "returns false" do
21
+ expect(any).to_not eq(10.5)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#initialize" do
27
+
28
+ let(:any) do
29
+ described_class.new(Integer)
30
+ end
31
+
32
+ it "sets the type" do
33
+ expect(any.type).to eq(Integer)
34
+ end
35
+ end
36
+
37
+ describe "#inspect" do
38
+
39
+ let(:any) do
40
+ described_class.new(Integer)
41
+ end
42
+
43
+ it "returns any + the name of the class" do
44
+ expect(any.inspect).to eq("any Integer")
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe Optionable::Invalid do
4
+
5
+ describe "#message" do
6
+
7
+ context "when a single value is provided" do
8
+
9
+ let(:invalid) do
10
+ described_class.new(:test, 10, [ 15 ])
11
+ end
12
+
13
+ it "returns the single value error message" do
14
+ expect(invalid.message).to eq(
15
+ "10 is not acceptable for option :test. Valid values are: 15."
16
+ )
17
+ end
18
+ end
19
+
20
+ context "when multiple values are provided" do
21
+
22
+ let(:invalid) do
23
+ described_class.new(:test, 10, [ 15, "something" ])
24
+ end
25
+
26
+ it "returns the single value error message" do
27
+ expect(invalid.message).to eq(
28
+ "10 is not acceptable for option :test. Valid values are: 15, \"something\"."
29
+ )
30
+ end
31
+ end
32
+
33
+ context "when multiple values are provided with type" do
34
+
35
+ let(:invalid) do
36
+ described_class.new(:test, "test", [ Optionable.any(Integer) ])
37
+ end
38
+
39
+ it "returns the single value error message" do
40
+ expect(invalid.message).to eq(
41
+ "\"test\" is not acceptable for option :test. Valid values are: any Integer."
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,89 @@
1
+ require "spec_helper"
2
+
3
+ describe Optionable::Validator do
4
+
5
+ describe "#allow" do
6
+
7
+ let(:validator) do
8
+ described_class.new(:test)
9
+ end
10
+
11
+ let(:allowed) do
12
+ validator.send(:allowed_values)
13
+ end
14
+
15
+ context "when no values exist" do
16
+
17
+ before do
18
+ validator.allow(:test)
19
+ end
20
+
21
+ it "sets the valid options" do
22
+ expect(allowed).to eq([ :test ])
23
+ end
24
+ end
25
+
26
+ context "when sending multiple values" do
27
+
28
+ before do
29
+ validator.allow(:test, :testing)
30
+ end
31
+
32
+ it "sets the valid options" do
33
+ expect(allowed).to eq([ :test, :testing ])
34
+ end
35
+ end
36
+
37
+ context "when existing values are present" do
38
+
39
+ before do
40
+ validator.allow(:test)
41
+ validator.allow(:testing)
42
+ end
43
+
44
+ it "sets the valid options" do
45
+ expect(allowed).to eq([ :test, :testing ])
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#initialize" do
51
+
52
+ let(:validator) do
53
+ described_class.new(:test)
54
+ end
55
+
56
+ it "sets the key of the option" do
57
+ expect(validator.key).to eq(:test)
58
+ end
59
+ end
60
+
61
+ describe "#validate!" do
62
+
63
+ let(:validator) do
64
+ described_class.new(:test)
65
+ end
66
+
67
+ context "when the value is acceptable" do
68
+
69
+ before do
70
+ validator.allow(:testing)
71
+ end
72
+
73
+ it "raises no error" do
74
+ expect {
75
+ validator.validate!(:testing)
76
+ }.to_not raise_error
77
+ end
78
+ end
79
+
80
+ context "when the value is invalid" do
81
+
82
+ it "raises an error" do
83
+ expect {
84
+ validator.validate!(:testing)
85
+ }.to raise_error(Optionable::Invalid)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+
3
+ describe Optionable do
4
+
5
+ before(:all) do
6
+ class Model
7
+ include Optionable
8
+
9
+ option(:read).allow(:primary, :secondary)
10
+ option(:write).allow(Optionable.any(Integer))
11
+ option(:update).allow(int: Optionable.any(Integer))
12
+ option(:update).allow(str: "exact")
13
+ option(:update).allow(flt: 10.5)
14
+
15
+ def initialize(options = {})
16
+ validate_strict(options)
17
+ end
18
+ end
19
+ end
20
+
21
+ after(:all) do
22
+ Object.send(:remove_const, :Model)
23
+ end
24
+
25
+ describe "#validate_strict" do
26
+
27
+ context "when options are empty" do
28
+
29
+ it "does not raise an error" do
30
+ expect {
31
+ Model.new
32
+ }.to_not raise_error
33
+ end
34
+ end
35
+
36
+ context "when options are nil" do
37
+
38
+ it "does not raise an error" do
39
+ expect {
40
+ Model.new(nil)
41
+ }.to_not raise_error
42
+ end
43
+ end
44
+
45
+ context "when the options are valid" do
46
+
47
+ context "when options are allowed specific values" do
48
+
49
+ it "does not raise an error for any value" do
50
+ expect {
51
+ Model.new(read: :primary)
52
+ Model.new(read: :secondary)
53
+ }.to_not raise_error
54
+ end
55
+ end
56
+
57
+ context "when options allow types" do
58
+
59
+ it "does not raise an error for correct type" do
60
+ expect {
61
+ Model.new(write: 10)
62
+ }.to_not raise_error
63
+ end
64
+ end
65
+
66
+ context "when options are mixed" do
67
+
68
+ it "does not raise an error for correct type" do
69
+ expect {
70
+ Model.new(update: { int: 10 })
71
+ }.to_not raise_error
72
+ end
73
+
74
+ it "does not raise an error for correct value" do
75
+ expect {
76
+ Model.new(update: { str: "exact" })
77
+ }.to_not raise_error
78
+ end
79
+ end
80
+ end
81
+
82
+ context "when the options are not valid" do
83
+
84
+ context "when options are allowed specific values" do
85
+
86
+ it "raises an error for any bad value" do
87
+ expect {
88
+ Model.new(read: :tertiary)
89
+ }.to raise_error(Optionable::Invalid)
90
+ end
91
+ end
92
+
93
+ context "when options allow types" do
94
+
95
+ it "raises an error for incorrect type" do
96
+ expect {
97
+ Model.new(write: 14.5)
98
+ }.to raise_error(Optionable::Invalid)
99
+ end
100
+ end
101
+
102
+ context "when options are mixed" do
103
+
104
+ it "raises an error for incorrect type" do
105
+ expect {
106
+ Model.new(update: { int: 14.5 })
107
+ }.to raise_error(Optionable::Invalid)
108
+ end
109
+
110
+ it "raises an error for incorrect value" do
111
+ expect {
112
+ Model.new(update: { str: "blah" })
113
+ }.to raise_error(Optionable::Invalid)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ if ENV["CI"]
5
+ require "simplecov"
6
+ require "coveralls"
7
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
8
+ SimpleCov.start do
9
+ add_filter "spec"
10
+ end
11
+ end
12
+
13
+ require "optionable"
14
+ require "rspec"
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: optionable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Durran Jordan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Robust options validation for methods.
14
+ email:
15
+ - durran@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/optionable/any.rb
21
+ - lib/optionable/dsl.rb
22
+ - lib/optionable/invalid.rb
23
+ - lib/optionable/validator.rb
24
+ - lib/optionable/version.rb
25
+ - lib/optionable.rb
26
+ - README.md
27
+ - LICENSE.md
28
+ - Rakefile
29
+ - spec/optionable/any_spec.rb
30
+ - spec/optionable/invalid_spec.rb
31
+ - spec/optionable/validator_spec.rb
32
+ - spec/optionable_spec.rb
33
+ - spec/spec_helper.rb
34
+ homepage:
35
+ licenses: []
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.9.2
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 1.3.6
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 2.0.3
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Robust options validation for methods.
57
+ test_files:
58
+ - spec/optionable/any_spec.rb
59
+ - spec/optionable/invalid_spec.rb
60
+ - spec/optionable/validator_spec.rb
61
+ - spec/optionable_spec.rb
62
+ - spec/spec_helper.rb