cashier 0.2.0 → 0.4.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 (69) hide show
  1. data/.gitignore +3 -42
  2. data/README.md +183 -0
  3. data/Rakefile +1 -5
  4. data/cashier.gemspec +8 -11
  5. data/lib/cashier.rb +93 -35
  6. data/lib/cashier/adapters/cache_store.rb +45 -0
  7. data/lib/cashier/adapters/redis_store.rb +46 -0
  8. data/lib/cashier/application_controller.rb +28 -0
  9. data/lib/cashier/matchers.rb +0 -1
  10. data/lib/cashier/railtie.rb +4 -3
  11. data/lib/cashier/version.rb +1 -1
  12. data/spec/{application_controller_spec.rb → controllers/application_controller_spec.rb} +0 -8
  13. data/spec/{test_app → dummy}/.gitignore +0 -0
  14. data/spec/{test_app → dummy}/Gemfile +0 -0
  15. data/spec/{test_app → dummy}/README +0 -0
  16. data/spec/{test_app → dummy}/Rakefile +0 -0
  17. data/spec/{test_app → dummy}/app/controllers/application_controller.rb +0 -0
  18. data/spec/{test_app → dummy}/app/controllers/home_controller.rb +0 -0
  19. data/spec/{test_app → dummy}/app/helpers/application_helper.rb +0 -0
  20. data/spec/{test_app → dummy}/app/helpers/home_helper.rb +0 -0
  21. data/spec/{test_app → dummy}/app/views/home/index.html.erb +0 -0
  22. data/spec/{test_app → dummy}/app/views/layouts/application.html.erb +0 -0
  23. data/spec/{test_app → dummy}/config.ru +0 -0
  24. data/spec/{test_app → dummy}/config/application.rb +0 -4
  25. data/spec/{test_app → dummy}/config/boot.rb +0 -0
  26. data/spec/{test_app → dummy}/config/environment.rb +0 -0
  27. data/spec/{test_app → dummy}/config/environments/development.rb +0 -3
  28. data/spec/{test_app → dummy}/config/environments/production.rb +0 -3
  29. data/spec/{test_app → dummy}/config/environments/test.rb +1 -6
  30. data/spec/{test_app → dummy}/config/initializers/backtrace_silencers.rb +0 -0
  31. data/spec/{test_app → dummy}/config/initializers/inflections.rb +0 -0
  32. data/spec/{test_app → dummy}/config/initializers/mime_types.rb +0 -0
  33. data/spec/{test_app → dummy}/config/initializers/secret_token.rb +0 -0
  34. data/spec/{test_app → dummy}/config/initializers/session_store.rb +0 -0
  35. data/spec/{test_app → dummy}/config/locales/en.yml +0 -0
  36. data/spec/{test_app → dummy}/config/routes.rb +0 -0
  37. data/spec/{test_app → dummy}/db/seeds.rb +0 -0
  38. data/spec/{test_app → dummy}/lib/tasks/.gitkeep +0 -0
  39. data/spec/{test_app → dummy}/public/404.html +0 -0
  40. data/spec/{test_app → dummy}/public/422.html +0 -0
  41. data/spec/{test_app → dummy}/public/500.html +0 -0
  42. data/spec/{test_app → dummy}/public/favicon.ico +0 -0
  43. data/spec/{test_app → dummy}/public/images/rails.png +0 -0
  44. data/spec/{test_app → dummy}/public/javascripts/application.js +0 -0
  45. data/spec/{test_app → dummy}/public/javascripts/controls.js +0 -0
  46. data/spec/{test_app → dummy}/public/javascripts/dragdrop.js +0 -0
  47. data/spec/{test_app → dummy}/public/javascripts/effects.js +0 -0
  48. data/spec/{test_app → dummy}/public/javascripts/prototype.js +0 -0
  49. data/spec/{test_app → dummy}/public/javascripts/rails.js +0 -0
  50. data/spec/{test_app → dummy}/public/robots.txt +0 -0
  51. data/spec/{test_app → dummy}/public/stylesheets/.gitkeep +0 -0
  52. data/spec/{test_app → dummy}/script/rails +0 -0
  53. data/spec/{test_app → dummy}/test/performance/browsing_test.rb +0 -0
  54. data/spec/{test_app → dummy}/test/test_helper.rb +0 -0
  55. data/spec/{test_app → dummy}/vendor/plugins/.gitkeep +0 -0
  56. data/spec/lib/adapters/cache_store_spec.rb +75 -0
  57. data/spec/lib/adapters/redis_store_spec.rb +89 -0
  58. data/spec/lib/cashier_spec.rb +112 -0
  59. data/spec/spec_helper.rb +34 -8
  60. metadata +179 -214
  61. data/..gemspec +0 -21
  62. data/.infinity_test +0 -19
  63. data/.rvmrc +0 -1
  64. data/Gemfile.lock +0 -118
  65. data/lib/cashier/controller_helper.rb +0 -34
  66. data/readme.md +0 -120
  67. data/spec/cashier_spec.rb +0 -89
  68. data/spec/test_app/Gemfile.lock +0 -73
  69. data/spec/test_app/config/database.yml +0 -22
