rails 4.0.0.beta1 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -0
  3. data/guides/CHANGELOG.md +3 -0
  4. data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
  5. data/guides/bug_report_templates/active_record_gem.rb +37 -0
  6. data/guides/bug_report_templates/active_record_master.rb +48 -0
  7. data/guides/code/getting_started/Gemfile +16 -11
  8. data/guides/code/getting_started/app/controllers/comments_controller.rb +2 -2
  9. data/guides/code/getting_started/app/controllers/posts_controller.rb +2 -2
  10. data/guides/code/getting_started/config/application.rb +3 -2
  11. data/guides/code/getting_started/config/initializers/session_store.rb +1 -1
  12. data/guides/code/getting_started/config/routes.rb +2 -2
  13. data/guides/code/getting_started/public/404.html +41 -10
  14. data/guides/code/getting_started/public/422.html +42 -10
  15. data/guides/code/getting_started/public/500.html +41 -10
  16. data/guides/rails_guides/markdown/renderer.rb +1 -1
  17. data/guides/source/2_2_release_notes.md +15 -15
  18. data/guides/source/4_0_release_notes.md +1 -7
  19. data/guides/source/action_controller_overview.md +176 -22
  20. data/guides/source/action_mailer_basics.md +246 -141
  21. data/guides/source/action_view_overview.md +3 -8
  22. data/guides/source/active_record_basics.md +98 -95
  23. data/guides/source/active_record_querying.md +90 -17
  24. data/guides/source/active_record_validations.md +41 -0
  25. data/guides/source/active_support_core_extensions.md +23 -3
  26. data/guides/source/active_support_instrumentation.md +6 -6
  27. data/guides/source/asset_pipeline.md +1 -1
  28. data/guides/source/association_basics.md +34 -10
  29. data/guides/source/caching_with_rails.md +2 -7
  30. data/guides/source/command_line.md +7 -7
  31. data/guides/source/configuring.md +3 -3
  32. data/guides/source/contributing_to_ruby_on_rails.md +38 -5
  33. data/guides/source/credits.html.erb +1 -1
  34. data/guides/source/debugging_rails_applications.md +19 -22
  35. data/guides/source/development_dependencies_install.md +2 -2
  36. data/guides/source/documents.yaml +5 -1
  37. data/guides/source/engines.md +21 -16
  38. data/guides/source/form_helpers.md +28 -7
  39. data/guides/source/generators.md +2 -2
  40. data/guides/source/getting_started.md +14 -13
  41. data/guides/source/i18n.md +22 -0
  42. data/guides/source/initialization.md +1 -1
  43. data/guides/source/layouts_and_rendering.md +60 -4
  44. data/guides/source/migrations.md +27 -2
  45. data/guides/source/rails_application_templates.md +11 -11
  46. data/guides/source/rails_on_rack.md +9 -6
  47. data/guides/source/routing.md +19 -3
  48. data/guides/source/ruby_on_rails_guides_guidelines.md +1 -1
  49. data/guides/source/security.md +2 -2
  50. data/guides/source/testing.md +106 -85
  51. data/guides/source/upgrading_ruby_on_rails.md +112 -9
  52. data/guides/source/working_with_javascript_in_rails.md +1 -0
  53. metadata +17 -16
  54. data/README.rdoc +0 -77
  55. data/guides/code/getting_started/app/assets/images/rails.png +0 -0
@@ -266,7 +266,7 @@ def start
266
266
  url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
267
267
  puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
268
268
  puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
269
- puts "=> Call with -d to detach" unless options[:daemonize]
269
+ puts "=> Run `rails server -h` for more startup options"
270
270
  trap(:INT) { exit }
271
271
  puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
272
272
 
@@ -1,7 +1,7 @@
1
1
  Layouts and Rendering in Rails
2
2
  ==============================
3
3
 
4
- This guide covers the basic layout features of Action Controller and Action View. By referring to this guide, you will be able to:
4
+ This guide covers the basic layout features of Action Controller and Action View.
5
5
 
6
6
  After reading this guide, you will know:
7
7
 
@@ -319,7 +319,62 @@ render status: 500
319
319
  render status: :forbidden
