railties 3.0.0.beta3 → 3.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG +5 -0
  2. data/README +118 -123
  3. data/guides/source/3_0_release_notes.textile +13 -11
  4. data/guides/source/action_controller_overview.textile +2 -2
  5. data/guides/source/action_mailer_basics.textile +70 -26
  6. data/guides/source/action_view_overview.textile +1 -1
  7. data/guides/source/active_record_basics.textile +9 -1
  8. data/guides/source/active_record_querying.textile +2 -2
  9. data/guides/source/active_support_core_extensions.textile +377 -9
  10. data/guides/source/activerecord_validations_callbacks.textile +98 -55
  11. data/guides/source/association_basics.textile +1 -1
  12. data/guides/source/caching_with_rails.textile +1 -1
  13. data/guides/source/command_line.textile +23 -23
  14. data/guides/source/configuring.textile +1 -3
  15. data/guides/source/contribute.textile +27 -28
  16. data/guides/source/credits.html.erb +4 -4
  17. data/guides/source/debugging_rails_applications.textile +2 -2
  18. data/guides/source/form_helpers.textile +7 -6
  19. data/guides/source/generators.textile +19 -29
  20. data/guides/source/getting_started.textile +106 -49
  21. data/guides/source/i18n.textile +27 -27
  22. data/guides/source/index.html.erb +18 -8
  23. data/guides/source/initialization.textile +140 -514
  24. data/guides/source/layout.html.erb +6 -4
  25. data/guides/source/layouts_and_rendering.textile +5 -5
  26. data/guides/source/migrations.textile +7 -3
  27. data/guides/source/nested_model_forms.textile +2 -2
  28. data/guides/source/performance_testing.textile +11 -12
  29. data/guides/source/plugins.textile +30 -30
  30. data/guides/source/rails_application_templates.textile +3 -3
  31. data/guides/source/rails_on_rack.textile +3 -66
  32. data/guides/source/routing.textile +10 -4
  33. data/guides/source/security.textile +1 -1
  34. data/guides/source/testing.textile +55 -52
  35. data/guides/w3c_validator.rb +67 -0
  36. data/lib/rails.rb +1 -0
  37. data/lib/rails/application.rb +49 -13
  38. data/lib/rails/application/bootstrap.rb +7 -6
  39. data/lib/rails/application/configuration.rb +24 -47
  40. data/lib/rails/application/finisher.rb +8 -3
  41. data/lib/rails/backtrace_cleaner.rb +11 -12
  42. data/lib/rails/commands.rb +54 -54
  43. data/lib/rails/commands/application.rb +7 -2
  44. data/lib/rails/commands/{performance/benchmarker.rb → benchmarker.rb} +0 -0
  45. data/lib/rails/commands/dbconsole.rb +4 -3
  46. data/lib/rails/commands/destroy.rb +1 -0
  47. data/lib/rails/commands/generate.rb +1 -0
  48. data/lib/rails/commands/{performance/profiler.rb → profiler.rb} +0 -0
  49. data/lib/rails/commands/runner.rb +4 -2
  50. data/lib/rails/configuration.rb +36 -0
  51. data/lib/rails/engine.rb +24 -24
  52. data/lib/rails/engine/configuration.rb +0 -1
  53. data/lib/rails/generators.rb +48 -10
  54. data/lib/rails/generators/actions.rb +5 -3
  55. data/lib/rails/generators/base.rb +23 -17
  56. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +9 -8
  57. data/lib/rails/generators/erb/scaffold/templates/show.html.erb +1 -1
  58. data/lib/rails/generators/generated_attribute.rb +7 -6
  59. data/lib/rails/generators/rails/app/USAGE +2 -2
  60. data/lib/rails/generators/rails/app/app_generator.rb +242 -97
  61. data/lib/rails/generators/rails/app/templates/Gemfile +3 -0
  62. data/lib/rails/generators/rails/app/templates/README +167 -130
  63. data/lib/rails/generators/rails/app/templates/Rakefile +0 -3
  64. data/lib/rails/generators/rails/app/templates/config/boot.rb +9 -2
  65. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +5 -5
  66. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +4 -0
  67. data/lib/rails/generators/rails/app/templates/script/rails +2 -5
  68. data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -3
  69. data/lib/rails/generators/rails/stylesheets/templates/scaffold.css +5 -9
  70. data/lib/rails/generators/test_case.rb +12 -0
  71. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +1 -1
  72. data/lib/rails/generators/test_unit/performance/templates/performance_test.rb +1 -1
  73. data/lib/rails/info.rb +0 -33
  74. data/lib/rails/log_subscriber.rb +13 -6
  75. data/lib/rails/rack/logger.rb +4 -3
  76. data/lib/rails/railtie.rb +4 -0
  77. data/lib/rails/railtie/configuration.rb +21 -4
  78. data/lib/rails/tasks/documentation.rake +2 -0
  79. data/lib/rails/tasks/framework.rake +22 -0
  80. data/lib/rails/tasks/middleware.rake +1 -1
  81. data/lib/rails/tasks/routes.rake +5 -1
  82. data/lib/rails/test_help.rb +3 -1
  83. data/lib/rails/test_unit/testing.rake +3 -1
  84. data/lib/rails/version.rb +1 -1
  85. metadata +12 -19
  86. data/lib/rails/application/metal_loader.rb +0 -50
  87. data/lib/rails/dispatcher.rb +0 -24
  88. data/lib/rails/generators/rails/mailer/USAGE +0 -15
  89. data/lib/rails/generators/rails/mailer/mailer_generator.rb +0 -14
  90. data/lib/rails/generators/rails/mailer/templates/mailer.rb +0 -16
  91. data/lib/rails/generators/rails/metal/USAGE +0 -8
  92. data/lib/rails/generators/rails/metal/metal_generator.rb +0 -11
  93. data/lib/rails/generators/rails/metal/templates/metal.rb +0 -12
