rails-patterns 0.6.0 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +33 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +59 -50
- data/README.md +7 -4
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/patterns/calculation.rb +16 -2
- data/lib/patterns/service.rb +10 -6
- data/rails-patterns.gemspec +15 -7
- data/spec/helpers/custom_calculation.rb +16 -0
- data/spec/helpers/custom_calculation_script.rb +4 -0
- data/spec/helpers/rails_redis_cache_mock.rb +5 -0
- data/spec/patterns/calculation_spec.rb +37 -0
- data/spec/patterns/service_spec.rb +16 -1
- data/spec/spec_helper.rb +1 -0
- metadata +24 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ffa6ee8fff6415c7271eb4a38172148881cdd8866d0279e59abffd452b54f591
|
4
|
+
data.tar.gz: a8e077bf276d9a6a3a05f345d09085561ccb5f06996b7c7a8a01f4082cf329b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4e616146039004e697d7a2b3fc3ef89eaaaaf11779af4744a605d2102b967b8b4b9856147a1b111db5c801fde833ca19c0c5ba067a246977a14c14d7f9c2f54
|
7
|
+
data.tar.gz: 1e883e3cbfc21fc4e7135acc9b23dc4db7e05b2a4671cfe6d618f04b5df4d672c7ac8f76487ae34cce503fd2fdc51e2a0952dffbc66964943c85b8136a0dd509
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
runs-on: ubuntu-latest
|
19
|
+
strategy:
|
20
|
+
fail-fast: false
|
21
|
+
matrix:
|
22
|
+
ruby: [ '2.5', '2.6', '2.7' ]
|
23
|
+
name: RSpec for Ruby version ${{ matrix.ruby }}
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- uses: supercharge/redis-github-action@1.1.0
|
27
|
+
- name: Set up Ruby
|
28
|
+
uses: actions/setup-ruby@v1
|
29
|
+
with:
|
30
|
+
ruby-version: ${{ matrix.ruby }}
|
31
|
+
- run: gem install bundler
|
32
|
+
- run: bundle install
|
33
|
+
- run: bundle exec rspec
|
data/Gemfile
CHANGED
@@ -3,16 +3,19 @@ source "https://rubygems.org"
|
|
3
3
|
gem "activerecord", ">= 4.2.6"
|
4
4
|
gem "actionpack", ">= 4.2.6"
|
5
5
|
gem "virtus"
|
6
|
+
gem "ruby2_keywords"
|
6
7
|
|
7
8
|
# Add dependencies to develop your gem here.
|
8
9
|
# Include everything needed to run rake, tests, features, etc.
|
9
10
|
|
10
11
|
group :development do
|
11
12
|
gem "rspec"
|
12
|
-
gem "bundler", "~>
|
13
|
+
gem "bundler", "~> 2.0"
|
13
14
|
gem "juwelier", "~> 2.1.0"
|
14
15
|
end
|
15
16
|
|
16
17
|
group "test" do
|
17
18
|
gem "pry-rails"
|
19
|
+
gem "rspec_junit_formatter"
|
20
|
+
gem "redis"
|
18
21
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,60 +1,60 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
actionpack (
|
5
|
-
actionview (=
|
6
|
-
activesupport (=
|
7
|
-
rack (~> 2.0)
|
4
|
+
actionpack (6.0.3.1)
|
5
|
+
actionview (= 6.0.3.1)
|
6
|
+
activesupport (= 6.0.3.1)
|
7
|
+
rack (~> 2.0, >= 2.0.8)
|
8
8
|
rack-test (>= 0.6.3)
|
9
9
|
rails-dom-testing (~> 2.0)
|
10
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
11
|
-
actionview (
|
12
|
-
activesupport (=
|
10
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
11
|
+
actionview (6.0.3.1)
|
12
|
+
activesupport (= 6.0.3.1)
|
13
13
|
builder (~> 3.1)
|
14
14
|
erubi (~> 1.4)
|
15
15
|
rails-dom-testing (~> 2.0)
|
16
|
-
rails-html-sanitizer (~> 1.
|
17
|
-
activemodel (
|
18
|
-
activesupport (=
|
19
|
-
activerecord (
|
20
|
-
activemodel (=
|
21
|
-
activesupport (=
|
22
|
-
|
23
|
-
activesupport (5.1.4)
|
16
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
17
|
+
activemodel (6.0.3.1)
|
18
|
+
activesupport (= 6.0.3.1)
|
19
|
+
activerecord (6.0.3.1)
|
20
|
+
activemodel (= 6.0.3.1)
|
21
|
+
activesupport (= 6.0.3.1)
|
22
|
+
activesupport (6.0.3.1)
|
24
23
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
25
|
-
i18n (
|
24
|
+
i18n (>= 0.7, < 2)
|
26
25
|
minitest (~> 5.1)
|
27
26
|
tzinfo (~> 1.1)
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
28
|
+
addressable (2.7.0)
|
29
|
+
public_suffix (>= 2.0.2, < 5.0)
|
31
30
|
axiom-types (0.1.1)
|
32
31
|
descendants_tracker (~> 0.0.4)
|
33
32
|
ice_nine (~> 0.11.0)
|
34
33
|
thread_safe (~> 0.3, >= 0.3.1)
|
35
|
-
builder (3.2.
|
34
|
+
builder (3.2.4)
|
36
35
|
coderay (1.1.2)
|
37
36
|
coercible (1.0.0)
|
38
37
|
descendants_tracker (~> 0.0.1)
|
39
|
-
concurrent-ruby (1.
|
40
|
-
crass (1.0.
|
38
|
+
concurrent-ruby (1.1.6)
|
39
|
+
crass (1.0.6)
|
41
40
|
descendants_tracker (0.0.4)
|
42
41
|
thread_safe (~> 0.3, >= 0.3.1)
|
43
42
|
diff-lcs (1.3)
|
44
43
|
equalizer (0.0.11)
|
45
|
-
erubi (1.
|
46
|
-
faraday (0.
|
44
|
+
erubi (1.9.0)
|
45
|
+
faraday (0.17.3)
|
47
46
|
multipart-post (>= 1.2, < 3)
|
48
|
-
git (1.
|
47
|
+
git (1.7.0)
|
48
|
+
rchardet (~> 1.8)
|
49
49
|
github_api (0.18.2)
|
50
50
|
addressable (~> 2.4)
|
51
51
|
descendants_tracker (~> 0.0.4)
|
52
52
|
faraday (~> 0.8)
|
53
53
|
hashie (~> 3.5, >= 3.5.2)
|
54
54
|
oauth2 (~> 1.0)
|
55
|
-
hashie (3.
|
56
|
-
highline (
|
57
|
-
i18n (
|
55
|
+
hashie (3.6.0)
|
56
|
+
highline (2.0.3)
|
57
|
+
i18n (1.8.2)
|
58
58
|
concurrent-ruby (~> 1.0)
|
59
59
|
ice_nine (0.11.2)
|
60
60
|
juwelier (2.1.3)
|
@@ -67,21 +67,21 @@ GEM
|
|
67
67
|
rake
|
68
68
|
rdoc
|
69
69
|
semver
|
70
|
-
jwt (
|
71
|
-
loofah (2.
|
70
|
+
jwt (2.2.1)
|
71
|
+
loofah (2.5.0)
|
72
72
|
crass (~> 1.0.2)
|
73
73
|
nokogiri (>= 1.5.9)
|
74
74
|
method_source (0.9.0)
|
75
|
-
mini_portile2 (2.
|
76
|
-
minitest (5.
|
77
|
-
multi_json (1.
|
75
|
+
mini_portile2 (2.4.0)
|
76
|
+
minitest (5.14.1)
|
77
|
+
multi_json (1.14.1)
|
78
78
|
multi_xml (0.6.0)
|
79
|
-
multipart-post (2.
|
80
|
-
nokogiri (1.
|
81
|
-
mini_portile2 (~> 2.
|
82
|
-
oauth2 (1.4.
|
83
|
-
faraday (>= 0.8, < 0
|
84
|
-
jwt (
|
79
|
+
multipart-post (2.1.1)
|
80
|
+
nokogiri (1.10.9)
|
81
|
+
mini_portile2 (~> 2.4.0)
|
82
|
+
oauth2 (1.4.4)
|
83
|
+
faraday (>= 0.8, < 2.0)
|
84
|
+
jwt (>= 1.0, < 3.0)
|
85
85
|
multi_json (~> 1.3)
|
86
86
|
multi_xml (~> 0.5)
|
87
87
|
rack (>= 1.2, < 3)
|
@@ -90,17 +90,19 @@ GEM
|
|
90
90
|
method_source (~> 0.9.0)
|
91
91
|
pry-rails (0.3.6)
|
92
92
|
pry (>= 0.10.4)
|
93
|
-
public_suffix (
|
94
|
-
rack (2.
|
95
|
-
rack-test (
|
93
|
+
public_suffix (4.0.5)
|
94
|
+
rack (2.2.2)
|
95
|
+
rack-test (1.1.0)
|
96
96
|
rack (>= 1.0, < 3)
|
97
97
|
rails-dom-testing (2.0.3)
|
98
98
|
activesupport (>= 4.2.0)
|
99
99
|
nokogiri (>= 1.6)
|
100
|
-
rails-html-sanitizer (1.0
|
101
|
-
loofah (~> 2.
|
102
|
-
rake (
|
103
|
-
|
100
|
+
rails-html-sanitizer (1.3.0)
|
101
|
+
loofah (~> 2.3)
|
102
|
+
rake (13.0.1)
|
103
|
+
rchardet (1.8.0)
|
104
|
+
rdoc (6.2.1)
|
105
|
+
redis (4.1.4)
|
104
106
|
rspec (3.7.0)
|
105
107
|
rspec-core (~> 3.7.0)
|
106
108
|
rspec-expectations (~> 3.7.0)
|
@@ -113,16 +115,20 @@ GEM
|
|
113
115
|
rspec-mocks (3.7.0)
|
114
116
|
diff-lcs (>= 1.2.0, < 2.0)
|
115
117
|
rspec-support (~> 3.7.0)
|
116
|
-
rspec-support (3.7.
|
118
|
+
rspec-support (3.7.1)
|
119
|
+
rspec_junit_formatter (0.3.0)
|
120
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
121
|
+
ruby2_keywords (0.0.2)
|
117
122
|
semver (1.0.1)
|
118
123
|
thread_safe (0.3.6)
|
119
|
-
tzinfo (1.2.
|
124
|
+
tzinfo (1.2.7)
|
120
125
|
thread_safe (~> 0.1)
|
121
126
|
virtus (1.0.5)
|
122
127
|
axiom-types (~> 0.1)
|
123
128
|
coercible (~> 1.0)
|
124
129
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
125
130
|
equalizer (~> 0.0, >= 0.0.9)
|
131
|
+
zeitwerk (2.3.0)
|
126
132
|
|
127
133
|
PLATFORMS
|
128
134
|
ruby
|
@@ -130,11 +136,14 @@ PLATFORMS
|
|
130
136
|
DEPENDENCIES
|
131
137
|
actionpack (>= 4.2.6)
|
132
138
|
activerecord (>= 4.2.6)
|
133
|
-
bundler (~>
|
139
|
+
bundler (~> 2.0)
|
134
140
|
juwelier (~> 2.1.0)
|
135
141
|
pry-rails
|
142
|
+
redis
|
136
143
|
rspec
|
144
|
+
rspec_junit_formatter
|
145
|
+
ruby2_keywords
|
137
146
|
virtus
|
138
147
|
|
139
148
|
BUNDLED WITH
|
140
|
-
1.
|
149
|
+
2.1.4
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+

|
2
|
+
|
1
3
|
# Pattern
|
2
4
|
|
3
|
-
A collection of lightweight, standardized, rails-oriented patterns.
|
5
|
+
A collection of lightweight, standardized, rails-oriented patterns used by [RubyOnRails Developers @ Selleo](https://selleo.com/ruby-on-rails)
|
4
6
|
|
5
7
|
- [Query - complex querying on active record relation](#query)
|
6
8
|
- [Service - useful for handling processes involving multiple steps](#service)
|
@@ -28,6 +30,7 @@ One should consider using query objects pattern when in need to perform complex
|
|
28
30
|
Usually one should avoid using scopes for such purpose.
|
29
31
|
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.
|
30
32
|
Also whenever a chain of scopes is to be used, one should consider using query object too.
|
33
|
+
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).
|
31
34
|
|
32
35
|
### Assumptions and rules
|
33
36
|
|
@@ -74,7 +77,7 @@ RecentlyActivatedUsersQuery.call(date_range: Date.today.beginning_of_day..Date.t
|
|
74
77
|
RecentlyActivatedUsersQuery.call(User.without_test_users, date_range: Date.today.beginning_of_day..Date.today.end_of_day)
|
75
78
|
|
76
79
|
class User < ApplicationRecord
|
77
|
-
scope :
|
80
|
+
scope :recently_activated, RecentlyActivatedUsersQuery
|
78
81
|
end
|
79
82
|
```
|
80
83
|
|
@@ -83,7 +86,7 @@ end
|
|
83
86
|
### When to use it
|
84
87
|
|
85
88
|
Service objects are commonly used to mitigate problems with model callbacks that interact with external classes ([read more...](http://samuelmullen.com/2013/05/the-problem-with-rails-callbacks/)).
|
86
|
-
Service objects are also useful for handling processes involving multiple steps. E.g. a controller that performs more than one operation on its subject (usually a model instance) is a possible candidate for Extract ServiceObject (or Extract FormObject) refactoring. In many cases service object can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object).
|
89
|
+
Service objects are also useful for handling processes involving multiple steps. E.g. a controller that performs more than one operation on its subject (usually a model instance) is a possible candidate for Extract ServiceObject (or Extract FormObject) refactoring. In many cases service object can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object). Some more information on using services can be found in [this article](https://medium.com/selleo/essential-rubyonrails-patterns-part-1-service-objects-1af9f9573ca1).
|
87
90
|
|
88
91
|
### Assumptions and rules
|
89
92
|
|
@@ -188,7 +191,7 @@ Form objects, just like service objects, are commonly used to mitigate problems
|
|
188
191
|
Form objects can also be used as replacement for `ActionController::StrongParameters` strategy, as all writable attributes are re-defined within each form.
|
189
192
|
Finally form objects can be used as wrappers for virtual (with no model representation) or composite (saving multiple models at once) resources.
|
190
193
|
In the latter case this may act as replacement for `ActiveRecord::NestedAttributes`.
|
191
|
-
In some cases FormObject can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object).
|
194
|
+
In some cases FormObject can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object). Some more information on using form objects can be found in [this article](https://medium.com/selleo/essential-rubyonrails-patterns-form-objects-b199aada6ec9).
|
192
195
|
|
193
196
|
### Assumptions and rules
|
194
197
|
|
data/Rakefile
CHANGED
@@ -21,6 +21,7 @@ Juwelier::Tasks.new do |gem|
|
|
21
21
|
gem.description = "A collection of lightweight, standardized, rails-oriented patterns."
|
22
22
|
gem.email = "b.kosmowski@selleo.com"
|
23
23
|
gem.authors = ["Stevo"]
|
24
|
+
gem.required_ruby_version = ">= 2.5.0"
|
24
25
|
|
25
26
|
# dependencies defined in Gemfile
|
26
27
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.3
|
data/lib/patterns/calculation.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
1
3
|
module Patterns
|
2
4
|
class Calculation
|
3
5
|
class_attribute :cache_expiry_every
|
@@ -21,8 +23,12 @@ module Patterns
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def cached_result
|
24
|
-
|
26
|
+
if cache_expiry_period.blank?
|
25
27
|
result
|
28
|
+
else
|
29
|
+
Rails.cache.fetch(cache_key, expires_in: cache_expiry_period) do
|
30
|
+
result
|
31
|
+
end
|
26
32
|
end
|
27
33
|
end
|
28
34
|
|
@@ -35,7 +41,15 @@ module Patterns
|
|
35
41
|
end
|
36
42
|
|
37
43
|
def cache_key
|
38
|
-
"#{self.class.name}_#{
|
44
|
+
"#{self.class.name}_#{hash_of(subject, options)}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.hash_of(*args)
|
48
|
+
Digest::SHA1.hexdigest(args.map(&:to_s).join(':'))
|
49
|
+
end
|
50
|
+
|
51
|
+
def hash_of(*args)
|
52
|
+
self.class.hash_of(*args)
|
39
53
|
end
|
40
54
|
|
41
55
|
def cache_expiry_period
|
data/lib/patterns/service.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
require 'ruby2_keywords'
|
2
|
+
|
1
3
|
module Patterns
|
2
4
|
class Service
|
3
5
|
attr_reader :result
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
service
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
class << self
|
8
|
+
ruby2_keywords def call(*args)
|
9
|
+
new(*args).tap do |service|
|
10
|
+
service.instance_variable_set(
|
11
|
+
"@result",
|
12
|
+
service.call
|
13
|
+
)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
data/rails-patterns.gemspec
CHANGED
@@ -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.
|
5
|
+
# stub: rails-patterns 0.7.3 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "rails-patterns".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.7.3"
|
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 = "
|
14
|
+
s.date = "2020-06-12"
|
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 = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
|
+
".github/workflows/ruby.yml",
|
23
24
|
".rspec",
|
24
25
|
"Gemfile",
|
25
26
|
"Gemfile.lock",
|
@@ -35,6 +36,9 @@ Gem::Specification.new do |s|
|
|
35
36
|
"lib/patterns/service.rb",
|
36
37
|
"lib/rails-patterns.rb",
|
37
38
|
"rails-patterns.gemspec",
|
39
|
+
"spec/helpers/custom_calculation.rb",
|
40
|
+
"spec/helpers/custom_calculation_script.rb",
|
41
|
+
"spec/helpers/rails_redis_cache_mock.rb",
|
38
42
|
"spec/patterns/calculation_spec.rb",
|
39
43
|
"spec/patterns/collection_spec.rb",
|
40
44
|
"spec/patterns/form_spec.rb",
|
@@ -44,7 +48,8 @@ Gem::Specification.new do |s|
|
|
44
48
|
]
|
45
49
|
s.homepage = "http://github.com/selleo/pattern".freeze
|
46
50
|
s.licenses = ["MIT".freeze]
|
47
|
-
s.
|
51
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0".freeze)
|
52
|
+
s.rubygems_version = "2.7.6.2".freeze
|
48
53
|
s.summary = "A collection of lightweight, standardized, rails-oriented patterns.".freeze
|
49
54
|
|
50
55
|
if s.respond_to? :specification_version then
|
@@ -54,23 +59,26 @@ Gem::Specification.new do |s|
|
|
54
59
|
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
55
60
|
s.add_runtime_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
56
61
|
s.add_runtime_dependency(%q<virtus>.freeze, [">= 0"])
|
62
|
+
s.add_runtime_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
57
63
|
s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
|
58
|
-
s.add_development_dependency(%q<bundler>.freeze, ["~>
|
64
|
+
s.add_development_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
59
65
|
s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
60
66
|
else
|
61
67
|
s.add_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
62
68
|
s.add_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
63
69
|
s.add_dependency(%q<virtus>.freeze, [">= 0"])
|
70
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
64
71
|
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
65
|
-
s.add_dependency(%q<bundler>.freeze, ["~>
|
72
|
+
s.add_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
66
73
|
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
67
74
|
end
|
68
75
|
else
|
69
76
|
s.add_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
70
77
|
s.add_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
71
78
|
s.add_dependency(%q<virtus>.freeze, [">= 0"])
|
79
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
72
80
|
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
73
|
-
s.add_dependency(%q<bundler>.freeze, ["~>
|
81
|
+
s.add_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
74
82
|
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
75
83
|
end
|
76
84
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'active_support/testing/time_helpers'
|
3
|
+
require_relative 'rails_redis_cache_mock'
|
4
|
+
require_relative '../../lib/patterns/calculation'
|
5
|
+
|
6
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
7
|
+
set_cache_expiry_every 1.hour
|
8
|
+
class_attribute :counter
|
9
|
+
self.counter = 0
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def result
|
14
|
+
self.class.counter += 1
|
15
|
+
end
|
16
|
+
end
|
@@ -14,6 +14,7 @@ RSpec.describe Patterns::Calculation do
|
|
14
14
|
after do
|
15
15
|
Object.send(:remove_const, :CustomCalculation) if defined?(CustomCalculation)
|
16
16
|
Rails.cache.clear
|
17
|
+
ActiveSupport::Cache::RedisCacheStore.new.clear
|
17
18
|
end
|
18
19
|
|
19
20
|
describe ".result" do
|
@@ -159,5 +160,41 @@ RSpec.describe Patterns::Calculation do
|
|
159
160
|
expect(CustomCalculation.result).to eq 1
|
160
161
|
expect(CustomCalculation.result).to eq 2
|
161
162
|
end
|
163
|
+
|
164
|
+
describe "when RedisCacheStore is used" do
|
165
|
+
it "does not store data in cache if 'cache_expiry_period' is not set" do
|
166
|
+
client = Redis.new
|
167
|
+
class Rails
|
168
|
+
def self.cache
|
169
|
+
@cache ||= ActiveSupport::Cache::RedisCacheStore.new
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
174
|
+
class_attribute :counter
|
175
|
+
self.counter = 0
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def result
|
180
|
+
self.class.counter += 1
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
expect(CustomCalculation.result).to eq 1
|
185
|
+
expect(CustomCalculation.result).to eq 2
|
186
|
+
expect(client.keys).to be_empty
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
it "uses cache keys consistent between processes" do
|
191
|
+
`bundle exec ruby spec/helpers/custom_calculation.rb`
|
192
|
+
Process.spawn('bundle exec ruby spec/helpers/custom_calculation_script.rb')
|
193
|
+
Process.spawn('bundle exec ruby spec/helpers/custom_calculation_script.rb')
|
194
|
+
Process.spawn('bundle exec ruby spec/helpers/custom_calculation_script.rb')
|
195
|
+
Process.waitall
|
196
|
+
|
197
|
+
expect(Redis.new.keys.length).to eq 1
|
198
|
+
end
|
162
199
|
end
|
163
200
|
end
|
@@ -10,7 +10,7 @@ RSpec.describe Patterns::Service do
|
|
10
10
|
expect(DoSomething.call).to be_kind_of(DoSomething)
|
11
11
|
end
|
12
12
|
|
13
|
-
it "instantiates service object passing arguments to constructor" do
|
13
|
+
it "instantiates service object passing keyword arguments to constructor" do
|
14
14
|
DoSomething = Class.new(Patterns::Service) do
|
15
15
|
def initialize(argument_1:, argument_2:); end
|
16
16
|
def call; end
|
@@ -25,6 +25,21 @@ RSpec.describe Patterns::Service do
|
|
25
25
|
}.not_to raise_error
|
26
26
|
end
|
27
27
|
|
28
|
+
it "instantiates service object passing positional arguments to constructor" do
|
29
|
+
DoSomething = Class.new(Patterns::Service) do
|
30
|
+
def initialize(argument_1, argument_2); end
|
31
|
+
def call; end
|
32
|
+
end
|
33
|
+
|
34
|
+
expect {
|
35
|
+
DoSomething.call
|
36
|
+
}.to raise_error ArgumentError
|
37
|
+
|
38
|
+
expect {
|
39
|
+
DoSomething.call(10, 20)
|
40
|
+
}.not_to raise_error
|
41
|
+
end
|
42
|
+
|
28
43
|
it "calls #call method on service object instance" do
|
29
44
|
Spy = Class.new do
|
30
45
|
def self.some_method; end
|
data/spec/spec_helper.rb
CHANGED
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.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stevo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ruby2_keywords
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +86,14 @@ dependencies:
|
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
89
|
+
version: '2.0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '2.0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: juwelier
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +117,7 @@ extra_rdoc_files:
|
|
103
117
|
- README.md
|
104
118
|
files:
|
105
119
|
- ".document"
|
120
|
+
- ".github/workflows/ruby.yml"
|
106
121
|
- ".rspec"
|
107
122
|
- Gemfile
|
108
123
|
- Gemfile.lock
|
@@ -118,6 +133,9 @@ files:
|
|
118
133
|
- lib/patterns/service.rb
|
119
134
|
- lib/rails-patterns.rb
|
120
135
|
- rails-patterns.gemspec
|
136
|
+
- spec/helpers/custom_calculation.rb
|
137
|
+
- spec/helpers/custom_calculation_script.rb
|
138
|
+
- spec/helpers/rails_redis_cache_mock.rb
|
121
139
|
- spec/patterns/calculation_spec.rb
|
122
140
|
- spec/patterns/collection_spec.rb
|
123
141
|
- spec/patterns/form_spec.rb
|
@@ -136,7 +154,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
154
|
requirements:
|
137
155
|
- - ">="
|
138
156
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
157
|
+
version: 2.5.0
|
140
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
159
|
requirements:
|
142
160
|
- - ">="
|
@@ -144,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
162
|
version: '0'
|
145
163
|
requirements: []
|
146
164
|
rubyforge_project:
|
147
|
-
rubygems_version: 2.6.
|
165
|
+
rubygems_version: 2.7.6.2
|
148
166
|
signing_key:
|
149
167
|
specification_version: 4
|
150
168
|
summary: A collection of lightweight, standardized, rails-oriented patterns.
|