320
320
  ```
321
321
 
322
- Rails understands both numeric and symbolic status codes.
322
+ Rails understands both numeric status codes and the corresponding symbols shown below:
323
+
324
+ | HTTP Status Code | Symbol |
325
+ | ---------------- | -------------------------------- |
326
+ | 100 | :continue |
327
+ | 101 | :switching_protocols |
328
+ | 102 | :processing |
329
+ | 200 | :ok |
330
+ | 201 | :created |
331
+ | 202 | :accepted |
332
+ | 203 | :non_authoritative_information |
333
+ | 204 | :no_content |
334
+ | 205 | :reset_content |
335
+ | 206 | :partial_content |
336
+ | 207 | :multi_status |
337
+ | 226 | :im_used |
338
+ | 300 | :multiple_choices |
339
+ | 301 | :moved_permanently |
340
+ | 302 | :found |
341
+ | 303 | :see_other |
342
+ | 304 | :not_modified |
343
+ | 305 | :use_proxy |
344
+ | 306 | :reserved |
345
+ | 307 | :temporary_redirect |
346
+ | 400 | :bad_request |
347
+ | 401 | :unauthorized |
348
+ | 402 | :payment_required |
349
+ | 403 | :forbidden |
350
+ | 404 | :not_found |
351
+ | 405 | :method_not_allowed |
352
+ | 406 | :not_acceptable |
353
+ | 407 | :proxy_authentication_required |
354
+ | 408 | :request_timeout |
355
+ | 409 | :conflict |
356
+ | 410 | :gone |
357
+ | 411 | :length_required |
358
+ | 412 | :precondition_failed |
359
+ | 413 | :request_entity_too_large |
360
+ | 414 | :request_uri_too_long |
361
+ | 415 | :unsupported_media_type |
362
+ | 416 | :requested_range_not_satisfiable |
363
+ | 417 | :expectation_failed |
364
+ | 418 | :i'm_a_teapot |
365
+ | 422 | :unprocessable_entity |
366
+ | 423 | :locked |
367
+ | 424 | :failed_dependency |
368
+ | 426 | :upgrade_required |
369
+ | 500 | :internal_server_error |
370
+ | 501 | :not_implemented |
371
+ | 502 | :bad_gateway |
372
+ | 503 | :service_unavailable |
373
+ | 504 | :gateway_timeout |
374
+ | 505 | :http_version_not_supported |
375
+ | 506 | :variant_also_negotiates |
376
+ | 507 | :insufficient_storage |
377
+ | 510 | :not_extended |
323
378
 
324
379
  ##### The `:location` Option
325
380
 
@@ -363,7 +418,7 @@ You can use a symbol to defer the choice of layout until a request is processed:
363
418
 
364
419
  ```ruby
365
420
  class ProductsController < ApplicationController
366
- layout "products_layout"
421
+ layout :products_layout
367
422
 
368
423
  def show
369
424
  @product = Product.find(params[:id])
@@ -568,7 +623,8 @@ def show
568
623
  @book = Book.find_by_id(params[:id])
569
624
  if @book.nil?
570
625
  @books = Book.all
571
- render "index", alert: "Your book was not found!"
626
+ flash[:alert] = "Your book was not found"
627
+ render "index"
572
628
  end
573
629
  end
574
630
  ```
@@ -61,6 +61,10 @@ migrations are wrapped in a transaction. If the database does not support this
61
61
  then when a migration fails the parts of it that succeeded will not be rolled
62
62
  back. You will have to rollback the changes that were made by hand.
63
63
 
64
+ NOTE: There are certain queries that can't run inside a transaction. If your
65
+ adapter supports DDL transactions you can use `disable_ddl_transaction!` to
66
+ disable them for a single migration.
67
+
64
68
  If you wish for a migration to do something that Active Record doesn't know how
65
69
  to reverse, you can use `reversible`:
66
70
 
@@ -179,6 +183,27 @@ class AddDetailsToProducts < ActiveRecord::Migration
179
183
  end
180
184
  ```
181
185
 
186
+ If the migration name is of the form "CreateXXX" and is
187
+ followed by a list of column names and types then a migration creating the table
188
+ XXX with the columns listed will be generated. For example:
189
+
190
+ ```bash
191
+ $ rails generate migration CreateProducts name:string part_number:string
192
+ ```
193
+
194
+ generates
195
+
196
+ ```ruby
197
+ class CreateProducts < ActiveRecord::Migration
198
+ def change
199
+ create_table :products do |t|
200
+ t.string :name
201
+ t.string :part_number
202
+ end
203
+ end
204
+ end
205
+ ```
206
+
182
207
  As always, what has been generated for you is just a starting point. You can add
183
208
  or remove from it as you see fit by editing the
184
209
  `db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb` file.
@@ -806,7 +831,7 @@ end
806
831
  ```
807
832
 
808
833
  ```ruby