@@ -698,7 +698,7 @@ The most common entry points are message posts, user comments, and guest books,
698
698
 
699
699
  XSS attacks work like this: An attacker injects some code, the web application saves it and displays it on a page, later presented to a victim. Most XSS examples simply display an alert box, but it is more powerful than that. XSS can steal the cookie, hijack the session, redirect the victim to a fake website, display advertisements for the benefit of the attacker, change elements on the web site to get confidential information or install malicious software through security holes in the web browser.
700
700
 
701
- During the second half of 2007, there were 88 vulnerabilities reported in Mozilla browsers, 22 in Safari, 18 in IE, and 12 in Opera. The "Symantec Global Internet Security threat report":http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_internet_security_threat_report_xiii_04-2008.en-us.pdf also documented 239 browser plug-in vulnerabilities in the last six months of 2007. "Mpack":http://pandalabs.pandasecurity.com/archive/MPack-uncovered_2100_.aspx is a very active and up-to-date attack framework which exploits these vulnerabilities. For criminal hackers, it is very attractive to exploit an SQL-Injection vulnerability in a web application framework and insert malicious code in every textual table column. In April 2008 more than 510,000 sites were hacked like this, among them the British government, United Nations, and many more high targets.
701
+ During the second half of 2007, there were 88 vulnerabilities reported in Mozilla browsers, 22 in Safari, 18 in IE, and 12 in Opera. The "Symantec Global Internet Security threat report":http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_internet_security_threat_report_xiii_04-2008.en-us.pdf also documented 239 browser plug-in vulnerabilities in the last six months of 2007. "Mpack":http://pandalabs.pandasecurity.com/mpack-uncovered/ is a very active and up-to-date attack framework which exploits these vulnerabilities. For criminal hackers, it is very attractive to exploit an SQL-Injection vulnerability in a web application framework and insert malicious code in every textual table column. In April 2008 more than 510,000 sites were hacked like this, among them the British government, United Nations, and many more high targets.
702
702
 
703
703
  A relatively new, and unusual, form of entry points are banner advertisements. In earlier 2008, malicious code appeared in banner ads on popular sites, such as MySpace and Excite, according to "Trend Micro":http://blog.trendmicro.com/myspace-excite-and-blick-serve-up-malicious-banner-ads/.
704
704
 
@@ -12,7 +12,7 @@ endprologue.
12
12
 
13
13
  h3. Why Write Tests for your Rails Applications?
14
14
 
