infopark_component_cache 3.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +25 -0
  4. data/.rubocop_todo.yml +115 -0
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +24 -0
  7. data/Gemfile +3 -1
  8. data/Gemfile.lock +206 -0
  9. data/Gemfile.rails51 +6 -0
  10. data/Gemfile.rails51.lock +206 -0
  11. data/README.md +8 -0
  12. data/Rakefile +7 -7
  13. data/app/helpers/infopark_component_cache_helper.rb +2 -2
  14. data/infopark_component_cache.gemspec +16 -13
  15. data/lib/engine.rb +6 -7
  16. data/lib/infopark_component_cache.rb +1 -2
  17. data/lib/infopark_component_cache/abstract_cache_storage.rb +4 -3
  18. data/lib/infopark_component_cache/cache_storage.rb +1 -0
  19. data/lib/infopark_component_cache/component.rb +14 -6
  20. data/lib/infopark_component_cache/component_cache.rb +35 -31
  21. data/lib/infopark_component_cache/consistency_guard.rb +1 -1
  22. data/lib/infopark_component_cache/delayed_guard.rb +7 -7
  23. data/lib/infopark_component_cache/guards/cms_state_guard.rb +6 -5
  24. data/lib/infopark_component_cache/guards/last_changed.rb +5 -2
  25. data/lib/infopark_component_cache/guards/obj_count.rb +3 -3
  26. data/lib/infopark_component_cache/guards/valid_from.rb +7 -10
  27. data/lib/infopark_component_cache/guards/valid_until.rb +7 -9
  28. data/lib/infopark_component_cache/key_generator.rb +3 -3
  29. data/lib/infopark_component_cache/version.rb +1 -1
  30. data/lib/infopark_component_cache/volatile_cache.rb +1 -1
  31. data/lib/infopark_component_cache/volatile_cache_storage.rb +1 -0
  32. data/spec/dummy/Rakefile +1 -1
  33. data/spec/dummy/config.ru +1 -1
  34. data/spec/dummy/config/application.rb +1 -2
  35. data/spec/dummy/config/boot.rb +5 -5
  36. data/spec/dummy/config/environment.rb +1 -1
  37. data/spec/dummy/config/environments/development.rb +1 -0
  38. data/spec/dummy/config/environments/test.rb +2 -0
  39. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  40. data/spec/dummy/config/initializers/session_store.rb +1 -1
  41. data/spec/dummy/db/schema.rb +1 -2
  42. data/spec/lib/infopark_component_cache/component_cache_spec.rb +118 -0
  43. data/spec/lib/{delayed_guard_spec.rb → infopark_component_cache/delayed_guard_spec.rb} +3 -3
  44. data/spec/lib/{guards → infopark_component_cache/guards}/always_consistent_spec.rb +7 -6
  45. data/spec/lib/{guards → infopark_component_cache/guards}/last_changed_spec.rb +20 -12
  46. data/spec/lib/{guards → infopark_component_cache/guards}/never_consistent_spec.rb +7 -6
  47. data/spec/lib/{guards → infopark_component_cache/guards}/obj_count_spec.rb +20 -12
  48. data/spec/lib/{guards → infopark_component_cache/guards}/valid_from_spec.rb +20 -12
  49. data/spec/lib/{guards → infopark_component_cache/guards}/valid_until_spec.rb +23 -14
  50. data/spec/spec_helper.rb +10 -7
  51. data/spec/support/cache_switching_macros.rb +4 -4
  52. metadata +95 -38
@@ -9,9 +9,9 @@ module InfoparkComponentCache
9
9
  class ValidUntil < CmsStateGuard
10
10
  def consistent?
11
11
  if min_valid_until_known?
12
- return no_changes_since?
12
+ no_changes_since?
13
13
  else
14
- return current_min_valid_until.nil?
14
+ current_min_valid_until.nil?
15
15
  end
16
16
  end
17
17
 
@@ -31,17 +31,15 @@ module InfoparkComponentCache
31
31
 
32
32
  # @return [String] the cache key for storing {#current_min_valid_until}
33
33
  def cache_key
34
- component.cache_key('min_valid_until')
34
+ component.cache_key("min_valid_until")
35
35
  end
36
36
 
37
37
  # @return [Time] the timestamp of the the object that will be deactivated in nearest future
38
38
  def current_min_valid_until
39
- str_value = scoped_relation.where('valid_until > ?', Time.now.to_iso).minimum(:valid_until)
40
- if str_value.present?
41
- RailsConnector::DateAttribute.parse(str_value)
42
- else
43
- nil
44
- end
39
+ str_value = scoped_relation.where("valid_until > ?", Time.now.to_iso).minimum(:valid_until)
40
+ return str_value if str_value.kind_of? Time
41
+
42
+ RailsConnector::DateAttribute.parse(str_value) if str_value.present?
45
43
  end
46
44
  end
47
45
  end
@@ -1,4 +1,4 @@
1
- require 'digest/sha2'
1
+ require "digest/sha2"
2
2
 
3
3
  module InfoparkComponentCache
4
4
  module KeyGenerator
@@ -19,7 +19,7 @@ module InfoparkComponentCache
19
19
  # uses some kind of hashing algorithm and therefore has the same
20
20
  # characteristics: equal inputs yield equal outputs, but different
21
21
  # inputs can yield same outputs (although it is very very unlikely)
22
- #
22
+ #
23
23
  # @param [String] string input string to be encoded
24
24
  # @return [String] string that is guaranteed to
25
25
  # consist only of alphanumeric characters,
@@ -28,4 +28,4 @@ module InfoparkComponentCache
28
28
  Digest::SHA2.hexdigest(string)
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module InfoparkComponentCache
2
- VERSION = "3.0.0"
2
+ VERSION = "4.0.1".freeze
3
3
  end
@@ -3,7 +3,7 @@ require "infopark_component_cache/volatile_cache_storage"
3
3
  module InfoparkComponentCache
4
4
  # @author Tomasz Przedmojski <tomasz.przedmojski@infopark.de>
5
5
  #
6
- # This module provides quick an convieniet access to
6
+ # This module provides quick an convieniet access to
7
7
  # VolatileCacheStorage in any class that includes it.
8
8
  module VolatileCache
9
9
  def volatile_cache
@@ -11,6 +11,7 @@ module InfoparkComponentCache
11
11
  # it is "nice to have" but also has to be extremely quick.
12
12
  class VolatileCacheStorage < AbstractCacheStorage
13
13
  protected
14
+
14
15
  def backing_storage
15
16
  @@backing_storage ||= ActiveSupport::Cache::MemoryStore.new({ size: 10.megabytes })
16
17
  end
@@ -2,6 +2,6 @@
2
2
  # Add your own tasks in files placed in lib/tasks ending in .rake,
3
3
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
4
 
5
- require File.expand_path('../config/application', __FILE__)
5
+ require File.expand_path("config/application", __dir__)
6
6
 
7
7
  Dummy::Application.load_tasks
@@ -1,4 +1,4 @@
1
1
  # This file is used by Rack-based servers to start the application.
2
2
 
3
- require ::File.expand_path('../config/environment', __FILE__)
3
+ require ::File.expand_path("config/environment", __dir__)
4
4
  run Dummy::Application
@@ -1,4 +1,4 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ require File.expand_path("boot", __dir__)
2
2
 
3
3
  # Pick the frameworks you want:
4
4
  require "active_record/railtie"
@@ -14,4 +14,3 @@ module Dummy
14
14
  config.active_support.escape_html_entities_in_json = true
15
15
  end
16
16
  end
17
-
@@ -1,10 +1,10 @@
1
- require 'rubygems'
2
- gemfile = File.expand_path('../../../../Gemfile', __FILE__)
1
+ require "rubygems"
2
+ gemfile = File.expand_path("../../../Gemfile", __dir__)
3
3
 
4
4
  if File.exist?(gemfile)
5
- ENV['BUNDLE_GEMFILE'] = gemfile
6
- require 'bundler'
5
+ ENV["BUNDLE_GEMFILE"] = gemfile
6
+ require "bundler"
7
7
  Bundler.setup
8
8
  end
9
9
 
10
- $:.unshift File.expand_path('../../../../lib', __FILE__)
10
+ $:.unshift File.expand_path("../../../lib", __dir__)
@@ -1,5 +1,5 @@
1
1
  # Load the rails application
2
- require File.expand_path('../application', __FILE__)
2
+ require File.expand_path("application", __dir__)
3
3
 
4
4
  # Initialize the rails application
5
5
  Dummy::Application.initialize!
@@ -1,2 +1,3 @@
1
1
  Dummy::Application.configure do
2
+ config.eager_load = false
2
3
  end
@@ -1,2 +1,4 @@
1
1
  Dummy::Application.configure do
2
+ config.cache_store = :memory_store
3
+ config.eager_load = false
2
4
  end
