hexx 7.1.0 → 8.0.0

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +9 -0
  4. data/.metrics +5 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +2 -63
  7. data/.travis.yml +5 -0
  8. data/.yardopts +2 -0
  9. data/Gemfile +3 -0
  10. data/Guardfile +16 -0
  11. data/{LICENSE.rdoc → LICENSE} +2 -2
  12. data/README.md +138 -0
  13. data/Rakefile +8 -14
  14. data/config/initializer.rb +5 -0
  15. data/config/initializers/capture.rb +19 -0
  16. data/config/initializers/sandbox.rb +16 -0
  17. data/config/initializers/sandbox/helpers.rb +38 -0
  18. data/config/initializers/sandbox/matchers.rb +19 -0
  19. data/config/metrics/STYLEGUIDE +230 -0
  20. data/config/metrics/cane.yml +5 -0
  21. data/config/metrics/churn.yml +6 -0
  22. data/config/metrics/flay.yml +2 -0
  23. data/config/metrics/metric_fu.yml +15 -0
  24. data/config/metrics/pippi.yml +3 -0
  25. data/config/metrics/reek.yml +1 -0
  26. data/config/metrics/roodi.yml +24 -0
  27. data/config/metrics/rubocop.yml +79 -0
  28. data/config/metrics/saikuro.yml +3 -0
  29. data/config/metrics/simplecov.yml +6 -0
  30. data/config/metrics/yardstick.yml +37 -0
  31. data/hexx.gemspec +24 -0
  32. data/lib/hexx.rb +8 -15
  33. data/lib/hexx/generator.rb +71 -0
  34. data/lib/hexx/generator/file.rb +83 -0
  35. data/lib/hexx/generator/folder.rb +68 -0
  36. data/lib/hexx/name.rb +122 -46
  37. data/lib/hexx/version.rb +6 -5
  38. data/spec/fixtures/root/_.beta +1 -0
  39. data/spec/fixtures/root/__omega +0 -0
  40. data/spec/fixtures/root/delta.erb.erb +0 -0
  41. data/spec/fixtures/root/gamma.rb.erb +1 -0
  42. data/spec/fixtures/root/subfolder/alfa.yml +0 -0
  43. data/spec/spec_helper.rb +5 -10
  44. data/spec/tests/lib/generator_spec.rb +126 -0
  45. data/spec/tests/lib/name_spec.rb +113 -0
  46. metadata +54 -168
  47. data/README.rdoc +0 -371
  48. data/lib/hexx/coercible.rb +0 -43
  49. data/lib/hexx/configurable.rb +0 -101
  50. data/lib/hexx/creators/base.rb +0 -103
  51. data/lib/hexx/creators/coercion.rb +0 -82
  52. data/lib/hexx/creators/dependency.rb +0 -87
  53. data/lib/hexx/creators/module_dependency.rb +0 -57
  54. data/lib/hexx/creators/parameter.rb +0 -40
  55. data/lib/hexx/dependable.rb +0 -51
  56. data/lib/hexx/helpers/exceptions.rb +0 -53
  57. data/lib/hexx/helpers/messages.rb +0 -26
  58. data/lib/hexx/helpers/parameters.rb +0 -47
  59. data/lib/hexx/helpers/validations.rb +0 -21
  60. data/lib/hexx/message.rb +0 -79
  61. data/lib/hexx/null.rb +0 -218
  62. data/lib/hexx/service.rb +0 -388
  63. data/lib/hexx/service/with_callbacks.rb +0 -104
  64. data/lib/hexx/service_invalid.rb +0 -73
  65. data/spec/hexx/coercible_spec.rb +0 -72
  66. data/spec/hexx/configurable_spec.rb +0 -93
  67. data/spec/hexx/dependable_spec.rb +0 -125
  68. data/spec/hexx/helpers/exceptions_spec.rb +0 -96
  69. data/spec/hexx/helpers/messages_spec.rb +0 -48
  70. data/spec/hexx/helpers/parameters_spec.rb +0 -96
  71. data/spec/hexx/helpers/validations_spec.rb +0 -32
  72. data/spec/hexx/message_spec.rb +0 -83
  73. data/spec/hexx/name_spec.rb +0 -80
  74. data/spec/hexx/null_spec.rb +0 -152
  75. data/spec/hexx/service_invalid_spec.rb +0 -46
  76. data/spec/hexx/service_spec.rb +0 -89
  77. data/spec/support/initializers/focus.rb +0 -5
  78. data/spec/support/initializers/garbage_collection.rb +0 -11
  79. data/spec/support/initializers/i18n.rb +0 -3
  80. data/spec/support/initializers/random_order.rb +0 -4
  81. data/spec/support/initializers/rspec.rb +0 -5
  82. data/spec/support/matchers/methods.rb +0 -11