15
- * Rails makes it super easy to write your tests. It starts by producing skeleton test code in background while you are creating your models and controllers.
15
+ * Rails makes it super easy to write your tests. It starts by producing skeleton test code in the background while you are creating your models and controllers.
16
16
  * By simply running your Rails tests you can ensure your code adheres to the desired functionality even after some major code refactoring.
17
17
  * Rails tests can also simulate browser requests and thus you can test your application's response without having to test it through your browser.
18
18
 
@@ -54,7 +54,7 @@ For good tests, you'll need to give some thought to setting up test data. In Rai
54
54
 
55
55
  h5. What are Fixtures?
56
56
 
57
- _Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and assume one of two formats: *YAML* or *CSV*. In this guide we will use *YAML* which is the preferred format.
57
+ _Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and assume one of two formats: *YAML* or *CSV*. In this guide, we will use *YAML*, which is the preferred format.
58
58
 
59
59
  You'll find fixtures under your +test/fixtures+ directory. When you run +rails generate model+ to create a new model, fixture stubs will be automatically created and placed in this directory.
60
60
 
@@ -65,7 +65,7 @@ YAML-formatted fixtures are a very human-friendly way to describe your sample da
65
65
  Here's a sample YAML fixture file:
66
66
 
67
67
  <yaml>
68
- # low & behold! I am a YAML comment!
68
+ # lo & behold! I am a YAML comment!
69
69
  david:
70
70
  name: David Heinemeier Hansson
71
71
  birthday: 1979-10-15
@@ -108,7 +108,7 @@ tag is considered Ruby code. When this fixture is loaded, the +size+ attribute o
108
108
 
109
109
  h5. Fixtures in Action
110
110
 
111
- Rails by default automatically loads all fixtures from the 'test/fixtures' folder for your unit and functional test. Loading involves three steps:
111
+ Rails by default automatically loads all fixtures from the +test/fixtures+ folder for your unit and functional test. Loading involves three steps:
112
112
 
113
113
  * Remove any existing data from the table corresponding to the fixture
114
114
  * Load the fixture data into the table
@@ -140,20 +140,20 @@ h3. Unit Testing your Models
140
140
 
141
141
  In Rails, unit tests are what you write to test your models.
142
142
 
143
- For this guide we will be using Rails _scaffolding_. It will create the model, a migration, controller and views for the new resource in a single operation. It will also create a full test suite following Rails best practices. I will be using examples from this generated code and would be supplementing it with additional examples where necessary.
143
+ For this guide we will be using Rails _scaffolding_. It will create the model, a migration, controller and views for the new resource in a single operation. It will also create a full test suite following Rails best practices. I will be using examples from this generated code and will be supplementing it with additional examples where necessary.
144
144
 
145
- NOTE: For more information on Rails _scaffolding_, refer to "Getting Started with Rails":getting_started.html
145
+ NOTE: For more information on Rails <i>scaffolding</i>, refer to "Getting Started with Rails":getting_started.html
146
146
 
147
147
  When you use +rails generate scaffold+, for a resource among other things it creates a test stub in the +test/unit+ folder:
148
148
 
149
- <pre>
149
+ <shell>
150
150
  $ rails generate scaffold post title:string body:text
151
151
  ...
152
152
  create app/models/post.rb
153
153
  create test/unit/post_test.rb
154
154
  create test/fixtures/posts.yml
155
155
  ...
156
- </pre>
156
+ </shell>
157
157
 
158
158
  The default test stub in +test/unit/post_test.rb+ looks like this:
159
159
 
@@ -174,7 +174,7 @@ A line by line examination of this file will help get you oriented to Rails test
174
174
  require 'test_helper'
175
175
  </ruby>
176
176
 
177
- As you know by now that +test_helper.rb+ specifies the default configuration to run our tests. This is included with all the tests, so any methods added to this file are available to all your tests.
177
+ As you know by now, +test_helper.rb+ specifies the default configuration to run our tests. This is included with all the tests, so any methods added to this file are available to all your tests.
178
178
 
179
179
  <ruby>
180
180
  class PostTest < ActiveSupport::TestCase
@@ -204,16 +204,16 @@ assert true
204
204
 
205
205
  This line of code is called an _assertion_. An assertion is a line of code that evaluates an object (or expression) for expected results. For example, an assertion can check:
