mirror of
https://github.com/TracksApp/tracks.git
synced 2026-03-08 05:32:37 +01:00
Install the `skinny_spec' plugin.
It's basically a set of rspec macro allowing you to write thing such as `it_should_find_and_assign :users'. See <http://github.com/rsl/skinny_spec/tree/master> for more informations. It's recommended to install the `ruby2ruby' gem to have nicer error messages, but it is not required to work. @@ update README_FOR_DEVELOPERS accordingly.
This commit is contained in:
parent
60b986a5b9
commit
0376067cf4
33 changed files with 2531 additions and 0 deletions
2
vendor/plugins/skinny_spec/.gitignore
vendored
Normal file
2
vendor/plugins/skinny_spec/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.DS_Store
|
||||
doc
|
||||
267
vendor/plugins/skinny_spec/README.rdoc
vendored
Normal file
267
vendor/plugins/skinny_spec/README.rdoc
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
= Skinny Spec
|
||||
|
||||
Skinny Spec is a collection of spec helper methods designed to help trim the fat and DRY up
|
||||
some of the bloat that sometimes results from properly specing your classes and templates.
|
||||
|
||||
== Requirements and Recommendations
|
||||
|
||||
Obviously you'll need to be using RSpec[http://github.com/dchelimsky/rspec/tree/master] and
|
||||
Rspec-Rails[http://github.com/dchelimsky/rspec-rails/tree/master] as your testing framework.
|
||||
|
||||
Skinny Spec was originally designed [and best enjoyed] if you're using
|
||||
Haml[http://github.com/nex3/haml/tree/master] and
|
||||
make_resourceful[http://github.com/rsl/make_resourceful/tree/master] but will default to
|
||||
ERb and a facsimile of Rails' default scaffolding [for the views and controllers, respectively]
|
||||
if Haml and/or make_resourceful are not available. I recommend using them though. :)
|
||||
|
||||
In addition, Skinny Spec uses Ruby2Ruby to make nicer expectation messages and you'll want to
|
||||
have that installed as well. It's not a dependency or anything but it <i>is</i> highly
|
||||
recommended.
|
||||
|
||||
== Setup
|
||||
|
||||
Once you've installed the plugin in your app's vendor/plugins folder, you're ready to rock!
|
||||
Skinny Spec includes itself into the proper RSpec classes so there's no configuration on your
|
||||
part. Sweet!
|
||||
|
||||
== Usage
|
||||
|
||||
The simplest way to use Skinny Specs is to generate a resource scaffold:
|
||||
|
||||
script/generate skinny_scaffold User
|
||||
|
||||
This command takes the usual complement of attribute definitions like
|
||||
<tt>script/generate scaffold</tt>. Then have a look at the generated files (particularly the
|
||||
specs) to see what's new and different with Skinny Spec.
|
||||
|
||||
=== Controller Specs
|
||||
|
||||
Let's look at the controller specs.
|
||||
|
||||
describe UsersController do
|
||||
def valid_attributes(args = {})
|
||||
{
|
||||
# Add valid attributes for the your params[:user] here!
|
||||
}.merge(args)
|
||||
end
|
||||
|
||||
describe "GET :index" do
|
||||
before(:each) do
|
||||
@users = stub_index(User)
|
||||
end
|
||||
|
||||
it_should_find_and_assign :users
|
||||
it_should_render :template, "index"
|
||||
end
|
||||
|
||||
# ...
|
||||
|
||||
describe "POST :create" do
|
||||
describe "when successful" do
|
||||
before(:each) do
|
||||
@user = stub_create(User)
|
||||
end
|
||||
|
||||
it_should_initialize_and_save :user
|
||||
it_should_redirect_to { user_url(@user) }
|
||||
end
|
||||
|
||||
# ...
|
||||
|
||||
First thing you should see is a method definition for
|
||||
<tt>valid_attributes</tt>. This will be used later by the <tt>create</tt> and <tt>update</tt>
|
||||
specs to more accurately represent how the controller works in actual practice by supplying
|
||||
somewhat real data for the <tt>params</tt> coming from the HTML forms.
|
||||
|
||||
Next we find an example group for <tt>GET :index</tt>. That <tt>stub_index</tt> method there
|
||||
does a lot of work behind the curtain. I'll leave it up to you to check the documentation for it
|
||||
(and its brothers and sister methods like <tt>stub_new</tt>) but I will point out that the
|
||||
methods named <tt>stub_<i>controller_method</i></tt> should only be used for stubbing and
|
||||
mocking the main object of the method. To create mocks for other ancillary objects, please
|
||||
use <tt>stub_find_all</tt>, <tt>stub_find_one</tt>, and <tt>stub_initialize</tt>. The reason
|
||||
for this is because the former methods actually save us a step by defining an implicit
|
||||
controller method request. If you add a new method to your resource routing, you'll want to
|
||||
use the helper method <tt>define_request</tt> in those example groups to define an explicit
|
||||
request. You can also define a method called <tt>shared_request</tt> to "share a
|
||||
<tt>define_request</tt>" across shared describe blocks, like so:
|
||||
|
||||
describe "POST :create" do
|
||||
def shared_request
|
||||
post :create
|
||||
end
|
||||
|
||||
describe "when successful" do
|
||||
# ...
|
||||
end
|
||||
|
||||
describe "when unsuccessful" do
|
||||
# ...
|
||||
end
|
||||
end
|
||||
|
||||
Note: When you're adding longer, more complicated controller specs you can still leverage
|
||||
implicit and shared requests by calling <tt>do_request</tt> in your spec as in the following
|
||||
example:
|
||||
|
||||
# Let's assume this controller is _not_ CategoriesController
|
||||
# and that loading the categories isn't part of the default actions
|
||||
describe "GET :index" do
|
||||
before(:each) do
|
||||
@categories = stub_find_all(Category)
|
||||
end
|
||||
|
||||
it "should preload categories" do
|
||||
Category.should_receive(:find).with(:all)
|
||||
do_request
|
||||
end
|
||||
|
||||
it "should assign @categories" do
|
||||
do_request
|
||||
assigns[:categories].should == @categories
|
||||
end
|
||||
end
|
||||
|
||||
Finally we get to the meat of the spec and of Skinny Specs itself: the actual expectations.
|
||||
The first thing you'll notice is the use of example group (read: "describe" block) level methods
|
||||
instead of the usual example (read: "it") blocks. Using this helper at the example group level
|
||||
saves us three lines over using an example block. (If this isn't significant to you, this is
|
||||
probably the wrong plugin for you as well. Sorry.) Note that none of these methods use the
|
||||
instance variables defined in the "before" block because they are all nil at the example block
|
||||
level. Let's look at a sample method to see how it works:
|
||||
|
||||
it_should_find_and_assign :users
|
||||
|
||||
This actually wraps two different expectations: one that <tt>User.should_receive(:find).with(:all)</tt>
|
||||
and another that the instance variable <tt>@users</tt> is assigned with the return value from that finder call.
|
||||
If you need to add more detailed arguments to the find, you can easily break this into two different
|
||||
expectations like:
|
||||
|
||||
it_should_find :users, :limit => 2
|
||||
it_should_assign :users
|
||||
|
||||
See the documentation for the <tt>it_should_find</tt> for more information. You might have guessed that
|
||||
<tt>it_should_initialize_assign</tt> and <tt>it_should_render_template</tt> work in a similar
|
||||
fashion and you'd be right. Again, see the documentation for these individual methods for more
|
||||
information. Lots of information in those docs.
|
||||
|
||||
A useful helper method that doesn't appear in any of the scaffolding is <tt>with_default_restful_actions</tt>
|
||||
which takes a block and evaluates it for each of the RESTful controller actions. Very useful for
|
||||
spec'ing that these methods redirect to the login page when the user isn't logged in, for example. This
|
||||
method is designed to be used inside an example like so:
|
||||
|
||||
describe "when not logged in" do
|
||||
it "should redirect all requests to the login page" do
|
||||
with_default_restful_actions do
|
||||
response.should redirect_to(login_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Before we're through with the controller specs, let me point out one more important detail. In
|
||||
order to use <tt>it_should_redirect_to</tt> we have to send the routing inside a block argument
|
||||
there so it can be evaluated in the example context instead of the example group, where it
|
||||
completely blows up. This methodology is used anywhere routing is referred to in a "skinny",
|
||||
example group level spec.
|
||||
|
||||
=== View Specs
|
||||
|
||||
Now let's move to the view specs!
|
||||
|
||||
describe "/users/form.html.haml" do
|
||||
before(:each) do
|
||||
@user = mock_and_assign(User, :stub => {
|
||||
:name => "foo",
|
||||
:birthday => 1.week.ago,
|
||||
:adult => false
|
||||
})
|
||||
end
|
||||
|
||||
it_should_have_form_for :user
|
||||
|
||||
it_should_allow_editing :user, :name
|
||||
it_should_allow_editing :user, :birthday
|
||||
it_should_allow_editing :user, :adult
|
||||
|
||||
it_should_link_to_show :user
|
||||
it_should_link_to { users_path }
|
||||
end
|
||||
|
||||
Like the special <tt>stub_index</tt> methods in the controller
|
||||
specs, the view specs have a shorthand mock and stub helpers: <tt>mock_and_assign</tt> and
|
||||
<tt>mock_and_assign_collection</tt>. These are well documented so please check them out.
|
||||
|
||||
There are also some really nice helper methods that I'd like point out. First is
|
||||
<tt>it_should_have_form_for</tt>. This is a really good convenience wrapper that basically wraps
|
||||
the much longer:
|
||||
|
||||
it "should use form_for to generate the proper form action and options" do
|
||||
template.should_receive(:form_for).with(@user)
|
||||
do_render
|
||||
end
|
||||
|
||||
Next up is the <tt>it_should_allow_editing</tt> helper. I love this method the most because it
|
||||
really helps DRY up that view spec while at the same time being amazingly unbrittle. Instead of
|
||||
creating an expectation for a specific form element, this method creates a generalized expectation
|
||||
that there's a form element with the <tt>name</tt> attribute set in such away that it will
|
||||
generate the proper <tt>params</tt> to use in the controller to edit or create the instance.
|
||||
Check out the docs and the source for more information on this. Also check out
|
||||
<tt>it_should_have_form_element_for</tt> which is roughly equivalent for those times when you use
|
||||
<tt>form_tag</tt> instead.
|
||||
|
||||
Finally let's look at those <tt>it_should_link_to_<i>controller_method</i></tt> helpers.
|
||||
These methods (and there's one each for the controller methods
|
||||
<tt>new</tt>, <tt>edit</tt>, <tt>show</tt>, and <tt>delete</tt>) point to instance variables
|
||||
which you should be created in the "before" blocks with <tt>mock_and_assign</tt>. The other is
|
||||
<tt>it_should_allow_editing</tt> which is likewise covered extensively in the documentation and
|
||||
I will just point out here that, like <tt>it_should_link_to_edit</tt> and such, it takes a
|
||||
symbol for the name of the instance variable it refers to and <i>additionally</i> takes
|
||||
a symbol for the name of the attribute to be edited.
|
||||
|
||||
Also note that, when constructing a long form example, instead of defining an instance variable
|
||||
for the name of the template and calling <tt>render @that_template</tt> you can simply call
|
||||
<tt>do_render</tt> which takes the name of the template from the outermost example group where
|
||||
it is customarily stated.
|
||||
|
||||
=== Model Specs
|
||||
|
||||
Skinny Spec adds a matcher for the various ActiveRecord associations. On the example group level
|
||||
you call them like:
|
||||
|
||||
it_should_belong_to :manager
|
||||
it_should_have_many :clients
|
||||
|
||||
Within an example you can call them on either the class or the instance setup in the
|
||||
"before" block. These are equivalent:
|
||||
|
||||
@user.should belong_to(:group)
|
||||
User.should belong_to(:group)
|
||||
|
||||
I've also added some very basic validation helpers like <tt>it_should_validate_presence_of</tt>,
|
||||
<tt>it_should_validate_uniqueness_of</tt>, <tt>it_should_not_mass_assign</tt>. Please consult
|
||||
the documentation for more information.
|
||||
|
||||
== Miscellaneous Notes
|
||||
|
||||
In the scaffolding, I have used my own idiomatic Rails usage:
|
||||
|
||||
* All controller actions which use HTML forms [<tt>new</tt>, <tt>edit</tt>, etc] use a shared
|
||||
form and leverage <tt>form_for</tt> to its fullest by letting it create the appropriate
|
||||
action and options.
|
||||
* Some instances where you might expect link_to are button_to. This is to provide a common
|
||||
interface element which can be styled the same instead of a mishmash of links and buttons and
|
||||
inputs everywhere. To take full advantage of this, I usually override many of Rails' default
|
||||
helpers with custom ones that all use actual HTML <tt>BUTTON</tt> elements which are much
|
||||
easier to style than "button" typed <tt>INPUT</tt>. I've provided a text file in the
|
||||
"additional" folder of this plugin which you can use in your ApplicationHelper. (I also
|
||||
provide an optional override helper for the <tt>label</tt> method which uses
|
||||
<tt>#titleize</tt> instead of <tt>humanize</tt> for stylistic reasons).
|
||||
* Probably more that I can't think of.
|
||||
|
||||
== Credits and Thanks
|
||||
|
||||
Sections of this code were taken from or inspired by Rick Olsen's
|
||||
rspec_on_rails_on_crack[http://github.com/technoweenie/rspec_on_rails_on_crack/tree/master].
|
||||
Also thanks and props to Hampton Catlin and Nathan Weizenbaum for the lovely and imminently useable
|
||||
Haml and make_resourceful. Also also praises and glory to David Chelimsky and the Rspec crew.
|
||||
|
||||
Also thanks to Don Petersen for his suggestions and fixes.
|
||||
11
vendor/plugins/skinny_spec/Rakefile
vendored
Normal file
11
vendor/plugins/skinny_spec/Rakefile
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
require 'rake'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
desc 'Generate documentation for the Skinny Spec plugin'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'doc'
|
||||
rdoc.title = 'Skinny Spec'
|
||||
rdoc.options << '--line-numbers' << '--inline-source'
|
||||
rdoc.rdoc_files.include('README.rdoc')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
58
vendor/plugins/skinny_spec/additional/helper_overrides.txt
vendored
Normal file
58
vendor/plugins/skinny_spec/additional/helper_overrides.txt
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Please insert these into your ApplicationHelper
|
||||
|
||||
# Replacement for Rails' default submit_tag helper
|
||||
# using HTML button element rather than HTML input element
|
||||
def submit_tag(text, options = {})
|
||||
content_tag :button, text, options.merge(:type => :submit)
|
||||
end
|
||||
|
||||
# Replacement for Rails' default button_to helper
|
||||
# using HTML button element rather than HTML input element
|
||||
def button_to(name, options = {}, html_options = {})
|
||||
html_options = html_options.stringify_keys
|
||||
convert_boolean_attributes!(html_options, %w( disabled ))
|
||||
|
||||
method_tag = ''
|
||||
if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
|
||||
method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
|
||||
end
|
||||
|
||||
form_method = method.to_s == 'get' ? 'get' : 'post'
|
||||
|
||||
request_token_tag = ''
|
||||
if form_method == 'post' && protect_against_forgery?
|
||||
request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
|
||||
end
|
||||
|
||||
if confirm = html_options.delete("confirm")
|
||||
html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
|
||||
end
|
||||
|
||||
url = options.is_a?(String) ? options : self.url_for(options)
|
||||
name ||= url
|
||||
|
||||
html_options.merge!("type" => "submit", "value" => name)
|
||||
|
||||
"<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button_to\"><div>" +
|
||||
method_tag + content_tag("button", name, html_options) + request_token_tag + "</div></form>"
|
||||
end
|
||||
|
||||
# Replacement for Rails' default button_to_function helper
|
||||
# using HTML button element rather than HTML input element
|
||||
def button_to_function(name, *args, &block)
|
||||
html_options = args.extract_options!
|
||||
function = args[0] || ''
|
||||
|
||||
html_options.symbolize_keys!
|
||||
function = update_page(&block) if block_given?
|
||||
content_tag(:button, name, html_options.merge({
|
||||
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
|
||||
}))
|
||||
end
|
||||
|
||||
# Replacement for Rails' default label helper
|
||||
# using String#titleize rather than String#humanize
|
||||
def label(object_name, method, text = nil, options = {})
|
||||
text ||= method.to_s[].titleize
|
||||
super
|
||||
end
|
||||
93
vendor/plugins/skinny_spec/generators/skinny_scaffold/skinny_scaffold_generator.rb
vendored
Normal file
93
vendor/plugins/skinny_spec/generators/skinny_scaffold/skinny_scaffold_generator.rb
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
class SkinnyScaffoldGenerator < Rails::Generator::NamedBase
|
||||
attr_reader :controller_class_path, :controller_file_path, :controller_class_nesting,
|
||||
:controller_class_nesting_depth, :controller_class_name, :controller_underscore_name,
|
||||
:controller_plural_name, :template_language
|
||||
alias_method :controller_file_name, :controller_underscore_name
|
||||
alias_method :controller_singular_name, :controller_file_name
|
||||
alias_method :controller_table_name, :controller_plural_name
|
||||
|
||||
def initialize(runtime_args, runtime_options = {})
|
||||
super
|
||||
|
||||
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@name.pluralize)
|
||||
@controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name)
|
||||
|
||||
if @controller_class_nesting.empty?
|
||||
@controller_class_name = @controller_class_name_without_nesting
|
||||
else
|
||||
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
||||
end
|
||||
end
|
||||
|
||||
def manifest
|
||||
record do |m|
|
||||
# Check for class naming collisions
|
||||
m.class_collisions controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper"
|
||||
m.class_collisions class_path, "#{class_name}"
|
||||
|
||||
# # Controller, helper, and views directories
|
||||
m.directory File.join('app', 'views', controller_class_path, controller_file_name)
|
||||
m.directory File.join('spec', 'views', controller_class_path, controller_file_name)
|
||||
m.directory File.join('app', 'helpers', controller_class_path)
|
||||
m.directory File.join('spec', 'helpers', controller_class_path)
|
||||
m.directory File.join('app', 'controllers', controller_class_path)
|
||||
m.directory File.join('spec', 'controllers', controller_class_path)
|
||||
m.directory File.join('app', 'models', class_path)
|
||||
m.directory File.join('spec', 'models', class_path)
|
||||
|
||||
# Views
|
||||
@template_language = defined?(Haml) ? "haml" : "erb"
|
||||
%w{index show form}.each do |action|
|
||||
m.template "#{action}.html.#{template_language}",
|
||||
File.join('app/views', controller_class_path, controller_file_name, "#{action}.html.#{template_language}")
|
||||
m.template "#{action}.html_spec.rb",
|
||||
File.join('spec/views', controller_class_path, controller_file_name, "#{action}.html.#{template_language}_spec.rb")
|
||||
end
|
||||
m.template "index_partial.html.#{template_language}",
|
||||
File.join('app/views', controller_class_path, controller_file_name, "_#{file_name}.html.#{template_language}")
|
||||
m.template 'index_partial.html_spec.rb',
|
||||
File.join('spec/views', controller_class_path, controller_file_name, "_#{file_name}.html.#{template_language}_spec.rb")
|
||||
|
||||
# Helper
|
||||
m.template 'helper.rb',
|
||||
File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")
|
||||
m.template 'helper_spec.rb',
|
||||
File.join('spec/helpers', controller_class_path, "#{controller_file_name}_helper_spec.rb")
|
||||
|
||||
# Controller
|
||||
m.template 'controller.rb',
|
||||
File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
|
||||
m.template 'controller_spec.rb',
|
||||
File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb")
|
||||
|
||||
# Model
|
||||
m.template 'model.rb',
|
||||
File.join('app/models', class_path, "#{file_name}.rb")
|
||||
m.template 'model_spec.rb',
|
||||
File.join('spec/models', class_path, "#{file_name}_spec.rb")
|
||||
|
||||
# Routing
|
||||
m.route_resources controller_file_name
|
||||
|
||||
unless options[:skip_migration]
|
||||
m.migration_template(
|
||||
'migration.rb', 'db/migrate',
|
||||
:assigns => {
|
||||
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}",
|
||||
:attributes => attributes
|
||||
},
|
||||
:migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def banner
|
||||
"Usage: #{$0} skinny_scaffold ModelName [field:type, field:type]"
|
||||
end
|
||||
|
||||
def model_name
|
||||
class_name.demodulize
|
||||
end
|
||||
end
|
||||
105
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/controller.rb
vendored
Normal file
105
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/controller.rb
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
class <%= controller_class_name %>Controller < ApplicationController
|
||||
<%- if defined?(Resourceful::Maker) -%>
|
||||
make_resourceful do
|
||||
actions :all
|
||||
|
||||
# Let's get the most use from form_for and share a single form here!
|
||||
response_for :new, :edit do
|
||||
render :template => "<%= plural_name %>/form"
|
||||
end
|
||||
|
||||
response_for :create_fails, :update_fails do
|
||||
flash[:error] = "There was a problem!"
|
||||
render :template => "<%= plural_name %>/form"
|
||||
end
|
||||
end
|
||||
<%- else -%>
|
||||
# GET /<%= table_name %>
|
||||
# GET /<%= table_name %>.xml
|
||||
def index
|
||||
@<%= table_name %> = <%= class_name %>.find(:all)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.xml { render :xml => @<%= table_name %> }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /<%= table_name %>/1
|
||||
# GET /<%= table_name %>/1.xml
|
||||
def show
|
||||
@<%= file_name %> = <%= class_name %>.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.xml { render :xml => @<%= file_name %> }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /<%= table_name %>/new
|
||||
# GET /<%= table_name %>/new.xml
|
||||
def new
|
||||
@<%= file_name %> = <%= class_name %>.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :template => "<%= plural_name %>/form" }
|
||||
format.xml { render :xml => @<%= file_name %> }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /<%= table_name %>/1/edit
|
||||
def edit
|
||||
@<%= file_name %> = <%= class_name %>.find(params[:id])
|
||||
render :template => "<%= plural_name %>/form"
|
||||
end
|
||||
|
||||
# POST /<%= table_name %>
|
||||
# POST /<%= table_name %>.xml
|
||||
def create
|
||||
@<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
|
||||
|
||||
respond_to do |format|
|
||||
if @<%= file_name %>.save
|
||||
flash[:notice] = '<%= class_name %> was successfully created.'
|
||||
format.html { redirect_to(@<%= file_name %>) }
|
||||
format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
|
||||
else
|
||||
flash.now[:error] = '<%= class_name %> could not be created.'
|
||||
format.html { render :template => "<%= plural_name %>/form" }
|
||||
format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /<%= table_name %>/1
|
||||
# PUT /<%= table_name %>/1.xml
|
||||
def update
|
||||
@<%= file_name %> = <%= class_name %>.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
|
||||
flash[:notice] = '<%= class_name %> was successfully updated.'
|
||||
format.html { redirect_to(@<%= file_name %>) }
|
||||
format.xml { head :ok }
|
||||
else
|
||||
flash.now[:error] = '<%= class_name %> could not be created.'
|
||||
format.html { render :template => "<%= plural_name %>/form" }
|
||||
format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /<%= table_name %>/1
|
||||
# DELETE /<%= table_name %>/1.xml
|
||||
def destroy
|
||||
@<%= file_name %> = <%= class_name %>.find(params[:id])
|
||||
@<%= file_name %>.destroy
|
||||
|
||||
respond_to do |format|
|
||||
flash[:notice] = '<%= class_name %> was successfully deleted.'
|
||||
format.html { redirect_to(<%= table_name %>_url) }
|
||||
format.xml { head :ok }
|
||||
end
|
||||
end
|
||||
<%- end -%>
|
||||
end
|
||||
116
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/controller_spec.rb
vendored
Normal file
116
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/controller_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
require File.dirname(__FILE__) + '/../spec_helper'
|
||||
|
||||
describe <%= controller_class_name %>Controller do
|
||||
def valid_attributes(args = {})
|
||||
{
|
||||
<% if attributes.empty? -%>
|
||||
# Add valid attributes for the your params[:<%= singular_name %>] here!
|
||||
<% else -%>
|
||||
<%- attributes.each_with_index do |attribute, index| -%>
|
||||
<%- case attribute.type -%>
|
||||
<%- when :string, :text -%>
|
||||
"<%= attribute.name %>" => "foo"<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :integer, :float, :decimal -%>
|
||||
"<%= attribute.name %>" => 815<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :boolean -%>
|
||||
"<%= attribute.name %>" => false<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :date, :datetime, :time, :timestamp -%>
|
||||
"<%= attribute.name %>" => 1.week.ago<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- else -%>
|
||||
"<%= attribute.name %>" => nil<%= index < attributes.size - 1 ? "," : "" %> # Could not determine valid attribute
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
}.merge(args)
|
||||
end
|
||||
|
||||
describe "GET :index" do
|
||||
before(:each) do
|
||||
@<%= plural_name %> = stub_index(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_find_and_assign :<%= plural_name %>
|
||||
it_should_render_template "index"
|
||||
end
|
||||
|
||||
describe "GET :new" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_new(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_initialize_and_assign :<%= singular_name %>
|
||||
it_should_render_template "form"
|
||||
end
|
||||
|
||||
describe "POST :create" do
|
||||
describe "when successful" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_create(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_initialize_and_save :<%= singular_name %>
|
||||
it_should_set_flash :notice
|
||||
it_should_redirect_to { <%= singular_name %>_url(@<%= singular_name %>) }
|
||||
end
|
||||
|
||||
describe "when unsuccessful" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_create(<%= class_name %>, :return => :false)
|
||||
end
|
||||
|
||||
it_should_initialize_and_assign :<%= singular_name %>
|
||||
it_should_set_flash :error
|
||||
it_should_render_template "form"
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET :show" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_show(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_find_and_assign :<%= singular_name %>
|
||||
it_should_render_template "show"
|
||||
end
|
||||
|
||||
describe "GET :edit" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_edit(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_find_and_assign :<%= singular_name %>
|
||||
it_should_render_template "form"
|
||||
end
|
||||
|
||||
describe "PUT :update" do
|
||||
describe "when successful" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_update(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_find_and_update :<%= singular_name %>
|
||||
it_should_set_flash :notice
|
||||
it_should_redirect_to { <%= singular_name %>_url(@<%= singular_name %>) }
|
||||
end
|
||||
|
||||
describe "when unsuccessful" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_update(<%= class_name %>, :return => :false)
|
||||
end
|
||||
|
||||
it_should_find_and_assign :<%= singular_name %>
|
||||
it_should_set_flash :error
|
||||
it_should_render_template "form"
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE :destroy" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = stub_destroy(<%= class_name %>)
|
||||
end
|
||||
|
||||
it_should_find_and_destroy :<%= singular_name %>
|
||||
it_should_set_flash :notice
|
||||
it_should_redirect_to { <%= plural_name %>_url }
|
||||
end
|
||||
end
|
||||
25
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html.erb
vendored
Normal file
25
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html.erb
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<h1><%= singular_name %>.new_record? ? "New" : "Edit" %> <%= model_name %></h1>
|
||||
<%% form_for(@<%= singular_name %>) do |f| %>
|
||||
<div id="form_errors">
|
||||
<%%= f.error_messages %>
|
||||
</div>
|
||||
<%- if attributes.blank? -%>
|
||||
<p>Add your form elements here, please!</p>
|
||||
<%- else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
<p>
|
||||
<%%= f.label :<%= attribute.name %> %><br />
|
||||
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
||||
</p>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<div id="commands">
|
||||
<%%= submit_tag "Save" %>
|
||||
<div id="navigation_commands">
|
||||
<%% unless @<%= singular_name %>.new_record? -%>
|
||||
<%%= button_to "Show", <%= singular_name %>_path(@<%= singular_name %>), :method => "get", :title => "Show <%= singular_name %>. Unsaved changes will be lost." %>
|
||||
<%% end -%>
|
||||
<%%= button_to "Back to List", <%= plural_name %>_path, :class => "cancel", :method => "get", :title => "Return to <%= singular_name %> list without saving changes" %>
|
||||
</div>
|
||||
</div>
|
||||
<%% end -%>
|
||||
18
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html.haml
vendored
Normal file
18
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html.haml
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
%h1== #{@<%= singular_name %>.new_record? ? "New" : "Edit"} #{<%= model_name %>}
|
||||
- form_for @<%= singular_name %> do |f|
|
||||
#form_errors= f.error_messages
|
||||
<% if attributes.blank? -%>
|
||||
%p Add your form elements here, please!
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
%p
|
||||
= f.label :<%= attribute.name %>
|
||||
= f.<%= attribute.field_type %> :<%= attribute.name %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
#commands
|
||||
= submit_tag "Save"
|
||||
#navigation_commands
|
||||
- unless @<%= singular_name %>.new_record?
|
||||
= button_to "Show", <%= singular_name %>_path(@<%= singular_name %>), :method => "get", :title => "Show <%= singular_name %>. Unsaved changes will be lost."
|
||||
= button_to "Back to List", <%= plural_name %>_path, :class => "cancel", :method => "get", :title => "Return to <%= singular_name %> list without saving changes"
|
||||
41
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html_spec.rb
vendored
Normal file
41
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../../spec_helper'
|
||||
|
||||
describe "<%= File.join(controller_class_path, controller_singular_name) %>/form.html.<%= template_language %>" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = mock_and_assign(<%= model_name %>, :stub => {
|
||||
<% if attributes.blank? -%>
|
||||
# Add your stub attributes and return values here like:
|
||||
# :name => "Foo", :created_at => 1.week.ago, :updated_at => nil
|
||||
<% else -%>
|
||||
<%- attributes.each_with_index do |attribute, index| -%>
|
||||
<%- case attribute.type -%>
|
||||
<%- when :string, :text -%>
|
||||
:<%= attribute.name %> => "foo"<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :integer, :float, :decimal -%>
|
||||
:<%= attribute.name %> => 815<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :boolean -%>
|
||||
:<%= attribute.name %> => false<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :date, :datetime, :time, :timestamp -%>
|
||||
:<%= attribute.name %> => 1.week.ago<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- else -%>
|
||||
:<%= attribute.name %> => nil<%= index < attributes.size - 1 ? "," : "" %> # Could not determine valid attribute
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
})
|
||||
end
|
||||
|
||||
it_should_have_form_for :<%= singular_name %>
|
||||
<% if attributes.blank? -%>
|
||||
# Add specs for editing attributes here, please! Like this:
|
||||
#
|
||||
# it_should_allow_editing :<%= singular_name %>, :foo
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
it_should_allow_editing :<%= singular_name %>, :<%= attribute.name %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
|
||||
it_should_link_to_show :<%= singular_name %>
|
||||
it_should_link_to { <%= plural_name %>_path }
|
||||
end
|
||||
2
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/helper.rb
vendored
Normal file
2
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/helper.rb
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module <%= controller_class_name %>Helper
|
||||
end
|
||||
5
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/helper_spec.rb
vendored
Normal file
5
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/helper_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../spec_helper'
|
||||
|
||||
describe <%= controller_class_name %>Helper do
|
||||
# Add your specs here or remove this file completely, please!
|
||||
end
|
||||
31
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html.erb
vendored
Normal file
31
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html.erb
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<h1><%= model_name %> List</h1>
|
||||
<table>
|
||||
<%%- if @<%= plural_name %>.empty? -%>
|
||||
<tbody>
|
||||
<tr class="empty">
|
||||
<td>There are no <%= plural_name.humanize.downcase %></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<%%- else -%>
|
||||
<thead>
|
||||
<tr>
|
||||
<%- if attributes.blank? -%>
|
||||
<th><!-- Generic display column --></th>
|
||||
<%- else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
<th><%= attribute.name.titleize %></th>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<th class="show"><!-- "Show" link column --></th>
|
||||
<th class="edit"><!-- "Edit" link column --></th>
|
||||
<th class="delete"><!-- "Delete" link column --></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%%= render :partial => @<%= plural_name %> %>
|
||||
</tbody>
|
||||
<%%- end -%>
|
||||
</table>
|
||||
<div id="commands">
|
||||
<%%= button_to "New <%= singular_name.titleize %>", new_<%= singular_name %>_path, :method => "get" %>
|
||||
</div>
|
||||
23
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html.haml
vendored
Normal file
23
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html.haml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
%h1 <%= model_name %> List
|
||||
%table
|
||||
- if @<%= plural_name %>.empty?
|
||||
%tbody
|
||||
%tr.empty
|
||||
%td== There are no <%= plural_name.humanize.downcase %>
|
||||
- else
|
||||
%thead
|
||||
%tr
|
||||
<% if attributes.blank? -%>
|
||||
%th= # Generic display column
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
%th <%= attribute.name.titleize %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
%th.show= # 'Show' link column
|
||||
%th.edit= # 'Edit' link column
|
||||
%th.delete= # 'Delete' link column
|
||||
%tbody
|
||||
= render :partial => @<%= plural_name %>
|
||||
#commands
|
||||
= button_to "New <%= singular_name.titleize %>", new_<%= singular_name %>_path, :method => "get"
|
||||
15
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html_spec.rb
vendored
Normal file
15
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../../spec_helper'
|
||||
|
||||
describe "<%= File.join(controller_class_path, controller_singular_name) %>/index.html.<%= template_language %>" do
|
||||
before(:each) do
|
||||
@<%= plural_name %> = mock_and_assign_collection(<%= model_name %>)
|
||||
template.stub_render :partial => @<%= plural_name %>
|
||||
end
|
||||
|
||||
it "should render :partial => @<%= plural_name %>" do
|
||||
template.expect_render :partial => @<%= plural_name %>
|
||||
do_render
|
||||
end
|
||||
|
||||
it_should_link_to_new :<%= singular_name %>
|
||||
end
|
||||
12
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html.erb
vendored
Normal file
12
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html.erb
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<tr class="<%%= cycle("odd", "even") %>">
|
||||
<% if attributes.blank? -%>
|
||||
<td><%= model_name %> #<%%= <%= singular_name %>.id %></td>
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
<td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
|
||||
<%- end %>
|
||||
<% end -%>
|
||||
<td class="show"><%%= button_to "Show", <%= singular_name %>, :method => "get" %></td>
|
||||
<td class="edit"><%%= button_to "Edit", edit_<%= singular_name %>_path(<%= singular_name %>), :method => "get" %></td>
|
||||
<td class="delete"><%%= button_to "Delete", <%= singular_name %>, :method => "delete" %></td>
|
||||
</tr>
|
||||
11
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html.haml
vendored
Normal file
11
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html.haml
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
%tr{:class => cycle("odd", "even")}
|
||||
<% if attributes.blank? -%>
|
||||
%td== <%= model_name %> #{<%= singular_name %>.id}
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
%td=h <%= singular_name %>.<%= attribute.name %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
%td.show= button_to "Show", <%= singular_name %>_path(<%= singular_name %>), :method => "get"
|
||||
%td.edit= button_to "Edit", edit_<%= singular_name %>_path(<%= singular_name %>), :method => "get"
|
||||
%td.delete= button_to "Delete", <%= singular_name %>, :method => "delete"
|
||||
32
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html_spec.rb
vendored
Normal file
32
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../../spec_helper'
|
||||
|
||||
describe "<%= File.join(controller_class_path, controller_singular_name) %>/_<%= singular_name %>.html.<%= template_language %>" do
|
||||
before(:each) do
|
||||
@<%= singular_name %> = mock_and_assign(<%= model_name %>, :stub => {
|
||||
<% if attributes.blank? -%>
|
||||
# Add your stub attributes and return values here like:
|
||||
# :name => "Foo", :created_at => 1.week.ago, :updated_at => nil
|
||||
<% else -%>
|
||||
<%- attributes.each_with_index do |attribute, index| -%>
|
||||
<%- case attribute.type -%>
|
||||
<%- when :string, :text -%>
|
||||
:<%= attribute.name %> => "foo"<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :integer, :float, :decimal -%>
|
||||
:<%= attribute.name %> => 815<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :boolean -%>
|
||||
:<%= attribute.name %> => false<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :date, :datetime, :time, :timestamp -%>
|
||||
:<%= attribute.name %> => 1.week.ago<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- else -%>
|
||||
:<%= attribute.name %> => nil<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
})
|
||||
template.stub!(:<%= singular_name %>).and_return(@<%= singular_name %>)
|
||||
end
|
||||
|
||||
it_should_link_to_show :<%= singular_name %>
|
||||
it_should_link_to_edit :<%= singular_name %>
|
||||
it_should_link_to_delete :<%= singular_name %>
|
||||
end
|
||||
14
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/migration.rb
vendored
Normal file
14
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/migration.rb
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class <%= migration_name %> < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :<%= table_name %>, :force => true do |t|
|
||||
<% attributes.each do |attribute| -%>
|
||||
t.column :<%= attribute.name %>, :<%= attribute.type %>
|
||||
<% end -%>
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :<%= table_name %>
|
||||
end
|
||||
end
|
||||
2
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/model.rb
vendored
Normal file
2
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/model.rb
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
class <%= class_name %> < ActiveRecord::Base
|
||||
end
|
||||
25
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/model_spec.rb
vendored
Normal file
25
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/model_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper'
|
||||
|
||||
describe <%= class_name %> do
|
||||
def valid_attributes(args = {})
|
||||
{
|
||||
# Add valid attributes for building your model instances here!
|
||||
}.merge(args)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
@<%= singular_name %> = <%= class_name %>.new
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
@<%= singular_name %>.destroy unless @<%= singular_name %>.new_record?
|
||||
end
|
||||
|
||||
# Add your model specs here, please!
|
||||
# And don't forget about the association matchers built-in to skinny_spec like:
|
||||
#
|
||||
# it_should_have_many :foos
|
||||
# it_should_validate_presence_of :bar
|
||||
#
|
||||
# Check out the docs for more information.
|
||||
end
|
||||
15
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html.erb
vendored
Normal file
15
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html.erb
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<h1>Show <%= model_name %></h1>
|
||||
<% if attributes.blank? -%>
|
||||
<p>Add your customized markup here, please!</p>
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
<p>
|
||||
<label><%= attribute.name.titleize %>:</label>
|
||||
<%%=h @<%= singular_name %>.<%= attribute.name %> %>
|
||||
</p>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
<div id="commands">
|
||||
<%%= button_to "Edit", edit_<%= singular_name %>_path(@<%= singular_name %>), :method => "get" %>
|
||||
<%%= button_to "Back to List", <%= plural_name %>_path, :method => "get" %>
|
||||
</div>
|
||||
13
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html.haml
vendored
Normal file
13
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html.haml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
%h1== Show #{<%= model_name %>}
|
||||
<% if attributes.blank? -%>
|
||||
%p Add your customized markup here, please!
|
||||
<% else -%>
|
||||
<%- attributes.each do |attribute| -%>
|
||||
%p
|
||||
%label <%= attribute.name.titleize %>:
|
||||
=h @<%= singular_name %>.<%= attribute.name %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
#commands
|
||||
= button_to "Edit", edit_<%= singular_name %>_path(@<%= singular_name %>), :method => "get"
|
||||
= button_to "Back to List", <%= plural_name %>_path, :method => "get"
|
||||
32
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html_spec.rb
vendored
Normal file
32
vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../../spec_helper'
|
||||
|
||||
describe "<%= File.join(controller_class_path, controller_singular_name) %>/show.html.<%= template_language %>" do
|
||||
before(:each) do
|
||||
<% if attributes.blank? -%>
|
||||
@<%= singular_name %> = mock_and_assign(<%= model_name %>)
|
||||
<% else -%>
|
||||
@<%= singular_name %> = mock_and_assign(<%= model_name %>, :stub => {
|
||||
<%- attributes.each_with_index do |attribute, index| -%>
|
||||
<%- case attribute.type -%>
|
||||
<%- when :string, :text -%>
|
||||
:<%= attribute.name %> => "foo"<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :integer, :float, :decimal -%>
|
||||
:<%= attribute.name %> => 815<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :boolean -%>
|
||||
:<%= attribute.name %> => false<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- when :date, :datetime, :time, :timestamp -%>
|
||||
:<%= attribute.name %> => 1.week.ago<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- else -%>
|
||||
:<%= attribute.name %> => nil<%= index < attributes.size - 1 ? "," : "" %>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
})
|
||||
<% end -%>
|
||||
end
|
||||
|
||||
# Add your specs here, please! But remember not to make them brittle
|
||||
# by specing specing specific HTML elements and classes.
|
||||
|
||||
it_should_link_to_edit :<%= singular_name %>
|
||||
it_should_link_to { <%= plural_name %>_path }
|
||||
end
|
||||
3
vendor/plugins/skinny_spec/init.rb
vendored
Normal file
3
vendor/plugins/skinny_spec/init.rb
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
if RAILS_ENV == "test"
|
||||
require "skinny_spec"
|
||||
end
|
||||
46
vendor/plugins/skinny_spec/lib/lucky_sneaks/common_spec_helpers.rb
vendored
Normal file
46
vendor/plugins/skinny_spec/lib/lucky_sneaks/common_spec_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
module LuckySneaks
|
||||
# These methods are mostly just called internally by various other spec helper
|
||||
# methods but you're welcome to use them as needed in your own specs.
|
||||
module CommonSpecHelpers
|
||||
# Returns class for the specified name. Example:
|
||||
#
|
||||
# class_for("foo") # => Foo
|
||||
def class_for(name)
|
||||
name.to_s.constantize
|
||||
rescue NameError
|
||||
name.to_s.classify.constantize
|
||||
# Let any other error rise!
|
||||
end
|
||||
|
||||
# Returns instance variable for the specified name. Example:
|
||||
#
|
||||
# instance_for("foo") # => @foo
|
||||
def instance_for(name)
|
||||
instance_variable_get("@#{name.to_s.underscore}")
|
||||
end
|
||||
|
||||
# Wraps a matcher that checks if the receiver contains an <tt>A</tt> element (link)
|
||||
# whose <tt>href</tt> attribute is set to the specified path.
|
||||
def have_link_to(path)
|
||||
have_tag("a[href='#{path}']")
|
||||
end
|
||||
|
||||
# Returns dummy value for specified attribute based on the datatype expected for that
|
||||
# attribute.
|
||||
def dummy_value_for(instance, attribute)
|
||||
if datatype = instance.column_for_attribute(attribute)
|
||||
actual = instance.send(attribute)
|
||||
case datatype.type
|
||||
when :string, :text
|
||||
actual == "foo" ? "bar" : "food"
|
||||
when :integer, :float, :decimal
|
||||
actual == 108 ? 815 : 108
|
||||
when :boolean
|
||||
actual ? false : true
|
||||
when :date, :datetime, :time, :timestamp
|
||||
actual == 1.week.ago ? 2.years.ago : 1.week.ago
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
67
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_request_helpers.rb
vendored
Normal file
67
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_request_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
module LuckySneaks
|
||||
module ControllerRequestHelpers # :nodoc:
|
||||
def self.included(base)
|
||||
base.extend ExampleGroupMethods
|
||||
end
|
||||
|
||||
private
|
||||
def define_implicit_request(method)
|
||||
@controller_method = method
|
||||
@implicit_request = case method
|
||||
when :index, :new, :show, :edit
|
||||
proc { get method, params }
|
||||
when :create
|
||||
proc { post :create, params }
|
||||
when :update
|
||||
proc { put :update, params }
|
||||
when :destroy
|
||||
proc { put :destroy, params }
|
||||
end
|
||||
end
|
||||
|
||||
def eval_request
|
||||
instance_eval &self.class.instance_variable_get("@the_request")
|
||||
rescue ArgumentError # missing block
|
||||
try_shared_request_definition
|
||||
end
|
||||
alias do_request eval_request
|
||||
|
||||
def try_shared_request_definition
|
||||
shared_request
|
||||
rescue NameError
|
||||
if @implicit_request
|
||||
try_implicit_request
|
||||
else
|
||||
error_message = "Could not determine request definition for 'describe' context. "
|
||||
error_message << "Please use define_request or define a shared_request."
|
||||
raise ArgumentError, error_message
|
||||
end
|
||||
end
|
||||
|
||||
def try_implicit_request
|
||||
@implicit_request.call
|
||||
end
|
||||
|
||||
def get_response(&block)
|
||||
eval_request
|
||||
block.call(response) if block_given?
|
||||
response
|
||||
end
|
||||
|
||||
module ExampleGroupMethods
|
||||
# Defines a request at the example group ("describe") level to be evaluated in the examples. Example:
|
||||
#
|
||||
# define_request { get :index, params }
|
||||
#
|
||||
# <b>Note:</b> The following methods all define implicit requests: <tt>stub_index</tt>, <tt>stub_new</tt>,
|
||||
# <tt>stub_create</tt>, <tt>stub_show</tt>, <tt>stub_edit</tt>, <tt>stub_update</tt>, and
|
||||
# <tt>stub_destroy</tt>. Using them in your <tt>before</tt> blocks will allow you to forego
|
||||
# defining explicit requests using <tt>define_request</tt>. See
|
||||
# LuckySneaks::ControllerStubHelpers for information on these methods.
|
||||
def define_request(&block)
|
||||
raise ArgumentError, "Must provide a block to define a request!" unless block_given?
|
||||
@the_request = block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
435
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_spec_helpers.rb
vendored
Normal file
435
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_spec_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
$:.unshift File.join(File.dirname(__FILE__), "..")
|
||||
require "skinny_spec"
|
||||
|
||||
module LuckySneaks
|
||||
module ControllerSpecHelpers # :nodoc:
|
||||
include LuckySneaks::CommonSpecHelpers
|
||||
include LuckySneaks::ControllerRequestHelpers
|
||||
include LuckySneaks::ControllerStubHelpers
|
||||
|
||||
def self.included(base)
|
||||
base.extend ExampleGroupMethods
|
||||
base.extend ControllerRequestHelpers::ExampleGroupMethods
|
||||
end
|
||||
|
||||
# Evaluates the specified block for each of the RESTful controller methods.
|
||||
# This is useful to spec that all controller methods redirect when no user is
|
||||
# logged in.
|
||||
def with_default_restful_actions(params = {}, &block)
|
||||
{
|
||||
:get => :index,
|
||||
:get => :new,
|
||||
:post => :create
|
||||
}.each do |method_id, message|
|
||||
self.send method_id, message, params
|
||||
block.call
|
||||
end
|
||||
{
|
||||
:get => :edit,
|
||||
:put => :update,
|
||||
:delete => :destroy
|
||||
}.each do |method_id, message|
|
||||
if params[:before]
|
||||
params.delete(:before).call
|
||||
end
|
||||
# Presuming any id will do
|
||||
self.send method_id, message, params.merge(:id => 1)
|
||||
block.call
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def create_ar_class_expectation(name, method, argument = nil, options = {})
|
||||
args = []
|
||||
if [:create, :update].include?(@controller_method)
|
||||
args << (argument.nil? ? valid_attributes : argument)
|
||||
else
|
||||
args << argument unless argument.nil?
|
||||
end
|
||||
args << options unless options.empty?
|
||||
if args.empty?
|
||||
return_value = class_for(name).send(method)
|
||||
class_for(name).should_receive(method).and_return(return_value)
|
||||
else
|
||||
return_value = class_for(name).send(method, *args)
|
||||
class_for(name).should_receive(method).with(*args).and_return(return_value)
|
||||
end
|
||||
end
|
||||
|
||||
def create_positive_ar_instance_expectation(name, method, *args)
|
||||
instance = instance_for(name)
|
||||
if args.empty?
|
||||
return_value = instance.send(method)
|
||||
instance.should_receive(method).and_return(true)
|
||||
else
|
||||
return_value = instance.send(method, *args)
|
||||
instance.should_receive(method).with(*args).and_return(true)
|
||||
end
|
||||
end
|
||||
|
||||
# These methods are designed to be used at the example group [read: "describe"] level
|
||||
# to simplify and DRY up common expectations.
|
||||
module ExampleGroupMethods
|
||||
# Creates an expectation that the controller method calls <tt>ActiveRecord::Base.find</tt>.
|
||||
# Examples:
|
||||
#
|
||||
# it_should_find :foos # => Foo.should_receive(:find).with(:all)
|
||||
# it_should_find :foos, :all # An explicit version of the above
|
||||
# it_should_find :foos, :conditions => {:foo => "bar"} # => Foo.should_receive(:find).with(:all, :conditions => {"foo" => "bar"}
|
||||
# it_should_find :foo # => Foo.should_recieve(:find).with(@foo.id.to_s)
|
||||
# it_should_find :foo, :params => "id" # => Foo.should_receive(:find).with(params[:id].to_s)
|
||||
# it_should_find :foo, 2 # => Foo.should_receive(:find).with("2")
|
||||
#
|
||||
# <b>Note:</b> All params (key and value) will be strings if they come from a form element and are handled
|
||||
# internally with this expectation.
|
||||
def it_should_find(name, *args)
|
||||
name_string = name.to_s
|
||||
name_message = if name_string == name_string.singularize
|
||||
"a #{name}"
|
||||
else
|
||||
name
|
||||
end
|
||||
it "should find #{name_message}" do
|
||||
options = args.extract_options!
|
||||
# Blech!
|
||||
argument = if param = params[options.delete(:params)]
|
||||
param.to_s
|
||||
else
|
||||
if args.first
|
||||
args.first
|
||||
elsif (instance = instance_variable_get("@#{name}")).is_a?(ActiveRecord::Base)
|
||||
instance.id.to_s
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
create_ar_class_expectation name, :find, argument, options
|
||||
eval_request
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method calls <tt>ActiveRecord::Base.new</tt>.
|
||||
# Takes optional <tt>params</tt> for the initialization arguments. Example
|
||||
#
|
||||
# it_should_initialize :foo # => Foo.should_receive(:new)
|
||||
# it_should_initialize :foo, :params => :bar # => Foo.should_receive(:new).with(params[:bar])
|
||||
# it_should_initialize :foo, :bar => "baz" # => Foo.should_receive(:new).with(:bar => "baz")
|
||||
def it_should_initialize(name, options = {})
|
||||
it "should initialize a #{name}" do
|
||||
create_ar_class_expectation name, :new, params[options.delete(:params)], options
|
||||
eval_request
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method calls <tt>ActiveRecord::Base#save</tt> on the
|
||||
# named instance. Example:
|
||||
#
|
||||
# it_should_save :foo # => @foo.should_receive(:save).and_return(true)
|
||||
#
|
||||
# <b>Note:</b> This helper should not be used to spec a failed <tt>save</tt> call. Use <tt>it_should_assign</tt>
|
||||
# instead, to verify that the instance is captured in an instance variable for the inevitable re-rendering
|
||||
# of the form template.
|
||||
def it_should_save(name)
|
||||
it "should save the #{name}" do
|
||||
create_positive_ar_instance_expectation name, :save
|
||||
eval_request
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method calls <tt>ActiveRecord::Base#update_attributes</tt>
|
||||
# on the named instance. Takes optional argument for <tt>params</tt> to specify in the
|
||||
# expectation. Examples:
|
||||
#
|
||||
# it_should_update :foo # => @foo.should_receive(:update_attributes).and_return(true)
|
||||
# it_should_update :foo, :params => :bar # => @foo.should_receive(:update_attributes).with(params[:bar]).and_return(true)
|
||||
#
|
||||
# <b>Note:</b> This helper should not be used to spec a failed <tt>update_attributes</tt> call. Use
|
||||
# <tt>it_should_assign</tt> instead, to verify that the instance is captured in an instance variable
|
||||
# for the inevitable re-rendering of the form template.
|
||||
def it_should_update(name, options = {})
|
||||
it "should update the #{name}" do
|
||||
create_positive_ar_instance_expectation name, :update_attributes, params[options[:params]]
|
||||
eval_request
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method calls <tt>ActiveRecord::Base#destroy</tt> on the named
|
||||
# instance. Example:
|
||||
#
|
||||
# it_should_destroy :foo # => @foo.should_receive(:destroy).and_return(true)
|
||||
#
|
||||
# <b>Note:</b> This helper should not be used to spec a failed <tt>destroy</tt> call. Use
|
||||
# <tt>it_should_assign</tt> instead, if you need to verify that the instance is captured in an instance
|
||||
# variable if it is re-rendered somehow. This is probably a really edge use case.
|
||||
def it_should_destroy(name, options = {})
|
||||
it "should delete the #{name}" do
|
||||
create_positive_ar_instance_expectation name, :destroy
|
||||
eval_request
|
||||
end
|
||||
end
|
||||
|
||||
# Creates expectation[s] that the controller method should assign the specified
|
||||
# instance variables along with any specified values. Examples:
|
||||
#
|
||||
# it_should_assign :foo # => assigns[:foo].should == @foo
|
||||
# it_should_assign :foo => "bar" # => assigns[:foo].should == "bar"
|
||||
# it_should_assign :foo => :nil # => assigns[:foo].should be_nil
|
||||
# it_should_assign :foo => :not_nil # => assigns[:foo].should_not be_nil
|
||||
# it_should_assign :foo => :undefined # => controller.send(:instance_variables).should_not include("@foo")
|
||||
#
|
||||
# Very special thanks to Rick Olsen for the basis of this code. The only reason I even
|
||||
# redefine it at all is purely an aesthetic choice for specs like "it should foo"
|
||||
# over ones like "it foos".
|
||||
def it_should_assign(*names)
|
||||
names.each do |name|
|
||||
if name.is_a?(Symbol)
|
||||
it_should_assign name => name
|
||||
elsif name.is_a?(Hash)
|
||||
name.each do |key, value|
|
||||
it_should_assign_instance_variable key, value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps the separate expectations <tt>it_should_find</tt> and <tt>it_should_assign</tt>
|
||||
# for simple cases. If you need more control over the parameters of the find, this
|
||||
# isn't the right helper method and you should write out the two expectations separately.
|
||||
def it_should_find_and_assign(*names)
|
||||
names.each do |name|
|
||||
it_should_find name
|
||||
it_should_assign name
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps the separate expectations <tt>it_should_initialize</tt> and <tt>it_should_assign</tt>
|
||||
# for simple cases. If you need more control over the parameters of the initialization, this
|
||||
# isn't the right helper method and you should write out the two expectations separately.
|
||||
#
|
||||
# <b>Note:</b> This method is used for controller methods like <tt>new</tt>, where the instance
|
||||
# is initialized without being saved (this includes failed <tt>create</tt> requests).
|
||||
# If you want to spec that the controller method successfully saves the instance,
|
||||
# please use <tt>it_should_initialize_and_save</tt>.
|
||||
def it_should_initialize_and_assign(*names)
|
||||
names.each do |name|
|
||||
it_should_initialize name
|
||||
it_should_assign name
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps the separate expectations <tt>it_should_initialize</tt> and <tt>it_should_save</tt>
|
||||
# for simple cases. If you need more control over the parameters of the initialization, this
|
||||
# isn't the right helper method and you should write out the two expectations separately.
|
||||
#
|
||||
# <b>Note:</b> This method is used for controller methods like <tt>create</tt>, where the instance
|
||||
# is initialized and successfully saved. If you want to spec that the instance is created
|
||||
# but not saved, just use <tt>it_should_initialize_and_assign</tt>.
|
||||
def it_should_initialize_and_save(*names)
|
||||
names.each do |name|
|
||||
it_should_initialize name
|
||||
it_should_save name
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps the separate expectations <tt>it_should_find</tt> and <tt>it_should_update</tt>
|
||||
# for simple cases. If you need more control over the parameters of the find, this
|
||||
# isn't the right helper method and you should write out the two expectations separately.
|
||||
#
|
||||
# <b>Note:</b> This method is used for controller methods like <tt>update</tt>, where the
|
||||
# instance is loaded from the database and successfully saved. If you want to spec that the
|
||||
# instance is found but not saved, just use <tt>it_should_find_and_assign</tt>.
|
||||
def it_should_find_and_update(*names)
|
||||
names.each do |name|
|
||||
it_should_find name
|
||||
it_should_update name
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps the separate expectations <tt>it_should_find</tt> and <tt>it_should_destroy</tt>
|
||||
# for simple cases. If you need more control over the parameters of the find, this
|
||||
# isn't the right helper method and you should write out the two expectations separately.
|
||||
def it_should_find_and_destroy(*names)
|
||||
names.each do |name|
|
||||
it_should_find name
|
||||
it_should_destroy name
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the specified collection (<tt>flash</tt> or <tt>session</tt>)
|
||||
# contains the specified key and value. To specify that the collection should be set
|
||||
# to <tt>nil</tt>, specify the value as :nil instead.
|
||||
def it_should_set(collection, key, value = nil, &block)
|
||||
it "should set #{collection}[:#{key}]" do
|
||||
# Allow flash.now[:foo] to remain in the flash
|
||||
flash.stub!(:sweep) if collection == :flash
|
||||
eval_request
|
||||
if value
|
||||
if value == :nil
|
||||
self.send(collection)[key].should be_nil
|
||||
else
|
||||
self.send(collection)[key].should == value
|
||||
end
|
||||
elsif block_given?
|
||||
self.send(collection)[key].should == block.call
|
||||
else
|
||||
self.send(collection)[key].should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps <tt>it_should_set :flash</tt>. To specify that the collection should be set
|
||||
# to <tt>nil</tt>, specify the value as :nil instead.
|
||||
def it_should_set_flash(name, value = nil, &block)
|
||||
it_should_set :flash, name, value, &block
|
||||
end
|
||||
|
||||
# Wraps <tt>it_should_set :session</tt>. To specify that the collection should be set
|
||||
# to <tt>nil</tt>, specify the value as :nil instead.
|
||||
def it_should_set_session(name, value = nil, &block)
|
||||
it_should_set :session, name, value, &block
|
||||
end
|
||||
|
||||
# Wraps the various <tt>it_should_render_<i>foo</i></tt> methods:
|
||||
# <tt>it_should_render_template</tt>, <tt>it_should_render_partial</tt>,
|
||||
# <tt>it_should_render_xml</tt>, <tt>it_should_render_json</tt>,
|
||||
# <tt>it_should_render_formatted</tt>, and <tt>it_should_render_nothing</tt>.
|
||||
def it_should_render(render_method, *args)
|
||||
send "it_should_render_#{render_method}", *args
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method renders the specified template.
|
||||
# Accepts the following options which create additional expectations.
|
||||
#
|
||||
# <tt>:content_type</tt>:: Creates an expectation that the Content-Type header for the response
|
||||
# matches the one specified
|
||||
# <tt>:status</tt>:: Creates an expectation that the HTTP status for the response
|
||||
# matches the one specified
|
||||
def it_should_render_template(name, options = {})
|
||||
create_status_expectation options[:status] if options[:status]
|
||||
it "should render '#{name}' template" do
|
||||
eval_request
|
||||
response.should render_template(name)
|
||||
end
|
||||
create_content_type_expectation(options[:content_type]) if options[:content_type]
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method renders the specified partial.
|
||||
# Accepts the following options which create additional expectations.
|
||||
#
|
||||
# <tt>:content_type</tt>:: Creates an expectation that the Content-Type header for the response
|
||||
# matches the one specified
|
||||
# <tt>:status</tt>:: Creates an expectation that the HTTP status for the response
|
||||
# matches the one specified
|
||||
def it_should_render_partial(name, options = {})
|
||||
create_status_expectation options[:status] if options[:status]
|
||||
it "should render '#{name}' partial" do
|
||||
controller.expect_render(:partial => name)
|
||||
eval_request
|
||||
end
|
||||
create_content_type_expectation(options[:content_type]) if options[:content_type]
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method renders the specified record via <tt>to_xml</tt>.
|
||||
# Accepts the following options which create additional expectations.
|
||||
#
|
||||
# <tt>:content_type</tt>:: Creates an expectation that the Content-Type header for the response
|
||||
# matches the one specified
|
||||
# <tt>:status</tt>:: Creates an expectation that the HTTP status for the response
|
||||
# matches the one specified
|
||||
def it_should_render_xml(record = nil, options = {}, &block)
|
||||
it_should_render_formatted :xml, record, options, &block
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method renders the specified record via <tt>to_json</tt>.
|
||||
# Accepts the following options which create additional expectations.
|
||||
#
|
||||
# <tt>:content_type</tt>:: Creates an expectation that the Content-Type header for the response
|
||||
# matches the one specified
|
||||
# <tt>:status</tt>:: Creates an expectation that the HTTP status for the response
|
||||
# matches the one specified
|
||||
def it_should_render_json(record = nil, options = {}, &block)
|
||||
it_should_render_formatted :json, record, options, &block
|
||||
end
|
||||
|
||||
# Called internally by <tt>it_should_render_xml</tt> and <tt>it_should_render_json</tt>
|
||||
# but should not really be called much externally unless you have defined your own
|
||||
# formats with a matching <tt>to_foo</tt> method on the record.
|
||||
#
|
||||
# Which is probably never.
|
||||
def it_should_render_formatted(format, record = nil, options = {}, &block)
|
||||
create_status_expectation options[:status] if options[:status]
|
||||
it "should render #{format.inspect}" do
|
||||
if record.is_a?(Hash)
|
||||
options = record
|
||||
record = nil
|
||||
end
|
||||
if record.nil? && !block_given?
|
||||
raise ArgumentError, "it_should_render must be called with either a record or a block and neither was given."
|
||||
else
|
||||
if record
|
||||
pieces = record.to_s.split(".")
|
||||
record = instance_variable_get("@#{pieces.shift}")
|
||||
record = record.send(pieces.shift) until pieces.empty?
|
||||
end
|
||||
block ||= proc { record.send("to_#{format}") }
|
||||
get_response do |response|
|
||||
response.should have_text(block.call)
|
||||
end
|
||||
end
|
||||
end
|
||||
create_content_type_expectation(options[:content_type]) if options[:content_type]
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method returns a blank page. You'd already
|
||||
# know when and why to use this so I'm not typing it out.
|
||||
def it_should_render_nothing(options = {})
|
||||
create_status_expectation options[:status] if options[:status]
|
||||
it "should render :nothing" do
|
||||
get_response do |response|
|
||||
response.body.strip.should be_blank
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the controller method redirects to the specified destination. Example:
|
||||
#
|
||||
# it_should_redirect_to { foos_url }
|
||||
#
|
||||
# <b>Note:</b> This method takes a block to evaluate the route in the example
|
||||
# context rather than the example group context.
|
||||
def it_should_redirect_to(hint = nil, &route)
|
||||
if hint.nil? && route.respond_to?(:to_ruby)
|
||||
hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
|
||||
end
|
||||
it "should redirect to #{(hint || route)}" do
|
||||
eval_request
|
||||
response.should redirect_to(instance_eval(&route))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def it_should_assign_instance_variable(name, value)
|
||||
expectation_proc = case value
|
||||
when :nil
|
||||
proc { assigns[name].should be_nil }
|
||||
when :not_nil
|
||||
proc { assigns[name].should_not be_nil }
|
||||
when :undefined
|
||||
proc { controller.send(:instance_variables).should_not include("@{name}") }
|
||||
when Symbol
|
||||
if (instance_variable = instance_variable_get("@#{name}")).nil?
|
||||
proc { assigns[name].should_not be_nil }
|
||||
else
|
||||
proc { assigns[name].should == instance_variable }
|
||||
end
|
||||
else
|
||||
proc { assigns[name].should == value }
|
||||
end
|
||||
it "should #{value == :nil ? 'not ' : ''}assign @#{name}" do
|
||||
eval_request
|
||||
instance_eval &expectation_proc
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
199
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_stub_helpers.rb
vendored
Normal file
199
vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_stub_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
module LuckySneaks # :nodoc:
|
||||
# These methods are designed to be used in your example <tt>before</tt> blocks to accomplish
|
||||
# a whole lot of functionality with just a tiny bit of effort. The methods which correspond
|
||||
# to the controller methods perform the most duties as they create the mock_model instances,
|
||||
# stub out all the necessary methods, and also create implicit requests to DRY up your spec
|
||||
# file even more. You are encouraged to use these methods to setup the basic calls for your
|
||||
# resources and only resort to the other methods when mocking and stubbing secondary objects
|
||||
# and calls.
|
||||
#
|
||||
# Both <tt>stub_create</tt> and <tt>stub_update</tt> benefit from having a <tt>valid_attributes</tt>
|
||||
# method defined at the top level of your example groups, ie the top-most "describe" block
|
||||
# of the spec file. If you did not generate your specs with <tt>skinny_scaffold</tt> or
|
||||
# <tt>skinny_resourceful</tt> generators, you can simply write a method like the following
|
||||
# for yourself:
|
||||
#
|
||||
# def valid_attributes
|
||||
# {
|
||||
# "foo" => "bar",
|
||||
# "baz" => "quux"
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# Note this method employs strings as both the key and values to best replicate the way
|
||||
# they are used in actual controllers where the params will come from a form.
|
||||
module ControllerStubHelpers
|
||||
# Stubs out <tt>find :all</tt> and returns a collection of <tt>mock_model</tt>
|
||||
# instances of that class. Accepts the following options:
|
||||
#
|
||||
# <b>:format</b>:: Format of the request. Used to only add <tt>to_xml</tt> and
|
||||
# <tt>to_json</tt> when actually needed.
|
||||
# <b>:size</b>:: Number of instances to return in the result. Default is 3.
|
||||
# <b>:stub</b>:: Additional methods to stub on the instances
|
||||
#
|
||||
# Any additional options will be passed as arguments to the class find.
|
||||
# You will want to make sure to pass those arguments to the <tt>it_should_find</tt> spec as well.
|
||||
def stub_find_all(klass, options = {})
|
||||
returning(Array.new(options[:size] || 3){mock_model(klass)}) do |collection|
|
||||
stub_out klass, options.delete(:stub)
|
||||
if format = options.delete(:format)
|
||||
stub_formatted collection, format
|
||||
params[:format] = format
|
||||
end
|
||||
if options.empty?
|
||||
klass.stub!(:find).with(:all).and_return(collection)
|
||||
else
|
||||
klass.stub!(:find).with(:all, options).and_return(collection)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_find_all</tt> but additionally defines an implicit request <tt>get :index</tt>.
|
||||
def stub_index(klass, options = {})
|
||||
define_implicit_request :index
|
||||
stub_find_all klass, options
|
||||
end
|
||||
|
||||
# Stubs out <tt>new</tt> method and returns a <tt>mock_model</tt> instance marked as a new record.
|
||||
# Accepts the following options:
|
||||
#
|
||||
# <b>:format</b>:: Format of the request. Used to only add <tt>to_xml</tt> and
|
||||
# <tt>to_json</tt> when actually needed.
|
||||
# <b>:stub</b>:: Additional methods to stub on the instances
|
||||
#
|
||||
# It also accepts some options used to stub out <tt>save</tt> with a specified <tt>true</tt>
|
||||
# or <tt>false</tt> but you should be using <tt>stub_create</tt> in that case.
|
||||
def stub_initialize(klass, options = {})
|
||||
returning mock_model(klass) do |member|
|
||||
stub_out member, options.delete(:stub)
|
||||
if format = options[:format]
|
||||
stub_formatted member, format
|
||||
params[:format] = format
|
||||
end
|
||||
klass.stub!(:new).and_return(member)
|
||||
if options[:stub_save]
|
||||
stub_ar_method member, :save, options[:return]
|
||||
klass.stub!(:new).with(params[options[:params]]).and_return(member)
|
||||
else
|
||||
member.stub!(:new_record?).and_return(true)
|
||||
member.stub!(:id).and_return(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_initialize</tt> which additionally defines an implicit request <tt>get :new</tt>.
|
||||
def stub_new(klass, options = {})
|
||||
define_implicit_request :new
|
||||
stub_initialize klass, options
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_initialize</tt> which additionally defines an implicit request <tt>post :create</tt>.
|
||||
#
|
||||
# <b>Note:</b> If <tt>stub_create<tt> is provided an optional <tt>:params</tt> hash
|
||||
# or the method <tt>valid_attributes</tt> is defined within its scope,
|
||||
# those params will be added to the example's <tt>params</tt> object. If <i>neither</i>
|
||||
# are provided an <tt>ArgumentError</tt> will be raised.
|
||||
def stub_create(klass, options = {})
|
||||
define_implicit_request :create
|
||||
if options[:params].nil?
|
||||
if self.respond_to?(:valid_attributes)
|
||||
params[klass.name.underscore.to_sym] = valid_attributes
|
||||
options[:params] = valid_attributes
|
||||
else
|
||||
error_message = "Params for creating #{klass} could not be determined. "
|
||||
error_message << "Please define valid_attributes method in the base 'describe' block "
|
||||
error_message << "or manually set params in the before block."
|
||||
raise ArgumentError, error_message
|
||||
end
|
||||
end
|
||||
stub_initialize klass, options.merge(:stub_save => true)
|
||||
end
|
||||
|
||||
# Stubs out <tt>find</tt> and returns a single <tt>mock_model</tt>
|
||||
# instances of that class. Accepts the following options:
|
||||
#
|
||||
# <b>:format</b>:: Format of the request. Used to only add <tt>to_xml</tt> and
|
||||
# <tt>to_json</tt> when actually needed.
|
||||
# <b>:stub</b>:: Additional methods to stub on the instances
|
||||
#
|
||||
# Any additional options will be passed as arguments to <tt>find</tt>.You will want
|
||||
# to make sure to pass those arguments to the <tt>it_should_find</tt> spec as well.
|
||||
#
|
||||
# <b>Note:</b> The option <tt>:stub_ar</tt> is used internally by <tt>stub_update</tt>
|
||||
# and <tt>stub_destroy</tt>. If you need to stub <tt>update_attributes</tt> or
|
||||
# <tt>destroy</tt> you should be using the aforementioned methods instead.
|
||||
def stub_find_one(klass, options = {})
|
||||
returning mock_model(klass) do |member|
|
||||
stub_out member, options.delete(:stub)
|
||||
if options[:format]
|
||||
stub_formatted member, options[:format]
|
||||
params[:format] = options[:format]
|
||||
end
|
||||
if options[:current_object]
|
||||
params[:id] = member.id
|
||||
if options[:stub_ar]
|
||||
stub_ar_method member, options[:stub_ar], options[:return]
|
||||
end
|
||||
end
|
||||
klass.stub!(:find).with(member.id.to_s).and_return(member)
|
||||
end
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_find_one</tt> which additionally defines an implicit request <tt>get :show</tt>.
|
||||
def stub_show(klass, options = {})
|
||||
define_implicit_request :show
|
||||
stub_find_one klass, options.merge(:current_object => true)
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_find_one</tt> which additionally defines an implicit request <tt>get :edit</tt>.
|
||||
def stub_edit(klass, options = {})
|
||||
define_implicit_request :edit
|
||||
stub_find_one klass, options.merge(:current_object => true)
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_find_one</tt> which additionally defines an implicit request <tt>put :update</tt>
|
||||
# and stubs out the <tt>update_attribute</tt> method on the instance as well.
|
||||
#
|
||||
# <b>Note:</b> If <tt>stub_update<tt> is provided an optional <tt>:params</tt> hash
|
||||
# or the method <tt>valid_attributes</tt> is defined within its scope,
|
||||
# those params will be added to the example's <tt>params</tt> object. If <i>neither</i>
|
||||
# are provided an <tt>ArgumentError</tt> will be raised.
|
||||
def stub_update(klass, options = {})
|
||||
define_implicit_request :update
|
||||
stub_find_one klass, options.merge(:current_object => true, :stub_ar => :update_attributes)
|
||||
end
|
||||
|
||||
# Alias for <tt>stub_find_one</tt> which additionally defines an implicit request <tt>delete :destroy</tt>
|
||||
# and stubs out the <tt>destroy</tt> method on the instance as well.
|
||||
def stub_destroy(klass, options = {})
|
||||
define_implicit_request :destroy
|
||||
stub_find_one klass, options.merge(:current_object => true, :stub_ar => :destroy)
|
||||
end
|
||||
|
||||
# Stubs <tt>to_xml</tt> or <tt>to_json</tt> respectively based on <tt>format</tt> argument.
|
||||
def stub_formatted(object, format)
|
||||
return unless format
|
||||
object.stub!("to_#{format}").and_return("#{object.class} formatted as #{format}")
|
||||
end
|
||||
|
||||
private
|
||||
# Stubs out multiple methods. You shouldn't be calling this yourself and if you do
|
||||
# you should be able to understand the code yourself, right?
|
||||
def stub_out(object, stubs = {})
|
||||
return if stubs.nil?
|
||||
stubs.each do |method, value|
|
||||
if value
|
||||
object.stub!(method).and_return(value)
|
||||
else
|
||||
object.stub!(method)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Stubs out ActiveRecord::Base methods like #save, #update_attributes, etc
|
||||
# that may be called on a found or instantiated mock_model instance.
|
||||
def stub_ar_method(object, method, return_value)
|
||||
object.stub!(method).and_return(return_value ? false : true)
|
||||
end
|
||||
end
|
||||
end
|
||||
326
vendor/plugins/skinny_spec/lib/lucky_sneaks/model_spec_helpers.rb
vendored
Normal file
326
vendor/plugins/skinny_spec/lib/lucky_sneaks/model_spec_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
$:.unshift File.join(File.dirname(__FILE__), "..")
|
||||
require "skinny_spec"
|
||||
|
||||
module LuckySneaks
|
||||
# These methods are designed to be used in your example [read: "it"] blocks
|
||||
# to make your model specs a little more DRY. You might also be interested
|
||||
# in checking out the example block [read: "describe"] level versions in of these
|
||||
# methods which can DRY things up even more:
|
||||
# LuckySneaks::ModelSpecHelpers::ExampleGroupLevelMethods
|
||||
#
|
||||
# <b>Note:</b> The validation matchers are only meant to be used for simple validation checking
|
||||
# not as a one-size-fits-all solution.
|
||||
module ModelSpecHelpers
|
||||
include LuckySneaks::CommonSpecHelpers
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ExampleGroupLevelMethods
|
||||
end
|
||||
|
||||
class AssociationMatcher # :nodoc:
|
||||
def initialize(associated, macro)
|
||||
@associated = associated
|
||||
@macro = macro
|
||||
@options = {}
|
||||
end
|
||||
|
||||
def matches?(main_model)
|
||||
unless main_model.respond_to?(:reflect_on_association)
|
||||
if main_model.class.respond_to?(:reflect_on_association)
|
||||
main_model = main_model.class
|
||||
else
|
||||
@not_model = main_model
|
||||
return false
|
||||
end
|
||||
end
|
||||
if @association = main_model.reflect_on_association(@associated)
|
||||
@options.all?{|k, v| @association.options[k] == v ||
|
||||
[@association.options[k]] == v} # Stupid to_a being obsoleted!
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message
|
||||
if @not_model
|
||||
" expected: #{@not_model} to be a subclass of ActiveRecord::Base class, but was not"
|
||||
elsif @association
|
||||
" expected: #{association_with(@options)}\n got: #{association_with(@association.options)}"
|
||||
else
|
||||
" expected: #{association_with(@options)}, but the association does not exist"
|
||||
end
|
||||
end
|
||||
|
||||
def negative_failure_message
|
||||
if @association
|
||||
" expected: #{association_with(@options)}\n got: #{association_with(@association.options)}"
|
||||
else
|
||||
" expected: #{association_with(@options)} to not occur but it does"
|
||||
end
|
||||
end
|
||||
|
||||
# The following public methods are chainable extensions on the main matcher
|
||||
# Examples:
|
||||
#
|
||||
# Foo.should have_many(:bars).through(:foobars).with_dependent(:destroy)
|
||||
# Bar.should belong_to(:baz).with_class_name("Unbaz")
|
||||
def through(through_model)
|
||||
@options[:through] = through_model
|
||||
self
|
||||
end
|
||||
|
||||
def and_includes(included_models)
|
||||
@options[:include] = included_models
|
||||
self
|
||||
end
|
||||
|
||||
def and_extends(*modules)
|
||||
@options[:extends] = modules
|
||||
self
|
||||
end
|
||||
|
||||
def with_counter_cache(counter_cache = false)
|
||||
if counter_cache
|
||||
@options[:counter_cache] = counter_cache
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def uniq(*irrelevant_args)
|
||||
@options[:uniq] = true
|
||||
self
|
||||
end
|
||||
alias and_is_unique uniq
|
||||
alias with_unique uniq
|
||||
|
||||
def polymorphic(*irrelevant_args)
|
||||
@options[:polymorphic] = true
|
||||
self
|
||||
end
|
||||
alias and_is_polymorphic polymorphic
|
||||
alias with_polymorphic polymorphic
|
||||
|
||||
def as(interface)
|
||||
@options[:as] = interface
|
||||
end
|
||||
|
||||
# Use this to just specify the options as a hash.
|
||||
# Note: It will completely override any previously set options
|
||||
def with_options(options = {})
|
||||
options.each{|k, v| @options[k] = v}
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
# Takes care of methods like with_dependent(:destroy)
|
||||
def method_missing(method_id, *args, &block)
|
||||
method_name = method_id.to_s
|
||||
if method_name =~ /^with_(.*)/
|
||||
@options[$1.to_sym] = args
|
||||
self
|
||||
else
|
||||
super method_id, *args, &block
|
||||
end
|
||||
end
|
||||
|
||||
def association_with(options)
|
||||
option_string = (options.nil? || options.empty?) ? "" : options.inspect
|
||||
unless option_string.blank?
|
||||
option_string.sub! /^\{(.*)\}$/, ', \1'
|
||||
option_string.gsub! /\=\>/, ' => '
|
||||
end
|
||||
"#{@macro} :#{@associated}#{option_string}"
|
||||
end
|
||||
end
|
||||
|
||||
# Creates matcher that checks if the receiver has a <tt>belongs_to</tt> association
|
||||
# with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def belong_to(model)
|
||||
AssociationMatcher.new model, :belongs_to
|
||||
end
|
||||
|
||||
# Creates matcher that checks if the receiver has a <tt>have_one</tt> association
|
||||
# with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def have_one(model)
|
||||
AssociationMatcher.new model, :has_one
|
||||
end
|
||||
|
||||
# Creates matcher that checks if the receiver has a <tt>have_many</tt> association
|
||||
# with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def have_many(models)
|
||||
AssociationMatcher.new models, :has_many
|
||||
end
|
||||
|
||||
# Creates matcher that checks if the receiver has a <tt>have_and_belong_to_many</tt> association
|
||||
# with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def have_and_belong_to_many(models)
|
||||
AssociationMatcher.new models, :has_and_belongs_to_many
|
||||
end
|
||||
|
||||
private
|
||||
def class_or_instance
|
||||
@model_spec_class_or_instance ||= class_for(self.class.description_text) || instance
|
||||
end
|
||||
|
||||
def instance
|
||||
@model_spec_instance ||= instance_for(self.class.description_text)
|
||||
end
|
||||
|
||||
# These methods are designed to be used at the example group [read: "describe"] level
|
||||
# to simplify and DRY up common expectations. Most of these methods are wrappers for
|
||||
# matchers which can also be used on the example level [read: within an "it" block]. See
|
||||
# LuckySneaks::ModelSpecHelpers for more information.
|
||||
module ExampleGroupLevelMethods
|
||||
# Creates an expectation that the current model being spec'd has a <tt>belongs_to</tt>
|
||||
# association with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def it_should_belong_to(model)
|
||||
it "should belong to a #{model}" do
|
||||
class_or_instance.should belong_to(model)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd has a <tt>have_one</tt>
|
||||
# association with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def it_should_have_one(model)
|
||||
it "should have one #{model}" do
|
||||
class_or_instance.should have_one(model)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd has a <tt>have_many</tt>
|
||||
# association with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def it_should_have_many(models)
|
||||
it "should have many #{models}" do
|
||||
class_or_instance.should have_many(models)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd has a <tt>have_and_belong_to_many</tt>
|
||||
# association with the specified model.
|
||||
#
|
||||
# <b>Note:</b> The argument should be a symbol as in the model's association definition
|
||||
# and not the model's class name.
|
||||
def it_should_have_and_belong_to_many(models)
|
||||
it "should have and belong to many #{models}" do
|
||||
class_or_instance.should have_and_belong_to_many(models)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd <tt>validates_presence_of</tt>
|
||||
# the specified attribute. Takes an optional custom message to match the one in the model's
|
||||
# validation.
|
||||
def it_should_validate_presence_of(attribute, message = ActiveRecord::Errors.default_error_messages[:blank])
|
||||
it "should not be valid if #{attribute} is blank" do
|
||||
instance.send "#{attribute}=", nil
|
||||
instance.errors_on(attribute).should include(message)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd <tt>validates_numericality_of</tt>
|
||||
# the specified attribute. Takes an optional custom message to match the one in the model's
|
||||
# validation.
|
||||
def it_should_validate_numericality_of(attribute, message = ActiveRecord::Errors.default_error_messages[:not_a_number])
|
||||
it "should validate #{attribute} is a numeric" do
|
||||
instance.send "#{attribute}=", "NaN"
|
||||
instance.errors_on(attribute).should include(message)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd <tt>validates_confirmation_of</tt>
|
||||
# the specified attribute. Takes an optional custom message to match the one in the model's
|
||||
# validation.
|
||||
def it_should_validate_confirmation_of(attribute, message = ActiveRecord::Errors.default_error_messages[:confirmation])
|
||||
it "should validate confirmation of #{attribute}" do
|
||||
dummy_value = dummy_value_for(instance, attribute) || "try a string"
|
||||
instance.send "#{attribute}=", dummy_value
|
||||
instance.send "#{attribute}_confirmation=", dummy_value.succ
|
||||
instance.errors_on(attribute).should include(message)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd <tt>validates_uniqueness_of</tt>
|
||||
# the specified attribute. Takes an optional custom message to match the one in the model's
|
||||
# validation.
|
||||
#
|
||||
# <b>Note:</b> This method will fail completely if <tt>valid_attributes</tt>
|
||||
# does not provide all the attributes needed to create a valid record.
|
||||
def it_should_validate_uniqueness_of(attribute, message = ActiveRecord::Errors.default_error_messages[:taken])
|
||||
it "should validate #{attribute} confirmation" do
|
||||
previous_instance = class_for(self.class.description_text).create!(valid_attributes)
|
||||
instance.attributes = valid_attributes
|
||||
instance.errors_on(attribute).should include(message)
|
||||
previous_instance.destroy
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd accepts the specified values as
|
||||
# valid for the specified attribute. This is most likely used with <tt>validates_format_of</tt>
|
||||
# but there's nothing saying it couldn't be another validation.
|
||||
def it_should_accept_as_valid(attribute, *values)
|
||||
values.each do |value|
|
||||
value_inspect = case value
|
||||
when String : "'#{value}'"
|
||||
when NilClass : "nil"
|
||||
else value
|
||||
end
|
||||
it "should accept #{value_inspect} as a valid #{attribute}" do
|
||||
instance.send "#{attribute}=", value
|
||||
instance.errors_on(attribute).should == []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the current model being spec'd does not accept the specified
|
||||
# values as valid for the specified attribute. This is most likely used with
|
||||
# <tt>validates_format_of</tt> but there's nothing saying it couldn't be another validation.
|
||||
# Takes an optional argument <tt>:message => "some custom error messsage"</tt> for
|
||||
# spec'ing the actual error message.
|
||||
def it_should_not_accept_as_valid(attribute, *values)
|
||||
options = values.extract_options!
|
||||
values.each do |value|
|
||||
value_inspect = case value
|
||||
when String : "'#{value}'"
|
||||
when NilClass : "nil"
|
||||
else value
|
||||
end
|
||||
it "should not accept #{value_inspect} as a valid #{attribute}" do
|
||||
instance.send "#{attribute}=", value
|
||||
if options[:message]
|
||||
instance.errors_on(attribute).should include(options[:message])
|
||||
else
|
||||
instance.should have_at_least(1).errors_on(attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# Creates an expectation that the current model being spec'd doesn't allow mass-assignment
|
||||
# of the specified attribute.
|
||||
def it_should_not_mass_assign(attribute)
|
||||
it "should not allow mass-assignment of #{attribute}" do
|
||||
lambda {
|
||||
instance.send :attributes=, {attribute => dummy_value_for(instance, attribute)}
|
||||
}.should_not change(instance, attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
460
vendor/plugins/skinny_spec/lib/lucky_sneaks/view_spec_helpers.rb
vendored
Normal file
460
vendor/plugins/skinny_spec/lib/lucky_sneaks/view_spec_helpers.rb
vendored
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
$:.unshift File.join(File.dirname(__FILE__), "..")
|
||||
require "skinny_spec"
|
||||
|
||||
module LuckySneaks
|
||||
# These methods are designed to be used in your example [read: "it"] blocks
|
||||
# to make your view specs less brittle and more DRY. You might also be interested
|
||||
# in checking out the example block [read: "describe"] level versions in of these
|
||||
# methods which can DRY things up even more:
|
||||
# LuckySneaks::ViewSpecHelpers::ExampleGroupLevelMethods
|
||||
module ViewSpecHelpers
|
||||
include LuckySneaks::CommonSpecHelpers
|
||||
include ActionController::PolymorphicRoutes
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ExampleGroupLevelMethods
|
||||
end
|
||||
|
||||
# Wraps a matcher that checks if the receiver contains a <tt>FORM</tt> element with
|
||||
# its <tt>action</tt> attribute set to the specified path.
|
||||
def submit_to(path)
|
||||
have_tag("form[action=#{path}]")
|
||||
end
|
||||
|
||||
# Wraps a matcher that checks is the receiver contains any of several form elements
|
||||
# that would return sufficient named parameters to allow editing of the specified
|
||||
# attribute on the specified instance. Example:
|
||||
#
|
||||
# response.should allow_editing(@foo, "bar")
|
||||
#
|
||||
# can be satisfied by any of the following HTML elements:
|
||||
#
|
||||
# <input name="foo[bar]" type="text" />
|
||||
# <input name="foo[bar]" type="checkbox" />
|
||||
# <input name="foo[bar_ids][]" type="checkbox" />
|
||||
# <select name="foo[bar]"></select>
|
||||
# <textarea name="foo[bar]"></textarea>
|
||||
def allow_editing(instance, attribute)
|
||||
instance_name = instance.class.name.underscore.downcase
|
||||
if instance.send(attribute).is_a?(Time)
|
||||
have_tag(
|
||||
"input[name='#{instance_name}[#{attribute}]'],
|
||||
select[name=?]", /#{instance_name}\[#{attribute}\(.*\)\]/
|
||||
)
|
||||
else
|
||||
have_tag(
|
||||
"input[type='text'][name='#{instance_name}[#{attribute}]'],
|
||||
input[type='password'][name='#{instance_name}[#{attribute}]'],
|
||||
select[name='#{instance_name}[#{attribute}]'],
|
||||
textarea[name='#{instance_name}[#{attribute}]'],
|
||||
input[type='checkbox'][name='#{instance_name}[#{attribute}]'],
|
||||
input[type='checkbox'][name='#{instance_name}[#{attribute.to_s.tableize.singularize}_ids][]']"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Wraps a matcher that checks if the receiver contains an <tt>A</tt> element (link)
|
||||
# whose <tt>href</tt> attribute is set to the specified path or a <tt>FORM</tt>
|
||||
# element whose <tt>action</tt> attribute is set to the specified path.
|
||||
def have_link_or_button_to(path)
|
||||
have_tag(
|
||||
"a[href='#{path}'],
|
||||
form[action='#{path}'] input,
|
||||
form[action='#{path}'] button"
|
||||
)
|
||||
end
|
||||
alias have_link_to have_link_or_button_to
|
||||
alias have_button_to have_link_or_button_to
|
||||
|
||||
# Wraps <tt>have_link_or_button_to new_polymorphic_path<tt> for the specified class which
|
||||
# corresponds with the <tt>new</tt> method of the controller.
|
||||
#
|
||||
# <b>Note:</b> This method may takes a string or symbol representing the model's name
|
||||
# to send to <tt>have_link_or_button_to_show</tt> or the model's name itself.
|
||||
def have_link_or_button_to_new(name)
|
||||
have_link_or_button_to new_polymorphic_path(name.is_a?(ActiveRecord::Base) ? name : class_for(name))
|
||||
end
|
||||
|
||||
# Wraps <tt>have_link_or_button_to polymorphic_path(instance)<tt> which
|
||||
# corresponds with the <tt>show</tt> method of the controller.
|
||||
def have_link_or_button_to_show(instance)
|
||||
have_link_or_button_to polymorphic_path(instance)
|
||||
end
|
||||
alias have_link_to_show have_link_or_button_to_show
|
||||
alias have_button_to_show have_link_or_button_to_show
|
||||
|
||||
# Wraps <tt>have_link_or_button_to edit_polymorphic_path(instance)<tt> which
|
||||
# corresponds with the <tt>edit</tt> method of the controller.
|
||||
def have_link_or_button_to_edit(instance)
|
||||
have_link_or_button_to edit_polymorphic_path(instance)
|
||||
end
|
||||
alias have_link_to_edit have_link_or_button_to_edit
|
||||
alias have_button_to_edit have_link_or_button_to_edit
|
||||
|
||||
# Wraps a matcher that checks if the receiver contains the HTML created by Rails'
|
||||
# <tt>button_to</tt> helper: to wit, a <tt>FORM</tt> element whose <tt>action</tt>
|
||||
# attribute is pointed at the <tt>polymorphic_path</tt> of the instance
|
||||
# and contains an <tt>INPUT</tt> named "_method" with a value of "delete".
|
||||
def have_button_to_delete(instance)
|
||||
path = polymorphic_path(instance)
|
||||
have_tag(
|
||||
"form[action='#{path}'] input[name='_method'][value='delete'] + input,
|
||||
form[action='#{path}'] input[name='_method'][value='delete'] + button"
|
||||
)
|
||||
end
|
||||
|
||||
# Creates a <tt>mock_model</tt> instance and adds it to the <tt>assigns</tt> collection
|
||||
# using either the name passed as the first argument or the underscore version
|
||||
# of its class name. Accepts optional arguments to stub out additional methods
|
||||
# (and their return values) on the <tt>mock_model</tt> instance. Example:
|
||||
#
|
||||
# mock_and_assign(Foo, :stub => {:bar => "bar"})
|
||||
#
|
||||
# is the same as running <tt>assigns[:foo] = mock_model(Foo, :bar => "bar")</tt>.
|
||||
#
|
||||
# mock_and_assign(Foo, "special_foo", :stub => {:bar => "baz"})
|
||||
#
|
||||
# is the same as running <tt>assigns[:special_foo] = mock_model(Foo, :bar => "baz").
|
||||
#
|
||||
# <b>Note:</b> Adding to the assigns collection returns the object added, so this can
|
||||
# be chained a la <tt>@foo = mock_and_assign(Foo)</tt>.
|
||||
def mock_and_assign(klass, *args)
|
||||
options = args.extract_options!
|
||||
mocked = if options[:stub]
|
||||
mock_model(klass, options[:stub])
|
||||
else
|
||||
mock_model(klass)
|
||||
end
|
||||
yield mocked if block_given?
|
||||
self.assigns[args.first || "#{klass}".underscore] = mocked
|
||||
end
|
||||
|
||||
# Creates an array of <tt>mock_model</tt> instances in the manner of
|
||||
# <tt>mock_and_assign</tt>. Accepts <tt>option[:size]</tt> which sets the size
|
||||
# of the array (default is 3).
|
||||
def mock_and_assign_collection(klass, *args)
|
||||
options = args.dup.extract_options!
|
||||
return_me = Array.new(options[:size] || 3) do
|
||||
mocked = if options[:stub]
|
||||
mock_model(klass, options[:stub])
|
||||
else
|
||||
mock_model(klass)
|
||||
end
|
||||
yield mocked if block_given?
|
||||
mocked
|
||||
end
|
||||
self.assigns[args.first || "#{klass}".tableize] = return_me
|
||||
end
|
||||
|
||||
private
|
||||
def do_render
|
||||
if @the_template
|
||||
render @the_template
|
||||
elsif File.exists?(File.join(RAILS_ROOT, "app/views", self.class.description_text))
|
||||
render self.class.description_text
|
||||
else
|
||||
error_message = "Cannot determine template for render. "
|
||||
error_message << "Please define @the_template in the before block "
|
||||
error_message << "or name your describe block so that it indicates the correct template."
|
||||
raise NameError, error_message
|
||||
end
|
||||
end
|
||||
|
||||
# These methods are designed to be used at the example group [read: "describe"] level
|
||||
# to simplify and DRY up common expectations. Most of these methods are wrappers for
|
||||
# matchers which can also be used on the example level [read: within an "it" block]. See
|
||||
# LuckySneaks::ViewSpecHelpers for more information.
|
||||
module ExampleGroupLevelMethods
|
||||
include LuckySneaks::CommonSpecHelpers
|
||||
|
||||
# Creates an expectation which calls <tt>submit_to</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a Proc to evaluate the route not simply a named route
|
||||
# helper, which would be undefined in the scope of the example block.
|
||||
def it_should_submit_to(hint = nil, &route)
|
||||
if hint.nil? && route.respond_to?(:to_ruby)
|
||||
hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
|
||||
end
|
||||
it "should submit to #{(hint || route)}" do
|
||||
do_render
|
||||
response.should submit_to(instance_eval(&route))
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the template uses Rails' <tt>form_for</tt> to generate
|
||||
# the proper form action and method to create or update the specified object.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name to create the expectation for <tt>form_for</tt>
|
||||
# not an instance variable, which would be nil in the scope of the example block.
|
||||
# If you use namespacing for your <tt>form_for</tt>, you'll have to manually write out
|
||||
# a similar spec.
|
||||
def it_should_have_form_for(name)
|
||||
it "should have a form_for(@#{name})" do
|
||||
template.should_receive(:form_for).with(instance_for(name))
|
||||
do_render
|
||||
end
|
||||
end
|
||||
|
||||
# Negative version of <tt>it_should_have_form_for</tt>. See that method for more
|
||||
# details.
|
||||
def it_should_not_have_form_for(name)
|
||||
it "should not have a form_for(@#{name})" do
|
||||
template.should_not_receive(:form_for).with(instance_for(name))
|
||||
do_render
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation which calls <tt>allow_editing</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name to send to <tt>allow_editing</tt>
|
||||
# not an instance variable, which would be nil in the scope of the example block.
|
||||
def it_should_allow_editing(name, method)
|
||||
it "should allow editing of @#{name}##{method}" do
|
||||
do_render
|
||||
response.should allow_editing(instance_for(name), method)
|
||||
end
|
||||
end
|
||||
|
||||
# Negative version of <tt>it_should_allow_editing</tt>. See that method for more
|
||||
# details.
|
||||
def it_should_not_allow_editing(name, method)
|
||||
it "should not allow editing of @#{name}##{method}" do
|
||||
do_render
|
||||
response.should_not allow_editing(instance_for(name), method)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation that the rendered template contains a <tt>FORM</tt> element
|
||||
# (<tt>INPUT</tt>, <tt>TEXTAREA</tt>, or <tt>SELECT</tt>) with the specified name.
|
||||
def it_should_have_form_element_for(name)
|
||||
it "should have a form element named '#{name}'" do
|
||||
do_render
|
||||
response.should have_tag(
|
||||
"form input[name='#{name}'],
|
||||
form textarea[name='#{name}'],
|
||||
form select[name='#{name}']"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Negative version of <tt>it_should_have_form_element_for</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_have_form_element_for(name)
|
||||
it "should not have a form element named '#{name}'" do
|
||||
do_render
|
||||
response.should_not have_tag(
|
||||
"form input[name='#{name}'],
|
||||
form textarea[name='#{name}'],
|
||||
form select[name='#{name}']"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a block to evaluate the route in the example context
|
||||
# instead of the example group context.
|
||||
def it_should_link_to(hint = nil, &route)
|
||||
if hint.nil? && route.respond_to?(:to_ruby)
|
||||
hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
|
||||
end
|
||||
it "should have a link/button to #{(hint || route)}" do
|
||||
do_render
|
||||
response.should have_link_or_button_to(instance_eval(&route))
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to it_should_link_to
|
||||
alias it_should_have_button_to it_should_link_to
|
||||
alias it_should_have_button_or_link_to it_should_link_to
|
||||
|
||||
# Negative version of <tt>it_should_link_to</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_link_to(hint = nil, &route)
|
||||
if hint.nil? && route.respond_to?(:to_ruby)
|
||||
hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
|
||||
end
|
||||
it "should have a link/button to #{(hint || route)}" do
|
||||
do_render
|
||||
response.should_not have_link_or_button_to(instance_eval(&route))
|
||||
end
|
||||
end
|
||||
alias it_should_not_have_link_to it_should_not_link_to
|
||||
alias it_should_not_have_button_to it_should_not_link_to
|
||||
alias it_should_not_have_button_or_link_to it_should_not_link_to
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_new</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method may takes a string or symbol representing the model's name
|
||||
# to send to <tt>have_link_or_button_to_show</tt> or the model's name itself.
|
||||
def it_should_link_to_new(name)
|
||||
it "should have a link/button to create a new #{name}" do
|
||||
do_render
|
||||
response.should have_link_or_button_to_new(name)
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_new it_should_link_to_new
|
||||
alias it_should_have_button_to_new it_should_link_to_new
|
||||
alias it_should_have_button_or_link_to_new it_should_link_to_new
|
||||
|
||||
# Negative version of <tt>it_should_link_to_show</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_link_to_new(name)
|
||||
it "should have a link/button to create a new #{name}" do
|
||||
do_render
|
||||
response.should_not have_link_or_button_to_new(name)
|
||||
end
|
||||
end
|
||||
alias it_should_not_have_link_to_new it_should_not_link_to_new
|
||||
alias it_should_not_have_button_to_new it_should_not_link_to_new
|
||||
alias it_should_not_have_button_or_link_to_new it_should_not_link_to_new
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_show</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name to send to <tt>have_link_or_button_to_show</tt>
|
||||
# not an instance variable, which would be nil in the scope of the example block.
|
||||
def it_should_link_to_show(name)
|
||||
it "should have a link/button to show @#{name}" do
|
||||
do_render
|
||||
response.should have_link_or_button_to_show(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_show it_should_link_to_show
|
||||
alias it_should_have_button_to_show it_should_link_to_show
|
||||
alias it_should_have_button_or_link_to_show it_should_link_to_show
|
||||
|
||||
# Negative version of <tt>it_should_link_to_show</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_link_to_show(name)
|
||||
it "should have a link/button to show @#{name}" do
|
||||
do_render
|
||||
response.should_not have_link_or_button_to_show(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_not_have_link_to_show it_should_not_link_to_show
|
||||
alias it_should_not_have_button_to_show it_should_not_link_to_show
|
||||
alias it_should_not_have_button_or_link_to_show it_should_not_link_to_show
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_show</tt>
|
||||
# for each member of the instance variable matching the specified name
|
||||
# on the response from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name and not an instance variable, which would be nil
|
||||
# in the scope of the example block.
|
||||
def it_should_link_to_show_each(name)
|
||||
it "should have a link/button to show each member of @#{name}" do
|
||||
do_render
|
||||
instance_for(name).each do |member|
|
||||
response.should have_link_or_button_to_show(member)
|
||||
end
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_show_each it_should_link_to_show_each
|
||||
alias it_should_have_button_to_show_each it_should_link_to_show_each
|
||||
alias it_should_have_button_or_link_to_show_each it_should_link_to_show_each
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_edit</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name to send to <tt>have_link_or_button_to_edit</tt>
|
||||
# not an instance variable, which would be nil in the scope of the example block.
|
||||
def it_should_link_to_edit(name)
|
||||
it "should have a link/button to edit @#{name}" do
|
||||
do_render
|
||||
response.should have_link_or_button_to_edit(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_edit it_should_link_to_edit
|
||||
alias it_should_have_button_to_edit it_should_link_to_edit
|
||||
alias it_should_have_button_or_link_to_edit it_should_link_to_edit
|
||||
|
||||
# Negative version of <tt>it_should_link_to_edit</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_link_to_edit(name)
|
||||
it "should have a link/button to edit @#{name}" do
|
||||
do_render
|
||||
response.should_not have_link_or_button_to_edit(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_not_have_link_to_edit it_should_not_link_to_edit
|
||||
alias it_should_not_have_button_to_edit it_should_not_link_to_edit
|
||||
alias it_should_not_have_button_or_link_to_edit it_should_not_link_to_edit
|
||||
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_edit</tt>
|
||||
# for each member of the instance variable matching the specified name
|
||||
# on the response from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name and not an instance variable, which would be nil
|
||||
# in the scope of the example block.
|
||||
def it_should_link_to_edit_each(name)
|
||||
it "should have a link/button to edit each member of @#{name}" do
|
||||
do_render
|
||||
instance_for(name).each do |member|
|
||||
response.should have_link_or_button_to_edit(member)
|
||||
end
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_edit_each it_should_link_to_edit_each
|
||||
alias it_should_have_button_to_edit_each it_should_link_to_edit_each
|
||||
alias it_should_have_button_or_link_to_edit_each it_should_link_to_edit_each
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_delete</tt> on the response
|
||||
# from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name to send to <tt>have_link_or_button_to_delete</tt>
|
||||
# not an instance variable, which would be nil in the scope of the example block.
|
||||
def it_should_link_to_delete(name)
|
||||
it "should have a link/button to delete @#{name}" do
|
||||
do_render
|
||||
response.should have_button_to_delete(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_delete it_should_link_to_delete
|
||||
alias it_should_have_button_to_delete it_should_link_to_delete
|
||||
alias it_should_have_button_or_link_to_delete it_should_link_to_delete
|
||||
|
||||
# Negative version of <tt>it_should_link_to_delete</tt>. See that method
|
||||
# for more details.
|
||||
def it_should_not_link_to_delete(name)
|
||||
it "should not have a link/button to delete @#{name}" do
|
||||
do_render
|
||||
response.should_not have_button_to_delete(instance_for(name))
|
||||
end
|
||||
end
|
||||
alias it_should_not_have_link_to_delete it_should_not_link_to_delete
|
||||
alias it_should_not_have_button_to_delete it_should_not_link_to_delete
|
||||
alias it_should_not_have_button_or_link_to_delete it_should_not_link_to_delete
|
||||
|
||||
# Creates an expectation which calls <tt>have_link_or_button_to_delete</tt>
|
||||
# for each member of the instance variable matching the specified name
|
||||
# on the response from rendering the template. See that method for more details.
|
||||
#
|
||||
# <b>Note:</b> This method takes a string or symbol representing the instance
|
||||
# variable's name and not an instance variable, which would be nil
|
||||
# in the scope of the example block.
|
||||
def it_should_link_to_delete_each(name)
|
||||
it "should have a link/button to delete each member of @#{name}" do
|
||||
do_render
|
||||
instance_for(name).each do |member|
|
||||
response.should have_button_to_delete(member)
|
||||
end
|
||||
end
|
||||
end
|
||||
alias it_should_have_link_to_delete_each it_should_link_to_delete_each
|
||||
alias it_should_have_button_to_delete_each it_should_link_to_delete_each
|
||||
alias it_should_have_button_or_link_to_delete_each it_should_link_to_delete_each
|
||||
end
|
||||
end
|
||||
end
|
||||
26
vendor/plugins/skinny_spec/lib/skinny_spec.rb
vendored
Normal file
26
vendor/plugins/skinny_spec/lib/skinny_spec.rb
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Let's make sure everyone else is loaded
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
||||
require 'spec'
|
||||
require 'spec/rails'
|
||||
begin
|
||||
require 'ruby2ruby'
|
||||
rescue
|
||||
puts "-----"
|
||||
puts "Attention: skinny_spec requires ruby2ruby for nicer route descriptions"
|
||||
puts "It is highly recommended that you install it: sudo gem install ruby2ruby"
|
||||
puts "-----"
|
||||
end
|
||||
|
||||
# Let's load our family now
|
||||
require "lucky_sneaks/common_spec_helpers"
|
||||
require "lucky_sneaks/controller_request_helpers"
|
||||
require "lucky_sneaks/controller_spec_helpers"
|
||||
require "lucky_sneaks/controller_stub_helpers"
|
||||
require "lucky_sneaks/model_spec_helpers"
|
||||
require "lucky_sneaks/view_spec_helpers"
|
||||
|
||||
# Let's all come together
|
||||
Spec::Rails::Example::ViewExampleGroup.send :include, LuckySneaks::ViewSpecHelpers
|
||||
Spec::Rails::Example::HelperExampleGroup.send :include, LuckySneaks::CommonSpecHelpers
|
||||
Spec::Rails::Example::ControllerExampleGroup.send :include, LuckySneaks::ControllerSpecHelpers
|
||||
Spec::Rails::Example::ModelExampleGroup.send :include, LuckySneaks::ModelSpecHelpers
|
||||
Loading…
Add table
Add a link
Reference in a new issue