809
- # app/model/product.rb
834
+ # app/models/product.rb
810
835
 
811
836
  class Product < ActiveRecord::Base
812
837
  validates :flag, presence: true
@@ -831,7 +856,7 @@ end
831
856
  ```
832
857
 
833
858
  ```ruby
834
- # app/model/product.rb
859
+ # app/models/product.rb
835
860
 
836
861
  class Product < ActiveRecord::Base
837
862
  validates :flag, :fuzz, presence: true
@@ -13,7 +13,7 @@ After reading this guide, you will know:
13
13
  Usage
14
14
  -----
15
15
 
16
- To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option. This can either be path to a file or a URL.
16
+ To apply a template, you need to provide the Rails generator with the location of the template you wish to apply using the -m option. This can either be a path to a file or a URL.
17
17
 
18
18
  ```bash
19
19
  $ rails new blog -m ~/template.rb
@@ -30,7 +30,7 @@ $ rake rails:template LOCATION=http://example.com/template.rb
30
30
  Template API
31
31
  ------------
32
32
 
33
- Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template:
33
+ The Rails templates API is easy to understand. Here's an example of a typical Rails template:
34
34
 
35
35
  ```ruby
36
36
  # template.rb
@@ -43,7 +43,7 @@ git add: "."
43
43
  git commit: %Q{ -m 'Initial commit' }
44
44
  ```
45
45
 
46
- The following sections outlines the primary methods provided by the API:
46
+ The following sections outline the primary methods provided by the API:
47
47
 
48
48
  ### gem(*args)
49
49
 
@@ -66,7 +66,7 @@ bundle install
66
66
 
67
67
  Wraps gem entries inside a group.
68
68
 
69
- For example, if you want to load `rspec-rails` only in `development` and `test` group:
69
+ For example, if you want to load `rspec-rails` only in the `development` and `test` groups:
70
70
 
71
71
  ```ruby
72
72
  gem_group :development, :test do
@@ -100,7 +100,7 @@ A block can be used in place of the `data` argument.
100
100
 
101
101
  Adds an initializer to the generated application’s `config/initializers` directory.
102
102
 
103
- Lets say you like using `Object#not_nil?` and `Object#not_blank?`:
103
+ Let's say you like using `Object#not_nil?` and `Object#not_blank?`:
104
104
 
105
105
  ```ruby
106
106
  initializer 'bloatlol.rb', <<-CODE
@@ -116,9 +116,9 @@ initializer 'bloatlol.rb', <<-CODE
116
116
  CODE
117
117
  ```
118
118
 
119
- Similarly `lib()` creates a file in the `lib/` directory and `vendor()` creates a file in the `vendor/` directory.
119
+ Similarly, `lib()` creates a file in the `lib/` directory and `vendor()` creates a file in the `vendor/` directory.
120
120
 
121
- There is even `file()`, which accepts a relative path from `Rails.root` and creates all the directories/file needed:
121
+ There is even `file()`, which accepts a relative path from `Rails.root` and creates all the directories/files needed:
122
122
 
123
123
  ```ruby
124
124
  file 'app/components/foo.rb', <<-CODE
@@ -127,7 +127,7 @@ file 'app/components/foo.rb', <<-CODE
127
127
  CODE
128
128
  ```
129
129
 
130
- That’ll create `app/components` directory and put `foo.rb` in there.
130
+ That’ll create the `app/components` directory and put `foo.rb` in there.
131
131
 
132
132
  ### rakefile(filename, data = nil, &block)
133
133
 
@@ -179,7 +179,7 @@ rake "db:migrate", env: 'production'
179
179
 
180
180
  ### route(routing_code)
181
181
 
182
- Adds a routing entry to the `config/routes.rb` file. In above steps, we generated a person scaffold and also removed `README.rdoc`. Now to make `PeopleController#index` as the default page for the application:
182
+ Adds a routing entry to the `config/routes.rb` file. In the steps above, we generated a person scaffold and also removed `README.rdoc`. Now, to make `PeopleController#index` the default page for the application:
183
183
 
184
184
  ```ruby
185
185
  route "root to: 'person#index'"
@@ -197,7 +197,7 @@ end
197
197
 
198
198
  ### ask(question)
199
199
 
200
- `ask()` gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding:
200
+ `ask()` gives you a chance to get some feedback from the user and use it in your templates. Let's say you want your user to name the new shiny library you’re adding:
201
201
 
202
202
  ```ruby
