verbalize 2.0.1 → 2.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 28277ada3b560d5fd8ed11a9b568dd03f8c0156a
4
- data.tar.gz: 9ff1315685ffa11c9a997a15a07206fe0e21f112
2
+ SHA256:
3
+ metadata.gz: b4ab48694dce4b9810ed7289498ee4ff0533919ed08041d5abfa4dda1a3800a7
4
+ data.tar.gz: e2a160824182fef4e702a65b27116505f492cf5f02022bfe928198bb822b2aae
5
5
  SHA512:
6
- metadata.gz: e4049ff78ca84f4e44f34c6525089edb96b74206ca6318f3b84c78779dd303863a612f0be86059e9e6bd1d8fce2f364a62e3d65b6269575ee13cd1dc7bbd44b9
7
- data.tar.gz: a6528d2fa2ec1dc97d9524f6feb75426a249cc6a8bd2b656d7491d2bb5698512ec9718c836f16b33c0bc85d65aba5551a6d135170e2e1ebfb5fdf37c86770948
6
+ metadata.gz: a533db1a4cc25d45a4c5474a96671d3f172f1e84e7c6bf574f2d281caebbce7967d61f96106a9582cdb3915d4d24c6d4ae33b39577734723b65e0ea4ffcab8d0
7
+ data.tar.gz: 9068fc27d208da171b89f173eec3af2d78b3a3d90bdc589ec737cf97a978c9044b22a7cc4a8b57237149562169859f819bfce672a65a94978ecaa227a216d907
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "11:00"
8
+ open-pull-requests-limit: 10
@@ -0,0 +1,25 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ ruby-version: ['2.6', '2.7', '3.0']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+ - name: Run tests
25
+ run: bundle exec rspec
data/CHANGELOG.md ADDED
@@ -0,0 +1,91 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## 2.3.1 - 2021-06-02
8
+ ### Added
9
+ - release documentation
10
+ - ruby 2.7 compatibility to remove deprecation warnings
11
+
12
+ ## 2.3.0 - 2019-09-23
13
+ ### Added
14
+ - you can now specify `validates :key { |value| ... }` on actions to run validation on the input
15
+ *before* running the `call` block.
16
+
17
+ ## 2.2.0 - 2017-08-19
18
+ ### Added
19
+ - changelog started
20
+ - You can now specify default values for optional inputs in the `input` call.
21
+ Use a regular value to load it once, at load-time, and a lambda to lazily load
22
+ the value each time the action is called.
23
+ ### Changed
24
+ - privatize Action.input. Now that we have Action.inputs, we want to avoid calling Action.input (no s) outside of the action itself
25
+
26
+ ## 2.1.1 - 2017-02-21
27
+ ### Fixed
28
+ - ensure Verbalize::Action.optional_input always returns an array
29
+
30
+ ## 2.1.0 - 2017-02-21
31
+ ### Added
32
+ - introspect Action input using Action.inputs, Action.required_inputs, and Action.optional_inputs
33
+
34
+ ## 2.0.2 - 2017-2-21 [YANKED]
35
+ - new functionality was added, so minor version should have been increased instead of patch
36
+
37
+ ## 2.0.1 - 2016-12-16
38
+ ### Changed
39
+ - internal refactoring
40
+
41
+ ## 2.0.0 - 2016-02-14
42
+ ### Added
43
+ - execution of action routed through Action#perform to better support stubbing
44
+ - 100% test coverage!!!
45
+ ### Changed
46
+ - calling Failure#value now raises an error, use Failure#failure instead? Did this happen in 1.3?
47
+ ### Removed
48
+ - removes action implementation methods other than #call/#call!
49
+
50
+ ## 1.4.1 - 2016-12-14
51
+ ### Added
52
+ - Failure#failure added to replace Failure#value
53
+ ### Changed
54
+ - Result split into Success/Failure
55
+ ### Deprecated
56
+ - stop including Verbalize itself, use Verbalize::Action instead
57
+ - stop using action implementation methods other than #call/#call!
58
+ - stop using Failure#value, used Failure#failure instead
59
+
60
+ ## 1.4.0 [YANKED] - 2016-12-14
61
+ ### Fixed
62
+ - error while uploading to ruby gems, yanked and released v1.4.1
63
+
64
+ ## 1.3.0 - 2016-11-09
65
+ ### Changed
66
+ - better failure handling
67
+
68
+ ## 1.2.0 - 2016-11-07
69
+ ### Added
70
+ - alias Result.success? to Result.succeeded?
71
+ - alias Result.failure? to Result.failed?
72
+ ### Changed
73
+ - Action now implements #to_ary instead of subclassing Array
74
+
75
+ ## 1.1.2 - 2016-11-07 [YANKED]
76
+ - new functionality was added, so minor version should have been increased instead of patch
77
+
78
+ ## 1.1.1 - 2016-08-25
79
+ ### Changed
80
+ - internal refactoring
81
+
82
+ ## 1.0.1 - 2016-08-10
83
+ ### Fixed
84
+ - Use send to call Action#call so that Action#call can be privatized
85
+
86
+ ## 1.0.0 - 2016-08-09
87
+ ### Added
88
+ - optional input
89
+
90
+ ## 0.1.0 - 2016-08-07
91
+ - initial release
data/Dockerfile ADDED
@@ -0,0 +1,45 @@
1
+ ARG BUNDLER_VERSION=2.0.2
2
+ ARG RUBY_VERSION=2.7.1
3
+ ARG APP_ROOT=/gem
4
+
5
+ #######################################
6
+ ### Builder
7
+ FROM ruby:${RUBY_VERSION}-alpine AS build-env
8
+
9
+ ARG APP_ROOT
10
+
11
+ ENV BUNDLE_APP_CONFIG="$APP_ROOT/.bundle"
12
+ ARG PACKAGES="curl tzdata less git"
13
+ RUN mkdir $APP_ROOT
14
+ WORKDIR $APP_ROOT
15
+
16
+ RUN apk update \
17
+ && apk upgrade \
18
+ && apk add --update --no-cache $PACKAGES
19
+
20
+ #######################################
21
+ ### Development
22
+ FROM build-env AS development
23
+
24
+ ARG BUNDLER_VERSION
25
+ ARG APP_ROOT
26
+ ENV BUNDLE_APP_CONFIG="$APP_ROOT/.bundle"
27
+
28
+ WORKDIR $APP_ROOT
29
+
30
+ RUN apk add --update --no-cache \
31
+ build-base \
32
+ git \
33
+ tzdata \
34
+ less
35
+
36
+ RUN gem install bundler:$BUNDLER_VERSION
37
+
38
+ COPY . $APP_ROOT
39
+
40
+ RUN bundle install -j4 --retry 3 \
41
+ && rm -rf /usr/local/bundle/cache/*.gem \
42
+ && find /usr/local/bundle/gems/ -name "*.c" -delete \
43
+ && find /usr/local/bundle/gems/ -name "*.o" -delete
44
+
45
+
data/README.md CHANGED
@@ -53,6 +53,35 @@ Add.call # => [:ok, 42]
53
53
  Add.call(a: 660, b: 6) # => [:ok, 666]
54
54
  ```
55
55
 
56
+ ## Default Values
57
+
58
+ ```ruby
59
+ # You can define defaults via key/value pairs, as so:
60
+ class Add
61
+ include Verbalize::Action
62
+ # note that these values are evaluated at load-time as they are not wrapped
63
+ # in lambdas.
64
+ input optional: [a: 35, b: 7]
65
+ def call; a + b; end
66
+ end
67
+
68
+ # default values can be lazily loaded by passing in a lambda, e.g.:
69
+
70
+ class Tomorrow
71
+ include Verbalize::Action
72
+ input optional: [as_of: -> { Time.now }]
73
+ def call
74
+ as_of + 1
75
+ end
76
+ end
77
+
78
+ start_time = Tomorrow.call!
79
+ sleep(1)
80
+ end_time = Tomorrow.call!
81
+ end_time - start_time # ~1s; the default is executed each call.
82
+ ```
83
+
84
+
56
85
  ```ruby
57
86
  class Divide
58
87
  include Verbalize::Action
@@ -69,6 +98,52 @@ result = Divide.call(a: 1, b: 0) # => [:error, 'You can’t divide by 0']
69
98
  result.failed? # => true
70
99
  ```
71
100
 
101
+ ### Reflection
102
+ ```ruby
103
+ class Add
104
+ include Verbalize::Action
105
+
106
+ input :a, :b, optional: [:c, :d]
107
+
108
+ def call
109
+ a + b + c + d
110
+ end
111
+
112
+ private
113
+
114
+ def c
115
+ @c ||= 0
116
+ end
117
+
118
+ def d
119
+ @d ||= 0
120
+ end
121
+ end
122
+
123
+ Add.required_inputs # [:a, :b]
124
+ Add.optional_inputs # [:c, :d]
125
+ Add.inputs # [:a, :b, :c, :d]
126
+ ```
127
+
128
+ ## Validation
129
+ ```ruby
130
+ class FloatAdd
131
+ include Verbalize::Action
132
+
133
+ input :a, :b
134
+ validate(:a) { |a| a.is_a?(Float) }
135
+ validate(:b) { |b| b.is_a?(Float) && b > 10.0 }
136
+
137
+ def call
138
+ a + b
139
+ end
140
+ end
141
+
142
+ FloatAdd.call!(a: 1, b: 1) # fails with Input "a" failed validation!
143
+ FloatAdd.call!(a: 1.0, b: 1.0) # fails with Input "b" failed validation!
144
+ FloatAdd.call!(a: 1.0, b: 12.0) # 13.0
145
+ ```
146
+
72
147
  ## Comparison/Benchmark
73
148
  ```ruby
74
149
  require 'verbalize'
@@ -132,21 +207,21 @@ end
132
207
 
133
208
  ```
134
209
  Warming up --------------------------------------
135
- Ruby 53.203k i/100ms
136
- Verbalize 27.518k i/100ms
137
- Actionizer 4.933k i/100ms
138
- Interactor 4.166k i/100ms
210
+ Ruby 63.091k i/100ms
211
+ Verbalize 40.521k i/100ms
212
+ Actionizer 5.226k i/100ms
213
+ Interactor 4.874k i/100ms
139
214
  Calculating -------------------------------------
140
- Ruby 544.025k13.7%) i/s - 2.660M in 5.011207s
141
- Verbalize 278.738k8.0%) i/s - 1.403M in 5.074676s
142
- Actionizer 49.571k7.0%) i/s - 246.650k in 5.006194s
143
- Interactor 45.896k7.1%) i/s - 229.130k in 5.018389s
215
+ Ruby 751.604k 3.0%) i/s - 3.785M in 5.041472s
216
+ Verbalize 457.598k6.1%) i/s - 2.310M in 5.072488s
217
+ Actionizer 54.874k3.5%) i/s - 276.978k in 5.054541s
218
+ Interactor 52.294k3.2%) i/s - 263.196k in 5.038365s
144
219
 
145
220
  Comparison:
146
- Ruby: 544025.0 i/s
147
- Verbalize: 278737.9 i/s - 1.95x slower
148
- Actionizer: 49571.1 i/s - 10.97x slower
149
- Interactor: 45896.1 i/s - 11.85x slower
221
+ Ruby: 751604.0 i/s
222
+ Verbalize: 457597.9 i/s - 1.64x slower
223
+ Actionizer: 54873.6 i/s - 13.70x slower
224
+ Interactor: 52293.6 i/s - 14.37x slower
150
225
 
151
226
  ```
152
227
 
@@ -155,15 +230,15 @@ Comparison:
155
230
  ### Happy Path
156
231
 
157
232
  When testing positive cases of a `Verbalize::Action`, it is recommended to test using the `call!` class method and
158
- assert on the result. This implicitly ensures a successful result, and your tests will fail with a bang! if
233
+ assert on the result. This implicitly ensures a successful result, and your tests will fail with a bang! if
159
234
  something goes wrong:
160
235
 
161
236
  ```ruby
162
237
  class MyAction
163
238
  include Verbalize::Action
164
-
239
+
165
240
  input :a
166
-
241
+
167
242
  def call
168
243
  fail!('#{a} is greater than than 100!') if a >= 100
169
244
  a + 1
@@ -178,28 +253,28 @@ end
178
253
 
179
254
  ### Sad Path
180
255
 
181
- When testing negative cases of a `Verbalize::Action`, it is recommended to test using the `call` non-bang
256
+ When testing negative cases of a `Verbalize::Action`, it is recommended to test using the `call` non-bang
182
257
  class method which will return a `Verbalize::Failure` on failure.
183
258
 
184
- Use of `call!` here is not advised as it will result in an exception being thrown. Set assertions on both
259
+ Use of `call!` here is not advised as it will result in an exception being thrown. Set assertions on both
185
260
  the failure outcome and value:
186
261
 
187
262
  ```ruby
188
263
  class MyAction
189
264
  include Verbalize::Action
190
-
265
+
191
266
  input :a
192
-
267
+
193
268
  def call
194
269
  fail!('#{a} is greater than 100!') if a >= 100
195
270
  a + 1
196
271
  end
197
272
  end
198
-
273
+
199
274
  # rspec:
200
275
  it 'fails when the input is out of bounds' do
201
276
  result = MyAction.call(a: 1000)
202
-
277
+
203
278
  expect(result).to be_failed
204
279
  expect(result.failure).to eq '1000 is greater than 100!'
205
280
  end
@@ -208,11 +283,11 @@ end
208
283
  ### Stubbing Responses
209
284
 
210
285
  When unit testing, it may be necessary to stub the responses of Verbalize actions. To correctly stub responses,
211
- you should __always__ stub the `MyAction.perform` class method on the action class being stubbed per the
286
+ you should __always__ stub the `MyAction.perform` class method on the action class being stubbed per the
212
287
  instructions below. __Never__ stub the `call` or `call!` methods directly.
213
288
 
214
289
  Stubbing `.perform` will enable `Verbalize` to wrap results correctly for references to either `call` or `call!`.
215
-
290
+
216
291
  #### Stubbing Successful Responses
217
292
 
218
293
  To simulate a successful response of the `Verbalize::Action` being stubbed, you should stub the `MyAction.perform`
@@ -225,7 +300,7 @@ class Foo
225
300
  def self.multiply_by(multiple)
226
301
  result = MyAction.call(a: 1)
227
302
  raise "I couldn't do the thing!" if result.failure?
228
-
303
+
229
304
  result.value * multiple
230
305
  end
231
306
  end
@@ -238,9 +313,9 @@ describe Foo do
238
313
  allow(MyAction).to receive(:perform)
239
314
  .with(a: 1)
240
315
  .and_return(123)
241
-
316
+
242
317
  result = described_class.multiply_by(100)
243
-
318
+
244
319
  expect(result).to eq 12300
245
320
  end
246
321
  end
@@ -266,7 +341,7 @@ describe Foo do
266
341
  allow(MyAction).to receive(:perform)
267
342
  .with(a: 1)
268
343
  .and_throw(::Verbalize::THROWN_SYMBOL, 'Y U NO!')
269
-
344
+
270
345
  expect {
271
346
  described_class.multiply_by(100)
272
347
  }.to raise_error "I couldn't do the thing!"
@@ -297,6 +372,13 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
297
372
 
298
373
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
299
374
 
375
+ ## Releasing
376
+
377
+ - Update CHANGELOG.md, and lib/verbalize/version.rb, commit, and push
378
+ - [Create a new release on github](https://github.com/taylorzr/verbalize/releases/new)
379
+ - Build the gem version: `gem build verbalize.gemspec`
380
+ - Push the gem version to rubygems: `gem push verbalize-<VERSION>.gem`
381
+
300
382
  ## Contributing
301
383
 
302
384
  Bug reports and pull requests are welcome on GitHub at https://github.com/taylorzr/verbalize.
@@ -305,4 +387,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/taylor
305
387
  ## License
306
388
 
307
389
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
308
-
data/bin/console CHANGED
@@ -6,9 +6,5 @@ require 'verbalize'
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require 'irb'
14
- IRB.start
9
+ require 'pry'
10
+ Pry.start
@@ -0,0 +1,12 @@
1
+ version: '3.7'
2
+
3
+ services:
4
+ ruby:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+ target: development
9
+ command: bundle exec rspec
10
+ volumes:
11
+ - .:/gem
12
+
@@ -11,13 +11,64 @@ module Verbalize
11
11
  throw(THROWN_SYMBOL, failure_value)
12
12
  end
13
13
 
14
+ def action_inputs
15
+ self.class.inputs.map { |i| [i, self.send(i)] }.to_h
16
+ end
17
+
14
18
  def self.included(target)
15
19
  target.extend ClassMethods
16
20
  end
17
21
 
22
+ private
23
+
24
+ def __setup(key, value)
25
+ is_valid = self.class.input_is_valid?(key, value)
26
+ local_error = self.class.pop_local_error
27
+ fail!(local_error) if !is_valid && local_error
28
+ fail! "Input '#{key}' failed validation!" unless is_valid
29
+
30
+ instance_variable_set(:"@#{key}", value)
31
+ end
32
+
18
33
  module ClassMethods
19
- def input(*required_keywords, optional: [])
20
- class_eval Build.call(required_keywords, Array(optional))
34
+ def required_inputs
35
+ @required_inputs || []
36
+ end
37
+
38
+ def optional_inputs
39
+ @optional_inputs || []
40
+ end
41
+
42
+ def default_inputs
43
+ (@defaults || {}).keys
44
+ end
45
+
46
+ def inputs
47
+ required_inputs + optional_inputs + default_inputs
48
+ end
49
+
50
+ def defaults
51
+ @defaults
52
+ end
53
+
54
+ def input_validations
55
+ @input_validations ||= {}
56
+ end
57
+
58
+ def input_is_valid?(input, value)
59
+ return true unless input_validations.include?(input.to_sym)
60
+
61
+ input_validations[input].call(value) == true
62
+ rescue => e
63
+ @local_error = e
64
+ false
65
+ end
66
+
67
+ def pop_local_error
68
+ return nil unless @local_error
69
+ @local_error
70
+ ensure
71
+ @local_error = nil
21
72
  end
22
73
 
23
74
  # Because call/call! are defined when Action.input is called, they would
@@ -30,35 +81,81 @@ module Verbalize
30
81
  def call!
31
82
  __proxied_call!
32
83
  end
84
+ alias_method :!, :call!
33
85
 
34
86
  private
35
87
 
36
- def perform(*args)
37
- new(*args).send(:call)
88
+ def input(*required_keywords, optional: [])
89
+ @required_inputs = required_keywords
90
+ optional = Array(optional)
91
+ @optional_inputs = optional.reject { |kw| kw.is_a?(Hash) }
92
+ assign_defaults(optional)
93
+
94
+ class_eval Build.call(required_inputs, optional_inputs, default_inputs)
38
95
  end
39
96
 
40
- # We used __proxied_call/__proxied_call! for 2 reasons:
41
- # 1. The declaration of call/call! needs to be explicit so that tools
42
- # like rspec-mocks can verify the actions keywords actually
43
- # exist when stubbing
44
- # 2. Because #1, meta-programming a simple interface to these proxied
45
- # methods is much simpler than meta-programming the full methods
46
- def __proxied_call(*args)
47
- error = catch(:verbalize_error) do
48
- value = perform(*args)
49
- return Success.new(value)
50
- end
97
+ def validate(keyword, &block)
98
+ raise Verbalize::Error, 'Missing block to validate against!' unless block_given?
99
+ input_validations[keyword.to_sym] = block
100
+ end
51
101
 
52
- Failure.new(error)
102
+ def assign_defaults(optional)
103
+ @defaults = optional.select { |kw| kw.is_a?(Hash) }.reduce(&:merge)
104
+ @defaults = (@defaults || {})
105
+ .map { |k, v| [k, v.respond_to?(:call) ? v : -> { v }] }
106
+ .to_h
53
107
  end
54
108
 
55
- def __proxied_call!(*args)
56
- perform(*args)
57
- rescue UncaughtThrowError => uncaught_throw_error
58
- fail_value = uncaught_throw_error.value
59
- error = Verbalize::Error.new("Unhandled fail! called with: #{fail_value.inspect}.")
60
- error.set_backtrace(uncaught_throw_error.backtrace[2..-1])
61
- raise error
109
+ if RUBY_VERSION < "2.7"
110
+ def perform(*args)
111
+ new(*args).send(:call)
112
+ end
113
+
114
+ def __proxied_call(*args)
115
+ error = catch(:verbalize_error) do
116
+ value = perform(*args)
117
+ return Success.new(value)
118
+ end
119
+
120
+ Failure.new(error)
121
+ end
122
+
123
+ def __proxied_call!(*args)
124
+ perform(*args)
125
+ rescue UncaughtThrowError => uncaught_throw_error
126
+ fail_value = uncaught_throw_error.value
127
+ error = Verbalize::Error.new("Unhandled fail! called with: #{fail_value.inspect}.")
128
+ error.set_backtrace(uncaught_throw_error.backtrace[2..-1])
129
+ raise error
130
+ end
131
+ else
132
+ def perform(**args)
133
+ new(**args).send(:call)
134
+ end
135
+
136
+ # We used __proxied_call/__proxied_call! for 2 reasons:
137
+ # 1. The declaration of call/call! needs to be explicit so that tools
138
+ # like rspec-mocks can verify the actions keywords actually
139
+ # exist when stubbing
140
+ # 2. Because #1, meta-programming a simple interface to these proxied
141
+ # methods is much simpler than meta-programming the full methods
142
+ def __proxied_call(**args)
143
+ error = catch(:verbalize_error) do
144
+ value = perform(**args)
145
+ return Success.new(value)
146
+ end
147
+
148
+ Failure.new(error)
149
+ end
150
+
151
+ def __proxied_call!(**args)
152
+ perform(**args)
153
+ rescue UncaughtThrowError => uncaught_throw_error
154
+ fail_value = uncaught_throw_error.value
155
+ error = Verbalize::Error.new("Unhandled fail! called with: #{fail_value.inspect}.")
156
+ error.set_backtrace(uncaught_throw_error.backtrace[2..-1])
157
+ raise error
158
+ end
62
159
  end
63
160
  end
64
161
  end
@@ -1,22 +1,28 @@
1
1
  module Verbalize
2
2
  class Build
3
- def self.call(required_keywords = [], optional_keywords = [])
4
- new(required_keywords, optional_keywords).call
3
+ def self.call(required_keywords = [], optional_keywords = [], default_keywords = [])
4
+ new(required_keywords, optional_keywords, default_keywords).call
5
5
  end
6
6
 
7
- def initialize(required_keywords, optional_keywords)
7
+ def initialize(required_keywords, optional_keywords, default_keywords)
8
8
  @required_keywords = required_keywords
9
9
  @optional_keywords = optional_keywords
10
+ @default_keywords = default_keywords
10
11
  end
11
12
 
12
13
  def call
14
+ # We have to re-alias `!` to `call!` here, otherwise it will be pointing
15
+ # to the original `call!` method
13
16
  <<-CODE
14
- def self.call(#{declaration_arguments_string})
15
- __proxied_call(#{forwarding_arguments_string})
16
- end
17
+ class << self
18
+ def call(#{declaration_arguments_string})
19
+ __proxied_call(#{forwarding_arguments_string})
20
+ end
17
21
 
18
- def self.call!(#{declaration_arguments_string})
19
- __proxied_call!(#{forwarding_arguments_string})
22
+ def call!(#{declaration_arguments_string})
23
+ __proxied_call!(#{forwarding_arguments_string})
24
+ end
25
+ alias_method :!, :call!
20
26
  end
21
27
 
22
28
  def initialize(#{declaration_arguments_string})
@@ -29,18 +35,19 @@ attr_reader #{attribute_readers_string}
29
35
  CODE
30
36
  end
31
37
 
32
- attr_reader :required_keywords, :optional_keywords
38
+ attr_reader :required_keywords, :optional_keywords, :default_keywords
33
39
 
34
40
  private
35
41
 
36
42
  def all_keywords
37
- required_keywords + optional_keywords
43
+ required_keywords + optional_keywords + default_keywords
38
44
  end
39
45
 
40
46
  def declaration_arguments_string
41
- required_segments = required_keywords.map { |keyword| "#{keyword}:" }
42
- optional_segments = optional_keywords.map { |keyword| "#{keyword}: nil" }
43
- (required_segments + optional_segments).join(', ')
47
+ required_segments = required_keywords.map { |kw| "#{kw}:" }
48
+ optional_segments = optional_keywords.map { |kw| "#{kw}: nil" }
49
+ default_segments = default_keywords.map { |kw| "#{kw}: self.defaults[:#{kw}].call" }
50
+ (required_segments + optional_segments + default_segments).join(', ')
44
51
  end
45
52
 
46
53
  def forwarding_arguments_string
@@ -48,7 +55,9 @@ attr_reader #{attribute_readers_string}
48
55
  end
49
56
 
50
57
  def initialize_body
51
- all_keywords.map { |keyword| "@#{keyword} = #{keyword}" }.join("\n ")
58
+ all_keywords.map do |keyword|
59
+ "__setup(:#{keyword}, #{keyword})"
60
+ end.join("\n ")
52
61
  end
53
62
 
54
63
  def attribute_readers_string
@@ -1,3 +1,3 @@
1
1
  module Verbalize
2
- VERSION = '2.0.1'.freeze
2
+ VERSION = '2.3.1'.freeze
3
3
  end
data/verbalize.gemspec CHANGED
@@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_development_dependency 'bundler'
24
- spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rake'
25
25
  spec.add_development_dependency 'rspec'
26
26
  spec.add_development_dependency 'coveralls'
27
- spec.add_development_dependency 'rubocop', '0.45'
27
+ spec.add_development_dependency 'rubocop'
28
28
  spec.add_development_dependency 'pry'
29
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verbalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Taylor
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-16 00:00:00.000000000 Z
11
+ date: 2021-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
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
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: rubocop
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0.45'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '0.45'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description:
97
+ description:
98
98
  email:
99
99
  - taylorzr@gmail.com
100
100
  executables: []
@@ -102,17 +102,20 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".codeclimate.yml"
105
+ - ".github/dependabot.yml"
106
+ - ".github/workflows/tests.yml"
105
107
  - ".gitignore"
106
108
  - ".rspec"
107
109
  - ".rubocop.yml"
108
- - ".travis.yml"
110
+ - CHANGELOG.md
111
+ - Dockerfile
109
112
  - Gemfile
110
113
  - LICENSE.txt
111
114
  - README.md
112
115
  - Rakefile
113
116
  - bin/console
114
117
  - bin/setup
115
- - circle.yml
118
+ - docker-compose.yml
116
119
  - lib/verbalize.rb
117
120
  - lib/verbalize/action.rb
118
121
  - lib/verbalize/build.rb
@@ -126,7 +129,7 @@ homepage: https://github.com/taylorzr/verbalize
126
129
  licenses:
127
130
  - MIT
128
131
  metadata: {}
129
- post_install_message:
132
+ post_install_message:
130
133
  rdoc_options: []
131
134
  require_paths:
132
135
  - lib
@@ -141,9 +144,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
144
  - !ruby/object:Gem::Version
142
145
  version: '0'
143
146
  requirements: []
144
- rubyforge_project:
145
- rubygems_version: 2.4.8
146
- signing_key:
147
+ rubygems_version: 3.0.3
148
+ signing_key:
147
149
  specification_version: 4
148
150
  summary: Verb based class pattern
149
151
  test_files: []
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.2
4
- before_install: gem install bundler -v 1.10.6
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- machine:
2
- ruby:
3
- version: '2.2'