Permalink
Browse files

Tons of documentation

git-svn-id: https://svn.thoughtbot.com/plugins/shoulda/trunk@146 7bbfaf0e-4d1d-0410-9690-a8bb5f8ef2aa
  • Loading branch information...
1 parent f00bddd commit 0ea1fc75c081d39db07a75722a3b509fa9dd14d9 tsaleh committed Jul 24, 2007
View
130 README
@@ -1,17 +1,123 @@
-= ThoughtBot Test Helpers
+= Shoulda
-A collection of Test::Unit helper methods.
+Shoulda makes it easy to write elegant, understandable, and maintainable tests. Shoulda consists of test macros, assertions, and helpers added on to the Test::Unit framework. It's fully compatible with your existing tests, and requires no retooling to use.
-Adds helpers for
+Helpers:: #context and #should give you rSpec like test blocks.
+ In addition, you get nested contexts and a much more readable syntax.
+Macros:: Generate hundreds of lines of Controller and ActiveRecord tests with these powerful macros.
+ They get you started quickly, and can help you ensure that your application is conforming to best practices.
+Assertions:: Many common rails testing idioms have been distilled into a set of useful assertions.
-* context and should statements
-* Common ActiveRecord model tests
-* A few general purpose assertions
+= Usage
+
+=== Context Helpers (ThoughtBot::Shoulda::Context)
+
+Stop killing your fingers with all of those underscores... Name your tests with plain sentences!
+
+ class UserTest << Test::Unit
+ context "A User instance" do
+ setup do
+ @user = User.find(:first)
+ end
+
+ should "return its full name"
+ assert_equal 'John Doe', @user.full_name
+ end
+
+ context "with a profile" do
+ setup do
+ @user.profile = Profile.find(:first)
+ end
+
+ should "return true when sent #has_profile?"
+ assert @user.has_profile?
+ end
+ end
+ end
+ end
+
+Produces the following test methods:
+
+ "test: A User instance should return its full name."
+ "test: A User instance with a profile should return true when sent #has_profile?."
+
+So readable!
+
+=== ActiveRecord Tests (ThoughtBot::Shoulda::ActiveRecord)
+
+Quick macro tests for your ActiveRecord associations and validations:
+
+ class PostTest < Test::Unit::TestCase
+ load_all_fixtures
+
+ should_belong_to :user
+ should_have_many :tags, :through => :taggings
+
+ should_require_unique_attributes :title
+ should_require_attributes :body, :message => /wtf/
+ should_require_attributes :title
+ should_only_allow_numeric_values_for :user_id
+ end
+
+ class UserTest < Test::Unit::TestCase
+ load_all_fixtures
+
+ should_have_many :posts
+
+ should_not_allow_values_for :email, "blah", "b lah"
+ should_allow_values_for :email, "a@b.com", "asdf@asdf.com"
+ should_ensure_length_in_range :email, 1..100
+ should_ensure_value_in_range :age, 1..100
+ should_protect_attributes :password
+ end
+
+Makes TDD so much easier.
+
+=== Controller Tests (ThoughtBot::Shoulda::Controller::ClassMethods)
+
+Macros to test the most common controller patterns...
+
+ context "on GET to :show for first record" do
+ setup do
+ get :show, :id => 1
+ end
-== Todo
+ should_assign_to :user
+ should_respond_with :success
+ should_render_template :show
+ should_not_set_the_flash
+
+ should "do something else really cool" do
+ assert_equal 1, assigns(:user).id
+ end
+ end
+
+Test entire controllers in a few lines...
+
+ class PostsControllerTest < Test::Unit::TestCase
+ should_be_restful do |resource|
+ resource.parent = :user
+
+ resource.create.params = { :title => "first post", :body => 'blah blah blah'}
+ resource.update.params = { :title => "changed" }
+ end
+ end
+
+should_be_restful generates 40 tests on the fly, for both html and xml requests.
+
+=== Helpful Assertions (ThoughtBot::Shoulda::General)
+
+More to come here, but have fun with what's there.
+
+ load_all_fixtures
+ assert_same_elements([:a, :b, :c], [:c, :a, :b])
+ assert_contains(['a', '1'], /\d/)
+ assert_contains(['a', '1'], 'a')
+
+= Credits
+
+Shoulda is maintained by {Tammer Saleh}[mailto:tsaleh@thoughtbot.com], and is funded by Thoughtbot[http://www.thoughtbot.com], inc.
+
+= License
-* Many more tests (of the tests). Specifically, the ActiveRecord macros need to be tested.
-* Controller test helpers
-* General code cleanups
-* More options for AR helpers
-
+Shoulda is Copyright © 2006-2007 Tammer Saleh, Thoughtbot. It is free software, and may be redistributed under the terms specified in the README file of the Ruby distribution.
View
@@ -22,9 +22,9 @@
require 'shoulda/color' if shoulda_options[:color]
-module Test # :nodoc:
- module Unit # :nodoc:
- class TestCase # :nodoc:
+module Test # :nodoc: all
+ module Unit
+ class TestCase
include ThoughtBot::Shoulda::Controller
include ThoughtBot::Shoulda::General
@@ -38,10 +38,10 @@ class << self
end
end
-module ActionController #:nodoc:
- module Integration #:nodoc:
- class Session #:nodoc:
- include ThoughtBot::Shoulda::General::InstanceMethods
+module ActionController #:nodoc: all
+ module Integration
+ class Session
+ include ThoughtBot::Shoulda::General
end
end
end
View
@@ -3,7 +3,7 @@
# Completely stolen from redgreen gem
#
# Adds colored output to your tests. Specify <tt>color: true</tt> in
-# your <tt>test/shoulda.conf</tt> file to enable.
+# your <tt>~/.shoulda.conf</tt> file to enable.
#
# *Bug*: for some reason, this adds another line of output to the end of
# every rake task, as though there was another (empty) set of tests.
View
@@ -2,9 +2,9 @@ module ThoughtBot # :nodoc:
module Shoulda # :nodoc:
# = context and should blocks
#
- # A context block can exist next to normal <tt>def test_blah</tt> statements,
- # meaning you do not have to fully commit to the context/should syntax in a test file. We have been
- # using this syntax at ThoughtBot, though, and find it very readable.
+ # A context block groups should statements under a common setup/teardown method.
+ # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
+ # and readability of your test code.
#
# A context block can contain setup, should, should_eventually, and teardown blocks.
#
@@ -20,7 +20,7 @@ module Shoulda # :nodoc:
# end
# end
#
- # This code will produce the method <tt>"test a User instance should return its full name"</tt> (yes, with spaces in the name).
+ # This code will produce the method <tt>"test a User instance should return its full name"</tt>.
#
# Contexts may be nested. Nested contexts run their setup blocks from out to in before each test.
# They then run their teardown blocks from in to out after each test.
@@ -48,8 +48,11 @@ module Shoulda # :nodoc:
# end
#
# This code will produce the following methods
- # * <tt>"test a User instance should return its full name"</tt>
- # * <tt>"test a User instance with a profile should return true when sent :has_profile?"</tt> (which will have both setup blocks run before it.)
+ # * <tt>"test: a User instance should return its full name."</tt>
+ # * <tt>"test: a User instance with a profile should return true when sent :has_profile?."</tt>
+ #
+ # <b>A context block can exist next to normal <tt>def test_the_old_way; end</tt> tests</b>,
+ # meaning you do not have to fully commit to the context/should syntax in a test file.
#
module Context
@@ -59,32 +62,20 @@ def Context.included(other) # :nodoc:
@@teardown_blocks = []
end
- # Creates a context block with the given name.
- def context(name, &context_block)
- saved_setups = @@setup_blocks.dup
- saved_teardowns = @@teardown_blocks.dup
- saved_contexts = @@context_names.dup
-
- @@context_names << name
- context_block.bind(self).call
-
- @@context_names = saved_contexts
- @@setup_blocks = saved_setups
- @@teardown_blocks = saved_teardowns
- end
-
- # Run before every should block in the current context
- def setup(&setup_block)
- @@setup_blocks << setup_block
- end
-
- # Run after every should block in the current context
- def teardown(&teardown_block)
- @@teardown_blocks << teardown_block
- end
-
- # Defines a test. Can be called either inside our outside of a context.
- # Optionally specify <tt>:unimplimented => true</tt> (see should_eventually)
+ # Defines a test method. Can be called either inside our outside of a context.
+ # Optionally specify <tt>:unimplimented => true</tt> (see should_eventually).
+ #
+ # Example:
+ #
+ # class UserTest << Test::Unit
+ # should "return first user on find(:first)"
+ # assert_equal users(:first), User.find(:first)
+ # end
+ # end
+ #
+ # Would create a test named
+ # 'test: should return first user on find(:first)'
+ #
def should(name, opts = {}, &should_block)
test_name = ["test:", @@context_names, "should", "#{name}. "].flatten.join(' ').to_sym
@@ -112,8 +103,38 @@ def should(name, opts = {}, &should_block)
end
end
+ # Creates a context block with the given name.
+ def context(name, &context_block)
+ saved_setups = @@setup_blocks.dup
+ saved_teardowns = @@teardown_blocks.dup
+ saved_contexts = @@context_names.dup
+
+ @@context_names << name
+ context_block.bind(self).call
+
+ @@context_names = saved_contexts
+ @@setup_blocks = saved_setups
+ @@teardown_blocks = saved_teardowns
+ end
+
+ # Run before every should block in the current context.
+ # If a setup block appears in a nested context, it will be run after the setup blocks
+ # in the parent contexts.
+ def setup(&setup_block)
+ @@setup_blocks << setup_block
+ end
+
+ # Run after every should block in the current context.
+ # If a teardown block appears in a nested context, it will be run before the teardown
+ # blocks in the parent contexts.
+ def teardown(&teardown_block)
+ @@teardown_blocks << teardown_block
+ end
+
# Defines a specification that is not yet implemented.
# Will be displayed as an 'X' when running tests, and failures will not be shown.
+ # This is equivalent to:
+ # should(name, {:unimplemented => true}, &block)
def should_eventually(name, &block)
should("eventually #{name}", {:unimplemented => true}, &block)
end
Oops, something went wrong.

0 comments on commit 0ea1fc7

Please sign in to comment.