aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Rakefile62
-rwxr-xr-xactionmailer/Rakefile4
-rw-r--r--actionmailer/lib/action_mailer/base.rb5
-rwxr-xr-xactionmailer/test/mail_service_test.rb6
-rw-r--r--actionpack/CHANGELOG14
-rw-r--r--actionpack/Rakefile10
-rwxr-xr-xactionpack/lib/action_controller/base.rb35
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb41
-rw-r--r--actionpack/lib/action_controller/dispatcher.rb2
-rw-r--r--actionpack/lib/action_controller/integration.rb9
-rw-r--r--actionpack/lib/action_controller/layout.rb2
-rw-r--r--actionpack/lib/action_controller/performance_test.rb16
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb4
-rw-r--r--actionpack/lib/action_controller/resources.rb6
-rw-r--r--actionpack/lib/action_controller/templates/rescues/layout.erb2
-rw-r--r--actionpack/lib/action_controller/verification.rb2
-rw-r--r--actionpack/lib/action_view.rb10
-rw-r--r--actionpack/lib/action_view/base.rb107
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb5
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb5
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb60
-rw-r--r--actionpack/lib/action_view/inline_template.rb9
-rw-r--r--actionpack/lib/action_view/partial_template.rb76
-rw-r--r--actionpack/lib/action_view/template.rb109
-rw-r--r--actionpack/lib/action_view/template_file.rb88
-rw-r--r--actionpack/lib/action_view/template_finder.rb177
-rw-r--r--actionpack/lib/action_view/template_handler.rb1
-rw-r--r--actionpack/lib/action_view/template_handlers.rb46
-rw-r--r--actionpack/lib/action_view/template_handlers/compilable.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb5
-rw-r--r--actionpack/lib/action_view/view_load_paths.rb103
-rw-r--r--actionpack/test/controller/base_test.rb18
-rw-r--r--actionpack/test/controller/caching_test.rb53
-rw-r--r--actionpack/test/controller/integration_test.rb93
-rw-r--r--actionpack/test/controller/new_render_test.rb15
-rw-r--r--actionpack/test/controller/verification_test.rb51
-rw-r--r--actionpack/test/controller/view_paths_test.rb111
-rwxr-xr-xactionpack/test/template/date_helper_test.rb12
-rw-r--r--actionpack/test/template/form_helper_test.rb251
-rw-r--r--actionpack/test/template/form_options_helper_test.rb36
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb29
-rw-r--r--actionpack/test/template/javascript_helper_test.rb14
-rw-r--r--actionpack/test/template/prototype_helper_test.rb20
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb9
-rw-r--r--actionpack/test/template/tag_helper_test.rb11
-rw-r--r--actionpack/test/template/template_file_test.rb95
-rw-r--r--actionpack/test/template/template_finder_test.rb73
-rw-r--r--actionpack/test/template/template_object_test.rb37
-rw-r--r--actionpack/test/template/text_helper_test.rb6
-rw-r--r--actionpack/test/template/url_helper_test.rb8
-rw-r--r--activerecord/CHANGELOG6
-rwxr-xr-xactiverecord/Rakefile6
-rw-r--r--activerecord/lib/active_record/association_preload.rb4
-rwxr-xr-xactiverecord/lib/active_record/associations.rb28
-rwxr-xr-xactiverecord/lib/active_record/base.rb38
-rw-r--r--activerecord/lib/active_record/calculations.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb4
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb79
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb71
-rwxr-xr-xactiverecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/observer.rb2
-rw-r--r--activerecord/lib/active_record/vendor/db2.rb362
-rw-r--r--activerecord/lib/active_record/vendor/mysql.rb1214
-rwxr-xr-xactiverecord/test/cases/associations/belongs_to_associations_test.rb19
-rw-r--r--activerecord/test/cases/associations/eager_test.rb13
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb17
-rwxr-xr-xactiverecord/test/cases/associations/has_one_associations_test.rb12
-rw-r--r--activerecord/test/cases/calculations_test.rb46
-rw-r--r--activerecord/test/cases/database_statements_test.rb12
-rwxr-xr-xactiverecord/test/cases/lifecycle_test.rb17
-rw-r--r--activerecord/test/cases/reflection_test.rb6
-rwxr-xr-xactiverecord/test/models/company.rb4
-rw-r--r--activerecord/test/models/developer.rb3
-rw-r--r--activeresource/Rakefile7
-rw-r--r--activeresource/lib/active_resource/base.rb6
-rw-r--r--activeresource/test/base_test.rb48
-rw-r--r--activeresource/test/fixtures/customer.rb3
-rw-r--r--activesupport/CHANGELOG8
-rw-r--r--activesupport/Rakefile12
-rw-r--r--activesupport/lib/active_support/core_ext/array/access.rb45
-rw-r--r--activesupport/lib/active_support/core_ext/blank.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb22
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb7
-rw-r--r--activesupport/lib/active_support/ordered_hash.rb1
-rw-r--r--activesupport/lib/active_support/test_case.rb9
-rw-r--r--activesupport/lib/active_support/testing/performance.rb397
-rw-r--r--activesupport/lib/active_support/testing/setup_and_teardown.rb38
-rw-r--r--activesupport/lib/active_support/vendor.rb4
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb95
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone_info.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone_info.rb)2
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Algiers.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Algiers.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Cairo.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Cairo.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Casablanca.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Casablanca.rb)2
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Harare.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Harare.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Johannesburg.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Johannesburg.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Monrovia.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Monrovia.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Nairobi.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Nairobi.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/Buenos_Aires.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/Buenos_Aires.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/San_Juan.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/San_Juan.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Bogota.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Bogota.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Caracas.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Caracas.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chicago.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chicago.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chihuahua.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chihuahua.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Denver.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Denver.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Godthab.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Godthab.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Guatemala.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Guatemala.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Halifax.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Halifax.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Indiana/Indianapolis.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Indiana/Indianapolis.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Juneau.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Juneau.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/La_Paz.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/La_Paz.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Lima.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Lima.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Los_Angeles.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Los_Angeles.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mazatlan.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mazatlan.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mexico_City.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mexico_City.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Monterrey.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Monterrey.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/New_York.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/New_York.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Phoenix.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Phoenix.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Regina.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Regina.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Santiago.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Santiago.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/St_Johns.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/St_Johns.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Tijuana.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Tijuana.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Almaty.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Almaty.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baghdad.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baghdad.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baku.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baku.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Bangkok.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Bangkok.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Chongqing.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Chongqing.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Dhaka.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Dhaka.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Hong_Kong.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Hong_Kong.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Irkutsk.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Irkutsk.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jakarta.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jakarta.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jerusalem.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jerusalem.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kabul.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kabul.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kamchatka.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kamchatka.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Karachi.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Karachi.rb)2
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Katmandu.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Katmandu.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kolkata.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kolkata.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Krasnoyarsk.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Krasnoyarsk.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuala_Lumpur.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuala_Lumpur.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuwait.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuwait.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Magadan.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Magadan.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Muscat.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Muscat.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Novosibirsk.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Novosibirsk.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Rangoon.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Rangoon.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Riyadh.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Riyadh.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Seoul.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Seoul.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Shanghai.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Shanghai.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Singapore.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Singapore.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Taipei.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Taipei.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tashkent.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tashkent.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tbilisi.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tbilisi.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tehran.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tehran.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tokyo.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tokyo.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Ulaanbaatar.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Ulaanbaatar.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Urumqi.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Urumqi.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Vladivostok.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Vladivostok.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yakutsk.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yakutsk.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yekaterinburg.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yekaterinburg.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yerevan.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yerevan.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Azores.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Azores.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Cape_Verde.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Cape_Verde.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/South_Georgia.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/South_Georgia.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Adelaide.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Adelaide.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Brisbane.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Brisbane.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Darwin.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Darwin.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Hobart.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Hobart.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Melbourne.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Melbourne.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Perth.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Perth.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Sydney.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Sydney.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Etc/UTC.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Etc/UTC.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Amsterdam.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Amsterdam.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Athens.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Athens.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Belgrade.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Belgrade.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Berlin.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Berlin.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bratislava.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bratislava.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Brussels.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Brussels.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bucharest.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bucharest.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Budapest.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Budapest.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Copenhagen.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Copenhagen.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Dublin.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Dublin.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Helsinki.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Helsinki.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Istanbul.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Istanbul.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Kiev.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Kiev.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Lisbon.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Lisbon.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Ljubljana.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Ljubljana.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/London.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/London.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Madrid.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Madrid.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Minsk.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Minsk.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Moscow.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Moscow.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Paris.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Paris.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Prague.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Prague.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Riga.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Riga.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Rome.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Rome.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sarajevo.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sarajevo.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Skopje.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Skopje.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sofia.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sofia.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Stockholm.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Stockholm.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Tallinn.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Tallinn.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vienna.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vienna.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vilnius.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vilnius.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Warsaw.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Warsaw.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Zagreb.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Zagreb.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Auckland.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Auckland.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Fiji.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Fiji.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Guam.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Guam.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Honolulu.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Honolulu.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Majuro.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Majuro.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Midway.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Midway.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Noumea.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Noumea.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Pago_Pago.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Pago_Pago.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Port_Moresby.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Port_Moresby.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Tongatapu.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Tongatapu.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/info_timezone.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/info_timezone.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone_info.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone_info.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/offset_rationals.rb95
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/time_or_datetime.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/time_or_datetime.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone.rb)12
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_definition.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_definition.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_info.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_info.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_offset_info.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_offset_info.rb)8
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_period.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_period.rb)0
-rw-r--r--activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_transition_info.rb (renamed from activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_transition_info.rb)4
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb14
-rw-r--r--activesupport/test/core_ext/blank_test.rb5
-rw-r--r--activesupport/test/core_ext/enumerable_test.rb6
-rw-r--r--activesupport/test/test_test.rb6
-rw-r--r--railties/CHANGELOG2
-rw-r--r--railties/Rakefile12
-rw-r--r--railties/configs/initializers/inflections.rb2
-rw-r--r--railties/helpers/performance_test.rb8
-rw-r--r--railties/helpers/performance_test_helper.rb6
-rw-r--r--railties/lib/rails_generator/generators/applications/app/app_generator.rb3
-rw-r--r--railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/model/templates/unit_test.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb14
-rw-r--r--railties/lib/tasks/databases.rake12
-rw-r--r--railties/lib/tasks/testing.rake15
-rw-r--r--railties/lib/test_help.rb3
-rw-r--r--railties/lib/webrick_server.rb13
250 files changed, 2248 insertions, 2681 deletions
diff --git a/.gitignore b/.gitignore
index 8c5dfb64e1..96a1c2117a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
debug.log
+doc
activeresource/doc
activerecord/doc
actionpack/doc
diff --git a/Rakefile b/Rakefile
index 11d205a725..368f36e56c 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,4 +1,6 @@
require 'rake'
+require 'rake/rdoctask'
+require 'rake/contrib/sshpublisher'
env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
@@ -11,7 +13,7 @@ end
desc 'Run all tests by default'
task :default => :test
-%w(test rdoc package pgem release).each do |task_name|
+%w(test rdoc package release).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
PROJECTS.each do |project|
@@ -19,3 +21,61 @@ task :default => :test
end
end
end
+
+
+desc "Generate documentation for the Rails framework"
+Rake::RDocTask.new do |rdoc|
+ rdoc.rdoc_dir = 'doc'
+ rdoc.title = "Rails Framework Documentation"
+
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.options << '-A cattr_accessor=object'
+ rdoc.options << '--charset' << 'utf-8'
+
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
+
+ rdoc.rdoc_files.include('railties/CHANGELOG')
+ rdoc.rdoc_files.include('railties/MIT-LICENSE')
+ rdoc.rdoc_files.include('railties/README')
+ rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,rails_generator/*.rb}')
+
+ rdoc.rdoc_files.include('activerecord/README')
+ rdoc.rdoc_files.include('activerecord/CHANGELOG')
+ rdoc.rdoc_files.include('activerecord/lib/active_record/**/*.rb')
+ rdoc.rdoc_files.exclude('activerecord/lib/active_record/vendor/*')
+
+ rdoc.rdoc_files.include('activeresource/README')
+ rdoc.rdoc_files.include('activeresource/CHANGELOG')
+ rdoc.rdoc_files.include('activeresource/lib/active_resource.rb')
+ rdoc.rdoc_files.include('activeresource/lib/active_resource/*')
+
+ rdoc.rdoc_files.include('actionpack/README')
+ rdoc.rdoc_files.include('actionpack/CHANGELOG')
+ rdoc.rdoc_files.include('actionpack/lib/action_controller/**/*.rb')
+ rdoc.rdoc_files.include('actionpack/lib/action_view/**/*.rb')
+ rdoc.rdoc_files.exclude('actionpack/lib/action_controller/vendor/*')
+
+ rdoc.rdoc_files.include('actionmailer/README')
+ rdoc.rdoc_files.include('actionmailer/CHANGELOG')
+ rdoc.rdoc_files.include('actionmailer/lib/action_mailer/base.rb')
+ rdoc.rdoc_files.exclude('actionmailer/lib/action_mailer/vendor/*')
+
+ rdoc.rdoc_files.include('activesupport/README')
+ rdoc.rdoc_files.include('activesupport/CHANGELOG')
+ rdoc.rdoc_files.include('activesupport/lib/active_support/**/*.rb')
+ rdoc.rdoc_files.exclude('activesupport/lib/active_support/vendor/*')
+end
+
+# Enhance rdoc task to copy referenced images also
+task :rdoc do
+ FileUtils.mkdir_p "doc/files/examples/"
+ FileUtils.copy "activerecord/examples/associations.png", "doc/files/examples/associations.png"
+end
+
+desc "Publish API docs for Rails as a whole and for each component"
+task :pdoc => :rdoc do
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/api", "doc").upload
+ PROJECTS.each do |project|
+ system %(cd #{project} && #{env} #{$0} pdoc)
+ end
+end
diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile
index c09526cbef..b003f4d559 100755
--- a/actionmailer/Rakefile
+++ b/actionmailer/Rakefile
@@ -76,12 +76,12 @@ end
desc "Publish the API documentation"
task :pgem => [:package] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/am", "doc").upload
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/am", "doc").upload
end
desc "Publish the release files to RubyForge."
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 51fc6032cc..1518e23dfe 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -426,8 +426,7 @@ module ActionMailer #:nodoc:
end
def template_root=(root)
- write_inheritable_attribute(:template_root, root)
- ActionView::TemplateFinder.process_view_paths(root)
+ write_inheritable_attribute(:template_root, ActionView::ViewLoadPaths.new(Array(root)))
end
end
@@ -547,7 +546,7 @@ module ActionMailer #:nodoc:
end
def initialize_template_class(assigns)
- ActionView::Base.new([template_root], assigns, self)
+ ActionView::Base.new(template_root, assigns, self)
end
def sort_parts(parts, order = [])
diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb
index e5ecb0e254..7f4a8817ca 100755
--- a/actionmailer/test/mail_service_test.rb
+++ b/actionmailer/test/mail_service_test.rb
@@ -942,13 +942,13 @@ end # uses_mocha
class InheritableTemplateRootTest < Test::Unit::TestCase
def test_attr
expected = "#{File.dirname(__FILE__)}/fixtures/path.with.dots"
- assert_equal expected, FunkyPathMailer.template_root
+ assert_equal [expected], FunkyPathMailer.template_root.map(&:to_s)
sub = Class.new(FunkyPathMailer)
sub.template_root = 'test/path'
- assert_equal 'test/path', sub.template_root
- assert_equal expected, FunkyPathMailer.template_root
+ assert_equal ['test/path'], sub.template_root.map(&:to_s)
+ assert_equal [expected], FunkyPathMailer.template_root.map(&:to_s)
end
end
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 8265b5b04f..4a6e70a153 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,19 @@
*Edge*
+* Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek]
+
+* Added block-call style to link_to [Sam Stephenson/DHH]. Example:
+
+ <% link_to(@profile) do %>
+ <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
+ <% end %>
+
+* Performance: integration test benchmarking and profiling. [Jeremy Kemper]
+
+* Make caching more aware of mime types. Ensure request format is not considered while expiring cache. [Jonathan del Strother]
+
+* Drop ActionController::Base.allow_concurrency flag [Josh Peek]
+
* More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper]
* Added page.reload functionality. Resolves #277. [Sean Huber]
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index b37f756c1e..86a2f3af14 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -54,7 +54,9 @@ Rake::RDocTask.new { |rdoc|
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
else
rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG')
- rdoc.rdoc_files.include('lib/**/*.rb')
+ rdoc.rdoc_files.include(Dir['lib/**/*.rb'] -
+ Dir['lib/*/vendor/**/*.rb'])
+ rdoc.rdoc_files.exclude('lib/actionpack.rb')
end
}
@@ -132,13 +134,13 @@ task :update_js => [ :update_scriptaculous ]
desc "Publish the API documentation"
task :pgem => [:package] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ `ssh wrath.rubyonrails.org './gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/ap", "doc").upload
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ap", "doc").upload
end
desc "Publish the release files to RubyForge."
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index a036600c2b..bf34edcd85 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -283,13 +283,6 @@ module ActionController #:nodoc:
@@debug_routes = true
cattr_accessor :debug_routes
- # Indicates to Mongrel or Webrick whether to allow concurrent action
- # processing. Your controller actions and any other code they call must
- # also behave well when called from concurrent threads. Turned off by
- # default.
- @@allow_concurrency = false
- cattr_accessor :allow_concurrency
-
# Modern REST web services often need to submit complex data to the web application.
# The <tt>@@param_parsers</tt> hash lets you register handlers which will process the HTTP body and add parameters to the
# <tt>params</tt> hash. These handlers are invoked for POST and PUT requests.
@@ -428,8 +421,7 @@ module ActionController #:nodoc:
end
def view_paths=(value)
- @view_paths = value
- ActionView::TemplateFinder.process_view_paths(value)
+ @view_paths = ActionView::ViewLoadPaths.new(Array(value)) if value
end
# Adds a view_path to the front of the view_paths array.
@@ -441,8 +433,7 @@ module ActionController #:nodoc:
#
def prepend_view_path(path)
@view_paths = superclass.view_paths.dup if @view_paths.nil?
- view_paths.unshift(*path)
- ActionView::TemplateFinder.process_view_paths(path)
+ @view_paths.unshift(*path)
end
# Adds a view_path to the end of the view_paths array.
@@ -454,8 +445,7 @@ module ActionController #:nodoc:
#
def append_view_path(path)
@view_paths = superclass.view_paths.dup if @view_paths.nil?
- view_paths.push(*path)
- ActionView::TemplateFinder.process_view_paths(path)
+ @view_paths.push(*path)
end
# Replace sensitive parameter data from the request log.
@@ -613,8 +603,8 @@ module ActionController #:nodoc:
#
# This takes the current URL as is and only exchanges the action. In contrast, <tt>url_for :action => 'print'</tt>
# would have slashed-off the path components after the changed action.
- def url_for(options = nil) #:doc:
- case options || {}
+ def url_for(options = {}) #:doc:
+ case options
when String
options
when Hash
@@ -647,11 +637,11 @@ module ActionController #:nodoc:
# View load paths for controller.
def view_paths
- @template.finder.view_paths
+ @template.view_paths
end
def view_paths=(value)
- @template.finder.view_paths = value # Mutex needed
+ @template.view_paths = ViewLoadPaths.new(value)
end
# Adds a view_path to the front of the view_paths array.
@@ -661,7 +651,7 @@ module ActionController #:nodoc:
# self.prepend_view_path(["views/default", "views/custom"])
#
def prepend_view_path(path)
- @template.finder.prepend_view_path(path) # Mutex needed
+ @template.view_paths.unshift(*path)
end
# Adds a view_path to the end of the view_paths array.
@@ -671,7 +661,7 @@ module ActionController #:nodoc:
# self.append_view_path(["views/default", "views/custom"])
#
def append_view_path(path)
- @template.finder.append_view_path(path) # Mutex needed
+ @template.view_paths.push(*path)
end
protected
@@ -1232,7 +1222,7 @@ module ActionController #:nodoc:
end
def template_exists?(template_name = default_template_name)
- @template.finder.file_exists?(template_name)
+ @template.file_exists?(template_name)
end
def template_public?(template_name = default_template_name)
@@ -1240,9 +1230,8 @@ module ActionController #:nodoc:
end
def template_exempt_from_layout?(template_name = default_template_name)
- extension = @template && @template.finder.pick_template_extension(template_name)
- name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name
- @@exempt_from_layout.any? { |ext| name_with_extension =~ ext }
+ template_name = @template.send(:template_file_from_name, template_name) if @template
+ @@exempt_from_layout.any? { |ext| template_name.to_s =~ ext }
end
def default_template_name(action_name = self.action_name)
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index c4b0a97a33..65a36f7f98 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -67,10 +67,10 @@ module ActionController #:nodoc:
if options[:action].is_a?(Array)
options[:action].dup.each do |action|
- expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action })))
+ expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false))
end
else
- expire_fragment(ActionCachePath.path_for(self, options))
+ expire_fragment(ActionCachePath.path_for(self, options, false))
end
end
@@ -125,16 +125,24 @@ module ActionController #:nodoc:
attr_reader :path, :extension
class << self
- def path_for(controller, options)
- new(controller, options).path
+ def path_for(controller, options, infer_extension=true)
+ new(controller, options, infer_extension).path
end
end
-
- def initialize(controller, options = {})
- @extension = extract_extension(controller.request.path)
+
+ # When true, infer_extension will look up the cache path extension from the request's path & format.
+ # This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.
+ def initialize(controller, options = {}, infer_extension=true)
+ if infer_extension and options.is_a? Hash
+ request_extension = extract_extension(controller.request)
+ options = options.reverse_merge(:format => request_extension)
+ end
path = controller.url_for(options).split('://').last
normalize!(path)
- add_extension!(path, @extension)
+ if infer_extension
+ @extension = request_extension
+ add_extension!(path, @extension)
+ end
@path = URI.unescape(path)
end
@@ -144,13 +152,22 @@ module ActionController #:nodoc:
end
def add_extension!(path, extension)
- path << ".#{extension}" if extension
+ path << ".#{extension}" if extension and !path.ends_with?(extension)
end
-
- def extract_extension(file_path)
+
+ def extract_extension(request)
# Don't want just what comes after the last '.' to accommodate multi part extensions
# such as tar.gz.
- file_path[/^[^.]+\.(.+)$/, 1]
+ extension = request.path[/^[^.]+\.(.+)$/, 1]
+
+ # If there's no extension in the path, check request.format
+ if extension.nil?
+ extension = request.format.to_sym.to_s
+ if extension=='all'
+ extension = nil
+ end
+ end
+ extension
end
end
end
diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb
index fe4f6b4a7e..7df987d525 100644
--- a/actionpack/lib/action_controller/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatcher.rb
@@ -134,7 +134,7 @@ module ActionController
run_callbacks :prepare_dispatch
Routing::Routes.reload
- ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading
+ ActionController::Base.view_paths.reload!
end
# Cleanup the application by clearing out loaded classes so they can
diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb
index bd69d02ed7..18c2df8b37 100644
--- a/actionpack/lib/action_controller/integration.rb
+++ b/actionpack/lib/action_controller/integration.rb
@@ -1,9 +1,10 @@
-require 'stringio'
-require 'uri'
-
+require 'active_support/test_case'
require 'action_controller/dispatcher'
require 'action_controller/test_process'
+require 'stringio'
+require 'uri'
+
module ActionController
module Integration #:nodoc:
# An integration Session instance represents a set of requests and responses
@@ -580,7 +581,7 @@ EOF
# end
# end
# end
- class IntegrationTest < Test::Unit::TestCase
+ class IntegrationTest < ActiveSupport::TestCase
include Integration::Runner
# Work around a bug in test/unit caused by the default test being named
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb
index b5b59f2d7c..0721f71498 100644
--- a/actionpack/lib/action_controller/layout.rb
+++ b/actionpack/lib/action_controller/layout.rb
@@ -304,7 +304,7 @@ module ActionController #:nodoc:
end
def layout_directory?(layout_name)
- @template.finder.find_template_extension_from_handler(File.join('layouts', layout_name))
+ @template.view_paths.find_template_file_for_path("#{File.join('layouts', layout_name)}.#{@template.template_format}.erb") ? true : false
end
end
end
diff --git a/actionpack/lib/action_controller/performance_test.rb b/actionpack/lib/action_controller/performance_test.rb
new file mode 100644
index 0000000000..85543fffae
--- /dev/null
+++ b/actionpack/lib/action_controller/performance_test.rb
@@ -0,0 +1,16 @@
+require 'action_controller/integration'
+require 'active_support/testing/performance'
+require 'active_support/testing/default'
+
+module ActionController
+ # An integration test that runs a code profiler on your test methods.
+ # Profiling output for combinations of each test method, measurement, and
+ # output format are written to your tmp/performance directory.
+ #
+ # By default, process_time is measured and both flat and graph_html output
+ # formats are written, so you'll have two output files per test method.
+ class PerformanceTest < ActionController::IntegrationTest
+ include ActiveSupport::Testing::Performance
+ include ActiveSupport::Testing::Default
+ end
+end
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index f69c3d6163..742d290ad6 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -66,12 +66,12 @@ module ActionController
# The DOM id convention is to use the singular form of an object or class with the id following an underscore.
# If no id is found, prefix with "new_" instead. Examples:
#
- # dom_id(Post.new(:id => 45)) # => "post_45"
+ # dom_id(Post.find(45)) # => "post_45"
# dom_id(Post.new) # => "new_post"
#
# If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
#
- # dom_id(Post.new(:id => 45), :edit) # => "edit_post_45"
+ # dom_id(Post.find(45), :edit) # => "edit_post_45"
def dom_id(record, prefix = nil)
if record_id = record.id
"#{dom_class(record, prefix)}#{JOIN}#{record_id}"
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb
index 9fb1f9fa39..af2fcaf3ad 100644
--- a/actionpack/lib/action_controller/resources.rb
+++ b/actionpack/lib/action_controller/resources.rb
@@ -72,7 +72,7 @@ module ActionController
end
def conditions
- @conditions = @options[:conditions] || {}
+ @conditions ||= @options[:conditions] || {}
end
def path
@@ -80,9 +80,9 @@ module ActionController
end
def new_path
- new_action = self.options[:path_names][:new] if self.options[:path_names]
+ new_action = self.options[:path_names][:new] if self.options[:path_names]
new_action ||= Base.resources_path_names[:new]
- @new_path ||= "#{path}/#{new_action}"
+ @new_path ||= "#{path}/#{new_action}"
end
def member_path
diff --git a/actionpack/lib/action_controller/templates/rescues/layout.erb b/actionpack/lib/action_controller/templates/rescues/layout.erb
index d38f3e67f9..4a04742e40 100644
--- a/actionpack/lib/action_controller/templates/rescues/layout.erb
+++ b/actionpack/lib/action_controller/templates/rescues/layout.erb
@@ -1,4 +1,4 @@
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Action Controller: Exception caught</title>
<style>
diff --git a/actionpack/lib/action_controller/verification.rb b/actionpack/lib/action_controller/verification.rb
index 9f606e7b7c..35b12a7f13 100644
--- a/actionpack/lib/action_controller/verification.rb
+++ b/actionpack/lib/action_controller/verification.rb
@@ -116,7 +116,7 @@ module ActionController #:nodoc:
end
def apply_redirect_to(redirect_to_option) # :nodoc:
- redirect_to_option.is_a?(Symbol) ? self.send!(redirect_to_option) : redirect_to_option
+ (redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.send!(redirect_to_option) : redirect_to_option
end
def apply_remaining_actions(options) # :nodoc:
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 5f4126e4e9..973020a768 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -21,13 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-require 'action_view/template_handler'
-require 'action_view/template_handlers/compilable'
-require 'action_view/template_handlers/builder'
-require 'action_view/template_handlers/erb'
-require 'action_view/template_handlers/rjs'
-
-require 'action_view/template_finder'
+require 'action_view/template_handlers'
+require 'action_view/template_file'
+require 'action_view/view_load_paths'
require 'action_view/template'
require 'action_view/partial_template'
require 'action_view/inline_template'
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index eeebf335dc..4f3cc46a14 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -1,17 +1,17 @@
module ActionView #:nodoc:
class ActionViewError < StandardError #:nodoc:
end
-
+
class MissingTemplate < ActionViewError #:nodoc:
end
- # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
- # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
+ # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
+ # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
# If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
- #
+ #
# = ERb
- #
- # You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
+ #
+ # You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
# following loop for names:
#
# <b>Names of all the people</b>
@@ -51,7 +51,7 @@ module ActionView #:nodoc:
# <title><%= @page_title %></title>
#
# == Passing local variables to sub templates
- #
+ #
# You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
#
# <%= render "shared/header", { :headline => "Welcome", :person => person } %>
@@ -77,8 +77,8 @@ module ActionView #:nodoc:
#
# == Builder
#
- # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
- # named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
+ # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
+ # named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
#
# Here are some basic examples:
#
@@ -87,7 +87,7 @@ module ActionView #:nodoc:
# xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
# xml.target("name"=>"compile", "option"=>"fast") # => <target option="fast" name="compile"\>
# # NOTE: order of attributes is not specified.
- #
+ #
# Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
#
# xml.div {
@@ -111,7 +111,7 @@ module ActionView #:nodoc:
# xml.description "Basecamp: Recent items"
# xml.language "en-us"
# xml.ttl "40"
- #
+ #
# for item in @recent_items
# xml.item do
# xml.title(item_title(item))
@@ -119,7 +119,7 @@ module ActionView #:nodoc:
# xml.pubDate(item_pubDate(item))
# xml.guid(@person.firm.account.url + @recent_items.url(item))
# xml.link(@person.firm.account.url + @recent_items.url(item))
- #
+ #
# xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
# end
# end
@@ -130,12 +130,12 @@ module ActionView #:nodoc:
#
# == JavaScriptGenerator
#
- # JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
- # render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
- # modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
+ # JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
+ # render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
+ # modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
# and make updates to the page where the request originated from.
- #
- # An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
+ #
+ # An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
#
# When an <tt>.rjs</tt> action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
#
@@ -145,15 +145,14 @@ module ActionView #:nodoc:
#
# page.replace_html 'sidebar', :partial => 'sidebar'
# page.remove "person-#{@person.id}"
- # page.visual_effect :highlight, 'user-list'
+ # page.visual_effect :highlight, 'user-list'
#
# This refreshes the sidebar, removes a person element and highlights the user list.
- #
+ #
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
class Base
include ERB::Util
- attr_reader :finder
attr_accessor :base_path, :assigns, :template_extension, :first_render
attr_accessor :controller
@@ -170,22 +169,22 @@ module ActionView #:nodoc:
# Specify whether file modification times should be checked to see if a template needs recompilation
@@cache_template_loading = false
cattr_accessor :cache_template_loading
-
+
def self.cache_template_extensions=(*args)
ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no affect. " <<
"Please remove it from your config files.", caller)
end
# Specify whether RJS responses should be wrapped in a try/catch block
- # that alert()s the caught exception (and then re-raises it).
+ # that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
cattr_accessor :debug_rjs
attr_internal :request
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
- :flash, :logger, :action_name, :to => :controller
-
+ :flash, :logger, :action_name, :controller_name, :to => :controller
+
module CompiledTemplates #:nodoc:
# holds compiled template code
end
@@ -221,11 +220,17 @@ module ActionView #:nodoc:
@assigns = assigns_for_first_render
@assigns_added = nil
@controller = controller
- @finder = TemplateFinder.new(self, view_paths)
+ self.view_paths = view_paths
end
- # Renders the template present at <tt>template_path</tt>. If <tt>use_full_path</tt> is set to true,
- # it's relative to the view_paths array, otherwise it's absolute. The hash in <tt>local_assigns</tt>
+ attr_reader :view_paths
+
+ def view_paths=(paths)
+ @view_paths = ViewLoadPaths.new(Array(paths))
+ end
+
+ # Renders the template present at <tt>template_path</tt>. If <tt>use_full_path</tt> is set to true,
+ # it's relative to the view_paths array, otherwise it's absolute. The hash in <tt>local_assigns</tt>
# is made available as local variables.
def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc:
if defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) && !template_path.include?("/")
@@ -240,11 +245,11 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
render :partial => 'signup' # no mailer_name necessary
END_ERROR
end
-
+
Template.new(self, template_path, use_full_path, local_assigns).render_template
end
-
- # Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
+
+ # Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
# The hash in <tt>local_assigns</tt> is made available as local variables.
def render(options = {}, local_assigns = {}, &block) #:nodoc:
if options.is_a?(String)
@@ -257,7 +262,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
if partial_layout = options.delete(:layout)
if block_given?
- wrap_content_for_layout capture(&block) do
+ wrap_content_for_layout capture(&block) do
concat(render(options.merge(:partial => partial_layout)))
end
else
@@ -314,6 +319,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
end
end
+ def file_exists?(template_path)
+ view_paths.template_exists?(template_file_from_name(template_path))
+ end
+
private
def wrap_content_for_layout(content)
original_content_for_layout, @content_for_layout = @content_for_layout, content
@@ -334,11 +343,43 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
def assign_variables_from_controller
@assigns.each { |key, value| instance_variable_set("@#{key}", value) }
end
-
+
def execute(template)
send(template.method, template.locals) do |*names|
instance_variable_get "@content_for_#{names.first || 'layout'}"
- end
+ end
+ end
+
+ def template_file_from_name(template_name)
+ template_name = TemplateFile.from_path(template_name)
+ pick_template_extension(template_name) unless template_name.extension
+ end
+
+ # Gets the extension for an existing template with the given template_path.
+ # Returns the format with the extension if that template exists.
+ #
+ # pick_template_extension('users/show')
+ # # => 'html.erb'
+ #
+ # pick_template_extension('users/legacy')
+ # # => "rhtml"
+ #
+ def pick_template_extension(file)
+ if f = self.view_paths.find_template_file_for_path(file.dup_with_extension(template_format)) || file_from_first_render(file)
+ f
+ elsif template_format == :js && f = self.view_paths.find_template_file_for_path(file.dup_with_extension(:html))
+ @template_format = :html
+ f
+ else
+ nil
+ end
+ end
+
+ # Determine the template extension from the <tt>@first_render</tt> filename
+ def file_from_first_render(file)
+ if extension = File.basename(@first_render.to_s)[/^[^.]+\.(.+)$/, 1]
+ file.dup_with_extension(extension)
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 25e62f78fb..9cd9d3d06a 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -31,7 +31,7 @@ module ActionView
# </body></html>
#
def capture(*args, &block)
- if @output_buffer
+ if output_buffer
with_output_buffer { block.call(*args) }
else
block.call(*args)
@@ -121,10 +121,11 @@ module ActionView
private
def with_output_buffer(buf = '')
- @output_buffer, old_buffer = buf, @output_buffer
+ self.output_buffer, old_buffer = buf, output_buffer
yield
+ output_buffer
ensure
- @output_buffer = old_buffer
+ self.output_buffer = old_buffer
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 90bd99a861..b3f8e63c1b 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -304,7 +304,7 @@ module ActionView
#
# NOTE: Only the option tags are returned, you have to wrap this call in
# a regular HTML select tag.
- def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ActiveSupport::TimeZone)
+ def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
zone_options = ""
zones = model.all
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 85b205c264..7404a251e4 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -202,11 +202,6 @@ module ActionView
end
js_option
end
-
- private
- def block_is_within_action_view?(block)
- !@output_buffer.nil?
- end
end
JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index a8a5987b1f..e1abec1847 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -122,10 +122,6 @@ module ActionView
" #{attrs.sort * ' '}" unless attrs.empty?
end
end
-
- def block_is_within_action_view?(block)
- !@output_buffer.nil?
- end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 3077c8f970..a1a91f6b3d 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -29,8 +29,9 @@ module ActionView
if unused_binding
ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.")
end
- if @output_buffer && string
- @output_buffer << string
+
+ if output_buffer && string
+ output_buffer << string
else
string
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 4b12adf225..baecd304cd 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -90,6 +90,13 @@ module ActionView
# link will be used in place of a referrer if none exists. If nil is passed as
# a name, the link itself will become the name.
#
+ # ==== Signatures
+ #
+ # link_to(name, options = {}, html_options = nil)
+ # link_to(options = {}, html_options = nil) do
+ # # name
+ # end
+ #
# ==== Options
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
# prompt with the question specified. If the user accepts, the link is
@@ -147,6 +154,13 @@ module ActionView
# link_to "Profiles", :controller => "profiles"
# # => <a href="/profiles">Profiles</a>
#
+ # You can use a block as well if your link target is hard to fit into the name parameter. ERb example:
+ #
+ # <% link_to(@profile) do %>
+ # <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
+ # <% end %>
+ # # => <a href="/profiles/1"><strong>David</strong> -- <span>Check it out!!</span></a>
+ #
# Classes and ids for CSS are easy to produce:
#
# link_to "Articles", articles_path, :id => "news", :class => "article"
@@ -189,27 +203,37 @@ module ActionView
# f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
# var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
# m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>
- def link_to(name, options = {}, html_options = nil)
- url = case options
- when String
- options
- when :back
- @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
+ def link_to(*args, &block)
+ if block_given?
+ options = args.first || {}
+ html_options = args.second
+ concat(link_to(capture(&block), options, html_options))
+ else
+ name = args.first
+ options = args.second || {}
+ html_options = args.third
+
+ url = case options
+ when String
+ options
+ when :back
+ @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
+ else
+ self.url_for(options)
+ end
+
+ if html_options
+ html_options = html_options.stringify_keys
+ href = html_options['href']
+ convert_options_to_javascript!(html_options, url)
+ tag_options = tag_options(html_options)
else
- self.url_for(options)
+ tag_options = nil
end
-
- if html_options
- html_options = html_options.stringify_keys
- href = html_options['href']
- convert_options_to_javascript!(html_options, url)
- tag_options = tag_options(html_options)
- else
- tag_options = nil
+
+ href_attr = "href=\"#{url}\"" unless href
+ "<a #{href_attr}#{tag_options}>#{name || url}</a>"
end
-
- href_attr = "href=\"#{url}\"" unless href
- "<a #{href_attr}#{tag_options}>#{name || url}</a>"
end
# Generates a form containing a single button that submits to the URL created
diff --git a/actionpack/lib/action_view/inline_template.rb b/actionpack/lib/action_view/inline_template.rb
index 87c012d181..fd0ad48302 100644
--- a/actionpack/lib/action_view/inline_template.rb
+++ b/actionpack/lib/action_view/inline_template.rb
@@ -1,20 +1,17 @@
module ActionView #:nodoc:
class InlineTemplate < Template #:nodoc:
-
def initialize(view, source, locals = {}, type = nil)
@view = view
- @finder = @view.finder
-
+
@source = source
@extension = type
@locals = locals || {}
-
+
@handler = self.class.handler_class_for_extension(@extension).new(@view)
end
-
+
def method_key
@source
end
-
end
end
diff --git a/actionpack/lib/action_view/partial_template.rb b/actionpack/lib/action_view/partial_template.rb
index 0b374db888..0cf996ca04 100644
--- a/actionpack/lib/action_view/partial_template.rb
+++ b/actionpack/lib/action_view/partial_template.rb
@@ -1,70 +1,70 @@
module ActionView #:nodoc:
class PartialTemplate < Template #:nodoc:
-
attr_reader :variable_name, :object
-
+
def initialize(view, partial_path, object = nil, locals = {})
- @path, @variable_name = extract_partial_name_and_path(view, partial_path)
+ @view_controller = view.controller if view.respond_to?(:controller)
+ set_path_and_variable_name!(partial_path)
super(view, @path, true, locals)
add_object_to_local_assigns!(object)
# This is needed here in order to compile template with knowledge of 'counter'
- initialize_counter
-
+ initialize_counter!
+
# Prepare early. This is a performance optimization for partial collections
prepare!
end
-
+
def render
- ActionController::Base.benchmark("Rendered #{@path}", Logger::DEBUG, false) do
+ ActionController::Base.benchmark("Rendered #{@path.path_without_format_and_extension}", Logger::DEBUG, false) do
@handler.render(self)
end
end
-
+
def render_member(object)
@locals[:object] = @locals[@variable_name] = object
-
+
template = render_template
@locals[@counter_name] += 1
@locals.delete(@variable_name)
@locals.delete(:object)
-
+
template
end
-
+
def counter=(num)
@locals[@counter_name] = num
end
private
+ def add_object_to_local_assigns!(object)
+ @locals[:object] ||=
+ @locals[@variable_name] ||=
+ if object.is_a?(ActionView::Base::ObjectWrapper)
+ object.value
+ else
+ object
+ end || @view_controller.instance_variable_get("@#{variable_name}")
+ end
- def add_object_to_local_assigns!(object)
- @locals[:object] ||=
- @locals[@variable_name] ||=
- if object.is_a?(ActionView::Base::ObjectWrapper)
- object.value
- else
- object
- end || @view.controller.instance_variable_get("@#{variable_name}")
- end
-
- def extract_partial_name_and_path(view, partial_path)
- path, partial_name = partial_pieces(view, partial_path)
- [File.join(path, "_#{partial_name}"), partial_name.split('/').last.split('.').first.to_sym]
- end
-
- def partial_pieces(view, partial_path)
- if partial_path.include?('/')
- return File.dirname(partial_path), File.basename(partial_path)
- else
- return view.controller.class.controller_path, partial_path
+ def set_path_and_variable_name!(partial_path)
+ if partial_path.include?('/')
+ @variable_name = File.basename(partial_path)
+ @path = "#{File.dirname(partial_path)}/_#{@variable_name}"
+ elsif @view_controller
+ @variable_name = partial_path
+ @path = "#{@view_controller.class.controller_path}/_#{@variable_name}"
+ else
+ @variable_name = partial_path
+ @path = "_#{@variable_name}"
+ end
+
+ @variable_name = @variable_name.sub(/\..*$/, '').to_sym
+ end
+
+ def initialize_counter!
+ @counter_name ||= "#{@variable_name}_counter".to_sym
+ @locals[@counter_name] = 0
end
- end
-
- def initialize_counter
- @counter_name ||= "#{@variable_name}_counter".to_sym
- @locals[@counter_name] = 0
- end
-
end
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index 369526188f..4c3f252c10 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -1,19 +1,20 @@
module ActionView #:nodoc:
class Template #:nodoc:
+ extend TemplateHandlers
attr_accessor :locals
- attr_reader :handler, :path, :extension, :filename, :path_without_extension, :method
+ attr_reader :handler, :path, :extension, :filename, :method
def initialize(view, path, use_full_path, locals = {})
@view = view
- @finder = @view.finder
+ @paths = view.view_paths
- # Clear the forward slash at the beginning if exists
- @path = use_full_path ? path.sub(/^\//, '') : path
- @view.first_render ||= @path
+ @original_path = path
+ @path = TemplateFile.from_path(path, !use_full_path)
+ @view.first_render ||= @path.to_s
@source = nil # Don't read the source until we know that it is required
set_extension_and_file_name(use_full_path)
-
+
@locals = locals || {}
@handler = self.class.handler_class_for_extension(@extension).new(@view)
end
@@ -29,12 +30,16 @@ module ActionView #:nodoc:
raise TemplateError.new(self, @view.assigns, e)
end
end
-
+
def render
prepare!
@handler.render(self)
end
+ def path_without_extension
+ @path.path_without_extension
+ end
+
def source
@source ||= File.read(self.filename)
end
@@ -44,13 +49,13 @@ module ActionView #:nodoc:
end
def base_path_for_exception
- @finder.find_base_path_for("#{@path_without_extension}.#{@extension}") || @finder.view_paths.first
+ (@paths.find_load_path_for_path(@path) || @paths.first).to_s
end
-
+
def prepare!
@view.send :evaluate_assigns
@view.current_render_extension = @extension
-
+
if @handler.compilable?
@handler.compile_template(self) # compile the given template, if necessary
@method = @view.method_names[method_key] # Set the method name for this template and run it
@@ -58,70 +63,32 @@ module ActionView #:nodoc:
end
private
-
- def set_extension_and_file_name(use_full_path)
- @path_without_extension, @extension = @finder.path_and_extension(@path)
- if use_full_path
- if @extension
- @filename = @finder.pick_template(@path_without_extension, @extension)
+ def set_extension_and_file_name(use_full_path)
+ @extension = @path.extension
+
+ if use_full_path
+ unless @extension
+ @path = @view.send(:template_file_from_name, @path)
+ raise_missing_template_exception unless @path
+ @extension = @path.extension
+ end
+
+ if @path = @paths.find_template_file_for_path(path)
+ @filename = @path.full_path
+ @extension = @path.extension
+ end
else
- @extension = @finder.pick_template_extension(@path).to_s
- raise_missing_template_exception unless @extension
-
- @filename = @finder.pick_template(@path, @extension)
- @extension = @extension.gsub(/^.+\./, '') # strip off any formats
+ @filename = @path.full_path
end
- else
- @filename = @path
- end
-
- raise_missing_template_exception if @filename.blank?
- end
-
- def raise_missing_template_exception
- full_template_path = @path.include?('.') ? @path : "#{@path}.#{@view.template_format}.erb"
- display_paths = @finder.view_paths.join(':')
- template_type = (@path =~ /layouts/i) ? 'layout' : 'template'
- raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
- end
-
- # Template Handlers
-
- @@template_handlers = HashWithIndifferentAccess.new
- @@default_template_handlers = nil
-
- # Register a class that knows how to handle template files with the given
- # extension. This can be used to implement new template types.
- # The constructor for the class must take the ActiveView::Base instance
- # as a parameter, and the class must implement a +render+ method that
- # takes the contents of the template to render as well as the Hash of
- # local assigns available to the template. The +render+ method ought to
- # return the rendered template as a string.
- def self.register_template_handler(extension, klass)
- @@template_handlers[extension.to_sym] = klass
- TemplateFinder.update_extension_cache_for(extension.to_s)
- end
- def self.template_handler_extensions
- @@template_handlers.keys.map(&:to_s).sort
- end
-
- def self.register_default_template_handler(extension, klass)
- register_template_handler(extension, klass)
- @@default_template_handlers = klass
- end
-
- def self.handler_class_for_extension(extension)
- (extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
- end
-
- register_default_template_handler :erb, TemplateHandlers::ERB
- register_template_handler :rjs, TemplateHandlers::RJS
- register_template_handler :builder, TemplateHandlers::Builder
+ raise_missing_template_exception if @filename.blank?
+ end
- # TODO: Depreciate old template extensions
- register_template_handler :rhtml, TemplateHandlers::ERB
- register_template_handler :rxml, TemplateHandlers::Builder
-
+ def raise_missing_template_exception
+ full_template_path = @original_path.include?('.') ? @original_path : "#{@original_path}.#{@view.template_format}.erb"
+ display_paths = @paths.join(':')
+ template_type = (@original_path =~ /layouts/i) ? 'layout' : 'template'
+ raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
+ end
end
end
diff --git a/actionpack/lib/action_view/template_file.rb b/actionpack/lib/action_view/template_file.rb
new file mode 100644
index 0000000000..dd66482b3c
--- /dev/null
+++ b/actionpack/lib/action_view/template_file.rb
@@ -0,0 +1,88 @@
+module ActionView #:nodoc:
+ # TemplateFile abstracts the pattern of querying a file path for its
+ # path with or without its extension. The path is only the partial path
+ # from the load path root e.g. "hello/index.html.erb" not
+ # "app/views/hello/index.html.erb"
+ class TemplateFile
+ def self.from_path(path, use_full_path = false)
+ path.is_a?(self) ? path : new(path, use_full_path)
+ end
+
+ def self.from_full_path(load_path, full_path)
+ file = new(full_path.split(load_path).last)
+ file.load_path = load_path
+ file.freeze
+ end
+
+ attr_accessor :load_path, :base_path, :name, :format, :extension
+ delegate :to_s, :inspect, :to => :path
+
+ def initialize(path, use_full_path = false)
+ path = path.dup
+
+ # Clear the forward slash in the beginning unless using full path
+ trim_forward_slash!(path) unless use_full_path
+
+ @base_path, @name, @format, @extension = split(path)
+ end
+
+ def freeze
+ @load_path.freeze
+ @base_path.freeze
+ @name.freeze
+ @format.freeze
+ @extension.freeze
+ super
+ end
+
+ def format_and_extension
+ extensions = [format, extension].compact.join(".")
+ extensions.blank? ? nil : extensions
+ end
+
+ def full_path
+ if load_path
+ "#{load_path}/#{path}"
+ else
+ path
+ end
+ end
+
+ def path
+ base_path.to_s + [name, format, extension].compact.join(".")
+ end
+
+ def path_without_extension
+ base_path.to_s + [name, format].compact.join(".")
+ end
+
+ def path_without_format_and_extension
+ "#{base_path}#{name}"
+ end
+
+ def dup_with_extension(extension)
+ file = dup
+ file.extension = extension ? extension.to_s : nil
+ file
+ end
+
+ private
+ def trim_forward_slash!(path)
+ path.sub!(/^\//, '')
+ end
+
+ # Returns file split into an array
+ # [base_path, name, format, extension]
+ def split(file)
+ if m = file.match(/^(.*\/)?(\w+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
+ if m[5] # Mulipart formats
+ [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
+ elsif m[4] # Single format
+ [m[1], m[2], m[3], m[4]]
+ else # No format
+ [m[1], m[2], nil, m[3]]
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_view/template_finder.rb b/actionpack/lib/action_view/template_finder.rb
deleted file mode 100644
index 83b7e27c09..0000000000
--- a/actionpack/lib/action_view/template_finder.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-module ActionView #:nodoc:
- class TemplateFinder #:nodoc:
-
- class InvalidViewPath < StandardError #:nodoc:
- attr_reader :unprocessed_path
- def initialize(path)
- @unprocessed_path = path
- super("Unprocessed view path found: #{@unprocessed_path.inspect}. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=.")
- end
- end
-
- cattr_reader :processed_view_paths
- @@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
-
- cattr_reader :file_extension_cache
- @@file_extension_cache = Hash.new {|hash, key|
- hash[key] = Hash.new {|hash, key| hash[key] = []}
- }
-
- class << self #:nodoc:
-
- # This method is not thread safe. Mutex should be used whenever this is accessed from an instance method
- def process_view_paths(*view_paths)
- view_paths.flatten.compact.each do |dir|
- next if @@processed_view_paths.has_key?(dir)
- @@processed_view_paths[dir] = []
-
- #
- # Dir.glob("#{dir}/**/*/**") reads all the directories in view path and templates inside those directories
- # Dir.glob("#{dir}/**") reads templates residing at top level of view path
- #
- (Dir.glob("#{dir}/**/*/**") | Dir.glob("#{dir}/**")).each do |file|
- unless File.directory?(file)
- @@processed_view_paths[dir] << file.split(dir).last.sub(/^\//, '')
-
- # Build extension cache
- extension = file.split(".").last
- if template_handler_extensions.include?(extension)
- key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
- @@file_extension_cache[dir][key] << extension
- end
- end
- end
- end
- end
-
- def update_extension_cache_for(extension)
- @@processed_view_paths.keys.each do |dir|
- Dir.glob("#{dir}/**/*.#{extension}").each do |file|
- key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
- @@file_extension_cache[dir][key] << extension
- end
- end
- end
-
- def template_handler_extensions
- ActionView::Template.template_handler_extensions
- end
-
- def reload!
- view_paths = @@processed_view_paths.keys
-
- @@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
- @@file_extension_cache = Hash.new {|hash, key|
- hash[key] = Hash.new {|hash, key| hash[key] = []}
- }
-
- process_view_paths(view_paths)
- end
- end
-
- attr_accessor :view_paths
-
- def initialize(*args)
- @template = args.shift
-
- @view_paths = args.flatten
- @view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact
- check_view_paths(@view_paths)
- end
-
- def prepend_view_path(path)
- @view_paths.unshift(*path)
-
- self.class.process_view_paths(path)
- end
-
- def append_view_path(path)
- @view_paths.push(*path)
-
- self.class.process_view_paths(path)
- end
-
- def view_paths=(path)
- @view_paths = path
- self.class.process_view_paths(path)
- end
-
- def pick_template(template_path, extension)
- file_name = "#{template_path}.#{extension}"
- base_path = find_base_path_for(file_name)
- base_path.blank? ? false : "#{base_path}/#{file_name}"
- end
- alias_method :template_exists?, :pick_template
-
- def file_exists?(template_path)
- # Clear the forward slash in the beginning if exists
- template_path = template_path.sub(/^\//, '')
-
- template_file_name, template_file_extension = path_and_extension(template_path)
-
- if template_file_extension
- template_exists?(template_file_name, template_file_extension)
- else
- template_exists?(template_file_name, pick_template_extension(template_path))
- end
- end
-
- def find_base_path_for(template_file_name)
- @view_paths.find { |path| @@processed_view_paths[path].include?(template_file_name) }
- end
-
- # Returns the view path that the full path resides in.
- def extract_base_path_from(full_path)
- @view_paths.find { |p| full_path[0..p.size - 1] == p }
- end
-
- # Gets the extension for an existing template with the given template_path.
- # Returns the format with the extension if that template exists.
- #
- # pick_template_extension('users/show')
- # # => 'html.erb'
- #
- # pick_template_extension('users/legacy')
- # # => "rhtml"
- #
- def pick_template_extension(template_path)
- if extension = find_template_extension_from_handler(template_path, @template.template_format) || find_template_extension_from_first_render
- extension
- elsif @template.template_format == :js && extension = find_template_extension_from_handler(template_path, :html)
- @template.template_format = :html
- extension
- end
- end
-
- def find_template_extension_from_handler(template_path, template_format = @template.template_format)
- formatted_template_path = "#{template_path}.#{template_format}"
-
- view_paths.each do |path|
- if (extensions = @@file_extension_cache[path][formatted_template_path]).any?
- return "#{template_format}.#{extensions.first}"
- elsif (extensions = @@file_extension_cache[path][template_path]).any?
- return extensions.first.to_s
- end
- end
- nil
- end
-
- # Splits the path and extension from the given template_path and returns as an array.
- def path_and_extension(template_path)
- template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
- [ template_path_without_extension, $1 ]
- end
-
- # Determine the template extension from the <tt>@first_render</tt> filename
- def find_template_extension_from_first_render
- File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1]
- end
-
- private
- def check_view_paths(view_paths)
- view_paths.each do |path|
- raise InvalidViewPath.new(path) unless @@processed_view_paths.has_key?(path)
- end
- end
- end
-end
diff --git a/actionpack/lib/action_view/template_handler.rb b/actionpack/lib/action_view/template_handler.rb
index ec407e3fb3..39e578e586 100644
--- a/actionpack/lib/action_view/template_handler.rb
+++ b/actionpack/lib/action_view/template_handler.rb
@@ -1,6 +1,5 @@
module ActionView
class TemplateHandler
-
def self.line_offset
0
end
diff --git a/actionpack/lib/action_view/template_handlers.rb b/actionpack/lib/action_view/template_handlers.rb
new file mode 100644
index 0000000000..1471e99e01
--- /dev/null
+++ b/actionpack/lib/action_view/template_handlers.rb
@@ -0,0 +1,46 @@
+require 'action_view/template_handler'
+require 'action_view/template_handlers/compilable'
+require 'action_view/template_handlers/builder'
+require 'action_view/template_handlers/erb'
+require 'action_view/template_handlers/rjs'
+
+module ActionView #:nodoc:
+ module TemplateHandlers #:nodoc:
+ def self.extended(base)
+ base.register_default_template_handler :erb, TemplateHandlers::ERB
+ base.register_template_handler :rjs, TemplateHandlers::RJS
+ base.register_template_handler :builder, TemplateHandlers::Builder
+
+ # TODO: Depreciate old template extensions
+ base.register_template_handler :rhtml, TemplateHandlers::ERB
+ base.register_template_handler :rxml, TemplateHandlers::Builder
+ end
+
+ @@template_handlers = {}
+ @@default_template_handlers = nil
+
+ # Register a class that knows how to handle template files with the given
+ # extension. This can be used to implement new template types.
+ # The constructor for the class must take the ActiveView::Base instance
+ # as a parameter, and the class must implement a +render+ method that
+ # takes the contents of the template to render as well as the Hash of
+ # local assigns available to the template. The +render+ method ought to
+ # return the rendered template as a string.
+ def register_template_handler(extension, klass)
+ @@template_handlers[extension.to_sym] = klass
+ end
+
+ def template_handler_extensions
+ @@template_handlers.keys.map(&:to_s).sort
+ end
+
+ def register_default_template_handler(extension, klass)
+ register_template_handler(extension, klass)
+ @@default_template_handlers = klass
+ end
+
+ def handler_class_for_extension(extension)
+ (extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
+ end
+ end
+end
diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb
index 28c72172a0..1aef81ba1a 100644
--- a/actionpack/lib/action_view/template_handlers/compilable.rb
+++ b/actionpack/lib/action_view/template_handlers/compilable.rb
@@ -106,7 +106,7 @@ module ActionView
locals_code << "#{key} = local_assigns[:#{key}]\n"
end
- "def #{render_symbol}(local_assigns)\nold_output_buffer = @output_buffer;#{locals_code}#{body}\nensure\n@output_buffer = old_output_buffer\nend"
+ "def #{render_symbol}(local_assigns)\nold_output_buffer = output_buffer;#{locals_code}#{body}\nensure\nself.output_buffer = old_output_buffer\nend"
end
# Return true if the given template was compiled for a superset of the keys in local_assigns
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 16fedd9732..1a3c93c283 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -37,6 +37,8 @@ module ActionView
if helper_class && !self.class.ancestors.include?(helper_class)
self.class.send(:include, helper_class)
end
+
+ self.output_buffer = ''
end
class TestController < ActionController::Base
@@ -48,6 +50,9 @@ module ActionView
end
end
+ protected
+ attr_accessor :output_buffer
+
private
def method_missing(selector, *args)
controller = TestController.new
diff --git a/actionpack/lib/action_view/view_load_paths.rb b/actionpack/lib/action_view/view_load_paths.rb
new file mode 100644
index 0000000000..e873d96aa0
--- /dev/null
+++ b/actionpack/lib/action_view/view_load_paths.rb
@@ -0,0 +1,103 @@
+module ActionView #:nodoc:
+ class ViewLoadPaths < Array #:nodoc:
+ def self.type_cast(obj)
+ obj.is_a?(String) ? LoadPath.new(obj) : obj
+ end
+
+ class LoadPath #:nodoc:
+ attr_reader :path, :paths
+ delegate :to_s, :inspect, :to => :path
+
+ def initialize(path)
+ @path = path.freeze
+ reload!
+ end
+
+ def eql?(view_path)
+ view_path.is_a?(ViewPath) && @path == view_path.path
+ end
+
+ def hash
+ @path.hash
+ end
+
+ # Rebuild load path directory cache
+ def reload!
+ @paths = {}
+
+ files.each do |file|
+ @paths[file.path] = file
+ @paths[file.path_without_extension] ||= file
+ end
+
+ @paths.freeze
+ end
+
+ # Tries to find the extension for the template name.
+ # If it does not it exist, tries again without the format extension
+ # find_template_file_for_partial_path('users/show') => 'html.erb'
+ # find_template_file_for_partial_path('users/legacy') => 'rhtml'
+ def find_template_file_for_partial_path(file)
+ @paths[file.path] || @paths[file.path_without_extension] || @paths[file.path_without_format_and_extension]
+ end
+
+ private
+ # Get all the files and directories in the path
+ def files_in_path
+ Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/**")
+ end
+
+ # Create an array of all the files within the path
+ def files
+ files_in_path.map do |file|
+ TemplateFile.from_full_path(@path, file) unless File.directory?(file)
+ end.compact
+ end
+ end
+
+ def initialize(*args)
+ super(*args).map! { |obj| self.class.type_cast(obj) }
+ end
+
+ def reload!
+ each { |path| path.reload! }
+ end
+
+ def <<(obj)
+ super(self.class.type_cast(obj))
+ end
+
+ def push(*objs)
+ delete_paths!(objs)
+ super(*objs.map { |obj| self.class.type_cast(obj) })
+ end
+
+ def unshift(*objs)
+ delete_paths!(objs)
+ super(*objs.map { |obj| self.class.type_cast(obj) })
+ end
+
+ def template_exists?(file)
+ find_load_path_for_path(file) ? true : false
+ end
+
+ def find_load_path_for_path(file)
+ find { |path| path.paths[file.to_s] }
+ end
+
+ def find_template_file_for_path(file)
+ file = TemplateFile.from_path(file)
+ each do |path|
+ if f = path.find_template_file_for_partial_path(file)
+ return f
+ end
+ end
+ nil
+ end
+
+ private
+ def delete_paths!(paths)
+ paths.each { |p1| delete_if { |p2| p1.to_s == p2.to_s } }
+ end
+ end
+end
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index b28717597e..34c0200fe8 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -169,6 +169,22 @@ class DefaultUrlOptionsTest < Test::Unit::TestCase
end
end
+class EmptyUrlOptionsTest < Test::Unit::TestCase
+ def setup
+ @controller = NonEmptyController.new
+
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @request.host = 'www.example.com'
+ end
+
+ def test_ensure_url_for_works_as_expected_when_called_with_no_options_if_default_url_options_is_not_set
+ get :public_action
+ assert_equal "http://www.example.com/non_empty/public_action", @controller.url_for
+ end
+end
+
class EnsureNamedRoutesWorksTicket22BugTest < Test::Unit::TestCase
def test_named_routes_still_work
ActionController::Routing::Routes.draw do |map|
@@ -180,4 +196,4 @@ class EnsureNamedRoutesWorksTicket22BugTest < Test::Unit::TestCase
ensure
ActionController::Routing::Routes.load!
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index aee60b1c6f..14cf0a86a1 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -188,6 +188,10 @@ class ActionCachingTestController < ActionController::Base
expire_action :controller => 'action_caching_test', :action => 'index'
render :nothing => true
end
+ def expire_xml
+ expire_action :controller => 'action_caching_test', :action => 'index', :format => 'xml'
+ render :nothing => true
+ end
end
class MockTime < Time
@@ -213,6 +217,7 @@ class ActionCachingMockController
mocked_path = @mock_path
Object.new.instance_eval(<<-EVAL)
def path; '#{@mock_path}' end
+ def format; 'all' end
self
EVAL
end
@@ -326,6 +331,20 @@ class ActionCacheTest < Test::Unit::TestCase
assert_equal new_cached_time, @response.body
end
+ def test_cache_expiration_isnt_affected_by_request_format
+ get :index
+ cached_time = content_to_cache
+ reset!
+
+ @request.set_REQUEST_URI "/action_caching_test/expire.xml"
+ get :expire, :format => :xml
+ reset!
+
+ get :index
+ new_cached_time = content_to_cache
+ assert_not_equal cached_time, @response.body
+ end
+
def test_cache_is_scoped_by_subdomain
@request.host = 'jamis.hostname.com'
get :index
@@ -370,11 +389,35 @@ class ActionCacheTest < Test::Unit::TestCase
end
def test_xml_version_of_resource_is_treated_as_different_cache
- @mock_controller.mock_url_for = 'http://example.org/posts/'
- @mock_controller.mock_path = '/posts/index.xml'
- path_object = @path_class.new(@mock_controller, {})
- assert_equal 'xml', path_object.extension
- assert_equal 'example.org/posts/index.xml', path_object.path
+ with_routing do |set|
+ ActionController::Routing::Routes.draw do |map|
+ map.connect ':controller/:action.:format'
+ map.connect ':controller/:action'
+ end
+
+ get :index, :format => 'xml'
+ cached_time = content_to_cache
+ assert_equal cached_time, @response.body
+ assert fragment_exist?('hostname.com/action_caching_test/index.xml')
+ reset!
+
+ get :index, :format => 'xml'
+ assert_equal cached_time, @response.body
+ assert_equal 'application/xml', @response.content_type
+ reset!
+
+ @request.env['HTTP_ACCEPT'] = "application/xml"
+ get :index
+ assert_equal cached_time, @response.body
+ assert_equal 'application/xml', @response.content_type
+ reset!
+
+ get :expire_xml
+ reset!
+
+ get :index, :format => 'xml'
+ assert_not_equal cached_time, @response.body
+ end
end
def test_correct_content_type_is_returned_for_cache_hit
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 62c00c5b9a..475e13897b 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'action_controller/integration'
+require 'action_controller/routing'
uses_mocha 'integration' do
@@ -12,12 +13,12 @@ end
class SessionTest < Test::Unit::TestCase
include IntegrationSessionStubbing
-
+
def setup
@session = ActionController::Integration::Session.new
stub_integration_session(@session)
end
-
+
def test_https_bang_works_and_sets_truth_by_default
assert !@session.https?
@session.https!
@@ -196,7 +197,7 @@ class SessionTest < Test::Unit::TestCase
@session.expects(:process).with(:head,path,params,headers_after_xhr)
@session.xml_http_request(:head,path,params,headers)
end
-
+
def test_xml_http_request_override_accept
path = "/index"; params = "blah"; headers = {:location => 'blah', "Accept" => "application/xml"}
headers_after_xhr = headers.merge(
@@ -227,7 +228,6 @@ class IntegrationTestTest < Test::Unit::TestCase
assert_equal ::ActionController::Integration::Session, session2.class
assert_not_equal session1, session2
end
-
end
# Tests that integration tests don't call Controller test methods for processing.
@@ -246,7 +246,90 @@ class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest
assert_nothing_raised("'#{verb}' should use integration test methods") { send!(verb, '/') }
end
end
+end
+
+class IntegrationProcessTest < ActionController::IntegrationTest
+ class IntegrationController < ActionController::Base
+ session :off
+
+ def get
+ render :text => "OK", :status => 200
+ end
+
+ def post
+ render :text => "Created", :status => 201
+ end
+
+ def cookie_monster
+ cookies["cookie_1"] = nil
+ cookies["cookie_3"] = "chocolate"
+ render :text => "Gone", :status => 410
+ end
+ end
+ def test_get
+ with_test_route_set do
+ get '/get'
+ assert_equal 200, status
+ assert_equal "OK", status_message
+ assert_equal "200 OK", response.headers["Status"]
+ assert_equal ["200 OK"], headers["status"]
+ assert_equal [], response.headers["cookie"]
+ assert_equal [], headers["cookie"]
+ assert_equal({}, cookies)
+ assert_equal "OK", response.body
+ assert_kind_of HTML::Document, html_document
+ assert_equal 1, request_count
+ end
+ end
+
+ def test_post
+ with_test_route_set do
+ post '/post'
+ assert_equal 201, status
+ assert_equal "Created", status_message
+ assert_equal "201 Created", response.headers["Status"]
+ assert_equal ["201 Created"], headers["status"]
+ assert_equal [], response.headers["cookie"]
+ assert_equal [], headers["cookie"]
+ assert_equal({}, cookies)
+ assert_equal "Created", response.body
+ assert_kind_of HTML::Document, html_document
+ assert_equal 1, request_count
+ end
+ end
+
+ def test_cookie_monster
+ with_test_route_set do
+ self.cookies['cookie_1'] = "sugar"
+ self.cookies['cookie_2'] = "oatmeal"
+ get '/cookie_monster'
+ assert_equal 410, status
+ assert_equal "Gone", status_message
+ assert_equal "410 Gone", response.headers["Status"]
+ assert_equal ["410 Gone"], headers["status"]
+ assert_equal nil, response.headers["Set-Cookie"]
+ assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], headers['set-cookie']
+ assert_equal [[], ["chocolate"]], response.headers["cookie"]
+ assert_equal [], headers["cookie"]
+ assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies)
+ assert_equal "Gone", response.body
+ end
+ end
+
+ private
+ def with_test_route_set
+ with_routing do |set|
+ set.draw do |map|
+ map.with_options :controller => "IntegrationProcessTest::Integration" do |c|
+ c.connect '/get', :action => "get"
+ c.connect '/post', :action => "post"
+ c.connect '/cookie_monster', :action => "cookie_monster"
+ end
+ end
+ yield
+ end
+ end
end
-end # uses_mocha
+end
diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb
index 6b83b8337e..b77b3ceffa 100644
--- a/actionpack/test/controller/new_render_test.rb
+++ b/actionpack/test/controller/new_render_test.rb
@@ -220,7 +220,7 @@ class NewRenderTestController < ActionController::Base
render :action => "test/hello_world"
end
- def render_to_string_with_partial
+ def render_to_string_with_partial
@partial_only = render_to_string :partial => "partial_only"
@partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
render :action => "test/hello_world"
@@ -251,11 +251,15 @@ class NewRenderTestController < ActionController::Base
def accessing_logger_in_template
render :inline => "<%= logger.class %>"
end
-
+
def accessing_action_name_in_template
render :inline => "<%= action_name %>"
end
+ def accessing_controller_name_in_template
+ render :inline => "<%= controller_name %>"
+ end
+
def accessing_params_in_template_with_layout
render :layout => nil, :inline => "Hello: <%= params[:name] %>"
end
@@ -559,12 +563,17 @@ class NewRenderTest < Test::Unit::TestCase
get :accessing_logger_in_template
assert_equal "Logger", @response.body
end
-
+
def test_access_to_action_name_in_view
get :accessing_action_name_in_template
assert_equal "accessing_action_name_in_template", @response.body
end
+ def test_access_to_controller_name_in_view
+ get :accessing_controller_name_in_template
+ assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller.
+ end
+
def test_render_xml
get :render_xml_hello
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
diff --git a/actionpack/test/controller/verification_test.rb b/actionpack/test/controller/verification_test.rb
index d6fde35f83..b289443129 100644
--- a/actionpack/test/controller/verification_test.rb
+++ b/actionpack/test/controller/verification_test.rb
@@ -21,10 +21,10 @@ class VerificationTest < Test::Unit::TestCase
verify :only => :guarded_by_method, :method => :post,
:redirect_to => { :action => "unguarded" }
-
+
verify :only => :guarded_by_xhr, :xhr => true,
:redirect_to => { :action => "unguarded" }
-
+
verify :only => :guarded_by_not_xhr, :xhr => false,
:redirect_to => { :action => "unguarded" }
@@ -39,10 +39,13 @@ class VerificationTest < Test::Unit::TestCase
verify :only => :no_default_action, :params => "santa"
+ verify :only => :guarded_with_back, :method => :post,
+ :redirect_to => :back
+
def guarded_one
render :text => "#{params[:one]}"
end
-
+
def guarded_one_for_named_route_test
render :text => "#{params[:one]}"
end
@@ -70,11 +73,11 @@ class VerificationTest < Test::Unit::TestCase
def guarded_by_method
render :text => "#{request.method}"
end
-
+
def guarded_by_xhr
render :text => "#{request.xhr?}"
end
-
+
def guarded_by_not_xhr
render :text => "#{request.xhr?}"
end
@@ -86,15 +89,19 @@ class VerificationTest < Test::Unit::TestCase
def two_redirects
render :nothing => true
end
-
+
def must_be_post
render :text => "Was a post!"
end
-
+
+ def guarded_with_back
+ render :text => "#{params[:one]}"
+ end
+
def no_default_action
# Will never run
end
-
+
protected
def rescue_action(e) raise end
@@ -109,7 +116,17 @@ class VerificationTest < Test::Unit::TestCase
@response = ActionController::TestResponse.new
ActionController::Routing::Routes.add_named_route :foo, '/foo', :controller => 'test', :action => 'foo'
end
-
+
+ def test_using_symbol_back_with_no_referrer
+ assert_raise(ActionController::RedirectBackError) { get :guarded_with_back }
+ end
+
+ def test_using_symbol_back_redirects_to_referrer
+ @request.env["HTTP_REFERER"] = "/foo"
+ get :guarded_with_back
+ assert_redirected_to '/foo'
+ end
+
def test_no_deprecation_warning_for_named_route
assert_not_deprecated do
get :guarded_one_for_named_route_test, :two => "not one"
@@ -209,44 +226,44 @@ class VerificationTest < Test::Unit::TestCase
get :guarded_by_method
assert_redirected_to :action => "unguarded"
end
-
+
def test_guarded_by_xhr_with_prereqs
xhr :post, :guarded_by_xhr
assert_equal "true", @response.body
end
-
+
def test_guarded_by_xhr_without_prereqs
get :guarded_by_xhr
assert_redirected_to :action => "unguarded"
end
-
+
def test_guarded_by_not_xhr_with_prereqs
get :guarded_by_not_xhr
assert_equal "false", @response.body
end
-
+
def test_guarded_by_not_xhr_without_prereqs
xhr :post, :guarded_by_not_xhr
assert_redirected_to :action => "unguarded"
end
-
+
def test_guarded_post_and_calls_render_succeeds
post :must_be_post
assert_equal "Was a post!", @response.body
end
-
+
def test_default_failure_should_be_a_bad_request
post :no_default_action
assert_response :bad_request
end
-
+
def test_guarded_post_and_calls_render_fails_and_sets_allow_header
get :must_be_post
assert_response 405
assert_equal "Must be post", @response.body
assert_equal "POST", @response.headers["Allow"]
end
-
+
def test_second_redirect
assert_nothing_raised { get :two_redirects }
end
diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb
index 0516da32d8..1b4c1fae2f 100644
--- a/actionpack/test/controller/view_paths_test.rb
+++ b/actionpack/test/controller/view_paths_test.rb
@@ -1,30 +1,30 @@
require 'abstract_unit'
class ViewLoadPathsTest < Test::Unit::TestCase
-
LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
- ActionController::Base.view_paths = [ LOAD_PATH_ROOT ]
+ ActionController::Base.view_paths = [LOAD_PATH_ROOT]
class TestController < ActionController::Base
def self.controller_path() "test" end
def rescue_action(e) raise end
-
+
before_filter :add_view_path, :only => :hello_world_at_request_time
-
+
def hello_world() end
def hello_world_at_request_time() render(:action => 'hello_world') end
+
private
- def add_view_path
- prepend_view_path "#{LOAD_PATH_ROOT}/override"
- end
+ def add_view_path
+ prepend_view_path "#{LOAD_PATH_ROOT}/override"
+ end
end
-
+
class Test::SubController < ActionController::Base
layout 'test/sub'
def hello_world; render(:template => 'test/hello_world'); end
end
-
+
def setup
TestController.view_paths = nil
@@ -41,68 +41,80 @@ class ViewLoadPathsTest < Test::Unit::TestCase
@last_message = nil
ActiveSupport::Deprecation.behavior = Proc.new { |message, callback| @last_message = message }
end
-
+
def teardown
ActiveSupport::Deprecation.behavior = @old_behavior
end
-
+
def test_template_load_path_was_set_correctly
- assert_equal [ LOAD_PATH_ROOT ], @controller.view_paths
+ assert_equal [ LOAD_PATH_ROOT ], @controller.view_paths.map(&:to_s)
end
-
+
def test_controller_appends_view_path_correctly
@controller.append_view_path 'foo'
- assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
-
+ assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths.map(&:to_s)
+
@controller.append_view_path(%w(bar baz))
- assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
+
+ @controller.append_view_path(LOAD_PATH_ROOT)
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
+
+ @controller.append_view_path([LOAD_PATH_ROOT])
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
end
-
+
def test_controller_prepends_view_path_correctly
@controller.prepend_view_path 'baz'
- assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
-
+ assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
+
@controller.prepend_view_path(%w(foo bar))
- assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
+
+ @controller.prepend_view_path(LOAD_PATH_ROOT)
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
+
+ @controller.prepend_view_path([LOAD_PATH_ROOT])
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
end
-
+
def test_template_appends_view_path_correctly
@controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
class_view_paths = TestController.view_paths
@controller.append_view_path 'foo'
- assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
-
+ assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths.map(&:to_s)
+
@controller.append_view_path(%w(bar baz))
- assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
assert_equal class_view_paths, TestController.view_paths
end
-
+
def test_template_prepends_view_path_correctly
@controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
class_view_paths = TestController.view_paths
-
+
@controller.prepend_view_path 'baz'
- assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
-
+ assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
+
@controller.prepend_view_path(%w(foo bar))
- assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&:to_s)
assert_equal class_view_paths, TestController.view_paths
end
-
+
def test_view_paths
get :hello_world
assert_response :success
assert_equal "Hello world!", @response.body
end
-
+
def test_view_paths_override
TestController.prepend_view_path "#{LOAD_PATH_ROOT}/override"
get :hello_world
assert_response :success
assert_equal "Hello overridden world!", @response.body
end
-
+
def test_view_paths_override_for_layouts_in_controllers_with_a_module
@controller = Test::SubController.new
Test::SubController.view_paths = [ "#{LOAD_PATH_ROOT}/override", LOAD_PATH_ROOT, "#{LOAD_PATH_ROOT}/override2" ]
@@ -110,31 +122,44 @@ class ViewLoadPathsTest < Test::Unit::TestCase
assert_response :success
assert_equal "layout: Hello overridden world!", @response.body
end
-
+
def test_view_paths_override_at_request_time
get :hello_world_at_request_time
assert_response :success
assert_equal "Hello overridden world!", @response.body
end
-
+
def test_inheritance
original_load_paths = ActionController::Base.view_paths
-
+
self.class.class_eval %{
class A < ActionController::Base; end
class B < A; end
class C < ActionController::Base; end
}
-
- A.view_paths = [ 'a/path' ]
-
- assert_equal [ 'a/path' ], A.view_paths
- assert_equal A.view_paths, B.view_paths
+
+ A.view_paths = ['a/path']
+
+ assert_equal ['a/path'], A.view_paths.map(&:to_s)
+ assert_equal A.view_paths, B.view_paths
assert_equal original_load_paths, C.view_paths
-
+
C.view_paths = []
assert_nothing_raised { C.view_paths << 'c/path' }
- assert_equal ['c/path'], C.view_paths
+ assert_equal ['c/path'], C.view_paths.map(&:to_s)
+ end
+
+ def test_find_template_file_for_path
+ assert_equal "test/hello_world.erb", @controller.view_paths.find_template_file_for_path("test/hello_world.erb").to_s
+ assert_equal "test/hello.builder", @controller.view_paths.find_template_file_for_path("test/hello.builder").to_s
+ assert_equal nil, @controller.view_paths.find_template_file_for_path("test/missing.erb")
+ end
+
+ def test_view_paths_find_template_file_for_path
+ assert_equal "test/formatted_html_erb.html.erb", @controller.view_paths.find_template_file_for_path("test/formatted_html_erb.html").to_s
+ assert_equal "test/formatted_xml_erb.xml.erb", @controller.view_paths.find_template_file_for_path("test/formatted_xml_erb.xml").to_s
+ assert_equal "test/hello_world.erb", @controller.view_paths.find_template_file_for_path("test/hello_world.html").to_s
+ assert_equal "test/hello_world.erb", @controller.view_paths.find_template_file_for_path("test/hello_world.xml").to_s
+ assert_equal nil, @controller.view_paths.find_template_file_for_path("test/missing.html")
end
-
end
diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb
index 3399b03dd2..11b3bdb3fa 100755
--- a/actionpack/test/template/date_helper_test.rb
+++ b/actionpack/test/template/date_helper_test.rb
@@ -1002,17 +1002,15 @@ class DateHelperTest < ActionView::TestCase
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
- @output_buffer = ''
-
fields_for :post, @post do |f|
- @output_buffer.concat f.date_select(:written_on)
+ concat f.date_select(:written_on)
end
expected = "<select id='post_written_on_1i' name='post[written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
expected << "<select id='post_written_on_2i' name='post[written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
expected << "<select id='post_written_on_3i' name='post[written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
- assert_dom_equal(expected, @output_buffer)
+ assert_dom_equal(expected, output_buffer)
end
def test_date_select_with_index
@@ -1287,10 +1285,8 @@ class DateHelperTest < ActionView::TestCase
@post = Post.new
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
- @output_buffer = ''
-
fields_for :post, @post do |f|
- @output_buffer.concat f.datetime_select(:updated_at)
+ concat f.datetime_select(:updated_at)
end
expected = "<select id='post_updated_at_1i' name='post[updated_at(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
@@ -1299,7 +1295,7 @@ class DateHelperTest < ActionView::TestCase
expected << " &mdash; <select id='post_updated_at_4i' name='post[updated_at(4i)]'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option selected='selected' value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n</select>\n"
expected << " : <select id='post_updated_at_5i' name='post[updated_at(5i)]'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n<option value='32'>32</option>\n<option value='33'>33</option>\n<option value='34'>34</option>\n<option selected='selected' value='35'>35</option>\n<option value='36'>36</option>\n<option value='37'>37</option>\n<option value='38'>38</option>\n<option value='39'>39</option>\n<option value='40'>40</option>\n<option value='41'>41</option>\n<option value='42'>42</option>\n<option value='43'>43</option>\n<option value='44'>44</option>\n<option value='45'>45</option>\n<option value='46'>46</option>\n<option value='47'>47</option>\n<option value='48'>48</option>\n<option value='49'>49</option>\n<option value='50'>50</option>\n<option value='51'>51</option>\n<option value='52'>52</option>\n<option value='53'>53</option>\n<option value='54'>54</option>\n<option value='55'>55</option>\n<option value='56'>56</option>\n<option value='57'>57</option>\n<option value='58'>58</option>\n<option value='59'>59</option>\n</select>\n"
- assert_dom_equal(expected, @output_buffer)
+ assert_dom_equal(expected, output_buffer)
end
def test_date_select_with_zero_value_and_no_start_year
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 65984fac44..39649c3622 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -337,14 +337,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for
- @output_buffer = ''
-
form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
- @output_buffer.concat f.label(:title)
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
- @output_buffer.concat f.submit('Create post')
+ concat f.label(:title)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ concat f.submit('Create post')
end
expected =
@@ -357,16 +355,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='commit' id='post_submit' type='submit' value='Create post' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_method
- @output_buffer = ''
-
form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -378,16 +374,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' type='hidden' value='0' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_without_object
- @output_buffer = ''
-
form_for(:post, :html => { :id => 'create-post' }) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -398,17 +392,15 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' type='hidden' value='0' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_index
- @output_buffer = ''
-
form_for("post[]", @post) do |f|
- @output_buffer.concat f.label(:title)
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.label(:title)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -420,16 +412,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[123][secret]' type='hidden' value='0' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_nil_index_option_override
- @output_buffer = ''
-
form_for("post[]", @post, :index => nil) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -440,14 +430,13 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[][secret]' type='hidden' value='0' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_nested_fields_for
- @output_buffer = ''
form_for(:post, @post) do |f|
f.fields_for(:comment, @post) do |c|
- @output_buffer.concat c.text_field(:title)
+ concat c.text_field(:title)
end
end
@@ -455,16 +444,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for
- @output_buffer = ''
-
fields_for(:post, @post) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -473,16 +460,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_with_index
- @output_buffer = ''
-
fields_for("post[]", @post) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -491,16 +476,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
"<input name='post[123][secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_with_nil_index_option_override
- @output_buffer = ''
-
fields_for("post[]", @post, :index => nil) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -509,16 +492,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
"<input name='post[][secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_with_index_option_override
- @output_buffer = ''
-
fields_for("post[]", @post, :index => "abc") do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -527,15 +508,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />" +
"<input name='post[abc][secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_without_object
- @output_buffer = ''
fields_for(:post) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -544,15 +524,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_with_only_object
- @output_buffer = ''
fields_for(@post) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -561,31 +540,29 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_object_with_bracketed_name
- @output_buffer = ''
fields_for("author[post]", @post) do |f|
- @output_buffer.concat f.label(:title)
- @output_buffer.concat f.text_field(:title)
+ concat f.label(:title)
+ concat f.text_field(:title)
end
assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
"<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
- @output_buffer
+ output_buffer
end
def test_fields_for_object_with_bracketed_name_and_index
- @output_buffer = ''
fields_for("author[post]", @post, :index => 1) do |f|
- @output_buffer.concat f.label(:title)
- @output_buffer.concat f.text_field(:title)
+ concat f.label(:title)
+ concat f.text_field(:title)
end
assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
"<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
- @output_buffer
+ output_buffer
end
def test_form_builder_does_not_have_form_for_method
@@ -593,14 +570,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_and_fields_for
- @output_buffer = ''
-
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- @output_buffer.concat post_form.text_field(:title)
- @output_buffer.concat post_form.text_area(:body)
+ concat post_form.text_field(:title)
+ concat post_form.text_area(:body)
fields_for(:parent_post, @post) do |parent_fields|
- @output_buffer.concat parent_fields.check_box(:secret)
+ concat parent_fields.check_box(:secret)
end
end
@@ -612,18 +587,16 @@ class FormHelperTest < ActionView::TestCase
"<input name='parent_post[secret]' type='hidden' value='0' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_and_fields_for_with_object
- @output_buffer = ''
-
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- @output_buffer.concat post_form.text_field(:title)
- @output_buffer.concat post_form.text_area(:body)
+ concat post_form.text_field(:title)
+ concat post_form.text_area(:body)
post_form.fields_for(@comment) do |comment_fields|
- @output_buffer.concat comment_fields.text_field(:name)
+ concat comment_fields.text_field(:name)
end
end
@@ -634,7 +607,7 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
class LabelledFormBuilder < ActionView::Helpers::FormBuilder
@@ -649,12 +622,10 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_labelled_builder
- @output_buffer = ''
-
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -665,18 +636,17 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_default_form_builder
old_default_form_builder, ActionView::Base.default_form_builder =
ActionView::Base.default_form_builder, LabelledFormBuilder
- @output_buffer = ''
form_for(:post, @post) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -687,17 +657,15 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
ensure
ActionView::Base.default_form_builder = old_default_form_builder
end
def test_default_form_builder_with_active_record_helpers
-
- @output_buffer = ''
form_for(:post, @post) do |f|
- @output_buffer.concat f.error_message_on('author_name')
- @output_buffer.concat f.error_messages
+ concat f.error_message_on('author_name')
+ concat f.error_messages
end
expected = %(<form action='http://www.example.com' method='post'>) +
@@ -705,7 +673,7 @@ class FormHelperTest < ActionView::TestCase
%(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
%(</form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
@@ -713,10 +681,9 @@ class FormHelperTest < ActionView::TestCase
post = @post
@post = nil
- @output_buffer = ''
form_for(:post, post) do |f|
- @output_buffer.concat f.error_message_on('author_name')
- @output_buffer.concat f.error_messages
+ concat f.error_message_on('author_name')
+ concat f.error_messages
end
expected = %(<form action='http://www.example.com' method='post'>) +
@@ -724,19 +691,18 @@ class FormHelperTest < ActionView::TestCase
%(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
%(</form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
# Perhaps this test should be moved to prototype helper tests.
def test_remote_form_for_with_labelled_builder
self.extend ActionView::Helpers::PrototypeHelper
- @output_buffer = ''
remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -747,16 +713,14 @@ class FormHelperTest < ActionView::TestCase
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"</form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_fields_for_with_labelled_builder
- @output_buffer = ''
-
fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- @output_buffer.concat f.text_field(:title)
- @output_buffer.concat f.text_area(:body)
- @output_buffer.concat f.check_box(:secret)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
end
expected =
@@ -765,29 +729,23 @@ class FormHelperTest < ActionView::TestCase
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' /><br/>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_html_options_adds_options_to_form_tag
- @output_buffer = ''
-
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_string_url_option
- @output_buffer = ''
-
form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
- assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', @output_buffer
+ assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
end
def test_form_for_with_hash_url_option
- @output_buffer = ''
-
form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
assert_equal 'controller', @controller.url_for_options[:controller]
@@ -795,26 +753,20 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_record_url_option
- @output_buffer = ''
-
form_for(:post, @post, :url => @post) do |f| end
expected = "<form action=\"/posts/123\" method=\"post\"></form>"
- assert_equal expected, @output_buffer
+ assert_equal expected, output_buffer
end
def test_form_for_with_existing_object
- @output_buffer = ''
-
form_for(@post) do |f| end
expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, @output_buffer
+ assert_equal expected, output_buffer
end
def test_form_for_with_new_object
- @output_buffer = ''
-
post = Post.new
post.new_record = true
def post.id() nil end
@@ -822,64 +774,61 @@ class FormHelperTest < ActionView::TestCase
form_for(post) do |f| end
expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
- assert_equal expected, @output_buffer
+ assert_equal expected, output_buffer
end
def test_form_for_with_existing_object_in_list
@post.new_record = false
@comment.save
- @output_buffer = ''
+
form_for([@post, @comment]) {}
expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_new_object_in_list
@post.new_record = false
- @output_buffer = ''
+
form_for([@post, @comment]) {}
expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_existing_object_and_namespace_in_list
@post.new_record = false
@comment.save
- @output_buffer = ''
+
form_for([:admin, @post, @comment]) {}
expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_new_object_and_namespace_in_list
@post.new_record = false
- @output_buffer = ''
+
form_for([:admin, @post, @comment]) {}
expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_existing_object_and_custom_url
- @output_buffer = ''
-
form_for(@post, :url => "/super_posts") do |f| end
expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, @output_buffer
+ assert_equal expected, output_buffer
end
def test_remote_form_for_with_html_options_adds_options_to_form_tag
self.extend ActionView::Helpers::PrototypeHelper
- @output_buffer = ''
remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 3c9fb297c3..3f89a5e426 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -20,8 +20,6 @@ class MockTimeZone
end
end
-ActionView::Helpers::FormOptionsHelper::TimeZone = MockTimeZone
-
class FormOptionsHelperTest < ActionView::TestCase
tests ActionView::Helpers::FormOptionsHelper
@@ -31,6 +29,8 @@ class FormOptionsHelperTest < ActionView::TestCase
Country = Struct.new('Country', :country_id, :country_name)
Firm = Struct.new('Firm', :time_zone)
Album = Struct.new('Album', :id, :title, :genre)
+
+ ActiveSupport::TimeZone = MockTimeZone
end
def test_collection_options
@@ -183,7 +183,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_time_zone_options_with_priority_zones
- zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
opts = time_zone_options_for_select( nil, zones )
assert_dom_equal "<option value=\"B\">B</option>\n" +
"<option value=\"E\">E</option>" +
@@ -195,7 +195,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_time_zone_options_with_selected_priority_zones
- zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
opts = time_zone_options_for_select( "E", zones )
assert_dom_equal "<option value=\"B\">B</option>\n" +
"<option value=\"E\" selected=\"selected\">E</option>" +
@@ -207,7 +207,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_time_zone_options_with_unselected_priority_zones
- zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
opts = time_zone_options_for_select( "C", zones )
assert_dom_equal "<option value=\"B\">B</option>\n" +
"<option value=\"E\">E</option>" +
@@ -230,16 +230,14 @@ class FormOptionsHelperTest < ActionView::TestCase
def test_select_under_fields_for
@post = Post.new
@post.category = "<mus>"
-
- @output_buffer = ''
-
+
fields_for :post, @post do |f|
- @output_buffer.concat f.select(:category, %w( abe <mus> hest))
+ concat f.select(:category, %w( abe <mus> hest))
end
assert_dom_equal(
"<select id=\"post_category\" name=\"post[category]\"><option value=\"abe\">abe</option>\n<option value=\"&lt;mus&gt;\" selected=\"selected\">&lt;mus&gt;</option>\n<option value=\"hest\">hest</option></select>",
- @output_buffer
+ output_buffer
)
end
@@ -352,16 +350,14 @@ class FormOptionsHelperTest < ActionView::TestCase
@post = Post.new
@post.author_name = "Babe"
-
- @output_buffer = ''
-
+
fields_for :post, @post do |f|
- @output_buffer.concat f.collection_select(:author_name, @posts, :author_name, :author_name)
+ concat f.collection_select(:author_name, @posts, :author_name, :author_name)
end
assert_dom_equal(
"<select id=\"post_author_name\" name=\"post[author_name]\"><option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
- @output_buffer
+ output_buffer
)
end
@@ -1194,11 +1190,9 @@ COUNTRIES
def test_time_zone_select_under_fields_for
@firm = Firm.new("D")
-
- @output_buffer = ''
-
+
fields_for :firm, @firm do |f|
- @output_buffer.concat f.time_zone_select(:time_zone)
+ concat f.time_zone_select(:time_zone)
end
assert_dom_equal(
@@ -1209,7 +1203,7 @@ COUNTRIES
"<option value=\"D\" selected=\"selected\">D</option>\n" +
"<option value=\"E\">E</option>" +
"</select>",
- @output_buffer
+ output_buffer
)
end
@@ -1293,7 +1287,7 @@ COUNTRIES
def test_time_zone_select_with_priority_zones
@firm = Firm.new("D")
- zones = [ TimeZone.new("A"), TimeZone.new("D") ]
+ zones = [ ActiveSupport::TimeZone.new("A"), ActiveSupport::TimeZone.new("D") ]
html = time_zone_select("firm", "time_zone", zones )
assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" +
"<option value=\"A\">A</option>\n" +
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index b281db18bd..47b3605849 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -43,19 +43,17 @@ class FormTagHelperTest < ActionView::TestCase
end
def test_form_tag_with_block
- @output_buffer = ''
- form_tag("http://example.com") { @output_buffer.concat "Hello world!" }
+ form_tag("http://example.com") { concat "Hello world!" }
expected = %(<form action="http://example.com" method="post">Hello world!</form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_tag_with_block_and_method
- @output_buffer = ''
- form_tag("http://example.com", :method => :put) { @output_buffer.concat "Hello world!" }
+ form_tag("http://example.com", :method => :put) { concat "Hello world!" }
expected = %(<form action="http://example.com" method="post"><div style='margin:0;padding:0'><input type="hidden" name="_method" value="put" /></div>Hello world!</form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_hidden_field_tag
@@ -234,23 +232,22 @@ class FormTagHelperTest < ActionView::TestCase
end
def test_field_set_tag
- @output_buffer = ''
- field_set_tag("Your details") { @output_buffer.concat "Hello world!" }
+ field_set_tag("Your details") { concat "Hello world!" }
expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
- @output_buffer = ''
- field_set_tag { @output_buffer.concat "Hello world!" }
+ self.output_buffer = ''
+ field_set_tag { concat "Hello world!" }
expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, @output_buffer
-
- @output_buffer = ''
- field_set_tag('') { @output_buffer.concat "Hello world!" }
+ assert_dom_equal expected, output_buffer
+
+ self.output_buffer = ''
+ field_set_tag('') { concat "Hello world!" }
expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def protect_against_forgery?
diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb
index 4924074c3e..8c649ea544 100644
--- a/actionpack/test/template/javascript_helper_test.rb
+++ b/actionpack/test/template/javascript_helper_test.rb
@@ -82,12 +82,12 @@ class JavaScriptHelperTest < ActionView::TestCase
end
def test_javascript_tag
- @output_buffer = 'foo'
+ self.output_buffer = 'foo'
assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>",
javascript_tag("alert('hello')")
- assert_equal 'foo', @output_buffer, 'javascript_tag without a block should not concat to @output_buffer'
+ assert_equal 'foo', output_buffer, 'javascript_tag without a block should not concat to output_buffer'
end
def test_javascript_tag_with_options
@@ -96,15 +96,13 @@ class JavaScriptHelperTest < ActionView::TestCase
end
def test_javascript_tag_with_block
- @output_buffer = ''
- javascript_tag { @output_buffer.concat "alert('hello')" }
- assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", @output_buffer
+ javascript_tag { concat "alert('hello')" }
+ assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
end
def test_javascript_tag_with_block_and_options
- @output_buffer = ''
- javascript_tag(:id => "the_js_tag") { @output_buffer.concat "alert('hello')" }
- assert_dom_equal "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", @output_buffer
+ javascript_tag(:id => "the_js_tag") { concat "alert('hello')" }
+ assert_dom_equal "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
end
def test_javascript_cdata_section
diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb
index 3f5ec07214..a5be0d2789 100644
--- a/actionpack/test/template/prototype_helper_test.rb
+++ b/actionpack/test/template/prototype_helper_test.rb
@@ -118,52 +118,46 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
end
def test_form_remote_tag_with_block
- @output_buffer = ''
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { @output_buffer.concat "Hello world!" }
- assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), @output_buffer
+ form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" }
+ assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), output_buffer
end
def test_remote_form_for_with_record_identification_with_new_record
- @output_buffer = ''
remote_form_for(@record, {:html => { :id => 'create-author' }}) {}
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' id='create-author' method='post'></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_record_identification_without_html_options
- @output_buffer = ''
remote_form_for(@record) {}
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' method='post' id='new_author'></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_record_identification_with_existing_record
@record.save
- @output_buffer = ''
remote_form_for(@record) {}
expected = %(<form action='#{author_path(@record)}' id='edit_author_1' method='post' onsubmit="new Ajax.Request('#{author_path(@record)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_author'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_new_object_in_list
- @output_buffer = ''
remote_form_for([@author, @article]) {}
expected = %(<form action='#{author_articles_path(@author)}' onsubmit="new Ajax.Request('#{author_articles_path(@author)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_article' method='post' id='new_article'></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_existing_object_in_list
@author.save
@article.save
- @output_buffer = ''
remote_form_for([@author, @article]) {}
expected = %(<form action='#{author_article_path(@author, @article)}' id='edit_article_1' method='post' onsubmit="new Ajax.Request('#{author_article_path(@author, @article)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_article'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div></form>)
- assert_dom_equal expected, @output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_on_callbacks
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index c39e5c69bf..441dc6b720 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -17,37 +17,32 @@ class RecordTagHelperTest < ActionView::TestCase
end
def test_content_tag_for
- @output_buffer = ''
expected = %(<li class="post bar" id="post_45"></li>)
actual = content_tag_for(:li, @post, :class => 'bar') { }
assert_dom_equal expected, actual
end
def test_content_tag_for_prefix
- @output_buffer = ''
expected = %(<ul class="post" id="archived_post_45"></ul>)
actual = content_tag_for(:ul, @post, :archived) { }
assert_dom_equal expected, actual
end
def test_content_tag_for_with_extra_html_tags
- @output_buffer = ''
expected = %(<tr class="post bar" id="post_45" style='background-color: #f0f0f0'></tr>)
actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { }
assert_dom_equal expected, actual
end
def test_block_works_with_content_tag_for
- @output_buffer = ''
expected = %(<tr class="post" id="post_45">#{@post.body}</tr>)
- actual = content_tag_for(:tr, @post) { @output_buffer.concat @post.body }
+ actual = content_tag_for(:tr, @post) { concat @post.body }
assert_dom_equal expected, actual
end
def test_div_for
- @output_buffer = ''
expected = %(<div class="post bar" id="post_45">#{@post.body}</div>)
- actual = div_for(@post, :class => "bar") { @output_buffer.concat @post.body }
+ actual = div_for(@post, :class => "bar") { concat @post.body }
assert_dom_equal expected, actual
end
diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb
index 7db04d178f..2941dfe217 100644
--- a/actionpack/test/template/tag_helper_test.rb
+++ b/actionpack/test/template/tag_helper_test.rb
@@ -35,18 +35,17 @@ class TagHelperTest < ActionView::TestCase
end
def test_content_tag_with_block
- @output_buffer = ''
- content_tag(:div) { @output_buffer.concat "Hello world!" }
- assert_dom_equal "<div>Hello world!</div>", @output_buffer
+ content_tag(:div) { concat "Hello world!" }
+ assert_dom_equal "<div>Hello world!</div>", output_buffer
end
def test_content_tag_with_block_and_options
- @output_buffer = ''
- content_tag(:div, :class => "green") { @output_buffer.concat "Hello world!" }
- assert_dom_equal %(<div class="green">Hello world!</div>), @output_buffer
+ content_tag(:div, :class => "green") { concat "Hello world!" }
+ assert_dom_equal %(<div class="green">Hello world!</div>), output_buffer
end
def test_content_tag_with_block_and_options_outside_of_action_view
+ self.output_buffer = nil
assert_equal content_tag("a", "Create", :href => "create"),
content_tag("a", "href" => "create") { "Create" }
end
diff --git a/actionpack/test/template/template_file_test.rb b/actionpack/test/template/template_file_test.rb
new file mode 100644
index 0000000000..d14a966c1c
--- /dev/null
+++ b/actionpack/test/template/template_file_test.rb
@@ -0,0 +1,95 @@
+require 'abstract_unit'
+
+class TemplateFileTest < Test::Unit::TestCase
+ LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
+
+ def setup
+ @template = ActionView::TemplateFile.new("test/hello_world.html.erb")
+ @another_template = ActionView::TemplateFile.new("test/hello_world.erb")
+ @file_only = ActionView::TemplateFile.new("hello_world.erb")
+ @full_path = ActionView::TemplateFile.new("/u/app/scales/config/../app/views/test/hello_world.erb", true)
+ @layout = ActionView::TemplateFile.new("layouts/hello")
+ @multipart = ActionView::TemplateFile.new("test_mailer/implicitly_multipart_example.text.html.erb")
+ end
+
+ def test_path
+ assert_equal "test/hello_world.html.erb", @template.path
+ assert_equal "test/hello_world.erb", @another_template.path
+ assert_equal "hello_world.erb", @file_only.path
+ assert_equal "/u/app/scales/config/../app/views/test/hello_world.erb", @full_path.path
+ assert_equal "layouts/hello", @layout.path
+ assert_equal "test_mailer/implicitly_multipart_example.text.html.erb", @multipart.path
+ end
+
+ def test_path_without_extension
+ assert_equal "test/hello_world.html", @template.path_without_extension
+ assert_equal "test/hello_world", @another_template.path_without_extension
+ assert_equal "hello_world", @file_only.path_without_extension
+ assert_equal "layouts/hello", @layout.path_without_extension
+ assert_equal "test_mailer/implicitly_multipart_example.text.html", @multipart.path_without_extension
+ end
+
+ def test_path_without_format_and_extension
+ assert_equal "test/hello_world", @template.path_without_format_and_extension
+ assert_equal "test/hello_world", @another_template.path_without_format_and_extension
+ assert_equal "hello_world", @file_only.path_without_format_and_extension
+ assert_equal "layouts/hello", @layout.path_without_format_and_extension
+ assert_equal "test_mailer/implicitly_multipart_example", @multipart.path_without_format_and_extension
+ end
+
+ def test_name
+ assert_equal "hello_world", @template.name
+ assert_equal "hello_world", @another_template.name
+ assert_equal "hello_world", @file_only.name
+ assert_equal "hello_world", @full_path.name
+ assert_equal "hello", @layout.name
+ assert_equal "implicitly_multipart_example", @multipart.name
+ end
+
+ def test_format
+ assert_equal "html", @template.format
+ assert_equal nil, @another_template.format
+ assert_equal nil, @layout.format
+ assert_equal "text.html", @multipart.format
+ end
+
+ def test_extension
+ assert_equal "erb", @template.extension
+ assert_equal "erb", @another_template.extension
+ assert_equal nil, @layout.extension
+ assert_equal "erb", @multipart.extension
+ end
+
+ def test_format_and_extension
+ assert_equal "html.erb", @template.format_and_extension
+ assert_equal "erb", @another_template.format_and_extension
+ assert_equal nil, @layout.format_and_extension
+ assert_equal "text.html.erb", @multipart.format_and_extension
+ end
+
+ def test_new_file_with_extension
+ file = @template.dup_with_extension(:haml)
+ assert_equal "test/hello_world.html", file.path_without_extension
+ assert_equal "haml", file.extension
+ assert_equal "test/hello_world.html.haml", file.path
+
+ file = @another_template.dup_with_extension(:haml)
+ assert_equal "test/hello_world", file.path_without_extension
+ assert_equal "haml", file.extension
+ assert_equal "test/hello_world.haml", file.path
+
+ file = @another_template.dup_with_extension(nil)
+ assert_equal "test/hello_world", file.path_without_extension
+ assert_equal nil, file.extension
+ assert_equal "test/hello_world", file.path
+ end
+
+ def test_freezes_entire_contents
+ @template.freeze
+ assert @template.frozen?
+ assert @template.base_path.frozen?
+ assert @template.name.frozen?
+ assert @template.format.frozen?
+ assert @template.extension.frozen?
+ end
+end
diff --git a/actionpack/test/template/template_finder_test.rb b/actionpack/test/template/template_finder_test.rb
deleted file mode 100644
index 3d6baff5fb..0000000000
--- a/actionpack/test/template/template_finder_test.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require 'abstract_unit'
-
-class TemplateFinderTest < Test::Unit::TestCase
-
- LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
-
- def setup
- ActionView::TemplateFinder.process_view_paths(LOAD_PATH_ROOT)
- ActionView::Template::register_template_handler :mab, Class.new(ActionView::TemplateHandler)
- @template = ActionView::Base.new
- @finder = ActionView::TemplateFinder.new(@template, LOAD_PATH_ROOT)
- end
-
- def test_should_raise_exception_for_unprocessed_view_path
- assert_raises ActionView::TemplateFinder::InvalidViewPath do
- ActionView::TemplateFinder.new(@template, File.dirname(__FILE__))
- end
- end
-
- def test_should_cache_file_extension_properly
- assert_equal ["builder", "erb", "rhtml", "rjs", "rxml", "mab"].sort,
- ActionView::TemplateFinder.file_extension_cache[LOAD_PATH_ROOT].values.flatten.uniq.sort
-
- assert_equal (Dir.glob("#{LOAD_PATH_ROOT}/**/*/*.{erb,rjs,rhtml,builder,rxml,mab}") |
- Dir.glob("#{LOAD_PATH_ROOT}/**.{erb,rjs,rhtml,builder,rxml,mab}")).size,
- ActionView::TemplateFinder.file_extension_cache[LOAD_PATH_ROOT].keys.size
- end
-
- def test_should_cache_dir_content_properly
- assert ActionView::TemplateFinder.processed_view_paths[LOAD_PATH_ROOT]
- assert_equal (Dir.glob("#{LOAD_PATH_ROOT}/**/*/**") | Dir.glob("#{LOAD_PATH_ROOT}/**")).find_all {|f| !File.directory?(f) }.size,
- ActionView::TemplateFinder.processed_view_paths[LOAD_PATH_ROOT].size
- end
-
- def test_find_template_extension_from_first_render
- assert_nil @finder.send(:find_template_extension_from_first_render)
-
- {
- nil => nil,
- '' => nil,
- 'foo' => nil,
- '/foo' => nil,
- 'foo.rb' => 'rb',
- 'foo.bar.rb' => 'bar.rb',
- 'baz/foo.rb' => 'rb',
- 'baz/foo.bar.rb' => 'bar.rb',
- 'baz/foo.o/foo.rb' => 'rb',
- 'baz/foo.o/foo.bar.rb' => 'bar.rb',
- }.each do |input,expectation|
- @template.instance_variable_set('@first_render', input)
- assert_equal expectation, @finder.send(:find_template_extension_from_first_render)
- end
- end
-
- def test_should_report_file_exists_correctly
- assert_nil @finder.send(:find_template_extension_from_first_render)
- assert_equal false, @finder.send(:file_exists?, 'test.rhtml')
- assert_equal false, @finder.send(:file_exists?, 'test.rb')
-
- @template.instance_variable_set('@first_render', 'foo.rb')
-
- assert_equal 'rb', @finder.send(:find_template_extension_from_first_render)
- assert_equal false, @finder.send(:file_exists?, 'baz')
- assert_equal false, @finder.send(:file_exists?, 'baz.rb')
- end
-
- uses_mocha 'Template finder tests' do
- def test_should_update_extension_cache_when_template_handler_is_registered
- ActionView::TemplateFinder.expects(:update_extension_cache_for).with("funky")
- ActionView::Template::register_template_handler :funky, Class.new(ActionView::TemplateHandler)
- end
- end
-end
diff --git a/actionpack/test/template/template_object_test.rb b/actionpack/test/template/template_object_test.rb
index afb5c5cc16..2cfc4523c6 100644
--- a/actionpack/test/template/template_object_test.rb
+++ b/actionpack/test/template/template_object_test.rb
@@ -2,60 +2,57 @@ require 'abstract_unit'
class TemplateObjectTest < Test::Unit::TestCase
LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
- ActionView::TemplateFinder.process_view_paths(LOAD_PATH_ROOT)
-
+
class TemplateTest < Test::Unit::TestCase
def setup
@view = ActionView::Base.new(LOAD_PATH_ROOT)
@path = "test/hello_world.erb"
end
-
+
def test_should_create_valid_template
template = ActionView::Template.new(@view, @path, true)
-
+
assert_kind_of ActionView::TemplateHandlers::ERB, template.handler
- assert_equal "test/hello_world.erb", template.path
+ assert_equal "test/hello_world.erb", template.path.to_s
assert_nil template.instance_variable_get(:"@source")
assert_equal "erb", template.extension
end
-
+
uses_mocha 'Template preparation tests' do
-
def test_should_prepare_template_properly
template = ActionView::Template.new(@view, @path, true)
view = template.instance_variable_get(:"@view")
-
+
view.expects(:evaluate_assigns)
template.handler.expects(:compile_template).with(template)
view.expects(:method_names).returns({})
-
+
template.prepare!
end
-
end
end
-
+
class PartialTemplateTest < Test::Unit::TestCase
def setup
@view = ActionView::Base.new(LOAD_PATH_ROOT)
@path = "test/partial_only"
end
-
+
def test_should_create_valid_partial_template
template = ActionView::PartialTemplate.new(@view, @path, nil)
-
- assert_equal "test/_partial_only", template.path
+
+ assert_equal "test/_partial_only", template.path.path_without_format_and_extension
assert_equal :partial_only, template.variable_name
-
+
assert template.locals.has_key?(:object)
assert template.locals.has_key?(:partial_only)
end
-
+
def test_partial_with_errors
template = ActionView::PartialTemplate.new(@view, 'test/raise', nil)
assert_raise(ActionView::TemplateError) { template.render_template }
end
-
+
uses_mocha 'Partial template preparation tests' do
def test_should_prepare_on_initialization
ActionView::PartialTemplate.any_instance.expects(:prepare!)
@@ -63,7 +60,7 @@ class TemplateObjectTest < Test::Unit::TestCase
end
end
end
-
+
class PartialTemplateFallbackTest < Test::Unit::TestCase
def setup
@view = ActionView::Base.new(LOAD_PATH_ROOT)
@@ -72,7 +69,7 @@ class TemplateObjectTest < Test::Unit::TestCase
def test_default
template = ActionView::PartialTemplate.new(@view, @path, nil)
- assert_equal 'test/_layout_for_partial', template.path
+ assert_equal 'test/_layout_for_partial', template.path.path_without_format_and_extension
assert_equal 'erb', template.extension
assert_equal :html, @view.template_format
end
@@ -80,7 +77,7 @@ class TemplateObjectTest < Test::Unit::TestCase
def test_js
@view.template_format = :js
template = ActionView::PartialTemplate.new(@view, @path, nil)
- assert_equal 'test/_layout_for_partial', template.path
+ assert_equal 'test/_layout_for_partial', template.path.path_without_format_and_extension
assert_equal 'erb', template.extension
assert_equal :html, @view.template_format
end
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 0f5c62acad..cbb5c7ee74 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -12,11 +12,11 @@ class TextHelperTest < ActionView::TestCase
end
def test_concat
- @output_buffer = 'foo'
+ self.output_buffer = 'foo'
concat 'bar'
- assert_equal 'foobar', @output_buffer
+ assert_equal 'foobar', output_buffer
assert_nothing_raised { concat nil }
- assert_equal 'foobar', @output_buffer
+ assert_equal 'foobar', output_buffer
end
def test_simple_format
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index d45ea08a6f..0713cea8ac 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -211,6 +211,14 @@ class UrlHelperTest < ActionView::TestCase
def test_link_tag_using_post_javascript_and_popup
assert_raises(ActionView::ActionViewError) { link_to("Hello", "http://www.example.com", :popup => true, :method => :post, :confirm => "Are you serious?") }
end
+
+ def test_link_tag_using_block
+ self.output_buffer = ''
+
+ link_to("http://example.com") { concat("Example site") }
+
+ assert_equal '<a href="http://example.com">Example site</a>', output_buffer
+ end
def test_link_to_unless
assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog")
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index a65771648e..a1d82fb45d 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,11 @@
*Edge*
+* Add :from option to calculations. #397 [Ben Munat]
+
+* Add :validate option to associations to enable/disable the automatic validation of associated models. Resolves #301. [Jan De Poorter]
+
+* PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later. [Jeremy Kemper]
+
* Added SQL escaping for :limit and :offset in MySQL [Jonathan Wiess]
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index fc068b16c3..7a5296c458 100755
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -225,13 +225,13 @@ end
desc "Publish the beta gem"
task :pgem => [:package] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ `ssh wrath.rubyonrails.org './gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/ar", "doc").upload
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload
end
desc "Publish the release files to RubyForge."
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index a3d1f12b03..49f5270396 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -103,10 +103,10 @@ module ActiveRecord
associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
:include => options[:include],
:joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} as t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
- :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as _parent_record_id",
+ :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id",
:order => options[:order])
- set_association_collection_records(id_to_record_map, reflection.name, associated_records, '_parent_record_id')
+ set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id')
end
def preload_has_one_association(records, reflection, preload_options={})
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index f32b217326..db99b7165d 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -690,6 +690,7 @@ module ActiveRecord
# association is a polymorphic +belongs_to+.
# * <tt>:uniq</tt> - If true, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
+ # * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. true by default.
#
# Option examples:
# has_many :comments, :order => "posted_on"
@@ -710,7 +711,7 @@ module ActiveRecord
configure_dependency_for_has_many(reflection)
- add_multiple_associated_save_callbacks(reflection.name)
+ add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
add_association_callbacks(reflection.name, reflection.options)
if options[:through]
@@ -769,6 +770,7 @@ module ActiveRecord
# * <tt>:source_type</tt> - Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
# association is a polymorphic +belongs_to+.
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
+ # * <tt>:validate</tt> - If false, don't validate the associated object when saving the parent object. +false+ by default.
#
# Option examples:
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
@@ -799,7 +801,7 @@ module ActiveRecord
end
after_save method_name
- add_single_associated_save_callbacks(reflection.name)
+ add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
association_accessor_methods(reflection, HasOneAssociation)
association_constructor_method(:build, reflection, HasOneAssociation)
association_constructor_method(:create, reflection, HasOneAssociation)
@@ -857,6 +859,7 @@ module ActiveRecord
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
+ # * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. +false+ by default.
#
# Option examples:
# belongs_to :firm, :foreign_key => "client_of"
@@ -937,6 +940,8 @@ module ActiveRecord
)
end
+ add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
+
configure_dependency_for_belongs_to(reflection)
end
@@ -1025,6 +1030,7 @@ module ActiveRecord
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
+ # * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. +true+ by default.
#
# Option examples:
# has_and_belongs_to_many :projects
@@ -1037,7 +1043,7 @@ module ActiveRecord
def has_and_belongs_to_many(association_id, options = {}, &extension)
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
- add_multiple_associated_save_callbacks(reflection.name)
+ add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
# Don't use a before_destroy callback since users' before_destroy
@@ -1343,7 +1349,8 @@ module ActiveRecord
:uniq,
:finder_sql, :counter_sql,
:before_add, :after_add, :before_remove, :after_remove,
- :extend, :readonly
+ :extend, :readonly,
+ :validate
)
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
@@ -1353,7 +1360,7 @@ module ActiveRecord
def create_has_one_reflection(association_id, options)
options.assert_valid_keys(
- :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly
+ :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly, :validate
)
create_reflection(:has_one, association_id, options, self)
@@ -1361,7 +1368,7 @@ module ActiveRecord
def create_has_one_through_reflection(association_id, options)
options.assert_valid_keys(
- :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type
+ :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type, :validate
)
create_reflection(:has_one, association_id, options, self)
end
@@ -1369,7 +1376,7 @@ module ActiveRecord
def create_belongs_to_reflection(association_id, options)
options.assert_valid_keys(
:class_name, :foreign_key, :foreign_type, :remote, :select, :conditions, :include, :dependent,
- :counter_cache, :extend, :polymorphic, :readonly
+ :counter_cache, :extend, :polymorphic, :readonly, :validate
)
reflection = create_reflection(:belongs_to, association_id, options, self)
@@ -1388,7 +1395,8 @@ module ActiveRecord
:uniq,
:finder_sql, :delete_sql, :insert_sql,
:before_add, :after_add, :before_remove, :after_remove,
- :extend, :readonly
+ :extend, :readonly,
+ :validate
)
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
@@ -1638,7 +1646,9 @@ module ActiveRecord
end
def join_for_table_name(table_name)
- @joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
+ join = (@joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first) rescue nil
+ return join unless join.nil?
+ @joins.select{|j|j.is_a?(JoinAssociation) && j.aliased_join_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
end
def joins_for_table_name(table_name)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 450ea5cb33..8fca34e524 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1297,6 +1297,20 @@ module ActiveRecord #:nodoc:
store_full_sti_class ? name : name.demodulize
end
+ # Merges conditions so that the result is a valid +condition+
+ def merge_conditions(*conditions)
+ segments = []
+
+ conditions.each do |condition|
+ unless condition.blank?
+ sql = sanitize_sql(condition)
+ segments << sql unless sql.blank?
+ end
+ end
+
+ "(#{segments.join(') AND (')})" unless segments.empty?
+ end
+
private
def find_initial(options)
options.update(:limit => 1)
@@ -1484,20 +1498,6 @@ module ActiveRecord #:nodoc:
(safe_to_array(first) + safe_to_array(second)).uniq
end
- # Merges conditions so that the result is a valid +condition+
- def merge_conditions(*conditions)
- segments = []
-
- conditions.each do |condition|
- unless condition.blank?
- sql = sanitize_sql(condition)
- segments << sql unless sql.blank?
- end
- end
-
- "(#{segments.join(') AND (')})" unless segments.empty?
- end
-
# Object#to_a is deprecated, though it does have the desired behavior
def safe_to_array(o)
case o
@@ -1903,10 +1903,12 @@ module ActiveRecord #:nodoc:
# MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
def compute_type(type_name)
modularized_name = type_name_with_module(type_name)
- begin
- class_eval(modularized_name, __FILE__, __LINE__)
- rescue NameError
- class_eval(type_name, __FILE__, __LINE__)
+ silence_warnings do
+ begin
+ class_eval(modularized_name, __FILE__, __LINE__)
+ rescue NameError
+ class_eval(type_name, __FILE__, __LINE__)
+ end
end
end
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index caa8c539d5..2ca1a0aaa3 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -1,6 +1,6 @@
module ActiveRecord
module Calculations #:nodoc:
- CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include]
+ CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include, :from]
def self.included(base)
base.extend(ClassMethods)
end
@@ -27,6 +27,8 @@ module ActiveRecord
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not
# include the joined columns.
# * <tt>:distinct</tt>: Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) ...
+ # * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
+ # of a database view).
#
# Examples for counting all:
# Person.count # returns the total count of all people
@@ -178,8 +180,12 @@ module ActiveRecord
sql = "SELECT COUNT(*) AS #{aggregate_alias}" if use_workaround
sql << ", #{options[:group_field]} AS #{options[:group_alias]}" if options[:group]
- sql << " FROM (SELECT #{distinct}#{column_name}" if use_workaround
- sql << " FROM #{connection.quote_table_name(table_name)} "
+ if options[:from]
+ sql << " FROM #{options[:from]} "
+ else
+ sql << " FROM (SELECT #{distinct}#{column_name}" if use_workaround
+ sql << " FROM #{connection.quote_table_name(table_name)} "
+ end
if merged_includes.any?
join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, options[:joins])
sql << join_dependency.join_associations.collect{|join| join.association_join }.join
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 55f67995d1..7d8530ebef 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -356,7 +356,7 @@ module ActiveRecord
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
if native = native_database_types[type]
- column_type_sql = native.is_a?(Hash) ? native[:name] : native
+ column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
if type == :decimal # ignore limit, use precision and scale
scale ||= native[:scale]
@@ -371,7 +371,7 @@ module ActiveRecord
raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale if specified"
end
- elsif limit ||= native.is_a?(Hash) && native[:limit]
+ elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
column_type_sql << "(#{limit})"
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 653b45021d..93aafaaad1 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -42,30 +42,6 @@ end
module ActiveRecord
class Base
- def self.require_mysql
- # Include the MySQL driver if one hasn't already been loaded
- unless defined? Mysql
- begin
- require_library_or_gem 'mysql'
- rescue LoadError => cannot_require_mysql
- # Use the bundled Ruby/MySQL driver if no driver is already in place
- begin
- ActiveRecord::Base.logger.info(
- "WARNING: You're using the Ruby-based MySQL library that ships with Rails. This library is not suited for production. " +
- "Please install the C-based MySQL library instead (gem install mysql)."
- ) if ActiveRecord::Base.logger
-
- require 'active_record/vendor/mysql'
- rescue LoadError
- raise cannot_require_mysql
- end
- end
- end
-
- # Define Mysql::Result.all_hashes
- MysqlCompat.define_all_hashes_method!
- end
-
# Establishes a connection to the database that's used by all Active Record objects.
def self.mysql_connection(config) # :nodoc:
config = config.symbolize_keys
@@ -81,7 +57,17 @@ module ActiveRecord
raise ArgumentError, "No database specified. Missing argument: database."
end
- require_mysql
+ # Require the MySQL driver and define Mysql::Result.all_hashes
+ unless defined? Mysql
+ begin
+ require_library_or_gem('mysql')
+ rescue LoadError
+ $stderr.puts '!!! The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql.'
+ raise
+ end
+ end
+ MysqlCompat.define_all_hashes_method!
+
mysql = Mysql.init
mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]
@@ -165,8 +151,10 @@ module ActiveRecord
#
# ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false
class MysqlAdapter < AbstractAdapter
- @@emulate_booleans = true
cattr_accessor :emulate_booleans
+ self.emulate_booleans = true
+
+ ADAPTER_NAME = 'MySQL'.freeze
LOST_CONNECTION_ERROR_MESSAGES = [
"Server shutdown in progress",
@@ -174,7 +162,22 @@ module ActiveRecord
"Lost connection to MySQL server during query",
"MySQL server has gone away" ]
- QUOTED_TRUE, QUOTED_FALSE = '1', '0'
+ QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
+
+ NATIVE_DATABASE_TYPES = {
+ :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY".freeze,
+ :string => { :name => "varchar", :limit => 255 },
+ :text => { :name => "text" },
+ :integer => { :name => "int"},
+ :float => { :name => "float" },
+ :decimal => { :name => "decimal" },
+ :datetime => { :name => "datetime" },
+ :timestamp => { :name => "datetime" },
+ :time => { :name => "time" },
+ :date => { :name => "date" },
+ :binary => { :name => "blob" },
+ :boolean => { :name => "tinyint", :limit => 1 }
+ }
def initialize(connection, logger, connection_options, config)
super(connection, logger)
@@ -184,7 +187,7 @@ module ActiveRecord
end
def adapter_name #:nodoc:
- 'MySQL'
+ ADAPTER_NAME
end
def supports_migrations? #:nodoc:
@@ -192,20 +195,7 @@ module ActiveRecord
end
def native_database_types #:nodoc:
- {
- :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
- :string => { :name => "varchar", :limit => 255 },
- :text => { :name => "text" },
- :integer => { :name => "int"},
- :float => { :name => "float" },
- :decimal => { :name => "decimal" },
- :datetime => { :name => "datetime" },
- :timestamp => { :name => "datetime" },
- :time => { :name => "time" },
- :date => { :name => "date" },
- :binary => { :name => "blob" },
- :boolean => { :name => "tinyint", :limit => 1 }
- }
+ NATIVE_DATABASE_TYPES
end
@@ -498,12 +488,17 @@ module ActiveRecord
private
def connect
+ @connection.reconnect = true if @connection.respond_to?(:reconnect=)
+
encoding = @config[:encoding]
if encoding
@connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
end
+
@connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
+
@connection.real_connect(*@connection_options)
+
execute("SET NAMES '#{encoding}'") if encoding
# By default, MySQL 'where id is null' selects the last inserted id.
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 049e6f61de..294f4c1929 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -238,9 +238,26 @@ module ActiveRecord
# * <tt>:min_messages</tt> - An optional client min messages that is used in a <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
# * <tt>:allow_concurrency</tt> - If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.
class PostgreSQLAdapter < AbstractAdapter
+ ADAPTER_NAME = 'PostgreSQL'.freeze
+
+ NATIVE_DATABASE_TYPES = {
+ :primary_key => "serial primary key".freeze,
+ :string => { :name => "character varying", :limit => 255 },
+ :text => { :name => "text" },
+ :integer => { :name => "integer" },
+ :float => { :name => "float" },
+ :decimal => { :name => "decimal" },
+ :datetime => { :name => "timestamp" },
+ :timestamp => { :name => "timestamp" },
+ :time => { :name => "time" },
+ :date => { :name => "date" },
+ :binary => { :name => "bytea" },
+ :boolean => { :name => "boolean" }
+ }
+
# Returns 'PostgreSQL' as adapter name for identification purposes.
def adapter_name
- 'PostgreSQL'
+ ADAPTER_NAME
end
# Initializes and connects a PostgreSQL adapter.
@@ -282,20 +299,7 @@ module ActiveRecord
end
def native_database_types #:nodoc:
- {
- :primary_key => "serial primary key",
- :string => { :name => "character varying", :limit => 255 },
- :text => { :name => "text" },
- :integer => { :name => "integer" },
- :float => { :name => "float" },
- :decimal => { :name => "decimal" },
- :datetime => { :name => "timestamp" },
- :timestamp => { :name => "timestamp" },
- :time => { :name => "time" },
- :date => { :name => "date" },
- :binary => { :name => "bytea" },
- :boolean => { :name => "boolean" }
- }
+ NATIVE_DATABASE_TYPES
end
# Does PostgreSQL support migrations?
@@ -319,6 +323,15 @@ module ActiveRecord
has_support
end
+ def supports_insert_with_returning?
+ unless defined? @supports_insert_with_returning
+ @supports_insert_with_returning =
+ @connection.respond_to?(:server_version) &&
+ @connection.server_version >= 80200
+ end
+ @supports_insert_with_returning
+ end
+
# Returns the configured supported identifier length supported by PostgreSQL,
# or report the default of 63 on PostgreSQL 7.x.
def table_alias_length
@@ -411,8 +424,34 @@ module ActiveRecord
# Executes an INSERT query and returns the new record's ID
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
+ # Extract the table from the insert sql. Yuck.
table = sql.split(" ", 4)[2].gsub('"', '')
- super || pk && last_insert_id(table, sequence_name || default_sequence_name(table, pk))
+
+ # Try an insert with 'returning id' if available (PG >= 8.2)
+ if supports_insert_with_returning?
+ pk, sequence_name = *pk_and_sequence_for(table) unless pk
+ if pk
+ id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
+ clear_query_cache
+ return id
+ end
+ end
+
+ # Otherwise, insert then grab last_insert_id.
+ if insert_id = super
+ insert_id
+ else
+ # If neither pk nor sequence name is given, look them up.
+ unless pk || sequence_name
+ pk, sequence_name = *pk_and_sequence_for(table)
+ end
+
+ # If a pk is given, fallback to default sequence name.
+ # Don't fetch last insert id for a table without a pk.
+ if pk && sequence_name ||= default_sequence_name(table, pk)
+ last_insert_id(table, sequence_name)
+ end
+ end
end
# create a 2D array representing the result set
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index c4cbe5d52f..e19614e31f 100755
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -547,7 +547,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
@connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
@class_name = class_name ||
(ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
- @table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix
+ @table_name = "#{ActiveRecord::Base.table_name_prefix}#{@table_name}#{ActiveRecord::Base.table_name_suffix}"
@table_name = class_name.table_name if class_name.respond_to?(:table_name)
@connection = class_name.connection if class_name.respond_to?(:connection)
read_fixture_files
diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb
index 6e55e36b7d..25e0e61c69 100644
--- a/activerecord/lib/active_record/observer.rb
+++ b/activerecord/lib/active_record/observer.rb
@@ -189,7 +189,7 @@ module ActiveRecord
def add_observer!(klass)
klass.add_observer(self)
- klass.class_eval 'def after_find() end' unless klass.respond_to?(:after_find)
+ klass.class_eval 'def after_find() end' unless klass.method_defined?(:after_find)
end
end
end
diff --git a/activerecord/lib/active_record/vendor/db2.rb b/activerecord/lib/active_record/vendor/db2.rb
deleted file mode 100644
index 812c8cc517..0000000000
--- a/activerecord/lib/active_record/vendor/db2.rb
+++ /dev/null
@@ -1,362 +0,0 @@
-require 'db2/db2cli.rb'
-
-module DB2
- module DB2Util
- include DB2CLI
-
- def free() SQLFreeHandle(@handle_type, @handle); end
- def handle() @handle; end
-
- def check_rc(rc)
- if ![SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA_FOUND].include?(rc)
- rec = 1
- msg = ''
- loop do
- a = SQLGetDiagRec(@handle_type, @handle, rec, 500)
- break if a[0] != SQL_SUCCESS
- msg << a[3] if !a[3].nil? and a[3] != '' # Create message.
- rec += 1
- end
- raise "DB2 error: #{msg}"
- end
- end
- end
-
- class Environment
- include DB2Util
-
- def initialize
- @handle_type = SQL_HANDLE_ENV
- rc, @handle = SQLAllocHandle(@handle_type, SQL_NULL_HANDLE)
- check_rc(rc)
- end
-
- def data_sources(buffer_length = 1024)
- retval = []
- max_buffer_length = buffer_length
-
- a = SQLDataSources(@handle, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH + 1, buffer_length)
- retval << [a[1], a[3]]
- max_buffer_length = [max_buffer_length, a[4]].max
-
- loop do
- a = SQLDataSources(@handle, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH + 1, buffer_length)
- break if a[0] == SQL_NO_DATA_FOUND
-
- retval << [a[1], a[3]]
- max_buffer_length = [max_buffer_length, a[4]].max
- end
-
- if max_buffer_length > buffer_length
- get_data_sources(max_buffer_length)
- else
- retval
- end
- end
- end
-
- class Connection
- include DB2Util
-
- def initialize(environment)
- @env = environment
- @handle_type = SQL_HANDLE_DBC
- rc, @handle = SQLAllocHandle(@handle_type, @env.handle)
- check_rc(rc)
- end
-
- def connect(server_name, user_name = '', auth = '')
- check_rc(SQLConnect(@handle, server_name, user_name.to_s, auth.to_s))
- end
-
- def set_connect_attr(attr, value)
- value += "\0" if value.class == String
- check_rc(SQLSetConnectAttr(@handle, attr, value))
- end
-
- def set_auto_commit_on
- set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON)
- end
-
- def set_auto_commit_off
- set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF)
- end
-
- def disconnect
- check_rc(SQLDisconnect(@handle))
- end
-
- def rollback
- check_rc(SQLEndTran(@handle_type, @handle, SQL_ROLLBACK))
- end
-
- def commit
- check_rc(SQLEndTran(@handle_type, @handle, SQL_COMMIT))
- end
- end
-
- class Statement
- include DB2Util
-
- def initialize(connection)
- @conn = connection
- @handle_type = SQL_HANDLE_STMT
- @parms = [] #yun
- @sql = '' #yun
- @numParms = 0 #yun
- @prepared = false #yun
- @parmArray = [] #yun. attributes of the parameter markers
- rc, @handle = SQLAllocHandle(@handle_type, @conn.handle)
- check_rc(rc)
- end
-
- def columns(table_name, schema_name = '%')
- check_rc(SQLColumns(@handle, '', schema_name.upcase, table_name.upcase, '%'))
- fetch_all
- end
-
- def tables(schema_name = '%')
- check_rc(SQLTables(@handle, '', schema_name.upcase, '%', 'TABLE'))
- fetch_all
- end
-
- def indexes(table_name, schema_name = '')
- check_rc(SQLStatistics(@handle, '', schema_name.upcase, table_name.upcase, SQL_INDEX_ALL, SQL_ENSURE))
- fetch_all
- end
-
- def prepare(sql)
- @sql = sql
- check_rc(SQLPrepare(@handle, sql))
- rc, @numParms = SQLNumParams(@handle) #number of question marks
- check_rc(rc)
- #--------------------------------------------------------------------------
- # parameter attributes are stored in instance variable @parmArray so that
- # they are available when execute method is called.
- #--------------------------------------------------------------------------
- if @numParms > 0 # get parameter marker attributes
- 1.upto(@numParms) do |i| # parameter number starts from 1
- rc, type, size, decimalDigits = SQLDescribeParam(@handle, i)
- check_rc(rc)
- @parmArray << Parameter.new(type, size, decimalDigits)
- end
- end
- @prepared = true
- self
- end
-
- def execute(*parms)
- raise "The statement was not prepared" if @prepared == false
-
- if parms.size == 1 and parms[0].class == Array
- parms = parms[0]
- end
-
- if @numParms != parms.size
- raise "Number of parameters supplied does not match with the SQL statement"
- end
-
- if @numParms > 0 #need to bind parameters
- #--------------------------------------------------------------------
- #calling bindParms may not be safe. Look comment below.
- #--------------------------------------------------------------------
- #bindParms(parms)
-
- valueArray = []
- 1.upto(@numParms) do |i| # parameter number starts from 1
- type = @parmArray[i - 1].class
- size = @parmArray[i - 1].size
- decimalDigits = @parmArray[i - 1].decimalDigits
-
- if parms[i - 1].class == String
- valueArray << parms[i - 1]
- else
- valueArray << parms[i - 1].to_s
- end
-
- rc = SQLBindParameter(@handle, i, type, size, decimalDigits, valueArray[i - 1])
- check_rc(rc)
- end
- end
-
- check_rc(SQLExecute(@handle))
-
- if @numParms != 0
- check_rc(SQLFreeStmt(@handle, SQL_RESET_PARAMS)) # Reset parameters
- end
-
- self
- end
-
- #-------------------------------------------------------------------------------
- # The last argument(value) to SQLBindParameter is a deferred argument, that is,
- # it should be available when SQLExecute is called. Even though "value" is
- # local to bindParms method, it seems that it is available when SQLExecute
- # is called. I am not sure whether it would still work if garbage collection
- # is done between bindParms call and SQLExecute call inside the execute method
- # above.
- #-------------------------------------------------------------------------------
- def bindParms(parms) # This is the real thing. It uses SQLBindParms
- 1.upto(@numParms) do |i| # parameter number starts from 1
- rc, dataType, parmSize, decimalDigits = SQLDescribeParam(@handle, i)
- check_rc(rc)
- if parms[i - 1].class == String
- value = parms[i - 1]
- else
- value = parms[i - 1].to_s
- end
- rc = SQLBindParameter(@handle, i, dataType, parmSize, decimalDigits, value)
- check_rc(rc)
- end
- end
-
- #------------------------------------------------------------------------------
- # bind method does not use DB2's SQLBindParams, but replaces "?" in the
- # SQL statement with the value before passing the SQL statement to DB2.
- # It is not efficient and can handle only strings since it puts everything in
- # quotes.
- #------------------------------------------------------------------------------
- def bind(sql, args) #does not use SQLBindParams
- arg_index = 0
- result = ""
- tokens(sql).each do |part|
- case part
- when '?'
- result << "'" + (args[arg_index]) + "'" #put it into quotes
- arg_index += 1
- when '??'
- result << "?"
- else
- result << part
- end
- end
- if arg_index < args.size
- raise "Too many SQL parameters"
- elsif arg_index > args.size
- raise "Not enough SQL parameters"
- end
- result
- end
-
- ## Break the sql string into parts.
- #
- # This is NOT a full lexer for SQL. It just breaks up the SQL
- # string enough so that question marks, double question marks and
- # quoted strings are separated. This is used when binding
- # arguments to "?" in the SQL string. Note: comments are not
- # handled.
- #
- def tokens(sql)
- toks = sql.scan(/('([^'\\]|''|\\.)*'|"([^"\\]|""|\\.)*"|\?\??|[^'"?]+)/)
- toks.collect { |t| t[0] }
- end
-
- def exec_direct(sql)
- check_rc(SQLExecDirect(@handle, sql))
- self
- end
-
- def set_cursor_name(name)
- check_rc(SQLSetCursorName(@handle, name))
- self
- end
-
- def get_cursor_name
- rc, name = SQLGetCursorName(@handle)
- check_rc(rc)
- name
- end
-
- def row_count
- rc, rowcount = SQLRowCount(@handle)
- check_rc(rc)
- rowcount
- end
-
- def num_result_cols
- rc, cols = SQLNumResultCols(@handle)
- check_rc(rc)
- cols
- end
-
- def fetch_all
- if block_given?
- while row = fetch do
- yield row
- end
- else
- res = []
- while row = fetch do
- res << row
- end
- res
- end
- end
-
- def fetch
- cols = get_col_desc
- rc = SQLFetch(@handle)
- if rc == SQL_NO_DATA_FOUND
- SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
- SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
- return nil
- end
- raise "ERROR" unless rc == SQL_SUCCESS
-
- retval = []
- cols.each_with_index do |c, i|
- rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
- retval << adjust_content(content)
- end
- retval
- end
-
- def fetch_as_hash
- cols = get_col_desc
- rc = SQLFetch(@handle)
- if rc == SQL_NO_DATA_FOUND
- SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
- SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
- return nil
- end
- raise "ERROR" unless rc == SQL_SUCCESS
-
- retval = {}
- cols.each_with_index do |c, i|
- rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
- retval[c[0]] = adjust_content(content)
- end
- retval
- end
-
- def get_col_desc
- rc, nr_cols = SQLNumResultCols(@handle)
- cols = (1..nr_cols).collect do |c|
- rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024)
- [name.downcase, type, col_sz]
- end
- end
-
- def adjust_content(c)
- case c.class.to_s
- when 'DB2CLI::NullClass'
- return nil
- when 'DB2CLI::Time'
- "%02d:%02d:%02d" % [c.hour, c.minute, c.second]
- when 'DB2CLI::Date'
- "%04d-%02d-%02d" % [c.year, c.month, c.day]
- when 'DB2CLI::Timestamp'
- "%04d-%02d-%02d %02d:%02d:%02d" % [c.year, c.month, c.day, c.hour, c.minute, c.second]
- else
- return c
- end
- end
- end
-
- class Parameter
- attr_reader :type, :size, :decimalDigits
- def initialize(type, size, decimalDigits)
- @type, @size, @decimalDigits = type, size, decimalDigits
- end
- end
-end
diff --git a/activerecord/lib/active_record/vendor/mysql.rb b/activerecord/lib/active_record/vendor/mysql.rb
deleted file mode 100644
index 1c3294c719..0000000000
--- a/activerecord/lib/active_record/vendor/mysql.rb
+++ /dev/null
@@ -1,1214 +0,0 @@
-# $Id: mysql.rb,v 1.24 2005/02/12 11:37:15 tommy Exp $
-#
-# Copyright (C) 2003-2005 TOMITA Masahiro
-# tommy@tmtm.org
-#
-
-class Mysql
-
- VERSION = "4.0-ruby-0.2.6-plus-changes"
-
- require "socket"
- require "digest/sha1"
-
- MAX_PACKET_LENGTH = 256*256*256-1
- MAX_ALLOWED_PACKET = 1024*1024*1024
-
- MYSQL_UNIX_ADDR = "/tmp/mysql.sock"
- MYSQL_PORT = 3306
- PROTOCOL_VERSION = 10
-
- SCRAMBLE_LENGTH = 20
- SCRAMBLE_LENGTH_323 = 8
-
- # Command
- COM_SLEEP = 0
- COM_QUIT = 1
- COM_INIT_DB = 2
- COM_QUERY = 3
- COM_FIELD_LIST = 4
- COM_CREATE_DB = 5
- COM_DROP_DB = 6
- COM_REFRESH = 7
- COM_SHUTDOWN = 8
- COM_STATISTICS = 9
- COM_PROCESS_INFO = 10
- COM_CONNECT = 11
- COM_PROCESS_KILL = 12
- COM_DEBUG = 13
- COM_PING = 14
- COM_TIME = 15
- COM_DELAYED_INSERT = 16
- COM_CHANGE_USER = 17
- COM_BINLOG_DUMP = 18
- COM_TABLE_DUMP = 19
- COM_CONNECT_OUT = 20
- COM_REGISTER_SLAVE = 21
-
- # Client flag
- CLIENT_LONG_PASSWORD = 1
- CLIENT_FOUND_ROWS = 1 << 1
- CLIENT_LONG_FLAG = 1 << 2
- CLIENT_CONNECT_WITH_DB= 1 << 3
- CLIENT_NO_SCHEMA = 1 << 4
- CLIENT_COMPRESS = 1 << 5
- CLIENT_ODBC = 1 << 6
- CLIENT_LOCAL_FILES = 1 << 7
- CLIENT_IGNORE_SPACE = 1 << 8
- CLIENT_PROTOCOL_41 = 1 << 9
- CLIENT_INTERACTIVE = 1 << 10
- CLIENT_SSL = 1 << 11
- CLIENT_IGNORE_SIGPIPE = 1 << 12
- CLIENT_TRANSACTIONS = 1 << 13
- CLIENT_RESERVED = 1 << 14
- CLIENT_SECURE_CONNECTION = 1 << 15
- CLIENT_CAPABILITIES = CLIENT_LONG_PASSWORD|CLIENT_LONG_FLAG|CLIENT_TRANSACTIONS
- PROTO_AUTH41 = CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION
-
- # Connection Option
- OPT_CONNECT_TIMEOUT = 0
- OPT_COMPRESS = 1
- OPT_NAMED_PIPE = 2
- INIT_COMMAND = 3
- READ_DEFAULT_FILE = 4
- READ_DEFAULT_GROUP = 5
- SET_CHARSET_DIR = 6
- SET_CHARSET_NAME = 7
- OPT_LOCAL_INFILE = 8
-
- # Server Status
- SERVER_STATUS_IN_TRANS = 1
- SERVER_STATUS_AUTOCOMMIT = 2
-
- # Refresh parameter
- REFRESH_GRANT = 1
- REFRESH_LOG = 2
- REFRESH_TABLES = 4
- REFRESH_HOSTS = 8
- REFRESH_STATUS = 16
- REFRESH_THREADS = 32
- REFRESH_SLAVE = 64
- REFRESH_MASTER = 128
-
- def initialize(*args)
- @client_flag = 0
- @max_allowed_packet = MAX_ALLOWED_PACKET
- @query_with_result = true
- @status = :STATUS_READY
- if args[0] != :INIT then
- real_connect(*args)
- end
- end
-
- def real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=nil)
- @server_status = SERVER_STATUS_AUTOCOMMIT
- if (host == nil or host == "localhost") and defined? UNIXSocket then
- unix_socket = socket || ENV["MYSQL_UNIX_PORT"] || MYSQL_UNIX_ADDR
- sock = UNIXSocket::new(unix_socket)
- @host_info = Error::err(Error::CR_LOCALHOST_CONNECTION)
- @unix_socket = unix_socket
- else
- sock = TCPSocket::new(host, port||ENV["MYSQL_TCP_PORT"]||(Socket::getservbyname("mysql","tcp") rescue MYSQL_PORT))
- @host_info = sprintf Error::err(Error::CR_TCP_CONNECTION), host
- end
- @host = host ? host.dup : nil
- sock.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true
- @net = Net::new sock
-
- a = read
- @protocol_version = a.slice!(0)
- @server_version, a = a.split(/\0/,2)
- @thread_id, @scramble_buff = a.slice!(0,13).unpack("La8")
- if a.size >= 2 then
- @server_capabilities, = a.slice!(0,2).unpack("v")
- end
- if a.size >= 16 then
- @server_language, @server_status = a.slice!(0,3).unpack("cv")
- end
-
- flag = 0 if flag == nil
- flag |= @client_flag | CLIENT_CAPABILITIES
- flag |= CLIENT_CONNECT_WITH_DB if db
-
- @pre_411 = (0 == @server_capabilities & PROTO_AUTH41)
- if @pre_411
- data = Net::int2str(flag)+Net::int3str(@max_allowed_packet)+
- (user||"")+"\0"+
- scramble(passwd, @scramble_buff, @protocol_version==9)
- else
- dummy, @salt2 = a.unpack("a13a12")
- @scramble_buff += @salt2
- flag |= PROTO_AUTH41
- data = Net::int4str(flag) + Net::int4str(@max_allowed_packet) +
- ([8] + Array.new(23, 0)).pack("c24") + (user||"")+"\0"+
- scramble41(passwd, @scramble_buff)
- end
-
- if db and @server_capabilities & CLIENT_CONNECT_WITH_DB != 0
- data << "\0" if @pre_411
- data << db
- @db = db.dup
- end
- write data
- pkt = read
- handle_auth_fallback(pkt, passwd)
- ObjectSpace.define_finalizer(self, Mysql.finalizer(@net))
- self
- end
- alias :connect :real_connect
-
- def handle_auth_fallback(pkt, passwd)
- # A packet like this means that we need to send an old-format password
- if pkt.size == 1 and pkt[0] == 254 and
- @server_capabilities & CLIENT_SECURE_CONNECTION != 0 then
- data = scramble(passwd, @scramble_buff, @protocol_version == 9)
- write data + "\0"
- read
- end
- end
-
- def escape_string(str)
- Mysql::escape_string str
- end
- alias :quote :escape_string
-
- def get_client_info()
- VERSION
- end
- alias :client_info :get_client_info
-
- def options(option, arg=nil)
- if option == OPT_LOCAL_INFILE then
- if arg == false or arg == 0 then
- @client_flag &= ~CLIENT_LOCAL_FILES
- else
- @client_flag |= CLIENT_LOCAL_FILES
- end
- else
- raise "not implemented"
- end
- end
-
- def real_query(query)
- command COM_QUERY, query, true
- read_query_result
- self
- end
-
- def use_result()
- if @status != :STATUS_GET_RESULT then
- error Error::CR_COMMANDS_OUT_OF_SYNC
- end
- res = Result::new self, @fields, @field_count
- @status = :STATUS_USE_RESULT
- res
- end
-
- def store_result()
- if @status != :STATUS_GET_RESULT then
- error Error::CR_COMMANDS_OUT_OF_SYNC
- end
- @status = :STATUS_READY
- data = read_rows @field_count
- res = Result::new self, @fields, @field_count, data
- @fields = nil
- @affected_rows = data.length
- res
- end
-
- def change_user(user="", passwd="", db="")
- if @pre_411
- data = user+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)+"\0"+db
- else
- data = user+"\0"+scramble41(passwd, @scramble_buff)+db
- end
- pkt = command COM_CHANGE_USER, data
- handle_auth_fallback(pkt, passwd)
- @user = user
- @passwd = passwd
- @db = db
- end
-
- def character_set_name()
- raise "not implemented"
- end
-
- def close()
- @status = :STATUS_READY
- command COM_QUIT, nil, true
- @net.close
- self
- end
-
- def create_db(db)
- command COM_CREATE_DB, db
- self
- end
-
- def drop_db(db)
- command COM_DROP_DB, db
- self
- end
-
- def dump_debug_info()
- command COM_DEBUG
- self
- end
-
- def get_host_info()
- @host_info
- end
- alias :host_info :get_host_info
-
- def get_proto_info()
- @protocol_version
- end
- alias :proto_info :get_proto_info
-
- def get_server_info()
- @server_version
- end
- alias :server_info :get_server_info
-
- def kill(id)
- command COM_PROCESS_KILL, Net::int4str(id)
- self
- end
-
- def list_dbs(db=nil)
- real_query "show databases #{db}"
- @status = :STATUS_READY
- read_rows(1).flatten
- end
-
- def list_fields(table, field=nil)
- command COM_FIELD_LIST, "#{table}\0#{field}", true
- if @pre_411
- f = read_rows 6
- else
- f = read_rows 7
- end
- fields = unpack_fields(f, @server_capabilities & CLIENT_LONG_FLAG != 0)
- res = Result::new self, fields, f.length
- res.eof = true
- res
- end
-
- def list_processes()
- data = command COM_PROCESS_INFO
- @field_count = get_length data
- if @pre_411
- fields = read_rows 5
- else
- fields = read_rows 7
- end
- @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
- @status = :STATUS_GET_RESULT
- store_result
- end
-
- def list_tables(table=nil)
- real_query "show tables #{table}"
- @status = :STATUS_READY
- read_rows(1).flatten
- end
-
- def ping()
- command COM_PING
- self
- end
-
- def query(query)
- real_query query
- if not @query_with_result then
- return self
- end
- if @field_count == 0 then
- return nil
- end
- store_result
- end
-
- def refresh(r)
- command COM_REFRESH, r.chr
- self
- end
-
- def reload()
- refresh REFRESH_GRANT
- self
- end
-
- def select_db(db)
- command COM_INIT_DB, db
- @db = db
- self
- end
-
- def shutdown()
- command COM_SHUTDOWN
- self
- end
-
- def stat()
- command COM_STATISTICS
- end
-
- attr_reader :info, :insert_id, :affected_rows, :field_count, :thread_id
- attr_accessor :query_with_result, :status
-
- def read_one_row(field_count)
- data = read
- if data[0] == 254 and data.length == 1 ## EOF
- return
- elsif data[0] == 254 and data.length == 5
- return
- end
- rec = []
- field_count.times do
- len = get_length data
- if len == nil then
- rec << len
- else
- rec << data.slice!(0,len)
- end
- end
- rec
- end
-
- def skip_result()
- if @status == :STATUS_USE_RESULT then
- loop do
- data = read
- break if data[0] == 254 and data.length == 1
- end
- @status = :STATUS_READY
- end
- end
-
- def inspect()
- "#<#{self.class}>"
- end
-
- private
-
- def read_query_result()
- data = read
- @field_count = get_length(data)
- if @field_count == nil then # LOAD DATA LOCAL INFILE
- File::open(data) do |f|
- write f.read
- end
- write "" # mark EOF
- data = read
- @field_count = get_length(data)
- end
- if @field_count == 0 then
- @affected_rows = get_length(data, true)
- @insert_id = get_length(data, true)
- if @server_capabilities & CLIENT_TRANSACTIONS != 0 then
- a = data.slice!(0,2)
- @server_status = a[0]+a[1]*256
- end
- if data.size > 0 and get_length(data) then
- @info = data
- end
- else
- @extra_info = get_length(data, true)
- if @pre_411
- fields = read_rows(5)
- else
- fields = read_rows(7)
- end
- @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
- @status = :STATUS_GET_RESULT
- end
- self
- end
-
- def unpack_fields(data, long_flag_protocol)
- ret = []
- data.each do |f|
- if @pre_411
- table = org_table = f[0]
- name = f[1]
- length = f[2][0]+f[2][1]*256+f[2][2]*256*256
- type = f[3][0]
- if long_flag_protocol then
- flags = f[4][0]+f[4][1]*256
- decimals = f[4][2]
- else
- flags = f[4][0]
- decimals = f[4][1]
- end
- def_value = f[5]
- max_length = 0
- else
- catalog = f[0]
- db = f[1]
- table = f[2]
- org_table = f[3]
- name = f[4]
- org_name = f[5]
- length = f[6][2]+f[6][3]*256+f[6][4]*256*256
- type = f[6][6]
- flags = f[6][7]+f[6][8]*256
- decimals = f[6][9]
- def_value = ""
- max_length = 0
- end
- ret << Field::new(table, org_table, name, length, type, flags, decimals, def_value, max_length)
- end
- ret
- end
-
- def read_rows(field_count)
- ret = []
- while rec = read_one_row(field_count) do
- ret << rec
- end
- ret
- end
-
- def get_length(data, longlong=nil)
- return if data.length == 0
- c = data.slice!(0)
- case c
- when 251
- return nil
- when 252
- a = data.slice!(0,2)
- return a[0]+a[1]*256
- when 253
- a = data.slice!(0,3)
- return a[0]+a[1]*256+a[2]*256**2
- when 254
- a = data.slice!(0,8)
- if longlong then
- return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3+
- a[4]*256**4+a[5]*256**5+a[6]*256**6+a[7]*256**7
- else
- return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3
- end
- else
- c
- end
- end
-
- def command(cmd, arg=nil, skip_check=nil)
- unless @net then
- error Error::CR_SERVER_GONE_ERROR
- end
- if @status != :STATUS_READY then
- error Error::CR_COMMANDS_OUT_OF_SYNC
- end
- @net.clear
- write cmd.chr+(arg||"")
- read unless skip_check
- end
-
- def read()
- unless @net then
- error Error::CR_SERVER_GONE_ERROR
- end
- a = @net.read
- if a[0] == 255 then
- if a.length > 3 then
- @errno = a[1]+a[2]*256
- @error = a[3 .. -1]
- else
- @errno = Error::CR_UNKNOWN_ERROR
- @error = Error::err @errno
- end
- raise Error::new(@errno, @error)
- end
- a
- end
-
- def write(arg)
- unless @net then
- error Error::CR_SERVER_GONE_ERROR
- end
- @net.write arg
- end
-
- def hash_password(password)
- nr = 1345345333
- add = 7
- nr2 = 0x12345671
- password.each_byte do |i|
- next if i == 0x20 or i == 9
- nr ^= (((nr & 63) + add) * i) + (nr << 8)
- nr2 += (nr2 << 8) ^ nr
- add += i
- end
- [nr & ((1 << 31) - 1), nr2 & ((1 << 31) - 1)]
- end
-
- def scramble(password, message, old_ver)
- return "" if password == nil or password == ""
- raise "old version password is not implemented" if old_ver
- hash_pass = hash_password password
- hash_message = hash_password message.slice(0,SCRAMBLE_LENGTH_323)
- rnd = Random::new hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]
- to = []
- 1.upto(SCRAMBLE_LENGTH_323) do
- to << ((rnd.rnd*31)+64).floor
- end
- extra = (rnd.rnd*31).floor
- to.map! do |t| (t ^ extra).chr end
- to.join
- end
-
- def scramble41(password, message)
- return 0x00.chr if password.nil? or password.empty?
- buf = [0x14]
- s1 = Digest::SHA1.digest(password)
- s2 = Digest::SHA1.digest(s1)
- x = Digest::SHA1.digest(message + s2)
- (0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}
- buf.pack("C*")
- end
-
- def error(errno)
- @errno = errno
- @error = Error::err errno
- raise Error::new(@errno, @error)
- end
-
- class Result
- def initialize(mysql, fields, field_count, data=nil)
- @handle = mysql
- @fields = fields
- @field_count = field_count
- @data = data
- @current_field = 0
- @current_row = 0
- @eof = false
- @row_count = 0
- end
- attr_accessor :eof
-
- def data_seek(n)
- @current_row = n
- end
-
- def fetch_field()
- return if @current_field >= @field_count
- f = @fields[@current_field]
- @current_field += 1
- f
- end
-
- def fetch_fields()
- @fields
- end
-
- def fetch_field_direct(n)
- @fields[n]
- end
-
- def fetch_lengths()
- @data ? @data[@current_row].map{|i| i ? i.length : 0} : @lengths
- end
-
- def fetch_row()
- if @data then
- if @current_row >= @data.length then
- @handle.status = :STATUS_READY
- return
- end
- ret = @data[@current_row]
- @current_row += 1
- else
- return if @eof
- ret = @handle.read_one_row @field_count
- if ret == nil then
- @eof = true
- return
- end
- @lengths = ret.map{|i| i ? i.length : 0}
- @row_count += 1
- end
- ret
- end
-
- def fetch_hash(with_table=nil)
- row = fetch_row
- return if row == nil
- hash = {}
- @fields.each_index do |i|
- f = with_table ? @fields[i].table+"."+@fields[i].name : @fields[i].name
- hash[f] = row[i]
- end
- hash
- end
-
- def field_seek(n)
- @current_field = n
- end
-
- def field_tell()
- @current_field
- end
-
- def free()
- @handle.skip_result
- @handle = @fields = @data = nil
- end
-
- def num_fields()
- @field_count
- end
-
- def num_rows()
- @data ? @data.length : @row_count
- end
-
- def row_seek(n)
- @current_row = n
- end
-
- def row_tell()
- @current_row
- end
-
- def each()
- while row = fetch_row do
- yield row
- end
- end
-
- def each_hash(with_table=nil)
- while hash = fetch_hash(with_table) do
- yield hash
- end
- end
-
- def inspect()
- "#<#{self.class}>"
- end
-
- end
-
- class Field
- # Field type
- TYPE_DECIMAL = 0
- TYPE_TINY = 1
- TYPE_SHORT = 2
- TYPE_LONG = 3
- TYPE_FLOAT = 4
- TYPE_DOUBLE = 5
- TYPE_NULL = 6
- TYPE_TIMESTAMP = 7
- TYPE_LONGLONG = 8
- TYPE_INT24 = 9
- TYPE_DATE = 10
- TYPE_TIME = 11
- TYPE_DATETIME = 12
- TYPE_YEAR = 13
- TYPE_NEWDATE = 14
- TYPE_ENUM = 247
- TYPE_SET = 248
- TYPE_TINY_BLOB = 249
- TYPE_MEDIUM_BLOB = 250
- TYPE_LONG_BLOB = 251
- TYPE_BLOB = 252
- TYPE_VAR_STRING = 253
- TYPE_STRING = 254
- TYPE_GEOMETRY = 255
- TYPE_CHAR = TYPE_TINY
- TYPE_INTERVAL = TYPE_ENUM
-
- # Flag
- NOT_NULL_FLAG = 1
- PRI_KEY_FLAG = 2
- UNIQUE_KEY_FLAG = 4
- MULTIPLE_KEY_FLAG = 8
- BLOB_FLAG = 16
- UNSIGNED_FLAG = 32
- ZEROFILL_FLAG = 64
- BINARY_FLAG = 128
- ENUM_FLAG = 256
- AUTO_INCREMENT_FLAG = 512
- TIMESTAMP_FLAG = 1024
- SET_FLAG = 2048
- NUM_FLAG = 32768
- PART_KEY_FLAG = 16384
- GROUP_FLAG = 32768
- UNIQUE_FLAG = 65536
-
- def initialize(table, org_table, name, length, type, flags, decimals, def_value, max_length)
- @table = table
- @org_table = org_table
- @name = name
- @length = length
- @type = type
- @flags = flags
- @decimals = decimals
- @def = def_value
- @max_length = max_length
- if (type <= TYPE_INT24 and (type != TYPE_TIMESTAMP or length == 14 or length == 8)) or type == TYPE_YEAR then
- @flags |= NUM_FLAG
- end
- end
- attr_reader :table, :org_table, :name, :length, :type, :flags, :decimals, :def, :max_length
-
- def inspect()
- "#<#{self.class}:#{@name}>"
- end
- end
-
- class Error < StandardError
- # Server Error
- ER_HASHCHK = 1000
- ER_NISAMCHK = 1001
- ER_NO = 1002
- ER_YES = 1003
- ER_CANT_CREATE_FILE = 1004
- ER_CANT_CREATE_TABLE = 1005
- ER_CANT_CREATE_DB = 1006
- ER_DB_CREATE_EXISTS = 1007
- ER_DB_DROP_EXISTS = 1008
- ER_DB_DROP_DELETE = 1009
- ER_DB_DROP_RMDIR = 1010
- ER_CANT_DELETE_FILE = 1011
- ER_CANT_FIND_SYSTEM_REC = 1012
- ER_CANT_GET_STAT = 1013
- ER_CANT_GET_WD = 1014
- ER_CANT_LOCK = 1015
- ER_CANT_OPEN_FILE = 1016
- ER_FILE_NOT_FOUND = 1017
- ER_CANT_READ_DIR = 1018
- ER_CANT_SET_WD = 1019
- ER_CHECKREAD = 1020
- ER_DISK_FULL = 1021
- ER_DUP_KEY = 1022
- ER_ERROR_ON_CLOSE = 1023
- ER_ERROR_ON_READ = 1024
- ER_ERROR_ON_RENAME = 1025
- ER_ERROR_ON_WRITE = 1026
- ER_FILE_USED = 1027
- ER_FILSORT_ABORT = 1028
- ER_FORM_NOT_FOUND = 1029
- ER_GET_ERRNO = 1030
- ER_ILLEGAL_HA = 1031
- ER_KEY_NOT_FOUND = 1032
- ER_NOT_FORM_FILE = 1033
- ER_NOT_KEYFILE = 1034
- ER_OLD_KEYFILE = 1035
- ER_OPEN_AS_READONLY = 1036
- ER_OUTOFMEMORY = 1037
- ER_OUT_OF_SORTMEMORY = 1038
- ER_UNEXPECTED_EOF = 1039
- ER_CON_COUNT_ERROR = 1040
- ER_OUT_OF_RESOURCES = 1041
- ER_BAD_HOST_ERROR = 1042
- ER_HANDSHAKE_ERROR = 1043
- ER_DBACCESS_DENIED_ERROR = 1044
- ER_ACCESS_DENIED_ERROR = 1045
- ER_NO_DB_ERROR = 1046
- ER_UNKNOWN_COM_ERROR = 1047
- ER_BAD_NULL_ERROR = 1048
- ER_BAD_DB_ERROR = 1049
- ER_TABLE_EXISTS_ERROR = 1050
- ER_BAD_TABLE_ERROR = 1051
- ER_NON_UNIQ_ERROR = 1052
- ER_SERVER_SHUTDOWN = 1053
- ER_BAD_FIELD_ERROR = 1054
- ER_WRONG_FIELD_WITH_GROUP = 1055
- ER_WRONG_GROUP_FIELD = 1056
- ER_WRONG_SUM_SELECT = 1057
- ER_WRONG_VALUE_COUNT = 1058
- ER_TOO_LONG_IDENT = 1059
- ER_DUP_FIELDNAME = 1060
- ER_DUP_KEYNAME = 1061
- ER_DUP_ENTRY = 1062
- ER_WRONG_FIELD_SPEC = 1063
- ER_PARSE_ERROR = 1064
- ER_EMPTY_QUERY = 1065
- ER_NONUNIQ_TABLE = 1066
- ER_INVALID_DEFAULT = 1067
- ER_MULTIPLE_PRI_KEY = 1068
- ER_TOO_MANY_KEYS = 1069
- ER_TOO_MANY_KEY_PARTS = 1070
- ER_TOO_LONG_KEY = 1071
- ER_KEY_COLUMN_DOES_NOT_EXITS = 1072
- ER_BLOB_USED_AS_KEY = 1073
- ER_TOO_BIG_FIELDLENGTH = 1074
- ER_WRONG_AUTO_KEY = 1075
- ER_READY = 1076
- ER_NORMAL_SHUTDOWN = 1077
- ER_GOT_SIGNAL = 1078
- ER_SHUTDOWN_COMPLETE = 1079
- ER_FORCING_CLOSE = 1080
- ER_IPSOCK_ERROR = 1081
- ER_NO_SUCH_INDEX = 1082
- ER_WRONG_FIELD_TERMINATORS = 1083
- ER_BLOBS_AND_NO_TERMINATED = 1084
- ER_TEXTFILE_NOT_READABLE = 1085
- ER_FILE_EXISTS_ERROR = 1086
- ER_LOAD_INFO = 1087
- ER_ALTER_INFO = 1088
- ER_WRONG_SUB_KEY = 1089
- ER_CANT_REMOVE_ALL_FIELDS = 1090
- ER_CANT_DROP_FIELD_OR_KEY = 1091
- ER_INSERT_INFO = 1092
- ER_INSERT_TABLE_USED = 1093
- ER_NO_SUCH_THREAD = 1094
- ER_KILL_DENIED_ERROR = 1095
- ER_NO_TABLES_USED = 1096
- ER_TOO_BIG_SET = 1097
- ER_NO_UNIQUE_LOGFILE = 1098
- ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099
- ER_TABLE_NOT_LOCKED = 1100
- ER_BLOB_CANT_HAVE_DEFAULT = 1101
- ER_WRONG_DB_NAME = 1102
- ER_WRONG_TABLE_NAME = 1103
- ER_TOO_BIG_SELECT = 1104
- ER_UNKNOWN_ERROR = 1105
- ER_UNKNOWN_PROCEDURE = 1106
- ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
- ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108
- ER_UNKNOWN_TABLE = 1109
- ER_FIELD_SPECIFIED_TWICE = 1110
- ER_INVALID_GROUP_FUNC_USE = 1111
- ER_UNSUPPORTED_EXTENSION = 1112
- ER_TABLE_MUST_HAVE_COLUMNS = 1113
- ER_RECORD_FILE_FULL = 1114
- ER_UNKNOWN_CHARACTER_SET = 1115
- ER_TOO_MANY_TABLES = 1116
- ER_TOO_MANY_FIELDS = 1117
- ER_TOO_BIG_ROWSIZE = 1118
- ER_STACK_OVERRUN = 1119
- ER_WRONG_OUTER_JOIN = 1120
- ER_NULL_COLUMN_IN_INDEX = 1121
- ER_CANT_FIND_UDF = 1122
- ER_CANT_INITIALIZE_UDF = 1123
- ER_UDF_NO_PATHS = 1124
- ER_UDF_EXISTS = 1125
- ER_CANT_OPEN_LIBRARY = 1126
- ER_CANT_FIND_DL_ENTRY = 1127
- ER_FUNCTION_NOT_DEFINED = 1128
- ER_HOST_IS_BLOCKED = 1129
- ER_HOST_NOT_PRIVILEGED = 1130
- ER_PASSWORD_ANONYMOUS_USER = 1131
- ER_PASSWORD_NOT_ALLOWED = 1132
- ER_PASSWORD_NO_MATCH = 1133
- ER_UPDATE_INFO = 1134
- ER_CANT_CREATE_THREAD = 1135
- ER_WRONG_VALUE_COUNT_ON_ROW = 1136
- ER_CANT_REOPEN_TABLE = 1137
- ER_INVALID_USE_OF_NULL = 1138
- ER_REGEXP_ERROR = 1139
- ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
- ER_NONEXISTING_GRANT = 1141
- ER_TABLEACCESS_DENIED_ERROR = 1142
- ER_COLUMNACCESS_DENIED_ERROR = 1143
- ER_ILLEGAL_GRANT_FOR_TABLE = 1144
- ER_GRANT_WRONG_HOST_OR_USER = 1145
- ER_NO_SUCH_TABLE = 1146
- ER_NONEXISTING_TABLE_GRANT = 1147
- ER_NOT_ALLOWED_COMMAND = 1148
- ER_SYNTAX_ERROR = 1149
- ER_DELAYED_CANT_CHANGE_LOCK = 1150
- ER_TOO_MANY_DELAYED_THREADS = 1151
- ER_ABORTING_CONNECTION = 1152
- ER_NET_PACKET_TOO_LARGE = 1153
- ER_NET_READ_ERROR_FROM_PIPE = 1154
- ER_NET_FCNTL_ERROR = 1155
- ER_NET_PACKETS_OUT_OF_ORDER = 1156
- ER_NET_UNCOMPRESS_ERROR = 1157
- ER_NET_READ_ERROR = 1158
- ER_NET_READ_INTERRUPTED = 1159
- ER_NET_ERROR_ON_WRITE = 1160
- ER_NET_WRITE_INTERRUPTED = 1161
- ER_TOO_LONG_STRING = 1162
- ER_TABLE_CANT_HANDLE_BLOB = 1163
- ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
- ER_DELAYED_INSERT_TABLE_LOCKED = 1165
- ER_WRONG_COLUMN_NAME = 1166
- ER_WRONG_KEY_COLUMN = 1167
- ER_WRONG_MRG_TABLE = 1168
- ER_DUP_UNIQUE = 1169
- ER_BLOB_KEY_WITHOUT_LENGTH = 1170
- ER_PRIMARY_CANT_HAVE_NULL = 1171
- ER_TOO_MANY_ROWS = 1172
- ER_REQUIRES_PRIMARY_KEY = 1173
- ER_NO_RAID_COMPILED = 1174
- ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
- ER_KEY_DOES_NOT_EXITS = 1176
- ER_CHECK_NO_SUCH_TABLE = 1177
- ER_CHECK_NOT_IMPLEMENTED = 1178
- ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
- ER_ERROR_DURING_COMMIT = 1180
- ER_ERROR_DURING_ROLLBACK = 1181
- ER_ERROR_DURING_FLUSH_LOGS = 1182
- ER_ERROR_DURING_CHECKPOINT = 1183
- ER_NEW_ABORTING_CONNECTION = 1184
- ER_DUMP_NOT_IMPLEMENTED = 1185
- ER_FLUSH_MASTER_BINLOG_CLOSED = 1186
- ER_INDEX_REBUILD = 1187
- ER_MASTER = 1188
- ER_MASTER_NET_READ = 1189
- ER_MASTER_NET_WRITE = 1190
- ER_FT_MATCHING_KEY_NOT_FOUND = 1191
- ER_LOCK_OR_ACTIVE_TRANSACTION = 1192
- ER_UNKNOWN_SYSTEM_VARIABLE = 1193
- ER_CRASHED_ON_USAGE = 1194
- ER_CRASHED_ON_REPAIR = 1195
- ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196
- ER_TRANS_CACHE_FULL = 1197
- ER_SLAVE_MUST_STOP = 1198
- ER_SLAVE_NOT_RUNNING = 1199
- ER_BAD_SLAVE = 1200
- ER_MASTER_INFO = 1201
- ER_SLAVE_THREAD = 1202
- ER_TOO_MANY_USER_CONNECTIONS = 1203
- ER_SET_CONSTANTS_ONLY = 1204
- ER_LOCK_WAIT_TIMEOUT = 1205
- ER_LOCK_TABLE_FULL = 1206
- ER_READ_ONLY_TRANSACTION = 1207
- ER_DROP_DB_WITH_READ_LOCK = 1208
- ER_CREATE_DB_WITH_READ_LOCK = 1209
- ER_WRONG_ARGUMENTS = 1210
- ER_NO_PERMISSION_TO_CREATE_USER = 1211
- ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212
- ER_LOCK_DEADLOCK = 1213
- ER_TABLE_CANT_HANDLE_FULLTEXT = 1214
- ER_CANNOT_ADD_FOREIGN = 1215
- ER_NO_REFERENCED_ROW = 1216
- ER_ROW_IS_REFERENCED = 1217
- ER_CONNECT_TO_MASTER = 1218
- ER_QUERY_ON_MASTER = 1219
- ER_ERROR_WHEN_EXECUTING_COMMAND = 1220
- ER_WRONG_USAGE = 1221
- ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
- ER_CANT_UPDATE_WITH_READLOCK = 1223
- ER_MIXING_NOT_ALLOWED = 1224
- ER_DUP_ARGUMENT = 1225
- ER_USER_LIMIT_REACHED = 1226
- ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227
- ER_LOCAL_VARIABLE = 1228
- ER_GLOBAL_VARIABLE = 1229
- ER_NO_DEFAULT = 1230
- ER_WRONG_VALUE_FOR_VAR = 1231
- ER_WRONG_TYPE_FOR_VAR = 1232
- ER_VAR_CANT_BE_READ = 1233
- ER_CANT_USE_OPTION_HERE = 1234
- ER_NOT_SUPPORTED_YET = 1235
- ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236
- ER_SLAVE_IGNORED_TABLE = 1237
- ER_ERROR_MESSAGES = 238
-
- # Client Error
- CR_MIN_ERROR = 2000
- CR_MAX_ERROR = 2999
- CR_UNKNOWN_ERROR = 2000
- CR_SOCKET_CREATE_ERROR = 2001
- CR_CONNECTION_ERROR = 2002
- CR_CONN_HOST_ERROR = 2003
- CR_IPSOCK_ERROR = 2004
- CR_UNKNOWN_HOST = 2005
- CR_SERVER_GONE_ERROR = 2006
- CR_VERSION_ERROR = 2007
- CR_OUT_OF_MEMORY = 2008
- CR_WRONG_HOST_INFO = 2009
- CR_LOCALHOST_CONNECTION = 2010
- CR_TCP_CONNECTION = 2011
- CR_SERVER_HANDSHAKE_ERR = 2012
- CR_SERVER_LOST = 2013
- CR_COMMANDS_OUT_OF_SYNC = 2014
- CR_NAMEDPIPE_CONNECTION = 2015
- CR_NAMEDPIPEWAIT_ERROR = 2016
- CR_NAMEDPIPEOPEN_ERROR = 2017
- CR_NAMEDPIPESETSTATE_ERROR = 2018
- CR_CANT_READ_CHARSET = 2019
- CR_NET_PACKET_TOO_LARGE = 2020
- CR_EMBEDDED_CONNECTION = 2021
- CR_PROBE_SLAVE_STATUS = 2022
- CR_PROBE_SLAVE_HOSTS = 2023
- CR_PROBE_SLAVE_CONNECT = 2024
- CR_PROBE_MASTER_CONNECT = 2025
- CR_SSL_CONNECTION_ERROR = 2026
- CR_MALFORMED_PACKET = 2027
-
- CLIENT_ERRORS = [
- "Unknown MySQL error",
- "Can't create UNIX socket (%d)",
- "Can't connect to local MySQL server through socket '%-.64s' (%d)",
- "Can't connect to MySQL server on '%-.64s' (%d)",
- "Can't create TCP/IP socket (%d)",
- "Unknown MySQL Server Host '%-.64s' (%d)",
- "MySQL server has gone away",
- "Protocol mismatch. Server Version = %d Client Version = %d",
- "MySQL client run out of memory",
- "Wrong host info",
- "Localhost via UNIX socket",
- "%-.64s via TCP/IP",
- "Error in server handshake",
- "Lost connection to MySQL server during query",
- "Commands out of sync; You can't run this command now",
- "%-.64s via named pipe",
- "Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'",
- "Embedded server",
- "Error on SHOW SLAVE STATUS:",
- "Error on SHOW SLAVE HOSTS:",
- "Error connecting to slave:",
- "Error connecting to master:",
- "SSL connection error",
- "Malformed packet"
- ]
-
- def initialize(errno, error)
- @errno = errno
- @error = error
- super error
- end
- attr_reader :errno, :error
-
- def Error::err(errno)
- CLIENT_ERRORS[errno - Error::CR_MIN_ERROR]
- end
- end
-
- class Net
- def initialize(sock)
- @sock = sock
- @pkt_nr = 0
- end
-
- def clear()
- @pkt_nr = 0
- end
-
- def read()
- buf = []
- len = nil
- @sock.sync = false
- while len == nil or len == MAX_PACKET_LENGTH do
- a = @sock.read(4)
- len = a[0]+a[1]*256+a[2]*256*256
- pkt_nr = a[3]
- if @pkt_nr != pkt_nr then
- raise "Packets out of order: #{@pkt_nr}<>#{pkt_nr}"
- end
- @pkt_nr = @pkt_nr + 1 & 0xff
- buf << @sock.read(len)
- end
- @sock.sync = true
- buf.join
- rescue
- errno = Error::CR_SERVER_LOST
- raise Error::new(errno, Error::err(errno))
- end
-
- def write(data)
- if data.is_a? Array then
- data = data.join
- end
- @sock.sync = false
- ptr = 0
- while data.length >= MAX_PACKET_LENGTH do
- @sock.write Net::int3str(MAX_PACKET_LENGTH)+@pkt_nr.chr+data[ptr, MAX_PACKET_LENGTH]
- @pkt_nr = @pkt_nr + 1 & 0xff
- ptr += MAX_PACKET_LENGTH
- end
- @sock.write Net::int3str(data.length-ptr)+@pkt_nr.chr+data[ptr .. -1]
- @pkt_nr = @pkt_nr + 1 & 0xff
- @sock.sync = true
- @sock.flush
- rescue
- errno = Error::CR_SERVER_LOST
- raise Error::new(errno, Error::err(errno))
- end
-
- def close()
- @sock.close
- end
-
- def Net::int2str(n)
- [n].pack("v")
- end
-
- def Net::int3str(n)
- [n%256, n>>8].pack("cv")
- end
-
- def Net::int4str(n)
- [n].pack("V")
- end
-
- end
-
- class Random
- def initialize(seed1, seed2)
- @max_value = 0x3FFFFFFF
- @seed1 = seed1 % @max_value
- @seed2 = seed2 % @max_value
- end
-
- def rnd()
- @seed1 = (@seed1*3+@seed2) % @max_value
- @seed2 = (@seed1+@seed2+33) % @max_value
- @seed1.to_f / @max_value
- end
- end
-
-end
-
-class << Mysql
- def init()
- Mysql::new :INIT
- end
-
- def real_connect(*args)
- Mysql::new(*args)
- end
- alias :connect :real_connect
-
- def finalizer(net)
- proc {
- net.clear
- begin
- net.write(Mysql::COM_QUIT.chr)
- net.close
- rescue # Ignore IOError if socket is already closed.
- end
- }
- end
-
- def escape_string(str)
- str.gsub(/([\0\n\r\032\'\"\\])/) do
- case $1
- when "\0" then "\\0"
- when "\n" then "\\n"
- when "\r" then "\\r"
- when "\032" then "\\Z"
- else "\\"+$1
- end
- end
- end
- alias :quote :escape_string
-
- def get_client_info()
- Mysql::VERSION
- end
- alias :client_info :get_client_info
-
- def debug(str)
- raise "not implemented"
- end
-end
-
-#
-# for compatibility
-#
-
-MysqlRes = Mysql::Result
-MysqlField = Mysql::Field
-MysqlError = Mysql::Error
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index e0da8bfb7a..9c718c4fef 100755
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -409,4 +409,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
sponsor.sponsorable = new_member
assert_equal nil, sponsor.sponsorable_id
end
+
+ def test_save_fails_for_invalid_belongs_to
+ assert log = AuditLog.create(:developer_id=>0,:message=>"")
+
+ log.developer = Developer.new
+ assert !log.developer.valid?
+ assert !log.valid?
+ assert !log.save
+ assert_equal "is invalid", log.errors.on("developer")
+ end
+
+ def test_save_succeeds_for_invalid_belongs_to_with_validate_false
+ assert log = AuditLog.create(:developer_id=>0,:message=>"")
+
+ log.unvalidated_developer = Developer.new
+ assert !log.unvalidated_developer.valid?
+ assert log.valid?
+ assert log.save
+ end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 3a3358e39b..f65ada550b 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -14,11 +14,14 @@ require 'models/job'
require 'models/subscriber'
require 'models/subscription'
require 'models/book'
+require 'models/developer'
+require 'models/project'
class EagerAssociationTest < ActiveRecord::TestCase
fixtures :posts, :comments, :authors, :categories, :categories_posts,
:companies, :accounts, :tags, :taggings, :people, :readers,
- :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books
+ :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
+ :developers, :projects
def test_loading_with_one_association
posts = Post.find(:all, :include => :comments)
@@ -609,4 +612,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
Comment.find :all, :include => :post
end
end
+
+ def test_conditions_on_join_table_with_include_and_limit
+ assert_equal 3, Developer.find(:all, :include => 'projects', :conditions => 'developers_projects.access_level = 1', :limit => 5).size
+ end
+
+ def test_order_on_join_table_with_include_and_limit
+ assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index dbfa025efb..b638143c5a 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -37,15 +37,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_counting_with_single_conditions
- assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
+ assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => ['name=?', "Microsoft"])
end
def test_counting_with_single_hash
- assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
+ assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => {:name => "Microsoft"})
end
def test_counting_with_column_name_and_hash
- assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
+ assert_equal 2, Firm.find(:first).plain_clients.count(:name)
end
def test_finding
@@ -342,6 +342,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert new_firm.new_record?
end
+ def test_invalid_adding_with_validate_false
+ firm = Firm.find(:first)
+ client = Client.new
+ firm.unvalidated_clients_of_firm << Client.new
+
+ assert firm.valid?
+ assert !client.valid?
+ assert firm.save
+ assert client.new_record?
+ end
+
def test_build
company = companies(:first_firm)
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index abc7ee7e9d..d3ca0cae41 100755
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -275,6 +275,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal "is invalid", firm.errors.on("account")
end
+
+ def test_save_succeeds_for_invalid_has_one_with_validate_false
+ firm = Firm.find(:first)
+ assert firm.valid?
+
+ firm.unvalidated_account = Account.new
+
+ assert !firm.unvalidated_account.valid?
+ assert firm.valid?
+ assert firm.save
+ end
+
def test_assignment_before_either_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.new("credit_limit" => 1000)
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index aefb13ea9a..754fd58f35 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -1,6 +1,7 @@
require "cases/helper"
require 'models/company'
require 'models/topic'
+require 'models/edge'
Company.has_many :accounts
@@ -274,4 +275,49 @@ class CalculationsTest < ActiveRecord::TestCase
def test_should_sum_expression
assert_equal 636, Account.sum("2 * credit_limit")
end
+
+ def test_count_with_from_option
+ assert_equal Company.count(:all), Company.count(:all, :from => 'companies')
+ assert_equal Account.count(:all, :conditions => "credit_limit = 50"),
+ Account.count(:all, :from => 'accounts', :conditions => "credit_limit = 50")
+ assert_equal Company.count(:type, :conditions => {:type => "Firm"}),
+ Company.count(:type, :conditions => {:type => "Firm"}, :from => 'companies')
+ end
+
+ def test_sum_with_from_option
+ assert_equal Account.sum(:credit_limit), Account.sum(:credit_limit, :from => 'accounts')
+ assert_equal Account.sum(:credit_limit, :conditions => "credit_limit > 50"),
+ Account.sum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
+ end
+
+ def test_average_with_from_option
+ assert_equal Account.average(:credit_limit), Account.average(:credit_limit, :from => 'accounts')
+ assert_equal Account.average(:credit_limit, :conditions => "credit_limit > 50"),
+ Account.average(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
+ end
+
+ def test_minimum_with_from_option
+ assert_equal Account.minimum(:credit_limit), Account.minimum(:credit_limit, :from => 'accounts')
+ assert_equal Account.minimum(:credit_limit, :conditions => "credit_limit > 50"),
+ Account.minimum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
+ end
+
+ def test_maximum_with_from_option
+ assert_equal Account.maximum(:credit_limit), Account.maximum(:credit_limit, :from => 'accounts')
+ assert_equal Account.maximum(:credit_limit, :conditions => "credit_limit > 50"),
+ Account.maximum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
+ end
+
+ def test_from_option_with_specified_index
+ if Edge.connection.adapter_name == 'MySQL'
+ assert_equal Edge.count(:all), Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)')
+ assert_equal Edge.count(:all, :conditions => 'sink_id < 5'),
+ Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)', :conditions => 'sink_id < 5')
+ end
+ end
+
+ def test_from_option_with_table_different_than_class
+ assert_equal Account.count(:all), Company.count(:all, :from => 'accounts')
+ end
+
end
diff --git a/activerecord/test/cases/database_statements_test.rb b/activerecord/test/cases/database_statements_test.rb
new file mode 100644
index 0000000000..6274d5250f
--- /dev/null
+++ b/activerecord/test/cases/database_statements_test.rb
@@ -0,0 +1,12 @@
+require "cases/helper"
+
+class DatabaseStatementsTest < ActiveRecord::TestCase
+ def setup
+ @connection = ActiveRecord::Base.connection
+ end
+
+ def test_insert_should_return_the_inserted_id
+ id = @connection.insert("INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)")
+ assert_not_nil id
+ end
+end
diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb
index ddcacacc3a..258f7c7a0f 100755
--- a/activerecord/test/cases/lifecycle_test.rb
+++ b/activerecord/test/cases/lifecycle_test.rb
@@ -2,6 +2,7 @@ require "cases/helper"
require 'models/topic'
require 'models/developer'
require 'models/reply'
+require 'models/minimalistic'
class Topic; def after_find() end end
class Developer; def after_find() end end
@@ -44,6 +45,14 @@ class TopicObserver < ActiveRecord::Observer
end
end
+class MinimalisticObserver < ActiveRecord::Observer
+ attr_reader :minimalistic
+
+ def after_find(minimalistic)
+ @minimalistic = minimalistic
+ end
+end
+
class MultiObserver < ActiveRecord::Observer
attr_reader :record
@@ -134,6 +143,14 @@ class LifecycleTest < ActiveRecord::TestCase
assert_equal developer.name, multi_observer.record.name
end
+ def test_observing_after_find_when_not_defined_on_the_model
+ observer = MinimalisticObserver.instance
+ assert_equal Minimalistic, MinimalisticObserver.observed_class
+
+ minimalistic = Minimalistic.find(1)
+ assert_equal minimalistic, observer.minimalistic
+ end
+
def test_invalid_observer
assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers }
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 8b4d232554..0c57b79401 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -160,9 +160,9 @@ class ReflectionTest < ActiveRecord::TestCase
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 20, Firm.reflect_on_all_associations.size
- assert_equal 16, Firm.reflect_on_all_associations(:has_many).size
- assert_equal 4, Firm.reflect_on_all_associations(:has_one).size
+ assert_equal 22, Firm.reflect_on_all_associations.size
+ assert_equal 17, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 5, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 70f83fa8e6..9fa810ac68 100755
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -26,6 +26,7 @@ class Firm < Company
"AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )"
has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id"
+ has_many :unvalidated_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :validate => false
has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :destroy
has_many :exclusively_dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all
has_many :limited_clients, :class_name => "Client", :order => "id", :limit => 1
@@ -46,7 +47,8 @@ class Firm < Company
has_many :plain_clients, :class_name => 'Client'
has_many :readonly_clients, :class_name => 'Client', :readonly => true
- has_one :account, :foreign_key => "firm_id", :dependent => :destroy
+ has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
+ has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id", :class_name=>'Account'
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
end
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index f77fd0e96d..9f26cacdec 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -56,7 +56,8 @@ class Developer < ActiveRecord::Base
end
class AuditLog < ActiveRecord::Base
- belongs_to :developer
+ belongs_to :developer, :validate => true
+ belongs_to :unvalidated_developer, :class_name => 'Developer'
end
DeveloperSalary = Struct.new(:amount)
diff --git a/activeresource/Rakefile b/activeresource/Rakefile
index 9fd0ec4921..89901292a5 100644
--- a/activeresource/Rakefile
+++ b/activeresource/Rakefile
@@ -45,6 +45,7 @@ Rake::RDocTask.new { |rdoc|
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/**/*.rb')
+ rdoc.rdoc_files.exclude('lib/activeresource.rb')
}
@@ -114,13 +115,13 @@ end
desc "Publish the beta gem"
task :pgem => [:package] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ `ssh wrath.rubyonrails.org './gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/ar", "doc").upload
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload
end
desc "Publish the release files to RubyForge."
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 55dacfdf06..347dbb82aa 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -988,7 +988,11 @@ module ActiveResource
self.class.const_get(resource_name)
end
rescue NameError
- resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
+ if self.class.const_defined?(resource_name)
+ resource = self.class.const_get(resource_name)
+ else
+ resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
+ end
resource.prefix = self.class.prefix
resource.site = self.class.site
resource
diff --git a/activeresource/test/base_test.rb b/activeresource/test/base_test.rb
index 9e2f6c1831..4addd52636 100644
--- a/activeresource/test/base_test.rb
+++ b/activeresource/test/base_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require "fixtures/person"
+require "fixtures/customer"
require "fixtures/street_address"
require "fixtures/beast"
@@ -15,6 +16,37 @@ class BaseTest < Test::Unit::TestCase
@people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
@addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses')
+ # - deep nested resource -
+ # - Luis (Customer)
+ # - JK (Customer::Friend)
+ # - Mateo (Customer::Friend::Brother)
+ # - Edith (Customer::Friend::Brother::Child)
+ # - Martha (Customer::Friend::Brother::Child)
+ # - Felipe (Customer::Friend::Brother)
+ # - Bryan (Customer::Friend::Brother::Child)
+ # - Luke (Customer::Friend::Brother::Child)
+ # - Eduardo (Customer::Friend)
+ # - Sebas (Customer::Friend::Brother)
+ # - Andres (Customer::Friend::Brother::Child)
+ # - Jorge (Customer::Friend::Brother::Child)
+ # - Elsa (Customer::Friend::Brother)
+ # - Natacha (Customer::Friend::Brother::Child)
+ # - Milena (Customer::Friend::Brother)
+ #
+ @luis = {:id => 1, :name => 'Luis',
+ :friends => [{:name => 'JK',
+ :brothers => [{:name => 'Mateo',
+ :children => [{:name => 'Edith'},{:name => 'Martha'}]},
+ {:name => 'Felipe',
+ :children => [{:name => 'Bryan'},{:name => 'Luke'}]}]},
+ {:name => 'Eduardo',
+ :brothers => [{:name => 'Sebas',
+ :children => [{:name => 'Andres'},{:name => 'Jorge'}]},
+ {:name => 'Elsa',
+ :children => [{:name => 'Natacha'}]},
+ {:name => 'Milena',
+ :children => []}]}]}.to_xml(:root => 'customer')
+
ActiveResource::HttpMock.respond_to do |mock|
mock.get "/people/1.xml", {}, @matz
mock.get "/people/2.xml", {}, @david
@@ -46,6 +78,8 @@ class BaseTest < Test::Unit::TestCase
mock.head "/people/1/addresses/2.xml", {}, nil, 404
mock.head "/people/2/addresses/1.xml", {}, nil, 404
mock.head "/people/Greg/addresses/1.xml", {}, nil, 200
+ # customer
+ mock.get "/customers/1.xml", {}, @luis
end
Person.user = nil
@@ -788,4 +822,18 @@ class BaseTest < Test::Unit::TestCase
matz = Person.find(1)
assert_equal '1', matz.to_param
end
+
+ def test_parse_deep_nested_resources
+ luis = Customer.find(1)
+ assert_kind_of Customer, luis
+ luis.friends.each do |friend|
+ assert_kind_of Customer::Friend, friend
+ friend.brothers.each do |brother|
+ assert_kind_of Customer::Friend::Brother, brother
+ brother.children.each do |child|
+ assert_kind_of Customer::Friend::Brother::Child, child
+ end
+ end
+ end
+ end
end
diff --git a/activeresource/test/fixtures/customer.rb b/activeresource/test/fixtures/customer.rb
new file mode 100644
index 0000000000..845d5d11cb
--- /dev/null
+++ b/activeresource/test/fixtures/customer.rb
@@ -0,0 +1,3 @@
+class Customer < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+end
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index c7739fd7e0..d87558aba9 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,13 @@
*Edge*
+* Added Array#second through Array#tenth as aliases for Array#[1] through Array#[9] [DHH]
+
+* Added test/do declaration style testing to ActiveSupport::TestCase [DHH via Jay Fields]
+
+* Added Object#present? which is equivalent to !Object#blank? [DHH]
+
+* Added Enumberable#many? to encapsulate collection.size > 1 [DHH]
+
* Add more standard Hash methods to ActiveSupport::OrderedHash [Steve Purcell]
* Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under ActiveSupport [Josh Peek]
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index 38ca03b658..74d2750011 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -36,8 +36,8 @@ Rake::RDocTask.new { |rdoc|
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/active_support.rb')
- rdoc.rdoc_files.include('lib/active_support/*.rb')
rdoc.rdoc_files.include('lib/active_support/**/*.rb')
+ rdoc.rdoc_files.exclude('lib/active_support/vendor/*')
}
spec = Gem::Specification.new do |s|
@@ -65,13 +65,13 @@ end
desc "Publish the beta gem"
task :pgem => [:package] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ `ssh wrath.rubyonrails.org './gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/as", "doc").upload
+ Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/as", "doc").upload
end
desc "Publish the release files to RubyForge."
@@ -119,7 +119,7 @@ namespace :tzinfo do
task :copy_definitions => :unpack_gem do
definitions_path = "#{destination_path}/tzinfo/definitions/"
mkdir_p definitions_path
- TimeZone::MAPPING.values.each do |zone|
+ ActiveSupport::TimeZone::MAPPING.values.each do |zone|
subdir = nil
if /\// === zone
subdir = zone.sub(/\w+$/, '')
@@ -172,4 +172,4 @@ namespace :tzinfo do
def excluded_classes
%w(country country_index_definition country_info country_timezone timezone_index_definition timezone_proxy tzdataparser)
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/core_ext/array/access.rb b/activesupport/lib/active_support/core_ext/array/access.rb
index 21a8584bb9..4ac95efdc7 100644
--- a/activesupport/lib/active_support/core_ext/array/access.rb
+++ b/activesupport/lib/active_support/core_ext/array/access.rb
@@ -20,6 +20,51 @@ module ActiveSupport #:nodoc:
def to(position)
self[0..position]
end
+
+ # Equal to self[1]
+ def second
+ self[1]
+ end
+
+ # Equal to self[2]
+ def third
+ self[2]
+ end
+
+ # Equal to self[3]
+ def fourth
+ self[3]
+ end
+
+ # Equal to self[4]
+ def fifth
+ self[4]
+ end
+
+ # Equal to self[5]
+ def sixth
+ self[5]
+ end
+
+ # Equal to self[6]
+ def seventh
+ self[6]
+ end
+
+ # Equal to self[7]
+ def eighth
+ self[7]
+ end
+
+ # Equal to self[8]
+ def ninth
+ self[8]
+ end
+
+ # Equal to self[9]
+ def tenth
+ self[9]
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/blank.rb b/activesupport/lib/active_support/core_ext/blank.rb
index dfe33162e8..4f8dc4e281 100644
--- a/activesupport/lib/active_support/core_ext/blank.rb
+++ b/activesupport/lib/active_support/core_ext/blank.rb
@@ -12,6 +12,11 @@ class Object
def blank?
respond_to?(:empty?) ? empty? : !self
end
+
+ # An object is present if it's not blank.
+ def present?
+ !blank?
+ end
end
class NilClass #:nodoc:
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index f1469aa0e3..9647797ec2 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -1,3 +1,5 @@
+require 'active_support/ordered_hash'
+
module Enumerable
# Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
@@ -18,10 +20,19 @@ module Enumerable
# "2006-02-24 -> Transcript, Transcript"
# "2006-02-23 -> Transcript"
def group_by
- inject ActiveSupport::OrderedHash.new do |grouped, element|
- (grouped[yield(element)] ||= []) << element
- grouped
+ assoc = ActiveSupport::OrderedHash.new
+
+ each do |element|
+ key = yield(element)
+
+ if assoc.has_key?(key)
+ assoc[key] << element
+ else
+ assoc[key] = [element]
+ end
end
+
+ assoc
end unless [].respond_to?(:group_by)
# Calculates a sum from the elements. Examples:
@@ -66,4 +77,9 @@ module Enumerable
accum
end
end
+
+ # Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1.
+ def many?
+ size > 1
+ end
end
diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb
index 8362cd880e..bc97fa35a6 100644
--- a/activesupport/lib/active_support/core_ext/hash/except.rb
+++ b/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -10,13 +10,14 @@ module ActiveSupport #:nodoc:
module Except
# Returns a new hash without the given keys.
def except(*keys)
- rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
- reject { |key,| rejected.include?(key) }
+ clone.except!(*keys)
end
# Replaces the hash without only the given keys.
def except!(*keys)
- replace(except(*keys))
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
+ keys.each { |key| delete(key) }
+ self
end
end
end
diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb
index 59ceaec696..9757054e43 100644
--- a/activesupport/lib/active_support/ordered_hash.rb
+++ b/activesupport/lib/active_support/ordered_hash.rb
@@ -12,6 +12,7 @@ module ActiveSupport
else
self << [key, value]
end
+ value
end
def [](key)
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index 67cde1556c..2fd02d5313 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -9,5 +9,14 @@ end
module ActiveSupport
class TestCase < Test::Unit::TestCase
+ # test "verify something" do
+ # ...
+ # end
+ def self.test(name, &block)
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
+ defined = instance_method(test_name) rescue false
+ raise "#{test_name} is already defined in #{self}" if defined
+ define_method(test_name, &block)
+ end
end
end
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb
new file mode 100644
index 0000000000..2317171467
--- /dev/null
+++ b/activesupport/lib/active_support/testing/performance.rb
@@ -0,0 +1,397 @@
+require 'rubygems'
+gem 'ruby-prof', '>= 0.6.1'
+require 'ruby-prof'
+
+require 'fileutils'
+require 'rails/version'
+
+module ActiveSupport
+ module Testing
+ module Performance
+ DEFAULTS =
+ if benchmark = ARGV.include?('--benchmark') # HAX for rake test
+ { :benchmark => true,
+ :runs => 10,
+ :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time],
+ :output => 'tmp/performance' }
+ else
+ { :benchmark => false,
+ :runs => 1,
+ :min_percent => 0.02,
+ :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time],
+ :formats => [:flat, :graph_html, :call_tree],
+ :output => 'tmp/performance' }
+ end
+
+ def self.included(base)
+ base.class_inheritable_hash :profile_options
+ base.profile_options = DEFAULTS.dup
+ end
+
+ def full_test_name
+ "#{self.class.name}##{method_name}"
+ end
+
+ def run(result)
+ return if method_name =~ /^default_test$/
+
+ yield(self.class::STARTED, name)
+ @_result = result
+
+ run_warmup
+ profile_options[:metrics].each do |metric_name|
+ if klass = Metrics[metric_name.to_sym]
+ run_profile(klass.new)
+ result.add_run
+ else
+ $stderr.puts '%20s: unsupported' % metric_name.to_s
+ end
+ end
+
+ yield(self.class::FINISHED, name)
+ end
+
+ def run_test(metric, mode)
+ run_callbacks :setup
+ setup
+ metric.send(mode) { __send__ @method_name }
+ rescue ::Test::Unit::AssertionFailedError => e
+ add_failure(e.message, e.backtrace)
+ rescue StandardError, ScriptError
+ add_error($!)
+ ensure
+ begin
+ teardown
+ run_callbacks :teardown, :enumerator => :reverse_each
+ rescue ::Test::Unit::AssertionFailedError => e
+ add_failure(e.message, e.backtrace)
+ rescue StandardError, ScriptError
+ add_error($!)
+ end
+ end
+
+ protected
+ def run_warmup
+ 5.times { GC.start }
+
+ time = Metrics::Time.new
+ run_test(time, :benchmark)
+ puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
+
+ 5.times { GC.start }
+ end
+
+ def run_profile(metric)
+ klass = profile_options[:benchmark] ? Benchmarker : Profiler
+ performer = klass.new(self, metric)
+
+ performer.run
+ puts performer.report
+ performer.record
+ end
+
+ class Performer
+ delegate :run_test, :profile_options, :full_test_name, :to => :@harness
+
+ def initialize(harness, metric)
+ @harness, @metric = harness, metric
+ end
+
+ def report
+ rate = @total / profile_options[:runs]
+ '%20s: %s/run' % [@metric.name, @metric.format(rate)]
+ end
+
+ protected
+ def output_filename
+ "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
+ end
+ end
+
+ class Benchmarker < Performer
+ def run
+ profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
+ @total = @metric.total
+ end
+
+ def record
+ avg = @metric.total / profile_options[:runs].to_i
+ now = Time.now.utc.xmlschema
+ with_output_file do |file|
+ file.puts "#{avg},#{now},#{environment}"
+ end
+ end
+
+ def environment
+ unless defined? @env
+ app = "#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
+
+ rails = Rails::VERSION::STRING
+ if File.directory?('vendor/rails/.git')
+ Dir.chdir('vendor/rails') do
+ rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
+ end
+ end
+
+ ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
+ ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
+
+ @env = [app, rails, ruby, RUBY_PLATFORM] * ','
+ end
+
+ @env
+ end
+
+ protected
+ HEADER = 'measurement,created_at,app,rails,ruby,platform'
+
+ def with_output_file
+ fname = output_filename
+
+ if new = !File.exist?(fname)
+ FileUtils.mkdir_p(File.dirname(fname))
+ end
+
+ File.open(fname, 'ab') do |file|
+ file.puts(HEADER) if new
+ yield file
+ end
+ end
+
+ def output_filename
+ "#{super}.csv"
+ end
+ end
+
+ class Profiler < Performer
+ def run
+ RubyProf.measure_mode = @metric.measure_mode
+ RubyProf.start
+ RubyProf.pause
+ profile_options[:runs].to_i.times { run_test(@metric, :profile) }
+ @data = RubyProf.stop
+ @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
+ end
+
+ def record
+ klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
+
+ klasses.each do |klass|
+ fname = output_filename(klass)
+ FileUtils.mkdir_p(File.dirname(fname))
+ File.open(fname, 'wb') do |file|
+ klass.new(@data).print(file, profile_options.slice(:min_percent))
+ end
+ end
+ end
+
+ protected
+ def output_filename(printer_class)
+ suffix =
+ case printer_class.name.demodulize
+ when 'FlatPrinter'; 'flat.txt'
+ when 'GraphPrinter'; 'graph.txt'
+ when 'GraphHtmlPrinter'; 'graph.html'
+ when 'CallTreePrinter'; 'tree.txt'
+ else printer_class.name.sub(/Printer$/, '').underscore
+ end
+
+ "#{super()}_#{suffix}"
+ end
+ end
+
+ module Metrics
+ def self.[](name)
+ klass = const_get(name.to_s.camelize)
+ klass if klass::Mode
+ rescue NameError
+ nil
+ end
+
+ class Base
+ attr_reader :total
+
+ def initialize
+ @total = 0
+ end
+
+ def name
+ @name ||= self.class.name.demodulize.underscore
+ end
+
+ def measure_mode
+ self.class::Mode
+ end
+
+ def measure
+ 0
+ end
+
+ def benchmark
+ with_gc_stats do
+ before = measure
+ yield
+ @total += (measure - before)
+ end
+ end
+
+ def profile
+ RubyProf.resume
+ yield
+ ensure
+ RubyProf.pause
+ end
+
+ protected
+ if GC.respond_to?(:enable_stats)
+ def with_gc_stats
+ GC.enable_stats
+ yield
+ ensure
+ GC.disable_stats
+ end
+ else
+ def with_gc_stats
+ yield
+ end
+ end
+ end
+
+ class Time < Base
+ def measure
+ ::Time.now.to_f
+ end
+
+ def format(measurement)
+ if measurement < 2
+ '%d ms' % (measurement * 1000)
+ else
+ '%.2f sec' % measurement
+ end
+ end
+ end
+
+ class ProcessTime < Time
+ Mode = RubyProf::PROCESS_TIME
+
+ def measure
+ RubyProf.measure_process_time
+ end
+ end
+
+ class WallTime < Time
+ Mode = RubyProf::WALL_TIME
+
+ def measure
+ RubyProf.measure_wall_time
+ end
+ end
+
+ class CpuTime < Time
+ Mode = RubyProf::CPU_TIME
+
+ def initialize(*args)
+ # FIXME: yeah my CPU is 2.33 GHz
+ RubyProf.cpu_frequency = 2.33e9
+ super
+ end
+
+ def measure
+ RubyProf.measure_cpu_time
+ end
+ end
+
+ class Memory < Base
+ Mode = RubyProf::MEMORY
+
+ # ruby-prof wrapper
+ if RubyProf.respond_to?(:measure_memory)
+ def measure
+ RubyProf.measure_memory / 1024.0
+ end
+
+ # Ruby 1.8 + adymo patch
+ elsif GC.respond_to?(:allocated_size)
+ def measure
+ GC.allocated_size / 1024.0
+ end
+
+ # Ruby 1.8 + lloyd patch
+ elsif GC.respond_to?(:heap_info)
+ def measure
+ GC.heap_info['heap_current_memory'] / 1024.0
+ end
+
+ # Ruby 1.9 unpatched
+ elsif GC.respond_to?(:malloc_allocated_size)
+ def measure
+ GC.malloc_allocated_size / 1024.0
+ end
+ end
+
+ def format(measurement)
+ '%.2f KB' % measurement
+ end
+ end
+
+ class Objects < Base
+ Mode = RubyProf::ALLOCATIONS
+
+ if RubyProf.respond_to?(:measure_allocations)
+ def measure
+ RubyProf.measure_allocations
+ end
+ elsif ObjectSpace.respond_to?(:allocated_objects)
+ def measure
+ ObjectSpace.allocated_objects
+ end
+ end
+
+ def format(measurement)
+ measurement.to_i.to_s
+ end
+ end
+
+ class GcRuns < Base
+ Mode = RubyProf::GC_RUNS
+
+ if RubyProf.respond_to?(:measure_gc_runs)
+ def measure
+ RubyProf.measure_gc_runs
+ end
+ elsif GC.respond_to?(:collections)
+ def measure
+ GC.collections
+ end
+ elsif GC.respond_to?(:heap_info)
+ def measure
+ GC.heap_info['num_gc_passes']
+ end
+ end
+
+ def format(measurement)
+ measurement.to_i.to_s
+ end
+ end
+
+ class GcTime < Base
+ Mode = RubyProf::GC_TIME
+
+ if RubyProf.respond_to?(:measure_gc_time)
+ def measure
+ RubyProf.measure_gc_time
+ end
+ elsif GC.respond_to?(:time)
+ def measure
+ GC.time
+ end
+ end
+
+ def format(measurement)
+ '%d ms' % (measurement / 1000)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb
index ed8e34510a..21d71eb92a 100644
--- a/activesupport/lib/active_support/testing/setup_and_teardown.rb
+++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb
@@ -10,19 +10,43 @@ module ActiveSupport
end
def self.included(base)
- base.send :include, ActiveSupport::Callbacks
- base.define_callbacks :setup, :teardown
+ base.class_eval do
+ include ActiveSupport::Callbacks
+ define_callbacks :setup, :teardown
+ if defined?(::Mini)
+ alias_method :run, :run_with_callbacks_and_miniunit
+ else
+ begin
+ require 'mocha'
+ alias_method :run, :run_with_callbacks_and_mocha
+ rescue LoadError
+ alias_method :run, :run_with_callbacks_and_testunit
+ end
+ end
+ end
+ end
+
+ def run_with_callbacks_and_miniunit(runner)
+ result = '.'
begin
- require 'mocha'
- base.alias_method_chain :run, :callbacks_and_mocha
- rescue LoadError
- base.alias_method_chain :run, :callbacks
+ run_callbacks :setup
+ result = super
+ rescue Exception => e
+ result = runner.puke(self.class, self.name, e)
+ ensure
+ begin
+ teardown
+ run_callbacks :teardown, :enumerator => :reverse_each
+ rescue Exception => e
+ result = runner.puke(self.class, self.name, e)
+ end
end
+ result
end
# This redefinition is unfortunate but test/unit shows us no alternative.
- def run_with_callbacks(result) #:nodoc:
+ def run_with_callbacks_and_testunit(result) #:nodoc:
return if @method_name.to_s == "default_test"
yield(Test::Unit::TestCase::STARTED, name)
diff --git a/activesupport/lib/active_support/vendor.rb b/activesupport/lib/active_support/vendor.rb
index cdbcedc75a..a02e42f791 100644
--- a/activesupport/lib/active_support/vendor.rb
+++ b/activesupport/lib/active_support/vendor.rb
@@ -20,7 +20,7 @@ rescue Gem::LoadError
end
begin
- gem 'tzinfo', '~> 0.3.8'
+ gem 'tzinfo', '~> 0.3.9'
rescue Gem::LoadError
- $:.unshift "#{File.dirname(__FILE__)}/vendor/tzinfo-0.3.8"
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/tzinfo-0.3.9"
end \ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb
deleted file mode 100644
index 32fa4123f1..0000000000
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-#--
-# Copyright (c) 2006 Philip Ross
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#++
-
-module TZInfo
-
- # Provides a method for getting Rationals for a timezone offset in seconds.
- # Pre-reduced rationals are returned for all the half-hour intervals between
- # -14 and +14 hours to avoid having to call gcd at runtime.
- module OffsetRationals #:nodoc:
- @@rational_cache = {
- -50400 => Rational(-7,12),
- -48600 => Rational(-9,16),
- -46800 => Rational(-13,24),
- -45000 => Rational(-25,48),
- -43200 => Rational(-1,2),
- -41400 => Rational(-23,48),
- -39600 => Rational(-11,24),
- -37800 => Rational(-7,16),
- -36000 => Rational(-5,12),
- -34200 => Rational(-19,48),
- -32400 => Rational(-3,8),
- -30600 => Rational(-17,48),
- -28800 => Rational(-1,3),
- -27000 => Rational(-5,16),
- -25200 => Rational(-7,24),
- -23400 => Rational(-13,48),
- -21600 => Rational(-1,4),
- -19800 => Rational(-11,48),
- -18000 => Rational(-5,24),
- -16200 => Rational(-3,16),
- -14400 => Rational(-1,6),
- -12600 => Rational(-7,48),
- -10800 => Rational(-1,8),
- -9000 => Rational(-5,48),
- -7200 => Rational(-1,12),
- -5400 => Rational(-1,16),
- -3600 => Rational(-1,24),
- -1800 => Rational(-1,48),
- 0 => Rational(0,1),
- 1800 => Rational(1,48),
- 3600 => Rational(1,24),
- 5400 => Rational(1,16),
- 7200 => Rational(1,12),
- 9000 => Rational(5,48),
- 10800 => Rational(1,8),
- 12600 => Rational(7,48),
- 14400 => Rational(1,6),
- 16200 => Rational(3,16),
- 18000 => Rational(5,24),
- 19800 => Rational(11,48),
- 21600 => Rational(1,4),
- 23400 => Rational(13,48),
- 25200 => Rational(7,24),
- 27000 => Rational(5,16),
- 28800 => Rational(1,3),
- 30600 => Rational(17,48),
- 32400 => Rational(3,8),
- 34200 => Rational(19,48),
- 36000 => Rational(5,12),
- 37800 => Rational(7,16),
- 39600 => Rational(11,24),
- 41400 => Rational(23,48),
- 43200 => Rational(1,2),
- 45000 => Rational(25,48),
- 46800 => Rational(13,24),
- 48600 => Rational(9,16),
- 50400 => Rational(7,12)}
-
- # Returns a Rational expressing the fraction of a day that offset in
- # seconds represents (i.e. equivalent to Rational(offset, 86400)).
- def rational_for_offset(offset)
- @@rational_cache[offset] || Rational(offset, 86400)
- end
- module_function :rational_for_offset
- end
-end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo.rb
index c8bdbeec5d..c8bdbeec5d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone.rb
index 5eccbdf0db..5eccbdf0db 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone_info.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone_info.rb
index f34fabc36a..a45d94554b 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone_info.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/data_timezone_info.rb
@@ -40,6 +40,8 @@ module TZInfo
super(identifier)
@offsets = {}
@transitions = []
+ @previous_offset = nil
+ @transitions_index = nil
end
# Defines a offset. The id uniquely identifies this offset within the
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Algiers.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Algiers.rb
index 8c5f25577f..8c5f25577f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Algiers.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Algiers.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Cairo.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Cairo.rb
index 6e6daf3522..6e6daf3522 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Cairo.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Cairo.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Casablanca.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Casablanca.rb
index 10d28e7613..dddf533f61 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Casablanca.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Casablanca.rb
@@ -31,6 +31,8 @@ module TZInfo
tz.transition 1978, 8, :o1, 271033200
tz.transition 1984, 3, :o3, 448243200
tz.transition 1985, 12, :o1, 504918000
+ tz.transition 2008, 6, :o2, 1212278400
+ tz.transition 2008, 9, :o1, 1222556400
end
end
end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Harare.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Harare.rb
index 070c95ae0f..070c95ae0f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Harare.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Harare.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Johannesburg.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Johannesburg.rb
index f0af0d8e33..f0af0d8e33 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Johannesburg.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Johannesburg.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Monrovia.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Monrovia.rb
index 40e711fa44..40e711fa44 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Monrovia.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Monrovia.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Nairobi.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Nairobi.rb
index 7b0a2f43be..7b0a2f43be 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Nairobi.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Africa/Nairobi.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/Buenos_Aires.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
index 7536f7553c..7536f7553c 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/San_Juan.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/San_Juan.rb
index a5413612ee..a5413612ee 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/San_Juan.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Argentina/San_Juan.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Bogota.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Bogota.rb
index ef96435c6a..ef96435c6a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Bogota.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Bogota.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Caracas.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Caracas.rb
index 27392a540a..27392a540a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Caracas.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Caracas.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chicago.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chicago.rb
index 0996857cf0..0996857cf0 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chicago.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chicago.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chihuahua.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chihuahua.rb
index 1710b57c79..1710b57c79 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chihuahua.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Chihuahua.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Denver.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Denver.rb
index 1c1efb5ff3..1c1efb5ff3 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Denver.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Denver.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Godthab.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Godthab.rb
index 1e05518b0d..1e05518b0d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Godthab.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Godthab.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Guatemala.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Guatemala.rb
index a2bf73401c..a2bf73401c 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Guatemala.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Guatemala.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Halifax.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Halifax.rb
index d25ae775b3..d25ae775b3 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Halifax.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Halifax.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Indiana/Indianapolis.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Indiana/Indianapolis.rb
index f1430f6c24..f1430f6c24 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Indiana/Indianapolis.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Indiana/Indianapolis.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Juneau.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Juneau.rb
index f646f3f54a..f646f3f54a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Juneau.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Juneau.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/La_Paz.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/La_Paz.rb
index 45c907899f..45c907899f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/La_Paz.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/La_Paz.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Lima.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Lima.rb
index af68ac29f7..af68ac29f7 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Lima.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Lima.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Los_Angeles.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Los_Angeles.rb
index 16007fd675..16007fd675 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Los_Angeles.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Los_Angeles.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mazatlan.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mazatlan.rb
index ba9e6efcf1..ba9e6efcf1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mazatlan.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mazatlan.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mexico_City.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mexico_City.rb
index 2347fce647..2347fce647 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mexico_City.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Mexico_City.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Monterrey.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Monterrey.rb
index 5816a9eab1..5816a9eab1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Monterrey.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Monterrey.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/New_York.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/New_York.rb
index 7d802bd2de..7d802bd2de 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/New_York.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/New_York.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Phoenix.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Phoenix.rb
index b514e0c0f9..b514e0c0f9 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Phoenix.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Phoenix.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Regina.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Regina.rb
index ebdb68814a..ebdb68814a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Regina.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Regina.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Santiago.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Santiago.rb
index 0287c9ebc4..0287c9ebc4 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Santiago.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Santiago.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/St_Johns.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/St_Johns.rb
index e4a3599d35..e4a3599d35 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/St_Johns.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/St_Johns.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Tijuana.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Tijuana.rb
index 423059da46..423059da46 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Tijuana.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/America/Tijuana.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Almaty.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Almaty.rb
index 9ee18970f1..9ee18970f1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Almaty.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Almaty.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baghdad.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baghdad.rb
index 774dca1587..774dca1587 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baghdad.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baghdad.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baku.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baku.rb
index e86340ebfa..e86340ebfa 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baku.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Baku.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Bangkok.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Bangkok.rb
index 139194e5e5..139194e5e5 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Bangkok.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Bangkok.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Chongqing.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Chongqing.rb
index 8c94b4ba86..8c94b4ba86 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Chongqing.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Chongqing.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Dhaka.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Dhaka.rb
index ccd0265503..ccd0265503 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Dhaka.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Dhaka.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Hong_Kong.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Hong_Kong.rb
index f1edd75ac8..f1edd75ac8 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Hong_Kong.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Hong_Kong.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Irkutsk.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Irkutsk.rb
index 2d47d9580b..2d47d9580b 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Irkutsk.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Irkutsk.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jakarta.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jakarta.rb
index cc58fa173b..cc58fa173b 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jakarta.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jakarta.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jerusalem.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jerusalem.rb
index 9b737b899e..9b737b899e 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jerusalem.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Jerusalem.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kabul.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kabul.rb
index 669c09790a..669c09790a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kabul.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kabul.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kamchatka.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kamchatka.rb
index 2f1690b3a9..2f1690b3a9 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kamchatka.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kamchatka.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Karachi.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Karachi.rb
index baa0d41d73..bd7656ef2f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Karachi.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Karachi.rb
@@ -21,6 +21,8 @@ module TZInfo
tz.transition 1971, 3, :o4, 38775600
tz.transition 2002, 4, :o5, 1018119660
tz.transition 2002, 10, :o4, 1033840860
+ tz.transition 2008, 5, :o5, 1212260400
+ tz.transition 2008, 8, :o4, 1220205600
end
end
end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Katmandu.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Katmandu.rb
index 37dbea1f41..37dbea1f41 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Katmandu.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Katmandu.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kolkata.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kolkata.rb
index 1b6ffbd59d..1b6ffbd59d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kolkata.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kolkata.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Krasnoyarsk.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Krasnoyarsk.rb
index d6c503c155..d6c503c155 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Krasnoyarsk.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Krasnoyarsk.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuala_Lumpur.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuala_Lumpur.rb
index 77a0c206fa..77a0c206fa 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuala_Lumpur.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuala_Lumpur.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuwait.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuwait.rb
index 5bd5283197..5bd5283197 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuwait.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Kuwait.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Magadan.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Magadan.rb
index 302093693e..302093693e 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Magadan.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Magadan.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Muscat.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Muscat.rb
index 604f651dfa..604f651dfa 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Muscat.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Muscat.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Novosibirsk.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Novosibirsk.rb
index a4e7796e75..a4e7796e75 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Novosibirsk.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Novosibirsk.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Rangoon.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Rangoon.rb
index 759b82d77a..759b82d77a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Rangoon.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Rangoon.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Riyadh.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Riyadh.rb
index 7add410620..7add410620 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Riyadh.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Riyadh.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Seoul.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Seoul.rb
index 795d2a75df..795d2a75df 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Seoul.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Seoul.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Shanghai.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Shanghai.rb
index 34b13d59ae..34b13d59ae 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Shanghai.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Shanghai.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Singapore.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Singapore.rb
index b323a78f74..b323a78f74 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Singapore.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Singapore.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Taipei.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Taipei.rb
index 3ba12108fb..3ba12108fb 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Taipei.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Taipei.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tashkent.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tashkent.rb
index c205c7934d..c205c7934d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tashkent.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tashkent.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tbilisi.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tbilisi.rb
index 15792a5651..15792a5651 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tbilisi.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tbilisi.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tehran.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tehran.rb
index d8df964a46..d8df964a46 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tehran.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tehran.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tokyo.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tokyo.rb
index 51c9e16421..51c9e16421 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tokyo.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Tokyo.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Ulaanbaatar.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Ulaanbaatar.rb
index 2854f5c5fd..2854f5c5fd 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Ulaanbaatar.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Ulaanbaatar.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Urumqi.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Urumqi.rb
index d793ff1341..d793ff1341 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Urumqi.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Urumqi.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Vladivostok.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Vladivostok.rb
index bd9e3d60ec..bd9e3d60ec 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Vladivostok.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Vladivostok.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yakutsk.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yakutsk.rb
index 56435a788f..56435a788f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yakutsk.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yakutsk.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yekaterinburg.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yekaterinburg.rb
index 8ef8df4a41..8ef8df4a41 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yekaterinburg.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yekaterinburg.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yerevan.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yerevan.rb
index e7f160861f..e7f160861f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yerevan.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Yerevan.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Azores.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Azores.rb
index 1bd16a75ac..1bd16a75ac 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Azores.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Azores.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Cape_Verde.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Cape_Verde.rb
index 61c8c15043..61c8c15043 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Cape_Verde.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/Cape_Verde.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/South_Georgia.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/South_Georgia.rb
index 6a4cbafb9f..6a4cbafb9f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/South_Georgia.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Atlantic/South_Georgia.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Adelaide.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Adelaide.rb
index c5d561cc1e..c5d561cc1e 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Adelaide.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Adelaide.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Brisbane.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Brisbane.rb
index dd85ddae94..dd85ddae94 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Brisbane.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Brisbane.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Darwin.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Darwin.rb
index 17de88124d..17de88124d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Darwin.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Darwin.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Hobart.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Hobart.rb
index 11384b9840..11384b9840 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Hobart.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Hobart.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Melbourne.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Melbourne.rb
index c1304488ea..c1304488ea 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Melbourne.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Melbourne.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Perth.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Perth.rb
index d9e66f14a8..d9e66f14a8 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Perth.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Perth.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Sydney.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Sydney.rb
index 9062bd7c3c..9062bd7c3c 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Sydney.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Australia/Sydney.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Etc/UTC.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Etc/UTC.rb
index 28b2c6a04c..28b2c6a04c 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Etc/UTC.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Etc/UTC.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Amsterdam.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Amsterdam.rb
index 2d0c95c4bc..2d0c95c4bc 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Amsterdam.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Amsterdam.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Athens.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Athens.rb
index 4e21e535ca..4e21e535ca 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Athens.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Athens.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Belgrade.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Belgrade.rb
index 4dbd893d75..4dbd893d75 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Belgrade.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Belgrade.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Berlin.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Berlin.rb
index de2e4d951c..de2e4d951c 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Berlin.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Berlin.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bratislava.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bratislava.rb
index 7a731a0b6a..7a731a0b6a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bratislava.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bratislava.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Brussels.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Brussels.rb
index 6b0a242944..6b0a242944 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Brussels.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Brussels.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bucharest.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bucharest.rb
index 521c3c932e..521c3c932e 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bucharest.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Bucharest.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Budapest.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Budapest.rb
index 1f3a9738b7..1f3a9738b7 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Budapest.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Budapest.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Copenhagen.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Copenhagen.rb
index 47cbaf14a7..47cbaf14a7 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Copenhagen.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Copenhagen.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Dublin.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Dublin.rb
index 0560bb5436..0560bb5436 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Dublin.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Dublin.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Helsinki.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Helsinki.rb
index 13a806bcc7..13a806bcc7 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Helsinki.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Helsinki.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Istanbul.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Istanbul.rb
index 8306c47536..8306c47536 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Istanbul.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Istanbul.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Kiev.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Kiev.rb
index 513d3308be..513d3308be 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Kiev.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Kiev.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Lisbon.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Lisbon.rb
index 1c6d2a3d30..1c6d2a3d30 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Lisbon.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Lisbon.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Ljubljana.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Ljubljana.rb
index a9828e6ef8..a9828e6ef8 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Ljubljana.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Ljubljana.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/London.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/London.rb
index 64ce41e900..64ce41e900 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/London.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/London.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Madrid.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Madrid.rb
index 1fb568239a..1fb568239a 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Madrid.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Madrid.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Minsk.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Minsk.rb
index fa15816cc8..fa15816cc8 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Minsk.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Minsk.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Moscow.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Moscow.rb
index ef269b675b..ef269b675b 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Moscow.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Moscow.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Paris.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Paris.rb
index e3236c0ba1..e3236c0ba1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Paris.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Paris.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Prague.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Prague.rb
index bcabee96c1..bcabee96c1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Prague.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Prague.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Riga.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Riga.rb
index 784837f758..784837f758 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Riga.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Riga.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Rome.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Rome.rb
index aa7b43d9d2..aa7b43d9d2 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Rome.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Rome.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sarajevo.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sarajevo.rb
index 068c5fe6ad..068c5fe6ad 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sarajevo.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sarajevo.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Skopje.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Skopje.rb
index 10b71f285e..10b71f285e 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Skopje.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Skopje.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sofia.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sofia.rb
index 38a70eceb9..38a70eceb9 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sofia.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Sofia.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Stockholm.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Stockholm.rb
index 43db70fa61..43db70fa61 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Stockholm.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Stockholm.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Tallinn.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Tallinn.rb
index de5a8569f3..de5a8569f3 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Tallinn.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Tallinn.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vienna.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vienna.rb
index 990aabab66..990aabab66 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vienna.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vienna.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vilnius.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vilnius.rb
index d89d095a75..d89d095a75 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vilnius.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Vilnius.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Warsaw.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Warsaw.rb
index 7fa51c2691..7fa51c2691 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Warsaw.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Warsaw.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Zagreb.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Zagreb.rb
index ecdd903d28..ecdd903d28 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Zagreb.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Europe/Zagreb.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Auckland.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Auckland.rb
index a524fd6b6b..a524fd6b6b 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Auckland.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Auckland.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Fiji.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Fiji.rb
index 5fe9bbd9a6..5fe9bbd9a6 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Fiji.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Fiji.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Guam.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Guam.rb
index d4c1a0a682..d4c1a0a682 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Guam.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Guam.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Honolulu.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Honolulu.rb
index 204b226537..204b226537 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Honolulu.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Honolulu.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Majuro.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Majuro.rb
index 32adad92c1..32adad92c1 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Majuro.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Majuro.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Midway.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Midway.rb
index 97784fcc10..97784fcc10 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Midway.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Midway.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Noumea.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Noumea.rb
index 70173db8ab..70173db8ab 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Noumea.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Noumea.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Pago_Pago.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Pago_Pago.rb
index c8fcd7d527..c8fcd7d527 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Pago_Pago.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Pago_Pago.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Port_Moresby.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Port_Moresby.rb
index f06cf6d54f..f06cf6d54f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Port_Moresby.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Port_Moresby.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Tongatapu.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Tongatapu.rb
index 7578d92f38..7578d92f38 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Tongatapu.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Pacific/Tongatapu.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/info_timezone.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/info_timezone.rb
index 001303c594..001303c594 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/info_timezone.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/info_timezone.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone.rb
index f8ec4fca87..f8ec4fca87 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone_info.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone_info.rb
index 8197ff3e81..8197ff3e81 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone_info.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/linked_timezone_info.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/offset_rationals.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/offset_rationals.rb
new file mode 100644
index 0000000000..c79eedb7ef
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/offset_rationals.rb
@@ -0,0 +1,95 @@
+#--
+# Copyright (c) 2006 Philip Ross
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#++
+
+module TZInfo
+
+ # Provides a method for getting Rationals for a timezone offset in seconds.
+ # Pre-reduced rationals are returned for all the half-hour intervals between
+ # -14 and +14 hours to avoid having to call gcd at runtime.
+ module OffsetRationals #:nodoc:
+ @@rational_cache = {
+ -50400 => Rational.send(:new!, -7,12),
+ -48600 => Rational.send(:new!, -9,16),
+ -46800 => Rational.send(:new!, -13,24),
+ -45000 => Rational.send(:new!, -25,48),
+ -43200 => Rational.send(:new!, -1,2),
+ -41400 => Rational.send(:new!, -23,48),
+ -39600 => Rational.send(:new!, -11,24),
+ -37800 => Rational.send(:new!, -7,16),
+ -36000 => Rational.send(:new!, -5,12),
+ -34200 => Rational.send(:new!, -19,48),
+ -32400 => Rational.send(:new!, -3,8),
+ -30600 => Rational.send(:new!, -17,48),
+ -28800 => Rational.send(:new!, -1,3),
+ -27000 => Rational.send(:new!, -5,16),
+ -25200 => Rational.send(:new!, -7,24),
+ -23400 => Rational.send(:new!, -13,48),
+ -21600 => Rational.send(:new!, -1,4),
+ -19800 => Rational.send(:new!, -11,48),
+ -18000 => Rational.send(:new!, -5,24),
+ -16200 => Rational.send(:new!, -3,16),
+ -14400 => Rational.send(:new!, -1,6),
+ -12600 => Rational.send(:new!, -7,48),
+ -10800 => Rational.send(:new!, -1,8),
+ -9000 => Rational.send(:new!, -5,48),
+ -7200 => Rational.send(:new!, -1,12),
+ -5400 => Rational.send(:new!, -1,16),
+ -3600 => Rational.send(:new!, -1,24),
+ -1800 => Rational.send(:new!, -1,48),
+ 0 => Rational.send(:new!, 0,1),
+ 1800 => Rational.send(:new!, 1,48),
+ 3600 => Rational.send(:new!, 1,24),
+ 5400 => Rational.send(:new!, 1,16),
+ 7200 => Rational.send(:new!, 1,12),
+ 9000 => Rational.send(:new!, 5,48),
+ 10800 => Rational.send(:new!, 1,8),
+ 12600 => Rational.send(:new!, 7,48),
+ 14400 => Rational.send(:new!, 1,6),
+ 16200 => Rational.send(:new!, 3,16),
+ 18000 => Rational.send(:new!, 5,24),
+ 19800 => Rational.send(:new!, 11,48),
+ 21600 => Rational.send(:new!, 1,4),
+ 23400 => Rational.send(:new!, 13,48),
+ 25200 => Rational.send(:new!, 7,24),
+ 27000 => Rational.send(:new!, 5,16),
+ 28800 => Rational.send(:new!, 1,3),
+ 30600 => Rational.send(:new!, 17,48),
+ 32400 => Rational.send(:new!, 3,8),
+ 34200 => Rational.send(:new!, 19,48),
+ 36000 => Rational.send(:new!, 5,12),
+ 37800 => Rational.send(:new!, 7,16),
+ 39600 => Rational.send(:new!, 11,24),
+ 41400 => Rational.send(:new!, 23,48),
+ 43200 => Rational.send(:new!, 1,2),
+ 45000 => Rational.send(:new!, 25,48),
+ 46800 => Rational.send(:new!, 13,24),
+ 48600 => Rational.send(:new!, 9,16),
+ 50400 => Rational.send(:new!, 7,12)}
+
+ # Returns a Rational expressing the fraction of a day that offset in
+ # seconds represents (i.e. equivalent to Rational(offset, 86400)).
+ def rational_for_offset(offset)
+ @@rational_cache[offset] || Rational(offset, 86400)
+ end
+ module_function :rational_for_offset
+ end
+end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/time_or_datetime.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/time_or_datetime.rb
index 264517f3ee..264517f3ee 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/time_or_datetime.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/time_or_datetime.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone.rb
index 04f2f2f0a5..f87fb6fb70 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone.rb
@@ -371,8 +371,8 @@ module TZInfo
# type as utc. Any timezone information in utc is ignored (it is treated as
# a UTC time).
def utc_to_local(utc)
- TimeOrDateTime.wrap(utc) {|utc|
- period_for_utc(utc).to_local(utc)
+ TimeOrDateTime.wrap(utc) {|wrapped|
+ period_for_utc(wrapped).to_local(wrapped)
}
end
@@ -410,14 +410,14 @@ module TZInfo
# single period to use to convert the time or return nil or an empty array
# to cause an AmbiguousTime exception to be raised.
def local_to_utc(local, dst = nil)
- TimeOrDateTime.wrap(local) {|local|
+ TimeOrDateTime.wrap(local) {|wrapped|
if block_given?
- period = period_for_local(local, dst) {|periods| yield periods }
+ period = period_for_local(wrapped, dst) {|periods| yield periods }
else
- period = period_for_local(local, dst)
+ period = period_for_local(wrapped, dst)
end
- period.to_utc(local)
+ period.to_utc(wrapped)
}
end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_definition.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_definition.rb
index 39ca8bfa53..39ca8bfa53 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_definition.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_definition.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_info.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_info.rb
index 68e38c35fb..68e38c35fb 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_info.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_info.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_offset_info.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_offset_info.rb
index 913c4164af..6a0bbca46f 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_offset_info.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_offset_info.rb
@@ -56,15 +56,15 @@ module TZInfo
# Converts a UTC DateTime to local time based on the offset of this period.
def to_local(utc)
- TimeOrDateTime.wrap(utc) {|utc|
- utc + @utc_total_offset
+ TimeOrDateTime.wrap(utc) {|wrapped|
+ wrapped + @utc_total_offset
}
end
# Converts a local DateTime to UTC based on the offset of this period.
def to_utc(local)
- TimeOrDateTime.wrap(local) {|local|
- local - @utc_total_offset
+ TimeOrDateTime.wrap(local) {|wrapped|
+ wrapped - @utc_total_offset
}
end
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_period.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_period.rb
index 00888fcfdc..00888fcfdc 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_period.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_period.rb
diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_transition_info.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_transition_info.rb
index 6ae1b7df97..3fecb24f0d 100644
--- a/activesupport/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_transition_info.rb
+++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/timezone_transition_info.rb
@@ -48,7 +48,7 @@ module TZInfo
# seconds since the epoch. If denominator is specified numerator_or_time
# and denominator are used to create a DateTime as follows:
#
- # DateTime.new!(Rational.new!(numerator_or_time, denominator), 0, Date::ITALY)
+ # DateTime.new!(Rational.send(:new!, numerator_or_time, denominator), 0, Date::ITALY)
#
# For performance reasons, the numerator and denominator must be specified
# in their lowest form.
@@ -70,7 +70,7 @@ module TZInfo
unless @denominator
@at = TimeOrDateTime.new(@numerator_or_time)
else
- r = Rational.new!(@numerator_or_time, @denominator)
+ r = Rational.send(:new!, @numerator_or_time, @denominator)
# Ruby 1.8.6 introduced new! and deprecated new0.
# Ruby 1.9.0 removed new0.
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 73fbeb8b6b..7563be44f8 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -13,6 +13,20 @@ class ArrayExtAccessTests < Test::Unit::TestCase
assert_equal %w( a b c ), %w( a b c d ).to(2)
assert_equal %w( a b c d ), %w( a b c d ).to(10)
end
+
+ def test_second_through_tenth
+ array = (1..10).to_a
+
+ assert_equal array[1], array.second
+ assert_equal array[2], array.third
+ assert_equal array[3], array.fourth
+ assert_equal array[4], array.fifth
+ assert_equal array[5], array.sixth
+ assert_equal array[6], array.seventh
+ assert_equal array[7], array.eighth
+ assert_equal array[8], array.ninth
+ assert_equal array[9], array.tenth
+ end
end
class ArrayExtToParamTests < Test::Unit::TestCase
diff --git a/activesupport/test/core_ext/blank_test.rb b/activesupport/test/core_ext/blank_test.rb
index 061d940383..00fea74639 100644
--- a/activesupport/test/core_ext/blank_test.rb
+++ b/activesupport/test/core_ext/blank_test.rb
@@ -16,4 +16,9 @@ class BlankTest < Test::Unit::TestCase
BLANK.each { |v| assert v.blank?, "#{v.inspect} should be blank" }
NOT.each { |v| assert !v.blank?, "#{v.inspect} should not be blank" }
end
+
+ def test_present
+ BLANK.each { |v| assert !v.present?, "#{v.inspect} should not be present" }
+ NOT.each { |v| assert v.present?, "#{v.inspect} should be present" }
+ end
end
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index f5facd54ad..fb9b9b8916 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -63,4 +63,10 @@ class EnumerableTests < Test::Unit::TestCase
assert_equal({ 5 => payments[0], 15 => payments[1], 10 => payments[2] },
payments.index_by { |p| p.price })
end
+
+ def test_several
+ assert ![].many?
+ assert ![ 1 ].many?
+ assert [ 1, 2 ].many?
+ end
end
diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb
index 1e75e18602..26a45af255 100644
--- a/activesupport/test/test_test.rb
+++ b/activesupport/test/test_test.rb
@@ -84,6 +84,12 @@ class SetupAndTeardownTest < Test::Unit::TestCase
assert_equal [:foo, :sentinel, :foo], self.class.teardown_callback_chain.map(&:method)
end
+ def setup
+ end
+
+ def teardown
+ end
+
protected
def reset_callback_record
@called_back = []
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 93f4f8fa28..27d4313862 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -6,6 +6,8 @@
* Plugins check for the gem init path (rails/init.rb) before the standard plugin init path (init.rb) [Jacek Becela]
+* Changed all generated tests to use the test/do declaration style [DHH]
+
* Wrapped Rails.env in StringInquirer so you can do Rails.env.development? [DHH]
* Fixed that RailsInfoController wasn't considering all requests local in development mode (Edgard Castro) [#310 state:resolved]
diff --git a/railties/Rakefile b/railties/Rakefile
index a1d1095c37..78fe8e6662 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -267,6 +267,7 @@ Rake::RDocTask.new { |rdoc|
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/*.rb')
+ rdoc.rdoc_files.include('lib/rails/*.rb')
rdoc.rdoc_files.include('lib/rails_generator/*.rb')
rdoc.rdoc_files.include('lib/commands/**/*.rb')
}
@@ -331,10 +332,15 @@ end
# Publishing -------------------------------------------------------
-desc "Publish the API documentation"
+desc "Publish the rails gem"
task :pgem => [:gem] do
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
+ Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
+ `ssh wrath.rubyonrails.org './gemupdate.sh'`
+end
+
+desc "Publish the API documentation"
+task :pdoc => :rdoc do
+ # railties API isn't separately published
end
desc "Publish the release files to RubyForge."
diff --git a/railties/configs/initializers/inflections.rb b/railties/configs/initializers/inflections.rb
index 09158b865c..d531b8bb82 100644
--- a/railties/configs/initializers/inflections.rb
+++ b/railties/configs/initializers/inflections.rb
@@ -2,7 +2,7 @@
# Add new inflection rules using the following format
# (all these examples are active by default):
-# Inflector.inflections do |inflect|
+# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
diff --git a/railties/helpers/performance_test.rb b/railties/helpers/performance_test.rb
new file mode 100644
index 0000000000..7c89816570
--- /dev/null
+++ b/railties/helpers/performance_test.rb
@@ -0,0 +1,8 @@
+require 'performance/test_helper'
+
+# Profiling results for each test method are written to tmp/performance.
+class BrowsingTest < ActionController::PerformanceTest
+ def test_homepage
+ get '/'
+ end
+end
diff --git a/railties/helpers/performance_test_helper.rb b/railties/helpers/performance_test_helper.rb
new file mode 100644
index 0000000000..3c4c7fb740
--- /dev/null
+++ b/railties/helpers/performance_test_helper.rb
@@ -0,0 +1,6 @@
+require 'test_helper'
+require 'action_controller/performance_test'
+
+ActionController::Base.perform_caching = true
+ActiveSupport::Dependencies.mechanism = :require
+Rails.logger.level = ActiveSupport::BufferedLogger::INFO
diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
index 2f2dd82682..80e8eabfd3 100644
--- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb
+++ b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
@@ -51,6 +51,8 @@ class AppGenerator < Rails::Generator::Base
m.template "helpers/application.rb", "app/controllers/application.rb", :assigns => { :app_name => @app_name, :app_secret => md5.hexdigest }
m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb"
m.template "helpers/test_helper.rb", "test/test_helper.rb"
+ m.template "helpers/performance_test_helper.rb", "test/performance/test_helper.rb"
+ m.template "helpers/performance_test.rb", "test/performance/browsing_test.rb"
# database.yml and routes.rb
m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
@@ -155,6 +157,7 @@ class AppGenerator < Rails::Generator::Base
test/fixtures
test/functional
test/integration
+ test/performance
test/unit
vendor
vendor/plugins
diff --git a/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb
index 38e0ae7123..62fa5d86fd 100644
--- a/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb
+++ b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class <%= class_name %>ControllerTest < ActionController::TestCase
# Replace this with your real tests.
- def test_truth
+ test "the truth" do
assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb b/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb
index 149b987d81..2c57158b1c 100644
--- a/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb
+++ b/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb
@@ -1,10 +1,10 @@
require 'test_helper'
class <%= class_name %>Test < ActionController::IntegrationTest
- # fixtures :your, :models
+ fixtures :all
# Replace this with your real tests.
- def test_truth
+ test "the truth" do
assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb
index 0b4b2ec60a..1b7bcfef08 100644
--- a/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb
+++ b/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class <%= class_name %>Test < ActionMailer::TestCase
tests <%= class_name %>
<% for action in actions -%>
- def test_<%= action %>
+ test "<%= action %>" do
@expected.subject = '<%= class_name %>#<%= action %>'
@expected.body = read_fixture('<%= action %>')
@expected.date = Time.now
@@ -14,7 +14,7 @@ class <%= class_name %>Test < ActionMailer::TestCase
<% end -%>
<% if actions.blank? -%>
# replace this with your real tests
- def test_truth
+ test "the truth" do
assert true
end
<% end -%>
diff --git a/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb
index 96bd34adab..3e0bc29d3a 100644
--- a/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb
+++ b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class <%= class_name %>Test < ActiveSupport::TestCase
# Replace this with your real tests.
- def test_truth
+ test "the truth" do
assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb
index 1faf8ed9ac..cae38e9a2a 100644
--- a/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb
+++ b/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class <%= class_name %>ObserverTest < Test::Unit::TestCase
# Replace this with your real tests.
- def test_truth
+ test "the truth" do
assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb
index 9028b84b7d..6ede6ef1d2 100644
--- a/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb
+++ b/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb
@@ -2,7 +2,7 @@ require 'test/unit'
class <%= class_name %>Test < Test::Unit::TestCase
# Replace this with your real tests.
- def test_this_plugin
- flunk
+ test "the truth" do
+ assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb
index fbb69fcca7..b1bb1dacbf 100644
--- a/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb
+++ b/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
# Replace this with your real tests.
- def test_truth
+ test "the truth" do
assert true
end
end
diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb
index 3b430a2061..2d9d635944 100644
--- a/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb
@@ -1,18 +1,18 @@
require 'test_helper'
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
- def test_should_get_index
+ test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:<%= table_name %>)
end
- def test_should_get_new
+ test "should get new" do
get :new
assert_response :success
end
- def test_should_create_<%= file_name %>
+ test "should create <%= file_name %>" do
assert_difference('<%= class_name %>.count') do
post :create, :<%= file_name %> => { }
end
@@ -20,22 +20,22 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
end
- def test_should_show_<%= file_name %>
+ test "should show <%= file_name %>" do
get :show, :id => <%= table_name %>(:one).id
assert_response :success
end
- def test_should_get_edit
+ test "should get edit" do
get :edit, :id => <%= table_name %>(:one).id
assert_response :success
end
- def test_should_update_<%= file_name %>
+ test "should update <%= file_name %>" do
put :update, :id => <%= table_name %>(:one).id, :<%= file_name %> => { }
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
end
- def test_should_destroy_<%= file_name %>
+ test "should destroy <%= file_name %>" do
assert_difference('<%= class_name %>.count', -1) do
delete :destroy, :id => <%= table_name %>(:one).id
end
diff --git a/railties/lib/tasks/databases.rake b/railties/lib/tasks/databases.rake
index 8077d0a401..75fba8b45a 100644
--- a/railties/lib/tasks/databases.rake
+++ b/railties/lib/tasks/databases.rake
@@ -264,13 +264,15 @@ namespace :db do
end
namespace :test do
- desc "Recreate the test database from the current environment's database schema"
- task :clone => %w(db:schema:dump db:test:purge) do
+ desc "Recreate the test database from the current schema.rb"
+ task :load => 'db:test:purge' do
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
ActiveRecord::Schema.verbose = false
Rake::Task["db:schema:load"].invoke
end
+ desc "Recreate the test database from the current environment's database schema"
+ task :clone => %w(db:schema:dump db:test:load)
desc "Recreate the test databases from the development structure"
task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
@@ -337,10 +339,10 @@ namespace :db do
end
end
- desc 'Prepare the test database and load the schema'
- task :prepare => %w(environment db:abort_if_pending_migrations) do
+ desc 'Check for pending migrations and load the test schema'
+ task :prepare => 'db:abort_if_pending_migrations' do
if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
- Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone" }[ActiveRecord::Base.schema_format]].invoke
+ Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:load" }[ActiveRecord::Base.schema_format]].invoke
end
end
end
diff --git a/railties/lib/tasks/testing.rake b/railties/lib/tasks/testing.rake
index cc2376cbb3..c8ba6eed94 100644
--- a/railties/lib/tasks/testing.rake
+++ b/railties/lib/tasks/testing.rake
@@ -103,6 +103,21 @@ namespace :test do
end
Rake::Task['test:integration'].comment = "Run the integration tests in test/integration"
+ Rake::TestTask.new(:benchmark => 'db:test:prepare') do |t|
+ t.libs << 'test'
+ t.pattern = 'test/performance/**/*_test.rb'
+ t.verbose = true
+ t.options = '-- --benchmark'
+ end
+ Rake::Task['test:benchmark'].comment = 'Benchmark the performance tests'
+
+ Rake::TestTask.new(:profile => 'db:test:prepare') do |t|
+ t.libs << 'test'
+ t.pattern = 'test/performance/**/*_test.rb'
+ t.verbose = true
+ end
+ Rake::Task['test:profile'].comment = 'Profile the performance tests'
+
Rake::TestTask.new(:plugins => :environment) do |t|
t.libs << "test"
diff --git a/railties/lib/test_help.rb b/railties/lib/test_help.rb
index 22ce9ab609..3cc61d7932 100644
--- a/railties/lib/test_help.rb
+++ b/railties/lib/test_help.rb
@@ -8,7 +8,6 @@ require 'test/unit'
require 'active_support/test_case'
require 'active_record/fixtures'
require 'action_controller/test_case'
-require 'action_controller/test_process'
require 'action_controller/integration'
require 'action_mailer/test_case' if defined?(ActionMailer)
@@ -25,4 +24,4 @@ begin
Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
rescue LoadError
# ruby-debug wasn't available so neither can the debugging be
-end \ No newline at end of file
+end
diff --git a/railties/lib/webrick_server.rb b/railties/lib/webrick_server.rb
index ad4ca926ba..2f60151b22 100644
--- a/railties/lib/webrick_server.rb
+++ b/railties/lib/webrick_server.rb
@@ -43,8 +43,6 @@ end
# can change this behavior by setting ActionController::Base.allow_concurrency
# to true.
class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
- REQUEST_MUTEX = Mutex.new
-
# Start the WEBrick server with the given options, mounting the
# DispatchServlet at <tt>/</tt>.
def self.dispatch(options = {})
@@ -73,15 +71,8 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
def service(req, res) #:nodoc:
unless handle_file(req, res)
- begin
- REQUEST_MUTEX.lock unless ActionController::Base.allow_concurrency
- unless handle_dispatch(req, res)
- raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- ensure
- unless ActionController::Base.allow_concurrency
- REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked?
- end
+ unless handle_dispatch(req, res)
+ raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
end
end
end