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
metadata CHANGED
@@ -1,192 +1,96 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexx
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-21 00:00:00.000000000 Z
11
+ date: 2015-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activemodel
14
+ name: extlib
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.1'
19
+ version: '0.9'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.1'
26
+ version: '0.9'
27
27
  - !ruby/object:Gem::Dependency
28
- name: wisper
28
+ name: hexx-suit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: '0.0'
34
34
  type: :runtime
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: '1.3'
41
- - !ruby/object:Gem::Dependency
42
- name: coveralls
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.7'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.7'
55
- - !ruby/object:Gem::Dependency
56
- name: inch
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.5'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.5'
69
- - !ruby/object:Gem::Dependency
70
- name: metric_fu
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '4.11'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '4.11'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '10.3'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '10.3'
97
- - !ruby/object:Gem::Dependency
98
- name: rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '3.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '3.0'
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.23'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.23'
125
- - !ruby/object:Gem::Dependency
126
- name: guard-rspec
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '4.3'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '4.3'
139
- description: Defines domain service object and model attributes coercion.
40
+ version: '0.0'
41
+ description: Collection of scaffolders.
140
42
  email: andrew.kozin@gmail.com
141
43
  executables: []
142
44
  extensions: []
143
45
  extra_rdoc_files:
144
- - LICENSE.rdoc
145
- - README.rdoc
46
+ - README.md
47
+ - LICENSE
48
+ - config/metrics/STYLEGUIDE
146
49
  files:
50
+ - ".coveralls.yml"
51
+ - ".gitignore"
52
+ - ".metrics"
53
+ - ".rspec"
147
54
  - ".rubocop.yml"
148
- - LICENSE.rdoc
149
- - README.rdoc
55
+ - ".travis.yml"
56
+ - ".yardopts"
57
+ - Gemfile
58
+ - Guardfile
59
+ - LICENSE
60
+ - README.md
150
61
  - Rakefile
62
+ - config/initializer.rb
63
+ - config/initializers/capture.rb
64
+ - config/initializers/sandbox.rb
65
+ - config/initializers/sandbox/helpers.rb
66
+ - config/initializers/sandbox/matchers.rb
67
+ - config/metrics/STYLEGUIDE
68
+ - config/metrics/cane.yml
69
+ - config/metrics/churn.yml
70
+ - config/metrics/flay.yml
71
+ - config/metrics/metric_fu.yml
72
+ - config/metrics/pippi.yml
73
+ - config/metrics/reek.yml
74
+ - config/metrics/roodi.yml
75
+ - config/metrics/rubocop.yml
76
+ - config/metrics/saikuro.yml
77
+ - config/metrics/simplecov.yml
78
+ - config/metrics/yardstick.yml
79
+ - hexx.gemspec
151
80
  - lib/hexx.rb
152
- - lib/hexx/coercible.rb
153
- - lib/hexx/configurable.rb
154
- - lib/hexx/creators/base.rb
155
- - lib/hexx/creators/coercion.rb
156
- - lib/hexx/creators/dependency.rb
157
- - lib/hexx/creators/module_dependency.rb
158
- - lib/hexx/creators/parameter.rb
159
- - lib/hexx/dependable.rb
160
- - lib/hexx/helpers/exceptions.rb
161
- - lib/hexx/helpers/messages.rb
162
- - lib/hexx/helpers/parameters.rb
163
- - lib/hexx/helpers/validations.rb
164
- - lib/hexx/message.rb
81
+ - lib/hexx/generator.rb
82
+ - lib/hexx/generator/file.rb
83
+ - lib/hexx/generator/folder.rb
165
84
  - lib/hexx/name.rb
166
- - lib/hexx/null.rb
167
- - lib/hexx/service.rb
168
- - lib/hexx/service/with_callbacks.rb
169
- - lib/hexx/service_invalid.rb
170
85
  - lib/hexx/version.rb