206
206
 
207
- * is this value = that value?
207
+ * does this value = that value?
208
208
  * is this object nil?
209
209
  * does this line of code throw an exception?
210
210
  * is the user's password greater than 5 characters?
211
211
 
212
- Every test contains one or more assertions. Only when all the assertions are successful the test passes.
212
+ Every test contains one or more assertions. Only when all the assertions are successful will the test pass.
213
213
 
214
214
  h4. Preparing your Application for Testing
215
215
 
216
- Before you can run your tests you need to ensure that the test database structure is current. For this you can use the following rake commands:
216
+ Before you can run your tests, you need to ensure that the test database structure is current. For this you can use the following rake commands:
217
217
 
218
218
  <shell>
219
219
  $ rake db:migrate
@@ -221,9 +221,9 @@ $ rake db:migrate
221
221
  $ rake db:test:load
222
222
  </shell>
223
223
 
224
- Above +rake db:migrate+ runs any pending migrations on the _development_ environment and updates +db/schema.rb+. +rake db:test:load+ recreates the test database from the current db/schema.rb. On subsequent attempts it is a good to first run +db:test:prepare+ as it first checks for pending migrations and warns you appropriately.
224
+ Above +rake db:migrate+ runs any pending migrations on the _development_ environment and updates +db/schema.rb+. +rake db:test:load+ recreates the test database from the current +db/schema.rb+. On subsequent attempts, it is a good idea to first run +db:test:prepare+, as it first checks for pending migrations and warns you appropriately.
225
225
 
226
- NOTE: +db:test:prepare+ will fail with an error if db/schema.rb doesn't exists.
226
+ NOTE: +db:test:prepare+ will fail with an error if +db/schema.rb+ doesn't exists.
227
227
 
228
228
  h5. Rake Tasks for Preparing your Application for Testing
229
229
 
@@ -256,7 +256,7 @@ This will run all the test methods from the test case.
256
256
 
257
257
  You can also run a particular test method from the test case by using the +-n+ switch with the +test method name+.
258
258
 
259
- <pre>
259
+ <shell>
260
260
  $ ruby unit/post_test.rb -n test_truth
261
261
 
262
262
  Loaded suite unit/post_test
@@ -265,7 +265,7 @@ Started
265
265
  Finished in 0.023513 seconds.
266
266
 
267
267
  1 tests, 1 assertions, 0 failures, 0 errors
268
- </pre>
268
+ </shell>
269
269
 
270
270
  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.
271
271
 
@@ -280,7 +280,7 @@ end
280
280
 
281
281
  Let us run this newly added test.
282
282
 
283
- <pre>
283
+ <shell>
284
284
  $ ruby unit/post_test.rb -n test_should_not_save_post_without_title
285
285
  Loaded suite -e
286
286
  Started
@@ -292,9 +292,9 @@ test_should_not_save_post_without_title(PostTest) [/test/unit/post_test.rb:6]:
292
292
  <false> is not true.
293
293
 
294
294
  1 tests, 1 assertions, 1 failures, 0 errors
295
- </pre>
295
+ </shell>
296
296
 
297
- 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:
297
+ 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:
298
298
 
299
299
  <ruby>
300
300
  test "should not save post without title" do
@@ -305,12 +305,12 @@ end
305
305
 
306
306
  Running this test shows the friendlier assertion message:
307
307
 
308
- <pre>
308
+ <shell>
309
309
  1) Failure:
310
310
  test_should_not_save_post_without_title(PostTest) [/test/unit/post_test.rb:6]:
311
311
  Saved the post without a title.
312
312
  <false> is not true.
313
- </pre>
313
+ </shell>
314
314
 
315
315
  Now to get this test to pass we can add a model level validation for the _title_ field.
316
316
 
@@ -322,7 +322,7 @@ end
322
322
 
323
323
  Now the test should pass. Let us verify by running the test again:
324
324
 
325
- <pre>
325
+ <shell>
326
326
  $ ruby unit/post_test.rb -n test_should_not_save_post_without_title
327
327
  Loaded suite unit/post_test
328
328
  Started
@@ -330,9 +330,9 @@ Started
330
330
  Finished in 0.193608 seconds.
331
331
 
