<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: rspec code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 26 Jul 2008 02:12:51 GMT</pubDate>
    <description>DZone Snippets: rspec code</description>
    <item>
      <title>Log slow rspec examples</title>
      <link>http://snippets.dzone.com/posts/show/5633</link>
      <description>Just a quick monkey patch...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Spec::Example&lt;br /&gt;  module ExampleMethods&lt;br /&gt;    THRESHOLD_TO_LOG = 500 # ms&lt;br /&gt;    &lt;br /&gt;    alias :execute_without_timing :execute&lt;br /&gt;    def execute_with_timing(options)&lt;br /&gt;      start_time = Time.now&lt;br /&gt;      execute_without_timing(options)&lt;br /&gt;      duration_ms = (Time.now - start_time) * 1000&lt;br /&gt;      if (duration_ms &gt; THRESHOLD_TO_LOG)&lt;br /&gt;        print "(#{sprintf("%.3fms", duration_ms)} - #{_example.description}) "&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    alias :execute :execute_with_timing&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 11 Jun 2008 17:41:07 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5633</guid>
      <author>mloughran ()</author>
    </item>
    <item>
      <title>RSpec Association Matchers</title>
      <link>http://snippets.dzone.com/posts/show/4721</link>
      <description>Ok, what I essentially wanted to accomplish was something like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;describe Product, 'with Group' do&lt;br /&gt;&lt;br /&gt;  it 'should belong to group' do&lt;br /&gt;    Product.should belong_to(:product_group)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;describe ProductGroup, 'with Product' do&lt;br /&gt;&lt;br /&gt;  it 'should have many products depending (on group)' do&lt;br /&gt;    ProductGroup.should have_many(:products).depending&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module AssociationMatchers&lt;br /&gt;&lt;br /&gt;  class AssociationReflection&lt;br /&gt;&lt;br /&gt;    def initialize(type, name)&lt;br /&gt;      @messages = {&lt;br /&gt;        :missing_association =&gt;&lt;br /&gt;          '%s is not associated with %s.',&lt;br /&gt;        :wrong_type =&gt;&lt;br /&gt;          "%s %s %s./nExpected: %s",&lt;br /&gt;        :wrong_options =&gt;&lt;br /&gt;          "Options are incorrect.\nExpected: %s Got: %s",&lt;br /&gt;        :missing_column =&gt;&lt;br /&gt;          "Missing foreign key.\nExpected: %s"&lt;br /&gt;      }&lt;br /&gt;      @name = name&lt;br /&gt;      @expected_type = type&lt;br /&gt;      @expected_options = {}&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def matches?(target)&lt;br /&gt;      Class === target or&lt;br /&gt;      raise ArgumentError, 'class expected'&lt;br /&gt;&lt;br /&gt;      @target = target&lt;br /&gt;&lt;br /&gt;      unless @assoc = target.reflect_on_association(@name)&lt;br /&gt;        @failure = :missing_association&lt;br /&gt;        return false&lt;br /&gt;      end &lt;br /&gt;&lt;br /&gt;      unless @assoc.macro.eql?(@expected_type)&lt;br /&gt;        @failure = :wrong_type&lt;br /&gt;        return false&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      if @expected_options.any? { |o| @assoc.options[o.first] != o.last }&lt;br /&gt;        @failure = :wrong_options&lt;br /&gt;        return false&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      @column ||= @assoc.primary_key_name || @assoc.klass.name.foreign_key&lt;br /&gt;&lt;br /&gt;      @failure = case @assoc.macro.to_s&lt;br /&gt;      when 'belongs_to'&lt;br /&gt;        if @target.column_names.include?(@column.to_s) then nil&lt;br /&gt;        else&lt;br /&gt;          :missing_column&lt;br /&gt;        end&lt;br /&gt;      when /(?:has_many|has_one)/&lt;br /&gt;        if    @assoc.options[:through] then nil&lt;br /&gt;        elsif @assoc.klass.column_names.include?(@column.to_s) then nil&lt;br /&gt;        else&lt;br /&gt;          :missing_column&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      return @failure.nil?&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def failure_message&lt;br /&gt;      case @failure&lt;br /&gt;      when :missing_association&lt;br /&gt;        @messages[@failure] % [@target.name, @name]&lt;br /&gt;      when :wrong_type&lt;br /&gt;        @messages[@failure] % [&lt;br /&gt;          @target.name,&lt;br /&gt;          @assoc.macro,&lt;br /&gt;          @name,&lt;br /&gt;          @expected_type&lt;br /&gt;        ]&lt;br /&gt;      when :wrong_options&lt;br /&gt;        @messages[@failure] % [&lt;br /&gt;          @expected_options.inspect,&lt;br /&gt;          @assoc.options.inspect&lt;br /&gt;        ]&lt;br /&gt;      when :missing_column&lt;br /&gt;        @messages[@failure] % @column&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    def negative_failure_message&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    ### Generic Options&lt;br /&gt;&lt;br /&gt;    def of(class_name)&lt;br /&gt;      class_name = class_name.name if Class === class_name&lt;br /&gt;      @expected_options[:class_name] = class_name&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def for(foreign_key)&lt;br /&gt;      @column = foreign_key&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def due_to(conditions)&lt;br /&gt;      @expected_options[:conditions] = conditions&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def ordered_by(statement)&lt;br /&gt;      @expected_options[:order] = statement&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def including(*models)&lt;br /&gt;      @expected_options[:include] = (models.length == 1)? models.first: models&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;  class BelongsToReflection &lt; AssociationReflection&lt;br /&gt;&lt;br /&gt;    def initialize(name)&lt;br /&gt;      super :belongs_to, name&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def counted(column)&lt;br /&gt;      @expected_options[:counter_cache] = column&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def polymorphic(true_or_false = true)&lt;br /&gt;      @expected_options[:polymorphic] = true_or_false&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class HasOneReflection &lt; AssociationReflection&lt;br /&gt;&lt;br /&gt;    def initialize(name)&lt;br /&gt;      super :has_one, name&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def as(interface_name)&lt;br /&gt;      @expected_options[:as] = interface_name&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def depending(dependency = true)&lt;br /&gt;      @expected_options[:dependent] = dependency&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def extended_by(mod)&lt;br /&gt;      @expected_options[:extend] = mod&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;  class HasManyReflection &lt; AssociationReflection&lt;br /&gt;&lt;br /&gt;    def initialize(name)&lt;br /&gt;      super :has_many, name&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def as(interface_name)&lt;br /&gt;      @expected_options[:as] = interface_name&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;    def depending(dependency = :destroy)&lt;br /&gt;      @expected_options[:dependent] = dependency&lt;br /&gt;      self&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;  class HasAndBelongsToManyReflection &lt; AssociationReflection&lt;br /&gt;&lt;br /&gt;    def initialize(name)&lt;br /&gt;      super :has_and_belongs_to_many, name&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def belong_to(model)&lt;br /&gt;    BelongsToReflection.new model&lt;br /&gt;  end&lt;br /&gt;  def have_one(model)&lt;br /&gt;    HasOneReflection.new model&lt;br /&gt;  end&lt;br /&gt;  def have_many(models)&lt;br /&gt;    HasManyReflection.new models&lt;br /&gt;  end&lt;br /&gt;  def have_and_belong_to_many(models)&lt;br /&gt;    HasAndBelongsToManyReflection.new models&lt;br /&gt;  end&lt;br /&gt;  alias_method :habtm, :have_and_belong_to_many&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It checks:&lt;br /&gt;* association exists&lt;br /&gt;* association macro&lt;br /&gt;* foreign key exists (except for habtm)&lt;br /&gt;* options match (only a subset is supported)&lt;br /&gt;&lt;br /&gt;Setup:&lt;br /&gt;* put the code in RAILS_ROOT + "/lib/association_matchers.rb"&lt;br /&gt;* put "config.include AssociationMatchers # lib/association_matchers.rb" in your spec_helper.rb configure block&lt;br /&gt;* refactor your model specs...</description>
      <pubDate>Wed, 31 Oct 2007 09:42:07 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4721</guid>
      <author>boof (Florian A&#223;mann)</author>
    </item>
    <item>
      <title>RSpec extension: testing attr_protected and attr_accessible</title>
      <link>http://snippets.dzone.com/posts/show/4712</link>
      <description>Include this module in a spec or inside the Spec::Runner.configure block in the spec_helper.rb. Because i suck, should_not is not working as expected. Usage:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class User &lt; ActiveRecord::Base&lt;br /&gt;  # either &lt;br /&gt;  attr_accessible :username, :full_name&lt;br /&gt;  # or&lt;br /&gt;  attr_protected :admin, :foo&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# ...&lt;br /&gt;&lt;br /&gt;it "should protect admin and foo" do&lt;br /&gt;  @user.should protect_attributes(:admin, :foo)&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here goes:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module CustomExpectations&lt;br /&gt;  class ProtectAttributes&lt;br /&gt;    def initialize(*attributes)&lt;br /&gt;      @attributes = attributes&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def matches?(target)&lt;br /&gt;      @target = target&lt;br /&gt;      &lt;br /&gt;      calculate_protected_methods&lt;br /&gt;      perform_check&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def failure_message&lt;br /&gt;      "expected #{@failed_attribute} to be protected"&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def negative_failure_message&lt;br /&gt;      "expected #{@failed_attribute} to not be protected"&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    private&lt;br /&gt;    &lt;br /&gt;    def calculate_protected_methods&lt;br /&gt;      read = proc {|var| @target.instance_eval { self.class.read_inheritable_attribute(var) } }&lt;br /&gt;      accessible = read.call("attr_accessible")&lt;br /&gt;      protekted = read.call("attr_protected")&lt;br /&gt;      all = @target.class.column_names.map(&amp;:to_sym)&lt;br /&gt;      &lt;br /&gt;      @protected = []&lt;br /&gt;      @protected &lt;&lt; protekted if protekted&lt;br /&gt;      @protected &lt;&lt; (all - accessible) if accessible&lt;br /&gt;      @protected.flatten!&lt;br /&gt;      &lt;br /&gt;      @accessible = all - @protected&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def perform_check&lt;br /&gt;      failed_attributes = (@attributes &amp; @accessible)&lt;br /&gt;      @failed_attribute = failed_attributes.first&lt;br /&gt;      failed_attributes.empty?&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def protect_attributes(attributes)&lt;br /&gt;    ProtectAttributes.new(attributes)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def protect_attribute(attribute)&lt;br /&gt;    ProtectAttributes.new(*[attribute])&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 29 Oct 2007 20:28:23 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4712</guid>
      <author>leethal (August Lilleaas)</author>
    </item>
    <item>
      <title>Rspec my validations for models</title>
      <link>http://snippets.dzone.com/posts/show/4508</link>
      <description>// This is the plain-vanilla way that I've been using spec for basic model validations.  &lt;br /&gt;// There is also a bit at the bottom that checks that I have the right association&lt;br /&gt;// setup.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require File.dirname(__FILE__) + '/../spec_helper'&lt;br /&gt;&lt;br /&gt;module CommentSpecHelper&lt;br /&gt;  def valid_comment_attributes&lt;br /&gt;    { :body =&gt; 'Some text',&lt;br /&gt;      :commentable_type =&gt; 'School',&lt;br /&gt;      :commentable_id =&gt; 1 }&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;describe Comment do&lt;br /&gt;&lt;br /&gt;  include CommentSpecHelper&lt;br /&gt;&lt;br /&gt;  before(:each) do&lt;br /&gt;    @comment = Comment.new&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  it "should be valid" do&lt;br /&gt;    @comment.attributes = valid_comment_attributes&lt;br /&gt;    @comment.should be_valid&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  it "should should not be valid without something to attach to" do&lt;br /&gt;    c = valid_comment_attributes&lt;br /&gt;    c.delete :commentable_id&lt;br /&gt;    c.delete :commentable_type&lt;br /&gt;    @comment.attributes = c&lt;br /&gt;    @comment.should_not be_valid&lt;br /&gt;    @comment.errors.on(:commentable_id).should eql("can't be blank")&lt;br /&gt;    @comment.commentable_id = 1&lt;br /&gt;    @comment.should_not be_valid&lt;br /&gt;    @comment.errors.on(:commentable_type).should eql("can't be blank")&lt;br /&gt;    @comment.commentable_type = "School"&lt;br /&gt;    @comment.should be_valid&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  it "should require body" do&lt;br /&gt;    @comment.attributes = valid_comment_attributes.except(:body)&lt;br /&gt;    @comment.should_not be_valid&lt;br /&gt;    @comment.errors.on(:body).should eql("can't be blank")&lt;br /&gt;    @comment.body = "Some text"&lt;br /&gt;    @comment.should be_valid&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  it "should relate to commentable" do&lt;br /&gt;    Comment.reflect_on_association(:commentable).should_not be_nil&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  it "should relate to user" do&lt;br /&gt;    Comment.reflect_on_association(:user).should_not be_nil&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 07 Sep 2007 14:48:32 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4508</guid>
      <author>drichards (David Richards)</author>
    </item>
    <item>
      <title>vim folding for RSpec editing</title>
      <link>http://snippets.dzone.com/posts/show/3528</link>
      <description>&lt;br /&gt;&lt;code&gt;&lt;br /&gt;" fold text between context and specify&lt;br /&gt;function! ShowRSpecContext()&lt;br /&gt;  let spec_idx = search('specify\s\+".\+"', 'Wbn', '^')&lt;br /&gt;  let ctx_idx  = search('context\s\+".\+"', 'Wbn', '^')&lt;br /&gt;  if spec_idx &amp;&amp; ctx_idx&lt;br /&gt;    exec (ctx_idx+1).','.(spec_idx-1).'fold'&lt;br /&gt;  endif&lt;br /&gt;endfunction&lt;br /&gt;&lt;br /&gt;" fold text between all contexts and specify lines&lt;br /&gt;function! ShowRSpecAnnotation()&lt;br /&gt; call cursor('$', 0)&lt;br /&gt; try&lt;br /&gt;   foldo!&lt;br /&gt; catch&lt;br /&gt; endtry&lt;br /&gt; let cur_line = line('$')&lt;br /&gt; while cur_line &gt; 0&lt;br /&gt;   let prev_spec = search('\(context\|specify\)\s\+".\+"', 'Wb', '^')&lt;br /&gt;   if ! prev_spec&lt;br /&gt;     break&lt;br /&gt;   endif&lt;br /&gt;   exec (prev_spec).','.cur_line.'fold'&lt;br /&gt;   let cur_line=prev_spec-1&lt;br /&gt; endwhile&lt;br /&gt;endfunction&lt;br /&gt;command! Sx :call ShowRSpecContext()&lt;br /&gt;command! Sa :call ShowRSpecAnnotation()&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Feb 2007 10:33:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3528</guid>
      <author>dseverin ()</author>
    </item>
    <item>
      <title>Extending 'context' with new methods in RSpec</title>
      <link>http://snippets.dzone.com/posts/show/3210</link>
      <description>Define a new method like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module Spec::Runner::ContextEval::ModuleMethods&lt;br /&gt;  def new_method&lt;br /&gt;    # ...&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then use like that:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;context "Some state" do&lt;br /&gt;  new_method&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 27 Dec 2006 05:49:28 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3210</guid>
      <author>infrared (Micha&#322; Kwiatkowski)</author>
    </item>
  </channel>
</rss>
