jcnetdev-shoulda 4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +12 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +123 -0
  4. data/Rakefile +32 -0
  5. data/bin/convert_to_should_syntax +40 -0
  6. data/init.rb +1 -0
  7. data/lib/shoulda.rb +43 -0
  8. data/lib/shoulda/active_record_helpers.rb +670 -0
  9. data/lib/shoulda/color.rb +77 -0
  10. data/lib/shoulda/controller_tests/controller_tests.rb +467 -0
  11. data/lib/shoulda/controller_tests/formats/html.rb +201 -0
  12. data/lib/shoulda/controller_tests/formats/xml.rb +170 -0
  13. data/lib/shoulda/gem/proc_extensions.rb +14 -0
  14. data/lib/shoulda/gem/shoulda.rb +246 -0
  15. data/lib/shoulda/general.rb +118 -0
  16. data/lib/shoulda/private_helpers.rb +22 -0
  17. data/rails/init.rb +1 -0
  18. data/shoulda.gemspec +109 -0
  19. data/tasks/list_tests.rake +23 -0
  20. data/tasks/yaml_to_shoulda.rake +28 -0
  21. data/test/README +36 -0
  22. data/test/fixtures/addresses.yml +3 -0
  23. data/test/fixtures/posts.yml +5 -0
  24. data/test/fixtures/taggings.yml +0 -0
  25. data/test/fixtures/tags.yml +9 -0
  26. data/test/fixtures/users.yml +6 -0
  27. data/test/functional/posts_controller_test.rb +43 -0
  28. data/test/functional/users_controller_test.rb +36 -0
  29. data/test/other/context_test.rb +115 -0
  30. data/test/other/helpers_test.rb +80 -0
  31. data/test/other/private_helpers_test.rb +26 -0
  32. data/test/rails_root/app/controllers/application.rb +25 -0
  33. data/test/rails_root/app/controllers/posts_controller.rb +78 -0
  34. data/test/rails_root/app/controllers/users_controller.rb +81 -0
  35. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  36. data/test/rails_root/app/helpers/posts_helper.rb +2 -0
  37. data/test/rails_root/app/helpers/users_helper.rb +2 -0
  38. data/test/rails_root/app/models/address.rb +4 -0
  39. data/test/rails_root/app/models/dog.rb +4 -0
  40. data/test/rails_root/app/models/flea.rb +3 -0
  41. data/test/rails_root/app/models/post.rb +11 -0
  42. data/test/rails_root/app/models/tag.rb +8 -0
  43. data/test/rails_root/app/models/tagging.rb +4 -0
  44. data/test/rails_root/app/models/user.rb +17 -0
  45. data/test/rails_root/app/views/layouts/posts.rhtml +17 -0
  46. data/test/rails_root/app/views/layouts/users.rhtml +17 -0
  47. data/test/rails_root/app/views/posts/edit.rhtml +27 -0
  48. data/test/rails_root/app/views/posts/index.rhtml +25 -0
  49. data/test/rails_root/app/views/posts/new.rhtml +26 -0
  50. data/test/rails_root/app/views/posts/show.rhtml +18 -0
  51. data/test/rails_root/app/views/users/edit.rhtml +22 -0
  52. data/test/rails_root/app/views/users/index.rhtml +22 -0
  53. data/test/rails_root/app/views/users/new.rhtml +21 -0
  54. data/test/rails_root/app/views/users/show.rhtml +13 -0
  55. data/test/rails_root/config/boot.rb +109 -0
  56. data/test/rails_root/config/database.yml +4 -0
  57. data/test/rails_root/config/environment.rb +18 -0
  58. data/test/rails_root/config/environments/sqlite3.rb +0 -0
  59. data/test/rails_root/config/initializers/new_rails_defaults.rb +15 -0
  60. data/test/rails_root/config/routes.rb +6 -0
  61. data/test/rails_root/db/migrate/001_create_users.rb +17 -0
  62. data/test/rails_root/db/migrate/002_create_posts.rb +13 -0
  63. data/test/rails_root/db/migrate/003_create_taggings.rb +12 -0
  64. data/test/rails_root/db/migrate/004_create_tags.rb +11 -0
  65. data/test/rails_root/db/migrate/005_create_dogs.rb +11 -0
  66. data/test/rails_root/db/migrate/006_create_addresses.rb +13 -0
  67. data/test/rails_root/db/migrate/007_create_fleas.rb +11 -0
  68. data/test/rails_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  69. data/test/rails_root/db/migrate/009_add_ssn_to_users.rb +9 -0
  70. data/test/rails_root/db/schema.rb +0 -0
  71. data/test/rails_root/log/.keep +0 -0
  72. data/test/rails_root/public/.htaccess +40 -0
  73. data/test/rails_root/public/404.html +30 -0
  74. data/test/rails_root/public/422.html +30 -0
  75. data/test/rails_root/public/500.html +30 -0
  76. data/test/rails_root/script/console +3 -0
  77. data/test/rails_root/script/generate +3 -0
  78. data/test/rails_root/vendor/plugins/.keep +0 -0
  79. data/test/test_helper.rb +35 -0
  80. data/test/unit/address_test.rb +7 -0
  81. data/test/unit/dog_test.rb +7 -0
  82. data/test/unit/flea_test.rb +7 -0
  83. data/test/unit/post_test.rb +14 -0
  84. data/test/unit/tag_test.rb +12 -0
  85. data/test/unit/tagging_test.rb +8 -0
  86. data/test/unit/user_test.rb +32 -0
  87. metadata +148 -0