332
332
  1 tests, 1 assertions, 0 failures, 0 errors
333
- </pre>
333
+ </shell>
334
334
 
335
- 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).
335
+ 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).
336
336
 
337
337
  TIP: Many Rails developers practice _Test-Driven Development_ (TDD). This is an excellent way to build up a test suite that exercises every part of your application. TDD is beyond the scope of this guide, but one place to start is with "15 TDD steps to create a Rails application":http://andrzejonsoftware.blogspot.com/2007/05/15-tdd-steps-to-create-rails.html.
338
338
 
@@ -348,7 +348,7 @@ end
348
348
 
349
349
  Now you can see even more output in the console from running the tests:
350
350
 
351
- <pre>
351
+ <shell>
352
352
  $ ruby unit/post_test.rb -n test_should_report_error
353
353
  Loaded suite -e
354
354
  Started
@@ -361,7 +361,7 @@ NameError: undefined local variable or method `some_undefined_variable' for #<Po
361
361
  /test/unit/post_test.rb:6:in `test_should_report_error'
362
362
 
363
363
  1 tests, 0 assertions, 0 failures, 1 errors
364
- </pre>
364
+ </shell>
365
365
 
366
366
  Notice the 'E' in the output. It denotes a test with error.
367
367
 
@@ -369,13 +369,13 @@ NOTE: The execution of each test method stops as soon as any error or an asserti
369
369
 
370
370
  h4. What to Include in Your Unit Tests
371
371
 
372
- Ideally you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.
372
+ Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.
373
373
 
374
374
  h4. Assertions Available
375
375
 
376
376
  By now you've caught a glimpse of some of the assertions that are available. Assertions are the worker bees of testing. They are the ones that actually perform the checks to ensure that things are going as planned.
377
377
 
378
- There are a bunch of different types of assertions you can use. Here's the complete list of assertions that ship with +test/unit+, the testing library used by Rails. The +[msg]+ parameter is an optional string message you can specify to make your test failure messages clearer. It's not required.
378
+ There are a bunch of different types of assertions you can use. Here's the complete list of assertions that ship with +test/unit+, the default testing library used by Rails. The +[msg]+ parameter is an optional string message you can specify to make your test failure messages clearer. It's not required.
379
379
 
380
380
  |_.Assertion |_.Purpose|
381
381
  |+assert( boolean, [msg] )+ |Ensures that the object/expression is true.|
@@ -446,7 +446,7 @@ test "should get index" do
446
446
  end
447
447
  </ruby>
448
448
 
449
- In the +test_should_get_index+ test, Rails simulates a request on the action called index, making sure the request was successful and also ensuring that it assigns a valid +posts+ instance variable.
449
+ In the +test_should_get_index+ test, Rails simulates a request on the action called +index+, making sure the request was successful and also ensuring that it assigns a valid +posts+ instance variable.
450
450
 
451
451
  The +get+ method kicks off the web request and populates the results into the response. It accepts 4 arguments:
452
452
 
@@ -615,7 +615,7 @@ Here's what a freshly-generated integration test looks like:
615
615
  require 'test_helper'
616
616
 
617
617
  class UserFlowsTest < ActionController::IntegrationTest
618
- # fixtures :your, :models
618
+ fixtures :all
619
619
 
620
620
  # Replace this with your real tests.
621
621
  test "the truth" do
@@ -702,24 +702,24 @@ class UserFlowsTest < ActionController::IntegrationTest
702
702
 
703
703
  private
704
704
 
705
- module CustomDsl
706
- def browses_site
707
- get "/products/all"
708
- assert_response :success
709
- assert assigns(:products)
710
- end
705
+ module CustomDsl
706
+ def browses_site
707
+ get "/products/all"
708
+ assert_response :success
709
+ assert assigns(:products)
711
710
  end
711
+ end
712
712
 
713
- def login(user)
714
- open_session do |sess|
715
- sess.extend(CustomDsl)
716
- u = users(user)
717
- sess.https!
718
- sess.post "/login", :username => u.username, :password => u.password
719
- assert_equal '/welcome', path
720
- sess.https!(false)
721
- end
713
+ def login(user)
714
+ open_session do |sess|
715
+ sess.extend(CustomDsl)
716
+ u = users(user)
717
+ sess.https!
718
+ sess.post "/login", :username => u.username, :password => u.password
719
+ assert_equal '/welcome', path
720
+ sess.https!(false)
722
721
  end
