test_spec_on_rails 1.1.0

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 (38) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGELOG +21 -0
  3. data/README.markdown +247 -0
  4. data/Rakefile +40 -0
  5. data/VERSION +1 -0
  6. data/lib/generators/controller/USAGE +29 -0
  7. data/lib/generators/controller/controller_generator.rb +37 -0
  8. data/lib/generators/controller/templates/controller.rb +10 -0
  9. data/lib/generators/controller/templates/functional_test.rb +8 -0
  10. data/lib/generators/controller/templates/helper.rb +2 -0
  11. data/lib/generators/controller/templates/view.html.erb +2 -0
  12. data/lib/generators/model/USAGE +27 -0
  13. data/lib/generators/model/model_generator.rb +45 -0
  14. data/lib/generators/model/templates/fixtures.yml +19 -0
  15. data/lib/generators/model/templates/migration.rb +16 -0
  16. data/lib/generators/model/templates/model.rb +2 -0
  17. data/lib/generators/model/templates/unit_test.rb +8 -0
  18. data/lib/test/spec/rails.rb +30 -0
  19. data/lib/test/spec/rails/convenience.rb +38 -0
  20. data/lib/test/spec/rails/dummy_response.rb +21 -0
  21. data/lib/test/spec/rails/should_redirect.rb +33 -0
  22. data/lib/test/spec/rails/should_render.rb +25 -0
  23. data/lib/test/spec/rails/should_route.rb +34 -0
  24. data/lib/test/spec/rails/should_select.rb +53 -0
  25. data/lib/test/spec/rails/should_validate.rb +16 -0
  26. data/lib/test/spec/rails/should_validate_presence_of.rb +27 -0
  27. data/lib/test/spec/rails/test_dummy.rb +46 -0
  28. data/lib/test/spec/rails/test_layout.rb +15 -0
  29. data/lib/test/spec/rails/test_spec_ext.rb +48 -0
  30. data/lib/test/spec/rails/test_status.rb +15 -0
  31. data/lib/test/spec/rails/test_template.rb +14 -0
  32. data/lib/test/spec/rails/test_unit_ext.rb +32 -0
  33. data/lib/test/spec/rails/test_url.rb +25 -0
  34. data/lib/test/spec/rails/use_controller.rb +51 -0
  35. data/tasks/spec.rake +15 -0
  36. data/test/test/spec/rails/test_status_test.rb +22 -0
  37. data/test/test_helper.rb +6 -0
  38. metadata +92 -0