203
203
  lib_name = ask("What do you want to call the shiny library ?")
@@ -211,7 +211,7 @@ CODE
211
211
 
212
212
  ### yes?(question) or no?(question)
213
213
 
214
- These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to:
214
+ These methods let you ask questions from templates and decide the flow based on the user’s answer. Let's say you want to freeze rails only if the user wants to:
215
215
 
216
216
  ```ruby
217
217
  rake("rails:freeze:gems") if yes?("Freeze rails gems?")
@@ -28,7 +28,10 @@ Rails on Rack
28
28
 
29
29
  ### Rails Application's Rack Object
30
30
 
31
- `ApplicationName::Application` is the primary Rack application object of a Rails application. Any Rack compliant web server should be using `ApplicationName::Application` object to serve a Rails application.
31
+ `ApplicationName::Application` is the primary Rack application object of a Rails
32
+ application. Any Rack compliant web server should be using
33
+ `ApplicationName::Application` object to serve a Rails
34
+ application. `Rails.application` refers to the same application object.
32
35
 
33
36
  ### `rails server`
34
37
 
@@ -79,11 +82,11 @@ To use `rackup` instead of Rails' `rails server`, you can put the following insi
79
82
 
80
83
  ```ruby
81
84
  # Rails.root/config.ru
82
- require "config/environment"
85
+ require ::File.expand_path('../config/environment', __FILE__)
83
86
 
84
87
  use Rack::Debugger
85
88
  use Rack::ContentLength
86
- run ApplicationName::Application
89
+ run Rails.application
87
90
  ```
88
91
 
89
92
  And start the server:
@@ -101,7 +104,7 @@ $ rackup --help
101
104
  Action Dispatcher Middleware Stack
102
105
  ----------------------------------
103
106
 
104
- Many of Action Dispatchers's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application.
107
+ Many of Action Dispatcher's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application.
105
108
 
106
109
  NOTE: `ActionDispatch::MiddlewareStack` is Rails equivalent of `Rack::Builder`, but built for better flexibility and more features to meet Rails' requirements.
107
110
 
@@ -324,7 +327,7 @@ config.middleware.clear
324
327
  ```ruby
325
328
  # config.ru
326
329
  use MyOwnStackFromScratch
327
- run ApplicationName::Application
330
+ run Rails.application
328
331
  ```
329
332
 
330
333
  Resources
@@ -332,7 +335,7 @@ Resources
332
335
 
333
336
  ### Learning Rack
334
337
 
335
- * [Official Rack Website](http://rack.github.com)
338
+ * [Official Rack Website](http://rack.github.io)
336
339
  * [Introducing Rack](http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html)
337
340
  * [Ruby on Rack #1 - Hello Rack!](http://m.onkey.org/ruby-on-rack-1-hello-rack)
338
341
  * [Ruby on Rack #2 - The Builder](http://m.onkey.org/ruby-on-rack-2-the-builder)
@@ -138,6 +138,12 @@ Sometimes, you have a resource that clients always look up without referencing a
138
138
  get 'profile', to: 'users#show'
139
139
  ```
140
140
 
141
+ Passing a `String` to `match` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action:
142
+
143
+ ```ruby
144
+ get 'profile', to: :show
145
+ ```
146
+
141
147
  This resourceful route:
142
148
 
143
149
  ```ruby
@@ -155,7 +161,7 @@ creates six different routes in your application, all mapping to the `Geocoders`
155
161
  | PATCH/PUT | /geocoder | update | update the one and only geocoder resource |
156
162
  | DELETE | /geocoder | destroy | delete the geocoder resource |
157
163
 
158
- NOTE: Because you might want to use the same controller for a singular route (`/account`) and a plural route (`/accounts/45`), singular resources map to plural controllers.
164
+ NOTE: Because you might want to use the same controller for a singular route (`/account`) and a plural route (`/accounts/45`), singular resources map to plural controllers. So that, for example, `resource :photo` and `resources :photos` creates both singular and plural routes that map to the same controller (`PhotosController`).
159
165
 
160
166
  A singular resourceful route generates these helpers:
161
167
 
@@ -530,7 +536,7 @@ In particular, simple routing makes it very easy to map legacy URLs to new Rails
530
536
 
531
537
  ### Bound Parameters
532
538
 
533
- When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: `:controller` maps to the name of a controller in your application, and `:action` maps to the name of an action within that controller. For example, consider one of the default Rails routes:
539
+ When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: `:controller` maps to the name of a controller in your application, and `:action` maps to the name of an action within that controller. For example, consider this route:
534
540
 
535
541
  ```ruby