@@ -1,388 +0,0 @@
1
- # encoding: utf-8
2
- require_relative "dependable"
3
-
4
- module Hexx
5
-
6
- # @abstract
7
- # The base class for service objects.
8
- #
9
- # @example
10
- # require "hexx"
11
- # class GetItem < Hexx::Service
12
- # allow_params :name
13
- # def run
14
- # publish :found, item = Item.where(name: name).first
15
- # end
16
- # end
17
- #
18
- # service = GetItem.new name: name
19
- # service.subscribe listener, prefix: :on
20
- # service.run
21
- # # => This will call the listener's method #on_found(item).
22
- class Service
23
-
24
- include Wisper::Publisher
25
-
26
- # @!method subscribe(listener, options = {})
27
- # @!visibility public
28
- # Subscribes the listener to service object's notifications.
29
- #
30
- # @example (see Hexx::Service)
31
- # @param [Object] listener The object that should receive notifications from
32
- # the service object.
33
- # @param [Hash] options The list of the subscription options.
34
- # @option options [Symbol] :prefix The prefix for the listener's callbacks.
35
- # It defines the prefix to be added to a notification name
36
- # to provide a corresponding listener method, that should be called by
37
- # the publisher.
38
-
39
- include Helpers::Parameters
40
- # @api hide
41
- private :params
42
- private_class_method :allow_params
43
-
44
- # @!scope class
45
- # @!method allow_params(*names)
46
- # @!visibility private
47
- # Sets a list of allowed parameters for the class constructor and
48
- # defines the corresponding instance attributes.
49
- #
50
- # @example
51
- # class MyService < Hexx::Service
52
- # allows_params :name
53
- # end
54
- #
55
- # service = MyService.new name: "name", code: "code"
56
- # service.send :name # => "name"
57
- # service.send :params # => { "name" => "name" }
58
- #
59
- # @param [Symbol, String, Array<Symbol, String>] names
60
- # The list of allowed parameters.
61
-
62
- # @!attribute [r] params
63
- # @!visibility private
64
- # The list of service object parameters.
65
- #
66
- # The attribute is assigned via the {.new} method options.
67
- # On initialization the parameters (keys) are stringified and whitelisted.
68
- #
69
- # Allowed parameters should be explicitly declared via the {.allow_params}
70
- # private class helper.
71
- #
72
- # @example
73
- # class GetItem < Hexx::Service
74
- # allow_params :name
75
- # end
76
- #
77
- # service = GetItem.new name: "Олег", family: "Рюрикович"
78
- # service.params # => { "name" => "Олег" }
79
- #
80
- # @return [Hash] the service object parameters.
81
-
82
- include Helpers::Messages
83
- # @api hide
84
- public :messages
85
- # @api hide
86
- private :add_message, :t
87
-
88
- # @!attribute [r] messages
89
- # @!visibility public
90
- # The array of service messages (instances of {Hexx::Message})
91
- # with +text+ and +type+ attributes.
92
- #
93
- # @note The attribute setter is private!
94
- #
95
- # @example The messages can be added by the {#add_message} private helper
96
- # class EditItem < Hexx::Service
97
- # def run
98
- # # ...
99
- # else
100
- # add_message "success", "changed"
101
- # publish :changed, messages
102
- # end
103
- # end
104
- #
105
- # service = Test.new
106
- # service.run
107
- # service.messages
108
- # # => [#<Hexx::Message @type="info" @text="some_text" >]
109
- #
110
- # @return [Array<Hexx::Message>] The array of messages.
111
-
112
- # @!scope instance
113
- # @!method add_message(type, text)
114
- # @!visibility private
115
- # Adds the translated message to the {#messages} array.
116
- #
117
- # @example
118
- # class Hello < Hexx::Service
119
- # def run
120
- # add_message "success", "Hello!"
121
- # publish :hello, messages
122
- # end
123
- # end
124
- #
125
- # hello = Hello.new
126
- # hello.subscribe listener
127
- # hello.run
128
- #
129
- # # The listener.hello [#<Hexx::Message @type="success", @text="Hello!" >]
130
- # # will be called.
131
- #
132
- # @param [String] type The type of the message: "error", "info", "success"
133
- # @param [String, Symbol] text The text of the message. The symbol will
134
- # be translated using the {#t} method.
135
- # @param [Hash] options The translation options.
136
- # @return The updated {#messages} array.
137
-
138
- # @!scope instance
139
- # @!method t(text, options = {})
140
- # @!visibility private
141
- # Translates given key in current service's scope.
142
- #
143
- # @note The method uses I18n.t library method.
144
- #
145
- # @example Returns a translation if the first argument is a symbol.
146
- # class PrintHello < Hexx::Service
147
- # def run
148
- # puts t(:hello)
149
- # end
150
- # end
151
- #
152
- # object = PrintHello.new
153
- # object.run
154
- # # => $ translation not found: en.activemodel.messages.models.test.name
155
- #
156
- # @example Returns the string argument.
157
- # class PrintHello < Hexx::Service
158
- # def run
159
- # puts t("hello")
160
- # end
161
- # end
162
- #
163
- # object = PrintHello.new
164
- # object.run
165
- # # => $ name
166
- #
167
- # @param [Symbol, String] text The text to be translated.
168
- # @param [Hash] options ({}) The translation options.
169
- # @return [String] The translation.
170
-
171
- include Helpers::Validations
172
- # @api hide
173
- private :validate!
174
-
175
- # @!scope class
176
- # @!method validates(attribute, options)
177
- # @!visibility private
178
- # Adds a standard validation for the attribute.
179
- #
180
- # @param [Symbol, String] attribute The name of the attribute to validate.
181
- # @param [Hash] options The list of validation options.
182
- # @see
183
- # http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates
184
- # ActiveModel validations APIdocs
185
-
186
- # @!scope class
187
- # @!method validate(method, options)
188
- # @!visibility private
189
- # Adds a custom validation (calls given method).
190
- #
191
- # @param [Symbol, String] method The name of the validation method.
192
- # @param [Hash] options The list of validation options.
193
- # @see
194
- # http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate
195
- # ActiveModel validations APIdocs
196
-
197
- # @!scope instance
198
- # @!method validate!
199
- # @!visibility private
200
- # Runs validations and raises <tt>Hexx::ServiceInvalid</tt>
201
- # when a validation fails.
202
- #
203
- # @example (see Hexx::ServiceInvalid)
204
- #
205
- # @example Safe usage (recommended) with the {#escape} wrapper.
206
- # service GetItem < Hexx::Service
207
- # allow_params :uuid
208
- # validates :uuid, presence: true
209
- # def run
210
- # escape { validate! }
211
- # end
212
- # end
213
- #
214
- # service = GetItem.new
215
- # service.run # => publishes :error notification
216
- #
217
- # @raise [Hexx::ServiceInvalid] when the service object isn't valid.
218
-
219
- include Helpers::Exceptions
220
- # @api hide
221
- private :escape, :on_error
222
- private_class_method :raises
223
-
224
- # @!scope class
225
- # @!method raises(exceptions)
226
- # @!visibility private
227
- # Declares a list of specific +StandardError+ exceptions.
228
- #
229
- # @example
230
- # class Service < Hexx::Service
231
- # raises :NotFound, :NotChanged
232
- #
233
- # def run
234
- # run!
235
- # rescue NotFound
236
- # publish :not_found
237
- # rescue NotChanged
238
- # publish :not_changed
239
- # rescue => err
240
- # # works out any other (unspecified exceptions)
241
- # publish :error
242
- # else
243
- # # works out the main scenario
244
- # publish :success
245
- # end
246
- # end
247
- #
248
- # Service.const_defined? :NotFound # => true
249
- # Service.const_defined? :NotChanged # => true
250
- #
251
- # exception = Service::NotFound.new
252
- # exception.is_a? StandardError # => true
253
- #
254
- # @param [String, Symbol, Array<String, Symbol>] exceptions The list of
255
- # specific +StandardError+ exceptions.
256
-
257
- # @!scope instance
258
- # @!method escape
259
- # @!visibility private
260
- # The method re-raises +StandardError+ exceptions as a
261
- # <tt>Hexx::ServiceInvalid</tt>.
262
- #
263
- # * rescues from a +StandardError+ exceptions
264
- # * adds error message to the service
265
- # * re-raises the <tt>Hexx::ServiceInvalid</tt> exception
266
- #
267
- # @example
268
- # class GetItem < Hexx::Service
269
- # def run
270
- # escape { do_something_unsafe }
271
- # rescue => err
272
- # publish :error, err.messages
273
- # end
274
- # publish :success
275
- # end
276
- # end
277
- #
278
- # @yield the block.
279
- # @raise [Hexx::ServiceInvalid] if the block raised the +StandardError+.
280
- # @return the value returned by the block.
281
-
282
- # @!scope instance
283
- # @!method on_error(messages)
284
- # @!visibility private
285
- # Raises the {Hexx::ServiceInvalid} exception, populated with given
286
- # messages.
287
- #
288
- # @example
289
- # class EditItem < Hexx::Service
290
- #
291
- # allow_params :id, :name
292
- # # ...
293
- #
294
- # def find_item
295
- # run_service GetItem, :on_item, id: id
296
- # end
297
- #
298
- # def on_item_not_found(*, messages)
299
- # on_error(messages) # Raises Hexx::ServiceInvalid
300
- # end
301
- # end
302
- #
303
- # @param [Array<Hexx::ServiceInvalid>] messages The list of error
304
- # messages to be added to the exception.
305
- # @raise [Hexx::ServiceInvalid] the exception.
306
-
307
- # @!scope class
308
- # @!method new(params = {})
309
- # Constructs a service object with given parameters.
310
- #
311
- # @example (see Hexx::Service)
312
- # @param [Hash] params ({}) The parameters of the service object to be
313
- # assigned to the {#params} attribute.
314
- # @return [Hexx::Service] The service object.
315
-
316
- # @abstract
317
- # Runs the service object.
318
- def run
319
- end
320
-
321
- private
322
-
323
- # The helper runs another service object and subscribes +self+ for the
324
- # service object's notifications.
325
- #
326
- # @example
327
- # class AddItem < Hexx::Service
328
- # allow_params :id
329
- #
330
- # # Runs a service for finding an item.
331
- # # Service notifications to be received with a prefix :on_item
332
- # def find_item
333
- # run_service GetItem, :on_item, id: params["id"]
334
- # end
335
- #
336
- # private
337
- #
338
- # attr_reader :item
339
- #
340
- # # Receives GetItem's :found notification
341
- # def on_item_found(item)
342
- # @item = item
343
- # publish :found, item
344
- # end
345
- #
346
- # # Receives GetItem's :not_found notification
347
- # def on_item_not_found(*)
348
- # # ... do some stuff here
349
- # end
350
- # end
351
- #
352
- # @param [Hexx::Service] service_class The class for the service object to
353
- # run.
354
- # @param [Symbol] prefix The prefix for callbacks to receive the service
355
- # object's notifications.
356
- # @param [Hash] options ({}) The options for the service object initializer.
357
- def run_service(service_class, prefix, options = {})
358
- service = service_class.new(options)
359
- service.subscribe with_callbacks, prefix: prefix
360
- service.run
361
- end
362
-
363
- # @api hide
364
- # Makes private methods with given prefix public.
365
- #
366
- # @example Opens private methods.
367
- # def GetItem < Hexx::Service
368
- # private
369
- # def on_success
370
- # publish :success
371
- # end
372
- # end
373
- #
374
- # service = GetItem.new
375
- # service.respond_to? :on_success
376
- # # => false
377
- #
378
- # service_with_callbacks = service.with_callbacks
379
- # service_with_callbacks.respond_to? :on_success
380
- # # => true
381
- #
382
- # @return [Hexx::Service::WithCallbacks<Hexx::Service>]
383
- # The decorator that allows access to the service's private methods.
384
- def with_callbacks(prefix: nil)
385
- WithCallbacks.new(self, prefix: prefix)
386
- end
387
- end
388
- end
@@ -1,104 +0,0 @@
1
- module Hexx
2
- class Service
3
-
4
- # @api hide
5
- # Service object decorator that grants access to its private methods
6
- # whose names begins from given prefix.
7
- #
8
- # @example
9
- # class GetItem < Hexx::Service
10
- # private
11
- # attr_reader :on_something, :something
12
- # end
13
- #
14
- # service = GetItem.new
15
- # service.respond_to? :on_something # => false
16
- # service.respond_to? :something # => false
17
- #
18
- # wrapper = Hexx::Service::WithCallbacks.new service, prefix: :on
19
- # wrapper.respond_to? :on_something # => true
20
- # wrapper.respond_to? :something # => false
21
- class WithCallbacks
22
-
23
- # @api hide
24
- # @!scope class
25
- # @!method new(object, prefix: nil)
26
- # Constructs the decorator.
27
- # @example (see Hexx::Service::WithCallbacks)
28
- # @param [Hexx::Service] object The service object to be decorated.
29
- # @param [Symbol, nil] prefix (nil) The prefix for accessible methods.
30
- def initialize(object, prefix: nil)
31
- @object = object
32
- @prefix = Regexp.new(prefix ? "^#{ prefix }_" : "")
33
- end
34
-
35
- # @api hide
36
- # Redefines the +respond_to?+ to allow access to object's methods.
37
- #
38
- # @example
39
- # service = WithCallbacks(some_service, prefix: :on)
40
- # service.respond_to? :on_something # => true
41
- #
42
- # @param [Symbol] method The name of the method to check access to.
43
- def respond_to?(method, *)
44
- object.respond_to?(method) || valid_callback?(method) || super
45
- end
46
-
47
- # Compares the object with another service object.
48
- # The wrapper is equal to another wrapper for the same object and prefix.
49
- #
50
- # @example Wrappers are equal if they have the same objects and prefixes
51
- # service = Hexx::Service.new
52
- # a = Hexx::Service::WithCallbacks.new service, prefix: :on
53
- # b = Hexx::Service::WithCallbacks.new service, prefix: :on
54
- # a == b # => true
55
- #
56
- # @example Wrappers are different if they have different prefixes
57
- # service = Hexx::Service.new
58
- # a = Hexx::Service::WithCallbacks.new service, prefix: :on
59
- # b = Hexx::Service::WithCallbacks.new service, prefix: :when
60
- # a == b # => false
61
- #
62
- # @example Wrappers are different if they have different objects
63
- # a = Hexx::Service::WithCallbacks.new Hexx::Service.new, prefix: :on
64
- # b = Hexx::Service::WithCallbacks.new Hexx::Service.new, prefix: :on
65
- # a == b # => false
66
- #
67
- # @example A wrapper differs from any non-wrapper
68
- # service = Hexx::Service.new
69
- # a = Hexx::Service::WithCallbacks.new service, prefix: :on
70
- # a == service # => false
71
- #
72
- # @param [Object] other The other object to compare the wrapper to.
73
- # @return [Boolean].
74
- def ==(other)
75
- return false unless other.is_a?(Service) || other.is_a?(self.class)
76
- value == other.value
77
- end
78
-
79
- protected
80
-
81
- # @api hide
82
- # The value to compare wrappers by.
83
- # @return [String] value.
84
- def value
85
- object.inspect + prefix.inspect
86
- end
87
-
88
- private
89
-
90
- # @api hide
91
- attr_reader :object, :prefix
92
-
93
- # @api hide
94
- def method_missing(method, *args, &block)
95
- valid_callback?(method) ? object.send(method, *args, &block) : super
96
- end
97
-
98
- # @api hide
99
- def valid_callback?(method)
100
- method.to_s[prefix] && object.respond_to?(method, include_all: true)
101
- end
102
- end
103
- end
104
- end