Sinatra::Tests

A Sinatra extension and repository of common RSpec helpers when testing your Sinatra apps/gems.

Installation

#  Add Gemcutter to your RubyGems sources 
$  gem sources -a http://gemcutter.com

$  (sudo)? gem install sinatra-tests

Dependencies

This Gem depends upon the following:

  • sinatra ( >= 0.10.1 )
  • rspec (>= 1.3.0 )
  • rack-test (>= 0.5.3)
  • rspec_hpricot_matchers (>= 0.1.0)

Getting Started

Step 1

In your spec/spec_helper.rb file add the following:

require 'sinatra/tests'

By just requiring that gem, you essentially get all of this:

require 'sinatra/base'
require 'test/unit'
require 'rack/test'
require 'spec'
require 'spec/interop/test'
require 'rspec_hpricot_matchers'

and a few other goodies.

Step 2

Declare the following Spec block:

Spec::Runner.configure do |config|
config.include RspecHpricotMatchers
config.include Sinatra::Tests::TestCase
config.include Sinatra::Tests::RSpec::SharedSpecs
end

Step 3

In your TestApp block, register the Sinatra::Tests extension, by adding the following:

class MyTestApp < Sinatra::Base 

register(Sinatra::Tests)

<snip...>
end

Step 4

And finally define the TestCase block like this:

class Test::Unit::TestCase 
Sinatra::Base.set :environment, :test
end

That's all. Now onto the niceties this provides you.

USAGE

RSpec Matchers

:be_even

A simple matcher that tests for an even number

1.should_not be_even
2.should be_even

:have_a_page_title(:title_text)

