rails-patterns 0.9.0 → 0.10.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
2
  SHA256:
3
- metadata.gz: f61449cb2feed58c4d3636c7e8cb06b9d6f93f7192861eb5c4567e114054610f
4
- data.tar.gz: '08e88e618593983f3fd0b82af0f18b42792e4413a40c2711befffcf06be29106'
3
+ metadata.gz: acffaa9187d107e66c029e063f1d9cd5fbb2a3f16af7c2f747f166bc3bafab64
4
+ data.tar.gz: '014944374d20b4e6113c2946e25c963aaebd5841dad52cf960f85896c29930e5'
5
5
  SHA512:
6
- metadata.gz: 0aac7fae367e8d81c4340f36680671f5ed4f292f72c956f8d1f3b28e9af87cb2c5d3257996be507af299dc0f27e45e07a848d7d3492b9c3f3c8a0a1a8278a1be
7
- data.tar.gz: 2279865d364019b49ed9621eb325459f70c7a5f63d873e147ec16700d81248fcc6dbc5108e27cf919e554d4a5fc23a7c710fece598b5255223ce3fe838843c82
6
+ metadata.gz: def79504af62d2295806ab1a6e35261ad413d9205cfe36c41d4ae110068cfb5afe267aee4b194dbe2199616ca2ca976d6ffc63d5ca2166875b73d80c1e3fc9df
7
+ data.tar.gz: 84033ea6eb230ddf0436bda70889f4f62d46bb734d490635f564232b00bd199cdca595729e0eddae5055679e6575debcc19ed0385236e47b01b253510c86df8c
data/README.md CHANGED
@@ -24,11 +24,11 @@ gem "rails-patterns"
24
24
  Then `bundle install`
25
25
 
26
26
  ## Query
27
-
27
+
28
28
  ### When to use it
29
29
 
30
- One should consider using query objects pattern when in need to perform complex querying on active record relation.
31
- Usually one should avoid using scopes for such purpose.
30
+ One should consider using query objects pattern when in need to perform complex querying on active record relation.
31
+ Usually one should avoid using scopes for such purpose.
32
32
  As a rule of thumb, if scope interacts with more than one column and/or joins in other tables, it should be moved to query object.
33
33
  Also whenever a chain of scopes is to be used, one should consider using query object too.