@@ -0,0 +1,45 @@
1
+ module Cashier
2
+ module Adapters
3
+ class CacheStore
4
+ def self.store_fragment_in_tag(fragment, tag)
5
+ fragments = Rails.cache.fetch(tag) || []
6
+ new_fragments = fragments + [fragment]
7
+ Rails.cache.write(tag, new_fragments)
8
+ end
9
+
10
+ def self.store_tags(tags)
11
+ cashier_tags = Rails.cache.fetch(Cashier::CACHE_KEY) || []
12
+ cashier_tags = (cashier_tags + tags).uniq
13
+
14
+ Rails.cache.write(Cashier::CACHE_KEY, cashier_tags)
15
+ end
16
+
17
+ def self.remove_tags(tags)
18
+ cashier_tags = Rails.cache.fetch(Cashier::CACHE_KEY) || []
19
+ cashier_tags = (cashier_tags - tags).uniq
20
+ Rails.cache.write(Cashier::CACHE_KEY, cashier_tags)
21
+ end
22
+
23
+ def self.tags
24
+ Rails.cache.read(Cashier::CACHE_KEY) || []
25
+ end
26
+
27
+ def self.get_fragments_for_tag(tag)
28
+ Rails.cache.read(tag) || []
29
+ end
30
+
31
+ def self.delete_tag(tag)
32
+ Rails.cache.delete(tag)
33
+ end
34
+
35
+ def self.clear
36
+ remove_tags(tags)
37
+ Rails.cache.delete(Cashier::CACHE_KEY)
38
+ end
39
+
40
+ def self.keys
41
+ tags.inject([]) { |arry, tag| arry += Rails.cache.fetch(tag) }.compact
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,46 @@
1
+ module Cashier
2
+ module Adapters
3
+ class RedisStore
4
+ def self.redis
5
+ @@redis
6
+ end
7
+
8
+ def self.redis=(redis_instance)
9
+ @@redis = redis_instance
10
+ end
11
+
12
+ def self.store_fragment_in_tag(fragment, tag)
13
+ redis.sadd(tag, fragment)
14
+ end
15
+
16
+ def self.store_tags(tags)
17
+ tags.each { |tag| redis.sadd(Cashier::CACHE_KEY, tag) }
18
+ end
19
+
20
+ def self.remove_tags(tags)
21
+ tags.each { |tag| redis.srem(Cashier::CACHE_KEY, tag) }
22
+ end
23
+
24
+ def self.tags
25
+ redis.smembers(Cashier::CACHE_KEY) || []
26
+ end
27
+
28
+ def self.get_fragments_for_tag(tag)
29
+ redis.smembers(tag) || []
30
+ end
31
+
32
+ def self.delete_tag(tag)
33
+ redis.del(tag)
34
+ end
35
+
36
+ def self.clear
37
+ remove_tags(tags)
38
+ redis.del(Cashier::CACHE_KEY)
39
+ end
40
+
41
+ def self.keys
42
+ tags.inject([]) { |arry, tag| arry += get_fragments_for_tag(tag) }.compact
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ # Hooks into ApplicationController's write_fragment method.
2
+ # write_fragment is used for action and fragment caching.
3
+ # Create an alias method chain to call our customer method
4
+ # which stores the associated key with the tag in a
5
+ # Redis Set. Then we can expire all those keys from anywhere
6
+ # in the code using Rails.cache.delete
7
+ #
8
+ # I use alias_method_chain instead of calling 'super'
9
+ # because there is a very rare case where someone
10
+ # may have redfined 'write_fragment' in their own
11
+ # controllers. Using an alias method chain
12
+ # keeps those methods intact.
13
+
14
+ class ApplicationController < ActionController::Base
15
+ def write_fragment_with_tagged_key(key, content, options = nil)
16
+ if options && options[:tag] && Cashier.perform_caching?
17
+ tags = case options[:tag].class.to_s
18
+ when 'Proc', 'Lambda'
19
+ options[:tag].call(self)
20
+ else
21
+ options[:tag]
22
+ end
23
+ Cashier.store_fragment fragment_cache_key(key), *tags
24
+ end
25
+ write_fragment_without_tagged_key(key, content, options)
26
+ end
27
+ alias_method_chain :write_fragment, :tagged_key
28
+ end
@@ -1,6 +1,5 @@
1
1
  module Cashier
