Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial Entry

  • Loading branch information...
commit 555ddba9208e54085a3a1a62a6629abf1035326c 0 parents
Benjamin Bloch authored
6 .gitignore
@@ -0,0 +1,6 @@
+*.gem
+archive/*
+doc/*
+.yardoc
+.bundle
+Gemfile.lock
2  .rspec
@@ -0,0 +1,2 @@
+--format documentation
+--color
9 .yardopts
@@ -0,0 +1,9 @@
+--no-save
+--no-private
+--title Padrino Flash
+--markup-provider redcarpet
+--markup markdown
+lib/**/*.rb
+-
+README.md
+LICENSE
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Benjamin Bloch
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
28 README.md
@@ -0,0 +1,28 @@
+### Overview
+
+Padrino Flash is a plugin for the [Padrino](https://github.com/padrino/padrino-framework) web framework which adds support for [Rails](https://github.com/rails/rails) like flash messages.
+
+### Setup & Installation
+
+Include it in your project's `Gemfile` with Bundler:
+
+``` ruby
+gem 'padrino-flash'
+```
+
+Modify your `app/app.rb` file to register the plugin:
+
+``` ruby
+class ExampleApplication < Padrino::Application
+ register Padrino::Flash
+end
+```
+
+### Dependencies
+
+* [Padrino-Core](https://github.com/padrino/padrino-framework) and [Padrino-Helpers](https://github.com/padrino/padrino-framework)
+* [Ruby](http://www.ruby-lang.org/en) >= 1.9.2
+
+### Copyright
+
+Copyright © 2012 Benjamin Bloch (Cirex). See LICENSE for details.
30 Rakefile
@@ -0,0 +1,30 @@
+$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
+require 'padrino-flash/version'
+
+require 'rake'
+require 'yard'
+require 'rspec'
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new do |task|
+ task.pattern = 'spec/**/*_spec.rb'
+end
+
+YARD::Rake::YardocTask.new
+
+task :build do
+ `gem build padrino-flash.gemspec`
+end
+
+task :install => :build do
+ `gem install padrino-flash-#{Padrino::Flash::VERSION}.gem`
+end
+
+desc 'Releases the current version into the wild'
+task :release => :build do
+ `git tag -a v#{Padrino::Flash::VERSION} -m "Version #{Padrino::Flash::VERSION}"`
+ `gem push padrino-flash-#{Padrino::Flash::VERSION}.gem`
+ `git push --tags`
+end
+
+task :default => :spec
22 lib/padrino-flash.rb
@@ -0,0 +1,22 @@
+# encoding: utf-8
+require 'padrino-core'
+require 'padrino-helpers'
+
+FileSet.glob_require('padrino-flash/**/*.rb', __FILE__)
+
+module Padrino
+ module Flash
+ class << self
+ # @private
+ def registered(app)
+ app.helpers Helpers
+ app.enable :sessions
+ app.enable :flash
+
+ app.after do
+ session[:_flash] = @_flash.next if @_flash && app.flash?
+ end
+ end
+ end # self
+ end # Flash
+end # Padrino
102 lib/padrino-flash/helpers.rb
@@ -0,0 +1,102 @@
+# encoding: UTF-8
+module Padrino
+ module Flash
+ module Helpers
+ ###
+ # Overloads the existing redirect helper in-order to provide support for flash messages
+ #
+ # @overload redirect(url)
+ # @param [String] url
+ #
+ # @overload redirect(url, status_code)
+ # @param [String] url
+ # @param [Fixnum] status_code
+ #
+ # @overload redirect(url, status_code, flash_messages)
+ # @param [String] url
+ # @param [Fixnum] status_code
+ # @param [Hash] flash_messages
+ #
+ # @overload redirect(url, flash_messages)
+ # @param [String] url
+ # @param [Hash] flash_messages
+ #
+ # @example
+ # redirect(dashboard, :success => :user_created)
+ # redirect(new_location, 301, notice: 'This page has moved. Please update your bookmarks!!')
+ #
+ # @since 0.1.0
+ # @api public
+ def redirect(url, *args)
+ flashes = args.extract_options!
+
+ flashes.each do |type, message|
+ message = I18n.translate(message) if message.is_a?(Symbol)
+ flash[type] = message
+ end
+
+ super(url, args)
+ end
+ alias_method :redirect_to, :redirect
+
+ ###
+ # Returns HTML tags to display the current flash messages
+ #
+ # @return [String]
+ # Generated HTML for flash messages
+ #
+ # @example
+ # flash_messages
+ # # => <div id="flash">
+ # # => <span class="warning" title="Warning">Danger, Will Robinson!</span>
+ # # => </div>
+ #
+ # @since 0.1.0
+ # @api public
+ def flash_messages
+ flashes = flash.collect do |type, message|
+ content_tag(:span, message, title: type.to_s.titleize, class: type)
+ end.join("\n")
+
+ # Create the tag even if we don't need it so it can be dynamically altered
+ content_tag(:div, flashes, id: 'flash')
+ end
+
+ ###
+ # Returns an HTML div to display the specified flash if it exists
+ #
+ # @return [String]
+ # Generated HTML for the specified flash message
+ #
+ # @example
+ # flash_message :error
+ # # => <div id="flash-error" title="Error" class="error">
+ # # => Invalid Handle/Password Combination
+ # # => </div>
+ #
+ # flash_message :success
+ # # => <div id="flash-success" title="Success" class="success">
+ # # => Your account has been successfully registered!
+ # # => </div>
+ #
+ # @since 0.1.0
+ # @api public
+ def flash_message(type)
+ if flash[type]
+ content_tag(:div, flash[type], id: "flash-#{type}", title: type.to_s.titleize, class: type)
+ end
+ end
+
+ ###
+ # Returns the flash storage object
+ #
+ # @return [Storage]
+ #
+ # @since 0.1.0
+ # @api public
+ def flash
+ @_flash ||= Storage.new(session[:_flash])
+ end
+ end # Helpers
+ end # Flash
+end # Padrino
157 lib/padrino-flash/storage.rb
@@ -0,0 +1,157 @@
+# encoding: UTF-8
+module Padrino
+ module Flash
+ class Storage
+ include Enumerable
+
+ attr_reader :now
+ attr_reader :next
+
+ # @private
+ def initialize(session)
+ @now = session || {}
+ @next = {}
+ end
+
+ # @since 0.1.0
+ # @api public
+ def [](type)
+ @now[type]
+ end
+
+ # @since 0.1.0
+ # @api public
+ def []=(type, message)
+ @next[type] = message
+ end
+
+ # @since 0.1.0
+ # @api public
+ def delete(type)
+ @now.delete(type)
+ self
+ end
+
+ # @since 0.1.0
+ # @api public
+ def keys
+ @now.keys
+ end
+
+ # @since 0.1.0
+ # @api public
+ def key?(type)
+ @now.key?(type)
+ end
+
+ # @since 0.1.0
+ # @api public
+ def each(&block)
+ @now.each(&block)
+ end
+
+ # @since 0.1.0
+ # @api public
+ def replace(hash)
+ @now.replace(hash)
+ self
+ end
+
+ # @since 0.1.0
+ # @api public
+ def update(hash)
+ @now.update(hash)
+ self
+ end
+ alias_method :merge!, :update
+
+ # @since 0.1.0
+ # @api public
+ def sweep
+ @now.replace(@next)
+ @next = {}
+ self
+ end
+
+ # @since 0.1.0
+ # @api public
+ def keep(key = nil)
+ if key
+ @next[key] = @now[key]
+ else
+ @next.merge!(@now)
+ end
+ end
+
+ # @since 0.1.0
+ # @api public
+ def discard(key = nil)
+ if key
+ @next.delete(key)
+ else
+ @next = {}
+ end
+ end
+
+ # @since 0.1.0
+ # @api public
+ def clear
+ @now.clear
+ end
+
+ # @since 0.1.0
+ # @api public
+ def empty?
+ @now.empty?
+ end
+
+ # @since 0.1.0
+ # @api public
+ def to_hash
+ @now.dup
+ end
+
+ # @since 0.1.0
+ # @api public
+ def to_s
+ @now.to_s
+ end
+
+ # @since 0.1.0
+ # @api public
+ def error=(message)
+ self[:error] = message
+ end
+
+ # @since 0.1.0
+ # @api public
+ def error
+ self[:error]
+ end
+
+ # @since 0.1.0
+ # @api public
+ def notice=(message)
+ self[:notice] = message
+ end
+
+ # @since 0.1.0
+ # @api public
+ def notice
+ self[:notice]
+ end
+
+ # @since 0.1.0
+ # @api public
+ def success=(message)
+ self[:success] = message
+ end
+
+ # @since 0.1.0
+ # @api public
+ def success
+ self[:success]
+ end
+ end # Storage
+ end # Flash
+end # Padrino
6 lib/padrino-flash/version.rb
@@ -0,0 +1,6 @@
+# encoding: UTF-8
+module Padrino
+ module Flash
+ VERSION = '0.1.0'
+ end # Flash
+end # Padrino
25 padrino-flash.gemspec
@@ -0,0 +1,25 @@
+# encoding: utf-8
+$:.push File.expand_path('../lib', __FILE__)
+require 'padrino-flash/version'
+
+Gem::Specification.new do |s|
+ s.name = 'padrino-flash'
+ s.version = Padrino::Flash::VERSION
+ s.authors = ['Benjamin Bloch']
+ s.email = ['cirex@gamesol.org']
+ s.homepage = 'https://github.com/Cirex/padrino-flash'
+ s.description = 'A plugin for the Padrino web framework which adds support for Rails like flash messages'
+ s.summary = s.description
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ['lib']
+
+ s.add_dependency 'padrino-core'
+ s.add_dependency 'padrino-helpers'
+
+ s.add_development_dependency 'rspec', '>= 2.0.0'
+ s.add_development_dependency 'rspec-html-matchers'
+ s.add_development_dependency 'rack-test'
+end
2  spec/fixtures/locale/en.yml
@@ -0,0 +1,2 @@
+en:
+ redirected: 'Redirected'
15 spec/flash_spec.rb
@@ -0,0 +1,15 @@
+require_relative 'spec'
+
+describe Padrino::Flash do
+ it 'can set the future flash' do
+ post '/flash', { notice: 'Flash' }
+ post '/flash', { success: 'Flash' }
+ last_response.body.should == '{:notice=>"Flash"}'
+ end
+
+ it 'knows the future flash' do
+ post '/flash', { notice: 'Flash' }
+ get '/flash'
+ last_response.body.should == '{:notice=>"Flash"}'
+ end
+end
72 spec/helpers_spec.rb
@@ -0,0 +1,72 @@
+require_relative 'spec'
+
+describe Padrino::Flash::Helpers do
+ include Padrino::Helpers::OutputHelpers
+ include Padrino::Helpers::TagHelpers
+ include Padrino::Flash::Helpers
+
+ context '#redirect' do
+ it 'should let you to use a string to set a flash message' do
+ app.get(:redirect) { redirect('/flash', notice: 'Redirected') }
+ get '/redirect'
+ follow_redirect!
+ last_response.body.should == '{:notice=>"Redirected"}'
+ end
+
+ it 'should localize flash message when a :symbol is used' do
+ app.get(:redirect) { redirect('/flash', :notice => :redirected) }
+ get '/redirect'
+ follow_redirect!
+ last_response.body.should == '{:notice=>"Redirected"}'
+ end
+
+ it 'should allow you to set multiple flash messages' do
+ app.get(:redirect) { redirect('/flash', notice: 'Redirected', success: 'Redirected') }
+ get '/redirect'
+ follow_redirect!
+ last_response.body.should == '{:notice=>"Redirected", :success=>"Redirected"}'
+ end
+
+ it 'should allow you to set the status code' do
+ app.get(:redirect) { redirect('/flash', 301) }
+ get '/redirect'
+ last_response.status.should == 301
+ end
+
+ it 'should allow you to set the status code with flash messages' do
+ app.get(:redirect) { redirect('/flash', 301, notice: 'Redirected') }
+ get '/redirect'
+ last_response.status.should == 301
+ follow_redirect!
+ last_response.body.should == '{:notice=>"Redirected"}'
+ end
+ end
+
+ context '#flash_message' do
+ it 'should return the contents of the specified flash' do
+ flash = flash_message(:success)
+ flash.should have_tag(:div, count: 1, with: { id: 'flash-success', class: 'success', title: 'Success' })
+ end
+
+ it 'should return nil when the specified flash is not set' do
+ flash = flash_message(:error)
+ flash.should be_nil
+ end
+ end
+
+ context '#flash_messages' do
+ it 'should return the contents of all flashes' do
+ flashes = flash_messages
+ flashes.should have_tag(:div, count: 1, with: { id: 'flash' }) do
+ with_tag(:span, text: 'Flash Success', with: { class: 'success', title: 'Success' })
+ with_tag(:span, text: 'Flash Notice', with: { class: 'notice', title: 'Notice' })
+ end
+ end
+
+ it 'should return an empty div when no flash messages set' do
+ session.clear
+ flashes = flash_messages
+ flashes.should have_tag(:div, count: 1, with: { id: 'flash' })
+ end
+ end
+end
35 spec/spec.rb
@@ -0,0 +1,35 @@
+PADRINO_ENV = 'test'
+
+require 'rspec'
+require 'rspec-html-matchers'
+require 'rack/test'
+require 'padrino-flash'
+
+module TestHelpers
+ def app
+ @app ||= Sinatra.new(Padrino::Application) do
+ register Padrino::Flash
+ set :logging, false
+
+ get :flash do
+ flash.inspect
+ end
+
+ post :flash do
+ params.each { |type, message| flash[type.to_sym] = message }
+ flash.inspect
+ end
+ end
+ end
+
+ def session
+ @session ||= { _flash: { notice: 'Flash Notice', success: 'Flash Success' }}
+ end
+end
+
+RSpec.configure do |configuration|
+ configuration.include TestHelpers
+ configuration.include Rack::Test::Methods
+end
+
+I18n.load_path += Dir[(File.dirname(__FILE__) + '/fixtures/locale/*.yml')]
104 spec/storage_spec.rb
@@ -0,0 +1,104 @@
+require_relative 'spec'
+
+describe Padrino::Flash::Storage do
+ let :flash do
+ Padrino::Flash::Storage.new(session[:_flash])
+ end
+
+ before do
+ flash[:one] = 'One'
+ flash[:two] = 'Two'
+ end
+
+ it 'can delete a single flash' do
+ flash[:notice].should == 'Flash Notice'
+ flash.delete :notice
+ flash.key?(:notice).should be_false
+ flash[:notice].should be_nil
+ end
+
+ it 'can delete the entire flash' do
+ flash[:notice].should == 'Flash Notice'
+ flash[:success].should == 'Flash Success'
+ flash.clear
+ flash[:notice].should be_nil
+ flash[:success].should be_nil
+ end
+
+ it 'should set future flash messages' do
+ flash[:future] = 'Test'
+ flash[:future].should be_nil
+ end
+
+ it 'should allow you to set the present flash' do
+ flash.now[:present] = 'Test'
+ flash[:present].should == 'Test'
+ end
+
+ it 'can discard the entire flash' do
+ flash.discard
+ flash.sweep
+ flash[:one].should_not == 'One'
+ flash[:two].should_not == 'Two'
+ end
+
+ it 'can discard a single flash' do
+ flash.discard :one
+ flash.sweep
+ flash[:one].should_not == 'One'
+ flash[:two].should == 'Two'
+ end
+
+ it 'can keep the entire flash' do
+ flash.keep
+ flash.sweep
+ flash[:notice].should == 'Flash Notice'
+ end
+
+ it 'can keep a single flash' do
+ flash.keep :notice
+ flash.sweep
+ flash[:notice].should == 'Flash Notice'
+ flash[:success].should_not == 'Flash Success'
+ end
+
+ it 'can iterate through flash messages' do
+ flashes = []
+ flash.each do |type, message|
+ flashes << [type, message]
+ end
+ flashes[0].should == [:notice, 'Flash Notice']
+ flashes[1].should == [:success, 'Flash Success']
+ end
+
+ it 'can sweep up the old to make room for the new' do
+ flash[:notice].should == 'Flash Notice'
+ flash[:one].should be_nil
+ flash.sweep
+ flash[:notice].should be_nil
+ flash[:one].should == 'One'
+ end
+
+ it 'can replace the current flash messages' do
+ flash[:notice].should == 'Flash Notice'
+ flash.replace(:error => 'Replaced')
+ flash[:notice].should be_nil
+ flash[:error].should == 'Replaced'
+ end
+
+ it 'can return the existing flash keys' do
+ flash.keys.should == [:notice, :success]
+ flash.keys.should_not include(:one, :two)
+ end
+
+ it 'can tell you if a key is set' do
+ flash.key?(:notice).should be_true
+ flash.key?(:one).should be_false
+ end
+
+ it 'can merge flash messages' do
+ flash[:notice].should == 'Flash Notice'
+ flash.update(:notice => 'Flash Success')
+ flash[:notice].should == 'Flash Success'
+ end
+end

0 comments on commit 555ddba

Please sign in to comment.
Something went wrong with that request. Please try again.