rails-patterns 0.3.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 +8 -4
- data/Gemfile.lock +104 -56
- data/README.md +183 -6
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/patterns/calculation.rb +59 -0
- data/lib/patterns/form.rb +117 -0
- data/lib/patterns/query.rb +20 -15
- data/lib/patterns/service.rb +10 -6
- data/lib/rails-patterns.rb +2 -0
- data/rails-patterns.gemspec +25 -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 +200 -0
- data/spec/patterns/form_spec.rb +478 -0
- data/spec/patterns/service_spec.rb +16 -1
- data/spec/spec_helper.rb +6 -1
- metadata +56 -6
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.3
|
1
|
+
0.7.3
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Patterns
|
4
|
+
class Calculation
|
5
|
+
class_attribute :cache_expiry_every
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
@options = args.extract_options!
|
9
|
+
@subject = args.first
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.result(*args)
|
13
|
+
new(*args).cached_result
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
alias_method :result_for, :result
|
18
|
+
alias_method :calculate, :result
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.set_cache_expiry_every(period)
|
22
|
+
self.cache_expiry_every = period
|
23
|
+
end
|
24
|
+
|
25
|
+
def cached_result
|
26
|
+
if cache_expiry_period.blank?
|
27
|
+
result
|
28
|
+
else
|
29
|
+
Rails.cache.fetch(cache_key, expires_in: cache_expiry_period) do
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :subject, :options
|
38
|
+
|
39
|
+
def result
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
|
43
|
+
def cache_key
|
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)
|
53
|
+
end
|
54
|
+
|
55
|
+
def cache_expiry_period
|
56
|
+
self.class.cache_expiry_every
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "virtus"
|
2
|
+
require "action_controller/metal/strong_parameters"
|
3
|
+
|
4
|
+
module Patterns
|
5
|
+
class Form
|
6
|
+
include Virtus.model
|
7
|
+
include ActiveModel::Validations
|
8
|
+
|
9
|
+
Error = Class.new(StandardError)
|
10
|
+
Invalid = Class.new(Error)
|
11
|
+
NoParamKey = Class.new(Error)
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
attributes = args.extract_options!
|
15
|
+
|
16
|
+
if attributes.blank? && args.last.is_a?(ActionController::Parameters)
|
17
|
+
attributes = args.pop.to_unsafe_h
|
18
|
+
end
|
19
|
+
|
20
|
+
@resource = args.first
|
21
|
+
|
22
|
+
super(build_original_attributes.merge(attributes))
|
23
|
+
end
|
24
|
+
|
25
|
+
def save
|
26
|
+
valid? ? persist : false
|
27
|
+
end
|
28
|
+
|
29
|
+
def save!
|
30
|
+
save.tap do |saved|
|
31
|
+
raise Invalid unless saved
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def as(form_owner)
|
36
|
+
@form_owner = form_owner
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_key
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_partial_path
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_model
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_param
|
53
|
+
if resource.present? && resource.respond_to?(:to_param)
|
54
|
+
resource.to_param
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def persisted?
|
61
|
+
if resource.present? && resource.respond_to?(:persisted?)
|
62
|
+
resource.persisted?
|
63
|
+
else
|
64
|
+
false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def model_name
|
69
|
+
@model_name ||= OpenStruct.new(model_name_attributes)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.param_key(key = nil)
|
73
|
+
if key.nil?
|
74
|
+
@param_key
|
75
|
+
else
|
76
|
+
@param_key = key
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
attr_reader :resource, :form_owner
|
83
|
+
|
84
|
+
def model_name_attributes
|
85
|
+
if self.class.param_key.present?
|
86
|
+
{
|
87
|
+
param_key: self.class.param_key,
|
88
|
+
route_key: self.class.param_key.pluralize,
|
89
|
+
singular_route_key: self.class.param_key
|
90
|
+
}
|
91
|
+
elsif resource.present? && resource.respond_to?(:model_name)
|
92
|
+
{
|
93
|
+
param_key: resource.model_name.param_key,
|
94
|
+
route_key: resource.model_name.route_key,
|
95
|
+
singular_route_key: resource.model_name.singular_route_key
|
96
|
+
}
|
97
|
+
else
|
98
|
+
raise NoParamKey
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_original_attributes
|
103
|
+
return {} if resource.nil?
|
104
|
+
base_attributes = resource.respond_to?(:attributes) && resource.attributes.symbolize_keys
|
105
|
+
|
106
|
+
self.class.attribute_set.each_with_object(base_attributes || {}) do |attribute, result|
|
107
|
+
if result[attribute.name].blank? && resource.respond_to?(attribute.name)
|
108
|
+
result[attribute.name] = resource.public_send(attribute.name)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def persist
|
114
|
+
raise NotImplementedError, "#persist has to be implemented"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/patterns/query.rb
CHANGED
@@ -6,17 +6,17 @@ module Patterns
|
|
6
6
|
|
7
7
|
def initialize(*args)
|
8
8
|
@options = args.extract_options!
|
9
|
-
@relation = args.first ||
|
9
|
+
@relation = args.first || base_relation
|
10
10
|
|
11
11
|
if relation.nil?
|
12
12
|
raise(
|
13
|
-
|
14
|
-
|
13
|
+
RelationRequired,
|
14
|
+
"Queries require a base relation defined. Use .queries method to define relation."
|
15
15
|
)
|
16
16
|
elsif !relation.is_a?(ActiveRecord::Relation)
|
17
17
|
raise(
|
18
|
-
|
19
|
-
|
18
|
+
RelationRequired,
|
19
|
+
"Queries accept only ActiveRecord::Relation as input"
|
20
20
|
)
|
21
21
|
end
|
22
22
|
end
|
@@ -29,20 +29,25 @@ module Patterns
|
|
29
29
|
query.tap do |relation|
|
30
30
|
unless relation.is_a?(ActiveRecord::Relation)
|
31
31
|
raise(
|
32
|
-
|
33
|
-
|
32
|
+
RelationRequired,
|
33
|
+
"#query method should return object of ActiveRecord::Relation class"
|
34
34
|
)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.queries(subject)
|
40
|
-
self.base_relation =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
self.base_relation = subject
|
41
|
+
end
|
42
|
+
|
43
|
+
def base_relation
|
44
|
+
return nil if self.class.base_relation.nil?
|
45
|
+
|
46
|
+
if self.class.base_relation.is_a?(ActiveRecord::Relation)
|
47
|
+
self.class.base_relation
|
48
|
+
elsif self.class.base_relation < ActiveRecord::Base
|
49
|
+
self.class.base_relation.all
|
50
|
+
end
|
46
51
|
end
|
47
52
|
|
48
53
|
private
|
@@ -55,8 +60,8 @@ module Patterns
|
|
55
60
|
|
56
61
|
def query
|
57
62
|
raise(
|
58
|
-
|
59
|
-
|
63
|
+
NotImplementedError,
|
64
|
+
"You need to implement #query method which returns ActiveRecord::Relation object"
|
60
65
|
)
|
61
66
|
end
|
62
67
|
end
|
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/lib/rails-patterns.rb
CHANGED
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.3
|
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.3
|
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",
|
@@ -28,19 +29,27 @@ Gem::Specification.new do |s|
|
|
28
29
|
"Rakefile",
|
29
30
|
"VERSION",
|
30
31
|
"lib/patterns.rb",
|
32
|
+
"lib/patterns/calculation.rb",
|
31
33
|
"lib/patterns/collection.rb",
|
34
|
+
"lib/patterns/form.rb",
|
32
35
|
"lib/patterns/query.rb",
|
33
36
|
"lib/patterns/service.rb",
|
34
37
|
"lib/rails-patterns.rb",
|
35
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",
|
42
|
+
"spec/patterns/calculation_spec.rb",
|
36
43
|
"spec/patterns/collection_spec.rb",
|
44
|
+
"spec/patterns/form_spec.rb",
|
37
45
|
"spec/patterns/query_spec.rb",
|
38
46
|
"spec/patterns/service_spec.rb",
|
39
47
|
"spec/spec_helper.rb"
|
40
48
|
]
|
41
49
|
s.homepage = "http://github.com/selleo/pattern".freeze
|
42
50
|
s.licenses = ["MIT".freeze]
|
43
|
-
s.
|
51
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0".freeze)
|
52
|
+
s.rubygems_version = "2.7.6.2".freeze
|
44
53
|
s.summary = "A collection of lightweight, standardized, rails-oriented patterns.".freeze
|
45
54
|
|
46
55
|
if s.respond_to? :specification_version then
|
@@ -48,19 +57,28 @@ Gem::Specification.new do |s|
|
|
48
57
|
|
49
58
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
59
|
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
60
|
+
s.add_runtime_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
61
|
+
s.add_runtime_dependency(%q<virtus>.freeze, [">= 0"])
|
62
|
+
s.add_runtime_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
51
63
|
s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
|
52
|
-
s.add_development_dependency(%q<bundler>.freeze, ["~>
|
64
|
+
s.add_development_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
53
65
|
s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
54
66
|
else
|
55
67
|
s.add_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
68
|
+
s.add_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
69
|
+
s.add_dependency(%q<virtus>.freeze, [">= 0"])
|
70
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
56
71
|
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
57
|
-
s.add_dependency(%q<bundler>.freeze, ["~>
|
72
|
+
s.add_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
58
73
|
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
59
74
|
end
|
60
75
|
else
|
61
76
|
s.add_dependency(%q<activerecord>.freeze, [">= 4.2.6"])
|
77
|
+
s.add_dependency(%q<actionpack>.freeze, [">= 4.2.6"])
|
78
|
+
s.add_dependency(%q<virtus>.freeze, [">= 0"])
|
79
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, [">= 0"])
|
62
80
|
s.add_dependency(%q<rspec>.freeze, [">= 0"])
|
63
|
-
s.add_dependency(%q<bundler>.freeze, ["~>
|
81
|
+
s.add_dependency(%q<bundler>.freeze, ["~> 2.0"])
|
64
82
|
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
65
83
|
end
|
66
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
|
@@ -0,0 +1,200 @@
|
|
1
|
+
RSpec.describe Patterns::Calculation do
|
2
|
+
before(:all) do
|
3
|
+
class Rails
|
4
|
+
def self.cache
|
5
|
+
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:all) do
|
11
|
+
Object.send(:remove_const, :Rails)
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
Object.send(:remove_const, :CustomCalculation) if defined?(CustomCalculation)
|
16
|
+
Rails.cache.clear
|
17
|
+
ActiveSupport::Cache::RedisCacheStore.new.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".result" do
|
21
|
+
it "returns a result of the calculation within a #result method" do
|
22
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
23
|
+
private
|
24
|
+
|
25
|
+
def result
|
26
|
+
50
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
expect(CustomCalculation.result).to eq 50
|
31
|
+
end
|
32
|
+
|
33
|
+
it "#result, #result_for and #calculate are aliases" do
|
34
|
+
CustomCalculation = Class.new(Patterns::Calculation)
|
35
|
+
|
36
|
+
expect(CustomCalculation.method(:result)).to eq CustomCalculation.method(:result_for)
|
37
|
+
expect(CustomCalculation.method(:result)).to eq CustomCalculation.method(:calculate)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "exposes the first argument as a subject" do
|
41
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
42
|
+
private
|
43
|
+
|
44
|
+
def result
|
45
|
+
subject
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
expect(CustomCalculation.result('test')).to eq 'test'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "exposes all keyword arguments using #options" do
|
53
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
54
|
+
private
|
55
|
+
|
56
|
+
def result
|
57
|
+
[options[:arg_1], options[:arg_2]]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
expect(CustomCalculation.result(nil, arg_1: 20, arg_2: 30)).to eq([20, 30])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "caching" do
|
66
|
+
it "caches result for 'set_cache_expiry_every' period" do
|
67
|
+
travel_to DateTime.new(2017, 1, 1, 12, 0) do
|
68
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
69
|
+
set_cache_expiry_every 1.hour
|
70
|
+
|
71
|
+
class_attribute :counter
|
72
|
+
self.counter = 0
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def result
|
77
|
+
self.class.counter += 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
expect(CustomCalculation.result).to eq 1
|
82
|
+
expect(CustomCalculation.result).to eq 1
|
83
|
+
end
|
84
|
+
|
85
|
+
travel_to DateTime.new(2017, 1, 1, 13, 1) do
|
86
|
+
expect(CustomCalculation.result).to eq 2
|
87
|
+
expect(CustomCalculation.result).to eq 2
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "caches result for every option passed" do
|
92
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
93
|
+
set_cache_expiry_every 1.hour
|
94
|
+
|
95
|
+
class_attribute :counter
|
96
|
+
self.counter = 0
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def result
|
101
|
+
self.class.counter += 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
expect(CustomCalculation.result(123)).to eq 1
|
106
|
+
expect(CustomCalculation.result(123)).to eq 1
|
107
|
+
expect(CustomCalculation.result(1024)).to eq 2
|
108
|
+
expect(CustomCalculation.result(1024)).to eq 2
|
109
|
+
expect(CustomCalculation.result(1024, arg: 1)).to eq 3
|
110
|
+
expect(CustomCalculation.result(1024, arg: 1)).to eq 3
|
111
|
+
end
|
112
|
+
|
113
|
+
it "caches result for every option passed dependant on the class" do
|
114
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
115
|
+
set_cache_expiry_every 1.hour
|
116
|
+
|
117
|
+
class_attribute :counter
|
118
|
+
self.counter = 0
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def result
|
123
|
+
self.class.counter += 1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
DifferentCalculation = Class.new(Patterns::Calculation) do
|
128
|
+
set_cache_expiry_every 1.hour
|
129
|
+
|
130
|
+
class_attribute :counter
|
131
|
+
self.counter = 100
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def result
|
136
|
+
self.class.counter += 1
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
expect(CustomCalculation.result(123)).to eq 1
|
141
|
+
expect(CustomCalculation.result(123)).to eq 1
|
142
|
+
expect(DifferentCalculation.result(123)).to eq 101
|
143
|
+
expect(DifferentCalculation.result(123)).to eq 101
|
144
|
+
|
145
|
+
Object.send(:remove_const, :DifferentCalculation)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "does not cache result if 'set_cache_expiry_every' is not set" do
|
149
|
+
CustomCalculation = Class.new(Patterns::Calculation) do
|
150
|
+
class_attribute :counter
|
151
|
+
self.counter = 0
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def result
|
156
|
+
self.class.counter += 1
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
expect(CustomCalculation.result).to eq 1
|
161
|
+
expect(CustomCalculation.result).to eq 2
|
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
|
199
|
+
end
|
200
|
+
end
|