2
2
  module Matchers
3
-
4
3
  def be_cached
5
4
  Cache.new
6
5
  end
@@ -1,8 +1,9 @@
1
1
  module Cashier
2
2
  class Railtie < Rails::Railtie
3
3
  initializer 'cashier.initialize' do
4
- ApplicationController.send :include, Cashier::ControllerHelper
4
+ ActiveSupport.on_load(:action_controller) do
5
+ require 'cashier/application_controller'
6
+ end
5
7
  end
6
8
  end
7
- end
8
-
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Cashier
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,14 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- require 'rspec/rails'
4
-
5
- class ApplicationController
6
- include Cashier::ControllerHelper
7
- end
8
-
9
3
  describe ApplicationController do
10
- include Rspec::Rails::ControllerExampleGroup
11
-
12
4
  it "should be able to tag framgents" do
13
5
  Cashier.should_receive(:store_fragment).with('views/key', 'tag')
14
6
  controller.write_fragment('key', 'content', :tag => 'tag')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,10 +1,6 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require "active_model/railtie"
4
- require "active_record/railtie"
5
3
  require "action_controller/railtie"
6
- require "action_view/railtie"
7
- require "action_mailer/railtie"
8
4
 
9
5
  # If you have a Gemfile, require the gems listed there, including any gems
10
6
  # you've limited to :test, :development, or :production.
File without changes
File without changes
@@ -14,9 +14,6 @@ TestApp::Application.configure do
14
14
  config.action_view.debug_rjs = true
15
15
  config.action_controller.perform_caching = true
16
16
 
17
- # Don't care if the mailer can't send
18
- config.action_mailer.raise_delivery_errors = false
19
-
20
17
  # Print deprecation notices to the Rails logger
21
18
  config.active_support.deprecation = :log
22
19
 
@@ -34,9 +34,6 @@ TestApp::Application.configure do
34
34
  # Enable serving of images, stylesheets, and javascripts from an asset server
35
35
  # config.action_controller.asset_host = "http://assets.example.com"
36
36
 
37
- # Disable delivery errors, bad email addresses will be ignored
38
- # config.action_mailer.raise_delivery_errors = false
39
-
40
37
  # Enable threaded mode
41
38
  # config.threadsafe!
42
39
 
@@ -13,7 +13,7 @@ TestApp::Application.configure do
13
13
  # Show full error reports and disable caching
14
14
  config.consider_all_requests_local = true
15
15
  config.action_controller.perform_caching = true
16
- config.cache_store = :mem_cache_store
16
+ config.cache_store = :dalli_store
17
17
 
18
18
  # Raise exceptions instead of rendering exception templates
19
19
  config.action_dispatch.show_exceptions = false
@@ -21,11 +21,6 @@ TestApp::Application.configure do
21
21
  # Disable request forgery protection in test environment
22
22
  config.action_controller.allow_forgery_protection = false
23
23
 
24
- # Tell Action Mailer not to deliver emails to the real world.
25
- # The :test delivery method accumulates sent emails in the
26
- # ActionMailer::Base.deliveries array.
27
- config.action_mailer.delivery_method = :test
28
-
29
24
  # Use SQL instead of Active Record's schema dumper when creating the test database.
30
25
  # This is necessary if your schema can't be completely dumped by the schema dumper,
