hexx 7.1.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
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