memflash 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ test/rails/log/*.log
2
+ pkg
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ Memflash
2
+ ========
3
+
4
+ Memflash is a gem which enables storing really long values in the Rails FlashHash
5
+ without writing them to the session. Instead, it transparently uses `Rails.cache`, thus
6
+ enabling the flash in your actions to contain large values, and still fit in a cookie-based
7
+ session store.
8
+
9
+ How do I use it?
10
+ ================
11
+
12
+ Memflash is completely transparent -- requiring the gem automatically enhances FlashHash
13
+ with caching-enabled reads and writes.
14
+
15
+ By default, any message that is over 300 characters long, will be saved in Rails.cache,
16
+ and a pointer to it stored in the flash. You can change this anywhere in your app by:
17
+
18
+ Memflash.threshold = #{length-at-which-writing-to-the-cache-is-trigerred}
19
+
20
+ How does it work?
21
+ =================
22
+
23
+ Memflash ties into the [] and []= methods of Rails's FlashHash. On writes, if the value
24
+ being written has a length over Memflash.threshold, Memflash generates a pseudo-random
25
+ key for it, writes the pseudo-random key and original value to `Rails.cache`, and stores
26
+ the original key and pseudo-random key in the flash. Conceptually, when you write
27
+ `flash[:error] = "some message"`, this is equivalent to:
28
+
29
+ if "some message".length >= Memflash.threshold
30
+ # generate a psedudo-random key, memflash_key
31
+ # write memflash_key, "some message" to Rails.cache
32
+ # write :error, memflash_key to the flash
33
+ else
34
+ # write :error, "some message" to the flash, as usual
35
+ end
36
+
37
+ On the flip side, reading from the flash, `flash[:error]` is conceptually equivalent to:
38
+
39
+ if the value for :error stored in the flash is a memflash key
40
+ # read the original (large) value from Rails.cache
41
+ # return the original (large) value
42
+ else
43
+ # return the value stored in the flash, as usual
44
+ end
45
+
46
+ Anything else?
47
+ ==============
48
+
49
+ We'd love to hear from you!
50
+
51
+ Authored by [Vladimir Andrijevik](mailto:vladimir@zendesk.com)
52
+
53
+ Copyright (c) 2010 Zendesk, released under the MIT license
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "memflash"
8
+ gem.summary = "Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session"
9
+ gem.description = "Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session. Instead, it transparently uses `Rails.cache`, thus enabling the flash in your actions to contain large values, and still fit in a cookie-based session store"
10
+ gem.email = "vladimir@zendesk.com"
11
+ gem.homepage = "http://github.com/zendesk/memflash"
12
+ gem.authors = ["Vladimir Andrijevik"]
13
+ gem.version = "1.0.0"
14
+ gem.add_dependency "actionpack", "~> 2.3.5"
15
+ gem.add_development_dependency "rails", "~> 2.3.5"
16
+ gem.add_development_dependency "shoulda", "~> 2.11.0"
17
+
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/*_test.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ task :default => :test
@@ -0,0 +1,43 @@
1
+ module Memflash
2
+ mattr_accessor :threshold
3
+ self.threshold = 300 # Messages longer than this will be stored in Rails.cache
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include InstanceMethods
8
+ alias_method_chain :[]=, :caching
9
+ alias_method_chain :[], :caching
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ define_method "[]_with_caching=" do |key, value|
15
+ value_for_hash = value
16
+
17
+ if value.kind_of?(String) && value.length >= Memflash.threshold
18
+ value_for_hash = memflash_key(key)
19
+ Rails.cache.write(value_for_hash, value)
20
+ end
21
+
22
+ send("[]_without_caching=", key, value_for_hash)
23
+ end
24
+
25
+ define_method "[]_with_caching" do |key|
26
+ value_in_hash = send("[]_without_caching", key)
27
+ memflashed?(key, value_in_hash) ? Rails.cache.read(value_in_hash) : value_in_hash
28
+ end
29
+
30
+ private
31
+ def memflash_key(hash_key)
32
+ "Memflash-#{hash_key}-#{Time.now.to_f}-#{Kernel.rand}"
33
+ end
34
+
35
+ def memflashed?(key, value)
36
+ !!(value =~ /^Memflash-#{key}/)
37
+ end
38
+ end # InstanceMethods
39
+ end # Memflash
40
+
41
+ require 'action_pack'
42
+ require 'action_controller'
43
+ ActionController::Flash::FlashHash.class_eval { include Memflash }
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{memflash}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Vladimir Andrijevik"]
12
+ s.date = %q{2010-09-14}
13
+ s.description = %q{Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session. Instead, it transparently uses `Rails.cache`, thus enabling the flash in your actions to contain large values, and still fit in a cookie-based session store}
14
+ s.email = %q{vladimir@zendesk.com}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "MIT-LICENSE",
21
+ "README.markdown",
22
+ "Rakefile",
23
+ "lib/memflash.rb",
24
+ "memflash.gemspec",
25
+ "test/memflash_test.rb",
26
+ "test/rails/app/controllers/application.rb",
27
+ "test/rails/config/boot.rb",
28
+ "test/rails/config/environment.rb",
29
+ "test/rails/config/environments/test.rb",
30
+ "test/rails/config/routes.rb",
31
+ "test/test_helper.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/zendesk/memflash}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.7}
37
+ s.summary = %q{Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session}
38
+ s.test_files = [
39
+ "test/memflash_test.rb",
40
+ "test/rails/app/controllers/application.rb",
41
+ "test/rails/config/boot.rb",
42
+ "test/rails/config/environment.rb",
43
+ "test/rails/config/environments/test.rb",
44
+ "test/rails/config/routes.rb",
45
+ "test/test_helper.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ s.add_runtime_dependency(%q<actionpack>, ["~> 2.3.5"])
54
+ s.add_development_dependency(%q<rails>, ["~> 2.3.5"])
55
+ s.add_development_dependency(%q<shoulda>, ["~> 2.11.0"])
56
+ else
57
+ s.add_dependency(%q<actionpack>, ["~> 2.3.5"])
58
+ s.add_dependency(%q<rails>, ["~> 2.3.5"])
59
+ s.add_dependency(%q<shoulda>, ["~> 2.11.0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<actionpack>, ["~> 2.3.5"])
63
+ s.add_dependency(%q<rails>, ["~> 2.3.5"])
64
+ s.add_dependency(%q<shoulda>, ["~> 2.11.0"])
65
+ end
66
+ end
67
+
@@ -0,0 +1,117 @@
1
+ require "test_helper"
2
+
3
+ class MemflashTest < Test::Unit::TestCase
4
+ class EnhancedHash < Hash
5
+ include Memflash
6
+ end
7
+
8
+ def setup
9
+ @hash = EnhancedHash.new
10
+ end
11
+
12
+ context "A memflash-enhanced Hash" do
13
+ should "have a caching-enabled []" do
14
+ assert @hash.respond_to?("[]_with_caching")
15
+ end
16
+
17
+ should "have a caching-enabled []=" do
18
+ assert @hash.respond_to?("[]_with_caching=")
19
+ end
20
+ end # A memflash-enhanced Hash
21
+
22
+ context "In a memflash-enhanced Hash, storing a value" do
23
+ context "that is a String" do
24
+ context "shorter than Memflash.threshold" do
25
+ should "not affect the cache" do
26
+ Rails.cache.expects(:write).never
27
+
28
+ @hash[:hello] = "a" * (Memflash.threshold - 1)
29
+ end # not affect the cache
30
+ end # shorter than Memflash.threshold
31
+
32
+ context "at least as long as Memflash.threshold" do
33
+ setup do
34
+ @key = "a-sample-key"
35
+ @value = "a" * (Memflash.threshold)
36
+ end
37
+
38
+ should "call memflash_key with the key" do
39
+ @hash.expects(:memflash_key).with(@key)
40
+
41
+ @hash[@key] = @value
42
+ end # call memflash_key with the key
43
+
44
+ should "write the memflash_key and value to Rails.cache" do
45
+ # Stubbing out memflash_key is necessary so we can set a proper expectation below.
46
+ # Without it, the key generated when setting the expectation and the one during
47
+ # the actual write are different, so the assertion fails
48
+ @hash.stubs(:memflash_key).with(@key).returns("a-memflash-key")
49
+
50
+ Rails.cache.expects(:write).with("a-memflash-key", @value)
51
+
52
+ @hash[@key] = @value
53
+ end # write the memflash_key and value to Rails.cache
54
+
55
+ should "store the memflash_key in place of the original value" do
56
+ # Stubbing out memflash_key is necessary so we can assert against the value
57
+ # in the hash below. Without it, we don't know the memflash key that is generated,
58
+ # so we cannot test whether it's in the hash or not.
59
+ @hash.stubs(:memflash_key).with(@key).returns("a-memflash-key")
60
+ @hash[@key] = @value
61
+
62
+ assert_equal "a-memflash-key", @hash[@key]
63
+ end # store the memflash_key in place of the original value
64
+ end # at least as long as Memflash.threshold
65
+ end # that is a String
66
+
67
+ context "that is not a String" do
68
+ should "not affect the cache" do
69
+ Rails.cache.expects(:write).never
70
+
71
+ @hash[:time] = Time.now.to_i
72
+ end # not affect the cache
73
+ end # that is not a String
74
+ end # In a memflash-enhanced Hash, storing a value
75
+
76
+ context "From a memflash-enhanced Hash, reading by a key" do
77
+ should "check whether the value in the hash was memflashed" do
78
+ @hash[:hello] = "world"
79
+
80
+ @hash.expects(:memflashed?).with(:hello, "world")
81
+
82
+ @hash[:hello]
83
+ end
84
+
85
+ context "whose value was memflashed" do
86
+ setup do
87
+ @hash.stubs(:memflashed?).returns(true)
88
+ end
89
+
90
+ should "retrieve the original value from Rails.cache" do
91
+ key = "a-sample-memflashed-key"
92
+ @hash[key] = "key-to-look-up-in-rails-cache"
93
+ Rails.cache.expects(:read).with("key-to-look-up-in-rails-cache")
94
+
95
+ @hash[key]
96
+ end # retrieve the original value from Rails.cache
97
+ end # whose value was memflashed
98
+
99
+ context "whose value was not memflashed" do
100
+ setup do
101
+ @hash.stubs(:memflashed?).returns(false)
102
+ end
103
+
104
+ should "not read from Rails.cache" do
105
+ Rails.cache.expects(:read).never
106
+
107
+ @hash["a-non-memflashed-key"]
108
+ end # not read from Rails.cache
109
+ end # whose value was not memflashed
110
+ end # From a memflash-enhanced Hash, reading a value
111
+
112
+ context "ActionController::Flash::FlashHash" do
113
+ should "be automatically cache-enhanced" do
114
+ assert ActionController::Flash::FlashHash.ancestors.include?(Memflash)
115
+ end
116
+ end # ActionController::Flash::FlashHash
117
+ end
@@ -0,0 +1,109 @@
1
+ # Don't change this file!
2
+ # Configure your app in config/environment.rb and config/environments/*.rb
3
+
4
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
+
6
+ module Rails
7
+ class << self
8
+ def boot!
9
+ unless booted?
10
+ preinitialize
11
+ pick_boot.run
12
+ end
13
+ end
14
+
15
+ def booted?
16
+ defined? Rails::Initializer
17
+ end
18
+
19
+ def pick_boot
20
+ (vendor_rails? ? VendorBoot : GemBoot).new
21
+ end
22
+
23
+ def vendor_rails?
24
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
25
+ end
26
+
27
+ def preinitialize
28
+ load(preinitializer_path) if File.exist?(preinitializer_path)
29
+ end
30
+
31
+ def preinitializer_path
32
+ "#{RAILS_ROOT}/config/preinitializer.rb"
33
+ end
34
+ end
35
+
36
+ class Boot
37
+ def run
38
+ load_initializer
39
+ Rails::Initializer.run(:set_load_path)
40
+ end
41
+ end
42
+
43
+ class VendorBoot < Boot
44
+ def load_initializer
45
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
+ Rails::Initializer.run(:install_gem_spec_stubs)
47
+ end
48
+ end
49
+
50
+ class GemBoot < Boot
51
+ def load_initializer
52
+ self.class.load_rubygems
53
+ load_rails_gem
54
+ require 'initializer'
55
+ end
56
+
57
+ def load_rails_gem
58
+ if version = self.class.gem_version
59
+ gem 'rails', version
60
+ else
61
+ gem 'rails'
62
+ end
63
+ rescue Gem::LoadError => load_error
64
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
65
+ exit 1
66
+ end
67
+
68
+ class << self
69
+ def rubygems_version
70
+ Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
71
+ end
72
+
73
+ def gem_version
74
+ if defined? RAILS_GEM_VERSION
75
+ RAILS_GEM_VERSION
76
+ elsif ENV.include?('RAILS_GEM_VERSION')
77
+ ENV['RAILS_GEM_VERSION']
78
+ else
79
+ parse_gem_version(read_environment_rb)
80
+ end
81
+ end
82
+
83
+ def load_rubygems
84
+ require 'rubygems'
85
+
86
+ unless rubygems_version >= '0.9.4'
87
+ $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
88
+ exit 1
89
+ end
90
+
91
+ rescue LoadError
92
+ $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93
+ exit 1
94
+ end
95
+
96
+ def parse_gem_version(text)
97
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
98
+ end
99
+
100
+ private
101
+ def read_environment_rb
102
+ File.read("#{RAILS_ROOT}/config/environment.rb")
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ # All that for this:
109
+ Rails.boot!
@@ -0,0 +1,9 @@
1
+ # Bootstrap the Rails environment, frameworks, and default configuration
2
+ require File.join(File.dirname(__FILE__), 'boot')
3
+
4
+ Rails::Initializer.run do |config|
5
+ config.frameworks -= [ :active_record ]
6
+ config.action_controller.session = { :key => "_memflash_session", :secret => "ac0dcc5b4d9eef497e671126a845c3c5" }
7
+
8
+ config.gem 'shoulda', :lib => 'shoulda/rails'
9
+ end
@@ -0,0 +1,19 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
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.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Tell ActionMailer not to deliver emails to the real world.
17
+ # The :test delivery method accumulates sent emails in the
18
+ # ActionMailer::Base.deliveries array.
19
+ config.action_mailer.delivery_method = :test
File without changes
@@ -0,0 +1,6 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "rails", "config", "environment"))
3
+
4
+ require 'rubygems'
5
+ require 'active_support/test_case'
6
+ require "memflash"
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: memflash
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Vladimir Andrijevik
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-09-14 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: actionpack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 9
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 5
34
+ version: 2.3.5
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rails
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 9
46
+ segments:
47
+ - 2
48
+ - 3
49
+ - 5
50
+ version: 2.3.5
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: shoulda
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 35
62
+ segments:
63
+ - 2
64
+ - 11
65
+ - 0
66
+ version: 2.11.0
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session. Instead, it transparently uses `Rails.cache`, thus enabling the flash in your actions to contain large values, and still fit in a cookie-based session store
70
+ email: vladimir@zendesk.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - README.markdown
77
+ files:
78
+ - .gitignore
79
+ - MIT-LICENSE
80
+ - README.markdown
81
+ - Rakefile
82
+ - lib/memflash.rb
83
+ - memflash.gemspec
84
+ - test/memflash_test.rb
85
+ - test/rails/app/controllers/application.rb
86
+ - test/rails/config/boot.rb
87
+ - test/rails/config/environment.rb
88
+ - test/rails/config/environments/test.rb
89
+ - test/rails/config/routes.rb
90
+ - test/test_helper.rb
91
+ has_rdoc: true
92
+ homepage: http://github.com/zendesk/memflash
93
+ licenses: []
94
+
95
+ post_install_message:
96
+ rdoc_options:
97
+ - --charset=UTF-8
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ requirements: []
119
+
120
+ rubyforge_project:
121
+ rubygems_version: 1.3.7
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: Memflash is a gem which enables storing really long values in the Rails FlashHash without writing them to the session
125
+ test_files:
126
+ - test/memflash_test.rb
127
+ - test/rails/app/controllers/application.rb
128
+ - test/rails/config/boot.rb
129
+ - test/rails/config/environment.rb
130
+ - test/rails/config/environments/test.rb
131
+ - test/rails/config/routes.rb
132
+ - test/test_helper.rb