Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
James Hunt & Paul Mucur authored and mudge committed Mar 31, 2012
0 parents commit c231f37
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.gem
2 changes: 2 additions & 0 deletions Gemfile
@@ -0,0 +1,2 @@
source 'https://rubygems.org'
gemspec
16 changes: 16 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,16 @@
PATH
remote: .
specs:
proffer (0.9.0)

GEM
remote: https://rubygems.org/
specs:
minitest (2.11.4)

PLATFORMS
ruby

DEPENDENCIES
minitest
proffer!
9 changes: 9 additions & 0 deletions LICENSE.txt
@@ -0,0 +1,9 @@
Copyright (c) 2012, James Hunt & Paul Mucur
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

29 changes: 29 additions & 0 deletions README.md
@@ -0,0 +1,29 @@
Proffer
=======

A module to stop Action Controller from copying every instance variable available
to an action to the view by default. Instead, use an explicit API to expose
variables as local variables within views.

Usage
-----

```ruby
class PostsController < ApplicationController
include Proffer

# This will make a new Post object available as post in the view but
# @heading will be nil.
def new
@heading = "New Post"
proffer :post => Post.new
end
end
```

```erb
<%= form_for(post) do |f| %>
...
<% end %>
```

10 changes: 10 additions & 0 deletions Rakefile
@@ -0,0 +1,10 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs << 'spec'
t.test_files = FileList['spec/*_spec.rb']
t.verbose = true
end

task :default => :test

54 changes: 54 additions & 0 deletions lib/proffer.rb
@@ -0,0 +1,54 @@
# Public: Stops an Action Controller from automatically passing all instance
# variables to the view. Instead, variables must be explicitly defined by
# using proffer.
#
# Examples
#
# class PostsController < ApplicationController
# include Proffer
#
# # This will make a new Post object available as post in the view but
# # @heading will be nil.
# def new
# @heading = "New Post"
# proffer :post => Post.new
# end
# end
module Proffer

# Public: Make the given values available to the view as local variables.
#
# variables - The Hash of values keyed by the local variable name to be used
# in the view.
#
# Examples
#
# proffer :model => Model.new
# # => render ..., :locals => { :model => Model.new }
#
# Returns nothing.
def proffer(variables)
@_proffered_variables ||= {}
@_proffered_variables.merge!(variables)
end

# Internal: Override Action Controller's render method to convert proffered
# variables to locals.
def render(*args)
if @_proffered_variables
options = args.extract_options!
options[:locals] ||= {}
options[:locals] = @_proffered_variables.merge(options[:locals])
args << options
end

super
end

# Internal: Override Action Controller's view_assigns to no longer copy
# instance variables into the view.
def view_assigns
{}
end
end

11 changes: 11 additions & 0 deletions proffer.gemspec
@@ -0,0 +1,11 @@
Gem::Specification.new do |s|
s.name = "proffer"
s.summary = "An Action Controller module to hide instance variables from views by default."
s.version = "0.9.0"
s.authors = ["James Hunt", "Paul Mucur"]
s.homepage = "http://github.com/hudge/proffer"
s.files = ["lib/proffer.rb", "Rakefile", "README.md", "LICENSE.txt"]
s.test_files = ["spec/spec_helper.rb", "spec/proffer_spec.rb"]
s.add_development_dependency("minitest")
end

61 changes: 61 additions & 0 deletions spec/proffer_spec.rb
@@ -0,0 +1,61 @@
require 'spec_helper'

class FakeController < BaseController
include Proffer

def index
proffer :foo => "bar", :baz => "quux"
render :index
end

def no_proffering
render :no_proffering
end

def proffering_with_locals(locals)
proffer :foo => "bar"
render :proffering, :locals => locals
end

def multiple_proffer
proffer :foo => "bar"
proffer :baz => "quux"
render :multiple_proffer
end
end

describe Proffer do
let(:controller) { FakeController.new }

it "sets view_assigns to an empty hash" do
controller.view_assigns.must_equal({})
end

describe "#proffer" do
it "assigns the proffered variables to the view as locals" do
controller.index
controller.args_for_render.must_equal([:index, { :locals => { :foo => "bar", :baz => "quux" } }])
end

it "doesn't add a locals option to the view if nothing is proffered" do
controller.no_proffering
controller.args_for_render.must_equal([:no_proffering])
end

it "doesn't override explicitly provided locals" do
controller.proffering_with_locals(:baz => "quux")
controller.args_for_render.must_equal([:proffering, :locals => { :baz => "quux", :foo => "bar" }])
end

it "prefers the explicit locals over the proffered variables if they have the same name" do
controller.proffering_with_locals(:foo => "new value")
controller.args_for_render.must_equal([:proffering, :locals => { :foo => "new value" }])
end

it "allows multiple calls to proffer" do
controller.multiple_proffer
controller.args_for_render.must_equal([:multiple_proffer, :locals => { :foo => "bar", :baz => "quux" }])
end
end
end

26 changes: 26 additions & 0 deletions spec/spec_helper.rb
@@ -0,0 +1,26 @@
require 'proffer'
require 'minitest/autorun'

# To avoid requiring Active Support during testing.
class Array
def extract_options!
if last.is_a?(Hash)
pop
else
{}
end
end
end

class BaseController
attr_reader :args_for_render

def render(*args)
@args_for_render = args
end

def view_assigns
{:stuff => :not_needed}
end
end

0 comments on commit c231f37

Please sign in to comment.