ruby_dci 0.2.0 → 0.3.0

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
- SHA256:
3
- metadata.gz: 1b8372e74de2567e52902b236b08aa68779df450995d8a7d83f1d4241d37ede3
4
- data.tar.gz: 13677405fdba528931c0f1b745d4507ac745192b218b363dbcc8a027f93b514c
2
+ SHA1:
3
+ metadata.gz: a61a836ec90dab9c17d7f88cfd866ac24fd7e4ca
4
+ data.tar.gz: 892f6b68acb2b87b6ef653c6c19860b3eac95c37
5
5
  SHA512:
6
- metadata.gz: 8f6a20d6b9de2c3eb81d18c845c34a073848dcf31e401fbe263674dbf0bd4e2a2960c21820948f3ece3cfb65d22b10ba564c53d30cb0e82315a8b2ebce423c7f
7
- data.tar.gz: 6e750cba64ddb92652af80f1364b33c2c53b5c3ee02407203de45fd39f842056ecb4bb0d327a671c98afaf52712fb23afdeba000ae4de55b4303827b35031db7
6
+ metadata.gz: 3f81879bf07b9d8d4c335f9e7c53783edaf19d0cc3e1f0b6abf5f26d11edd3f696bfacd017925778f9d7b7fb93abc3258af419e27481f7cb5d0689e8c7430277
7
+ data.tar.gz: 888c5768b1f5c9d35454173eb91103ce3ad40914cb39f99e22b4898190e3b084fd033f3703d16b5eb725f39cc79ad03fc9c3be6ae2b40cafb06b663d2b74c89b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 0.3.0 (2018-05-24)
2
+
3
+ Features:
4
+
5
+ - Renamed `DCI::Configuration` accessors. `event_routes` is now `routes`, `route_methods` is now `router`, `raise_in_event_router` is now `raise_in_router`.
6
+ - `events` is not an instance variable defined in the context anymore, but has the same access style like the `context` itself. In the role don't push events to `context.events`, but to `context_events`.
7
+
8
+ Bugfixes:
9
+
10
+ - Added specs
11
+ - Added `README.md`
12
+ - Added `CHANGELOG.md`
13
+
1
14
  ## 0.2.0 (2018-05-19)
2
15
 
3
16
  Features:
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{ repo_name }" }
4
+
5
+ gem "coveralls", require: false
4
6
 
5
7
  # Specify your gem's dependencies in ruby_dci.gemspec
6
8
  gemspec
