optioning 0.0.1.beta → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/README.md +106 -14
- data/examples/client_maroto.rb +6 -0
- data/examples/module_maroto.rb +20 -0
- data/lib/deprecation.rb +73 -0
- data/lib/optioning/version.rb +2 -2
- data/lib/optioning.rb +180 -2
- data/optioning.gemspec +1 -1
- data/test/deprecation_test.rb +92 -0
- data/test/optioning_test.rb +78 -0
- data/test/unrecognized_option_test.rb +60 -0
- metadata +20 -10
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTNiNDg2OWNhZTkwNDIwYTk1MGYzYTBmMzQyMmU0ZTZjZmIyYmE4OA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Nzc3YjdmYjNjOTYwOGZlMDg0MmRkNWM4ODA4OTI5MjczNGM0MWFiMw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDYyYTI5YWNhZDUwYTBlNGJiMjFhMDEyZTRlOWFlZDFlOGNkOGRiMDgxMzRi
|
10
|
+
MTk0NjAwMWFkY2U4ZWYxMjM4MzE1NWM3NWQyOGViZDgyYTNmM2E2ODk0OTRi
|
11
|
+
MjM5YjBmNDg0ZjY0YTJlYjlmN2RlMTg4NzU5NDcwYzkwZGRjMjk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTA3YWY5MGU3MDQ1MjdhY2UyMzI0MmI0ZjI4ZTk3YTNiODdlNTE1OWM4Yzhj
|
14
|
+
Mjg0YzQ2YzQ4ZjBiZGYzYmYxNmUzYTUxN2YxNWVmYjliYTg4NGNhMjhlOWU5
|
15
|
+
NzUzMjZjOTNlNjY1ZTg4YzJlMWE5MTQxNTQxMDE2MWZkZWIyZTk=
|
data/README.md
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# Optioning
|
2
2
|
|
3
3
|
An easy way to retrieve, store, filter, transform and deprecate `options` passed
|
4
|
-
to a method. Where `options` are the keys our beloved `Hash` as last parameter
|
5
|
-
|
4
|
+
to a method. Where `options` are the keys in our beloved `Hash` as last parameter
|
5
|
+
in a method call.
|
6
6
|
|
7
7
|
## Status
|
8
8
|
[](http://badge.fury.io/rb/hashing)
|
9
9
|
[](http://travis-ci.org/ricardovaleriano/hashing?branch=master)
|
10
10
|
[](https://codeclimate.com/github/ricardovaleriano/hashing)
|
11
|
+
[](http://inch-pages.github.io/github/ricardovaleriano/optioning)
|
11
12
|
|
12
13
|
## Installation
|
13
14
|
|
@@ -31,6 +32,54 @@ Or install it yourself as:
|
|
31
32
|
|
32
33
|
## Usage
|
33
34
|
|
35
|
+
### An "end to end" example
|
36
|
+
|
37
|
+
Given a `Hashing` module, with a `.hasherize` method like this:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
module Hashing
|
41
|
+
def hasherize(*values_and_options)
|
42
|
+
optioning = Optioning.new values_and_options
|
43
|
+
optioning.deprecate :to_hash, :to, "v2.0.0"
|
44
|
+
optioning.recognize :persist
|
45
|
+
optioning.process caller
|
46
|
+
|
47
|
+
puts "*" * 80
|
48
|
+
puts optioning.on :to
|
49
|
+
puts optioning.on :persist
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
And a `class` `Client` extending the `Hashing` and invoking the `.hasherize`
|
55
|
+
method like in this example:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require "./hashing"
|
59
|
+
class Client
|
60
|
+
extend Hashing
|
61
|
+
|
62
|
+
hasherize :some_ivar, to_hash: ->(){}, store: "NO!", persist: "I will persist!"
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
The following output will be generated:
|
67
|
+
|
68
|
+
```
|
69
|
+
NOTE: option `:to_hash` is deprecated; use `:to` instead. It will be removed on or after version v2.0.0.
|
70
|
+
Called from examples/client_maroto.rb:5:in `<class:Client>'.
|
71
|
+
NOTE: unrecognized option `:store` used.
|
72
|
+
You should use only the following: `:to`, `:persist`
|
73
|
+
Called from examples/client_maroto.rb:5:in `<class:Client>'.
|
74
|
+
********************************************************************************
|
75
|
+
#<Proc:0x007fd6f42749a8@examples/client_maroto.rb:5 (lambda)>
|
76
|
+
I will persist!
|
77
|
+
```
|
78
|
+
|
79
|
+
The warning messages will be written in the `$stderr`. Done! :smiley:
|
80
|
+
|
81
|
+
### A more step by step example
|
82
|
+
|
34
83
|
Given the following `File` class:
|
35
84
|
|
36
85
|
```ruby
|
@@ -85,13 +134,13 @@ methods:
|
|
85
134
|
|
86
135
|
```ruby
|
87
136
|
@options.raw
|
88
|
-
# => [:path, :commit, {to_hash: #<Proc:0x007fa4120bd318@(irb):
|
137
|
+
# => [:path, :commit, {to_hash: #<Proc:0x007fa4120bd318@(irb):42 (lambda)>}]
|
89
138
|
|
90
139
|
@options.values
|
91
140
|
# => [:path, :commit]
|
92
141
|
|
93
142
|
@options.on :to_hash
|
94
|
-
# => #<Proc:0x007fa4120bd318@(irb):
|
143
|
+
# => #<Proc:0x007fa4120bd318@(irb):42 (lambda)>
|
95
144
|
```
|
96
145
|
|
97
146
|
### Deprecating options
|
@@ -102,7 +151,7 @@ favor of the new `:to` option, you could do:
|
|
102
151
|
```ruby
|
103
152
|
def hasherize(*ivars_and_options)
|
104
153
|
@options = Optioning.new ivars_and_options
|
105
|
-
@options.deprecate :to_hash, :to
|
154
|
+
@options.deprecate :to_hash, :to
|
106
155
|
|
107
156
|
# ...
|
108
157
|
end
|
@@ -113,9 +162,9 @@ so you can do the following invocation to recover the value passed to the
|
|
113
162
|
deprecated `option`:
|
114
163
|
|
115
164
|
```ruby
|
116
|
-
@options.on :
|
165
|
+
@options.on :to
|
117
166
|
|
118
|
-
# => #<Proc:0x007fa4120bd318@(irb):
|
167
|
+
# => #<Proc:0x007fa4120bd318@(irb):42 (lambda)>
|
119
168
|
```
|
120
169
|
|
121
170
|
#### Deprecation warnings
|
@@ -127,17 +176,21 @@ method:
|
|
127
176
|
def hasherize(*ivars_and_options)
|
128
177
|
@options = Optioning.new ivars_and_options
|
129
178
|
@options.deprecate :to_hash, :to
|
130
|
-
@options.
|
179
|
+
@options.deprecation_warn
|
131
180
|
|
132
181
|
# ...
|
133
182
|
end
|
134
183
|
```
|
135
184
|
|
136
185
|
You can inform the date when the deprecation will not be available anymore.
|
137
|
-
These date will be
|
186
|
+
These date will be part of the deprecation message:
|
138
187
|
|
139
188
|
```ruby
|
140
|
-
@options.deprecate :to_hash, :to,
|
189
|
+
@options.deprecate :to_hash, :to, 2015, 05
|
190
|
+
@options.deprecation_warn
|
191
|
+
|
192
|
+
# => NOTE: option `:to_hash` is deprecated use `:to` instead. It will be
|
193
|
+
# removed on or after 2015-05-01."
|
141
194
|
```
|
142
195
|
|
143
196
|
Or if you prefer, you can specify a version of your software that pretend to
|
@@ -145,8 +198,39 @@ remove the deprecated thing:
|
|
145
198
|
|
146
199
|
```ruby
|
147
200
|
@options.deprecate :to_hash, :to, "v2.0.0"
|
201
|
+
@options.deprecation_warn
|
202
|
+
|
203
|
+
# => NOTE: option `:to_hash` is deprecated use `:to` instead. It will be
|
204
|
+
# removed on or after version v2.0.0"
|
148
205
|
```
|
149
206
|
|
207
|
+
And finally, you can add information about where te deprecated option was used
|
208
|
+
by passing the `caller` to the `deprecation_warn` method.
|
209
|
+
|
210
|
+
##### Caller info
|
211
|
+
|
212
|
+
Sometimes you will want to show information about where the call with the
|
213
|
+
deprecated option took place. If this is the case, you can pass the caller info
|
214
|
+
when instantiating the `Optioning`:
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
def hasherize(*ivars_and_options)
|
218
|
+
@options = Optioning.new ivars_and_options
|
219
|
+
@options.deprecate :to_hash, :to
|
220
|
+
@options.deprecated_warn caller
|
221
|
+
|
222
|
+
# ...
|
223
|
+
end
|
224
|
+
```
|
225
|
+
|
226
|
+
##### Calling a deprecated option
|
227
|
+
|
228
|
+
If you call a deprecated option, the return will be `nil`, and the deprecation
|
229
|
+
warning will be exhibited.
|
230
|
+
|
231
|
+
* [ ] maybe we should allow a deprecation strategy? To choose between warning
|
232
|
+
or exception when a deprecated options is called?
|
233
|
+
|
150
234
|
### Ignoring unrecongnized options
|
151
235
|
|
152
236
|
If you need, you could fitler the options to mantain just the recognized ones
|
@@ -157,19 +241,19 @@ the `#unrecognized_warn` method:
|
|
157
241
|
```ruby
|
158
242
|
def hasherize(*ivars_and_options)
|
159
243
|
@options = Optioning.new ivars_and_options
|
160
|
-
@options.recognize :
|
244
|
+
@options.recognize :from
|
161
245
|
@options.unrecognized_warn
|
162
246
|
|
163
247
|
# ...
|
164
248
|
end
|
165
249
|
```
|
166
250
|
|
167
|
-
Now, if a user pass an option different than the `:
|
251
|
+
Now, if a user pass an option different than the `:from` one, a warning will
|
168
252
|
inform that the option is not recognized and will be ignored.
|
169
253
|
|
170
254
|
#### Do I Need to register deprecated options as recognized?
|
171
255
|
|
172
|
-
|
256
|
+
Fortunately no. You just need to register your deprecations as usual:
|
173
257
|
|
174
258
|
```ruby
|
175
259
|
def hasherize(*ivars_and_options)
|
@@ -203,6 +287,14 @@ def hasherize(*ivars_and_options)
|
|
203
287
|
end
|
204
288
|
```
|
205
289
|
|
290
|
+
If you want the deprecation warning messages with the information about where
|
291
|
+
the deprecated options were passed, you can pass the `caller` info to the
|
292
|
+
`process` method:
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
@options.process caller
|
296
|
+
```
|
297
|
+
|
206
298
|
### Fluent interface
|
207
299
|
|
208
300
|
And finally, just for a matter of taste, `#deprecate`, `#recognize` and
|
@@ -220,7 +312,7 @@ end
|
|
220
312
|
|
221
313
|
## Contributing
|
222
314
|
|
223
|
-
1. Fork it ( http://github.com
|
315
|
+
1. Fork it ( http://github.com/ricardovaleriano/optioning/fork )
|
224
316
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
225
317
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
226
318
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
begin
|
2
|
+
require "optioning"
|
3
|
+
rescue LoadError => e
|
4
|
+
$:.unshift File.expand_path "../../lib", __FILE__
|
5
|
+
require "optioning"
|
6
|
+
end
|
7
|
+
|
8
|
+
module Maroto
|
9
|
+
def hasherize(*values_and_options)
|
10
|
+
optioning = Optioning.new values_and_options
|
11
|
+
optioning.deprecate :to_hash, :to, "v2.0.0"
|
12
|
+
optioning.recognize :persist
|
13
|
+
optioning.process caller
|
14
|
+
|
15
|
+
puts "\n"
|
16
|
+
puts "*" * 80
|
17
|
+
puts optioning.on :to
|
18
|
+
puts optioning.on :persist
|
19
|
+
end
|
20
|
+
end
|
data/lib/deprecation.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Represent a deprecated option.
|
2
|
+
# Util to store deprecated options for future reference.
|
3
|
+
class Deprecation
|
4
|
+
attr_reader :option, :replacement, :date, :version
|
5
|
+
attr_writer :caller
|
6
|
+
|
7
|
+
# Creates a representation of a {Deprecation}
|
8
|
+
#
|
9
|
+
# @example using a version as a deadline to deprecate
|
10
|
+
# deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
11
|
+
# deprecation.warn
|
12
|
+
# # => NOTE: option `:to_hash` is deprecated; use `:to` instead. It will be
|
13
|
+
# # removed on or after version v2.0.0.
|
14
|
+
#
|
15
|
+
# @example using a date (YYYY/MM) as a deadline to deprecate
|
16
|
+
# deprecation = Deprecation.new :to_hash, :to, 2015, 05
|
17
|
+
# deprecation.warn
|
18
|
+
# # => NOTE: option `:to_hash` is deprecated; use `:to` instead. It will be
|
19
|
+
# # removed on or after 2015-05-01.
|
20
|
+
#
|
21
|
+
# @example using the caller information to compose the warn message
|
22
|
+
# deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
23
|
+
# deprecation.warn
|
24
|
+
# deprecation.caller = caller
|
25
|
+
# # => NOTE: option `:to_hash` is deprecated; use `:to` instead. It will be
|
26
|
+
# # removed on or after version v2.0.0.
|
27
|
+
# # Called from examples/client_maroto.rb:5:in `<class:Client>'.
|
28
|
+
def initialize(option, replacement, version_or_year = nil, month = nil)
|
29
|
+
@option = option
|
30
|
+
@replacement = replacement
|
31
|
+
@date, @version = extract_date_and_version version_or_year, month
|
32
|
+
end
|
33
|
+
|
34
|
+
# Composes the deprecation message accordingly to date or version of
|
35
|
+
# deprecation. Also verifies (and show) the caller information.
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def warn
|
39
|
+
message = [ "NOTE: option `:#{@option}` is deprecated; use ",
|
40
|
+
"`:#{@replacement}` instead. ",
|
41
|
+
"It will be removed #{when_deprecation_occurs}."]
|
42
|
+
message << "\nCalled from #{@caller}." if @caller
|
43
|
+
message.join << "\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
# Decides if the parameters related to when a deprecation will occur are date
|
48
|
+
# or version based.
|
49
|
+
#
|
50
|
+
# @return [Array<Date, String>] the [Date] or version (string) for a deprecation
|
51
|
+
def extract_date_and_version(version_or_year, month)
|
52
|
+
date, version = nil, nil
|
53
|
+
if month.nil?
|
54
|
+
version = version_or_year
|
55
|
+
else
|
56
|
+
date = Date.new version_or_year, month, 1
|
57
|
+
end
|
58
|
+
[date, version]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a string ready to be used in a message, indicating when a
|
62
|
+
# deprecation will occur (based on date or version).
|
63
|
+
#
|
64
|
+
# @return [String]
|
65
|
+
def when_deprecation_occurs
|
66
|
+
if @date || @version
|
67
|
+
after = "on or after "
|
68
|
+
after += @date ? @date.strftime("%Y-%m-%d") : "version #{@version}"
|
69
|
+
else
|
70
|
+
"in a future version"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/optioning/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.1
|
1
|
+
class Optioning
|
2
|
+
VERSION = "0.0.1"
|
3
3
|
end
|
data/lib/optioning.rb
CHANGED
@@ -1,5 +1,183 @@
|
|
1
1
|
require "optioning/version"
|
2
|
+
require "deprecation"
|
2
3
|
|
3
|
-
|
4
|
-
#
|
4
|
+
class Optioning
|
5
|
+
# Receives a varargs to extract the values (anything before a last parameter
|
6
|
+
# `Hash`) and the options (last parameter instance_of `Hash`)
|
7
|
+
#
|
8
|
+
# These values can be retrieved using the methods {#values}, {#raw} and {#on}.
|
9
|
+
#
|
10
|
+
# @example a standard usage
|
11
|
+
# @options = Optioning.new :path, :commit, to_hash: ->(value) { value.upcase }
|
12
|
+
# @options.deprecate :to_hash, :to, Date.new(2015, 05, 01)
|
13
|
+
#
|
14
|
+
# @ivars = @options.values
|
15
|
+
# # => [:path, :commit]
|
16
|
+
#
|
17
|
+
# @to = @options.on :to
|
18
|
+
# # => #<Proc:0x8d99c54@(irb):42 (lambda)>
|
19
|
+
def initialize(args)
|
20
|
+
@args = args
|
21
|
+
@values = @args.dup
|
22
|
+
@options = @values.pop if @args.last.is_a? Hash
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return the value for a specific option
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# @option = Optioning.new [:path, :commit, stored_value: 42]
|
29
|
+
# @option.on :stored_value
|
30
|
+
# # => 42
|
31
|
+
#
|
32
|
+
# @param option [Symbol] (or Object used as an index) name of option to retrieve
|
33
|
+
# @return value for option passed as parameter
|
34
|
+
def on(option)
|
35
|
+
replace_deprecations
|
36
|
+
@options[option]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a deprecation for an option, stores info about it's replacement
|
40
|
+
# and time or version to its removal.
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# @option = Optioning.new :path, :commit, to_hash: ->(value) { value.upcase }
|
44
|
+
# @option.deprecate :to_hash, :to, Date.new(2015, 05, 01)
|
45
|
+
#
|
46
|
+
# @param option [Symbol] option to be deprecated
|
47
|
+
# @param replacement [Symbol] replacement option
|
48
|
+
# @param version_or_year version when the deprecation will be removed, if
|
49
|
+
# month is filled, this param will be treated as the year of replacement
|
50
|
+
# @param month [Integer] month when the deprecated option will be removed
|
51
|
+
# @return [Optioning] the current instance of optioning
|
52
|
+
def deprecate(option, replacement, version_or_year = nil, month = nil)
|
53
|
+
deprecations << Deprecation.new(option, replacement, version_or_year, month)
|
54
|
+
recognize(replacement)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Provides a way to inform which options can be used and which will be ignored
|
59
|
+
# by an instance of {Optioning}
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# @options = Optioning.new :path, :commit, to_hash: ->(value) { value.upcase }
|
63
|
+
# @options.deprecate :to_hash, :to, Date.new(2015, 05, 01)
|
64
|
+
#
|
65
|
+
# @param options [Array<Symbol>] all recognized options for the current {Optioning}
|
66
|
+
# @return [Optioning] the current {Optioning} instance
|
67
|
+
def recognize(*options)
|
68
|
+
@recognized ||= []
|
69
|
+
@recognized += options
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
# Issues all deprecation messages to the $stderr
|
74
|
+
#
|
75
|
+
# @param called_from [Array] expected to be the result of calling `caller`
|
76
|
+
# @return [Optioning] current {Optioning} instance
|
77
|
+
def deprecation_warn(called_from = nil)
|
78
|
+
set_caller_on_deprecations(called_from)
|
79
|
+
deprecations.select { |deprecation|
|
80
|
+
deprecated_but_used.include? deprecation.option
|
81
|
+
}.each { |deprecation| $stderr.write deprecation.warn }
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
# Issues all unrecognized messages and the recognized_options message to the $stderr
|
86
|
+
#
|
87
|
+
# @param called_from [Array<String>] the result of calling {Object#caller}
|
88
|
+
# @return [Optioning] the current {Optioning} instance
|
89
|
+
def unrecognized_warn(called_from = nil)
|
90
|
+
unrecognized_options.each do |unrecognized|
|
91
|
+
$stderr.write "NOTE: unrecognized option `:#{unrecognized}` used.\n"
|
92
|
+
end
|
93
|
+
recognized_options_warn called_from
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
# Issues the deprecation warnings and the unrecognized warnings.
|
98
|
+
# Let the current {Optioning} in a `ready to use` state.
|
99
|
+
#
|
100
|
+
# @param called_from [Array<String>] the result of calling {Object#caller}
|
101
|
+
# @return [Optioning] the current {Optioning} instance
|
102
|
+
def process(called_from = nil)
|
103
|
+
deprecation_warn called_from
|
104
|
+
unrecognized_warn called_from
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
# Return all values passed as varargs to the constructor.
|
109
|
+
#
|
110
|
+
# @return [Array] all values passed to the constructor
|
111
|
+
def raw
|
112
|
+
@args
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return all the values passed before the last one (if this one is a `Hash`
|
116
|
+
# instance).
|
117
|
+
#
|
118
|
+
# @return [Array] arguments that are not part of the options `Hash`
|
119
|
+
def values
|
120
|
+
@values
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
# Memoization for the `deprecations` created by invocations of {#deprecate}
|
125
|
+
#
|
126
|
+
# @return [Array<Deprecation>] all {Deprecation}s for these {Optioning} instance
|
127
|
+
def deprecations
|
128
|
+
@deprecations ||= []
|
129
|
+
end
|
130
|
+
|
131
|
+
# Memoization for the `recognized` options created by {#recognize}
|
132
|
+
#
|
133
|
+
# @return [Array<Symbol>] all options recognized by this {Optioning}
|
134
|
+
def recognized
|
135
|
+
@recognized ||= []
|
136
|
+
end
|
137
|
+
|
138
|
+
# Cleanup the options trashing up the deprecated options in favor the
|
139
|
+
# replacements.
|
140
|
+
#
|
141
|
+
# @return [Hash] @options already filtered
|
142
|
+
def replace_deprecations
|
143
|
+
deprecations.each do |deprecation|
|
144
|
+
@options[deprecation.replacement] = @options.delete deprecation.option
|
145
|
+
end
|
146
|
+
@options
|
147
|
+
end
|
148
|
+
|
149
|
+
# All unrecognized options used as parameter to an {Optioning}
|
150
|
+
#
|
151
|
+
# @return [Array<Symbol>] unrecognized options
|
152
|
+
def unrecognized_options
|
153
|
+
values = raw.dup
|
154
|
+
return [] unless values.last.is_a? Hash
|
155
|
+
options = values.pop
|
156
|
+
options.keys - (recognized + deprecations.map { |d| d.option.to_sym })
|
157
|
+
end
|
158
|
+
|
159
|
+
# Issues a message containing all the recognized options for an {Optioning}
|
160
|
+
#
|
161
|
+
# @param called_from [Array<String>] the result of calling {Kernel#caller}
|
162
|
+
def recognized_options_warn(called_from = nil)
|
163
|
+
recognized = @recognized.map { |option| "`:#{option}`" }
|
164
|
+
$stderr.write "You should use only the following: #{recognized.join(", ")}"
|
165
|
+
$stderr.write "\nCalled from #{called_from.first}." if called_from.respond_to? :first
|
166
|
+
end
|
167
|
+
|
168
|
+
# Configure the caller in all the deprecations for this instance
|
169
|
+
#
|
170
|
+
# @return [Array<Deprecations>]
|
171
|
+
def set_caller_on_deprecations(called_from)
|
172
|
+
return unless called_from.respond_to? :first
|
173
|
+
deprecations.each { |deprecation| deprecation.caller = called_from.first }
|
174
|
+
end
|
175
|
+
|
176
|
+
# All deprecated options that were passed to the constructor for this instance
|
177
|
+
# of {Optioning}
|
178
|
+
#
|
179
|
+
# @return [Array<Symbol>] deprecated options used in the construction of a {Optioning}
|
180
|
+
def deprecated_but_used
|
181
|
+
deprecations.map(&:option).select { |option| @options.include? option }
|
182
|
+
end
|
5
183
|
end
|
data/optioning.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["ricardo.valeriano@gmail.com"]
|
11
11
|
spec.summary = %q{An object oriented way to treat our beloved last parameter: Hash.}
|
12
12
|
spec.description = %q{An easy way to retrieve, store, filter and deprecate `options` passed to a method. Where `options` are the keys on our beloved `Hash` as last parameter for a method call.}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "http://github.com/ricardovaleriano/optioning"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
describe Deprecation do
|
2
|
+
let(:to_hash_lambda) { ->(value) { value } }
|
3
|
+
let(:optioning) { Optioning.new [:path, :commit, to_hash: to_hash_lambda] }
|
4
|
+
|
5
|
+
it "stores the option deprecated and the replacement" do
|
6
|
+
deprecation = Deprecation.new :to_hash, :to
|
7
|
+
deprecation.option.must_be :==, :to_hash
|
8
|
+
deprecation.replacement.must_be :==, :to
|
9
|
+
end
|
10
|
+
|
11
|
+
it "accepts the date of deprecation" do
|
12
|
+
deprecation = Deprecation.new :to_hash, :to, 2015, 3
|
13
|
+
deprecation.date.must_be :==, Date.new(2015, 03, 01)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "accepts a version of deprecation" do
|
17
|
+
deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
18
|
+
deprecation.version.must_be :==, "v2.0.0"
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#warn" do
|
22
|
+
it "without version or date" do
|
23
|
+
deprecation = Deprecation.new :to_hash, :to
|
24
|
+
deprecation.warn.must_be :==, "NOTE: option `:to_hash` is deprecated;"+
|
25
|
+
" use `:to` instead. It will be removed in a future version.\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the message to warn about deprecation" do
|
29
|
+
deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
30
|
+
deprecation.warn.must_be :==, "NOTE: option `:to_hash` is deprecated;"+
|
31
|
+
" use `:to` instead. It will be removed on or after version v2.0.0.\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "uses date to deprecate when it is available" do
|
35
|
+
deprecation = Deprecation.new :to_hash, :to, 2015, 3
|
36
|
+
deprecation.warn.must_be :==, "NOTE: option `:to_hash` is deprecated;"+
|
37
|
+
" use `:to` instead. It will be removed on or after 2015-03-01.\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "when caller is available" do
|
41
|
+
let(:deprecation) { Deprecation.new :to_hash, :to, "v2.0.0" }
|
42
|
+
before do
|
43
|
+
deprecation.caller = "/x/p/t/o/omg_lol_bbq.rb:42:in `hasherize'"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "deprecation message includes caller info" do
|
47
|
+
deprecation.warn.must_be :==, "NOTE: option `:to_hash` is deprecated;"+
|
48
|
+
" use `:to` instead. It will be removed on or after version v2.0.0.\n"+
|
49
|
+
"Called from /x/p/t/o/omg_lol_bbq.rb:42:in `hasherize'.\n"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Optioning do
|
55
|
+
describe "#deprecate" do
|
56
|
+
it "returns the instance of `Optioning`" do
|
57
|
+
optioning.deprecate(:to_hash, :to).must_be_same_as optioning
|
58
|
+
end
|
59
|
+
|
60
|
+
it "replaces the deprecate option" do
|
61
|
+
optioning.deprecate :to_hash, :to
|
62
|
+
optioning.on(:to).object_id.must_be :==, to_hash_lambda.object_id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#deprecation_warn" do
|
67
|
+
before do
|
68
|
+
@original_stderr, $stderr = $stderr, StringIO.new
|
69
|
+
optioning.deprecate :to_hash, :to, "v2.0.0"
|
70
|
+
end
|
71
|
+
|
72
|
+
after do
|
73
|
+
$stderr = @original_stderr
|
74
|
+
end
|
75
|
+
|
76
|
+
it "constructs a deprecation message accordingly to the arguments" do
|
77
|
+
optioning.deprecation_warn
|
78
|
+
deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
79
|
+
$stderr.string.must_be :==, deprecation.warn
|
80
|
+
end
|
81
|
+
|
82
|
+
it "uses the callee information to compose the warning message" do
|
83
|
+
optioning.deprecation_warn [
|
84
|
+
"examples/client_maroto.rb:5:in `<class:Client>'",
|
85
|
+
"examples/client_maroto.rb:2:in `<main>'"]
|
86
|
+
deprecation = Deprecation.new :to_hash, :to, "v2.0.0"
|
87
|
+
deprecation.caller = "examples/client_maroto.rb:5:in `<class:Client>'"
|
88
|
+
$stderr.string.must_be :==, deprecation.warn
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
describe Optioning do
|
2
|
+
let(:to_hash_lambda) { ->(value) { value } }
|
3
|
+
let(:optioning) { Optioning.new [:path, :commit, to_hash: to_hash_lambda] }
|
4
|
+
|
5
|
+
before do
|
6
|
+
@original_stderr, $stderr = $stderr, StringIO.new
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
$stderr = @original_stderr
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#process" do
|
14
|
+
let(:optioning) {
|
15
|
+
Optioning.new [:path, :commit,
|
16
|
+
old: "OH!",
|
17
|
+
from: ->(){},
|
18
|
+
omg: "O YEAH!",
|
19
|
+
wtf: "?"]
|
20
|
+
}
|
21
|
+
|
22
|
+
before do
|
23
|
+
optioning.deprecate :old, :new
|
24
|
+
optioning.deprecate :from_hash, :from
|
25
|
+
optioning.recognize :omg
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the instance of `Optioning`" do
|
29
|
+
optioning.process.must_be_same_as optioning
|
30
|
+
end
|
31
|
+
|
32
|
+
it "shows deprecations and unrecognized warnings" do
|
33
|
+
optioning.process
|
34
|
+
$stderr.string.must_be :==,[
|
35
|
+
"NOTE: option `:old` is deprecated;",
|
36
|
+
" use `:new` instead. It will be removed in a future version.\n",
|
37
|
+
|
38
|
+
"NOTE: unrecognized option `:wtf` used.",
|
39
|
+
"\nYou should use only the following: `:new`, `:from`, `:omg`"
|
40
|
+
].join
|
41
|
+
end
|
42
|
+
|
43
|
+
it "accepts the caller info as argument" do
|
44
|
+
optioning.process [
|
45
|
+
"examples/client_maroto.rb:5:in `<class:Client>'",
|
46
|
+
"examples/client_maroto.rb:2:in `<main>'"]
|
47
|
+
|
48
|
+
$stderr.string.must_be :==,[
|
49
|
+
"NOTE: option `:old` is deprecated;",
|
50
|
+
" use `:new` instead. It will be removed in a future version.\n",
|
51
|
+
"Called from examples/client_maroto.rb:5:in `<class:Client>'.\n",
|
52
|
+
|
53
|
+
"NOTE: unrecognized option `:wtf` used.",
|
54
|
+
"\nYou should use only the following: `:new`, `:from`, `:omg`\n",
|
55
|
+
"Called from examples/client_maroto.rb:5:in `<class:Client>'.",
|
56
|
+
].join
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#raw" do
|
61
|
+
it "transforms the var args passed to the constructor into an Array" do
|
62
|
+
optioning.raw.must_be :==, [:path, :commit, to_hash: to_hash_lambda]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#values" do
|
67
|
+
it "the arguments passed before the last one (if it is a `Hash`)" do
|
68
|
+
optioning.values.must_be :==, [:path, :commit]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#on" do
|
73
|
+
it "returns the value passed to specific option" do
|
74
|
+
# impossible to use lambda.must_be_same_as, maybe a bug?
|
75
|
+
optioning.on(:to_hash).object_id.must_be :==, to_hash_lambda.object_id
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
describe Optioning do
|
2
|
+
let(:optioning) {
|
3
|
+
Optioning.new [from: "xpto", to: "bbq", no_one_knows: "omg lol"]
|
4
|
+
}
|
5
|
+
|
6
|
+
before do
|
7
|
+
@original_stderr, $stderr = $stderr, StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
$stderr = @original_stderr
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#recognize" do
|
15
|
+
it "returns the instance of `Optioning`" do
|
16
|
+
optioning.recognize(:x).must_be_same_as optioning
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#unrecognized_warn" do
|
21
|
+
it "should not warning about a recognized option" do
|
22
|
+
optioning.recognize :from
|
23
|
+
optioning.unrecognized_warn
|
24
|
+
($stderr.string =~ /unrecognized option `:from`/).must_be :==, nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should warning about a unrecognized option" do
|
28
|
+
optioning.recognize :from, :to
|
29
|
+
optioning.unrecognized_warn
|
30
|
+
$stderr.string.must_be :==, "NOTE: unrecognized option `:no_one_knows` used."+
|
31
|
+
"\nYou should use only the following: `:from`, `:to`"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "not consider deprecated options unrecognized" do
|
35
|
+
optioning = Optioning.new [
|
36
|
+
from: "xpto",
|
37
|
+
to: "bbq",
|
38
|
+
omg: "x",
|
39
|
+
no_one_knows: "omg lol"]
|
40
|
+
optioning.deprecate :omg, :lol
|
41
|
+
optioning.recognize :from, :to
|
42
|
+
optioning.unrecognized_warn
|
43
|
+
$stderr.string.must_be :==, "NOTE: unrecognized option `:no_one_knows` used."+
|
44
|
+
"\nYou should use only the following: `:lol`, `:from`, `:to`"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "not consider replacement options unrecognized" do
|
48
|
+
optioning = Optioning.new [
|
49
|
+
from: "xpto",
|
50
|
+
to: "bbq",
|
51
|
+
lol: "x",
|
52
|
+
no_one_knows: "omg lol"]
|
53
|
+
optioning.deprecate :omg, :lol
|
54
|
+
optioning.recognize :from, :to
|
55
|
+
optioning.unrecognized_warn
|
56
|
+
$stderr.string.must_be :==, "NOTE: unrecognized option `:no_one_knows` used."+
|
57
|
+
"\nYou should use only the following: `:lol`, `:from`, `:to`"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optioning
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ricardo Valeriano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -67,13 +67,19 @@ files:
|
|
67
67
|
- LICENSE.txt
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
|
+
- examples/client_maroto.rb
|
71
|
+
- examples/module_maroto.rb
|
72
|
+
- lib/deprecation.rb
|
70
73
|
- lib/optioning.rb
|
71
74
|
- lib/optioning/version.rb
|
72
75
|
- optioning.gemspec
|
73
76
|
- tasks/lines.rake
|
74
77
|
- tasks/test.rake
|
78
|
+
- test/deprecation_test.rb
|
79
|
+
- test/optioning_test.rb
|
75
80
|
- test/test_helper.rb
|
76
|
-
|
81
|
+
- test/unrecognized_option_test.rb
|
82
|
+
homepage: http://github.com/ricardovaleriano/optioning
|
77
83
|
licenses:
|
78
84
|
- MIT
|
79
85
|
metadata: {}
|
@@ -83,19 +89,23 @@ require_paths:
|
|
83
89
|
- lib
|
84
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
85
91
|
requirements:
|
86
|
-
- - '>='
|
92
|
+
- - ! '>='
|
87
93
|
- !ruby/object:Gem::Version
|
88
94
|
version: '0'
|
89
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
96
|
requirements:
|
91
|
-
- - '
|
97
|
+
- - ! '>='
|
92
98
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
99
|
+
version: '0'
|
94
100
|
requirements: []
|
95
101
|
rubyforge_project:
|
96
|
-
rubygems_version: 2.1.
|
102
|
+
rubygems_version: 2.1.4
|
97
103
|
signing_key:
|
98
104
|
specification_version: 4
|
99
|
-
summary: 'An object oriented way to treat our beloved last parameter: Hash.'
|
105
|
+
summary: ! 'An object oriented way to treat our beloved last parameter: Hash.'
|
100
106
|
test_files:
|
107
|
+
- test/deprecation_test.rb
|
108
|
+
- test/optioning_test.rb
|
101
109
|
- test/test_helper.rb
|
110
|
+
- test/unrecognized_option_test.rb
|
111
|
+
has_rdoc:
|