rack-flash3 1.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.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # Rack Flash
2
+
3
+ flash[:notice] = "You can stop rolling your own now."
4
+
5
+ Simple flash hash implementation for Rack apps.
6
+
7
+ [View the RDoc](http://gitrdoc.com/nakajima/rack-flash/tree/master).
8
+
9
+ ## Usage
10
+
11
+ Here's how to use it.
12
+
13
+ ### Vanilla Rack apps
14
+
15
+ You can access flash entries via `env['x-rack.flash']`. You can treat it either
16
+ like a regular flash hash:
17
+
18
+ env['x-rack.flash'][:notice] = 'You have logged out.'
19
+
20
+ Or you can pass the `:accessorize` option to declare your flash types. Each of
21
+ these will have accessors defined on the flash object:
22
+
23
+ use Rack::Flash, :accessorize => [:notice, :error]
24
+
25
+ # Set a flash entry
26
+ env['x-rack.flash'].notice = 'You have logged out.'
27
+
28
+ # Get a flash entry
29
+ env['x-rack.flash'].notice # => 'You have logged out.'
30
+
31
+ # Set a a flash entry for only the current request
32
+ env['x-rack.flash'].notice! 'You have logged out.'
33
+
34
+ Sample rack app:
35
+
36
+ get = proc { |env|
37
+ [200, {},
38
+ env['x-rack.flash'].notice || 'No flash set. Try going to /set'
39
+ ]
40
+ }
41
+
42
+ set = proc { |env|
43
+ env['x-rack.flash'].notice = 'Hey, the flash was set!'
44
+ [302, {'Location' => '/'},
45
+ 'You are being redirected.'
46
+ ]
47
+ }
48
+
49
+ builder = Rack::Builder.new do
50
+ use Rack::Session::Cookie
51
+ use Rack::Flash, :accessorize => true
52
+
53
+ map('/set') { run set }
54
+ map('/') { run get }
55
+ end
56
+
57
+ Rack::Handler::Mongrel.run builder, :Port => 9292
58
+
59
+ ### Sinatra
60
+
61
+ If you're using Sinatra, you can use the flash hash just like in Rails:
62
+
63
+ require 'sinatra/base'
64
+ require 'rack-flash'
65
+
66
+ class MyApp < Sinatra::Base
67
+ enable :sessions
68
+ use Rack::Flash
69
+
70
+ post '/set-flash' do
71
+ # Set a flash entry
72
+ flash[:notice] = "Thanks for signing up!"
73
+
74
+ # Get a flash entry
75
+ flash[:notice] # => "Thanks for signing up!"
76
+
77
+ # Set a flash entry for only the current request
78
+ flash.now[:notice] = "Thanks for signing up!"
79
+ end
80
+ end
81
+
82
+ If you've got any ideas on how to simplify access to the flash hash for vanilla
83
+ Rack apps, let me know. It still feels a bit off to me.
84
+
85
+ ## Sweeping stale entries
86
+
87
+ By default Rack::Flash has slightly different behavior than Rails in that it
88
+ doesn't delete entries until they are used. If you want entries to be cleared
89
+ even if they are not ever accessed, you can use the `:sweep` option:
90
+
91
+ use Rack::Flash, :sweep => true
92
+
93
+ This will sweep stale flash entries, whether or not you actually use them.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler2'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rack-flash3"
8
+ gem.summary = "Flash hash implementation for Rack apps."
9
+ gem.description = "Flash hash implementation for Rack apps."
10
+ gem.email = "treeder@gmail.com"
11
+ gem.homepage = "http://www.iron.io"
12
+ gem.authors = ["Pat Nakajima", "Travis Reeder"]
13
+ gem.add_dependency 'rack'
14
+ gem.required_ruby_version = '>= 1.9'
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler2"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ task :default => :test
data/VERSION.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 1
3
+ :minor: 0
4
+ :patch: 0
5
+ :build: !!null
@@ -0,0 +1,22 @@
1
+ require 'rack/request'
2
+ require 'rack/response'
3
+ require 'rack/showexceptions'
4
+ require 'rack/session/cookie'
5
+ require File.dirname(__FILE__) + '/../lib/rack-flash'
6
+
7
+ class Base
8
+ attr_accessor :env
9
+
10
+ def call(env)
11
+ @env = env
12
+ flash['err'] = "IT'S ALIVE"
13
+ res = Rack::Response.new
14
+ res.write "<title>Flashy</title>"
15
+ res.write "#{flash['err']}"
16
+ res.finish
17
+ end
18
+ end
19
+ use Rack::Session::Cookie
20
+ use Rack::Flash#, :flash_app_class => Base
21
+ use Rack::ShowExceptions
22
+ run Base.new
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'sinatra/base'
3
+ require File.dirname(__FILE__) + '/../lib/rack-flash'
4
+
5
+ class MyApp < Sinatra::Base
6
+ use Rack::Flash
7
+
8
+ set :root, File.dirname(__FILE__)
9
+ set :layout, true
10
+ set :logging, true
11
+ set :sessions, true
12
+
13
+ get '/' do
14
+ erb :index
15
+ end
16
+
17
+ # View the value of any given flash
18
+ get '/:name' do
19
+ erb :show
20
+ end
21
+
22
+ post '/:name' do
23
+ if params[:message].strip.empty?
24
+ flash["err"] = "You must enter a message."
25
+ flash["err_on_#{params[:name]}"] = 1
26
+ redirect('/')
27
+ end
28
+
29
+ flash[:ok] = "Set flash entry!"
30
+
31
+ flash[params[:name]] = params[:message]
32
+ redirect '/'
33
+ end
34
+
35
+ run!
36
+ end
@@ -0,0 +1,28 @@
1
+ <% if flash.has?(:err) %>
2
+ <h3 class="err"><%= flash[:err] %></h3>
3
+ <% end %>
4
+
5
+ <% if flash.has?(:ok) %>
6
+ <h3 class="ok"><%= flash[:ok] %></h3>
7
+ <% end %>
8
+
9
+ <% [:notice, :error, :success, :whatevz, :bliggety].each do |name| %>
10
+ <form action="/<%= name %>" method="post" accept-charset="utf-8">
11
+ <label>
12
+ <span>
13
+ <% if flash.has?(name) %>
14
+ <a href="/<%= name %>">View Current</a>
15
+ <% end %>
16
+
17
+ Set <code>flash[:<%= name %>]</code>
18
+
19
+ <% if err = flash["err_on_#{name}"] %>
20
+ <strong class="err_on">Required!</strong>
21
+ <% end %>
22
+ </span>
23
+ <input type="text" name="message" value="" id="message">
24
+ </label>
25
+
26
+ <input type="submit" value="Set Flash">
27
+ </form>
28
+ <% end %>
@@ -0,0 +1,131 @@
1
+ <html>
2
+ <head>
3
+ <title>Flash Examples</title>
4
+ <style type="text/css" media="screen">
5
+ * {
6
+ margin: 0;
7
+ padding: 0;
8
+ }
9
+
10
+ body {
11
+ font-family: Helvetica;
12
+ font-size: 18px;
13
+ }
14
+
15
+ a {
16
+ color: #f09;
17
+ text-decoration: none;
18
+ padding: 0px 3px;
19
+ }
20
+
21
+ a:hover {
22
+ background: #f09;
23
+ color: #fff;
24
+ }
25
+
26
+ a:active {
27
+ text-decoration: underline;
28
+ }
29
+
30
+ h1 {
31
+ text-align: center;
32
+ }
33
+
34
+ code {
35
+ font-family: Bitstream Vera Sans Mono , monospace;
36
+ background: #D4EBF7;
37
+ }
38
+
39
+ form {
40
+ margin: 0.4em auto;
41
+ display: inline-block;
42
+ }
43
+
44
+ label {
45
+ line-height: 1em;
46
+ height: 1em;
47
+ }
48
+
49
+ label span {
50
+ display: block;
51
+ font-size: 12px;
52
+ margin-bottom: 1px;
53
+ }
54
+
55
+ label a {
56
+ font-weight: bold;
57
+ float: right;
58
+ margin-right: 79px;
59
+ line-height: 1.5em;
60
+ }
61
+
62
+ input[type="text"] {
63
+ padding: 2px;
64
+ font-size: 18px;
65
+ width: 610px;
66
+ margin-right: 10px;
67
+ }
68
+
69
+ input[type="submit"] {
70
+ cursor: pointer;
71
+ vertical-align: 20%;
72
+ }
73
+
74
+ .err, .ok {
75
+ margin: 0.3em 0;
76
+ padding: 5px 7px;
77
+ text-align: center;
78
+ color: #fff;
79
+ }
80
+
81
+ .ok {
82
+ background: #00A8FF;
83
+ }
84
+
85
+ .err {
86
+ background: #f10;
87
+ }
88
+
89
+ .err_on {
90
+ display: inline-block;
91
+ padding: 0px 3px;
92
+ color: #f10;
93
+ font-weight: bold;
94
+ }
95
+
96
+ .highlight {
97
+ background: #ffc;
98
+ padding: 10px;
99
+ margin-bottom: 10px;
100
+ }
101
+
102
+ #content {
103
+ width: 700px;
104
+ margin: 1em auto;
105
+ }
106
+
107
+ #result {
108
+ font-size: 48px;
109
+ margin: 10% auto 20%;
110
+ text-align: center;
111
+ display: block;
112
+ }
113
+
114
+ #result cite {
115
+ font-size: 14px;
116
+ display: block;
117
+ text-align: right;
118
+ }
119
+
120
+ #result cite code {
121
+ font-style: normal;
122
+ }
123
+ </style>
124
+ </head>
125
+ <body>
126
+ <div id="content">
127
+ <h1><code>Sinatra::Flash</code></h1>
128
+ <%= yield %>
129
+ </div>
130
+ </body>
131
+ </html>
@@ -0,0 +1,15 @@
1
+ <div id="result">
2
+ <% if flash.has?(params[:name]) %>
3
+ <h1 class="highlight"><%= flash[params[:name]] %></h1>
4
+ <cite>- from <code>flash[:<%= params[:name] %>]</code></cite>
5
+ <% else %>
6
+ <p>No flash message for <code>flash[:<%= params[:name] %>]</code></p>
7
+ <% end %>
8
+
9
+ <br>
10
+
11
+ <small>
12
+ <a href="/">Go Back Home</a>
13
+ </small>
14
+ </div>
15
+
data/lib/rack-flash.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), *%w[rack flash])
data/lib/rack/flash.rb ADDED
@@ -0,0 +1,138 @@
1
+ module Rack
2
+
3
+ class Flash
4
+ # Raised when the session passed to FlashHash initialize is nil. This
5
+ # is usually an indicator that session middleware is not in use.
6
+ class SessionUnavailable < StandardError; end
7
+
8
+ # Implements bracket accessors for storing and retrieving flash entries.
9
+ class FlashHash
10
+ attr_reader :flagged
11
+
12
+ def initialize(store, opts={})
13
+ raise Rack::Flash::SessionUnavailable \
14
+ .new('Rack::Flash depends on session middleware.') unless store
15
+
16
+ @opts = opts
17
+ @store = store
18
+
19
+ if accessors = @opts[:accessorize]
20
+ accessors.each { |opt| def_accessor(opt) }
21
+ end
22
+ end
23
+
24
+ # Remove an entry from the session and return its value. Cache result in
25
+ # the instance cache.
26
+ def [](key)
27
+ key = key.to_sym
28
+ cache[key] ||= values.delete(key)
29
+ end
30
+
31
+ # Store the entry in the session, updating the instance cache as well.
32
+ def []=(key,val)
33
+ key = key.to_sym
34
+ cache[key] = values[key] = val
35
+ end
36
+
37
+ # Store a flash entry for only the current request, swept regardless of
38
+ # whether or not it was actually accessed. Useful for AJAX requests, where
39
+ # you want a flash message, even though you're response isn't redirecting.
40
+ def now
41
+ cache
42
+ end
43
+
44
+ # Checks for the presence of a flash entry without retrieving or removing
45
+ # it from the cache or store.
46
+ def has?(key)
47
+ [cache, values].any? { |store| store.keys.include?(key.to_sym) }
48
+ end
49
+ alias_method :include?, :has?
50
+
51
+ # Mark existing entries to allow for sweeping.
52
+ def flag!
53
+ @flagged = values.keys
54
+ end
55
+
56
+ # Remove flagged entries from flash session, clear flagged list.
57
+ def sweep!
58
+ Array(flagged).each { |key| values.delete(key) }
59
+ flagged.clear
60
+ end
61
+
62
+ # Hide the underlying :__FLASH__ session key and only expose values stored
63
+ # in the flash.
64
+ def inspect
65
+ '#<FlashHash @values=%s @cache=%s>' % [values.inspect, cache.inspect]
66
+ end
67
+
68
+ # Human readable for logging.
69
+ def to_s
70
+ values.inspect
71
+ end
72
+
73
+ private
74
+
75
+ # Maintain an instance-level cache of retrieved flash entries. These
76
+ # entries will have been removed from the session, but are still available
77
+ # through the cache.
78
+ def cache
79
+ @cache ||= {}
80
+ end
81
+
82
+ # Helper to access flash entries from :__FLASH__ session value. This key
83
+ # is used to prevent collisions with other user-defined session values.
84
+ def values
85
+ @store[:__FLASH__] ||= {}
86
+ end
87
+
88
+ # Generate accessor methods for the given entry key if :accessorize is true.
89
+ def def_accessor(key)
90
+ raise ArgumentError.new('Invalid entry type: %s' % key) if respond_to?(key)
91
+
92
+ class << self; self end.class_eval do
93
+ define_method(key) { |*args| val = args.first; val ? (self[key]=val) : self[key] }
94
+ define_method("#{key}=") { |val| self[key] = val }
95
+ define_method("#{key}!") { |val| cache[key] = val }
96
+ end
97
+ end
98
+ end
99
+
100
+ # -------------------------------------------------------------------------
101
+ # - Rack Middleware implementation
102
+
103
+ def initialize(app, opts={})
104
+ if klass = app_class(app, opts)
105
+ klass.class_eval do
106
+ def flash; env['x-rack.flash'] end
107
+ end
108
+ end
109
+
110
+ @app, @opts = app, opts
111
+ end
112
+
113
+ def call(env)
114
+ env['x-rack.flash'] ||= Rack::Flash::FlashHash.new(env['rack.session'], @opts)
115
+
116
+ if @opts[:sweep]
117
+ env['x-rack.flash'].flag!
118
+ end
119
+
120
+ res = @app.call(env)
121
+
122
+ if @opts[:sweep]
123
+ env['x-rack.flash'].sweep!
124
+ end
125
+
126
+ res
127
+ end
128
+
129
+ private
130
+
131
+ def app_class(app, opts)
132
+ return nil if opts.has_key?(:helper) and not opts[:helper]
133
+ opts[:flash_app_class] ||
134
+ defined?(Sinatra::Base) && Sinatra::Base ||
135
+ self.class.rack_builder.leaf_app.class
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,14 @@
1
+ module Rack
2
+ class Flash
3
+ def self.fake_session
4
+ @fake_session ||= {}
5
+ end
6
+
7
+ alias_method :old_call, :call
8
+ def new_call(env)
9
+ env['rack.session'] ||= Rack::Flash.fake_session
10
+ old_call(env)
11
+ end
12
+ alias_method :call, :new_call
13
+ end
14
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ gem 'sinatra', '<=1.3.2'
3
+ require 'sinatra/base'
4
+ require 'bacon'
5
+ require 'rack/test'
6
+ require File.join(File.dirname(__FILE__), *%w[.. lib rack-flash])
7
+
8
+ class String
9
+ [:green, :yellow, :red].each { |c| define_method(c) { self } }
10
+ end if ENV['TM_RUBY']
11
+
12
+ # bacon swallows errors alive
13
+ def err_explain
14
+ begin
15
+ yield
16
+ rescue => e
17
+ puts e.inspect
18
+ puts e.backtrace
19
+ raise e
20
+ end
21
+ end
22
+
23
+ module Rack
24
+ class FakeFlash < Rack::Flash::FlashHash
25
+ attr_reader :flagged, :sweeped, :store
26
+
27
+ def initialize(*args)
28
+ @flagged, @sweeped = false, false
29
+ @store = {}
30
+ super(@store)
31
+ end
32
+
33
+ def flag!
34
+ @flagged = true
35
+ super
36
+ end
37
+
38
+ def sweep!
39
+ @sweeped = true
40
+ super
41
+ end
42
+
43
+ def flagged?
44
+ @flagged
45
+ end
46
+
47
+ def swept?
48
+ @sweeped
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,157 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'Rack::Flash' do
4
+ include Rack::Test::Methods
5
+
6
+ def app(&block)
7
+ return Sinatra.new &block
8
+ end
9
+
10
+ before do
11
+ @fake_session = {}
12
+ end
13
+
14
+ def new_flash(entries={})
15
+ flash = Rack::Flash::FlashHash.new(@fake_session)
16
+ entries.each { |key,val| flash[key] = val }
17
+ flash
18
+ end
19
+
20
+ it 'stores entries' do
21
+ new_flash[:foo] = 'bar'
22
+ new_flash[:foo].should.equal('bar')
23
+ end
24
+
25
+ it 'accepts strings or hashes' do
26
+ new_flash[:foo] = 'bar'
27
+ new_flash['foo'].should.equal('bar')
28
+ end
29
+
30
+ it 'deletes entries from session after retrieval' do
31
+ new_flash[:foo] = 'bar'
32
+ new_flash[:foo]
33
+ new_flash[:foo].should.be.nil
34
+ end
35
+
36
+ it 'caches retrieved entries in instance' do
37
+ flash = new_flash(:foo => 'bar')
38
+ flash[:foo].should.equal('bar')
39
+ flash[:foo].should.equal('bar')
40
+ end
41
+
42
+ it 'does not step on session keys' do
43
+ @fake_session[:foo] = true
44
+ new_flash[:foo] = false
45
+ @fake_session[:foo].should.be.true
46
+ end
47
+
48
+ it 'can flag existing entries' do
49
+ flash = new_flash(:foo => 'bar', :fizz => 'buzz')
50
+ flash.flag!
51
+ flash.flagged.should.include(:foo)
52
+ flash.flagged.should.include(:fizz)
53
+ end
54
+
55
+ it 'can sweep flagged entries' do
56
+ err_explain do
57
+ flash = new_flash(:foo => 'bar', :fizz => 'buzz')
58
+ flash.flag!
59
+ flash.sweep!
60
+ flash.flagged.should.be.empty
61
+ new_flash[:foo].should.be.nil
62
+ new_flash[:fizz].should.be.nil
63
+ end
64
+ end
65
+
66
+ it 'allows setters with Flash.now semantics' do
67
+ flash = new_flash
68
+ flash.now[:foo] = 'bar'
69
+ flash[:foo].should.equal('bar')
70
+ new_flash[:foo].should.be.nil
71
+ end
72
+
73
+ it 'does not raise an error when session is cleared' do
74
+ flash = new_flash
75
+ flash[:foo] = 'bar'
76
+ @fake_session.clear
77
+ flash['foo'].should.equal(nil)
78
+ end
79
+
80
+ describe 'accessorize option' do
81
+ def new_flash(entries={})
82
+ flash = Rack::Flash::FlashHash.new(@fake_session, :accessorize => [:foo, :fizz])
83
+ entries.each { |key,val| flash[key] = val }
84
+ flash
85
+ end
86
+
87
+ it 'allows getters' do
88
+ flash = new_flash(:foo => 'bar')
89
+ flash.foo.should.equal('bar')
90
+ end
91
+
92
+ it 'allows setters' do
93
+ flash = new_flash
94
+ flash.fizz = 'buzz'
95
+ flash.fizz.should.equal('buzz')
96
+ end
97
+
98
+ it 'allows declarative setters' do
99
+ flash = new_flash
100
+ flash.fizz 'buzz'
101
+ flash.fizz.should.equal('buzz')
102
+ end
103
+
104
+ it 'allows setters with Flash.now semantics' do
105
+ flash = new_flash
106
+ flash.foo! 'bar'
107
+ flash.foo.should.equal('bar')
108
+ new_flash[:foo].should.be.nil
109
+ end
110
+
111
+ it 'only defines accessors for passed entry types' do
112
+ err_explain do
113
+ flash = new_flash
114
+ proc {
115
+ flash.bliggety = 'blam'
116
+ }.should.raise(NoMethodError)
117
+ end
118
+ end
119
+ end
120
+
121
+ it 'does not provide getters by default' do
122
+ proc {
123
+ new_flash(:foo => 'bar').foo
124
+ }.should.raise(NoMethodError)
125
+ end
126
+
127
+ it 'does not provide setters by default' do
128
+ proc {
129
+ flash = new_flash
130
+ flash.fizz = 'buzz'
131
+ }.should.raise(NoMethodError)
132
+ end
133
+
134
+ describe 'integration' do
135
+ it 'provides :sweep option to clear unused entries' do
136
+ app {
137
+ use Rack::Flash, :sweep => true
138
+
139
+ set :sessions, true
140
+
141
+ get '/' do
142
+ 'ok'
143
+ end
144
+ }
145
+
146
+ fake_flash = Rack::FakeFlash.new(:foo => 'bar')
147
+
148
+ get '/', :env=>{ 'x-rack.flash' => fake_flash }
149
+
150
+ fake_flash.should.be.flagged
151
+ fake_flash.should.be.swept
152
+ fake_flash.store[:foo].should.be.nil
153
+ end
154
+ end
155
+
156
+ # Testing sessions is a royal pain in the ass.
157
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-flash3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pat Nakajima
9
+ - Travis Reeder
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-03-19 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ requirement: &11215120 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *11215120
26
+ - !ruby/object:Gem::Dependency
27
+ name: rack
28
+ requirement: &11214480 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *11214480
37
+ description: Flash hash implementation for Rack apps.
38
+ email: treeder@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files:
42
+ - README.md
43
+ files:
44
+ - README.md
45
+ - Rakefile
46
+ - VERSION.yml
47
+ - example/base_app.ru
48
+ - example/sinatra_app.rb
49
+ - example/views/index.erb
50
+ - example/views/layout.erb
51
+ - example/views/show.erb
52
+ - lib/rack-flash.rb
53
+ - lib/rack/flash.rb
54
+ - lib/rack/flash/test.rb
55
+ - test/helper.rb
56
+ - test/test_flash.rb
57
+ homepage: http://www.iron.io
58
+ licenses: []
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '1.9'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 1.8.15
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Flash hash implementation for Rack apps.
81
+ test_files: []