536
542
  get ':controller(/:action(/:id))'
@@ -797,6 +803,16 @@ You should put the `root` route at the top of the file, because it is the most p
797
803
 
798
804
  NOTE: The `root` route only routes `GET` requests to the action.
799
805
 
806
+ You can also use root inside namespaces and scopes as well. For example:
807
+
808
+ ```ruby
809
+ namespace :admin do
810
+ root to: "admin#index"
811
+ end
812
+
813
+ root to: "home#index"
814
+ ```
815
+
800
816
  ### Unicode character routes
801
817
 
802
818
  You can specify unicode character routes directly. For example:
@@ -840,7 +856,7 @@ resources :user_permissions, controller: 'admin/user_permissions'
840
856
 
841
857
  This will route to the `Admin::UserPermissions` controller.
842
858
 
843
- NOTE: Only the directory notation is supported. specifying the
859
+ NOTE: Only the directory notation is supported. Specifying the
844
860
  controller with ruby constant notation (eg. `:controller =>
845
861
  'Admin::UserPermissions'`) can lead to routing problems and results in
846
862
  a warning.
@@ -65,7 +65,7 @@ HTML Guides
65
65
 
66
66
  ### Generation
67
67
 
68
- To generate all the guides, just `cd` into the **`guides`** directory, run `bundle install` and execute:
68
+ To generate all the guides, just `cd` into the `guides` directory, run `bundle install` and execute:
69
69
 
70
70
  ```
71
71
  bundle exec rake guides:generate
@@ -1,4 +1,4 @@
1
- Ruby On Rails Security Guide
1
+ Ruby on Rails Security Guide
2
2
  ============================
3
3
 
4
4
  This manual describes common security problems in web applications and how to avoid them with Rails.
@@ -432,7 +432,7 @@ Depending on your web application, there may be more ways to hijack the user's a
432
432
 
433
433
  INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._
434
434
 
435
- But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](http://ambethia.com/recaptcha/) is also a Rails plug-in with the same name as the API.
435
+ But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](https://github.com/ambethia/recaptcha/) is also a Rails plug-in with the same name as the API.
436
436
 
437
437
  You will get two keys from the API, a public and a private key, which you have to put into your Rails environment. After that you can use the recaptcha_tags method in the view, and the verify_recaptcha method in the controller. Verify_recaptcha will return false if the validation fails.
438
438
  The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that he is human, but reveal that a spam robot is a bot.
@@ -1,8 +1,7 @@
1
1
  A Guide to Testing Rails Applications
2
2
  =====================================
3
3
 
4
- This guide covers built-in mechanisms offered by Rails to test your
5
- application.
4
+ This guide covers built-in mechanisms in Rails for testing your application.
6
5
 
7
6
  After reading this guide, you will know:
8
7
 
@@ -38,11 +37,11 @@ Rails creates a `test` folder for you as soon as you create a Rails project usin
38
37
 
39
38
  ```bash
40
39
  $ ls -F test
41
-
42
- fixtures/ functional/ integration/ test_helper.rb unit/
40
+ controllers/ helpers/ mailers/ test_helper.rb
41
+ fixtures/ integration/ models/
43
42
  ```
44
43
 
45
- The `unit` directory is meant to hold tests for your models, the `functional` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting.
44
+ The `models` directory is meant to hold tests for your models, the `controllers` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting.
46
45
 
47
46
  Fixtures are a way of organizing test data; they reside in the `fixtures` folder.
48
47
 
@@ -140,10 +139,9 @@ The default test stub in `test/models/post_test.rb` looks like this:
140
139
  require 'test_helper'
141
140
 
142
141
  class PostTest < ActiveSupport::TestCase
143
- # Replace this with your real tests.
144
- test "the truth" do
145
- assert true
146
- end
142
+ # test "the truth" do
143
+ # assert true
144
+ # end
147
145
  end
148
146
  ```
149
147
 
@@ -224,34 +222,30 @@ TIP: You can see all these rake tasks and their descriptions by running `rake --
224
222
 
225
223
  ### Running Tests
226
224
 
227
- Running a test is as simple as invoking the file containing the test cases through Ruby:
225
+ Running a test is as simple as invoking the file containing the test cases through `rake test` command.
228
226
 
229
227
  ```bash
230
- $ ruby -Itest test/models/post_test.rb
231
-
232
- Loaded suite models/post_test
233
- Started
228
+ $ rake test test/models/post_test.rb
234
229
  .