722
+ end
723
723
  end
724
724
  </ruby>
725
725
 
@@ -729,12 +729,15 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai
729
729
 
730
730
  |_.Tasks |_.Description|
731
731
  |+rake test+ |Runs all unit, functional and integration tests. You can also simply run +rake+ as the _test_ target is the default.|
732
- |+rake test:units+ |Runs all the unit tests from +test/unit+|
732
+ |+rake test:benchmark+ |Benchmark the performance tests|
733
733
  |+rake test:functionals+ |Runs all the functional tests from +test/functional+|
734
734
  |+rake test:integration+ |Runs all the integration tests from +test/integration+|
735
+ |+rake test:plugins+ |Run all the plugin tests from +vendor/plugins/*/**/test+ (or specify with +PLUGIN=_name_+)|
736
+ |+rake test:profile+ |Profile the performance tests|
735
737
  |+rake test:recent+ |Tests recent changes|
736
738
  |+rake test:uncommitted+ |Runs all the tests which are uncommitted. Only supports Subversion|
737
- |+rake test:plugins+ |Run all the plugin tests from +vendor/plugins/*/**/test+ (or specify with +PLUGIN=_name_+)|
739
+ |+rake test:units+ |Runs all the unit tests from +test/unit+|
740
+
738
741
 
739
742
  h3. Brief Note About +Test::Unit+
740
743
 
@@ -780,7 +783,7 @@ class PostsControllerTest < ActionController::TestCase
780
783
  end
781
784
  </ruby>
782
785
 
783
- Above, the +setup+ method is called before each test and so +@post+ is available for each of the tests. Rails implements +setup+ and +teardown+ as ActiveSupport::Callbacks. Which essentially means you need not only use +setup+ and +teardown+ as methods in your tests. You could specify them by using:
786
+ Above, the +setup+ method is called before each test and so +@post+ is available for each of the tests. Rails implements +setup+ and +teardown+ as +ActiveSupport::Callbacks+. Which essentially means you need not only use +setup+ and +teardown+ as methods in your tests. You could specify them by using:
784
787
 
785
788
  * a block
786
789
  * a method (like in the earlier example)
@@ -845,9 +848,9 @@ Testing mailer classes requires some specific tools to do a thorough job.
845
848
 
846
849
  h4. Keeping the Postman in Check
847
850
 
848
- Your +ActionMailer+ classes -- like every other part of your Rails application -- should be tested to ensure that it is working as expected.
851
+ Your mailer classes -- like every other part of your Rails application -- should be tested to ensure that it is working as expected.
849
852
 
850
- The goals of testing your +ActionMailer+ classes are to ensure that:
853
+ The goals of testing your mailer classes are to ensure that:
851
854
 
852
855
  * emails are being processed (created and sent)
853
856
  * the email content is correct (subject, sender, body, etc)
@@ -855,7 +858,7 @@ The goals of testing your +ActionMailer+ classes are to ensure that:
855
858
 
856
859
  h5. From All Sides
857
860
 
858
- There are two aspects of testing your mailer, the unit tests and the functional tests. In the unit tests, you run the mailer in isolation with tightly controlled inputs and compare the output to a known value (a fixture -- yay! more fixtures!). In the functional tests you don't so much test the minute details produced by the mailer Instead we test that our controllers and models are using the mailer in the right way. You test to prove that the right email was sent at the right time.
861
+ There are two aspects of testing your mailer, the unit tests and the functional tests. In the unit tests, you run the mailer in isolation with tightly controlled inputs and compare the output to a known value (a fixture.) In the functional tests you don't so much test the minute details produced by the mailer; instead, we test that our controllers and models are using the mailer in the right way. You test to prove that the right email was sent at the right time.
859
862
 
860
863
  h4. Unit Testing
861
864
 
@@ -907,7 +910,7 @@ However often in unit tests, mails will not actually be sent, simply constructed
907
910
 
908
911
  h4. Functional Testing
909
912
 
