optioning 0.0.1.beta → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/optioning.svg)](http://badge.fury.io/rb/hashing)
|
9
9
|
[![Build Status](https://travis-ci.org/ricardovaleriano/optioning.svg?branch=master)](http://travis-ci.org/ricardovaleriano/hashing?branch=master)
|
10
10
|
[![Code Climate](https://codeclimate.com/github/ricardovaleriano/optioning.png)](https://codeclimate.com/github/ricardovaleriano/hashing)
|
11
|
+
[![Inline docs](http://inch-pages.github.io/github/ricardovaleriano/optioning.png)](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:
|