@@ -0,0 +1,5 @@
1
+ .svn
2
+ <<<<<<< HEAD:.gitignore
3
+ =======
4
+ .svn/*
5
+ >>>>>>> b5e4da7269801960e95c60b3aa6e3b95d4f3dd77:.gitignore
@@ -0,0 +1,21 @@
1
+ 12/03/09 - Is now a gem [Matthew Bass]
2
+
3
+ 07/01/08 - should.render now takes optional response code [Matthew Bass]
4
+
5
+ 06/28/08 - Added should.render for testing template rendering [Matthew Bass]
6
+
7
+ 05/15/08 - First pass at overriding generators to produce specs [Matthew Bass]
8
+
9
+ 03/18/08 - it_should_validate_presence_of helper added [Matthew Bass]
10
+
11
+ 03/12/08 - layout.should.be nil is now supported [Rob Sanheim]
12
+
13
+ 03/11/08 - Added content_type attr to dummy response for Rails 2.0 [Jason Rudolph]
14
+
15
+ 03/06/08 - Added should.differ(:method).by wrapper for assert_difference [Matthew Bass]
16
+
17
+ 02/18/08 - Added Rakefile, began adding tests [Matthew Bass]
18
+
19
+ 02/08/08 - Added support for route checking (i.e. assert_generates) [Jason Rudolph]
20
+
21
+ 01/10/08 - Added CHANGELOG and LICENSE [Matthew Bass]
@@ -0,0 +1,247 @@
1
+ test/spec/rails
2
+ ---------------
3
+
4
+ This plugin contain some helpers to test your Rails app using test/spec.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ * Install test/spec: gem install test-spec
10
+ * Install test/spec/rails
11
+ * require 'test/spec/rails' in your test_helper.rb
12
+
13
+
14
+ Dependencies
15
+ ------------
16
+
17
+ If you want to run the plugin's tests, you'll need these gems:
18
+
19
+ * multi_rails
20
+ * mocha
21
+
22
+ Then run "rake test:multi_rails:all" from the root of the project. The tests will be
23
+ executed against each version of Rails you have installed on your system.
24
+
25
+
26
+ Source
27
+ ------
28
+
29
+ test/spec/rails uses Git for source control. If you're running edge Rails you can install with:
30
+
31
+ script/plugin install git://github.com/pelargir/test_spec_on_rails.git
32
+
33
+ Otherwise just clone the project directly:
34
+
35
+ git clone git://github.com/pelargir/test_spec_on_rails.git vendor/plugins/test_spec_on_rails
36
+
37
+
38
+ Model validation
39
+ ----------------
40
+
41
+ @user.should.validate
42
+ @user.should.not.validate
43
+
44
+ OR:
45
+
46
+ @user.should.be.validated
47
+ @user.should.not.be.validated
48
+
49
+
50
+ Redirection
51
+ -----------
52
+
53
+ response.should.be.redirected # assert_response :redirect
54
+ response.should.redirect foo_url(@foo) # assert_redirected_to foo_url(@foo)
55
+ should.redirect_to :action => 'show' # because "response" is optional
56
+
57
+ It's aliased as redirect, redirect_to, redirected and redirected_to
58
+
59
+
60
+ Output verification
61
+ -------------------
62
+
63
+ Wrapper for assert_select:
64
+
65
+ get :show
66
+ page.should.select "form#user_form" # require the output to have a <form id="user_form">
67
+ # you can also do:
68
+ page.should.have "form#user_form"
69
+ page.should.contain "form#user_form"
70
+
71
+ page.should.select "form#user_form" do |form|
72
+ # the user_form must include a <input type="submit">
73
+ form.should.select "input[type=submit]"
74
+ end
75
+
76
+
77
+ HTTP Status
78
+ -----------
79
+
80
+ Wrapper for assert_response:
81
+
82
+ status.should.be :success
83
+ status.should.be 200
84
+
85
+
86
+ Which template was rendered?
87
+ ----------------------------
88
+
89
+ Wrapper for assert_template:
90
+
91
+ template.should.be "foo/show.rhtml"
92
+
93
+
94
+ Which layout used?
95
+ ------------------
96
+
97
+ Wrapper for asserting that a certain layout is used:
98
+
99
+ layout.should.be "foo"
100
+
101
+
102
+ URL testing
103
+ -----------
104
+
105
+ get :show, :user_id => 1
106
+ url.should.be "/users/1"
107
+ url.should.be :controller => "users", :action => "show", :user_id => 1
108
+
109
+
110
+ Difference
111
+ ----------
112
+
113
+ Wrapper for assert_difference:
114
+
115
+ Article.should.differ(:count).by(2) { blah }
116
+
117
+
118
+ Routing to set of url options from a given path (i.e., #assert_generates)
119
+ -------------------------------------------------------------------------
120
+
121
+ assert_generates "/users/1", :controller => "users", :action => "show", :id => "1"
122
+
123
+ BECOMES
124
+
125
+ {:controller => "users", :action => "show", :id => "1"}.should.route_to "/users/1"
126
+
127
+
128
+ Routing from a set of url options to an expected path (i.e., #assert_recognizes)
129
+ --------------------------------------------------------------------------------
130
+
131
+ assert_recognizes({:controller => "users", :action => "show", :id => "1"}, {:path => "/users/1", :method => :get})
132
+
133
+ BECOMES
134
+
135
+ {:path => "/users/1", :method => :get}.should.route_from :controller => "users", :action => "show", :id =>"1"
136
+
137
+
138
+ Setup controller for testing + example usage
139
+ --------------------------------------------
140
+
141
+ context "A guest" do
142
+ use_controller FooController # => you can also do use_controller :foo
143
+
144
+ specify "isn't allowed to foo" do
145
+ post :create, :foo => 'bar'
146
+ flash[:error].should.not.be.blank
147
+ response.should.redirect :controller => 'front', :action => 'show'
148
+ assigns(:foo).errors.on(:bar).should.not.be.blank
149
+ assigns(:foo).should.not.validate
150
+ follow_redirect
151
+ page.should.select "#errors", :text => /#{flash[:error]}/
152
+ end
153
+ end
154
+
155
+ context "Tuxie" do
156
+ setup do
157
+ use_controller FooController
158
+ login_as :tuxie
159
+ end
160
+
161
+ specify "may foo" do
162
+ post :create, :foo => 'bar'
163
+ flash[:notice].should.not.be.blank
164
+ assigns(:foo).errors.should.be.empty
165
+ assigns(:foo).should.validate
166
+ should.redirect_to :action => 'show'
167
+ follow_redirect
168
+ page.should.select "#notice", :text => /#{flash[:notice]}/
169
+ end
170
+ end
171
+
172
+
173
+ Misc
174
+ ----
175
+
176
+ page, response and request are just aliases for self (the TestCase) so the following
177
+ are functionally identical:
178
+
179
+ page.should.redirect
180
+ response.should.redirect
181
+ request.should.redirect
182
+
183
+ output, body, html and xhtml return @response.body so the following lines are identical:
184
+
185
+ output.should.match /foo/
186
+ html.should.match /foo/
187
+ xhtml.should.match /foo/
188
+ body.should.match /foo/
189
+
190
+ If an object respond to #should_equal, that method will be used instead of assert_equal
191
+ when using foo.should.equal(bar) or foo.should.be(bar)
192
+ foo.should.not.equal and foo.should.not.be look for #should_not_equal
193
+
194
+
195
+ Convenience and Shortcut methods
196
+ --------------------------------
197
+
198
+ Typing in should.not.be.nil all the time can be tiresome and overwhelming, here are some shortcuts that you can use.
199
+
200
+ INSTEAD OF:
201
+
202
+ assigns(:var).should.not.be.nil
203
+
204
+ DO:
205
+
206
+ has(:var) # => assigns(:var).should.not.be.nil
207
+
208
+ OR pass multiple variables to test:
209
+
210
+ has :var, :page_title # => assigns(:var).should.not.be.nil
211
+ # => assigns(:page_title).should.not.be.nil
212
+
213
+ Likewise you can test for the non existence of the variable using cant_have :
214
+
215
+ INSTEAD OF:
216
+
217
+ assigns(:var).should.be.nil
218
+
219
+ DO:
220
+
221
+ cant_have :var
222
+
223
+ OR pass multiple variables to test:
224
+
225
+ cant_have :var, :page_title
226
+
227
+ Shortcuts for checking on flash values:
228
+
229
+ INSTEAD OF:
230
+
231
+ flash[:notice].should.not.be.nil
232
+
233
+ DO:
234
+
235
+ has_flash :notice
236
+
237
+ Sometimes you might want to set the HTTP_REFERER variable when testing response.should.redirect, here's
238
+ an easy way to do it:
239
+
240
+ set_redirect_back "/your/path"
241
+
242
+ Credit
243
+ ------
244
+
245
+ * Created by Per "Tuxie" Wigren <per.wigren@gmail.com>
246
+ * Enhanced by Rick Olson <technoweenie@gmail.com>
247
+ * Currently maintained by Matthew Bass <pelargir@gmail.com>
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'load_multi_rails_rake_tasks'
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the test_spec_on_rails plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation for the test_spec_on_rails plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'ResponseVisualizer'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ begin
27
+ require 'jeweler'
28
+ Jeweler::Tasks.new do |gemspec|
29
+ gemspec.name = "test_spec_on_rails"
30
+ gemspec.summary = "Provides helpers to test your Rails app using test/spec."
31
+ gemspec.description = "Provides helpers to test your Rails app using test/spec."
32
+ gemspec.email = "pelargir@gmail.com"
33
+ gemspec.homepage = "http://github.com/pelargir/test_spec_on_rails"
34
+ gemspec.authors = ["Matthew Bass"]
35
+ end
36
+ rescue LoadError
37
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
38
+ end
39
+
40
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
@@ -0,0 +1,29 @@
1
+ Description:
2
+ Stubs out a new controller and its views. Pass the controller name, either
3
+ CamelCased or under_scored, and a list of views as arguments.
4
+
5
+ To create a controller within a module, specify the controller name as a
6
+ path like 'parent_module/controller_name'.
7
+
8
+ This generates a controller class in app/controllers, view templates in
9
+ app/views/controller_name, a helper class in app/helpers, and a functional
10
+ test suite in test/functional.
11
+
12
+ Example:
13
+ `./script/generate controller CreditCard open debit credit close`
14
+
15
+ Credit card controller with URLs like /credit_card/debit.
16
+ Controller: app/controllers/credit_card_controller.rb
17
+ Views: app/views/credit_card/debit.html.erb [...]
18
+ Helper: app/helpers/credit_card_helper.rb
19
+ Test: test/functional/credit_card_controller_test.rb
20
+
21
+ Modules Example:
22
+ `./script/generate controller 'admin/credit_card' suspend late_fee`
23
+
24
+ Credit card admin controller with URLs /admin/credit_card/suspend.
25
+ Controller: app/controllers/admin/credit_card_controller.rb
26
+ Views: app/views/admin/credit_card/debit.html.erb [...]
27
+ Helper: app/helpers/admin/credit_card_helper.rb
28
+ Test: test/functional/admin/credit_card_controller_test.rb
29
+
@@ -0,0 +1,37 @@
1
+ class ControllerGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+ # Check for class naming collisions.
5
+ m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper"
6
+
7
+ # Controller, helper, views, and test directories.
8
+ m.directory File.join('app/controllers', class_path)
9
+ m.directory File.join('app/helpers', class_path)
10
+ m.directory File.join('app/views', class_path, file_name)
11
+ m.directory File.join('test/functional', class_path)
12
+
13
+ # Controller class, functional test, and helper class.
14
+ m.template 'controller.rb',
15
+ File.join('app/controllers',
16
+ class_path,
17
+ "#{file_name}_controller.rb")
18
+
19
+ m.template 'functional_test.rb',
20
+ File.join('test/functional',
21
+ class_path,
22
+ "#{file_name}_controller_test.rb")
23
+
24
+ m.template 'helper.rb',
25
+ File.join('app/helpers',
26
+ class_path,
27
+ "#{file_name}_helper.rb")
28
+
29
+ # View template for each action.
30
+ actions.each do |action|
31
+ path = File.join('app/views', class_path, file_name, "#{action}.html.erb")
32
+ m.template 'view.html.erb', path,
33
+ :assigns => { :action => action, :path => path }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ class <%= class_name %>Controller < ApplicationController
2
+ <% if options[:scaffold] -%>
3
+ scaffold :<%= singular_name %>
4
+ <% end -%>
5
+ <% for action in actions -%>
6
+
7
+ def <%= action %>
8
+ end
9
+ <% end -%>
10
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
+
3
+ describe "<%= class_name %>Controller", ActionController::TestCase do
4
+ # Replace this with your real tests.
5
+ it "should be true" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ module <%= class_name %>Helper
2
+ end
@@ -0,0 +1,2 @@
1
+ <h1><%= class_name %>#<%= action %></h1>
2
+ <p>Find me in <%= path %></p>
@@ -0,0 +1,27 @@
1
+ Description:
2
+ Stubs out a new model. Pass the model name, either CamelCased or
3
+ under_scored, and an optional list of attribute pairs as arguments.
4
+
5
+ Attribute pairs are column_name:sql_type arguments specifying the
6
+ model's attributes. Timestamps are added by default, so you don't have to
7
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
8
+
9
+ You don't have to think up every attribute up front, but it helps to
10
+ sketch out a few so you can start working with the model immediately.
11
+
12
+ This generates a model class in app/models, a unit test in test/unit,
13
+ a test fixture in test/fixtures/singular_name.yml, and a migration in
14
+ db/migrate.
15
+
16
+ Examples:
17
+ `./script/generate model account`
18
+
19
+ creates an Account model, test, fixture, and migration:
20
+ Model: app/models/account.rb
21
+ Test: test/unit/account_test.rb
22
+ Fixtures: test/fixtures/accounts.yml
23
+ Migration: db/migrate/XXX_add_accounts.rb
24
+
25
+ `./script/generate model post title:string body:text published:boolean`
26
+
27
+ creates a Post model with a string title, text body, and published flag.
@@ -0,0 +1,45 @@
1
+ class ModelGenerator < Rails::Generator::NamedBase
2
+ default_options :skip_timestamps => false, :skip_migration => false, :skip_fixture => false
3
+
4
+ def manifest
5
+ record do |m|
6
+ # Check for class naming collisions.
7
+ m.class_collisions class_path, class_name, "#{class_name}Test"
8
+
9
+ # Model, test, and fixture directories.
10
+ m.directory File.join('app/models', class_path)
11
+ m.directory File.join('test/unit', class_path)
12
+ m.directory File.join('test/fixtures', class_path)
13
+
14
+ # Model class, unit test, and fixtures.
15
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
16
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
17
+
18
+ unless options[:skip_fixture]
19
+ m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
20
+ end
21
+
22
+ unless options[:skip_migration]
23
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
24
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
25
+ }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
26
+ end
27
+ end
28
+ end
29
+
30
+ protected
31
+ def banner
32
+ "Usage: #{$0} #{spec.name} ModelName [field:type, field:type]"
33
+ end
34
+
35
+ def add_options!(opt)
36
+ opt.separator ''
37
+ opt.separator 'Options:'
38
+ opt.on("--skip-timestamps",
39
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
40
+ opt.on("--skip-migration",
41
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
42
+ opt.on("--skip-fixture",
43
+ "Don't generation a fixture file for this model") { |v| options[:skip_fixture] = v}
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+
3
+ <% unless attributes.empty? -%>
4
+ one:
5
+ <% for attribute in attributes -%>
6
+ <%= attribute.name %>: <%= attribute.default %>
7
+ <% end -%>
8
+
9
+ two:
10
+ <% for attribute in attributes -%>
11
+ <%= attribute.name %>: <%= attribute.default %>
12
+ <% end -%>
13
+ <% else -%>
14
+ # one:
15
+ # column: value
16
+ #
17
+ # two:
18
+ # column: value
19
+ <% end -%>
@@ -0,0 +1,16 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% for attribute in attributes -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% unless options[:skip_timestamps] %>
8
+ t.timestamps
9
+ <% end -%>
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= table_name %>
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
+
3
+ describe "<%= class_name %>", ActiveSupport::TestCase do
4
+ # Replace this with your real tests.
5
+ it "should be true" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ require 'test/spec'
2
+
3
+ module Test::Spec::Rails
4
+ VERSION = "0.1"
5
+ end
6
+
7
+ %w(
8
+ test_spec_ext
9
+ test_unit_ext
10
+
11
+ test_dummy
12
+ dummy_response
13
+ test_status
14
+ test_template
15
+ test_layout
16
+
17
+ should_redirect
18
+ should_render
19
+ should_route
20
+ should_select
21
+ should_validate
22
+ should_validate_presence_of
23
+
24
+ use_controller
25
+
26
+ convenience
27
+
28
+ ).each do |file|
29
+ require "test/spec/rails/#{file}"
30
+ end
@@ -0,0 +1,38 @@
1
+ module Convenience
2
+ # convenience helpers, these methods are basically shortcuts to the should methods
3
+
4
+ # shortcut for should.not.be.nil
5
+ # has :page_title => assigns(:page_title).should.not.be.nil
6
+ # OR you can also pass an array of values
7
+ # has :page_title, :user # => assigns(:page_title).should.not.be.nil
8
+ # => assigns(:user).should.not.be.nil
9
+ def has(*var)
10
+ return assigns(var).should.not.be.nil if var.length == 1
11
+ var.each { |v| assigns(v).should.not.be.nil }
12
+ end
13
+
14
+ # shortcut for should.be.nil
15
+ # cant_have :page_title => assigns(:page_title).should.be.nil
16
+ # OR you can pass an array of values
17
+ # cant_have :page_title, :user # => assigns(:page_title).should.be.nil
18
+ # => assigns(:user).should.be.nil
19
+ def cant_have(*var)
20
+ return assigns(var).should.be.nil if var.length == 1
21
+ var.each { |v| assigns(v).should.be.nil }
22
+ end
23
+
24
+ # shortcut for flash[:type].should.not.be.nil
25
+ # has_flash :notice => assigns(flash[:notice]).should.not.be.nil
26
+ def has_flash(flash_type)
27
+ flash[flash_type].should.not.be.nil
28
+ end
29
+
30
+ # shortcut for setting the HTTP_REFERER variable
31
+ # set_redirect_back '/users'
32
+ def set_redirect_back(path="/back/to/path")
33
+ @request.env["HTTP_REFERER"] = path
34
+ end
35
+
36
+ end
37
+
38
+ Test::Unit::TestCase.send(:include, Convenience)
@@ -0,0 +1,21 @@
1
+ module Test::Spec::Rails
2
+ class DummyResponse < TestDummy
3
+
4
+ attr_reader :body, :headers, :content_type
5
+
6
+ def initialize(body, headers=nil)
7
+ if headers.nil?
8
+ response = body.instance_variable_get('@response')
9
+ @body, @headers = response.body, response.headers
10
+ else
11
+ @body, @headers = body, headers
12
+ end
13
+ @response = self
14
+ end
15
+
16
+ def html_document
17
+ @html_document ||= HTML::Document.new(@body)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module Test::Spec::Rails::ShouldRedirect
2
+ # Test that we were redirected somewhere:
3
+ # request.should.redirect
4
+ #
5
+ # Test that we were redirected to a specific url:
6
+ # request.should.redirect :controller => 'foo', :action => 'bar'
7
+ # or:
8
+ # request.should.be.redirected foo_url(@foo)
9
+ #
10
+ def redirect(options = {})
11
+ if options.empty?
12
+ @object.assert_response :redirect
13
+ else
14
+ @object.assert_redirected_to options
15
+ end
16
+ end
17
+ alias :redirect_to :redirect
18
+ alias :redirected :redirect
19
+ alias :redirected_to :redirect
20
+ end
21
+
22
+ module Test::Spec::Rails::ShouldNotRedirect
23
+ # Test that we weren't redirected
24
+ def redirect(options = {})
25
+ @object.assert_response :success
26
+ end
27
+ alias :redirect_to :redirect
28
+ alias :redirected :redirect
29
+ alias :redirected_to :redirect
30
+ end
31
+
32
+ Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldRedirect)
33
+ Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotRedirect)
@@ -0,0 +1,25 @@
1
+ module Test::Spec::Rails::ShouldRender
2
+ # Test that something was rendered:
3
+ # request.should.render
4
+ #
5
+ # Test that a specific template was rendered:
6
+ # request.should.render 'foo'
7
+ #
8
+ # Test that a template was rendered with a specific response code:
9
+ # request.should.render 'foo', :error
10
+ #
11
+ def render(template = '', response = :success)
12
+ @object.assert_response response
13
+ @object.assert_template template unless template.blank?
14
+ end
15
+ end
16
+
17
+ module Test::Spec::Rails::ShouldNotRender
18
+ # Test that we didn't render
19
+ def render(template = '', response = :success)
20
+ @object.assert_response :redirect
21
+ end
22
+ end
23
+
24
+ Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldRender)
25
+ Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotRender)
@@ -0,0 +1,34 @@
1
+ module Test::Spec::Rails::ShouldRoute
2
+ # Specify that a set of url options route to a path.
3
+ # This translates directly to assert_generates
4
+ # Example:
5
+ # {:controller => "items", :action => "show", :id =>"1"}.should.route_to "/items/1"
6
+ #
7
+ # See also http://api.rubyonrails.org/classes/ActionController/Assertions/RoutingAssertions.html#M000367
8
+ def route_to(options)
9
+ assert_generates(options, @object)
10
+ end
11
+
12
+ # Specify that a path should be routable from a set of url options.
13
+ # This translates directly to assert_recognizes
14
+ # Examples:
15
+ # {:path => "/items/1", :method => :get}.should.route_from :controller => "items", :action => "show", :id =>"1"
16
+ # {:path => "/items/1?print=true", :method => :get}.should.route_from({:controller => "items", :action => "show", :id =>"1"}, {:print => true})
17
+ #
18
+ # See also http://api.rubyonrails.org/classes/ActionController/Assertions/RoutingAssertions.html#M000366
19
+ def route_from(options, extras={})
20
+ assert_recognizes(options, @object, extras)
21
+ end
22
+
23
+ # Specify that a path should be routable from a set of url options and vice versa.
24
+ # This translates directly to assert_routing
25
+ # Examples:
26
+ # "/items/1".should.route :controller => "items", :action => "show", :id =>"1"
27
+ #
28
+ # See also http://api.rubyonrails.org/classes/ActionController/Assertions/RoutingAssertions.html#M000368
29
+ def route(options)
30
+ assert_routing(@object, options)
31
+ end
32
+ end
33
+
34
+ Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldRoute)
@@ -0,0 +1,53 @@
1
+ module Test::Spec::Rails::ShouldSelect
2
+ # Wrapper for +assert_select+. Examples:
3
+ #
4
+ # Test that the previous request has a login form:
5
+ # page.should.select "form#login"
6
+ #
7
+ # Test that a specific form has a field pre-filled (this is specific test/spec/rails):
8
+ # page.should.select "form#login" do |form|
9
+ # form.should.select "input[name=user_nick]", :text => @user.nick
10
+ # end
11
+ #
12
+ # OR you can use contain
13
+ # page.should.contain "form#login"
14
+ #
15
+ # page.should.contain "form#login" do |form|
16
+ # form.should.contain "input[name=user_nick]", :text => @user.nick
17
+ # end
18
+ #
19
+ # See the Rails API documentation for assert_select for more information
20
+ def select(selector, equality=true, message=nil, &block)
21
+ @@response_stack ||= []
22
+
23
+ if @object.is_a?(Test::Unit::TestCase)
24
+ @@response_stack.push(Test::Spec::Rails::DummyResponse.new(@object))
25
+
26
+ elsif @object.is_a?(Array) && @object.first.is_a?(HTML::Tag)
27
+ @@response_stack.push(Test::Spec::Rails::DummyResponse.new(
28
+ @object.first.to_s, @@response_stack.last.headers
29
+ ))
30
+ else
31
+ @@response_stack.push(Test::Spec::Rails::DummyResponse.new(@object.to_s,
32
+ (@@response_stack.last.headers rescue 'Content-Type: text/html; charset=utf8')
33
+ ))
34
+ end
35
+
36
+ @@response_stack.last.assert_select(selector, equality, message, &block)
37
+ @@response_stack.pop
38
+ end
39
+
40
+ # because contain sounds better imo
41
+ alias :contain :select
42
+ alias :have :select
43
+ end
44
+
45
+ module Test::Spec::Rails::ShouldNotSelect
46
+ include Test::Spec::Rails::ShouldSelect
47
+ def select(selector, message=nil, &block)
48
+ super(selector, false, message, &block)
49
+ end
50
+ end
51
+
52
+ Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldSelect)
53
+ Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotSelect)
@@ -0,0 +1,16 @@
1
+ module Test::Spec::Rails::ShouldValidate
2
+ def validate
3
+ assert @object.valid?
4
+ end
5
+ alias :validated :validate
6
+ end
7
+
8
+ module Test::Spec::Rails::ShouldNotValidate
9
+ def validate
10
+ assert !@object.valid?
11
+ end
12
+ alias :validated :validate
13
+ end
14
+
15
+ Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldValidate)
16
+ Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotValidate)
@@ -0,0 +1,27 @@
1
+ module Test::Spec::Rails::ShouldValidatePresenceOf
2
+ def it_should_validate_presence_of(*one_or_more_fields)
3
+ model_name = self.model_class_under_test
4
+ options = one_or_more_fields.last.is_a?(Hash) ? one_or_more_fields.pop : {}
5
+
6
+ one_or_more_fields.each do |field|
7
+ it "should validate presence of #{field.to_s.humanize.downcase}" do
8
+ validations = model_name.reflect_on_all_validations
9
+ validations = validations.select { |e| e.macro == :validates_presence_of }
10
+ validations = validations.inject({}) { |h,v| h[v.name] = v; h }
11
+
12
+ validation = validations[field]
13
+ assert_not_nil validation, "Expected validates_presence_of to be called on :#{field}, but it wasn't"
14
+ options.each_pair do |k,v|
15
+ assert_equal v, validation.options[k],
16
+ "Expected validates_presence_of to set :#{k} => :#{v} as an option, but it didn't"
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def model_class_under_test
23
+ name.constantize
24
+ end
25
+ end
26
+
27
+ Test::Unit::TestCase.send(:extend, Test::Spec::Rails::ShouldValidatePresenceOf)
@@ -0,0 +1,46 @@
1
+ # Base class for testcase/response/request/controller mocks
2
+ class Test::Spec::Rails::TestDummy
3
+ include Test::Unit::Assertions
4
+
5
+ if defined?(ActionController::TestCase::Assertions)
6
+ include ActionController::TestCase::Assertions
7
+ end
8
+
9
+ # Rails > 2 moved Assertions module to the ActionController class
10
+ if defined?(ActionController::Assertions)
11
+ include ActionController::Assertions
12
+ end
13
+
14
+ def initialize(testcase)
15
+ @controller = testcase.instance_variable_get('@controller')
16
+ @request = testcase.instance_variable_get('@request')
17
+ @response = testcase.instance_variable_get('@response')
18
+ end
19
+
20
+ def inspect
21
+ "<#{self.class}:#{self.to_s}>"
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ if real_response.respond_to?(method)
26
+ real_response.send(method, *args, &block)
27
+ elsif real_request.respond_to?(method)
28
+ real_request.send(method, *args, &block)
29
+ elsif real_controller.respond_to?(method)
30
+ real_controller.send(method, *args, &block)
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def real_response
37
+ @response unless @response == self
38
+ end
39
+ def real_request
40
+ @request unless @request == self
41
+ end
42
+ def real_controller
43
+ @controller unless @controller == self
44
+ end
45
+
46
+ end
@@ -0,0 +1,15 @@
1
+ module Test::Spec::Rails
2
+ class TestLayout < TestDummy
3
+
4
+ def should_equal(expected, message=nil)
5
+ layout = @response.layout.gsub(/layouts\//, '') if @response.layout
6
+ assert_equal expected, layout, message
7
+ end
8
+ alias :should_be :should_equal
9
+
10
+ def to_s
11
+ @response.rendered_file
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ class Test::Spec::Should
2
+ include Test::Unit::Assertions
3
+
4
+ if defined?(ActionController::TestCase::Assertions)
5
+ include ActionController::TestCase::Assertions
6
+ end
7
+
8
+ alias :_old_equal :equal
9
+ def equal(*args)
10
+ @object.respond_to?(:should_equal) ? @object.should_equal(*args) : _old_equal(*args)
11
+ end
12
+
13
+ alias :_old_be :be
14
+ def be(*args)
15
+ @object.respond_to?(:should_equal) ? @object.should_equal(*args) : _old_be(*args)
16
+ end
17
+
18
+ alias :have :be
19
+
20
+ def differ(method)
21
+ @initial_value = @object.send(@method = method)
22
+ self
23
+ end
24
+
25
+ def by(value)
26
+ yield
27
+ # TODO: this should use should_equal if available
28
+ assert_equal @initial_value + value, @object.send(@method)
29
+ end
30
+ end
31
+
32
+ class Test::Spec::ShouldNot
33
+ include Test::Unit::Assertions
34
+
35
+ if defined?(ActionController::TestCase::Assertions)
36
+ include ActionController::TestCase::Assertions
37
+ end
38
+
39
+ alias :_old_equal :equal
40
+ def equal(*args,&block)
41
+ @object.respond_to?(:should_not_equal) ? @object.should_not_equal(*args,&block) : _old_equal(*args,&block)
42
+ end
43
+
44
+ alias :_old_be :be
45
+ def be(*args,&block)
46
+ @object.respond_to?(:should_not_equal) ? @object.should_not_equal(*args,&block) : _old_be(*args,&block)
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ module Test::Spec::Rails
2
+ class TestStatus < TestDummy
3
+
4
+ def should_equal(status, message=nil)
5
+ assert_response status, message
6
+ end
7
+ alias :should_be :should_equal
8
+
9
+ def to_s
10
+ @response.response_code.to_s
11
+ end
12
+
13
+ end
14
+ end
15
+
@@ -0,0 +1,14 @@
1
+ module Test::Spec::Rails
2
+ class TestTemplate < TestDummy
3
+
4
+ def should_equal(template, message=nil)
5
+ assert_template template, message
6
+ end
7
+ alias :should_be :should_equal
8
+
9
+ def to_s
10
+ @response.rendered_file
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ class Test::Unit::TestCase
2
+ def page #:nodoc:
3
+ self
4
+ end
5
+ alias :response :page
6
+ alias :request :page
7
+ alias :view :page
8
+
9
+ def output
10
+ @response.body
11
+ end
12
+ alias :to_s :output
13
+ alias :body :output
14
+ alias :html :output
15
+ alias :xhtml :output
16
+
17
+ def url
18
+ Test::Spec::Rails::TestUrl.new(self)
19
+ end
20
+
21
+ def status
22
+ Test::Spec::Rails::TestStatus.new(self)
23
+ end
24
+
25
+ def template
26
+ Test::Spec::Rails::TestTemplate.new(self)
27
+ end
28
+
29
+ def layout
30
+ Test::Spec::Rails::TestLayout.new(self)
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module Test::Spec::Rails
2
+ class TestUrl < TestDummy
3
+
4
+ def initialize(testcase)
5
+ super(testcase)
6
+ @params = @request.symbolized_path_parameters
7
+ @path = @request.path
8
+ end
9
+
10
+ def should_equal(wanted, defaults={}, extras={}, message=nil)
11
+ if wanted.is_a?(Hash)
12
+ assert_recognizes(wanted, @path, defaults, message)
13
+ else
14
+ assert_generates(wanted, @params, defaults, extras, message)
15
+ end
16
+ end
17
+ alias :should_be :should_equal
18
+
19
+ def to_s
20
+ @path
21
+ end
22
+
23
+ end
24
+ end
25
+
@@ -0,0 +1,51 @@
1
+ module Test::Spec::Rails::UseController
2
+ module InstanceMethod
3
+ # Setup controller for tests.
4
+ # For example:
5
+ # context "Tuxie" do
6
+ # setup do
7
+ # use_controller UsersController
8
+ # login_as users(:tuxie)
9
+ # end
10
+ # specify "should be able to see his profile" { ... }
11
+ # end
12
+
13
+ # OR
14
+ # to save some keystrokes you can use a symbolized version of the controller name
15
+ # without the 'Controller' suffix
16
+ # For example:
17
+ # context "Tuxie" do
18
+ # setup do
19
+ # use_controller :users
20
+ # login_as :tuxie
21
+ # end
22
+ # specify "should be able to see his profile" { ... }
23
+ # end
24
+
25
+ def use_controller(controller)
26
+ controller = eval("#{controller.to_s.camelize}Controller") if controller.is_a? Symbol
27
+ controller.class_eval { def rescue_action(e); raise e; end }
28
+ @controller = controller.new
29
+ @request = ActionController::TestRequest.new
30
+ @response = ActionController::TestResponse.new
31
+ end
32
+ end
33
+
34
+ module ClassMethod
35
+ # Setup context for controller testing. For example:
36
+ # context "If not logged in" do
37
+ # use_controller SessionsController
38
+ # specify "one should see the login box" do
39
+ # get :new
40
+ # page.should.select "form#login"
41
+ # end
42
+ # end
43
+ def use_controller(controller)
44
+ setups << lambda { use_controller(controller) }
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ Test::Spec::TestCase::ClassMethods.send(:include, Test::Spec::Rails::UseController::ClassMethod)
51
+ Test::Unit::TestCase.send(:include, Test::Spec::Rails::UseController::InstanceMethod)
@@ -0,0 +1,15 @@
1
+ desc "Show specs when testing"
2
+ task :spec do
3
+ ENV['TESTOPTS'] = '--runner=s'
4
+ Rake::Task[:test].invoke
5
+ end
6
+
7
+ %w(functionals units integration).each do |type|
8
+ namespace :spec do
9
+ desc "Show specs when testing #{type}"
10
+ task type do
11
+ ENV['TESTOPTS'] = '--runner=s'
12
+ Rake::Task["test:#{type}"].invoke
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ describe "TestStatus" do
4
+ it "should call assert_response" do
5
+ status = Test::Spec::Rails::TestStatus.new(stub_everything)
6
+ status.expects(:assert_response).with(:success, nil)
7
+ status.should_equal :success
8
+ end
9
+
10
+ it "should call assert_response with message" do
11
+ status = Test::Spec::Rails::TestStatus.new(stub_everything)
12
+ status.expects(:assert_response).with(:success, "Response should be successful")
13
+ status.should_equal :success, "Response should be successful"
14
+ end
15
+
16
+ it "should return response code" do
17
+ status = Test::Spec::Rails::TestStatus.new(stub_everything)
18
+ status.class.class_eval { attr_accessor :response }
19
+ status.response.expects(:response_code).returns("200")
20
+ status.to_s.should == "200"
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'multi_rails_init'
3
+
4
+ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
5
+ require 'test/spec/rails'
6
+ require 'mocha'
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_spec_on_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Bass
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-03 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Provides helpers to test your Rails app using test/spec.
17
+ email: pelargir@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - .gitignore
26
+ - CHANGELOG
27
+ - README.markdown
28
+ - Rakefile
29
+ - VERSION
30
+ - lib/generators/controller/USAGE
31
+ - lib/generators/controller/controller_generator.rb
32
+ - lib/generators/controller/templates/controller.rb
33
+ - lib/generators/controller/templates/functional_test.rb
34
+ - lib/generators/controller/templates/helper.rb
35
+ - lib/generators/controller/templates/view.html.erb
36
+ - lib/generators/model/USAGE
37
+ - lib/generators/model/model_generator.rb
38
+ - lib/generators/model/templates/fixtures.yml
39
+ - lib/generators/model/templates/migration.rb
40
+ - lib/generators/model/templates/model.rb
41
+ - lib/generators/model/templates/unit_test.rb
42
+ - lib/test/spec/rails.rb
43
+ - lib/test/spec/rails/convenience.rb
44
+ - lib/test/spec/rails/dummy_response.rb
45
+ - lib/test/spec/rails/should_redirect.rb
46
+ - lib/test/spec/rails/should_render.rb
47
+ - lib/test/spec/rails/should_route.rb
48
+ - lib/test/spec/rails/should_select.rb
49
+ - lib/test/spec/rails/should_validate.rb
50
+ - lib/test/spec/rails/should_validate_presence_of.rb
51
+ - lib/test/spec/rails/test_dummy.rb
52
+ - lib/test/spec/rails/test_layout.rb
53
+ - lib/test/spec/rails/test_spec_ext.rb
54
+ - lib/test/spec/rails/test_status.rb
55
+ - lib/test/spec/rails/test_template.rb
56
+ - lib/test/spec/rails/test_unit_ext.rb
57
+ - lib/test/spec/rails/test_url.rb
58
+ - lib/test/spec/rails/use_controller.rb
59
+ - tasks/spec.rake
60
+ - test/test/spec/rails/test_status_test.rb
61
+ - test/test_helper.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/pelargir/test_spec_on_rails
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Provides helpers to test your Rails app using test/spec.
90
+ test_files:
91
+ - test/test/spec/rails/test_status_test.rb
92
+ - test/test_helper.rb