235
- Finished in 0.023513 seconds.
236
230
 
237
- 1 tests, 1 assertions, 0 failures, 0 errors
238
- ```
231
+ Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
239
232
 
240
- This will run all the test methods from the test case. Note that `test_helper.rb` is in the `test` directory, hence this directory needs to be added to the load path using the `-I` switch.
233
+ 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
234
+ ```
241
235
 
242
- You can also run a particular test method from the test case by using the `-n` switch with the `test method name`.
236
+ You can also run a particular test method from the test case by running the test and providing the `test method name`.
243
237
 
244
238
  ```bash
245
- $ ruby -Itest test/models/post_test.rb -n test_the_truth
246
-
247
- Loaded suite models/post_test
248
- Started
239
+ $ rake test test/models/post_test.rb test_the_truth
249
240
  .
250
- Finished in 0.023513 seconds.
251
241
 
252
- 1 tests, 1 assertions, 0 failures, 0 errors
242
+ Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
243
+
244
+ 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
253
245
  ```
254
246
 
247
+ This will run all test methods from the test case. Note that `test_helper.rb` is in the `test` directory, hence this directory needs to be added to the load path using the `-I` switch.
248
+
255
249
  The `.` (dot) above indicates a passing test. When a test fails you see an `F`; when a test throws an error you see an `E` in its place. The last line of the output is the summary.
256
250
 
257
251
  To see how a test failure is reported, you can add a failing test to the `post_test.rb` test case.
@@ -266,17 +260,16 @@ end
266
260
  Let us run this newly added test.
267
261
 
268
262
  ```bash
269
- $ ruby unit/post_test.rb -n test_should_not_save_post_without_title
270
- Loaded suite -e
271
- Started
263
+ $ rake test test/models/post_test.rb test_should_not_save_post_without_title
272
264
  F
273
- Finished in 0.102072 seconds.
265
+
266
+ Finished tests in 0.044632s, 22.4054 tests/s, 22.4054 assertions/s.
274
267
 
275
268
  1) Failure:
276
- test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]:
277
- <false> is not true.
269
+ test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
270
+ Failed assertion, no message given.
278
271
 
279
- 1 tests, 1 assertions, 1 failures, 0 errors
272
+ 1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
280
273
  ```
281
274
 
282
275
  In the output, `F` denotes a failure. You can see the corresponding trace shown under `1)` along with the name of the failing test. The next few lines contain the stack trace followed by a message which mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
@@ -292,9 +285,8 @@ Running this test shows the friendlier assertion message:
292
285
 
293
286
  ```bash
294
287
  1) Failure:
295
- test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]:
296
- Saved the post without a title.
297
- <false> is not true.
288
+ test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
289
+ Saved the post without a title
298
290
  ```
299
291
 
300
292
  Now to get this test to pass we can add a model level validation for the _title_ field.
@@ -308,13 +300,12 @@ end
308
300
  Now the test should pass. Let us verify by running the test again:
309
301
 
310
302
  ```bash
311
- $ ruby unit/post_test.rb -n test_should_not_save_post_without_title
312
- Loaded suite unit/post_test
313
- Started
303
+ $ rake test test/models/post_test.rb test_should_not_save_post_without_title
314
304
  .
315
- Finished in 0.193608 seconds.
316
305
 
317
- 1 tests, 1 assertions, 0 failures, 0 errors
306
+ Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
307
+
308
+ 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
318
309
  ```
319
310
 
320
311
  Now, if you noticed, we first wrote a test which fails for a desired functionality, then we wrote some code which adds the functionality and finally we ensured that our test passes. This approach to software development is referred to as _Test-Driven Development_ (TDD).
@@ -334,18 +325,17 @@ end
334
325
  Now you can see even more output in the console from running the tests:
335
326
 
336
327
  ```bash
337
- $ ruby unit/post_test.rb -n test_should_report_error
338
- Loaded suite -e
339
- Started
328
+ $ rake test test/models/post_test.rb test_should_report_error
340
329
  E
341
- Finished in 0.082603 seconds.
330
+
331
+ Finished tests in 0.030974s, 32.2851 tests/s, 0.0000 assertions/s.
342
332
 
343
333
  1) Error:
344
334
  test_should_report_error(PostTest):
345
- NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x249d354>
346
- /test/models/post_test.rb:6:in `test_should_report_error'
335
+ NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x007fe32e24afe0>
336
+ test/models/post_test.rb:10:in `block in <class:PostTest>'
347
337
 
348
- 1 tests, 0 assertions, 0 failures, 1 errors
338
+ 1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
349
339
  ```
