infopark_component_cache 2.0.0 → 4.0.0

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.
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 +2 -4
  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 +15 -12
  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 +7 -6
  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 -4
  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 -35
  38. data/spec/dummy/config/environments/test.rb +2 -8
  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 +81 -30
@@ -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 = "2.0.0"
2
+ VERSION = "4.0.0".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,9 +1,8 @@
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"
5
5
  require "action_controller/railtie"
6
- require "active_resource/railtie"
7
6
 
8
7
  Bundler.require(*Rails.groups)
9
8
  require "infopark_component_cache"
@@ -13,7 +12,5 @@ module Dummy
13
12
  config.encoding = "utf-8"
14
13
  config.filter_parameters += [:password]
15
14
  config.active_support.escape_html_entities_in_json = true
16
- config.active_record.whitelist_attributes = true
17
15
  end
18
16
  end
19
-
@@ -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,37 +1,3 @@
1
1
  Dummy::Application.configure do
2
- # Settings specified here will take precedence over those in config/application.rb
3
-
4
- # In the development environment your application's code is reloaded on
5
- # every request. This slows down response time but is perfect for development
6
- # since you don't have to restart the web server when you make code changes.
7
- config.cache_classes = false
8
-
9
- # Log error messages when you accidentally call methods on nil.
10
- config.whiny_nils = true
11
-
12
- # Show full error reports and disable caching
13
- config.consider_all_requests_local = true
14
- config.action_controller.perform_caching = false
15
-
16
- # Don't care if the mailer can't send
17
- config.action_mailer.raise_delivery_errors = false
18
-
19
- # Print deprecation notices to the Rails logger
20
- config.active_support.deprecation = :log
21
-
22
- # Only use best-standards-support built into browsers
23
- config.action_dispatch.best_standards_support = :builtin
24
-
25
- # Raise exception on mass assignment protection for Active Record models
26
- config.active_record.mass_assignment_sanitizer = :strict
27
-
28
- # Log the query plan for queries taking more than this (works
29
- # with SQLite, MySQL, and PostgreSQL)
30
- config.active_record.auto_explain_threshold_in_seconds = 0.5
31
-
32
- # Do not compress assets
33
- config.assets.compress = false
34
-
35
- # Expands the lines which load the assets
36
- config.assets.debug = true
2
+ config.eager_load = false
37
3
  end
@@ -1,10 +1,4 @@
1
1
  Dummy::Application.configure do
2
- config.cache_classes = true
3
- config.whiny_nils = true
4
- config.consider_all_requests_local = true
5
- config.action_controller.perform_caching = false
6
- config.action_dispatch.show_exceptions = false
7
- config.action_controller.allow_forgery_protection = false
8
- config.active_record.mass_assignment_sanitizer = :strict
9
- config.active_support.deprecation = :stderr
2
+ config.cache_store = :memory_store
3
+ config.eager_load = false
10
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