Skip to content
This repository has been archived by the owner on Jul 18, 2023. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Apr 20, 2012
0 parents commit 1bc322b
Show file tree
Hide file tree
Showing 17 changed files with 493 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .gitignore
@@ -0,0 +1,17 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in rails-bare.gemspec
gemspec
22 changes: 22 additions & 0 deletions LICENSE
@@ -0,0 +1,22 @@
Copyright (c) 2012 Santiago Pastorino and Carlos Antonio da Silva

MIT License

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.
29 changes: 29 additions & 0 deletions README.md
@@ -0,0 +1,29 @@
# Rails::Bare

TODO: Write a gem description

## Installation

Add this line to your application's Gemfile:

gem 'rails-bare'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-bare

## Usage

TODO: Write usage instructions here

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
10 changes: 10 additions & 0 deletions Rakefile
@@ -0,0 +1,10 @@
require 'rake/testtask'

Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end

task :default => [:test]
153 changes: 153 additions & 0 deletions lib/action_controller/bare.rb
@@ -0,0 +1,153 @@
require 'action_controller/log_subscriber'
require 'action_controller'

module ActionController
# Bare Controller is a lightweight version of <tt>ActionController::Base</tt>,
# created for applications that don't require all functionality that a complete
# \Rails controller provides, allowing you to create faster controllers. The
# main scenario where Bare Controllers could be used is API only applications.
#
# An Bare Controller is different from a normal controller in the sense that
# by default it doesn't include a number of features that are usually required
# by browser access only: layouts and templates rendering, cookies, sessions,
# flash, assets, and so on. This makes the entire controller stack thinner and
# faster, suitable for API applications. It doesn't mean you won't have such
# features if you need them: they're all available for you to include in
# your application, they're just not part of the default Bare Controller stack.
#
# By default, only the ApplicationController in a \Rails application inherits
# from <tt>ActionController::Bare</tt>. All other controllers in turn inherit
# from ApplicationController.
#
# A sample controller could look like this:
#
# class PostsController < ApplicationController
# def index
# @posts = Post.all
# render json: @posts
# end
# end
#
# Request, response and parameters objects all work the exact same way as
# <tt>ActionController::Base</tt>.
#
# == Renders
#
# The default Bare Controller stack includes all renderers, which means you
# can use <tt>render :json</tt> and brothers freely in your controllers. Keep
# in mind that templates are not going to be rendered, so you need to ensure
# your controller is calling either <tt>render</tt> or <tt>redirect</tt> in
# all actions.
#
# def show
# @post = Post.find(params[:id])
# render json: @post
# end
#
# == Redirects
#
# Redirects are used to move from one action to another. You can use the
# <tt>redirect</tt> method in your controllers in the same way as
# <tt>ActionController::Base</tt>. For example:
#
# def create
# redirect_to root_url and return if not_authorized?
# # do stuff here
# end
#
# == Adding new behavior
#
# In some scenarios you may want to add back some functionality provided by
# <tt>ActionController::Base</tt> that is not present by default in
# <tt>ActionController::Bare</tt>, for instance <tt>MimeResponds</tt>. This
# module gives you the <tt>respond_to</tt> and <tt>respond_with</tt> methods.
# Adding it is quite simple, you just need to include the module in a specific
# controller or in <tt>ApplicationController</tt> in case you want it
# available to your entire app:
#
# class ApplicationController < ActionController::Bare
# include ActionController::MimeResponds
# end
#
# class PostsController < ApplicationController
# respond_to :json, :xml
#
# def index
# @posts = Post.all
# respond_with @posts
# end
# end
#
# Quite straightforward. Make sure to check <tt>ActionController::Base</tt>
# available modules if you want to include any other functionality that is
# not provided by <tt>ActionController::Bare</tt> out of the box.
class Bare < Metal
abstract!

module Compabitility
def cache_store; end
def cache_store=(*); end
def assets_dir=(*); end
def javascripts_dir=(*); end
def stylesheets_dir=(*); end
def page_cache_directory=(*); end
def asset_path=(*); end
def asset_host=(*); end
def relative_url_root=(*); end
def perform_caching=(*); end
def wrap_parameters(*); end
def helpers_path=(*); end
def allow_forgery_protection=(*); end
end

extend Compabitility

# Shortcut helper that returns all the ActionController::Bare modules except the ones passed in the argument:
#
# class MetalController
# ActionController::Bare.without_modules(:Redirecting, :DataStreaming).each do |left|
# include left
# end
# end
#
# This gives better control over what you want to exclude and makes it easier
# to create a bare controller class, instead of listing the modules required manually.
def self.without_modules(*modules)
modules = modules.map do |m|
m.is_a?(Symbol) ? ActionController.const_get(m) : m
end