@@ -1 +1 @@
1
- Dummy::Application.config.secret_token = '4806ad3606eea6388c0428912c8c8b37266f29c4c45fa5ecd233316cd5b6a0016aea879cfa603059a7c00296daef192955e26ae3298830bd904c8ff6a791feb1'
1
+ Dummy::Application.config.secret_token = "4806ad3606eea6388c0428912c8c8b37266f29c4c45fa5ecd233316cd5b6a0016aea879cfa603059a7c00296daef192955e26ae3298830bd904c8ff6a791feb1"
@@ -1 +1 @@
1
- Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
1
+ Dummy::Application.config.session_store :cookie_store, key: "_dummy_session"
@@ -1,3 +1,2 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
-
1
+ ActiveRecord::Schema.define(version: 0) do
3
2
  end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+
3
+ describe InfoparkComponentCache::ComponentCache do
4
+ subject(:component_cache) { described_class.new(obj, name, params, [guard]) }
5
+
6
+ let(:obj) { double(name: "spec_obj", id: 2001) }
7
+ let(:name) { "spec_cached_component" }
8
+ let(:params) { { some: "additional", params: "supplied" } }
9
+ let(:guard) { Class.new(Struct.new(:component)) }
10
+
11
+ context "with caching disabled" do
12
+ before { allow(Rails.application.config.action_controller).to receive(:perform_caching).and_return(false) }
13
+
14
+ describe "#fetch" do
15
+ let(:value) { "very_hard_computation_required_for_this_string" }
16
+ let(:specific_guard) { component_cache.guards.first }
17
+
18
+ it "returns the passed the block value" do
19
+ expect(component_cache.fetch { value }).to eq(value)
20
+ end
21
+
22
+ it "never calls any methods on the guard" do
23
+ expect(specific_guard).not_to receive(:consistent?)
24
+ expect(specific_guard).not_to receive(:guard!)
25
+
26
+ component_cache.fetch { value }
27
+ end
28
+ end
29
+ end
30
+
31
+ context "with caching enabled" do
32
+ before { allow(Rails.application.config.action_controller).to receive(:perform_caching).and_return(true) }
33
+
34
+ let(:guard) do
35
+ Class.new(InfoparkComponentCache::ConsistencyGuard) do
36
+ def consistent?
37
+ cache.exist?(:guard_called)
38
+ end
39
+
40
+ def guard!
41
+ cache.write(:guard_called, 1)
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#fetch" do
47
+ let(:value) { "very_hard_computation_required_for_this_string" }
48
+ let(:specific_guard) { component_cache.guards.first }
49
+ let(:computer) { double }
50
+
51
+ it "returns the passed the block value" do
52
+ expect(component_cache.fetch { value }).to eq(value)
53
+ end
54
+
55
+ it "calls the required methods on the guard" do
56
+ expect(specific_guard).to receive(:consistent?).exactly(3).times
57
+ expect(specific_guard).to receive(:guard!).exactly(3).times
58
+
59
+ 3.times { component_cache.fetch { value } }
60
+ end
61
+
62
+ it "only evalues the block once" do
63
+ expect(computer).to receive(:compute).and_return(value).once
64
+
65
+ 3.times { expect(component_cache.fetch { computer.compute }).to eq(value) }
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "#compontent" do
71
+ subject(:component_cache) { described_class.new(obj, name, params).component }
72
+
73
+ it "stores the passed obj" do
74
+ expect(component_cache.obj).to eq(obj)
75
+ end
76
+
77
+ it "stores the passed name" do
78
+ expect(component_cache.name).to eq(name)
79
+ end
80
+
81
+ it "stores the passed params" do
82
+ expect(component_cache.params).to eq(params)
83
+ end
84
+ end
85
+
86
+ describe "#guards" do
87
+ subject(:component_cache) { described_class.new(obj, name, params, [guard_class1, guard_params]).guards }
88
+
89
+ let(:guard_class1) { Struct.new(:component) }
90
+ let(:guard_class2) { Struct.new(:compontent, :extra) }
91
+ let(:guard_params) { { guard: guard_class2, something: "more" } }
92
+
93
+ it "contains an array of passed guards" do
94
+ expect(component_cache).to match_array([
95
+ an_instance_of(guard_class1),
96
+ an_instance_of(guard_class2)
97
+ ])
98
+ end
99
+
100
+ it "preserves the extra params" do
101
+ expect(component_cache.last.extra).to eq(guard_params)
102
+ end
103
+
104
+ context "with no guards specified in the constructors" do
105
+ subject(:component_cache) { described_class.new(obj, name, params).guards }
106
+
107
+ it "contains standard guards" do
108
+ expect(component_cache).to match_array([
109
+ an_instance_of(InfoparkComponentCache::Guards::ValuePresent),
110
+ an_instance_of(InfoparkComponentCache::Guards::LastChanged),
111
+ an_instance_of(InfoparkComponentCache::Guards::ObjCount),
112
+ an_instance_of(InfoparkComponentCache::Guards::ValidFrom),
113
+ an_instance_of(InfoparkComponentCache::Guards::ValidUntil)
114
+ ])
115
+ end
116
+ end
117
+ end
118
+ end
@@ -1,5 +1,5 @@
1
- require 'spec_helper'
2
- require 'infopark_component_cache/delayed_guard'
1
+ require "spec_helper"
2
+ require "infopark_component_cache/delayed_guard"
3
3
 