910
- Functional testing for mailers involves more than just checking that the email body, recipients and so forth are correct. In functional mail tests you call the mail deliver methods and check that the appropriate emails have been appended to the delivery list. It is fairly safe to assume that the deliver methods themselves do their job You are probably more interested in is whether your own business logic is sending emails when you expect them to got out. For example, you can check that the invite friend operation is sending an email appropriately:
913
+ Functional testing for mailers involves more than just checking that the email body, recipients and so forth are correct. In functional mail tests you call the mail deliver methods and check that the appropriate emails have been appended to the delivery list. It is fairly safe to assume that the deliver methods themselves do their job. You are probably more interested in whether your own business logic is sending emails when you expect them to go out. For example, you can check that the invite friend operation is sending an email appropriately:
911
914
 
912
915
  <ruby>
913
916
  require 'test_helper'
@@ -0,0 +1,67 @@
1
+ # ---------------------------------------------------------------------------
2
+ #
3
+ # This script validates the generated guides against the W3C Validator.
4
+ #
5
+ # Guides are taken from the output directory, from where all .html files are
6
+ # submitted to the validator.
7
+ #
8
+ # This script is prepared to be launched from the railties directory as a rake task:
9
+ #
10
+ # rake validate_guides
11
+ #
12
+ # If nothing is specified, all files will be validated, but you can check just
13
+ # some of them using this environment variable:
14
+ #
15
+ # ONLY
16
+ # Use ONLY if you want to validate only one or a set of guides. Prefixes are
17
+ # enough:
18
+ #
19
+ # # validates only association_basics.html
20
+ # ONLY=assoc rake validate_guides
21
+ #
22
+ # Separate many using commas:
23
+ #
24
+ # # validates only
25
+ # ONLY=assoc,migrations rake validate_guides
26
+ #
27
+ # ---------------------------------------------------------------------------
28
+
29
+ require 'rubygems'
30
+ require 'w3c_validators'
31
+ include W3CValidators
32
+
33
+ module RailsGuides
34
+ class Validator
35
+
36
+ def validate
37
+ validator = MarkupValidator.new
38
+
39
+ guides_to_validate.each do |f|
40
+ puts "Validating #{f}"
41
+ results = validator.validate_file(f)
42
+
43
+ if !results.validity
44
+ puts "#{f} FAILED W3C validation with #{results.errors.size} error(s):"
45
+ results.errors.each do |error|
46
+ puts error.to_s
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ private
53
+ def guides_to_validate
54
+ guides = Dir["./guides/output/*.html"]
55
+ ENV.key?('ONLY') ? select_only(guides) : guides
56
+ end
57
+
58
+ def select_only(guides)
59
+ prefixes = ENV['ONLY'].split(",").map(&:strip)
60
+ guides.select do |guide|
61
+ prefixes.any? {|p| guide.start_with?("./guides/output/#{p}")}
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ RailsGuides::Validator.new.validate
@@ -23,6 +23,7 @@ if RUBY_VERSION < '1.9'
23
23
  $KCODE='u'
24
24
  else
25
25
  Encoding.default_external = Encoding::UTF_8
26
+ Encoding.default_internal = Encoding::UTF_8
26
27
  end
27
28
 
28
29
  module Rails
@@ -12,7 +12,7 @@ module Rails
12
12
  # points to it.
13
13
  #
14
14
  # In other words, Rails::Application is Singleton and whenever you are accessing
15
- # Rails::Application.config or YourApplication::Application.config, you are actually
15
+ # Rails::Application.config or YourApplication::Application.config, you are actually
16
16
  # accessing YourApplication::Application.instance.config.
17
17
  #
18
18
  # == Initialization
@@ -27,7 +27,7 @@ module Rails
27
27
  # Besides providing the same configuration as Rails::Engine and Rails::Railtie,
28
28
  # the application object has several specific configurations, for example
29
29
  # "allow_concurrency", "cache_classes", "consider_all_requests_local", "filter_parameters",
30
- # "logger", "metals", "reload_engines", "reload_plugins" and so forth.
30
+ # "logger", "reload_engines", "reload_plugins" and so forth.
31
31
  #
32
32
  # Check Rails::Application::Configuration to see them all.
33
33
  #
@@ -36,17 +36,15 @@ module Rails
36
36
  # The application object is also responsible for holding the routes and reloading routes
