<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/view_stub_helpers.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -39,12 +39,6 @@ specs) to see what's new and different with Skinny Spec.
 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 &quot;GET :index&quot; do
       before(:each) do
         @users = stub_index(User)
@@ -68,12 +62,7 @@ Let's look at the controller specs.
     
     # ...
 
-First thing you should see is a method definition for 
-&lt;tt&gt;valid_attributes&lt;/tt&gt;. This will be used later by the &lt;tt&gt;create&lt;/tt&gt; and &lt;tt&gt;update&lt;/tt&gt;
-specs to more accurately represent how the controller works in actual practice by supplying
-somewhat real data for the &lt;tt&gt;params&lt;/tt&gt; coming from the HTML forms.
-
-Next we find an example group for &lt;tt&gt;GET :index&lt;/tt&gt;. That &lt;tt&gt;stub_index&lt;/tt&gt; method there
+First thing you should see is an example group for &lt;tt&gt;GET :index&lt;/tt&gt;. That &lt;tt&gt;stub_index&lt;/tt&gt; 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 &lt;tt&gt;stub_new&lt;/tt&gt;) but I will point out that the
 methods named &lt;tt&gt;stub_&lt;i&gt;controller_method&lt;/i&gt;&lt;/tt&gt; should only be used for stubbing and
@@ -82,8 +71,16 @@ use &lt;tt&gt;stub_find_all&lt;/tt&gt;, &lt;tt&gt;stub_find_one&lt;/tt&gt;, and &lt;tt&gt;stub_initialize&lt;/tt&gt;
 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 &lt;tt&gt;define_request&lt;/tt&gt; in those example groups to define an explicit
-request. You can also define a method called &lt;tt&gt;shared_request&lt;/tt&gt; to &quot;share a
-&lt;tt&gt;define_request&lt;/tt&gt;&quot; across shared describe blocks, like so:
+request, like so:
+
+  describe &quot;PUT :demote&quot; do
+    define_request { put :demote }
+    
+    # ...
+  end
+
+You can also define a method called &lt;tt&gt;shared_request&lt;/tt&gt; to &quot;share&quot; a
+&lt;tt&gt;define_request&lt;/tt&gt; across nested describe blocks, like so:
 
   describe &quot;POST :create&quot; do
     def shared_request
@@ -100,16 +97,22 @@ request. You can also define a method called &lt;tt&gt;shared_request&lt;/tt&gt; to &quot;share a
   end
   
 Note: When you're adding longer, more complicated controller specs you can still leverage
-implicit and shared requests by calling &lt;tt&gt;do_request&lt;/tt&gt; in your spec as in the following
+implicit and explicit requests by calling &lt;tt&gt;do_request&lt;/tt&gt; in your spec as in the following
 example:
 
-  # Let's assume this controller is _not_ CategoriesController
+  # Note this controller is UsersController and _not_ CategoriesController
   # and that loading the categories isn't part of the default actions
-  describe &quot;GET :index&quot; do
+  # and cannot use the &lt;tt&gt;stub_&lt;i&gt;controller_method&lt;/i&gt;&lt;/tt&gt; helpers
+  # [which create implicit requests based on the controller method in the name]
+  # but uses &lt;tt&gt;stub_find_all&lt;/tt&gt; instead
+  describe &quot;GET :new&quot; do
     before(:each) do
+      @user = stub_new(User)
       @categories = stub_find_all(Category)
     end
     
+    # ...
+    
     it &quot;should preload categories&quot; do
       Category.should_receive(:find).with(:all)
       do_request