4
4
  describe InfoparkComponentCache::DelayedGuard do
5
5
  let(:base_class_with_options) do
@@ -56,7 +56,7 @@ describe InfoparkComponentCache::DelayedGuard do
56
56
  end
57
57
  end
58
58
 
59
- context "after the delay has passed" do
59
+ context "when after the delay has passed" do
60
60
  specify "the calls returns new value" do
61
61
  first_value = delayed_subject.simple_counter
62
62
  expect(first_value).to eq(undelayed_subject.simple_counter)
@@ -1,19 +1,20 @@
1
- require 'spec_helper'
2
- require 'infopark_component_cache/guards/always_consistent'
1
+ require "spec_helper"
2
+ require "infopark_component_cache/guards/always_consistent"
3
3
 
4
4
  describe InfoparkComponentCache::Guards::AlwaysConsistent do
5
- {"with cache disabled" => :disable_cache, "with cache enabled" => :enable_cache}.each do |context_description, macro|
5
+ { "with cache disabled" => :disable_cache, "with cache enabled" => :enable_cache }.each do |context_description, macro|
6
6
  context context_description do
7
- self.send(macro)
7
+ send(macro)
8
8
 
9
- subject { described_class.new(double) }
9
+ subject(:guard) { described_class.new(double) }
10
10
 
11
11
  context "without a call to guard!" do
12
12
  it { is_expected.to be_consistent }
13
13
  end
14
14
 
15
15
  context "with a call to guard!" do
16
- before { subject.guard! }
16
+ before { guard.guard! }
17
+
17
18
  it { is_expected.to be_consistent }
18
19
  end
19
20
  end
@@ -1,6 +1,8 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe InfoparkComponentCache::Guards::LastChanged do
4
+ subject(:guard) { described_class.new(cache_component_stub) }
5
+
4
6
  let(:cache_component_stub) do
5
7
  double.tap do |cache_component_stub|
6
8
  cache_component_stub.stub(:cache_key) do |input|
@@ -9,7 +11,7 @@ describe InfoparkComponentCache::Guards::LastChanged do
9
11
  end
10
12
  end
11
13
 
12
- let(:maximum_last_changed) { 10.minutes.ago.to_iso }
14
+ let(:maximum_last_changed) { 10.minutes.ago }
13
15
 
14
16
  let(:obj_stub) do
15
17
  double.tap do |obj_stub|
@@ -23,8 +25,6 @@ describe InfoparkComponentCache::Guards::LastChanged do
23
25
 
24
26
  before { InfoparkComponentCache::CmsStateGuard.obj_root_class = obj_stub }
25
27
 
26
- subject { described_class.new(cache_component_stub) }
27
-
28
28
  context "with cache disabled" do
29
29
  disable_cache
30
30
 
@@ -33,7 +33,8 @@ describe InfoparkComponentCache::Guards::LastChanged do
33
33
  end
34
34
 
35
35
  context "with a call to guard!" do
36
- before { subject.guard! }
36
+ before { guard.guard! }
37
+
37
38
  it { is_expected.not_to be_consistent }
38
39
  end
39
40
  end
@@ -47,19 +48,26 @@ describe InfoparkComponentCache::Guards::LastChanged do
47
48
  end
48
49
 
49
50
  context "with a call to guard!" do
50
- before { subject.guard! }
51
+ before { guard.guard! }
52
+
51
53
  it { is_expected.to be_consistent }
52
54
  end
53
55
 