37
37
  # whenever the files change in development.
38
38
  #
39
- # == Middlewares and metals
39
+ # == Middlewares
40
+ #
41
+ # The Application is also responsible for building the middleware stack.
40
42
  #
41
- # The Application is also responsible for building the middleware stack and setting up
42
- # both application and engines metals.
43
- #
44
43
  class Application < Engine
45
44
  autoload :Bootstrap, 'rails/application/bootstrap'
46
45
  autoload :Configurable, 'rails/application/configurable'
47
46
  autoload :Configuration, 'rails/application/configuration'
48
47
  autoload :Finisher, 'rails/application/finisher'
49
- autoload :MetalLoader, 'rails/application/metal_loader'
50
48
  autoload :Railties, 'rails/application/railties'
51
49
  autoload :RoutesReloader, 'rails/application/routes_reloader'
52
50
 
@@ -69,6 +67,8 @@ module Rails
69
67
  raise "You cannot have more than one Rails::Application" if Rails.application
70
68
  super
71
69
  Rails.application = base.instance
70
+ Rails.application.add_lib_to_load_paths!
71
+ ActiveSupport.run_load_hooks(:before_configuration, base.instance)
72
72
  end
73
73
 
74
74
  def respond_to?(*args)
@@ -82,13 +82,23 @@ module Rails
82
82
  end
83
83
  end
84
84
 
85
- delegate :metal_loader, :to => :config
85
+ delegate :middleware, :to => :config
86
+
87
+ def add_lib_to_load_paths!
88
+ path = config.root.join('lib').to_s
89
+ $LOAD_PATH.unshift(path) if File.exists?(path)
90
+ end
86
91
 
87
92
  def require_environment!
88
- environment = config.paths.config.environment.to_a.first
93
+ environment = paths.config.environment.to_a.first
89
94
  require environment if environment
90
95
  end
91
96
 
97
+ def eager_load!
98
+ railties.all(&:eager_load!)
99
+ super
100
+ end
101
+
92
102
  def routes
93
103
  @routes ||= ActionDispatch::Routing::RouteSet.new
94
104
  end
@@ -112,20 +122,23 @@ module Rails
112
122
 
113
123
  def load_tasks
114
124
  initialize_tasks
115
- super
116
125
  railties.all { |r| r.load_tasks }
126
+ super
117
127
  self
118
128
  end
119
129
 
120
130
  def load_generators
121
131
  initialize_generators
122
- super
123
132
  railties.all { |r| r.load_generators }
133
+ super
124
134
  self
125
135
  end
126
136
 
127
137
  def app
128
- @app ||= middleware.build(routes)
138
+ @app ||= begin
139
+ config.middleware = config.middleware.merge_into(default_middleware_stack)
140
+ config.middleware.build(routes)
141
+ end
129
142
  end
130
143
 
131
144
  def call(env)
@@ -149,11 +162,34 @@ module Rails
149
162
 
150
163
  protected
151
164
 
165
+ def default_middleware_stack
166
+ ActionDispatch::MiddlewareStack.new.tap do |middleware|
167
+ middleware.use ::ActionDispatch::Static, paths.public.to_a.first if config.serve_static_assets
168
+ middleware.use ::Rack::Lock if !config.allow_concurrency
169
+ middleware.use ::Rack::Runtime
170
+ middleware.use ::Rails::Rack::Logger
171
+ middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local if config.action_dispatch.show_exceptions
172
+ middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
173
+ middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
174
+ middleware.use ::ActionDispatch::Callbacks, !config.cache_classes
175
+ middleware.use ::ActionDispatch::Cookies
176
+
177
+ if config.session_store
178
+ middleware.use config.session_store, config.session_options
179
+ middleware.use ::ActionDispatch::Flash
180
+ end
181
+
182
+ middleware.use ::ActionDispatch::ParamsParser
183
+ middleware.use ::Rack::MethodOverride
184
+ middleware.use ::ActionDispatch::Head
185
+ end
186
+ end
187
+
152
188
  def initialize_tasks
153
189
  require "rails/tasks"
154
190
  task :environment do
155
191
  $rails_rake_task = true
156
- initialize!
192
+ require_environment!
157
193
  end
158
194
  end
159
195