@@ -264,4 +267,4 @@ rspec_on_rails_on_crack[http://github.com/technoweenie/rspec_on_rails_on_crack/t
 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.
\ No newline at end of file
+Also thanks to Don Petersen, Nicolas M&#233;rouze, Mikkel Malmberg, and Brandan Lennox for their suggestions and fixes.
\ No newline at end of file</diff>
      <filename>vendor/plugins/skinny_spec/README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -33,7 +33,7 @@ def button_to(name, options = {}, html_options = {})
 
   html_options.merge!(&quot;type&quot; =&gt; &quot;submit&quot;, &quot;value&quot; =&gt; name)
 
-  &quot;&lt;form method=\&quot;#{form_method}\&quot; action=\&quot;#{escape_once url}\&quot; class=\&quot;button_to\&quot;&gt;&lt;div&gt;&quot; +
+  &quot;&lt;form method=\&quot;#{form_method}\&quot; action=\&quot;#{escape_once url}\&quot; class=\&quot;button-to\&quot;&gt;&lt;div&gt;&quot; +
     method_tag + content_tag(&quot;button&quot;, name, html_options) + request_token_tag + &quot;&lt;/div&gt;&lt;/form&gt;&quot;
 end
 </diff>
      <filename>vendor/plugins/skinny_spec/additional/helper_overrides.txt</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,8 @@ class SkinnyScaffoldGenerator &lt; Rails::Generator::NamedBase
   alias_method :controller_singular_name, :controller_file_name
   alias_method :controller_table_name, :controller_plural_name
   
+  default_options :skip_migration =&gt; false
+  
   def initialize(runtime_args, runtime_options = {})
     super
     
@@ -86,6 +88,13 @@ protected
   def banner
     &quot;Usage: #{$0} skinny_scaffold ModelName [field:type, field:type]&quot;
   end
+  
+  def add_options!(opt)
+    opt.separator ''
+    opt.separator 'Options:'
+    opt.on(&quot;--skip-migration&quot;, 
+           &quot;Don't generate a migration file for this model&quot;) { |v| options[:skip_migration] = v }
+  end
 
   def model_name 
     class_name.demodulize</diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/skinny_scaffold_generator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,29 +1,6 @@
 require File.dirname(__FILE__) + '/../spec_helper'
 
 describe &lt;%= controller_class_name %&gt;Controller do
-  def valid_attributes(args = {})
-    {
-&lt;% if attributes.empty? -%&gt;
-      # Add valid attributes for the your params[:&lt;%= singular_name %&gt;] here!
-&lt;% else -%&gt;
-  &lt;%- attributes.each_with_index do |attribute, index| -%&gt;
-    &lt;%- case attribute.type -%&gt;
-      &lt;%- when :string, :text -%&gt;
-      &quot;&lt;%= attribute.name %&gt;&quot; =&gt; &quot;foo&quot;&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
-      &lt;%- when :integer, :float, :decimal -%&gt;
-      &quot;&lt;%= attribute.name %&gt;&quot; =&gt; 815&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
-      &lt;%- when :boolean -%&gt;
-      &quot;&lt;%= attribute.name %&gt;&quot; =&gt; false&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
-      &lt;%- when :date, :datetime, :time, :timestamp -%&gt;
-      &quot;&lt;%= attribute.name %&gt;&quot; =&gt; 1.week.ago&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
-      &lt;%- else -%&gt;
-      &quot;&lt;%= attribute.name %&gt;&quot; =&gt; nil&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt; # Could not determine valid attribute
-    &lt;%- end -%&gt;
-  &lt;%- end -%&gt;
-&lt;% end -%&gt;
-    }.merge(args)
-  end
-  
   describe &quot;GET :index&quot; do
     before(:each) do
       @&lt;%= plural_name %&gt; = stub_index(&lt;%= class_name %&gt;)</diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/controller_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,11 +5,10 @@ describe &quot;&lt;%= File.join(controller_class_path, controller_singular_name) %&gt;/form
     @&lt;%= singular_name %&gt; = mock_and_assign(&lt;%= model_name %&gt;, :stub =&gt; {
 &lt;% if attributes.blank? -%&gt;
       # Add your stub attributes and return values here like: 
-      # :name =&gt; &quot;Foo&quot;, :created_at =&gt; 1.week.ago, :updated_at =&gt; nil
+      # :name =&gt; &quot;Foo&quot;, :address =&gt; &quot;815 Oceanic Drive&quot;
 &lt;% else -%&gt;
   &lt;%- attributes.each_with_index do |attribute, index| -%&gt;
-    &lt;%- case attribute.type -%&gt;
-      &lt;%- when :string, :text -%&gt;
+    &lt;%- case attribute.type when :string, :text -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; &quot;foo&quot;&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
       &lt;%- when :integer, :float, :decimal -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; 815&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
@@ -21,7 +20,7 @@ describe &quot;&lt;%= File.join(controller_class_path, controller_singular_name) %&gt;/form
       :&lt;%= attribute.name %&gt; =&gt; nil&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt; # Could not determine valid attribute
     &lt;%- end -%&gt;
   &lt;%- end -%&gt;
-&lt;% end -%&gt;  
+&lt;% end -%&gt;
     })
   end
   </diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/form.html_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,11 +3,11 @@ require File.dirname(__FILE__) + '&lt;%= '/..' * controller_class_nesting_depth %&gt;/
 describe &quot;&lt;%= File.join(controller_class_path, controller_singular_name) %&gt;/index.html.&lt;%= template_language %&gt;&quot; do
   before(:each) do
     @&lt;%= plural_name %&gt; = mock_and_assign_collection(&lt;%= model_name %&gt;)
-    template.stub_render :partial =&gt; @&lt;%= plural_name %&gt;
+    template.stub! :render
   end
   
   it &quot;should render :partial =&gt; @&lt;%= plural_name %&gt;&quot; do
-    template.expect_render :partial =&gt; @&lt;%= plural_name %&gt;
+    template.should_receive(:render).with(:partial =&gt; @&lt;%= plural_name %&gt;)
     do_render
   end
   </diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index.html_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,8 +8,7 @@ describe &quot;&lt;%= File.join(controller_class_path, controller_singular_name) %&gt;/_&lt;%=
       # :name =&gt; &quot;Foo&quot;, :created_at =&gt; 1.week.ago, :updated_at =&gt; nil
 &lt;% else -%&gt;
   &lt;%- attributes.each_with_index do |attribute, index| -%&gt;
-    &lt;%- case attribute.type -%&gt;
-      &lt;%- when :string, :text -%&gt;
+    &lt;%- case attribute.type when :string, :text -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; &quot;foo&quot;&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
       &lt;%- when :integer, :float, :decimal -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; 815&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;</diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/index_partial.html_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,7 +12,7 @@ describe &lt;%= class_name %&gt; do
   end
   
   after(:each) do
-    @&lt;%= singular_name %&gt;.destroy unless @&lt;%= singular_name %&gt;.new_record?
+    @&lt;%= singular_name %&gt;.destroy
   end
   
   # Add your model specs here, please!</diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/model_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,8 +7,7 @@ describe &quot;&lt;%= File.join(controller_class_path, controller_singular_name) %&gt;/show
 &lt;% else -%&gt;
     @&lt;%= singular_name %&gt; = mock_and_assign(&lt;%= model_name %&gt;, :stub =&gt; {
   &lt;%- attributes.each_with_index do |attribute, index| -%&gt;
-    &lt;%- case attribute.type -%&gt;
-      &lt;%- when :string, :text -%&gt;
+    &lt;%- case attribute.type when :string, :text -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; &quot;foo&quot;&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;
       &lt;%- when :integer, :float, :decimal -%&gt;
       :&lt;%= attribute.name %&gt; =&gt; 815&lt;%= index &lt; attributes.size - 1 ? &quot;,&quot; : &quot;&quot; %&gt;</diff>
      <filename>vendor/plugins/skinny_spec/generators/skinny_scaffold/templates/show.html_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,13 +2,24 @@ 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
+    # Stubs out Time.now and returns value to use when comparing it. Example:
+    # 
+    #   time_now = stub_time_now
+    #   @foo.some_method_that_resets_updated_at
+    #   @foo.updated_at.should == time_now
+    def stub_time_now
+      returning Time.now do |now|
+        Time.stub!(:now).and_return(now)
+      end
+    end
+    
     # Returns class for the specified name. Example:
     # 
     #   class_for(&quot;foo&quot;) # =&gt; Foo
     def class_for(name)
       name.to_s.constantize
     rescue NameError
-      name.to_s.classify.constantize
+      name.to_s.pluralize.classify.constantize
       # Let any other error rise!
     end
 
@@ -42,5 +53,31 @@ module LuckySneaks
         end
       end
     end
+    
+    # Returns class description text
+    def class_description_text
+      if self.class.respond_to?(:description_text)
+        # Old school
+        self.class.description_text
+      else
+        # New school
+        self.class.description
+      end
+    end
+    
+    # Returns description text
+    def self_description_text
+      if respond_to?(:description_text)
+        # Old school
+        description_text
+      else
+        # New school
+        description
+      end
+    end
+    
+    def described_type
+      self.class.described_type
+    end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/common_spec_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,9 +27,9 @@ module LuckySneaks
     alias do_request eval_request
 
     def try_shared_request_definition
-      shared_request
-    rescue NameError
-      if @implicit_request
+      if defined?(shared_request) == &quot;method&quot;
+        shared_request
+      elsif @implicit_request
         try_implicit_request
       else
         error_message = &quot;Could not determine request definition for 'describe' context. &quot;
@@ -64,4 +64,4 @@ module LuckySneaks
       end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_request_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -41,28 +41,23 @@ module LuckySneaks
   private
     def create_ar_class_expectation(name, method, argument = nil, options = {})
       args = []
-      if [:create, :update].include?(@controller_method)
-        args &lt;&lt; (argument.nil? ? valid_attributes : argument)
-      else
+      unless options.delete(:only_method)
         args &lt;&lt; argument unless argument.nil?
+        args &lt;&lt; hash_including(options) unless options.empty?
       end
-      args &lt;&lt; options unless options.empty?
+      method = options.delete(:find_method) if options[:find_method]
       if args.empty?
-        return_value = class_for(name).send(method)
-        class_for(name).should_receive(method).and_return(return_value)
+        class_for(name).should_receive(method).and_return(instance_for(name))
       else
-        return_value = class_for(name).send(method, *args)
-        class_for(name).should_receive(method).with(*args).and_return(return_value)
+        class_for(name).should_receive(method).with(*args).and_return(instance_for(name))
       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
@@ -73,12 +68,14 @@ module LuckySneaks
       # Creates an expectation that the controller method calls &lt;tt&gt;ActiveRecord::Base.find&lt;/tt&gt;.
       # Examples:
       # 
-      #   it_should_find :foos                                 # =&gt; Foo.should_receive(:find).with(:all)
-      #   it_should_find :foos, :all                           # An explicit version of the above
-      #   it_should_find :foos, :conditions =&gt; {:foo =&gt; &quot;bar&quot;} # =&gt; Foo.should_receive(:find).with(:all, :conditions =&gt; {&quot;foo&quot; =&gt; &quot;bar&quot;}
-      #   it_should_find :foo                                  # =&gt; Foo.should_recieve(:find).with(@foo.id.to_s)
-      #   it_should_find :foo, :params =&gt; &quot;id&quot;                 # =&gt; Foo.should_receive(:find).with(params[:id].to_s)
-      #   it_should_find :foo, 2                               # =&gt; Foo.should_receive(:find).with(&quot;2&quot;)
+      #   it_should_find :foos                                      # =&gt; Foo.should_receive(:find).with(:all)
+      #   it_should_find :foos, :all                                # An explicit version of the above
+      #   it_should_find :foos, :conditions =&gt; {:foo =&gt; &quot;bar&quot;}      # =&gt; Foo.should_receive(:find).with(:all, :conditions =&gt; {&quot;foo&quot; =&gt; &quot;bar&quot;}
+      #   it_should_find :foos, &quot;joe&quot;, :method =&gt; :find_all_by_name # Foo.should_receive(:find_all_by_name).with(&quot;joe&quot;)
+      #   it_should_find :foo                                       # =&gt; Foo.should_recieve(:find).with(@foo.id.to_s)
+      #   it_should_find :foo, :params =&gt; &quot;id&quot;                      # =&gt; Foo.should_receive(:find).with(params[:id].to_s)
+      #   it_should_find :foo, 2                                    # =&gt; Foo.should_receive(:find).with(&quot;2&quot;)
+      #   it_should_find :foo, &quot;joe&quot;, :method =&gt; :find_by_name      # =&gt; Foo.should_recieve(:find_by_name).with(&quot;joe&quot;)
       # 
       # &lt;b&gt;Note:&lt;/b&gt; All params (key and value) will be strings if they come from a form element and are handled
       # internally with this expectation.
@@ -103,7 +100,27 @@ module LuckySneaks
               :all
             end
           end
-          create_ar_class_expectation name, :find, argument, options
+          find_method = options.delete(:method) || :find
+          create_ar_class_expectation name, find_method, argument, options
+          eval_request
+        end
+      end
+      
+      # Negative version of &lt;tt&gt;it_should_find&lt;/tt&gt;. This creates an expectation that
+      # the class never receives &lt;tt&gt;find&lt;/tt&gt; at all.
+      def it_should_not_find(name)
+        name_string = name.to_s
+        name_message = if name_string == name_string.singularize
+          &quot;a #{name}&quot;
+        else
+          name
+        end
+        it &quot;should not find #{name_message}&quot; do
+          if name_string == name_string.singularize
+            class_for(name).should_not_receive(:find)
+          else
+            class_for(name).should_not_receive(:find).with(:all)
+          end
           eval_request
         end
       end
@@ -121,6 +138,15 @@ module LuckySneaks
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_initialize&lt;/tt&gt;. This creates an expectation
+      # that the class never recieves &lt;tt&gt;new&lt;/tt&gt; at all.
+      def it_should_not_initialize(name)
+        it &quot;should initialize a #{name}&quot; do
+          class_for(name).should_not_receive(:new)
+          eval_request
+        end
+      end
+      
       # Creates an expectation that the controller method calls &lt;tt&gt;ActiveRecord::Base#save&lt;/tt&gt; on the
       # named instance. Example:
       #
@@ -136,6 +162,15 @@ module LuckySneaks
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_update&lt;/tt&gt;. This creates an expectation
+      # that the instance never receives &lt;tt&gt;save&lt;/tt&gt; at all.
+      def it_should_not_save(name)
+        it &quot;should not save the #{name}&quot; do
+          instance_for(name).should_not_receive(:save)
+          eval_request
+        end
+      end
+      
       # Creates an expectation that the controller method calls &lt;tt&gt;ActiveRecord::Base#update_attributes&lt;/tt&gt;
       # on the named instance. Takes optional argument for &lt;tt&gt;params&lt;/tt&gt; to specify in the
       # expectation. Examples:
@@ -148,7 +183,16 @@ module LuckySneaks
       # for the inevitable re-rendering of the form template.
       def it_should_update(name, options = {})
         it &quot;should update the #{name}&quot; do
-          create_positive_ar_instance_expectation name, :update_attributes, params[options[:params]]
+          create_positive_ar_instance_expectation name, :update_attributes, params[name]
+          eval_request
+        end
+      end
+      
+      # Negative version of &lt;tt&gt;it_should_update&lt;/tt&gt;. This creates an expectation
+      # that the instance never receives &lt;tt&gt;update_attributes&lt;/tt&gt; at all.
+      def it_should_not_update(name)
+        it &quot;should not update the #{name}&quot; do
+          instance_for(name).should_not_receive(:update_attributes)
           eval_request
         end
       end
@@ -168,6 +212,15 @@ module LuckySneaks
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_destroy&lt;/tt&gt;. This creates an expectation
+      # that the instance never receives &lt;tt&gt;destroy&lt;/tt&gt; at all.
+      def it_should_not_destroy(name)
+        it &quot;should not destroy the #{name}&quot; do
+          instance_for(name).should_not_receive(:destroy)
+          eval_request
+        end
+      end
+      
       # Creates expectation[s] that the controller method should assign the specified 
       # instance variables along with any specified values. Examples:
       # 
@@ -192,16 +245,36 @@ module LuckySneaks
         end
       end
       
+      # Essentially shorthand for &lt;tt&gt;it_should_assign name =&gt; :nil&lt;/tt&gt;. This method can take multiple
+      # instance variable names, creating this shorthand for each name. See the docs for
+      # &lt;tt&gt;it_should_assign&lt;/tt&gt; for more information.
+      def it_should_not_assign(*names)
+        names.each do |name|
+          # Assuming name is a symbol
+          it_should_assign name =&gt; :nil
+        end
+      end
+      
       # Wraps the separate expectations &lt;tt&gt;it_should_find&lt;/tt&gt; and &lt;tt&gt;it_should_assign&lt;/tt&gt;
       # 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_find name, :only_method =&gt; true
           it_should_assign name
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_find_and_assign&lt;/tt&gt;. This creates an
+      # expectation that the class never receives &lt;tt&gt;find&lt;/tt&gt; at all and that 
+      # no matching instance variable is ever created.
+      def it_should_not_find_and_assign(*names)
+        names.each do |name|
+          it_should_not_find name
+          it_should_assign name =&gt; :nil
+        end
+      end
+      
       # Wraps the separate expectations &lt;tt&gt;it_should_initialize&lt;/tt&gt; and &lt;tt&gt;it_should_assign&lt;/tt&gt;
       # 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.
@@ -212,11 +285,21 @@ module LuckySneaks
       # please use &lt;tt&gt;it_should_initialize_and_save&lt;/tt&gt;.
       def it_should_initialize_and_assign(*names)
         names.each do |name|
-          it_should_initialize name
+          it_should_initialize name, :only_method =&gt; true
           it_should_assign name
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_initialize_and_assign&lt;/tt&gt;. This creates an
+      # expectation that the class never receives &lt;tt&gt;new&lt;/tt&gt; at all and that 
+      # no matching instance variable is ever created.
+      def it_should_not_initialize_and_assign(*names)
+        names.each do |name|
+          it_should_not_initialize name
+          it_should_assign name =&gt; :nil
+        end
+      end
+      
       # Wraps the separate expectations &lt;tt&gt;it_should_initialize&lt;/tt&gt; and &lt;tt&gt;it_should_save&lt;/tt&gt;
       # 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.
@@ -226,7 +309,7 @@ module LuckySneaks
       # but not saved, just use &lt;tt&gt;it_should_initialize_and_assign&lt;/tt&gt;.
       def it_should_initialize_and_save(*names)
         names.each do |name|
-          it_should_initialize name
+          it_should_initialize name, :only_method =&gt; true
           it_should_save name
         end
       end
@@ -240,7 +323,7 @@ module LuckySneaks
       # instance is found but not saved, just use &lt;tt&gt;it_should_find_and_assign&lt;/tt&gt;.
       def it_should_find_and_update(*names)
         names.each do |name|
-          it_should_find name
+          it_should_find name, :only_method =&gt; true
           it_should_update name
         end
       end
@@ -250,16 +333,16 @@ module LuckySneaks
       # 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_find name, :only_method =&gt; true
           it_should_destroy name
         end
       end
 
-      # Creates an expectation that the specified collection (&lt;tt&gt;flash&lt;/tt&gt; or &lt;tt&gt;session&lt;/tt&gt;)
-      # contains the specified key and value. To specify that the collection should be set
-      # to &lt;tt&gt;nil&lt;/tt&gt;, specify the value as :nil instead.
+      # Creates an expectation that the specified collection (&lt;tt&gt;flash&lt;/tt&gt;, &lt;tt&gt;session&lt;/tt&gt;,
+      # &lt;tt&gt;params&lt;/tt&gt;, &lt;tt&gt;cookies&lt;/tt&gt;) contains the specified key and value. To specify that
+      # the collection should be set to &lt;tt&gt;nil&lt;/tt&gt;, specify the value as :nil instead.
       def it_should_set(collection, key, value = nil, &amp;block)
-        it &quot;should set #{collection}[:#{key}]&quot; do
+        it &quot;should set #{collection}[:#{key}]#{' with ' + value.inspect if value}&quot; do
           # Allow flash.now[:foo] to remain in the flash
           flash.stub!(:sweep) if collection == :flash
           eval_request
@@ -270,7 +353,7 @@ module LuckySneaks
               self.send(collection)[key].should == value
             end
           elsif block_given?
-            self.send(collection)[key].should == block.call
+            self.send(collection)[key].should == instance_eval(&amp;block)
           else
             self.send(collection)[key].should_not be_nil
           end
@@ -282,6 +365,11 @@ module LuckySneaks
       def it_should_set_flash(name, value = nil, &amp;block)
         it_should_set :flash, name, value, &amp;block
       end
+      
+      # Wraps &lt;tt&gt;it_should_set :flash, :nil&lt;/tt&gt;.
+      def it_should_not_set_flash(name)
+        it_should_set :flash, name, :nil
+      end
 
       # Wraps &lt;tt&gt;it_should_set :session&lt;/tt&gt;. To specify that the collection should be set
       # to &lt;tt&gt;nil&lt;/tt&gt;, specify the value as :nil instead.
@@ -289,6 +377,33 @@ module LuckySneaks
         it_should_set :session, name, value, &amp;block
       end
       
+      # Wraps &lt;tt&gt;it_should_set :session, :nil&lt;/tt&gt;.
+      def it_should_not_set_session(name)
+        it_should_set :session, name, :nil
+      end
+      
+      # Wraps &lt;tt&gt;it_should_set :params&lt;/tt&gt;. To specify that the collection should be set
+      # to &lt;tt&gt;nil&lt;/tt&gt;, specify the value as :nil instead.
+      def it_should_set_params(name, value = nil, &amp;block)
+        it_should_set :params, name, value, &amp;block
+      end
+      
+      # Wraps &lt;tt&gt;it_should_set :params, :nil&lt;/tt&gt;.
+      def it_should_not_set_params(name)
+        it_should_set :params, name, :nil
+      end
+      
+      # Wraps &lt;tt&gt;it_should_set :cookies&lt;/tt&gt;. To specify that the collection should be set
+      # to &lt;tt&gt;nil&lt;/tt&gt;, specify the value as :nil instead.
+      def it_should_set_cookies(name, value = nil, &amp;block)
+        it_should_set :cookies, name, value, &amp;block
+      end
+      
+      # Wraps &lt;tt&gt;it_should_set :cookies, :nil&lt;/tt&gt;.
+      def it_should_not_set_cookies(name)
+        it_should_set :cookies, name, :nil
+      end
+      
       # Wraps the various &lt;tt&gt;it_should_render_&lt;i&gt;foo&lt;/i&gt;&lt;/tt&gt; methods:
       # &lt;tt&gt;it_should_render_template&lt;/tt&gt;, &lt;tt&gt;it_should_render_partial&lt;/tt&gt;,
       # &lt;tt&gt;it_should_render_xml&lt;/tt&gt;, &lt;tt&gt;it_should_render_json&lt;/tt&gt;,
@@ -407,6 +522,27 @@ module LuckySneaks
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_redirect_to&lt;/tt&gt;.
+      def it_should_not_redirect_to(hint = nil, &amp;route)
+        if hint.nil? &amp;&amp; route.respond_to?(:to_ruby)
+          hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
+        end
+        it &quot;should not redirect to #{(hint || route)}&quot; do
+          eval_request
+          response.should_not redirect_to(instance_eval(&amp;route))
+        end
+      end
+      
+      # Creates an expectation that the controller method redirects back to the previous page
+      def it_should_redirect_to_referer
+        it &quot;should redirect to the referring page&quot; do
+          request.env[&quot;HTTP_REFERER&quot;] = &quot;http://test.host/referer&quot;
+          eval_request
+          response.should redirect_to(&quot;http://test.host/referer&quot;)
+        end
+      end
+      alias it_should_redirect_to_referrer it_should_redirect_to_referer
+      
     private
       def it_should_assign_instance_variable(name, value)
         expectation_proc = case value</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_spec_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,26 +6,13 @@ module LuckySneaks # :nodoc:
   # 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 &lt;tt&gt;stub_create&lt;/tt&gt; and &lt;tt&gt;stub_update&lt;/tt&gt; benefit from having a &lt;tt&gt;valid_attributes&lt;/tt&gt;
-  # method defined at the top level of your example groups, ie the top-most &quot;describe&quot; block
-  # of the spec file. If you did not generate your specs with &lt;tt&gt;skinny_scaffold&lt;/tt&gt; or
-  # &lt;tt&gt;skinny_resourceful&lt;/tt&gt; generators, you can simply write a method like the following
-  # for yourself:
-  # 
-  #   def valid_attributes
-  #     {
-  #       &quot;foo&quot; =&gt; &quot;bar&quot;,
-  #       &quot;baz&quot; =&gt; &quot;quux&quot;
-  #     }
-  #   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 &lt;tt&gt;find :all&lt;/tt&gt; and returns a collection of &lt;tt&gt;mock_model&lt;/tt&gt;
     # instances of that class. Accepts the following options:
     # 
+    # &lt;b&gt;:find_method&lt;/b&gt;:: Method to use as finder call. Default is &lt;tt&gt;:find&lt;/tt&gt;.
+    #                  &lt;b&gt;Note:&lt;/b&gt; When specifying the method, the call is stubbed
+    #                  to accept any arguments. Caveat programmer.
     # &lt;b&gt;:format&lt;/b&gt;:: Format of the request. Used to only add &lt;tt&gt;to_xml&lt;/tt&gt; and 
     #                  &lt;tt&gt;to_json&lt;/tt&gt; when actually needed.
     # &lt;b&gt;:size&lt;/b&gt;::   Number of instances to return in the result. Default is 3.
@@ -40,10 +27,13 @@ module LuckySneaks # :nodoc:
           stub_formatted collection, format
           params[:format] = format
         end
-        if options.empty?
-          klass.stub!(:find).with(:all).and_return(collection)
+        if find_method = options[:find_method]
+          # Not stubbing specific arguments here
+          # If you need more specificity, write a custom example
+          klass.stub!(find_method).and_return(collection)
         else
-          klass.stub!(:find).with(:all, options).and_return(collection)
+          klass.stub!(:find).with(:all).and_return(collection)
+          klass.stub!(:find).with(:all, hash_including(options)).and_return(collection)
         end
       end
     end
@@ -71,9 +61,11 @@ module LuckySneaks # :nodoc:
           params[:format] = format
         end
         klass.stub!(:new).and_return(member)
+        if options[:params]
+          klass.stub!(:new).with(hash_including(options[:params])).and_return(member)
+        end
         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)
@@ -89,32 +81,25 @@ module LuckySneaks # :nodoc:
     
     # Alias for &lt;tt&gt;stub_initialize&lt;/tt&gt; which additionally defines an implicit request &lt;tt&gt;post :create&lt;/tt&gt;.
     # 
-    # &lt;b&gt;Note:&lt;/b&gt; If &lt;tt&gt;stub_create&lt;tt&gt; is provided an optional &lt;tt&gt;:params&lt;/tt&gt; hash
-    # or the method &lt;tt&gt;valid_attributes&lt;/tt&gt; is defined within its scope,
-    # those params will be added to the example's &lt;tt&gt;params&lt;/tt&gt; object. If &lt;i&gt;neither&lt;/i&gt;
-    # are provided an &lt;tt&gt;ArgumentError&lt;/tt&gt; will be raised.
+    # &lt;b&gt;Note:&lt;/b&gt; If &lt;tt&gt;stub_create&lt;tt&gt; is provided an optional &lt;tt&gt;:params&lt;/tt&gt; hash,
+    # those params will be added to the example's &lt;tt&gt;params&lt;/tt&gt; object.
     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 = &quot;Params for creating #{klass} could not be determined. &quot;
-          error_message &lt;&lt; &quot;Please define valid_attributes method in the base 'describe' block &quot;
-          error_message &lt;&lt; &quot;or manually set params in the before block.&quot;
-          raise ArgumentError, error_message
-        end
-      end
+      class_name = klass.name.underscore
+      options[:params] ||= params[class_name]
       stub_initialize klass, options.merge(:stub_save =&gt; true)
     end
     
     # Stubs out &lt;tt&gt;find&lt;/tt&gt; and returns a single &lt;tt&gt;mock_model&lt;/tt&gt;
     # instances of that class. Accepts the following options:
     # 
-    # &lt;b&gt;:format&lt;/b&gt;::  Format of the request. Used to only add &lt;tt&gt;to_xml&lt;/tt&gt; and 
-    #                   &lt;tt&gt;to_json&lt;/tt&gt; when actually needed.
-    # &lt;b&gt;:stub&lt;/b&gt;::    Additional methods to stub on the instances
+    # &lt;b&gt;:find_method&lt;/b&gt;:: Method to use as finder call. Default is &lt;tt&gt;:find&lt;/tt&gt;.
+    # &lt;b&gt;:format&lt;/b&gt;:: Format of the request. Used to only add &lt;tt&gt;to_xml&lt;/tt&gt; and 
+    #                  &lt;tt&gt;to_json&lt;/tt&gt; when actually needed.
+    # &lt;b&gt;:stub&lt;/b&gt;::   Additional methods to stub on the instances
+    # &lt;b&gt;:current_object&lt;/b&gt;:: If set to true, &lt;tt&gt;find&lt;/tt&gt; will set &lt;tt&gt;params[:id]&lt;/tt&gt;
+    #                          using the &lt;tt&gt;id&lt;/tt&gt; of the &lt;tt&gt;mock_model&lt;/tt&gt; instance
+    #                          and use that value as an argument when stubbing &lt;tt&gt;find&lt;/tt&gt;
     # 
     # Any additional options will be passed as arguments to &lt;tt&gt;find&lt;/tt&gt;.You will want
     # to make sure to pass those arguments to the &lt;tt&gt;it_should_find&lt;/tt&gt; spec as well.
@@ -125,17 +110,55 @@ module LuckySneaks # :nodoc:
     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]
+        if format = options.delete(:format)
+          stub_formatted member, format
+          params[:format] = format
         end
-        if options[:current_object]
+        if options.delete(:current_object)
           params[:id] = member.id
-          if options[:stub_ar]
-            stub_ar_method member, options[:stub_ar], options[:return]
+          if ar_stub = options.delete(:stub_ar)
+            stub_ar_method member, ar_stub, options.delete(:return), options.delete(:update_params)
+          end
+        end
+        if find_method = options.delete(:find_method)
+          klass.stub!(find_method).and_return(member)
+        else
+          # Stubbing string and non-string just to be safe
+          klass.stub!(:find).with(member.id).and_return(member)
+          klass.stub!(:find).with(member.id.to_s).and_return(member)
+          unless options.empty?
+            klass.stub!(:find).with(member.id, hash_including(options)).and_return(member)
+            klass.stub!(:find).with(member.id.to_s, hash_including(options)).and_return(member)
           end
         end
-        klass.stub!(:find).with(member.id.to_s).and_return(member)
+      end
+    end
+    
+    # &lt;b&gt;Note:&lt;/b&gt; Use of this method with :child options (to mock
+    # association) is deprecated. Please use &lt;tt&gt;stub_association&lt;/tt&gt;.
+    # 
+    # Same as &lt;tt&gt;stub_find_one&lt;/tt&gt; but setups the instance as the parent
+    # of the specified association. Example:
+    # 
+    #   stub_parent(Document, :child =&gt; :comments)
+    # 
+    # This stubs &lt;tt&gt;Document.find&lt;/tt&gt;, &lt;tt&gt;@document.comments&lt;/tt&gt; (which
+    # will return &lt;tt&gt;Comment&lt;/tt&gt; class), as well as &lt;tt&gt;params[:document_id]&lt;/tt&gt;.
+    # This method is meant to be used in the controller for the specified child
+    # (&lt;tt&gt;CommentsController&lt;/tt&gt; in this instance) in situations like:
+    # 
+    #   def index
+    #     @document = Document.find(params[:document_id])
+    #     @comments = @document.comments.find(:all)
+    #   end
+    def stub_parent(klass, options = {})
+      returning stub_find_one(klass, options) do |member|
+        params[klass.name.foreign_key] = member.id
+        if offspring = options.delete(:child)
+          puts &quot;stub_parent with :child option has been marked for deprecation&quot;
+          puts &quot;please use stub_association to create the mock instead&quot;
+          member.stub!(offspring).and_return(class_for(offspring))
+        end
       end
     end
     
@@ -154,10 +177,8 @@ module LuckySneaks # :nodoc:
     # Alias for &lt;tt&gt;stub_find_one&lt;/tt&gt; which additionally defines an implicit request &lt;tt&gt;put :update&lt;/tt&gt;
     # and stubs out the &lt;tt&gt;update_attribute&lt;/tt&gt; method on the instance as well.
     # 
-    # &lt;b&gt;Note:&lt;/b&gt; If &lt;tt&gt;stub_update&lt;tt&gt; is provided an optional &lt;tt&gt;:params&lt;/tt&gt; hash
-    # or the method &lt;tt&gt;valid_attributes&lt;/tt&gt; is defined within its scope,
-    # those params will be added to the example's &lt;tt&gt;params&lt;/tt&gt; object. If &lt;i&gt;neither&lt;/i&gt;
-    # are provided an &lt;tt&gt;ArgumentError&lt;/tt&gt; will be raised.
+    # &lt;b&gt;Note:&lt;/b&gt; If &lt;tt&gt;stub_update&lt;tt&gt; is provided an optional &lt;tt&gt;:params&lt;/tt&gt; hash,
+    # those params will be added to the example's &lt;tt&gt;params&lt;/tt&gt; object.
     def stub_update(klass, options = {})
       define_implicit_request :update
       stub_find_one klass, options.merge(:current_object =&gt; true, :stub_ar =&gt; :update_attributes)
@@ -176,6 +197,20 @@ module LuckySneaks # :nodoc:
       object.stub!(&quot;to_#{format}&quot;).and_return(&quot;#{object.class} formatted as #{format}&quot;)
     end
     
+    # Creates a mock object representing an association proxy, stubs the appropriate 
+    # method on the parent object and returns that association proxy.
+    # Accepts the following option:
+    # 
+    # &lt;b&gt;:stub&lt;/b&gt;::   Additional methods to stub on the mock proxy object
+    def stub_association(object, association, options = {})
+      # I know options isn't implemented anywhere
+      object_name = instance_variables.select{|name| instance_variable_get(name) == object}
+      returning mock(&quot;Association proxy for #{object_name}.#{association}&quot;) do |proxy|
+        stub_out proxy, options[:stub] if options[:stub]
+        object.stub!(association).and_return(proxy)
+      end
+    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?
@@ -192,8 +227,12 @@ module LuckySneaks # :nodoc:
     
     # 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)
+    def stub_ar_method(object, method, return_value, params = {})
+      if params.blank?
+        object.stub!(method).and_return(return_value ? false : true)
+      else
+        object.stub!(method).with(hash_including(params)).and_return(return_value ? false : true)
+      end
     end
   end
 end</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/controller_stub_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,25 +6,51 @@ module LuckySneaks
   # to make your model specs a little more DRY. You might also be interested 
   # in checking out the example block [read: &quot;describe&quot;] level versions in of these
   # methods which can DRY things up even more:
-  # LuckySneaks::ModelSpecHelpers::ExampleGroupLevelMethods
+  # LuckySneaks::ModelSpecHelpers::ExampleGroupLevelMethods.
   # 
-  # &lt;b&gt;Note:&lt;/b&gt; The validation matchers are only meant to be used for simple validation checking
-  # not as a one-size-fits-all solution.
+  # Also check out the methods in LuckySneaks::ModelSpecHelpers::AssociationMatcher
+  # for some helpful matcher helper methods to use with these methods if you want to spec
+  # options on your association setups.
   module ModelSpecHelpers
     include LuckySneaks::CommonSpecHelpers
     
     def self.included(base) # :nodoc:
       base.extend ExampleGroupLevelMethods
     end
-  
-    class AssociationMatcher # :nodoc:
-      def initialize(associated, macro)
+    
+    # These methods cannot be used alone but are used in compliment with the association
+    # matchers in LuckySneaks::ModelSpecHelpers like &lt;tt&gt;have_many&lt;/tt&gt;. Example:
+    # 
+    #   describe User do
+    #     it &quot;should have many memberships&quot; do
+    #       User.should have_many(:memberships)
+    #     end
+    # 
+    #     it &quot;should have many sites through memberships&quot; do
+    #       User.should have_many(:sites).through(:memberships)
+    #     end
+    # 
+    #     it &quot;should belong to a manager&quot; do
+    #       User.should belong_to(:manager).with_counter_cache
+    #     end
+    #   end
+    # 
+    # &lt;b&gt;Note:&lt;/b&gt; To spec these sorts of options using the example block helpers like
+    # &lt;tt&gt;it_should_have_many&lt;/tt&gt;, just add them as options directly. This will use
+    # &lt;tt&gt;with_options&lt;/tt&gt; rather than any specific matcher helpers but will have the same
+    # effects. Example:
+    # 
+    #   describe User do
+    #     it_should_have_many :sites, :through =&gt; :memberships
+    #   end
+    class AssociationMatcher
+      def initialize(associated, macro) # :nodoc:
         @associated = associated
         @macro = macro
         @options = {}
       end
 
-      def matches?(main_model)
+      def matches?(main_model) # :nodoc:
         unless main_model.respond_to?(:reflect_on_association)
           if main_model.class.respond_to?(:reflect_on_association)
             main_model = main_model.class
@@ -39,7 +65,7 @@ module LuckySneaks
         end
       end
 
-      def failure_message
+      def failure_message # :nodoc:
         if @not_model
           &quot; expected: #{@not_model} to be a subclass of ActiveRecord::Base class, but was not&quot;
         elsif @association
@@ -49,7 +75,7 @@ module LuckySneaks
         end
       end
 
-      def negative_failure_message
+      def negative_failure_message # :nodoc:
         if @association
           &quot; expected: #{association_with(@options)}\n      got: #{association_with(@association.options)}&quot;
         else
@@ -77,7 +103,7 @@ module LuckySneaks
         self
       end
 
-      def with_counter_cache(counter_cache = false)
+      def with_counter_cache(counter_cache = true)
         if counter_cache
           @options[:counter_cache] = counter_cache
         end
@@ -169,86 +195,208 @@ module LuckySneaks
     
   private
     def class_or_instance
-      @model_spec_class_or_instance ||= class_for(self.class.description_text) || instance
+      @model_spec_class_or_instance ||= class_for(described_type) || instance
     end
     
     def instance
-      @model_spec_instance ||= instance_for(self.class.description_text)
+      @model_spec_instance ||= instance_for(described_type)
     end
     
     # These methods are designed to be used at the example group [read: &quot;describe&quot;] level
-    # to simplify and DRY up common expectations. Most of these methods are wrappers for
+    # to simplify and DRY up common expectations. Some of these methods are wrappers for
     # matchers which can also be used on the example level [read: within an &quot;it&quot; block]. See
     # LuckySneaks::ModelSpecHelpers for more information.
+    # 
+    # &lt;b&gt;Note:&lt;/b&gt; The validation matchers are only meant to be used for simple validation checking
+    # not as a one-size-fits-all solution.
     module ExampleGroupLevelMethods
-      # Creates an expectation that the current model being spec'd has a &lt;tt&gt;belongs_to&lt;/tt&gt;
-      # association with the specified model.
+      # Creates an expectation that the current model being spec'd has a &lt;tt&gt;belong_to&lt;/tt&gt;
+      # association with the specified model. Accepts optional arguments which are appended to
+      # the &lt;tt&gt;belong_to&lt;/tt&gt; spec like this:
+      # 
+      #   it_should_belong_to :document, :counter_cache =&gt; true
+      # 
+      # which is the same as writing out:
+      # 
+      #   it &quot;should belong to document&quot; do
+      #     Comment.should belong_to(:document).with_options(:counter_cache =&gt; true)
+      #   end
+      # 
+      # If you want a more detailed spec description text, feel free to write this out in the long
+      # form and use &lt;tt&gt;belong_to&lt;/tt&gt; and its related matcher helpers.
       # 
       # &lt;b&gt;Note:&lt;/b&gt; 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)
+      def it_should_belong_to(model, options = {})
         it &quot;should belong to a #{model}&quot; do
-          class_or_instance.should belong_to(model)
+          if options.empty?
+            class_or_instance.should belong_to(model)
+          else
+            class_or_instance.should belong_to(model).with_options(options)
+          end
         end
       end
       
       # Creates an expectation that the current model being spec'd has a &lt;tt&gt;have_one&lt;/tt&gt;
-      # association with the specified model.
+      # association with the specified model. Accepts optional arguments which are appended to
+      # the &lt;tt&gt;have_one&lt;/tt&gt; spec like this:
+      # 
+      #   it_should_have_one :last_comment, :class_name =&gt; &quot;Comment&quot;, :order =&gt; &quot;created_at DESC&quot;
+      # 
+      # which is the same as writing out:
+      # 
+      #   it &quot;should have one document&quot; do
+      #     Document.should have_one(:last_comment).with_options(:class_name =&gt; &quot;Comment&quot;, :order =&gt; &quot;created_at DESC&quot;)
+      #   end
+      # 
+      # If you want a more detailed spec description text, feel free to write this out in the long
+      # form and use &lt;tt&gt;have_one&lt;/tt&gt; and its related matcher helpers.
       # 
       # &lt;b&gt;Note:&lt;/b&gt; 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)
+      def it_should_have_one(model, options = {})
         it &quot;should have one #{model}&quot; do
-          class_or_instance.should have_one(model)
+          if options.empty?
+            class_or_instance.should have_one(model)
+          else
+            class_or_instance.should have_one(model).with_options(options)
+          end
         end
       end
       
       # Creates an expectation that the current model being spec'd has a &lt;tt&gt;have_many&lt;/tt&gt;
-      # association with the specified model.
+      # association with the specified model. Accepts optional arguments which are appended to
+      # the &lt;tt&gt;have_many&lt;/tt&gt; spec like this:
+      # 
+      #   it_should_have_many :memberships, :through =&gt; :sites
+      # 
+      # which is the same as writing out:
+      # 
+      #   it &quot;should have many memberships&quot; do
+      #     User.should have_many(:memberships).with_options(:through =&gt; :sites)
+      #   end
+      # 
+      # If you want a more detailed spec description text, feel free to write this out in the long
+      # form and use &lt;tt&gt;have_many&lt;/tt&gt; and its related matcher helpers.
       # 
       # &lt;b&gt;Note:&lt;/b&gt; 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)
+      def it_should_have_many(models, options = {})
         it &quot;should have many #{models}&quot; do
-          class_or_instance.should have_many(models)
+          if options.empty?
+            class_or_instance.should have_many(models)
+          else
+            class_or_instance.should have_many(models).with_options(options)
+          end
         end
       end
       
       # Creates an expectation that the current model being spec'd has a &lt;tt&gt;have_and_belong_to_many&lt;/tt&gt;
-      # association with the specified model.
+      # association with the specified model. Accepts optional arguments which are appended to
+      # the &lt;tt&gt;have_and_belong_to_many&lt;/tt&gt; spec like this:
+      # 
+      #   it_should_have_and_belong_to_many :documents, :include =&gt; :attachments
+      # 
+      # which is the same as writing out:
+      # 
+      #   it &quot;should belong to document&quot; do
+      #     User.should have_and_belong_to_many(:documents).with_options(:include =&gt; :attachments)
+      #   end
+      # 
+      # If you want a more detailed spec description text, feel free to write this out in the long
+      # form and use &lt;tt&gt;have_and_belong_to_many&lt;/tt&gt; and its related matcher helpers.
       # 
       # &lt;b&gt;Note:&lt;/b&gt; 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)
+      def it_should_have_and_belong_to_many(models, options = {})
         it &quot;should have and belong to many #{models}&quot; do
-          class_or_instance.should have_and_belong_to_many(models)
+          if options.empty?
+            class_or_instance.should have_and_belong_to_many(models)
+          else
+            class_or_instance.should have_and_belong_to_many(models).with_options(options)
+          end
+        end
+      end
+      
+      # Creates an expectation that new instances of the model being spec'd 
+      # should initialise the specified attributes with a default value.
+      # 
+      #  it_should_default_attributes :status =&gt; 'new'
+      #
+      def it_should_default_attributes(hash_attribute_values)
+        hash_attribute_values.each_pair do |a,v|
+          it &quot;should default #{a} attribute to #{v}&quot; do
+            class_or_instance.new.send(a).should == v
+          end
         end
       end
       
       # Creates an expectation that the current model being spec'd &lt;tt&gt;validates_presence_of&lt;/tt&gt;
       # 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 = I18n.translate('activerecord.errors.messages')[:blank])
+      def it_should_validate_presence_of(attribute, message = default_error_message(:blank))
         it &quot;should not be valid if #{attribute} is blank&quot; do
           instance.send &quot;#{attribute}=&quot;, nil
           instance.errors_on(attribute).should include(message)
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_validate_presence_of&lt;/tt&gt;. See that method for more
+      # details. You'd probably only be using this in a nested example block to compare that
+      # one scenario validates presence and another does not (because of conditions in
+      # &lt;tt&gt;:if/:unless&lt;/tt&gt;).
+      def it_should_not_validate_presence_of(attribute, message = default_error_message(:blank))
+        it &quot;should be valid if #{attribute} is blank&quot; do
+          instance.send &quot;#{attribute}=&quot;, nil
+          instance.errors_on(attribute).should_not include(message)
+        end
+      end
+            
+      # Creates an expectation that the current model being spec'd &lt;tt&gt;validates_inclusion_of&lt;/tt&gt;
+      # the specified attribute. Takes an optional custom message to match the one in the model's
+      # validation.     
+      def it_should_validate_inclusion_of(attribute, options = {}, message = default_error_message(:inclusion))
+       it &quot;should validate #{attribute} is in #{options[:in].to_s}&quot; do
+         # We specifically do not try to go below the range on String and character ranges because that problem set is unpredictable. 
+         lower  = options[:in].first.respond_to?(:-) ? options[:in].first - 0.0001 : nil
+         higher = options[:in].last.succ 
+         
+         instance.send &quot;#{attribute}=&quot;, lower
+         instance.errors_on(attribute).should include(message)
+
+         instance.send &quot;#{attribute}=&quot;, higher
+         instance.errors_on(attribute).should include(message)
+
+         instance.send &quot;#{attribute}=&quot;, (lower+higher)/2
+         instance.errors_on(attribute).should_not include(message)
+       end
+     end
+
       # Creates an expectation that the current model being spec'd &lt;tt&gt;validates_numericality_of&lt;/tt&gt;
       # 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 = I18n.translate('activerecord.errors.messages')[:not_a_number])
+      def it_should_validate_numericality_of(attribute, message = default_error_message(:not_a_number))
         it &quot;should validate #{attribute} is a numeric&quot; do
           instance.send &quot;#{attribute}=&quot;, &quot;NaN&quot;
           instance.errors_on(attribute).should include(message)
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_validate_numericality_of&lt;/tt&gt;. See that method for more
+      # details. You'd probably only be using this in a nested example block to compare that
+      # one scenario validates presence and another does not (because of conditions in
+      # &lt;tt&gt;:if/:unless&lt;/tt&gt;).
+      def it_should_not_validate_numericality_of(attribute, message = default_error_message(:not_a_number))
+        it &quot;should not validate #{attribute} is a numeric&quot; do
+          instance.send &quot;#{attribute}=&quot;, &quot;NaN&quot;
+          instance.errors_on(attribute).should_not include(message)
+        end
+      end
+      
       # Creates an expectation that the current model being spec'd &lt;tt&gt;validates_confirmation_of&lt;/tt&gt;
       # 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 = I18n.translate('activerecord.errors.messages')[:confirmation])
+      def it_should_validate_confirmation_of(attribute, message = default_error_message(:confirmation))
         it &quot;should validate confirmation of #{attribute}&quot; do
           dummy_value = dummy_value_for(instance, attribute) || &quot;try a string&quot;
           instance.send &quot;#{attribute}=&quot;, dummy_value
@@ -263,20 +411,33 @@ module LuckySneaks
       # 
       # &lt;b&gt;Note:&lt;/b&gt; This method will fail completely if &lt;tt&gt;valid_attributes&lt;/tt&gt;
       # does not provide all the attributes needed to create a valid record.
-      def it_should_validate_uniqueness_of(attribute, message = I18n.translate('activerecord.errors.messages')[:taken])
-        it &quot;should validate #{attribute} confirmation&quot; do
-          previous_instance = class_for(self.class.description_text).create!(valid_attributes)
+      def it_should_validate_uniqueness_of(attribute, message = default_error_message(:taken))
+        it &quot;should validate uniqueness of #{attribute}&quot; do
+          previous_instance = instance.class.create!(valid_attributes)
           instance.attributes = valid_attributes
           instance.errors_on(attribute).should include(message)
           previous_instance.destroy
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_validate_uniqueness_of&lt;/tt&gt;. See that method for more
+      # details. You'd probably only be using this in a nested example block to compare that
+      # one scenario validates presence and another does not (because of conditions in
+      # &lt;tt&gt;:if/:unless&lt;/tt&gt;).
+      def it_should_not_validate_uniqueness_of(attribute, message = default_error_message(:taken))
+        it &quot;should not validate uniqueness of #{attribute}&quot; do
+          previous_instance = instance.class.create!(valid_attributes)
+          instance.attributes = valid_attributes
+          instance.errors_on(attribute).should_not 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 &lt;tt&gt;validates_format_of&lt;/tt&gt;
       # but there's nothing saying it couldn't be another validation.
       def it_should_accept_as_valid(attribute, *values)
-        values.each do |value|
+        values.flatten.each do |value|
           value_inspect = case value
             when String : &quot;'#{value}'&quot;
             when NilClass : &quot;nil&quot;
@@ -296,7 +457,7 @@ module LuckySneaks
       # spec'ing the actual error message.
       def it_should_not_accept_as_valid(attribute, *values)
         options = values.extract_options!
-        values.each do |value|
+        values.flatten.each do |value|
           value_inspect = case value
             when String : &quot;'#{value}'&quot;
             when NilClass : &quot;nil&quot;
@@ -312,6 +473,7 @@ module LuckySneaks
           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)
@@ -321,6 +483,14 @@ module LuckySneaks
           }.should_not change(instance, attribute)
         end
       end
+      
+      def default_error_message(attribute)
+        if defined?(I18n)
+          I18n.translate attribute, :scope =&gt; &quot;activerecord.errors.messages&quot;
+        else
+          ActiveRecord::Errors.default_error_messages[attribute]
+        end
+      end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/model_spec_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,9 +6,10 @@ module LuckySneaks
   # to make your view specs less brittle and more DRY. You might also be interested 
   # in checking out the example block [read: &quot;describe&quot;] level versions in of these
   # methods which can DRY things up even more:
-  # LuckySneaks::ViewSpecHelpers::ExampleGroupLevelMethods
+  # LuckySneaks::ViewSpecHelpers::ExampleGroupLevelMethods.
   module ViewSpecHelpers
     include LuckySneaks::CommonSpecHelpers
+    include LuckySneaks::ViewStubHelpers
     include ActionController::PolymorphicRoutes
     
     def self.included(base) # :nodoc:
@@ -21,7 +22,7 @@ module LuckySneaks
       have_tag(&quot;form[action=#{path}]&quot;)
     end
     
-    # Wraps a matcher that checks is the receiver contains any of several form elements
+    # Wraps a matcher that checks if 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:
     # 
@@ -36,7 +37,8 @@ module LuckySneaks
     #   &lt;textarea name=&quot;foo[bar]&quot;&gt;&lt;/textarea&gt;
     def allow_editing(instance, attribute)
       instance_name = instance.class.name.underscore.downcase
-      if instance.send(attribute).is_a?(Time)
+      column = instance.column_for_attribute(attribute)
+      if column &amp;&amp; [Date, Time].include?(column.klass)
         have_tag(
           &quot;input[name='#{instance_name}[#{attribute}]'],
           select[name=?]&quot;, /#{instance_name}\[#{attribute}\(.*\)\]/
@@ -48,10 +50,20 @@ module LuckySneaks
           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][]']&quot;
+          input[type='checkbox'][name='#{instance_name}[#{attribute.to_s.tableize.singularize}_ids][]'],
+          input[type='radio'][name='#{instance_name}[#{attribute}]']&quot;
         )
       end
     end
+    
+    # Wraps a matcher that checks if the receiver contains a &lt;tt&gt;FORM&lt;/tt&gt; element
+    # whose &lt;tt&gt;enctype&lt;/tt&gt; attribute is set to &lt;tt&gt;&quot;multipart/form-data&quot;&lt;tt&gt;
+    # and contains an &lt;tt&gt;INPUT&lt;/tt&gt; element whose &lt;tt&gt;name&lt;/tt&gt; attribute correlates
+    # with the provided instance and attribute.
+    def allow_uploading(instance, attribute)
+      instance_name = instance.class.name.underscore.downcase
+      have_tag(&quot;form[enctype='multipart/form-data'] input[type='file'][name='#{instance_name}[#{attribute}]']&quot;)
+    end
 
     # Wraps a matcher that checks if the receiver contains an &lt;tt&gt;A&lt;/tt&gt; element (link) 
     # whose &lt;tt&gt;href&lt;/tt&gt; attribute is set to the specified path or a &lt;tt&gt;FORM&lt;/tt&gt;
@@ -78,7 +90,14 @@ module LuckySneaks
     # Wraps &lt;tt&gt;have_link_or_button_to polymorphic_path(instance)&lt;tt&gt; which
     # corresponds with the &lt;tt&gt;show&lt;/tt&gt; method of the controller.
     def have_link_or_button_to_show(instance)
-      have_link_or_button_to polymorphic_path(instance)
+      path = polymorphic_path(instance)
+      have_tag(
+        &quot;a[href='#{path}'],
+        form[action='#{path}'][method='get'] input,
+        form[action='#{path}'][method='get'] button,
+        form[action='#{path}'] input[name='_method'][value='get'] + input,
+        form[action='#{path}'] input[name='_method'][value='get'] + button&quot;
+      )
     end
     alias have_link_to_show have_link_or_button_to_show
     alias have_button_to_show have_link_or_button_to_show
@@ -99,7 +118,8 @@ module LuckySneaks
       path = polymorphic_path(instance)
       have_tag(
         &quot;form[action='#{path}'] input[name='_method'][value='delete'] + input,
-        form[action='#{path}'] input[name='_method'][value='delete'] + button&quot;
+        form[action='#{path}'] input[name='_method'][value='delete'] + button,
+        a[href=\&quot;#{path}\&quot;][onclick*=\&quot;f.method = 'POST'\&quot;][onclick*=\&quot;m.setAttribute('name', '_method'); m.setAttribute('value', 'delete')\&quot;]&quot;
       )
     end
     
@@ -121,9 +141,9 @@ module LuckySneaks
     def mock_and_assign(klass, *args)
       options = args.extract_options!
       mocked = if options[:stub]
-        mock_model(klass, options[:stub])
+        self.respond_to?(:stub_model) ? stub_model(klass, options[:stub]) : mock_model(klass, options[:stub])
       else
-        mock_model(klass)
+        self.respond_to?(:stub_model) ? stub_model(klass) : mock_model(klass)
       end
       yield mocked if block_given?
       self.assigns[args.first || &quot;#{klass}&quot;.underscore] = mocked
@@ -133,12 +153,12 @@ module LuckySneaks
     # &lt;tt&gt;mock_and_assign&lt;/tt&gt;. Accepts &lt;tt&gt;option[:size]&lt;/tt&gt; which sets the size
     # of the array (default is 3).
     def mock_and_assign_collection(klass, *args)
-      options = args.dup.extract_options!
+      options = args.extract_options!
       return_me = Array.new(options[:size] || 3) do
         mocked = if options[:stub]
-          mock_model(klass, options[:stub])
+          self.respond_to?(:stub_model) ? stub_model(klass, options[:stub]) : mock_model(klass, options[:stub])
         else
-          mock_model(klass)
+          self.respond_to?(:stub_model) ? stub_model(klass) : mock_model(klass)
         end
         yield mocked if block_given?
         mocked
@@ -150,8 +170,8 @@ module LuckySneaks
     def do_render
       if @the_template
         render @the_template
-      elsif File.exists?(File.join(RAILS_ROOT, &quot;app/views&quot;, self.class.description_text))
-        render self.class.description_text
+      elsif File.exists?(File.join(RAILS_ROOT, &quot;app/views&quot;, class_description_text))
+        render class_description_text
       else
         error_message = &quot;Cannot determine template for render. &quot;
         error_message &lt;&lt; &quot;Please define @the_template in the before block &quot;
@@ -182,6 +202,18 @@ module LuckySneaks
         end
       end
       
+      # Negative version of &lt;tt&gt;it_should_submit_to&lt;/tt&gt;. See that method for more
+      # details.
+      def it_should_not_submit_to(hint = nil, &amp;route)
+        if hint.nil? &amp;&amp; route.respond_to?(:to_ruby)
+          hint = route.to_ruby.gsub(/(^proc \{)|(\}$)/, '').strip
+        end
+        it &quot;should not submit to #{(hint || route)}&quot; do
+          do_render
+          response.should_not submit_to(instance_eval(&amp;route))
+        end
+      end
+      
       # Creates an expectation that the template uses Rails' &lt;tt&gt;form_for&lt;/tt&gt; to generate
       # the proper form action and method to create or update the specified object.
       # 
@@ -190,41 +222,85 @@ module LuckySneaks
       # not an instance variable, which would be nil in the scope of the example block.
       # If you use namespacing for your &lt;tt&gt;form_for&lt;/tt&gt;, you'll have to manually write out
       # a similar spec.
-      def it_should_have_form_for(name)
+      def it_should_have_form_for(name, options = {})
         it &quot;should have a form_for(@#{name})&quot; do
-          template.should_receive(:form_for).with(instance_for(name))
+          if options.empty?
+            template.should_receive(:form_for).with(instance_for(name))
+          else
+            template.should_receive(:form_for).with(instance_for(name), hash_including(options))
+          end
           do_render
         end
       end
       
       # Negative version of &lt;tt&gt;it_should_have_form_for&lt;/tt&gt;. See that method for more
       # details.
-      def it_should_not_have_form_for(name)
+      def it_should_not_have_form_for(name, options = {})
         it &quot;should not have a form_for(@#{name})&quot; do
-          template.should_not_receive(:form_for).with(instance_for(name))
+          if options.empty?
+            template.should_not_receive(:form_for).with(instance_for(name))
+          else
+            template.should_not_receive(:form_for).with(instance_for(name), hash_including(options))
+          end
           do_render
         end
       end
 
-      # Creates an expectation which calls &lt;tt&gt;allow_editing&lt;/tt&gt; on the response
-      # from rendering the template. See that method for more details.
+      # Creates an expectation which calls &lt;tt&gt;allow_editing&lt;/tt&gt; on the rendered
+      # template for each attribute specified. See the docs for &lt;tt&gt;allow_editing&lt;/tt&gt;
+      # for more details.
       # 
       # &lt;b&gt;Note:&lt;/b&gt; This method takes a string or symbol representing the instance
       # variable's name to send to &lt;tt&gt;allow_editing&lt;/tt&gt;
       # not an instance variable, which would be nil in the scope of the example block.
-      def it_should_allow_editing(name, method)
-        it &quot;should allow editing of @#{name}##{method}&quot; do
-          do_render
-          response.should allow_editing(instance_for(name), method)
+      def it_should_allow_editing(instance_name, *attributes)
+        attributes.flatten!
+        attributes.each do |attribute|
+          it &quot;should allow editing of @#{instance_name}##{attribute}&quot; do
+            do_render
+            response.should allow_editing(instance_for(instance_name), attribute)
+          end
         end
       end
       
       # Negative version of &lt;tt&gt;it_should_allow_editing&lt;/tt&gt;. See that method for more
       # details.
-      def it_should_not_allow_editing(name, method)
-        it &quot;should not allow editing of @#{name}##{method}&quot; do
-          do_render
-          response.should_not allow_editing(instance_for(name), method)
+      def it_should_not_allow_editing(instance_name, *attributes)
+        attributes.flatten!
+        attributes.each do |attribute|
+          it &quot;should not allow editing of @#{instance_name}##{attribute}&quot; do
+            do_render
+            response.should_not allow_editing(instance_for(instance_name), attribute)
+          end
+        end
+      end
+      
+      # Creates an expectation which calls &lt;tt&gt;allow_uploading&lt;/tt&gt; on the rendered
+      # template for each attribute specified. See the docs for &lt;tt&gt;allow_uploading&lt;/tt&gt;
+      # for more details.
+      # 
+      # &lt;b&gt;Note:&lt;/b&gt; This method takes a string or symbol representing the instance
+      # variable's name to send to &lt;tt&gt;allow_uploading&lt;/tt&gt;
+      # not an instance variable, which would be nil in the scope of the example block.
+      def it_should_allow_uploading(instance_name, *attributes)
+        attributes.flatten!
+        attributes.each do |attribute|
+          it &quot;should allow editing of @#{instance_name}##{attribute}&quot; do
+            do_render
+            response.should allow_uploading(instance_for(instance_name), attribute)
+          end
+        end
+      end
+      
+      # Negative version of &lt;tt&gt;it_should_allow_uploading&lt;/tt&gt;. See that method for more
+      # details.
+      def it_should_not_allow_uploading(instance_name, *attributes)
+        attributes.flatten!
+        attributes.each do |attribute|
+          it &quot;should not allow editing of @#{instance_name}##{attribute}&quot; do
+            do_render
+            response.should_not allow_uploading(instance_for(instance_name), attribute)
+          end
         end
       end
       
@@ -455,6 +531,47 @@ module LuckySneaks
       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
+      
+      # Creates an expectation that the template should call &lt;tt&gt;render :partial&lt;/tt&gt;
+      # with the specified template.
+      def it_should_render_partial(name)
+        it &quot;should render :partial =&gt; '#{name}'&quot; do
+          template.should_receive(:render).with(hash_including(:partial =&gt; name))
+          do_render
+        end
+      end
+      
+      # Negative version of &lt;tt&gt;it_should_render_partial&lt;/tt&gt;. See that method
+      # for more details.
+      def it_should_not_render_partial(name)
+        it &quot;should not render :partial =&gt; '#{name}'&quot; do
+          template.should_not_receive(:render).with(hash_including(:partial =&gt; name))
+          do_render
+        end
+      end
+      
+      # Sets &lt;tt&gt;@the_template&lt;/tt&gt; (for use in &lt;tt&gt;do_render&lt;/tt&gt;) using the current 
+      # example group description. Example:
+      # 
+      # describe &quot;users/index.haml.erb&quot; do
+      #   use_describe_for_template!
+      #   # ...
+      # end
+      # 
+      # This is equivalent to setting &lt;tt&gt;@the_template = &quot;users/index.haml.erb&quot;&lt;/tt&gt;
+      # in a before block.
+      def use_describe_for_template!
+        template = self_description_text
+        if File.exists?(File.join(RAILS_ROOT, &quot;app/views&quot;, template))
+          before(:each) do
+            @the_template = template
+          end
+        else
+          error_message = &quot;You called use_describe_for_template! &quot;
+          error_message &lt;&lt; &quot;but 'app/views/#{template}' does not exist. &quot;
+          raise NameError, error_message
+        end
+      end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>vendor/plugins/skinny_spec/lib/lucky_sneaks/view_spec_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,10 @@
 # Let's make sure everyone else is loaded
-require File.expand_path(File.dirname(__FILE__) + &quot;/../../../../config/environment&quot;)
+require File.expand_path(RAILS_ROOT + &quot;/config/environment&quot;)
 require 'spec'
 require 'spec/rails'
 begin
   require 'ruby2ruby'
-rescue
+rescue LoadError
   puts &quot;-----&quot;
   puts &quot;Attention: skinny_spec requires ruby2ruby for nicer route descriptions&quot;
   puts &quot;It is highly recommended that you install it: sudo gem install ruby2ruby&quot;</diff>
      <filename>vendor/plugins/skinny_spec/lib/skinny_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bbf3e95b219bdadab2e694b09384bbe18bb5347d</id>
    </parent>
  </parents>
  <author>
    <name>Eric Allen</name>
    <email>ericpallen@gmail.com</email>
  </author>
  <url>http://github.com/bsag/tracks/commit/feeca283b43041e9f7b503f843571fb32b6664e4</url>
  <id>feeca283b43041e9f7b503f843571fb32b6664e4</id>
  <committed-date>2009-05-03T21:07:08-07:00</committed-date>
  <authored-date>2009-05-03T21:06:46-07:00</authored-date>
  <message>Upgrade skinny_spec to deal with newer version of RSpec due to unfreezing.</message>
  <tree>f0696bd3629e56ae7e58d9a58810c05882f40d17</tree>
  <committer>
    <name>Eric Allen</name>
    <email>ericpallen@gmail.com</email>
  </committer>
</commit>