A simple matcher that tests for a with a tag with the given text.</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_page_title identifier id'>have_a_page_title</span><span class='lparen token'>(</span><span class='string val'>"Home | Site Title"</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_page_title identifier id'>have_a_page_title</span><span class='lparen token'>(</span><span class='regexp val'>/Home/</span><span class='rparen token'>)</span> </code></pre> <h4 id="_have_a_page_header__text___tag_">:have_a_page_header(:text, :tag)</h4> <p>A simple matcher that tests for <h(1..6)> header tag with the given text.</p> <p><b>NB!</b> Throws an Exception when there's more than one page header on the page.</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_page_header identifier id'>have_a_page_header</span><span class='lparen token'>(</span><span class='string val'>'Page Header'</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_page_header identifier id'>have_a_page_header</span><span class='lparen token'>(</span><span class='regexp val'>/Contact Information/</span><span class='comma token'>,</span> <span class='string val'>'h1'</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_page_header identifier id'>have_a_page_header</span><span class='lparen token'>(</span><span class='regexp val'>/Contact Information/</span><span class='comma token'>,</span> <span class='string val'>'body > h1'</span><span class='rparen token'>)</span> </code></pre> <h4 id="_have_a_ui_btn__tag___action___model_name_singluar___link_text_">:have_a_ui_btn(:tag, :action, :model_name_singluar, :link_text)</h4> <p>A simple matcher that tests for a <tt><a href></tt> tag with class 'ui-btn :action-link' and a number of other specific values, derived from the other arguments passed.</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_ui_btn identifier id'>have_a_ui_btn</span><span class='lparen token'>(</span><span class='string val'>'div'</span><span class='comma token'>,</span> <span class='symbol val'>:edit</span><span class='comma token'>,</span> <span class='symbol val'>:article</span><span class='comma token'>,</span> <span class='string val'>'Edit'</span><span class='rparen token'>)</span> <span class='assign token'>=</span><span class='gt op'>></span> <span class='rubyid_expects identifier id'>expects</span> <span class='lt op'><</span><span class='rubyid_a identifier id'>a</span> <span class='rubyid_href identifier id'>href</span><span class='assign token'>=</span><span class='string val'>"/articles/:id/edit"</span> <span class='rubyid_class class kw'>class</span><span class='assign token'>=</span><span class='string val'>"ui-btn edit-link"</span> <span class='rubyid_title identifier id'>title</span><span class='assign token'>=</span><span class='string val'>"edit article"</span><span class='gt op'>></span><span class='rubyid_Edit constant id'>Edit</span><span class='lt op'><</span><span class='regexp val'>/a> body.should have_a_ui_btn('div', :delete, :article) => => expects <a href="/</span><span class='rubyid_articles identifier id'>articles</span><span class='div op'>/</span><span class='symbol val'>:id</span><span class='string val'>" class="</span><span class='rubyid_ui identifier id'>ui</span><span class='minus op'>-</span><span class='rubyid_btn identifier id'>btn</span> <span class='rubyid_delete identifier id'>delete</span><span class='minus op'>-</span><span class='rubyid_link identifier id'>link</span><span class='string val'>" title="</span><span class='rubyid_delete identifier id'>delete</span> <span class='rubyid_article identifier id'>article</span><span class='string val'>">DELETE</a> </span></code></pre> <h4 id="_have_an_edit_btn__tag___model_name_singluar_">:have_an_edit_btn(:tag, :model_name_singluar)</h4> <p>A simple matcher that tests for a <tt><a href></tt> tag with class 'ui-btn edit-link'</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_an_edit_btn identifier id'>have_an_edit_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_an_edit_btn identifier id'>have_an_edit_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='comma token'>,</span> <span class='string val'>'Custom Btn Text'</span><span class='rparen token'>)</span> </code></pre> <h4 id="_have_a_delete_btn__tag___model_name_singluar_">:have_a_delete_btn(:tag, :model_name_singluar)</h4> <p>A simple matcher that tests for a <tt><a href></tt> tag with class 'ui-btn delete-link'</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_delete_btn identifier id'>have_a_delete_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_delete_btn identifier id'>have_a_delete_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='comma token'>,</span> <span class='string val'>'Custom Btn Text'</span><span class='rparen token'>)</span> </code></pre> <h4 id="_have_a_show_btn__tag___model_name_singluar_">:have_a_show_btn(:tag, :model_name_singluar)</h4> <p>A simple matcher that tests for a <tt><a href></tt> tag with class 'ui-btn show-link'</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_show_btn identifier id'>have_a_show_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='rparen token'>)</span> <span class='rubyid_body identifier id'>body</span><span class='dot token'>.</span><span class='rubyid_should identifier id'>should</span> <span class='rubyid_have_a_show_btn identifier id'>have_a_show_btn</span><span class='lparen token'>(</span><span class='string val'>'td.actions'</span><span class='comma token'>,</span> <span class='symbol val'>:post</span><span class='comma token'>,</span> <span class='string val'>'Custom Btn Text'</span><span class='rparen token'>)</span> </code></pre> <h3 id="RSpec_SharedSpecs">RSpec SharedSpecs</h3> <p>These are just some of the shared specs that I have been using, but they are being changed at the moment, so no guarantees of them surviving or remaining in their current form / functionality.</p> <h4 id="DEBUG">DEBUG</h4> <p>Dump a list of methods for the current <tt>app</tt></p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"debug => app.methods"</span> </code></pre> <p>Tests the body output for a <tt><debug></tt> tag, ie: prints out the entire body content</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"debug"</span> </code></pre> <h4 id="RESPONSE">RESPONSE</h4> <p>Checks that we got a 200 status (OK), and content-type is <tt>text/html</tt></p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"HTTP headers"</span> <span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"HTML"</span> </code></pre> <p>Checks that we got a 200 status (OK), and content-type is <tt>text/css</tt></p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"CSS"</span> </code></pre> <h4 id="HTML_OUTPUT">HTML OUTPUT</h4> <p>Checks that the page has a <tt><div id="main-content"></div></tt></p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"div#main-content"</span> </code></pre> <p>Checks that the page has an <tt><h2></tt> tag within the <tt><div id="main-content"></div></tt></p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"div#main-content > h2"</span> </code></pre> <p>More to be addded later...</p> <h4 id="FORMS">FORMS</h4> <p>Checks that the page has a form with a <tt><input type="hidden"...></tt> tag.</p> <pre class="code ruby"><code class="ruby"><span class='rubyid_it_should_behave_like identifier id'>it_should_behave_like</span> <span class='string val'>"forms > faux method > input.hidden"</span> </code></pre> <p>More to be addded later...</p> <h2 id="RTFM">RTFM</h2> <p>For a better understanding of this Gem, make sure you study the '<tt>sinatra-tests/spec/*_spec.rb</tt>' files.</p> <h2 id="Errors___Bugs">Errors / Bugs</h2> <p>If something is not behaving intuitively, it is a bug, and should be reported. Report it here: <a href="http://github.com/kematzy/sinatra-tests/issues">http://github.com/kematzy/sinatra-tests/issues</a></p> <h2 id="TODOs">TODOs</h2> <ul> <li> <p>Add more tests to various matchers.</p> </li> <li> <p>Create a test suite for the Shared Specs.</p> </li> <li> <p>Add Test::Unit (assert*) matchers and shared tests. (Please fork and add if you want this!)</p> </li> </ul> <h2 id="Note_on_Patches_Pull_Requests">Note on Patches/Pull Requests</h2> <ul> <li>Fork the project.</li> <li>Make your feature addition or bug fix.</li> <li>Add tests for it. This is important so I don't break it in a future version unintentionally.</li> <li>Commit, do not mess with rakefile, version, or history. <ul> <li>(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)</li> </ul> </li> <li>Send me a pull request. Bonus points for topic branches.</li> </ul> <h2 id="Credits">Credits</h2> <p>Copyright (c) 2009 Kematzy [ kematzy gmail com ]</p> <h2 id="Licence">Licence</h2> <p>Released under the MIT license.</p></div></div> <div id="footer"> Generated on Fri Sep 18 11:35:04 2026 by <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a> 0.9.45 (ruby-4.0.7). </div> </div> </body> </html>