350
340
 
351
341
  Notice the 'E' in the output. It denotes a test with error.
@@ -511,6 +501,21 @@ You also have access to three instance variables in your functional tests:
511
501
  * `@request` - The request
512
502
  * `@response` - The response
513
503
 
504
+ ### Setting Headers and CGI variables
505
+
506
+ Headers and cgi variables can be set directly on the `@request`
507
+ instance variable:
508
+
509
+ ```ruby
510
+ # setting a HTTP Header
511
+ @request.headers["Accepts"] = "text/plain, text/html"
512
+ get :index # simulate the request with custom header
513
+
514
+ # setting a CGI variable
515
+ @request.headers["HTTP_REFERER"] = "http://example.com/home"
516
+ post :create # simulate the request with custom env variable
517
+ ```
518
+
514
519
  ### Testing Templates and Layouts
515
520
 
516
521
  If you want to make sure that the response rendered the correct template and layout, you can use the `assert_template`
@@ -642,12 +647,9 @@ Here's what a freshly-generated integration test looks like:
642
647
  require 'test_helper'
643
648
 
644
649
  class UserFlowsTest < ActionDispatch::IntegrationTest
645
- fixtures :all
646
-
647
- # Replace this with your real tests.
648
- test "the truth" do
649
- assert true
650
- end
650
+ # test "the truth" do
651
+ # assert true
652
+ # end
651
653
  end
652
654
  ```
653
655
 
@@ -688,9 +690,9 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
688
690
  get "/login"
689
691
  assert_response :success
690
692
 
691
- post_via_redirect "/login", username: users(:avs).username, password: users(:avs).password
693
+ post_via_redirect "/login", username: users(:david).username, password: users(:david).password
692
694
  assert_equal '/welcome', path
693
- assert_equal 'Welcome avs!', flash[:notice]
695
+ assert_equal 'Welcome david!', flash[:notice]
694
696
 
695
697
  https!(false)
696
698
  get "/posts/all"
@@ -712,17 +714,17 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
712
714
 
713
715
  test "login and browse site" do
714
716
 
715
- # User avs logs in
716
- avs = login(:avs)
717
+ # User david logs in
718
+ david = login(:david)
717
719
  # User guest logs in
718
720
  guest = login(:guest)
719
721
 
720
722
  # Both are now available in different sessions
721
- assert_equal 'Welcome avs!', avs.flash[:notice]
723
+ assert_equal 'Welcome david!', david.flash[:notice]
722
724
  assert_equal 'Welcome guest!', guest.flash[:notice]
723
725
 
724
- # User avs can browse site
725
- avs.browses_site
726
+ # User david can browse site
727
+ david.browses_site
726
728
  # User guest can browse site as well
727
729
  guest.browses_site
728
730
 
@@ -755,23 +757,28 @@ end
755
757
  Rake Tasks for Running your Tests
756
758
  ---------------------------------
757
759
 
758
- You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of rake tasks to help in testing. The table below lists all rake tasks that come along in the default Rakefile when you initiate a Rails project.
760
+ You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of commands to help in testing. The table below lists all commands that come along in the default Rakefile when you initiate a Rails project.
761
+
762
+ | Tasks | Description |
763
+ | ------------------------ | ----------- |
764
+ | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake test` as Rails will run all the tests by default|
765
+ | `rake test:controllers` | Runs all the controller tests from `test/controllers`|
766
+ | `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`|
767
+ | `rake test:helpers` | Runs all the helper tests from `test/helpers`|
768
+ | `rake test:integration` | Runs all the integration tests from `test/integration`|
769
+ | `rake test:mailers` | Runs all the mailer tests from `test/mailers`|
770
+ | `rake test:models` | Runs all the model tests from `test/models`|
771
+ | `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`|
759
772
 
760
- | Tasks | Description |
761
- | ------------------------------- | ----------- |
762
- | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.|
763
- | `rake test:controllers` | Runs all the controller tests from `test/controllers`|
764
- | `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`|
765
- | `rake test:helpers` | Runs all the helper tests from `test/helpers`|
766
- | `rake test:integration` | Runs all the integration tests from `test/integration`|
767
- | `rake test:mailers` | Runs all the mailer tests from `test/mailers`|
768
- | `rake test:models` | Runs all the model tests from `test/models`|
769
- | `rake test:recent` | Tests recent changes|
770
- | `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git|
771
- | `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`|
773
+ There're also some test commands which you can initiate by running rake tasks:
772
774
 
775
+ | Tasks | Description |
776
+ | ------------------------ | ----------- |
777
+ | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.|
778
+ | `rake test:recent` | Tests recent changes|
779
+ | `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git|
773
780
 