54
- context "after maximum last change changes" do
55
- before { subject.guard! }
56
- before { obj_stub.stub(:maximum).and_return(Time.now.to_iso) }
56
+ context "when after maximum last change changes" do
57
+ before do
58
+ guard.guard!
59
+ obj_stub.stub(:maximum).and_return(Time.now.to_iso)
60
+ end
61
+
57
62
  it { is_expected.not_to be_consistent }
58
63
  end
59
64
 
60
- context "after maximum last change changes to a past date" do
61
- before { subject.guard! }
62
- before { obj_stub.stub(:maximum).and_return(1.month.ago.to_iso) }
65
+ context "when after maximum last change changes to a past date" do
66
+ before do
67
+ guard.guard!
68
+ obj_stub.stub(:maximum).and_return(1.month.ago.to_iso)
69
+ end
70
+
63
71
  it { is_expected.to be_consistent }
64
72
  end
65
73
  end
@@ -1,19 +1,20 @@
1
- require 'spec_helper'
2
- require 'infopark_component_cache/guards/never_consistent'
1
+ require "spec_helper"
2
+ require "infopark_component_cache/guards/never_consistent"
3
3
 
4
4
  describe InfoparkComponentCache::Guards::NeverConsistent do
5
- {"cache disabled" => :disable_cache, "cache enabled" => :enable_cache}.each do |context_description, macro|
5
+ { "cache disabled" => :disable_cache, "cache enabled" => :enable_cache }.each do |context_description, macro|
6
6
  context context_description do
7
- self.send(macro)
7
+ send(macro)
8
8
 
9
- subject { described_class.new(double) }
9
+ subject(:guard) { described_class.new(double) }
10
10
 
11
11
  context "without a call to guard!" do
12
12
  it { is_expected.not_to be_consistent }
13
13
  end
14
14
 
15
15
  context "with a call to guard!" do
16
- before { subject.guard! }
16
+ before { guard.guard! }
17
+
17
18
  it { is_expected.not_to be_consistent }
18
19
  end
19
20
  end
@@ -1,6 +1,8 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe InfoparkComponentCache::Guards::ObjCount do
4
+ subject(:guard) { described_class.new(cache_component_stub) }
5
+
4
6
  let(:cache_component_stub) do
5
7
  double.tap do |cache_component_stub|
6
8
  cache_component_stub.stub(:cache_key) do |input|
@@ -9,7 +11,7 @@ describe InfoparkComponentCache::Guards::ObjCount do
9
11
  end
10
12
  end
11
13
 
12
- let(:count) { 12314 }
14
+ let(:count) { 12_314 }
13
15
 
14
16
  let(:obj_stub) do
15
17
  double.tap do |obj_stub|
@@ -21,8 +23,6 @@ describe InfoparkComponentCache::Guards::ObjCount do
21
23
 
22
24
  before { InfoparkComponentCache::CmsStateGuard.obj_root_class = obj_stub }
23
25
 
24
- subject { described_class.new(cache_component_stub) }
25
-
26
26
  context "with cache disabled" do
27
27
  disable_cache
28
28
 
@@ -31,7 +31,8 @@ describe InfoparkComponentCache::Guards::ObjCount do
31
31
  end
32
32
 
33
33
  context "with a call to guard!" do
34
- before { subject.guard! }
34
+ before { guard.guard! }
35
+
35
36
  it { is_expected.not_to be_consistent }
36
37
  end
37
38
  end
@@ -45,19 +46,26 @@ describe InfoparkComponentCache::Guards::ObjCount do
45
46
  end
46
47
 
47
48
  context "with a call to guard!" do
48
- before { subject.guard! }
49
+ before { guard.guard! }
50
+
49
51
  it { is_expected.to be_consistent }
50
52
  end
51
53
 
52
- context "after obj count increases" do
53
- before { subject.guard! }
54
- before { obj_stub.stub(:count).and_return(55555) }
54
+ context "when after obj count increases" do
55
+ before do
56
+ guard.guard!
57
+ obj_stub.stub(:count).and_return(55_555)
58
+ end
59
+
55
60
  it { is_expected.not_to be_consistent }
56
61
  end
57
62
 
58
- context "after obj count decreases" do
59
- before { subject.guard! }
60
- before { obj_stub.stub(:count).and_return(500) }
63
+ context "when after obj count decreases" do
64
+ before do
65
+ guard.guard!
66
+ obj_stub.stub(:count).and_return(500)
67
+ end
68
+
61
69
  it { is_expected.not_to be_consistent }
62
70
  end
63
71
  end