data/Gemfile.lock CHANGED
@@ -1,13 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_dci (0.2.0)
4
+ ruby_dci (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  coderay (1.1.2)
10
+ coveralls (0.8.21)
11
+ json (>= 1.8, < 3)
12
+ simplecov (~> 0.14.1)
13
+ term-ansicolor (~> 1.3)
14
+ thor (~> 0.19.4)
15
+ tins (~> 1.6)
10
16
  diff-lcs (1.3)
17
+ docile (1.1.5)
18
+ json (2.1.0)
11
19
  method_source (0.9.0)
12
20
  pry (0.11.3)
13
21
  coderay (~> 1.1.0)
@@ -26,12 +34,22 @@ GEM
26
34
  diff-lcs (>= 1.2.0, < 2.0)
27
35
  rspec-support (~> 3.7.0)
28
36
  rspec-support (3.7.1)
37
+ simplecov (0.14.1)
38
+ docile (~> 1.1.0)
39
+ json (>= 1.8, < 3)
40
+ simplecov-html (~> 0.10.0)
41
+ simplecov-html (0.10.2)
42
+ term-ansicolor (1.6.0)
43
+ tins (~> 1.0)
44
+ thor (0.19.4)
45
+ tins (1.16.3)
29
46
 
30
47
  PLATFORMS
31
48
  ruby
32
49
 
33
50
  DEPENDENCIES
34
51
  bundler (~> 1.16)
52
+ coveralls
35
53
  pry (~> 0.11.3)
36
54
  rake (~> 10.0)
37
55
  rspec (~> 3.0)
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  [![Build Status](https://travis-ci.org/egze/ruby_dci.svg?branch=master)](https://travis-ci.org/egze/ruby_dci)
2
+ [![Coverage Status](https://coveralls.io/repos/github/egze/ruby_dci/badge.svg?branch=master)](https://coveralls.io/github/egze/ruby_dci?branch=master)
2
3
 
3
4
  # RubyDci
4
5
 
@@ -9,7 +10,7 @@ A classic DCI implementation for ruby with some extra sugar. I've been using DCI
9
10
  Add this line to your application's Gemfile:
10
11
 
11
12
  ```ruby
12
- gem 'ruby_dci'
13
+ gem 'ruby_dci', require: 'dci'
13
14
  ```
14
15
 
15
16
  And then execute:
@@ -43,8 +44,8 @@ I configure the gem in `config/initializers/dci_configuration.rb`.
43
44
 
44
45
  ```ruby
45
46
  DCI.configure do |config|
46
- config.event_routes = Hash.new([])
47
- config.route_methods = EventRouteStore.new
47
+ config.routes = Hash.new([])
48
+ config.router = EventRouter.new
48
49
  config.transaction_class = ApplicationRecord
49
50
  config.raise_in_event_router = !Rails.env.production?
50
51
  config.on_exception_in_router = -> (exception) {}
@@ -55,7 +56,7 @@ end
55
56
 
56
57
  Usually you want your code to run in a transaction. Either everything runs fine, or nothing is saved. This is done by wrapping the executed code in a transaction block. I use ActiveRecord, but you can use whatever you want. Your class just needs to implement a `transaction` method that takes a block. If you don't want any transactions, you can either skip `config.transaction_class` completely, or set it to `DCI::NullTransaction`.
57
58
 
58
- ### config.event_routes
59
+ ### config.routes
59
60
 
60
61
  This is your mapping of events that may happen in the context. Key is a class name, and the value is an array of method names. Example:
61
62
 
@@ -65,7 +66,7 @@ This is your mapping of events that may happen in the context. Key is a class na
65
66
  }
66
67
  ```
67
68
 
68
- The system will know that it needs to execute `send_product_added_notification` from `config.route_methods` for every event of class `DomainEvents::ProductAddedToCart`. If you don't have any actions that you need to perform after a transaction, the just skip `config.event_routes` completely or set it to `Hash.new([])`.
69
+ The system will know that it needs to execute `send_product_added_notification` from `config.route_methods` for every event of class `DomainEvents::ProductAddedToCart`. If you don't have any actions that you need to perform after a transaction, then just skip `config.event_routes` completely or set it to `Hash.new([])`.
69
70
 
70
71
  I implement events as plain ruby Structs. Example:
71
72
 
@@ -79,12 +80,12 @@ end
79
80
 
80
81
  Why do I do it like this? It makes it easier to add other callbacks later. I can do it in one place instead of searching through hundreds of files. Also makes testing easier.
81
82
 
82
- ### config.route_methods
83
+ ### config.router
83
84
 
84
- This is a class that implements the methods for the `config.event_routes` mapping. Example:
85
+ This is a class that implements the methods for the `config.routes` mapping. Example:
85
86
 
86
87
  ```ruby
87
- class EventRouteStore
88
+ class EventRouter
88
89
 
89
90
  def send_product_added_notification(event)
90
91
  AddedToCartNotificationJob.perform_later(id: event.product.id)
@@ -106,7 +107,7 @@ config.raise_in_event_router = !Rails.env.production?
106
107
  In case there is an exception in the event router, you can provide a handler for the exception. It should be a lambda that receives an exception as a parameter. You can use it to log the exception. If you don't need any logging, just skip `config.on_exception_in_router` completely, or assign an empty lambda.
107
108
 
108
109
  ```ruby
109
- config.logger = -> (exception) { Rails.logger.error(exception) }
110
+ config.on_exception_in_router = -> (exception) { Rails.logger.error(exception) }
110
111
  ```
111
112
 
112
113
 
@@ -142,7 +143,7 @@ Couple of thigs to keep in mind:
142
143
 
143
144
  ### Role
144
145
 
145
- In a Rails app I put my roles in `app/roles`. Roles are plain ruby modules. You define a role by including `DCI::Role`.
146
+ In a Rails app I put my roles in `app/roles`. Roles are plain ruby modules. You define a role by including `DCI::Role`. A role has access to the `context` and to the `context_events` methods. You can push events to `context_events` to process them after the transaction.
146
147
 
147
148
  ```ruby
148
149
  module Customer
@@ -153,7 +154,7 @@ module Customer
153
154
  # do your thing
154
155
 
155
156
  # add event to the context
156
- context.events << DomainEvents::ProductAddedToCart.new(product)
157
+ context_events << DomainEvents::ProductAddedToCart.new(product)
157
158
  end
158
159
 
159
160
  end
data/lib/dci/accessor.rb CHANGED
@@ -5,5 +5,9 @@ module DCI
5
5
  Thread.current[:context]
6
6
  end
7
7
 
8
+ def context_events
9
+ Thread.current[:context_events]
10
+ end
11
+
8
12
  end
9
13
  end
@@ -1,17 +1,19 @@
1
1
  module DCI
2
2
  class Configuration
3
+
3
4
  attr_accessor :transaction_class,
4
- :event_routes,
5
- :route_methods,
6
- :raise_in_event_router,
7
- :on_exception_in_router
5
+ :routes,
6
+ :router,
7
+ :on_exception_in_router,
8
+ :raise_in_router
8
9
 
9
10
  def initialize
10
11
  @transaction_class = NullTransaction
11
- @event_routes = Hash.new([])
12
- @route_methods = nil
13
- @raise_in_event_router = false
14
- @on_exception_in_router = -> (exception) { }
12
+ @routes = Hash.new([])
13
+ @router = nil
14
+ @raise_in_router = false
15
+ @on_exception_in_router = -> (exception) {}
15
16
  end
17
+
16
18
  end
17
19
  end
data/lib/dci/context.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  module DCI
2
-
3
2
  module Context
4
3
 
5
4
  include EventRouter
@@ -16,8 +15,10 @@ module DCI
16
15
 
17
16
  def perform_in_transaction
18
17
  old_context = context
19
- @events = init_context_events
18
+ old_context_events = context_events
19
+
20
20
  self.context = self
21
+ self.context_events = []
21
22
 
22
23
  res = nil
23
24
 
@@ -25,33 +26,40 @@ module DCI
25
26
  res = call
26
27
  end
27
28
 
28
- route_events!(events)
29
+ route_events!(context_events)
29
30
  res
30
31
  ensure
31
32
  self.context = old_context
32
- self.events.clear
33
+ self.context_events = old_context_events
33
34
  end
34
35
 
35
36
  def context=(ctx)
36
37
  Thread.current[:context] = ctx
37
38
  end
38
39
 
40
+ def context_events=(ctx_events = [])
41
+ Thread.current[:context_events] = Array(ctx_events).compact.flatten
42
+ end
43
+
39
44
  def call
40
45
  raise NotImplementedError.new("implement me")
41
46
  end
42
47
 
43
48
  private
49
+
44
50
  def init_context_events
45
51
  []
46
52
  end
53
+
47
54
  end
48
55
 
49
56
  module ClassMethods
57
+
50
58
  def call(*args)
51
59
  new(*args).perform_in_transaction
52
60
  end
61
+
53
62
  end
54
63
 
55
64
  end
56
-
57
65
  end
@@ -1,5 +1,4 @@
1
1
  module DCI
2
-
3
2
  module EventRouter
4
3
 
5
4
  def route_events!(events)
@@ -7,10 +6,11 @@ module DCI
7
6
  end
8
7
 
9
8
  private
9
+
10
10
  def route_event!(event)
11
- DCI.configuration.event_routes[event.class].each do |callback|
11
+ DCI.configuration.routes[event.class].each do |callback|
12
12
  dispatch_catching_standard_errors do
13
- DCI.configuration.route_methods.send(callback, event)
13
+ DCI.configuration.router.send(callback, event)
14
14
  end
15
15
  end
16
16
  end
@@ -21,10 +21,9 @@ module DCI
21
21
  rescue StandardError => exception
22
22
  DCI.configuration.on_exception_in_router.call(exception) rescue nil
23
23
 
24
- raise exception if DCI.configuration.raise_in_event_router
24
+ raise exception if DCI.configuration.raise_in_router
25
25
  end
26
26
  end
27
27
 
28
28
  end
29
-
30
29
  end
@@ -1,7 +1,9 @@
1
1
  module DCI
2
2
  class NullTransaction
3
+
3
4
  def self.transaction
4
5
  yield
5
6
  end
7
+
6
8
  end
7
9
  end
data/lib/dci/version.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  module DCI
2
- VERSION = "0.2.0"
2
+
3
+ VERSION = "0.3.0".freeze
4
+
3
5
  end
data/lib/dci.rb CHANGED
@@ -7,8 +7,11 @@ require "dci/context"
7
7
  require "dci/role"
8
8
 
9
9
  module DCI
10
+
10
11
  class << self
11
- attr_accessor :configuration
12
+
13
+ #attr_accessor :configuration
14
+
12
15
  end
13
16
 
14
17
  def self.configuration
@@ -22,4 +25,5 @@ module DCI
22
25
  def self.configure
23
26
  yield(configuration)
24
27
  end
28
+
25
29
  end
data/ruby_dci.gemspec CHANGED
@@ -13,7 +13,6 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/egze/ruby_dci"
14
14
  spec.license = "MIT"
15
15
 
16
-
17
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
17
  f.match(%r{^(test|spec|features)/})
19
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_dci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksandr Lossenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-19 00:00:00.000000000 Z
11
+ date: 2018-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.7.3
118
+ rubygems_version: 2.6.13
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Opinionated DCI implementation for ruby.