MODULES - modules
end

MODULES = [
HideActions,
UrlFor,
Redirecting,
Rendering,
Renderers::All,
ConditionalGet,
RackDelegation,

ForceSSL,
DataStreaming,

# Before callbacks should also be executed the earliest as possible, so
# also include them at the bottom.
AbstractController::Callbacks,

# Append rescue at the bottom to wrap as much as possible.
Rescue,

# Add instrumentations hooks at the bottom, to ensure they instrument
# all the methods properly.
Instrumentation
]

MODULES.each do |mod|
include mod
end

ActiveSupport.run_load_hooks(:action_controller, self)
end
end
2 changes: 2 additions & 0 deletions lib/rails-bare.rb
@@ -0,0 +1,2 @@
require "rails-bare/version"
require "action_controller/bare"
5 changes: 5 additions & 0 deletions lib/rails-bare/version.rb
@@ -0,0 +1,5 @@
module Rails
module Bare
VERSION = "0.0.0"
end
end
26 changes: 26 additions & 0 deletions rails-bare.gemspec
@@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path('../lib', __FILE__)
require 'rails-bare/version'

Gem::Specification.new do |gem|
gem.name = "rails-bare"
gem.version = Rails::Bare::VERSION
gem.platform = Gem::Platform::RUBY
gem.summary = %q{Bare Applications}
gem.description = %q{Bare Applications}
gem.licenses = ['MIT']

gem.authors = ["Santiago Pastorino and Carlos Antonio da Silva"]
gem.email = ["<santiago@wyeworks.com>", "<carlosantoniodasilva@gmail.com>"]
gem.homepage = "https://github.com/spastorino/rails-bare"

gem.required_rubygems_version = '>= 1.3.6'

gem.files = Dir['README.md', 'lib/**/*', 'test/**/*']
gem.test_files = Dir['test/**/*']
gem.require_paths = ["lib"]

gem.add_runtime_dependency 'actionpack', '>= 3.2.0'

gem.add_development_dependency 'activesupport', '>= 3.2.0'
end
17 changes: 17 additions & 0 deletions test/bare_controller/action_methods_test.rb
@@ -0,0 +1,17 @@
require 'test_helper'

class ActionMethodsBareController < ActionController::Bare
def one; end
def two; end
hide_action :two
end

class ActionMethodsBareTest < ActionController::TestCase
tests ActionMethodsBareController

def test_action_methods
assert_equal Set.new(%w(one)),
@controller.class.action_methods,
"#{@controller.controller_path} should not be empty!"
end
end
57 changes: 57 additions & 0 deletions test/bare_controller/conditional_get_test.rb
@@ -0,0 +1,57 @@
require 'test_helper'
require 'active_support/core_ext/integer/time'
require 'active_support/core_ext/numeric/time'

class ConditionalGetBareController < ActionController::Bare
before_filter :handle_last_modified_and_etags, :only => :two

def one
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123])
render :text => "Hi!"
end
end

def two
render :text => "Hi!"
end

private

def handle_last_modified_and_etags
fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ])
end
end

class ConditionalGetBareTest < ActionController::TestCase
tests ConditionalGetBareController

def setup
@last_modified = Time.now.utc.beginning_of_day.httpdate
end

def test_request_with_bang_gets_last_modified
get :two
assert_equal @last_modified, @response.headers['Last-Modified']
assert_response :success
end

def test_request_with_bang_obeys_last_modified
@request.if_modified_since = @last_modified
get :two
assert_response :not_modified
end

def test_last_modified_works_with_less_than_too
@request.if_modified_since = 5.years.ago.httpdate
get :two
assert_response :success
end

def test_request_not_modified
@request.if_modified_since = @last_modified
get :one
assert_equal 304, @response.status.to_i
assert_blank @response.body
assert_equal @last_modified, @response.headers['Last-Modified']
end
end
27 changes: 27 additions & 0 deletions test/bare_controller/data_streaming_test.rb
@@ -0,0 +1,27 @@
require 'test_helper'

module TestBareFileUtils
def file_name() File.basename(__FILE__) end
def file_path() File.expand_path(__FILE__) end
def file_data() @data ||= File.open(file_path, 'rb') { |f| f.read } end
end

class DataStreamingBareController < ActionController::Bare
include TestBareFileUtils

def one; end
def two
send_data(file_data, {})
end
end

class DataStreamingBareTest < ActionController::TestCase
include TestBareFileUtils
tests DataStreamingBareController

def test_data
response = process('two')
assert_kind_of String, response.body
assert_equal file_data, response.body
end
end

0 comments on commit 1bc322b

Please sign in to comment.