34
34
  Some more information on using query objects can be found in [this article](https://medium.com/@blazejkosmowski/essential-rubyonrails-patterns-part-2-query-objects-4b253f4f4539).
@@ -98,9 +98,9 @@ Service objects are also useful for handling processes involving multiple steps.
98
98
  * It is recommended for `#call` method to be the only public method of service object (besides state readers)
99
99
  * It is recommended to name service object classes after commands (e.g. `ActivateUser` instead of `UserActivation`)
100
100
 
101
- ### Other
101
+ ### Other
102
102
 
103
- A bit higher level of abstraction is provided by [business_process gem](https://github.com/Selleo/business_process).
103
+ A bit higher level of abstraction is provided by [business_process gem](https://github.com/Selleo/business_process).
104
104
 
105
105
  ### Examples
106
106
 
@@ -396,13 +396,13 @@ However, from the actual usage perspective, it usually easier to conceptually de
396
396
  #### Declaration
397
397
 
398
398
  ```ruby
399
- class OrderIsSentRule < Rule
399
+ class OrderIsSentRule < Patterns::Rule
400
400
  def satisfied?
401
401
  subject.sent?
402
402
  end
403
403
  end
404
404
 
405
- class OrderIsPaidRule < Rule
405
+ class OrderIsPaidRule < Patterns::Rule
406
406
  def satisfied?
407
407
  subject.paid?
408
408
  end
@@ -412,7 +412,7 @@ class OrderIsPaidRule < Rule
412
412
  end
413
413
  end
414
414
 
415
- OrderCompletedNotificationRuleset = Class.new(Ruleset)
415
+ OrderCompletedNotificationRuleset = Class.new(Patterns::Ruleset)
416
416
  OrderCompletedNotificationRuleset.
417
417
  add_rule(:order_is_sent_rule).
418
418
  add_rule(:order_is_paid_rule)
@@ -437,4 +437,4 @@ ResendOrderNotification.call(order) if OrderCompletedNotificationRuleset.new(ord
437
437
 
438
438
  Software development teams with an entrepreneurial sense of ownership at their core delivering great digital products and building culture people want to belong to. We are a community of engaged co-workers passionate about crafting impactful web solutions which transform the way our clients do business.
439
439
 
440
- All names and logos for [Selleo](https://selleo.com/about) are trademark of Selleo sp. z o. o. sp. k.
440
+ All names and logos for [Selleo](https://selleo.com/about) are trademark of Selleo Labs Sp. z o.o. (formerly Selleo Sp. z o.o. Sp.k.)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.10.0
data/lib/patterns/rule.rb CHANGED
@@ -1,25 +1,27 @@
1
- class Rule
2
- def initialize(subject)
3
- @subject = subject
4
- end
1
+ module Patterns
2
+ class Rule
3
+ def initialize(subject)
4
+ @subject = subject
5
+ end
5
6
 
6
- def satisfied?
7
- raise NotImplementedError
8
- end
7
+ def satisfied?
8
+ raise NotImplementedError
9
+ end
9
10
 
10
- def not_applicable?
11
- false
12
- end
11
+ def not_applicable?
12
+ false
13
+ end
13
14
 
14
- def applicable?
15
- !not_applicable?
16
- end
15
+ def applicable?
16
+ !not_applicable?
17
+ end
17
18
 
18
- def forceable?
19
- true
20
- end
19
+ def forceable?
20
+ true
21
+ end
21
22
 
22
- private
23
+ private
23
24
 
24
- attr_reader :subject
25
+ attr_reader :subject
26
+ end
25
27
  end
@@ -1,69 +1,71 @@
1
- class Ruleset
2
- class EmptyRuleset < StandardError; end
1
+ module Patterns
2
+ class Ruleset
3
+ class EmptyRuleset < StandardError; end
3
4
 
4
- class << self
5
- attr_accessor :rule_names
6
- end
5
+ class << self
6
+ attr_accessor :rule_names
7
+ end
7
8
 
8
- def self.rules
9
- (rule_names || []).map do |rule_name|
10
- rule_name.to_s.classify.constantize
9
+ def self.rules
10
+ (rule_names || []).map do |rule_name|
11
+ rule_name.to_s.classify.constantize
12
+ end
11
13
  end
12
- end
13
14
 
14
- def self.add_rule(rule_name)
15
- self.rule_names ||= []
16
- self.rule_names << rule_name.to_sym
17
- self
18
- end
15
+ def self.add_rule(rule_name)
16
+ self.rule_names ||= []
17
+ self.rule_names << rule_name.to_sym
18
+ self
19
+ end
19
20
 
20
- def initialize(subject = nil)
21
- raise EmptyRuleset if self.class.rules.empty?
21
+ def initialize(subject = nil)
22
+ raise EmptyRuleset if self.class.rules.empty?
22
23
 
23
- @rules = self.class.rules.map { |rule| rule.new(subject) }
24
- end
24
+ @rules = self.class.rules.map { |rule| rule.new(subject) }
25
+ end
25
26
 
26
- def satisfied?(force: false)
27
- rules.all? do |rule|
28
- rule.satisfied? ||
29
- rule.not_applicable? ||
30
- (force && rule.forceable?)
27
+ def satisfied?(force: false)
28
+ rules.all? do |rule|
29
+ rule.satisfied? ||
30
+ rule.not_applicable? ||
31
+ (force && rule.forceable?)
32
+ end
31
33
  end
32
- end
33
34
 
34
- def not_satisfied?
35
- !satisfied?
36
- end
35
+ def not_satisfied?
36
+ !satisfied?
37
+ end
37
38
 
38
- def applicable?
39
- !not_applicable?
40
- end
39
+ def applicable?
40
+ !not_applicable?
41
+ end
41
42
 
42
- def not_applicable?
43
- rules.all?(&:not_applicable?)
44
- end
43
+ def not_applicable?
44
+ rules.all?(&:not_applicable?)
45
+ end
45
46
 
46
- def forceable?
47
- rules.all? do |rule|
48
- rule.forceable? ||
49
- rule.not_applicable? ||
50
- rule.satisfied?
47
+ def forceable?
48
+ rules.all? do |rule|
49
+ rule.forceable? ||
50
+ rule.not_applicable? ||
51
+ rule.satisfied?
52
+ end
51
53
  end
52
- end
53
54
 
54
- def each(&block)
55
- return enum_for(:each) unless block_given?
55
+ def each(&block)
56
+ return enum_for(:each) unless block_given?
56
57
 
57
- rules.each do |rule_or_ruleset|
58
- if rule_or_ruleset.is_a?(Ruleset)
59
- rule_or_ruleset.each(&block)
60
- else
61
- yield rule_or_ruleset
58
+ rules.each do |rule_or_ruleset|
59
+ if rule_or_ruleset.is_a?(Ruleset)
60
+ rule_or_ruleset.each(&block)
61
+ else
62
+ yield rule_or_ruleset
63
+ end
62
64
  end
63
65
  end
64
- end
65
66
 
66
- private
67
+ private
67
68
 
68
- attr_reader :rules
69
+ attr_reader :rules
70
+ end
69
71
  end
@@ -1,19 +1,21 @@
1
1
  # StrongRuleset is not satisfied and not forceable if any of rules is not applicable
2
2
 
3
- class StrongRuleset < Ruleset
4
- def satisfied?(force: false)
5
- rules.all? do |rule|
6
- (rule.applicable? && rule.satisfied?) || (force && rule.forceable?)
3
+ module Patterns
4
+ class StrongRuleset < Ruleset
5
+ def satisfied?(force: false)
6
+ rules.all? do |rule|
7
+ (rule.applicable? && rule.satisfied?) || (force && rule.forceable?)
8
+ end
7
9
  end
8
- end
9
10
 
10
- def not_applicable?
11
- rules.any?(&:not_applicable?)
12
- end
11
+ def not_applicable?
12
+ rules.any?(&:not_applicable?)
13
+ end
13
14
 
14
- def forceable?
15
- rules.all? do |rule|
16
- (rule.applicable? && rule.forceable?) || rule.satisfied?
15
+ def forceable?
16
+ rules.all? do |rule|
17
+ (rule.applicable? && rule.forceable?) || rule.satisfied?
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: rails-patterns 0.9.0 ruby lib
5
+ # stub: rails-patterns 0.10.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "rails-patterns".freeze
9
- s.version = "0.9.0"
9
+ s.version = "0.10.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Stevo".freeze]
14
- s.date = "2021-06-25"
14
+ s.date = "2021-12-10"
15
15
  s.description = "A collection of lightweight, standardized, rails-oriented patterns.".freeze
16
16
  s.email = "b.kosmowski@selleo.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -1,18 +1,18 @@
1
- RSpec.describe Rule do
1
+ RSpec.describe Patterns::Rule do
2
2
  after(:each) do
3
3
  Object.send(:remove_const, :CustomRule) if defined?(CustomRule)
4
4
  end
5
5
 
6
6
  it 'requires subject as the first argument' do
7
- CustomRule = Class.new(Rule)
7
+ CustomRule = Class.new(Patterns::Rule)
8
8
 
9
9
  expect { CustomRule.new }.to raise_error ArgumentError
10
10
  expect { CustomRule.new(Object.new) }.not_to raise_error
11
11
  end
12
12
 
13
13
  it 'requires #satisfied? method to be defined' do
14
- InvalidCustomRule = Class.new(Rule)
15
- CustomRule = Class.new(Rule) do
14
+ InvalidCustomRule = Class.new(Patterns::Rule)
15
+ CustomRule = Class.new(Patterns::Rule) do
16
16
  def satisfied?
17
17
  true
18
18
  end
@@ -27,7 +27,7 @@ RSpec.describe Rule do
27
27
  it 'returns true' do
28
28
  article = OpenStruct.new('published?' => true, 'deleted?' => false)
29
29
 
30
- ArticleIsPublishedRule = Class.new(Rule) do
30
+ ArticleIsPublishedRule = Class.new(Patterns::Rule) do
31
31
  def satisfied?
32
32
  subject.published?
33
33
  end
@@ -1,8 +1,8 @@
1
- RSpec.describe Ruleset do
1
+ RSpec.describe Patterns::Ruleset do
2
2
  context 'when empty ruleset is initialized' do
3
3
  it 'raises an error' do
4
- empty_ruleset_klass = Class.new(Ruleset)
5
- custom_ruleset_klass = Class.new(Ruleset)
4
+ empty_ruleset_klass = Class.new(Patterns::Ruleset)
5
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
6
6
  subject = double
7
7
 
8
8
  with_mocked_rules do |rules|
@@ -12,7 +12,7 @@ RSpec.describe Ruleset do
12
12
  expect { custom_ruleset_klass.new(subject) }.not_to raise_error
13
13
  end
14
14
 
15
- expect { empty_ruleset_klass.new(subject) }.to raise_error Ruleset::EmptyRuleset
15
+ expect { empty_ruleset_klass.new(subject) }.to raise_error Patterns::Ruleset::EmptyRuleset
16
16
  end
17
17
  end
18
18
 
@@ -24,7 +24,7 @@ RSpec.describe Ruleset do
24
24
  rules << mock_rule(:rule_1, is_forceable: true)
25
25
  rules << mock_rule(:rule_2, is_forceable: true)
26
26
 
27
- custom_ruleset_klass = Class.new(Ruleset)
27
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
28
28
  custom_ruleset_klass.add_rule(:rule_1)
29
29
  custom_ruleset_klass.add_rule(:rule_2)
30
30
 
@@ -40,7 +40,7 @@ RSpec.describe Ruleset do
40
40
  rules << mock_rule(:rule_1, is_forceable: false, is_satisfied: false, is_applicable: true)
41
41
  rules << mock_rule(:rule_2, is_forceable: true)
42
42
 
43
- custom_ruleset_klass = Class.new(Ruleset)
43
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
44
44
  custom_ruleset_klass.add_rule(:rule_1)
45
45
  custom_ruleset_klass.add_rule(:rule_2)
46
46
 
@@ -60,7 +60,7 @@ RSpec.describe Ruleset do
60
60
  )
61
61
  rules << mock_rule(:rule_2, is_forceable: true)
62
62
 
63
- custom_ruleset_klass = Class.new(Ruleset)
63
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
64
64
  custom_ruleset_klass.add_rule(:rule_1)
65
65
  custom_ruleset_klass.add_rule(:rule_2)
66
66
 
@@ -81,7 +81,7 @@ RSpec.describe Ruleset do
81
81
  )
82
82
  rules << mock_rule(:rule_2, is_forceable: true)
83
83
 
84
- custom_ruleset_klass = Class.new(Ruleset)
84
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
85
85
  custom_ruleset_klass.add_rule(:rule_1)
86
86
  custom_ruleset_klass.add_rule(:rule_2)
87
87
 
@@ -100,7 +100,7 @@ RSpec.describe Ruleset do
100
100
  rules << mock_rule(:rule_1, is_applicable: false)
101
101
  rules << mock_rule(:rule_2, is_applicable: false)
102
102
 
103
- custom_ruleset_klass = Class.new(Ruleset)
103
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
104
104
  custom_ruleset_klass.add_rule(:rule_1)
105
105
  custom_ruleset_klass.add_rule(:rule_2)
106
106
 
@@ -116,7 +116,7 @@ RSpec.describe Ruleset do
116
116
  rules << mock_rule(:rule_1, is_applicable: false)
117
117
  rules << mock_rule(:rule_2, is_applicable: true)
118
118
 
119
- custom_ruleset_klass = Class.new(Ruleset)
119
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
120
120
  custom_ruleset_klass.add_rule(:rule_1)
121
121
  custom_ruleset_klass.add_rule(:rule_2)
122
122
 
@@ -134,7 +134,7 @@ RSpec.describe Ruleset do
134
134
  rules << mock_rule(:rule_1)
135
135
  rules << mock_rule(:rule_2)
136
136
 
137
- custom_ruleset_klass = Class.new(Ruleset)
137
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
138
138
  custom_ruleset_klass.add_rule(:rule_1)
139
139
  custom_ruleset_klass.add_rule(:rule_2)
140
140
 
@@ -150,7 +150,7 @@ RSpec.describe Ruleset do
150
150
  rules << mock_rule(:rule_1)
151
151
  rules << mock_rule(:rule_2, is_satisfied: false)
152
152
 
153
- custom_ruleset_klass = Class.new(Ruleset)
153
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
154
154
  custom_ruleset_klass.add_rule(:rule_1)
155
155
  custom_ruleset_klass.add_rule(:rule_2)
156
156
 
@@ -165,7 +165,7 @@ RSpec.describe Ruleset do
165
165
  rules << mock_rule(:rule_1)
166
166
  rules << mock_rule(:rule_2, is_satisfied: false, is_applicable: false)
167
167
 
168
- custom_ruleset_klass = Class.new(Ruleset)
168
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
169
169
  custom_ruleset_klass.add_rule(:rule_1)
170
170
  custom_ruleset_klass.add_rule(:rule_2)
171
171
 
@@ -182,7 +182,7 @@ RSpec.describe Ruleset do
182
182
  rules << mock_rule(:rule_1)
183
183
  rules << mock_rule(:rule_2, is_satisfied: false, is_forceable: true)
184
184
 
185
- custom_ruleset_klass = Class.new(Ruleset)
185
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
186
186
  custom_ruleset_klass.add_rule(:rule_1)
187
187
  custom_ruleset_klass.add_rule(:rule_2)
188
188
 
@@ -198,7 +198,7 @@ RSpec.describe Ruleset do
198
198
  rules << mock_rule(:rule_1)
199
199
  rules << mock_rule(:rule_2, is_satisfied: false, is_forceable: false)
200
200
 
201
- custom_ruleset_klass = Class.new(Ruleset)
201
+ custom_ruleset_klass = Class.new(Patterns::Ruleset)
202
202
  custom_ruleset_klass.add_rule(:rule_1)
203
203
  custom_ruleset_klass.add_rule(:rule_2)
204
204
 
@@ -216,10 +216,10 @@ RSpec.describe Ruleset do
216
216
  rules << (_, rule_1 = mock_rule(:rule_1))
217
217
  rules << (_, rule_2 = mock_rule(:rule_2))
218
218
  rules << (_, rule_3 = mock_rule(:rule_3))
219
- custom_ruleset_klass_1 = Class.new(Ruleset)
219
+ custom_ruleset_klass_1 = Class.new(Patterns::Ruleset)
220
220
  custom_ruleset_klass_1.add_rule(:rule_1)
221
221
  custom_ruleset_klass_1.add_rule(:rule_2)
222
- Ruleset2 = Class.new(Ruleset)
222
+ Ruleset2 = Class.new(Patterns::Ruleset)
223
223
  Ruleset2.add_rule(:rule_3)
224
224
  custom_ruleset_klass_1.add_rule(:ruleset_2)
225
225
 
@@ -235,7 +235,7 @@ RSpec.describe Ruleset do
235
235
  private
236
236
 
237
237
  def mock_rule(rule_name, is_applicable: true, is_satisfied: true, is_forceable: true)
238
- klass = Object.const_set(rule_name.to_s.classify, Class.new(Rule))
238
+ klass = Object.const_set(rule_name.to_s.classify, Class.new(Patterns::Rule))
239
239
  rule = double(
240
240
  not_applicable?: !is_applicable,
241
241
  satisfied?: is_satisfied,
@@ -1,7 +1,7 @@
1
- RSpec.describe StrongRuleset do
1
+ RSpec.describe Patterns::StrongRuleset do
2
2
  it 'inherites from Ruleset' do
3
- custom_strong_ruleset_klass = Class.new(StrongRuleset)
4
- expect(custom_strong_ruleset_klass.ancestors).to include Ruleset
3
+ custom_strong_ruleset_klass = Class.new(Patterns::StrongRuleset)
4
+ expect(custom_strong_ruleset_klass.ancestors).to include Patterns::Ruleset
5
5
  end
6
6
 
7
7
  context 'when any of rules is not applicable' do
@@ -11,7 +11,7 @@ RSpec.describe StrongRuleset do
11
11
  rules << mock_rule(:rule_1, is_applicable: false)
12
12
  rules << mock_rule(:rule_2)
13
13
 
14
- custom_ruleset_klass = Class.new(StrongRuleset)
14
+ custom_ruleset_klass = Class.new(Patterns::StrongRuleset)
15
15
  custom_ruleset_klass.add_rule(:rule_1)
16
16
  custom_ruleset_klass.add_rule(:rule_2)
17
17
 
@@ -26,7 +26,7 @@ RSpec.describe StrongRuleset do
26
26
  rules << mock_rule(:rule_1, is_applicable: false, is_satisfied: false)
27
27
  rules << mock_rule(:rule_2)
28
28
 
29
- custom_ruleset_klass = Class.new(StrongRuleset)
29
+ custom_ruleset_klass = Class.new(Patterns::StrongRuleset)
30
30
  custom_ruleset_klass.add_rule(:rule_1)
31
31
  custom_ruleset_klass.add_rule(:rule_2)
32
32
 
@@ -41,7 +41,7 @@ RSpec.describe StrongRuleset do
41
41
  rules << mock_rule(:rule_1, is_applicable: false)
42
42
  rules << mock_rule(:rule_2)
43
43
 
44
- custom_ruleset_klass = Class.new(StrongRuleset)
44
+ custom_ruleset_klass = Class.new(Patterns::StrongRuleset)
45
45
  custom_ruleset_klass.add_rule(:rule_1)
46
46
  custom_ruleset_klass.add_rule(:rule_2)
47
47
 
@@ -53,7 +53,7 @@ RSpec.describe StrongRuleset do
53
53
  private
54
54
 
55
55
  def mock_rule(rule_name, is_applicable: true, is_satisfied: true, is_forceable: true)
56
- klass = Object.const_set(rule_name.to_s.classify, Class.new(Rule))
56
+ klass = Object.const_set(rule_name.to_s.classify, Class.new(Patterns::Rule))
57
57
  rule = double(
58
58
  not_applicable?: !is_applicable,
59
59
  applicable?: is_applicable,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-patterns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stevo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-25 00:00:00.000000000 Z
11
+ date: 2021-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord