evnt 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 63694dd6640e60116fa220f26d2c5c534434f488
4
- data.tar.gz: b8a2784a560444babd7ac31a9d43d4cf73b4be91
2
+ SHA256:
3
+ metadata.gz: 0d2cecb4f90544de842098f1f89110548ef2a2231504ac0cf47f821bf0abfbb3
4
+ data.tar.gz: 731c1460b90c981043850df9a5a5b6cc6b9a4d1d0b780859e2070cd0d94c8047
5
5
  SHA512:
6
- metadata.gz: 4c1381e123afa1b6dfac53d92086102a5d57167d90dbfbaa5e72c59af1aff1bf71ccd48766d33841e265c8875db73812a582600eb192e2d35ea0cb324559c795
7
- data.tar.gz: e1baebd245175ff2034607294c4e4836579d6f03148de64cbbc36b60211da29066dec7623263408799c5afbe1296d468f78c24628d614cf139a79ce2fb802252
6
+ metadata.gz: e93adc9ffeead5ee8632b41d1bee8a030376d1876f61bf6d8e5c4f077fb5efda56c7a3a92a62493a3e3f118a153be0436dc9c5eb6ee87cd335530efc7f9300c9
7
+ data.tar.gz: 69e531d6aa91fd78f31c75bd3eb4cc30e9848f917bde1e81e191959633736f85e4b3ae7638104df84ecaf5bdaf32f301f8ec6e1348deb44c02ffeffb7895b82d
data/README.md CHANGED
@@ -8,14 +8,25 @@ CQRS and Event Driven Development architecture for Ruby projects.
8
8
  - [Event](#event)
9
9
  - [Handler](#handler)
10
10
  - [Rails integration](#rails-integration)
11
+ - [Generators integration](#generators-integration)
12
+ - [Command generators](#command-generators)
13
+ - [Event generators](#event-generators)
14
+ - [Handler generators](#handler-generators)
15
+ - [Manual integration](#manual-integration)
11
16
  - [Development](#development)
12
17
 
13
- Full documentation here: https://ideonetwork.github.io/ruby-evnt/
18
+ Full documentation here: https://ideonetwork.github.io/evnt/
14
19
 
15
20
  ## Installation
16
21
 
17
22
  To use the gem you need to add it on your Gemfile
18
23
 
24
+ Latest version
25
+ ```ruby
26
+ gem 'evnt', git: 'https://github.com/ideonetwork/evnt'
27
+ ```
28
+
29
+ Legacy version
19
30
  ```ruby
20
31
  gem 'evnt'
21
32
  ```
@@ -30,7 +41,7 @@ Evnt is developed to be used over all kinds of projects and frameworks (like Rub
30
41
 
31
42
  ### Command
32
43
 
33
- Commands are used to run single tasks on the system. It's like a controller on an MVC architecture without the communication with the client.
44
+ Commands are used to run single tasks on the system. It's like a controller on an MVC architecture.
34
45
 
35
46
  Every command has three steps to execute:
36
47
 
@@ -44,15 +55,16 @@ An example of command should be:
44
55
  ```ruby
45
56
  class CreateOrderCommand < Evnt::Command
46
57
 
58
+ validates :user_id, type: :integer, presence: true
59
+ validates :product_id, type: :integer, presence: true
60
+ validates :quantity, type: :integer, presence: true
61
+
47
62
  to_normalize_params do
48
63
  params[:quantity] = params[:quantity].to_i
49
64
  end
50
65
 
51
66
  to_validate_params do
52
- # check params presence
53
- err 'User should be present' if params[:user_id].blank?
54
- err 'Product should be present' if params[:product_id].blank?
55
- err 'Quantity should be present' if params[:quantity].blank?
67
+ err 'Quantity should be positive' unless params[:quantity].positive?
56
68
  end
57
69
 
58
70
  to_validate_logic do
@@ -136,22 +148,6 @@ rescue => e
136
148
  end
137
149
  ```
138
150
 
139
- Some validations are similar for every command (like presence or paramter type), so you can also use general validations instead of **to_validate_params** block. An example of general validations should be:
140
-
141
- ```ruby
142
-
143
- class CreateOrderCommand < Evnt::Command
144
-
145
- validates :user_id, type: :integer, presence: true
146
- validates :product_id, type: :integer, presence: true
147
- validates :quantity, type: :integer, presence: true
148
-
149
- # ...
150
-
151
- end
152
-
153
- ```
154
-
155
151
  ### Event
156
152
 
157
153
  Events are used to save on a persistent data structure what happends on the system.
@@ -180,7 +176,10 @@ class CreateOrderEvent < Evnt::Event
180
176
 
181
177
  to_write_event do
182
178
  # save event on database
183
- Event.create(name: name, payload: payload)
179
+ Event.create(
180
+ name: name,
181
+ payload: payload
182
+ )
184
183
  end
185
184
 
186
185
  end
@@ -201,7 +200,7 @@ puts event.attributes # -> [:order_id, :user_id, :product_id, :quantity]
201
200
  puts event.payload # -> { order_id: 1, user_id: 128, product_id: 534, quantity: 10, evnt: { timestamp: 2017010101, name: 'create_order' } }
202
201
  ```
203
202
 
204
- The event payload should contain all event attributes and a reserver attributes "evnt" used to store the event timestamp and the event name.
203
+ The event payload should contain all event attributes and a reserved attributes "evnt" used to store the event timestamp and the event name.
205
204
 
206
205
  It's also possible to give datas to the event without save them on the event payload, to do this you shuld only use a key with "_" as first character. An example should be:
207
206
 
@@ -283,6 +282,101 @@ end
283
282
 
284
283
  Evnt can be used with Ruby on Rails to extends the MVC pattern.
285
284
 
285
+ ### Generators integration
286
+
287
+ There's a simple generator that can be used to inizialize a Rails application with Evnt.
288
+
289
+ ```shell
290
+
291
+ rails generate evnt:initializer
292
+
293
+ ```
294
+
295
+ This command should:
296
+
297
+ - Create an **application_command.rb** on app/commands directory.
298
+ - Create an **application_event.rb** on app/events directory.
299
+ - Create an **application_handler.rb** on app/handlers directory.
300
+ - Create tests for the three new classes added on the project.
301
+ - Added app/commands, app/events and app/handlers on config.autoload_paths setting of the application.
302
+
303
+ #### Command generators
304
+
305
+ Usage:
306
+
307
+ ```shell
308
+
309
+ rails generate evnt:command Authentication::LoginCommand email:string password:string ip_address:string
310
+
311
+ ```
312
+
313
+ Output:
314
+
315
+ ```ruby
316
+ # ./app/commands/authentication/login_command.rb
317
+ module Authentication
318
+ class LoginCommand < ApplicationCommand
319
+
320
+ validates :email, type: :string
321
+
322
+ validates :password, type: :string
323
+
324
+ validates :ip_address, type: :string
325
+
326
+ end
327
+ end
328
+ ```
329
+
330
+ #### Event generators
331
+
332
+ Usage:
333
+
334
+ ```shell
335
+
336
+ rails generate evnt:event Authentication::LoginEvent user_uuid ip_address
337
+
338
+ ```
339
+
340
+ Output:
341
+
342
+ ```ruby
343
+ # ./app/events/authentication/login_event.rb
344
+ module Authentication
345
+ class LoginEvent < ApplicationEvent
346
+
347
+ name_is :authentication_login_event
348
+
349
+ attributes_are :user_uuid, :ip_address
350
+
351
+ end
352
+ end
353
+ ```
354
+
355
+ #### Handler generators
356
+
357
+ Usage:
358
+
359
+ ```shell
360
+
361
+ rails generate evnt:handler AuthenticationHandler authentication_login_event authentication_signup_event
362
+
363
+ ```
364
+
365
+ Output:
366
+
367
+ ```ruby
368
+ # ./app/handlers/authentication_handler.rb
369
+ class AuthenticationHandler < ApplicationHandler
370
+
371
+ on :authentication_login_event do; end
372
+
373
+ on :authentication_signup_event do; end
374
+
375
+ end
376
+ ```
377
+
378
+ ### Manual integration
379
+
286
380
  To use the gem with Rails you need to create three folders inside the ./app project's path:
287
381
 
288
382
  - **./app/commands**
@@ -26,7 +26,7 @@ module Evnt
26
26
  #
27
27
  # * +exceptions+ - Boolean value used to activate the throw of excetions.
28
28
  ##
29
- def initialize(params)
29
+ def initialize(params = {})
30
30
  _init_command_data(params)
31
31
  _run_command_steps
32
32
  end
@@ -96,7 +96,7 @@ module Evnt
96
96
  )
97
97
 
98
98
  # raise error if command needs exceptions
99
- raise error if @options[:exceptions]
99
+ raise message if @options[:exceptions]
100
100
  end
101
101
 
102
102
  # Private functions:
@@ -111,7 +111,7 @@ module Evnt
111
111
  result: true,
112
112
  errors: []
113
113
  }
114
-
114
+
115
115
  # set options
116
116
  options = params[:_options] || {}
117
117
  @options = {
@@ -46,7 +46,7 @@ module Evnt
46
46
  # * +silent+ - Boolean value used to avoid the call of the notify method of
47
47
  # handlers.
48
48
  ##
49
- def initialize(params)
49
+ def initialize(params = {})
50
50
  _init_event_data(params)
51
51
  _validate_payload
52
52
  _run_event_steps
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Evnt.
3
4
  module Evnt
4
5
 
5
- ##
6
- # Constant containing the current gem version.
7
- ##
8
- VERSION = '3.0.1'
6
+ VERSION = '3.0.2'
9
7
 
10
8
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Evnt
6
+
7
+ # CommandGenerator.
8
+ class CommandGenerator < Rails::Generators::Base
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ argument :informations, type: :array, optional: false
13
+
14
+ def create_comand
15
+ path = informations.first.split('::')
16
+ @command_class = path.last.camelize
17
+ @command_modules = path - [path.last]
18
+ @command_params = (informations - [informations.first]).map do |data|
19
+ data = data.split(':')
20
+ data.length > 1 ? ":#{data.first}, type: :#{data.last}" : ":#{data.first}"
21
+ end
22
+
23
+ template(
24
+ './command/command.rb.erb',
25
+ command_path
26
+ )
27
+ end
28
+
29
+ def command_path
30
+ path = './app/commands'
31
+ @command_modules.map { |m| path = "#{path}/#{m.underscore}" }
32
+ path = "#{path}/#{@command_class.underscore}.rb"
33
+ path
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Evnt
6
+
7
+ # EventGenerator.
8
+ class EventGenerator < Rails::Generators::Base
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ argument :informations, type: :array, optional: false
13
+
14
+ def create_event
15
+ path = informations.first.split('::')
16
+ @event_class = path.last.camelize
17
+ @event_modules = path - [path.last]
18
+ @event_name = path.map(&:underscore).join('_')
19
+ @event_attributes = (informations - [informations.first]).map { |a| ":#{a}" }.join(', ')
20
+
21
+ template(
22
+ './event/event.rb.erb',
23
+ event_path
24
+ )
25
+ end
26
+
27
+ def event_path
28
+ path = './app/events'
29
+ @event_modules.map { |m| path = "#{path}/#{m.underscore}" }
30
+ path = "#{path}/#{@event_class.underscore}.rb"
31
+ path
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Evnt
6
+
7
+ # HandlerGenerator.
8
+ class HandlerGenerator < Rails::Generators::Base
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ argument :informations, type: :array, optional: false
13
+
14
+ def create_handler
15
+ path = informations.first.split('::')
16
+ @handler_class = path.last.camelize
17
+ @handler_modules = path - [path.last]
18
+ @handler_events = (informations - [informations.first])
19
+
20
+ template(
21
+ './handler/handler.rb.erb',
22
+ handler_path
23
+ )
24
+ end
25
+
26
+ def handler_path
27
+ path = './app/handlers'
28
+ @handler_modules.map { |m| path = "#{path}/#{m.underscore}" }
29
+ path = "#{path}/#{@handler_class.underscore}.rb"
30
+ path
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Evnt
6
+
7
+ # InitializerGenerator.
8
+ class InitializerGenerator < Rails::Generators::Base
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ def create_initializer
13
+ directory './initializer', './'
14
+ update_config_application
15
+ end
16
+
17
+ def update_config_application
18
+ application "config.autoload_paths += %W[\#{Rails.root}/app/commands]"
19
+ application "config.autoload_paths += %W[\#{Rails.root}/app/events]"
20
+ application "config.autoload_paths += %W[\#{Rails.root}/app/handlers]"
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ <% @command_modules.each_with_index do |module_name, index| %>
3
+ <%= ' ' * index %>module <%= module_name %>
4
+ <% end %>
5
+ <%= ' ' * @command_modules.length %># <%= @command_class %>
6
+ <%= ' ' * @command_modules.length %>class <%= @command_class %> < ApplicationCommand
7
+ <% @command_params.each do |param| %>
8
+ <%= ' ' * (@command_modules.length + 1) %>validates <%= param %>
9
+ <% end %>
10
+ <%= ' ' * @command_modules.length %>end
11
+ <% @command_modules.each_with_index do |_module_name, index| %>
12
+ <%= ' ' * (@command_modules.length - index - 1) %>end
13
+ <% end %>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ <% @event_modules.each_with_index do |module_name, index| %>
3
+ <%= ' ' * index %>module <%= module_name %>
4
+ <% end %>
5
+ <%= ' ' * @event_modules.length %># <%= @event_class %>
6
+ <%= ' ' * @event_modules.length %>class <%= @event_class %> < ApplicationEvent
7
+
8
+ <%= ' ' * (@event_modules.length + 1) %>name_is :<%= @event_name %>
9
+ <% unless @event_attributes.blank? %>
10
+ <%= ' ' * (@event_modules.length + 1) %>attributes_are <%= @event_attributes %>
11
+ <% end %>
12
+ <%= ' ' * @event_modules.length %>end
13
+ <% @event_modules.each_with_index do |_module_name, index| %>
14
+ <%= ' ' * (@event_modules.length - index - 1) %>end
15
+ <% end %>
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ <% @handler_modules.each_with_index do |module_name, index| %>
3
+ <%= ' ' * index %>module <%= module_name %>
4
+ <% end %>
5
+ <%= ' ' * @handler_modules.length %># <%= @handler_class %>
6
+ <%= ' ' * @handler_modules.length %>class <%= @handler_class %> < ApplicationHandler
7
+ <% @handler_events.each do |event| %>
8
+ <%= ' ' * (@handler_modules.length + 1) %>on :<%= event %> do; end
9
+ <% end %>
10
+ <%= ' ' * @handler_modules.length %>end
11
+ <% @handler_modules.each_with_index do |_module_name, index| %>
12
+ <%= ' ' * (@handler_modules.length - index - 1) %>end
13
+ <% end %>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ApplicationCommand.
4
+ class ApplicationCommand < Evnt::Command
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ApplicationEvent.
4
+ class ApplicationEvent < Evnt::Event
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ApplicationHandler.
4
+ class ApplicationHandler < Evnt::Handler
5
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ # ApplicationCommandTest.
6
+ class ApplicationCommandTest < ActiveSupport::TestCase
7
+
8
+ test 'it should be initialized' do
9
+ command = ApplicationCommand.new
10
+ assert_not_nil command
11
+ assert command.completed?
12
+ end
13
+
14
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ # ApplicationEventTest.
6
+ class ApplicationEventTest < ActiveSupport::TestCase
7
+
8
+ test 'it should be initialized' do
9
+ event = ApplicationEvent.new
10
+ assert_not_nil event
11
+ assert_not_nil event.payload
12
+ assert_not_nil event.payload[:evnt]
13
+ end
14
+
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ # ApplicationHandlerTest.
6
+ class ApplicationHandlerTest < ActiveSupport::TestCase
7
+
8
+ test 'it should be initialized' do
9
+ handler = ApplicationHandler.new
10
+ assert_not_nil handler
11
+ end
12
+
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evnt
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ideonetwork
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-14 00:00:00.000000000 Z
11
+ date: 2018-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,6 +67,19 @@ files:
67
67
  - lib/evnt/handler.rb
68
68
  - lib/evnt/validator.rb
69
69
  - lib/evnt/version.rb
70
+ - lib/generators/evnt/command_generator.rb
71
+ - lib/generators/evnt/event_generator.rb
72
+ - lib/generators/evnt/handler_generator.rb
73
+ - lib/generators/evnt/initializer_generator.rb
74
+ - lib/generators/evnt/templates/command/command.rb.erb
75
+ - lib/generators/evnt/templates/event/event.rb.erb
76
+ - lib/generators/evnt/templates/handler/handler.rb.erb
77
+ - lib/generators/evnt/templates/initializer/app/commands/application_command.rb
78
+ - lib/generators/evnt/templates/initializer/app/events/application_event.rb
79
+ - lib/generators/evnt/templates/initializer/app/handlers/application_handler.rb
80
+ - lib/generators/evnt/templates/initializer/test/commands/application_command_test.rb
81
+ - lib/generators/evnt/templates/initializer/test/events/application_event_test.rb
82
+ - lib/generators/evnt/templates/initializer/test/handlers/application_handler_test.rb
70
83
  homepage: http://ideonetwork.it/
71
84
  licenses:
72
85
  - MIT
@@ -87,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
100
  version: '0'
88
101
  requirements: []
89
102
  rubyforge_project:
90
- rubygems_version: 2.6.14
103
+ rubygems_version: 2.7.3
91
104
  signing_key:
92
105
  specification_version: 4
93
106
  summary: CQRS and Event Driven Development architecture for Ruby