171
- - spec/hexx/coercible_spec.rb
172
- - spec/hexx/configurable_spec.rb
173
- - spec/hexx/dependable_spec.rb
174
- - spec/hexx/helpers/exceptions_spec.rb
175
- - spec/hexx/helpers/messages_spec.rb
176
- - spec/hexx/helpers/parameters_spec.rb
177
- - spec/hexx/helpers/validations_spec.rb
178
- - spec/hexx/message_spec.rb
179
- - spec/hexx/name_spec.rb
180
- - spec/hexx/null_spec.rb
181
- - spec/hexx/service_invalid_spec.rb
182
- - spec/hexx/service_spec.rb
86
+ - spec/fixtures/root/_.beta
87
+ - spec/fixtures/root/__omega
88
+ - spec/fixtures/root/delta.erb.erb
89
+ - spec/fixtures/root/gamma.rb.erb
90
+ - spec/fixtures/root/subfolder/alfa.yml
183
91
  - spec/spec_helper.rb
184
- - spec/support/initializers/focus.rb
185
- - spec/support/initializers/garbage_collection.rb
186
- - spec/support/initializers/i18n.rb
187
- - spec/support/initializers/random_order.rb
188
- - spec/support/initializers/rspec.rb
189
- - spec/support/matchers/methods.rb
92
+ - spec/tests/lib/generator_spec.rb
93
+ - spec/tests/lib/name_spec.rb
190
94
  homepage: https://github.com/nepalez/hexx
191
95
  licenses:
192
96
  - MIT
@@ -197,7 +101,7 @@ require_paths:
197
101
  - lib
198
102
  required_ruby_version: !ruby/object:Gem::Requirement
199
103
  requirements:
200
- - - "~>"
104
+ - - ">="
201
105
  - !ruby/object:Gem::Version
202
106
  version: '2.1'
203
107
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -210,27 +114,9 @@ rubyforge_project:
210
114
  rubygems_version: 2.2.2
211
115
  signing_key:
212
116
  specification_version: 4
213
- summary: Service objects for Rails.
117
+ summary: Collection of scaffolders for projects that follow the hexagonal architecture.
214
118
  test_files:
215
119
  - spec/spec_helper.rb
216
- - spec/hexx/service_spec.rb
217
- - spec/hexx/message_spec.rb
218
- - spec/hexx/null_spec.rb
219
- - spec/hexx/helpers/parameters_spec.rb
220
- - spec/hexx/helpers/messages_spec.rb
221
- - spec/hexx/helpers/validations_spec.rb
222
- - spec/hexx/helpers/exceptions_spec.rb
223
- - spec/hexx/service_invalid_spec.rb
224
- - spec/hexx/coercible_spec.rb
225
- - spec/hexx/dependable_spec.rb
226
- - spec/hexx/name_spec.rb
227
- - spec/hexx/configurable_spec.rb
228
- - spec/support/matchers/methods.rb
229
- - spec/support/initializers/garbage_collection.rb
230
- - spec/support/initializers/i18n.rb
231
- - spec/support/initializers/focus.rb
232
- - spec/support/initializers/random_order.rb
233
- - spec/support/initializers/rspec.rb
234
- - Rakefile
235
- - ".rubocop.yml"
120
+ - spec/tests/lib/generator_spec.rb
121
+ - spec/tests/lib/name_spec.rb
236
122
  has_rdoc:
@@ -1,371 +0,0 @@
1
- = Hexx
2
-
3
- {<img src="http://img.shields.io/gem/v/hexx.svg?style=flat" alt="Gem Version" />}[https://rubygems.org/gems/hexx]
4
- {<img src="http://img.shields.io/travis/nepalez/hexx.svg?style=flat" alt="Bild Status" />}[https://travis-ci.org/nepalez/hexx]
5
- {<img src="http://img.shields.io/codeclimate/github/nepalez/hexx.svg?style=flat" alt="Code Metrics" />}[https://codeclimate.com/github/nepalez/hexx]
6
- {<img src="http://img.shields.io/gemnasium/nepalez/hexx.svg?style=flat" alt="Dependency Status" />}[https://gemnasium.com/nepalez/hexx]
7
- {<img src="http://img.shields.io/coveralls/nepalez/hexx.svg?style=flat" alt="Coverage Status" />}[https://coveralls.io/r/nepalez/hexx]
8
- {<img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="License" />}[https://github.com/nepalez/hexx/blob/master/LICENSE.rdoc]
9
-
10
- The base library for domain models.
11
-
12
- == API
13
-
14
- Includes classes and modules as below:
15
- <tt>Hexx::Service</tt>:: The base class for service objects.
16
- <tt>Hexx::Message</tt>:: The message provided by service objects.
17
- <tt>Hexx::Null</tt>:: The Null object.
18
- <tt>Hexx::Coercible</tt>:: The module that makes model attributes coercible.
19
- <tt>Hexx::Configurable</tt>:: The module to convert a core domain module to the
20
- dependency injection framework.
21
- <tt>Hexx::Dependable</tt>:: The module provides +depends_on+ class helper methodto
22
- to implement the setter dependency injection.
23
-
24
- The module is expected to be used in PORO domains for Ruby MRI 2.1+.
25
-
26
- For usage in active record bases domains consider the
27
- { hexx-active_record }[https://github.com/nepalez/hexx-active_record]
28
- gem extension.
29
-
30
- == Installation
31
-
32
- Add this line to your application's Gemfile:
33
-
34
- gem "hexx", "~> 2.0"
35
-
36
- And then execute:
37
-
38
- $ bundle
39
-
40
- Or install it yourself as:
41
-
42
- $ gem install hexx
43
-
44
- == Usage
45
-
46
- === Hexx::Configurable
47
-
48
- Adds the +configure+ and +depends_on+ helpers to the module to convert it
49
- to the {dependency injection container}[http://en.m.wikipedia.org/wiki/Dependency_injection].
50
-
51
- Extend the base class of the gem and declare the module dependencies from
52
- outer classes and modules with the +depend_on+ helper:
53
-
54
- # lib/my_gem.rb
55
- module MyGem
56
- extend Hexx::Configurable
57
-
58
- depend_on :get_item, :add_item
59
- end
60
-
61
- Inject the dependencies in the gem config with the +configure+ wrapper:
62
-
63
- # config/dependencies.rb
64
- MyGem.configure do |c|
65
- c.get_item = OuterModule::Services::Get
66
- c.add_item = OuterModule::Services::Add
67
- end
68
-
69
- Use the dependencies somewhere inside the code of the gem:
70
-
71
- MyGem.get_item # => OuterModule::Services::Get
72
-
73
- === Hexx::Coercible
74
-
75
- Adds the +attr_coerced+ class helper method to the PORO model.
76
-
77
- Provide a value object that accepts <tt>0..1</tt> arguments.
78
-
79
- # app/attributes/coercer.rb
80
- class Coercer < MultiByte::Chars
81
- def self.new(source = nil)
82
- return unless source
83
- end
84
-
85
- def initialize(source)
86
- # ...
87
- end
88
- end
89
-
90
- Extend the model with a +Coercible+ module and declare its attributes
91
- with the +attr_coerced+ helper.
92
-
93
- # app/models/some_model.rb
94
- class SomeModel
95
- extend Hexx::Coercible
96
-
97
- attr_coerced :name, type: Coercer
98
- end
99
-
100
- Both the getter and setter will return the coerced value, provided by
101
- the +Coercer+ class.
102
-
103
- object = SomeModel.new name: "Ivo"
104
- object.name
105
- # #<Coercer @wrapped_string="Ivo" >
106
-
107
- Be careful when designing a coercer class. Its constructor should accept both
108
- the raw value (<tt>"Ivo"</tt>) and the coerced one (<tt>#<Coercer @wrapped_string = "Ivo"></tt>).
109
- This is needed because the coercer works twofold - it coerces both the
110
- setter and getter. The getter coercer will take the coerced value.
111
-
112
- This feature is added for compatibility with +ActiveRecord+ attributes
113
- whose getters gives raw values from a database.
114
-
115
- *Note*: The coercer from the +hexx+ gem itself won't work for +ActiveRecord+ models.
116
- Use the +hexx-active_record+ gem instead. The gem extends the +Coercible+ model
117
- so that the +attr_coerced+ reloads +ActiveRecord+ attributes properly.
118
-
119
- === Hexx::Service
120
-
121
- Inherit services from the <tt>Hexx::Service</tt> class.
122
-
123
- The class implements a set of patterns:
124
-
125
- * The {Service object pattern}[http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/] used to decouple business logics from both the models and web delivery mechanism (such as +Rails+).
126
- * The {Observer pattern}[http://reefpoints.dockyard.com/2013/08/20/design-patterns-observer-pattern.html] to follow the {Tell, don't ask}[http://martinfowler.com/bliki/TellDontAsk.html] design princible.
127
- The pattern is implemented with the help of {wisper}[http://www.github.com/krisleech/wisper] gem by Kris Leech.
128
-
129
- A typical service object is shown below:
130
-
131
- # app/services/add_item.rb
132
- require 'hexx'
133
- class AddItem < Hexx::Service
134
-
135
- # Whitelists parameters and defines corresponding attributes.
136
- # For example, the #name attribute is avalable.
137
- allow_params :name
138
-
139
- # Defines some validation using ActiveModel::Validations helpers.
140
- validate :name, presence: true
141
-
142
- # Runs a service
143
- def run
144
- run!
145
- rescue Found
146
- # Publishes notification in case the item exists.
147
- publish :found, item
148
- rescue => err
149
- publish :error, err.messages
150
- else
151
- # The notification to be published if the #run! raises nothing.
152
- publish :added, item
153
- end
154
-
155
- private
156
-
157
- attr_accessor :item
158
-
159
- # Declares specific exceptions to be raised by the #run! method
160
- # and processed by the #run differently.
161
- #
162
- # All other exceptions will be re-raised as Hexx::Service::Invalid
163
- # and processed by publishing the :error notification.
164
- raises :Found
165
-
166
- # The sequence of the service steps. Any step can raise error to
167
- # be rescued in #run with publishing a corresponding notification.
168
- def run!
169
- find_item
170
- add_item
171
- end
172
-
173
- def find_item
174
- # The method runs another service and listens to its notifications
175
- # via private callback methods available to that service only.
176
- # The callback names should start from given prefix (:on_item_).
177
- run_service GetItem, :on_item, name: name
178
- end
179
-
180
- # The callback to listen to :found notification of the 'get_item' service.
181
- def on_item_found(item, *)
182
- @item = item
183
- # Adds the Hexx::Message object of type "error" to the +messages+ array.
184
- # The :not_found key will be translated in context of current service:
185
- # {locale}.activemodule.messages.models.add_item.not_found
186
- add_message "error", :not_found
187
- fail Found # goes to publishing a result
188
- end
189
-
190
- # The callback to listen to :error notification of the 'get_item' service.
191
- # that is expected to publish a list of error messages.
192
- def on_item_error(*, messages)
193
- # The helper raises Hexx::Service::Invalid exception where the messages
194
- # are added to. The exception will be rescued by the #run method.
195
- on_error(messages)
196
- end
197
-
198
- def add_item
199
- # The escape re-raises any error as the Hexx::Service::Invalid
200
- # with the array of Hexx::Message messages.
201
- escape { @item = Item.create! name: name }
202
- end
203
- end
204
-
205
- A typical usage of the service (in a Rails controller):
206
-
207
- # app/controllers/items_controller.rb
208
- class ItemsController < ActionController::Base
209
-
210
- # Creates an item with given name
211
- def create
212
- service = AddItem.new params.allow(:name)
213
- service.subscribe self, prefix: :on
214
- service.run
215
- end
216
-
217
- # Publishes a success message
218
- def on_created(item, messages)
219
- @item = item
220
- self.messages.concat messages
221
- render "created", status: 201
222
- end
223
-
224
- # Responds with 304 (not changed)
225
- def on_found(*)
226
- render nothing: true, status: 304
227
- end
228
-
229
- # Publishes an error messages
230
- def on_error(messages)
231
- @messages = messages
232
- render "error", status: 422
233
- end
234
- end
235
-
236
- The controller knows nothing about the action itself. It only needs to
237
- send the request to a corresponding service and sort out the notifications.
238
-
239
- === Hexx::Message
240
-
241
- The messages published by the service has two attributes: +type+ and +text+.
242
-
243
- message = Hexx::Message.new type: :error, text: "some error message"
244
- message.type # => "error"
245
- message.text # => "some error message"
246
-
247
- Inside a service use the +add_message+ to add message to the +messages+ array:
248
-
249
- add_message "error", "text"
250
- messages # => [#<Hexx::Message @type="error", @text="text" >]
251
-
252
- === Hexx::Dependable
253
-
254
- The module provides the +depends_on+ class helper for {setter-based dependency injection}[http://brandonhilkert.com/blog/a-ruby-refactor-exploring-dependency-injection-options/]. It allows decoupling the service from another services it uses.
255
-
256
- Extend the service class and declare the dependencies with an optional default
257
- implementation (see example above):
258
-
259
- class AddItem < Hexx::Service
260
- extend Hexx::Dependable
261
-
262
- depends_on :get_item, default: GetItem
263
-
264
- # ...
265
-
266
- def find_item
267
- run_service get_item, :on_item, name: name
268
- end
269
- end
270
-
271
- Now the dependency can be injected afterwards:
272
-
273
- # The default implementation
274
- service = AddItem.new
275
- service.get_item # => GetItem
276
-
277
- # Change it to other implementation
278
- service.get_item = FindItem
279
- service.get_item # => FindItem
280
-
281
- # Reset it to default by assigning +nil+
282
- service.get_item = nil
283
- service.get_item # => GetItem
284
-
285
- It is possible to test a service in isolation from its dependencies.
286
-
287
- # spec/services/my_service_spec.rb
288
- describe AddService do
289
-
290
- describe "#run" do
291
-
292
- # Mock a service objects to publish expected notifications
293
- let(:object) { Hexx::Service }
294
- before { allow(object).to receive(:run) { publish :not_found } }
295
-
296
- # Inject a class dependency
297
- before { service.get_item = class_double "Hexx::Service", new: object }
298
-
299
- # ...
300
- end
301
- end
302
-
303
- === Hexx::Name
304
-
305
- The module provides the base class for name constructors for various instances.
306
-
307
- It declares helpers:
308
-
309
- * +object+:: the attribute for the object to be named
310
- * +locale+:: the locale to name the object in
311
- * +scope+:: the current translation scope
312
- * +t(value, options):: the translator of the value in current scope and locale
313
-
314
- Inherit the class and reload its <tt>#for</tt> instance method:
315
-
316
- module Names
317
- class Hash < Hexx::Name
318
- def for
319
- user ? t(:user, value: user) : t(:empty)
320
- end
321
-
322
- def user
323
- value = object[:user]
324
- value ? value.upcase : nil
325
- end
326
- end
327
- end
328
-
329
- Add the necessary translations:
330
-
331
- # config/locales/ru.yml
332
- ru:
333
- activemodel:
334
- names/hash:
335
- user: "чувак %{value}"
336
- empty: "н/д"
337
-
338
- # config/locales/en.yml
339
- en:
340
- activemodel:
341
- names/hash:
342
- user: "dude %{value}"
343
- empty: "-"
344
-
345
- Then use its <tt>for</tt> class method to construct names:
346
-
347
- Names::Hash.for { user: "Ivan" }, locale: :en
348
- # => "dude IVAN"
349
-
350
- Names::Hash.for { user: nil }, locale: :ru
351
- # => "н/д"
352
-
353
- === Hexx::Null
354
-
355
- The class implements the {Null object}[http://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object] pattern. The object:
356
-
357
- * responds like +nil+ to <tt><=></tt>, +eq?+, +nil?+, +false?+, +true?+, +to_s+,
358
- +to_i+, +to_f+, +to_c+, +to_r+, +to_nil+
359
- * responds with +self+ to any other method call
360
-
361
- Providing {this problem}[http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/], use double negation in logical expressions:
362
-
363
- # Though:
364
- Hexx::Null && true # => true
365
-
366
- # But:
367
- !!Hexx::Null && true # => false
368
-
369
- == License
370
-
371
- The project is distributed under the {MIT LICENSE}[LICENSE.rdoc].