@@ -0,0 +1,115 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ContextTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "context with setup block" do
6
+ setup do
7
+ @blah = "blah"
8
+ end
9
+
10
+ should "have @blah == 'blah'" do
11
+ assert_equal "blah", @blah
12
+ end
13
+
14
+ should "have name set right" do
15
+ assert_match(/^test: context with setup block/, self.to_s)
16
+ end
17
+
18
+ context "and a subcontext" do
19
+ setup do
20
+ @blah = "#{@blah} twice"
21
+ end
22
+
23
+ should "be named correctly" do
24
+ assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
25
+ end
26
+
27
+ should "run the setup methods in order" do
28
+ assert_equal @blah, "blah twice"
29
+ end
30
+ end
31
+ end
32
+
33
+ context "another context with setup block" do
34
+ setup do
35
+ @blah = "foo"
36
+ end
37
+
38
+ should "have @blah == 'foo'" do
39
+ assert_equal "foo", @blah
40
+ end
41
+
42
+ should "have name set right" do
43
+ assert_match(/^test: another context with setup block/, self.to_s)
44
+ end
45
+ end
46
+
47
+ context "context with method definition" do
48
+ setup do
49
+ def hello; "hi"; end
50
+ end
51
+
52
+ should "be able to read that method" do
53
+ assert_equal "hi", hello
54
+ end
55
+
56
+ should "have name set right" do
57
+ assert_match(/^test: context with method definition/, self.to_s)
58
+ end
59
+ end
60
+
61
+ context "another context" do
62
+ should "not define @blah" do
63
+ assert_nil @blah
64
+ end
65
+ end
66
+
67
+ context "context with multiple setups and/or teardowns" do
68
+
69
+ cleanup_count = 0
70
+
71
+ 2.times do |i|
72
+ setup { cleanup_count += 1 }
73
+ teardown { cleanup_count -= 1 }
74
+ end
75
+
76
+ 2.times do |i|
77
+ should "call all setups and all teardowns (check ##{i + 1})" do
78
+ assert_equal 2, cleanup_count
79
+ end
80
+ end
81
+
82
+ context "subcontexts" do
83
+
84
+ 2.times do |i|
85
+ setup { cleanup_count += 1 }
86
+ teardown { cleanup_count -= 1 }
87
+ end
88
+
89
+ 2.times do |i|
90
+ should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
91
+ assert_equal 4, cleanup_count
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+
99
+ should_eventually "pass, since it's unimplemented" do
100
+ flunk "what?"
101
+ end
102
+
103
+ should_eventually "not require a block when using should_eventually"
104
+ should "pass without a block, as that causes it to piggyback to should_eventually"
105
+
106
+ context "context for testing should piggybacking" do
107
+ should "call should_eventually as we are not passing a block"
108
+ end
109
+
110
+ context "context" do
111
+ context "with nested subcontexts" do
112
+ should_eventually "only print this statement once for a should_eventually"
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+ require 'action_mailer'
3
+ require 'mocha'
4
+
5
+ class HelpersTest < Test::Unit::TestCase # :nodoc:
6
+
7
+ context "given delivered emails" do
8
+ setup do
9
+ email1 = stub(:subject => "one", :to => ["none1@email.com"])
10
+ email2 = stub(:subject => "two", :to => ["none2@email.com"])
11
+ ActionMailer::Base.stubs(:deliveries).returns([email1, email2])
12
+ end
13
+
14
+ should "have sent an email" do
15
+ assert_sent_email
16
+
17
+ assert_raises(Test::Unit::AssertionFailedError) do
18
+ assert_did_not_send_email
19
+ end
20
+ end
21
+
22
+ should "find email one" do
23
+ assert_sent_email do |e|
24
+ e.subject =~ /one/
25
+ end
26
+ end
27
+
28
+ should "not find an email that doesn't exist" do
29
+ assert_raises(Test::Unit::AssertionFailedError) do
30
+ assert_sent_email do |e|
31
+ e.subject =~ /whatever/
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ context "when there are no emails" do
38
+ setup do
39
+ ActionMailer::Base.stubs(:deliveries).returns([])
40
+ end
41
+
42
+ should "not have sent an email" do
43
+ assert_did_not_send_email
44
+
45
+ assert_raises(Test::Unit::AssertionFailedError) do
46
+ assert_sent_email
47
+ end
48
+ end
49
+ end
50
+
51
+ context "an array of values" do
52
+ setup do
53
+ @a = ['abc', 'def', 3]
54
+ end
55
+
56
+ [/b/, 'abc', 3].each do |x|
57
+ should "contain #{x.inspect}" do
58
+ assert_raises(Test::Unit::AssertionFailedError) do
59
+ assert_does_not_contain @a, x
60
+ end
61
+ assert_contains @a, x
62
+ end
63
+ end
64
+
65
+ should "not contain 'wtf'" do
66
+ assert_raises(Test::Unit::AssertionFailedError) {assert_contains @a, 'wtf'}
67
+ assert_does_not_contain @a, 'wtf'
68
+ end
69
+
70
+ should "be the same as another array, ordered differently" do
71
+ assert_same_elements(@a, [3, "def", "abc"])
72
+ assert_raises(Test::Unit::AssertionFailedError) do
73
+ assert_same_elements(@a, [3, 3, "def", "abc"])
74
+ end
75
+ assert_raises(Test::Unit::AssertionFailedError) do
76
+ assert_same_elements([@a, "abc"].flatten, [3, 3, "def", "abc"])
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class PrivateHelpersTest < Test::Unit::TestCase # :nodoc:
4
+ include ThoughtBot::Shoulda::ActiveRecord
5
+ context "get_options!" do
6
+ should "remove opts from args" do
7
+ args = [:a, :b, {}]
8
+ get_options!(args)
9
+ assert_equal [:a, :b], args
10
+ end
11
+
12
+ should "return wanted opts in order" do
13
+ args = [{:one => 1, :two => 2}]
14
+ one, two = get_options!(args, :one, :two)
15
+ assert_equal 1, one
16
+ assert_equal 2, two
17
+ end
18
+
19
+ should "raise ArgumentError if given unwanted option" do
20
+ args = [{:one => 1, :two => 2}]
21
+ assert_raises ArgumentError do
22
+ get_options!(args, :one)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ # Pick a unique cookie name to distinguish our session data from others'
6
+ session :session_key => '_rails_root_session_id'
7
+
8
+ def ensure_logged_in
9
+ unless session[:logged_in]
10
+ respond_to do |accepts|
11
+ accepts.html do
12
+ flash[:error] = 'What do you think you\'re doing?'
13
+ redirect_to '/'
14
+ end
15
+ accepts.xml do
16
+ headers["Status"] = "Unauthorized"
17
+ headers["WWW-Authenticate"] = %(Basic realm="Web Password")
18
+ render :text => "Couldn't authenticate you", :status => '401 Unauthorized'
19
+ end
20
+ end
21
+ return false
22
+ end
23
+ return true
24
+ end
25
+ end
@@ -0,0 +1,78 @@
1
+ class PostsController < ApplicationController
2
+ before_filter :ensure_logged_in
3
+ before_filter :load_user
4
+
5
+ def index
6
+ @posts = @user.posts
7
+
8
+ respond_to do |format|
9
+ format.html # index.rhtml
10
+ format.xml { render :xml => @posts.to_xml }
11
+ end
12
+ end
13
+
14
+ def show
15
+ @post = @user.posts.find(params[:id])
16
+
17
+ respond_to do |format|
18
+ format.html # show.rhtml
19
+ format.xml { render :xml => @post.to_xml }
20
+ end
21
+ end
22
+
23
+ def new
24
+ @post = @user.posts.build
25
+ end
26
+
27
+ def edit
28
+ @post = @user.posts.find(params[:id])
29
+ end
30
+
31
+ def create
32
+ @post = @user.posts.build(params[:post])
33
+
34
+ respond_to do |format|
35
+ if @post.save
36
+ flash[:notice] = 'Post was successfully created.'
37
+ format.html { redirect_to user_post_url(@post.user, @post) }
38
+ format.xml { head :created, :location => user_post_url(@post.user, @post) }
39
+ else
40
+ format.html { render :action => "new" }
41
+ format.xml { render :xml => @post.errors.to_xml }
42
+ end
43
+ end
44
+ end
45
+
46
+ def update
47
+ @post = @user.posts.find(params[:id])
48
+
49
+ respond_to do |format|
50
+ if @post.update_attributes(params[:post])
51
+ flash[:notice] = 'Post was successfully updated.'
52
+ format.html { redirect_to user_post_url(@post.user, @post) }
53
+ format.xml { head :ok }
54
+ else
55
+ format.html { render :action => "edit" }
56
+ format.xml { render :xml => @post.errors.to_xml }
57
+ end
58
+ end
59
+ end
60
+
61
+ def destroy
62
+ @post = @user.posts.find(params[:id])
63
+ @post.destroy
64
+
65
+ flash[:notice] = "Post was removed"
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to user_posts_url(@post.user) }
69
+ format.xml { head :ok }
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def load_user
76
+ @user = User.find(params[:user_id])
77
+ end
78
+ end
@@ -0,0 +1,81 @@
1
+ class UsersController < ApplicationController
2
+ # GET /users
3
+ # GET /users.xml
4
+ def index
5
+ @users = User.find(:all)
6
+
7
+ respond_to do |format|
8
+ format.html # index.rhtml
9
+ format.xml { render :xml => @users.to_xml }
10
+ end
11
+ end
12
+
13
+ # GET /users/1
14
+ # GET /users/1.xml
15
+ def show
16
+ @user = User.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.rhtml
20
+ format.xml { render :xml => @user.to_xml }
21
+ end
22
+ end
23
+
24
+ # GET /users/new
25
+ def new
26
+ @user = User.new
27
+ end
28
+
29
+ # GET /users/1;edit
30
+ def edit
31
+ @user = User.find(params[:id])
32
+ end
33
+
34
+ # POST /users
35
+ # POST /users.xml
36
+ def create
37
+ @user = User.new(params[:user])
38
+
39
+ respond_to do |format|
40
+ if @user.save
41
+ flash[:notice] = 'User was successfully created.'
42
+ format.html { redirect_to user_url(@user) }
43
+ format.xml { head :created, :location => user_url(@user) }
44
+ else
45
+ format.html { render :action => "new" }
46
+ format.xml { render :xml => @user.errors.to_xml }
47
+ end
48
+ end
49
+ end
50
+
51
+ # PUT /users/1
52
+ # PUT /users/1.xml
53
+ def update
54
+ @user = User.find(params[:id])
55
+
56
+ respond_to do |format|
57
+ if @user.update_attributes(params[:user])
58
+ flash[:notice] = 'User was successfully updated.'
59
+ format.html { redirect_to user_url(@user) }
60
+ format.xml { head :ok }
61
+ else
62
+ format.html { render :action => "edit" }
63
+ format.xml { render :xml => @user.errors.to_xml }
64
+ end
65
+ end
66
+ end
67
+
68
+ # DELETE /users/1
69
+ # DELETE /users/1.xml
70
+ def destroy
71
+ @user = User.find(params[:id])
72
+ @user.destroy
73
+
74
+ flash[:notice] = "User was removed"
75
+
76
+ respond_to do |format|
77
+ format.html { redirect_to users_url }
78
+ format.xml { head :ok }
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,2 @@
1
+ module PostsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,4 @@
1
+ class Address < ActiveRecord::Base
2
+ belongs_to :addressable, :polymorphic => true
3
+ validates_uniqueness_of :title, :scope => [:addressable_type, :addressable_id]
4
+ end
@@ -0,0 +1,4 @@
1
+ class Dog < ActiveRecord::Base
2
+ belongs_to :user, :foreign_key => :owner_id
3
+ has_and_belongs_to_many :fleas
4
+ end
@@ -0,0 +1,3 @@
1
+ class Flea < ActiveRecord::Base
2
+ has_and_belongs_to_many :dogs
3
+ end
@@ -0,0 +1,11 @@
1
+ class Post < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :owner, :foreign_key => :user_id, :class_name => 'User'
4
+ has_many :taggings
5
+ has_many :tags, :through => :taggings
6
+
7
+ validates_uniqueness_of :title
8
+ validates_presence_of :title
9
+ validates_presence_of :body, :message => 'Seriously... wtf'
10
+ validates_numericality_of :user_id
11
+ end