31
26
  # like if you have constraints or database-specific column types
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cashier::Adapters::CacheStore do
4
+ subject { Cashier::Adapters::CacheStore }
5
+ let(:cache) { Rails.cache }
6
+
7
+ it "should store the fragment in a tag" do
8
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
9
+ cache.fetch('dashboard').should eql(['fragment-key'])
10
+ end
11
+
12
+ it "should store the tag in the tags array" do
13
+ subject.store_tags(["dashboard"])
14
+ cache.fetch(Cashier::CACHE_KEY).should eql(['dashboard'])
15
+ end
16
+
17
+ it "should return all of the fragments for a given tag" do
18
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
19
+ subject.store_fragment_in_tag('fragment-key-2', 'dashboard')
20
+ subject.store_fragment_in_tag('fragment-key-3', 'dashboard')
21
+
22
+ subject.get_fragments_for_tag('dashboard').length.should == 3
23
+ end
24
+
25
+ it "should delete a tag from the cache" do
26
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
27
+ Rails.cache.read('dashboard').should_not be_nil
28
+
29
+ subject.delete_tag('dashboard')
30
+ Rails.cache.read('dashboard').should be_nil
31
+ end
32
+
33
+ it "should return the list of tags" do
34
+ (1..5).each {|i| subject.store_tags(["tag-#{i}"])}
35
+ subject.tags.length.should == 5
36
+ end
37
+
38
+ it "should return the tags correctly" do
39
+ subject.store_tags(["tag-1", "tag-2", "tag-3"])
40
+ subject.tags.include?("tag-1").should be_true
41
+ end
42
+
43
+ it "should remove tags from the tags list" do
44
+ (1..5).each {|i| subject.store_tags(["tag-#{i}"])}
45
+ subject.remove_tags(["tag-1", "tag-2", "tag-3", "tag-4", "tag-5"])
46
+ subject.tags.length.should == 0
47
+ end
48
+
49
+ context "clear" do
50
+ before(:each) do
51
+ subject.store_tags(['dashboard'])
52
+ subject.store_tags(['settings'])
53
+ subject.store_tags(['email'])
54
+ end
55
+
56
+ it "should clear the cache and remove all of the tags" do
57
+ subject.should_receive(:remove_tags).with(['dashboard','settings','email'])
58
+ subject.clear
59
+ Rails.cache.read(Cashier::CACHE_KEY).should be_nil
60
+ end
61
+ end
62
+
63
+ context "keys" do
64
+ it "should return the list of keys" do
65
+
66
+ subject.store_tags(['dashboard', 'settings', 'email'])
67
+
68
+ subject.store_fragment_in_tag('key1', 'dashboard')
69
+ subject.store_fragment_in_tag('key2', 'settings')
70
+ subject.store_fragment_in_tag('key3', 'email')
71
+
72
+ subject.keys.should eql(%w(key1 key2 key3))
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cashier::Adapters::RedisStore do
4
+ subject { Cashier::Adapters::RedisStore }
5
+ let(:cache) { Rails.cache }
6
+ let(:redis) { subject.redis }
7
+
8
+ context "setting and getting the redis instance" do
9
+ it "should allow to set the redis instance" do
10
+ subject.respond_to?(:redis=).should be_true
11
+ end
12
+
13
+ it "should allow to get the redis instance" do
14
+ subject.respond_to?(:redis).should be_true
15
+ end
16
+ end
17
+
18
+ it "should return the redis instance you set" do
19
+ subject.redis = redis
20
+ subject.redis.should == redis
21
+ end
22
+
23
+ it "should store the fragment in a tag" do
24
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
25
+ redis.smembers('dashboard').should eql(['fragment-key'])
26
+ end
27
+
28
+ it "should store the tag in the tags array" do
29
+ subject.store_tags(["dashboard"])
30
+ redis.smembers(Cashier::CACHE_KEY).should eql(['dashboard'])
31
+ end
32
+
33
+ it "should return all of the fragments for a given tag" do
34
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
35
+ subject.store_fragment_in_tag('fragment-key-2', 'dashboard')
36
+ subject.store_fragment_in_tag('fragment-key-3', 'dashboard')
37
+
38
+ subject.get_fragments_for_tag('dashboard').length.should == 3
39
+ end
40
+
41
+ it "should delete a tag from the cache" do
42
+ subject.store_fragment_in_tag('fragment-key', 'dashboard')
43
+ redis.smembers('dashboard').should_not be_nil
44
+
45
+ subject.delete_tag('dashboard')
46
+ redis.exists('dashboard').should be_false
47
+ end
48
+
49
+ it "should return the list of tags" do
50
+ (1..5).each {|i| subject.store_tags(["tag-#{i}"])}
51
+ subject.tags.length.should == 5
52
+ end
53
+
54
+ it "should return the tags correctly" do
55
+ subject.store_tags(["tag-1", "tag-2", "tag-3"])
56
+ subject.tags.include?("tag-1").should be_true
57
+ end
58
+
59
+ it "should remove tags from the tags list" do
60
+ (1..5).each {|i| subject.store_tags(["tag-#{i}"])}
61
+ subject.remove_tags(["tag-1", "tag-2", "tag-3", "tag-4", "tag-5"])
62
+ subject.tags.length.should == 0
63
+ end
64
+
65
+ context "clear" do
66
+ before(:each) do
67
+ subject.store_tags(['dashboard'])
68
+ subject.store_tags(['settings'])
69
+ subject.store_tags(['email'])
70
+ end
71
+
72
+ it "should clear the cache and remove all of the tags" do
73
+ subject.clear
74
+ redis.smembers(Cashier::CACHE_KEY).should eql([])
75
+ end
76
+ end
77
+
78
+ context "keys" do
79
+ it "should return the list of keys" do
80
+ subject.store_tags(['dashboard', 'settings', 'email'])
81
+
82
+ subject.store_fragment_in_tag('key1', 'dashboard')
83
+ subject.store_fragment_in_tag('key2', 'settings')
84
+ subject.store_fragment_in_tag('key3', 'email')
85
+
86
+ subject.keys.sort.should eql(%w(key1 key2 key3))
87
+ end
88
+ end
89
+ end