774
- Brief Note About `Test::Unit`
781
+ Brief Note About `MiniTest`
775
782
  -----------------------------
776
783
 
777
784
  Ruby ships with a boat load of libraries. Ruby 1.8 provides `Test::Unit`, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in `Test::Unit::Assertions`. The class `ActiveSupport::TestCase` which we have been using in our unit and functional tests extends `Test::Unit::TestCase`, allowing
@@ -920,19 +927,24 @@ require 'test_helper'
920
927
  class UserMailerTest < ActionMailer::TestCase
921
928
  tests UserMailer
922
929
  test "invite" do
923
- @expected.from = 'me@example.com'
924
- @expected.to = 'friend@example.com'
925
- @expected.subject = "You have been invited by #{@expected.from}"
926
- @expected.body = read_fixture('invite')
927
- @expected.date = Time.now
928
-
929
- assert_equal @expected.encoded, UserMailer.create_invite('me@example.com', 'friend@example.com', @expected.date).encoded
930
+ # Send the email, then test that it got queued
931
+ email = UserMailer.create_invite('me@example.com',
932
+ 'friend@example.com', Time.now).deliver
933
+ assert !ActionMailer::Base.deliveries.empty?
934
+
935
+ # Test the body of the sent email contains what we expect it to
936
+ assert_equal ['me@example.com'], email.from
937
+ assert_equal ['friend@example.com'], email.to
938
+ assert_equal 'You have been invited by me@example.com', email.subject
939
+ assert_equal read_fixture('invite').join, email.body.to_s
930
940
  end
931
-
932
941
  end
933
942
  ```
934
943
 
935
- In this test, `@expected` is an instance of `TMail::Mail` that you can use in your tests. It is defined in `ActionMailer::TestCase`. The test above uses `@expected` to construct an email, which it then asserts with email created by the custom mailer. The `invite` fixture is the body of the email and is used as the sample content to assert against. The helper `read_fixture` is used to read in the content from this file.
944
+ In the test we send the email and store the returned object in the `email`
945
+ variable. We then ensure that it was sent (the first assert), then, in the
946
+ second batch of assertions, we ensure that the email does indeed contain what we
947
+ expect. The helper `read_fixture` is used to read in the content from this file.
936
948
 
937
949
  Here's the content of the `invite` fixture:
938
950
 
@@ -944,9 +956,17 @@ You have been invited.
944
956
  Cheers!
945
957
  ```
946
958
 
947
- This is the right time to understand a little more about writing tests for your mailers. The line `ActionMailer::Base.delivery_method = :test` in `config/environments/test.rb` sets the delivery method to test mode so that email will not actually be delivered (useful to avoid spamming your users while testing) but instead it will be appended to an array (`ActionMailer::Base.deliveries`).
959
+ This is the right time to understand a little more about writing tests for your
960
+ mailers. The line `ActionMailer::Base.delivery_method = :test` in
961
+ `config/environments/test.rb` sets the delivery method to test mode so that
962
+ email will not actually be delivered (useful to avoid spamming your users while
963
+ testing) but instead it will be appended to an array
964
+ (`ActionMailer::Base.deliveries`).
948
965
 
949
- This way, emails are not actually sent, simply constructed. The precise content of the email can then be checked against what is expected, as in the example above.
966
+ NOTE: The `ActionMailer::Base.deliveries` array is only reset automatically in
967
+ `ActionMailer::TestCase` tests. If you want to have a clean slate outside Action
968
+ Mailer tests, you can reset it manually with:
969
+ `ActionMailer::Base.deliveries.clear`
950
970
 
951
971
  ### Functional Testing
952
972
 
@@ -977,5 +997,6 @@ The built-in `test/unit` based testing is not the only way to test Rails applica
977
997
  * [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use.
978
998
  * [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures.
979
999
  * [Machinist](https://github.com/notahat/machinist/tree/master), another replacement for fixtures.
1000
+ * [MiniTest::Spec Rails](https://github.com/metaskills/minitest-spec-rails), use the MiniTest::Spec DSL within your rails tests.
980
1001
  * [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions.
981
1002
  * [RSpec](http://relishapp.com/rspec), a behavior-driven development framework