aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile9
-rw-r--r--Rakefile8
-rw-r--r--actionmailer/lib/action_mailer/base.rb7
-rw-r--r--actionmailer/lib/action_mailer/collector.rb12
-rw-r--r--actionmailer/lib/action_mailer/old_api.rb4
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb4
-rw-r--r--actionmailer/lib/action_mailer/railties/log_subscriber.rb6
-rw-r--r--actionmailer/test/abstract_unit.rb21
-rw-r--r--actionmailer/test/base_test.rb58
-rw-r--r--actionmailer/test/fixtures/base_mailer/explicit_multipart_with_one_template.erb1
-rw-r--r--actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb (renamed from actionmailer/test/fixtures/test_mailer/signed_up_with_url.erb)0
-rw-r--r--actionmailer/test/old_base/mail_layout_test.rb22
-rw-r--r--actionmailer/test/old_base/mail_service_test.rb6
-rw-r--r--actionmailer/test/old_base/url_test.rb16
-rw-r--r--actionpack/lib/abstract_controller/helpers.rb10
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb33
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb64
-rw-r--r--actionpack/lib/action_controller/base.rb1
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb28
-rw-r--r--actionpack/lib/action_controller/caching/fragments.rb14
-rw-r--r--actionpack/lib/action_controller/deprecated/base.rb2
-rw-r--r--actionpack/lib/action_controller/metal.rb14
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb9
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rack_delegation.rb6
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb2
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb2
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb2
-rw-r--r--actionpack/lib/action_controller/railtie.rb17
-rw-r--r--actionpack/lib/action_controller/railties/url_helpers.rb2
-rw-r--r--actionpack/lib/action_controller/test_case.rb103
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb1
-rw-r--r--actionpack/lib/action_dispatch/railtie.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing.rb1
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb53
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb26
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb52
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb18
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb41
-rw-r--r--actionpack/lib/action_view.rb4
-rw-r--r--actionpack/lib/action_view/base.rb67
-rw-r--r--actionpack/lib/action_view/context.rb2
-rw-r--r--actionpack/lib/action_view/helpers.rb50
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb49
-rw-r--r--actionpack/lib/action_view/helpers/cache_helper.rb23
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb32
-rw-r--r--actionpack/lib/action_view/helpers/deprecated_block_helpers.rb52
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb88
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb402
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb49
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb12
-rw-r--r--actionpack/lib/action_view/locale/en.yml51
-rw-r--r--actionpack/lib/action_view/lookup_context.rb105
-rw-r--r--actionpack/lib/action_view/railtie.rb12
-rw-r--r--actionpack/lib/action_view/render/layouts.rb17
-rw-r--r--actionpack/lib/action_view/render/rendering.rb13
-rw-r--r--actionpack/lib/action_view/template.rb24
-rw-r--r--actionpack/lib/action_view/template/error.rb24
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb19
-rw-r--r--actionpack/lib/action_view/template/resolver.rb45
-rw-r--r--actionpack/lib/action_view/test_case.rb29
-rw-r--r--actionpack/test/abstract_unit.rb54
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb13
-rw-r--r--actionpack/test/controller/base_test.rb39
-rw-r--r--actionpack/test/controller/caching_test.rb38
-rw-r--r--actionpack/test/controller/cookie_test.rb11
-rw-r--r--actionpack/test/controller/filters_test.rb4
-rw-r--r--actionpack/test/controller/integration_test.rb8
-rw-r--r--actionpack/test/controller/layout_test.rb16
-rw-r--r--actionpack/test/controller/mime_responds_test.rb2
-rw-r--r--actionpack/test/controller/new_base/bare_metal_test.rb27
-rw-r--r--actionpack/test/controller/new_base/metal_test.rb6
-rw-r--r--actionpack/test/controller/new_base/middleware_test.rb2
-rw-r--r--actionpack/test/controller/new_base/render_action_test.rb4
-rw-r--r--actionpack/test/controller/new_base/render_rjs_test.rb18
-rw-r--r--actionpack/test/controller/render_test.rb24
-rw-r--r--actionpack/test/dispatch/routing_test.rb58
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb7
-rw-r--r--actionpack/test/fixtures/functional_caching/_partial.erb4
-rw-r--r--actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb4
-rw-r--r--actionpack/test/fixtures/functional_caching/fragment_cached.html.erb2
-rw-r--r--actionpack/test/fixtures/functional_caching/inline_fragment_cached.html.erb2
-rw-r--r--actionpack/test/fixtures/layouts/block_with_layout.erb4
-rw-r--r--actionpack/test/fixtures/test/array_translation.erb1
-rw-r--r--actionpack/test/fixtures/test/deprecated_nested_layout.erb3
-rw-r--r--actionpack/test/fixtures/test/nested_layout.erb2
-rw-r--r--actionpack/test/fixtures/test/scoped_array_translation.erb1
-rw-r--r--actionpack/test/fixtures/test/using_layout_around_block.html.erb2
-rw-r--r--actionpack/test/lib/fixture_template.rb8
-rw-r--r--actionpack/test/template/active_model_helper_test.rb18
-rw-r--r--actionpack/test/template/body_parts_test.rb3
-rw-r--r--actionpack/test/template/capture_helper_test.rb106
-rw-r--r--actionpack/test/template/erb/form_for_test.rb11
-rw-r--r--actionpack/test/template/erb/helper.rb30
-rw-r--r--actionpack/test/template/erb/tag_helper_test.rb58
-rw-r--r--actionpack/test/template/javascript_helper_test.rb31
-rw-r--r--actionpack/test/template/lookup_context_test.rb45
-rw-r--r--actionpack/test/template/number_helper_i18n_test.rb128
-rw-r--r--actionpack/test/template/number_helper_test.rb295
-rw-r--r--actionpack/test/template/output_buffer_test.rb19
-rw-r--r--actionpack/test/template/render_test.rb10
-rw-r--r--actionpack/test/template/translation_helper_test.rb15
-rw-r--r--actionpack/test/template/url_helper_test.rb5
-rw-r--r--activemodel/lib/active_model/attribute_methods.rb18
-rw-r--r--activemodel/lib/active_model/callbacks.rb7
-rw-r--r--activemodel/lib/active_model/dirty.rb35
-rw-r--r--activemodel/lib/active_model/errors.rb3
-rw-r--r--activemodel/lib/active_model/serializers/xml.rb3
-rw-r--r--activemodel/lib/active_model/validations.rb4
-rw-r--r--activemodel/lib/active_model/validator.rb3
-rw-r--r--activemodel/test/cases/dirty_test.rb30
-rw-r--r--activerecord/activerecord.gemspec2
-rw-r--r--activerecord/lib/active_record/aggregations.rb5
-rwxr-xr-xactiverecord/lib/active_record/associations.rb39
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb1
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb4
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb18
-rwxr-xr-xactiverecord/lib/active_record/base.rb24
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb23
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb23
-rw-r--r--activerecord/lib/active_record/migration.rb2
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb7
-rw-r--r--activerecord/lib/active_record/railtie.rb5
-rw-r--r--activerecord/lib/active_record/railties/databases.rake8
-rw-r--r--activerecord/lib/active_record/railties/log_subscriber.rb7
-rw-r--r--activerecord/lib/active_record/relation.rb7
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb13
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb19
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb36
-rw-r--r--activerecord/lib/rails/generators/active_record.rb (renamed from activerecord/lib/generators/active_record.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/migration/migration_generator.rb (renamed from activerecord/lib/generators/active_record/migration/migration_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/migration/templates/migration.rb (renamed from activerecord/lib/generators/active_record/migration/templates/migration.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/model/model_generator.rb (renamed from activerecord/lib/generators/active_record/model/model_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/model/templates/migration.rb (renamed from activerecord/lib/generators/active_record/model/templates/migration.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/model/templates/model.rb (renamed from activerecord/lib/generators/active_record/model/templates/model.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/observer/observer_generator.rb (renamed from activerecord/lib/generators/active_record/observer/observer_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/observer/templates/observer.rb (renamed from activerecord/lib/generators/active_record/observer/templates/observer.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb (renamed from activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb (renamed from activerecord/lib/generators/active_record/session_migration/templates/migration.rb)0
-rw-r--r--activerecord/test/cases/active_schema_test_postgresql.rb7
-rw-r--r--activerecord/test/cases/adapter_test.rb27
-rw-r--r--activerecord/test/cases/associations/eager_test.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb9
-rw-r--r--activerecord/test/cases/associations/inner_join_association_test.rb4
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb12
-rwxr-xr-xactiverecord/test/cases/base_test.rb18
-rw-r--r--activerecord/test/cases/callbacks_test.rb13
-rw-r--r--activerecord/test/cases/defaults_test.rb4
-rw-r--r--activerecord/test/cases/dirty_test.rb5
-rw-r--r--activerecord/test/cases/finder_test.rb21
-rw-r--r--activerecord/test/cases/fixtures_test.rb12
-rw-r--r--activerecord/test/cases/json_serialization_test.rb2
-rw-r--r--activerecord/test/cases/lifecycle_test.rb40
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb10
-rw-r--r--activerecord/test/cases/method_scoping_test.rb2
-rw-r--r--activerecord/test/cases/migration_test.rb20
-rw-r--r--activerecord/test/cases/named_scope_test.rb4
-rw-r--r--activerecord/test/cases/query_cache_test.rb4
-rw-r--r--activerecord/test/cases/reflection_test.rb6
-rw-r--r--activerecord/test/cases/schema_authorization_test_postgresql.rb9
-rw-r--r--activerecord/test/cases/transactions_test.rb38
-rw-r--r--activerecord/test/cases/validations/i18n_validation_test.rb19
-rw-r--r--activeresource/lib/active_resource/base.rb49
-rw-r--r--activeresource/lib/active_resource/railtie.rb4
-rw-r--r--activeresource/test/setter_trap.rb2
-rw-r--r--activesupport/activesupport.gemspec4
-rw-r--r--activesupport/lib/active_support/core_ext/array/extract_options.rb17
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb60
-rw-r--r--activesupport/lib/active_support/core_ext/class/delegating_attributes.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/reporting.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb46
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/module/method_names.rb14
-rw-r--r--activesupport/lib/active_support/core_ext/module/remove_method.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/string/inflections.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb10
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb4
-rw-r--r--activesupport/lib/active_support/inflector/transliterate.rb4
-rw-r--r--activesupport/lib/active_support/multibyte.rb4
-rw-r--r--activesupport/lib/active_support/multibyte/utils.rb2
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb2
-rw-r--r--activesupport/lib/active_support/railtie.rb6
-rw-r--r--activesupport/lib/active_support/ruby/shim.rb1
-rw-r--r--activesupport/lib/active_support/test_case.rb3
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb4
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/test/abstract_unit.rb11
-rw-r--r--activesupport/test/callback_inheritance_test.rb1
-rw-r--r--activesupport/test/callbacks_test.rb2
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb34
-rw-r--r--activesupport/test/core_ext/class/attribute_accessor_test.rb8
-rw-r--r--activesupport/test/core_ext/class/delegating_attributes_test.rb22
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb4
-rw-r--r--activesupport/test/core_ext/module/attribute_accessor_test.rb6
-rw-r--r--activesupport/test/core_ext/module_test.rb14
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb2
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb4
-rw-r--r--activesupport/test/dependencies_test.rb2
-rw-r--r--activesupport/test/flush_cache_on_private_memoization_test.rb1
-rw-r--r--activesupport/test/inflector_test_cases.rb16
-rw-r--r--activesupport/test/notifications_test.rb6
-rw-r--r--activesupport/test/ts_isolated.rb2
-rwxr-xr-xci/ci_build.rb16
-rw-r--r--load_paths.rb8
-rw-r--r--railties/Rakefile8
-rw-r--r--railties/builtin/rails_info/rails/info_helper.rb2
-rw-r--r--railties/lib/generators/erb.rb8
-rw-r--r--railties/lib/generators/erb/mailer/mailer_generator.rb20
-rw-r--r--railties/lib/generators/test_unit/controller/templates/functional_test.rb8
-rw-r--r--railties/lib/generators/test_unit/mailer/templates/fixture3
-rw-r--r--railties/lib/rails.rb3
-rw-r--r--railties/lib/rails/application.rb3
-rw-r--r--railties/lib/rails/application/configuration.rb59
-rw-r--r--railties/lib/rails/application/finisher.rb4
-rw-r--r--railties/lib/rails/commands/application.rb2
-rw-r--r--railties/lib/rails/commands/dbconsole.rb12
-rw-r--r--railties/lib/rails/engine.rb8
-rw-r--r--railties/lib/rails/generators.rb4
-rw-r--r--railties/lib/rails/generators/base.rb12
-rw-r--r--railties/lib/rails/generators/erb.rb21
-rw-r--r--railties/lib/rails/generators/erb/controller/controller_generator.rb (renamed from railties/lib/generators/erb/controller/controller_generator.rb)9
-rw-r--r--railties/lib/rails/generators/erb/controller/templates/view.html.erb (renamed from railties/lib/generators/erb/controller/templates/view.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/mailer/mailer_generator.rb13
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/view.text.erb (renamed from railties/lib/generators/erb/mailer/templates/view.text.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb (renamed from railties/lib/generators/erb/scaffold/scaffold_generator.rb)40
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/_form.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/edit.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/index.html.erb)2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/layout.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/new.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb (renamed from railties/lib/generators/erb/scaffold/templates/show.html.erb)0
-rw-r--r--railties/lib/rails/generators/named_base.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/USAGE (renamed from railties/lib/generators/rails/app/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb (renamed from railties/lib/generators/rails/app/app_generator.rb)2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile (renamed from railties/lib/generators/rails/app/templates/Gemfile)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/README (renamed from railties/lib/generators/rails/app/templates/README)0
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/Rakefile (renamed from railties/lib/generators/rails/app/templates/Rakefile)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb (renamed from railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb (renamed from railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory (renamed from railties/lib/generators/rails/app/templates/app/models/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory (renamed from railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config.ru (renamed from railties/lib/generators/rails/app/templates/config.ru)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb (renamed from railties/lib/generators/rails/app/templates/config/application.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb (renamed from railties/lib/generators/rails/app/templates/config/boot.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/frontbase.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/mysql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/oracle.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/postgresql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml (renamed from railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environment.rb (renamed from railties/lib/generators/rails/app/templates/config/environment.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt (renamed from railties/lib/generators/rails/app/templates/config/environments/development.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt (renamed from railties/lib/generators/rails/app/templates/config/environments/production.rb.tt)9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt (renamed from railties/lib/generators/rails/app/templates/config/environments/test.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb (renamed from railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt (renamed from railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb (renamed from railties/lib/generators/rails/app/templates/config/initializers/inflections.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb (renamed from railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt (renamed from railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/locales/en.yml (renamed from railties/lib/generators/rails/app/templates/config/locales/en.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb (renamed from railties/lib/generators/rails/app/templates/config/routes.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/db/seeds.rb (renamed from railties/lib/generators/rails/app/templates/db/seeds.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP (renamed from railties/lib/generators/rails/app/templates/doc/README_FOR_APP)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore (renamed from railties/lib/generators/rails/app/templates/gitignore)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/404.html (renamed from railties/lib/generators/rails/app/templates/public/404.html)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/422.html (renamed from railties/lib/generators/rails/app/templates/public/422.html)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/500.html (renamed from railties/lib/generators/rails/app/templates/public/500.html)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/favicon.ico (renamed from railties/lib/generators/rails/app/templates/public/favicon.ico)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/images/rails.png (renamed from railties/lib/generators/rails/app/templates/public/images/rails.png)bin6646 -> 6646 bytes
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/index.html (renamed from railties/lib/generators/rails/app/templates/public/index.html)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/application.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/controls.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/effects.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/prototype.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js (renamed from railties/lib/generators/rails/app/templates/public/javascripts/rails.js)3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/robots.txt (renamed from railties/lib/generators/rails/app/templates/public/robots.txt)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory (renamed from railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/script/rails (renamed from railties/lib/generators/rails/app/templates/script/rails)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory (renamed from railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory (renamed from railties/lib/generators/rails/app/templates/test/functional/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory (renamed from railties/lib/generators/rails/app/templates/test/integration/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb (renamed from railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/test_helper.rb (renamed from railties/lib/generators/rails/app/templates/test/test_helper.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory (renamed from railties/lib/generators/rails/app/templates/test/unit/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/controller/USAGE (renamed from railties/lib/generators/rails/controller/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/controller/controller_generator.rb (renamed from railties/lib/generators/rails/controller/controller_generator.rb)6
-rw-r--r--railties/lib/rails/generators/rails/controller/templates/controller.rb (renamed from railties/lib/generators/rails/controller/templates/controller.rb)0
-rw-r--r--railties/lib/rails/generators/rails/generator/USAGE (renamed from railties/lib/generators/rails/generator/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/generator/generator_generator.rb (renamed from railties/lib/generators/rails/generator/generator_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt (renamed from railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/generator/templates/USAGE.tt (renamed from railties/lib/generators/rails/generator/templates/USAGE.tt)0
-rw-r--r--railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory (renamed from railties/lib/generators/rails/generator/templates/templates/.empty_directory)0
-rw-r--r--railties/lib/rails/generators/rails/helper/USAGE (renamed from railties/lib/generators/rails/helper/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/helper/helper_generator.rb (renamed from railties/lib/generators/rails/helper/helper_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/helper/templates/helper.rb (renamed from railties/lib/generators/rails/helper/templates/helper.rb)0
-rw-r--r--railties/lib/rails/generators/rails/integration_test/USAGE (renamed from railties/lib/generators/rails/integration_test/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb (renamed from railties/lib/generators/rails/integration_test/integration_test_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/mailer/USAGE (renamed from railties/lib/generators/rails/mailer/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/mailer/mailer_generator.rb (renamed from railties/lib/generators/rails/mailer/mailer_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/mailer/templates/mailer.rb (renamed from railties/lib/generators/rails/mailer/templates/mailer.rb)0
-rw-r--r--railties/lib/rails/generators/rails/metal/USAGE (renamed from railties/lib/generators/rails/metal/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/metal/metal_generator.rb (renamed from railties/lib/generators/rails/metal/metal_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/metal/templates/metal.rb (renamed from railties/lib/generators/rails/metal/templates/metal.rb)0
-rw-r--r--railties/lib/rails/generators/rails/migration/USAGE (renamed from railties/lib/generators/rails/migration/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/migration/migration_generator.rb (renamed from railties/lib/generators/rails/migration/migration_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE (renamed from railties/lib/generators/rails/model/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/model/model_generator.rb (renamed from railties/lib/generators/rails/model/model_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb (renamed from railties/lib/generators/rails/model_subclass/model_subclass_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/observer/USAGE (renamed from railties/lib/generators/rails/observer/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/observer/observer_generator.rb (renamed from railties/lib/generators/rails/observer/observer_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/performance_test/USAGE (renamed from railties/lib/generators/rails/performance_test/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb (renamed from railties/lib/generators/rails/performance_test/performance_test_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/USAGE (renamed from railties/lib/generators/rails/plugin/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb (renamed from railties/lib/generators/rails/plugin/plugin_generator.rb)2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt (renamed from railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/README.tt (renamed from railties/lib/generators/rails/plugin/templates/README.tt)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt (renamed from railties/lib/generators/rails/plugin/templates/Rakefile.tt)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/init.rb (renamed from railties/lib/generators/rails/plugin/templates/init.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/install.rb (renamed from railties/lib/generators/rails/plugin/templates/install.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt (renamed from railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt (renamed from railties/lib/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/uninstall.rb (renamed from railties/lib/generators/rails/plugin/templates/uninstall.rb)0
-rw-r--r--railties/lib/rails/generators/rails/resource/USAGE (renamed from railties/lib/generators/rails/resource/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb (renamed from railties/lib/generators/rails/resource/resource_generator.rb)3
-rw-r--r--railties/lib/rails/generators/rails/scaffold/USAGE (renamed from railties/lib/generators/rails/scaffold/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb (renamed from railties/lib/generators/rails/scaffold/scaffold_generator.rb)2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/USAGE (renamed from railties/lib/generators/rails/scaffold_controller/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb (renamed from railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb (renamed from railties/lib/generators/rails/scaffold_controller/templates/controller.rb)4
-rw-r--r--railties/lib/rails/generators/rails/session_migration/USAGE (renamed from railties/lib/generators/rails/session_migration/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb (renamed from railties/lib/generators/rails/session_migration/session_migration_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/stylesheets/USAGE (renamed from railties/lib/generators/rails/stylesheets/USAGE)0
-rw-r--r--railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb (renamed from railties/lib/generators/rails/stylesheets/stylesheets_generator.rb)0
-rw-r--r--railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css (renamed from railties/lib/generators/rails/stylesheets/templates/scaffold.css)0
-rw-r--r--railties/lib/rails/generators/test_unit.rb (renamed from railties/lib/generators/test_unit.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/controller/controller_generator.rb (renamed from railties/lib/generators/test_unit/controller/controller_generator.rb)3
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb18
-rw-r--r--railties/lib/rails/generators/test_unit/helper/helper_generator.rb (renamed from railties/lib/generators/test_unit/helper/helper_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb (renamed from railties/lib/generators/test_unit/helper/templates/helper_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/integration/integration_generator.rb (renamed from railties/lib/generators/test_unit/integration/integration_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb (renamed from railties/lib/generators/test_unit/integration/templates/integration_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb (renamed from railties/lib/generators/test_unit/mailer/mailer_generator.rb)9
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb (renamed from railties/lib/generators/test_unit/mailer/templates/functional_test.rb)11
-rw-r--r--railties/lib/rails/generators/test_unit/model/model_generator.rb (renamed from railties/lib/generators/test_unit/model/model_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/fixtures.yml (renamed from railties/lib/generators/test_unit/model/templates/fixtures.yml)0
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/unit_test.rb (renamed from railties/lib/generators/test_unit/model/templates/unit_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/observer/observer_generator.rb (renamed from railties/lib/generators/test_unit/observer/observer_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb (renamed from railties/lib/generators/test_unit/observer/templates/unit_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/performance/performance_generator.rb (renamed from railties/lib/generators/test_unit/performance/performance_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb (renamed from railties/lib/generators/test_unit/performance/templates/performance_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb (renamed from railties/lib/generators/test_unit/plugin/plugin_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt (renamed from railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt)0
-rw-r--r--railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb (renamed from railties/lib/generators/test_unit/plugin/templates/test_helper.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb (renamed from railties/lib/generators/test_unit/scaffold/scaffold_generator.rb)2
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb (renamed from railties/lib/generators/test_unit/scaffold/templates/functional_test.rb)14
-rw-r--r--railties/lib/rails/info.rb (renamed from railties/builtin/rails_info/rails/info.rb)0
-rw-r--r--railties/lib/rails/info_controller.rb (renamed from railties/builtin/rails_info/rails/info_controller.rb)0
-rw-r--r--railties/lib/rails/info_routes.rb (renamed from railties/builtin/routes.rb)0
-rw-r--r--railties/lib/rails/railtie.rb27
-rw-r--r--railties/lib/rails/railtie/configuration.rb77
-rw-r--r--railties/lib/rails/railties_path.rb1
-rw-r--r--railties/lib/rails/tasks/documentation.rake7
-rw-r--r--railties/lib/rails/tasks/framework.rake13
-rw-r--r--railties/lib/rails/tasks/misc.rake8
-rw-r--r--railties/lib/rails/test_help.rb6
-rw-r--r--railties/lib/rails/test_unit/railtie.rb2
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/abstract_unit.rb1
-rw-r--r--railties/test/application/configuration_test.rb70
-rw-r--r--railties/test/application/paths_test.rb18
-rw-r--r--railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb2
-rw-r--r--railties/test/fixtures/lib/rails/generators/foobar/foobar_generator.rb (renamed from railties/test/fixtures/lib/rails_generators/foobar/foobar_generator.rb)0
-rw-r--r--railties/test/generators/actions_test.rb5
-rw-r--r--railties/test/generators/app_generator_test.rb2
-rw-r--r--railties/test/generators/controller_generator_test.rb15
-rw-r--r--railties/test/generators/generator_generator_test.rb2
-rw-r--r--railties/test/generators/generators_test_helper.rb7
-rw-r--r--railties/test/generators/helper_generator_test.rb2
-rw-r--r--railties/test/generators/integration_test_generator_test.rb2
-rw-r--r--railties/test/generators/mailer_generator_test.rb14
-rw-r--r--railties/test/generators/metal_generator_test.rb2
-rw-r--r--railties/test/generators/migration_generator_test.rb2
-rw-r--r--railties/test/generators/model_generator_test.rb2
-rw-r--r--railties/test/generators/named_base_test.rb20
-rw-r--r--railties/test/generators/observer_generator_test.rb2
-rw-r--r--railties/test/generators/performance_test_generator_test.rb2
-rw-r--r--railties/test/generators/plugin_generator_test.rb2
-rw-r--r--railties/test/generators/resource_generator_test.rb12
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb2
-rw-r--r--railties/test/generators/scaffold_generator_test.rb12
-rw-r--r--railties/test/generators/session_migration_generator_test.rb2
-rw-r--r--railties/test/generators/stylesheets_generator_test.rb2
-rw-r--r--railties/test/generators_test.rb4
-rw-r--r--railties/test/rails_info_controller_test.rb3
-rw-r--r--railties/test/railties/railtie_test.rb21
411 files changed, 3065 insertions, 1786 deletions
diff --git a/Gemfile b/Gemfile
index a51c560232..ea9842c0c5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,14 +7,17 @@ gem "rails", "3.0.0.beta1"
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"
-if RUBY_VERSION < '1.9'
- gem "ruby-debug", ">= 0.10.3"
+group :mri do
+ if RUBY_VERSION < '1.9'
+ gem "system_timer"
+ gem "ruby-debug", ">= 0.10.3"
+ end
end
# AR
gem "sqlite3-ruby", ">= 1.2.5", :require => 'sqlite3'
-group :test do
+group :db do
gem "pg", ">= 0.9.0"
gem "mysql", ">= 2.8.1"
end
diff --git a/Rakefile b/Rakefile
index 4437b48d9a..66a65fb249 100644
--- a/Rakefile
+++ b/Rakefile
@@ -49,13 +49,13 @@ end
desc "Install gems for all projects."
task :install => :gem do
- require File.expand_path("../actionpack/lib/action_pack/version", __FILE__)
+ version = File.read("RAILS_VERSION").strip
(PROJECTS - ["railties"]).each do |project|
puts "INSTALLING #{project}"
- system("gem install #{project}/pkg/#{project}-#{ActionPack::VERSION::STRING}.gem --no-ri --no-rdoc")
+ system("gem install #{project}/pkg/#{project}-#{version}.gem --no-ri --no-rdoc")
end
- system("gem install railties/pkg/railties-#{ActionPack::VERSION::STRING}.gem --no-ri --no-rdoc")
- system("gem install pkg/rails-#{ActionPack::VERSION::STRING}.gem --no-ri --no-rdoc")
+ system("gem install railties/pkg/railties-#{version}.gem --no-ri --no-rdoc")
+ system("gem install pkg/rails-#{version}.gem --no-ri --no-rdoc")
end
desc "Generate documentation for the Rails framework"
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index f94e23fe05..0519783d02 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -1,6 +1,7 @@
require 'mail'
require 'action_mailer/tmail_compat'
require 'action_mailer/collector'
+require 'active_support/core_ext/array/wrap'
module ActionMailer #:nodoc:
# Action Mailer allows you to send email from your application using a mailer model and views.
@@ -590,7 +591,7 @@ module ActionMailer #:nodoc:
responses, parts_order = [], nil
if block_given?
- collector = ActionMailer::Collector.new(self) { render(action_name) }
+ collector = ActionMailer::Collector.new(lookup_context) { render(action_name) }
yield(collector)
parts_order = collector.responses.map { |r| r[:content_type] }
responses = collector.responses
@@ -604,6 +605,8 @@ module ActionMailer #:nodoc:
templates_name = headers.delete(:template_name) || action_name
each_template(templates_path, templates_name) do |template|
+ self.formats = template.formats
+
responses << {
:body => render(:template => template),
:content_type => template.mime_type.to_s
@@ -615,7 +618,7 @@ module ActionMailer #:nodoc:
end
def each_template(paths, name, &block) #:nodoc:
- Array(paths).each do |path|
+ Array.wrap(paths).each do |path|
templates = lookup_context.find_all(name, path)
templates = templates.uniq_by { |t| t.formats }
diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb
index 5431efccfe..d03e085e83 100644
--- a/actionmailer/lib/action_mailer/collector.rb
+++ b/actionmailer/lib/action_mailer/collector.rb
@@ -11,7 +11,6 @@ module ActionMailer #:nodoc:
@context = context
@responses = []
@default_render = block
- @default_formats = context.formats
end
def any(*args, &block)
@@ -21,16 +20,11 @@ module ActionMailer #:nodoc:
end
alias :all :any
- def custom(mime, options={}, &block)
+ def custom(mime, options={})
options.reverse_merge!(:content_type => mime.to_s)
- @context.formats = [mime.to_sym]
- options[:body] = if block
- block.call
- else
- @default_render.call
- end
+ @context.freeze_formats([mime.to_sym])
+ options[:body] = block_given? ? yield : @default_render.call
@responses << options
- @context.formats = @default_formats
end
end
end \ No newline at end of file
diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb
index fb4b6701dd..c7f341d46c 100644
--- a/actionmailer/lib/action_mailer/old_api.rb
+++ b/actionmailer/lib/action_mailer/old_api.rb
@@ -31,9 +31,6 @@ module ActionMailer
# replies to this message.
adv_attr_accessor :reply_to
- # Specify additional headers to be added to the message.
- adv_attr_accessor :headers
-
# Specify the order in which parts should be sorted, based on content-type.
# This defaults to the value for the +default_implicit_parts_order+.
adv_attr_accessor :implicit_parts_order
@@ -207,6 +204,7 @@ module ActionMailer
@parts.unshift create_inline_part(@body)
elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ }
lookup_context.find_all(@template, @mailer_name).each do |template|
+ self.formats = template.formats
@parts << create_inline_part(render(:template => template), template.mime_type)
end
diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index 0182e48425..2703367fdb 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -3,14 +3,14 @@ require "rails"
module ActionMailer
class Railtie < Rails::Railtie
- railtie_name :action_mailer
+ config.action_mailer = ActiveSupport::OrderedOptions.new
initializer "action_mailer.url_for", :before => :load_environment_config do |app|
ActionMailer.base_hook { include app.routes.url_helpers }
end
require "action_mailer/railties/log_subscriber"
- log_subscriber ActionMailer::Railties::LogSubscriber.new
+ log_subscriber :action_mailer, ActionMailer::Railties::LogSubscriber.new
initializer "action_mailer.logger" do
ActionMailer.base_hook { self.logger ||= Rails.logger }
diff --git a/actionmailer/lib/action_mailer/railties/log_subscriber.rb b/actionmailer/lib/action_mailer/railties/log_subscriber.rb
index d1b3dd33af..af76d807d0 100644
--- a/actionmailer/lib/action_mailer/railties/log_subscriber.rb
+++ b/actionmailer/lib/action_mailer/railties/log_subscriber.rb
@@ -1,8 +1,10 @@
+require 'active_support/core_ext/array/wrap'
+
module ActionMailer
module Railties
class LogSubscriber < Rails::LogSubscriber
def deliver(event)
- recipients = Array(event.payload[:to]).join(', ')
+ recipients = Array.wrap(event.payload[:to]).join(', ')
info("\nSent mail to #{recipients} (%1.fms)" % event.duration)
debug(event.payload[:mail])
end
@@ -17,4 +19,4 @@ module ActionMailer
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb
index 16fef3a9a4..ea15709b45 100644
--- a/actionmailer/test/abstract_unit.rb
+++ b/actionmailer/test/abstract_unit.rb
@@ -1,4 +1,23 @@
-require File.expand_path('../../../load_paths', __FILE__)
+# Pathname has a warning, so require it first while silencing
+# warnings to shut it up.
+#
+# Also, in 1.9, Bundler creates warnings due to overriding
+# Rubygems methods
+begin
+ old, $VERBOSE = $VERBOSE, nil
+ require 'pathname'
+ require File.expand_path('../../../load_paths', __FILE__)
+ensure
+ $VERBOSE = old
+end
+
+
+require 'active_support/core_ext/kernel/reporting'
+silence_warnings do
+ # These external dependencies have warnings :/
+ require 'text/format'
+ require 'mail'
+end
lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index f5fd12a6b0..6f274c11df 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -74,13 +74,20 @@ class BaseTest < ActiveSupport::TestCase
end
end
- def custom_block(include_html=false)
+ def explicit_multipart_with_options(include_html = false)
mail do |format|
format.text(:content_transfer_encoding => "base64"){ render "welcome" }
format.html{ render "welcome" } if include_html
end
end
+ def explicit_multipart_with_one_template(hash = {})
+ mail(hash) do |format|
+ format.html
+ format.text
+ end
+ end
+
def implicit_different_template(template_name='')
mail(:template_name => template_name)
end
@@ -148,6 +155,13 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("Hello there", email.body.encoded)
end
+ test "should set template content type if mail has only one part" do
+ mail = BaseMailer.html_only
+ assert_equal('text/html', mail.mime_type)
+ mail = BaseMailer.plain_text_only
+ assert_equal('text/plain', mail.mime_type)
+ end
+
# Custom headers
test "custom headers" do
email = BaseMailer.welcome
@@ -162,7 +176,7 @@ class BaseTest < ActiveSupport::TestCase
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
- test "can pass random headers in as a hash" do
+ test "can pass random headers in as a hash to headers" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
mail = BaseMailer.welcome_with_headers(hash)
@@ -366,6 +380,11 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("HTML Explicit Multipart", email.parts[1].body.encoded)
end
+ test "explicit multipart have a boundary" do
+ mail = BaseMailer.explicit_multipart
+ assert_not_nil(mail.content_type_parameters[:boundary])
+ end
+
test "explicit multipart does not sort order" do
order = ["text/html", "text/plain"]
with_default BaseMailer, :parts_order => order do
@@ -399,7 +418,7 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("TEXT Explicit Multipart Templates", email.parts[1].body.encoded)
end
- test "explicit multipart with any" do
+ test "explicit multipart with format.any" do
email = BaseMailer.explicit_multipart_with_any
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
@@ -409,8 +428,8 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("Format with any!", email.parts[1].body.encoded)
end
- test "explicit multipart with options" do
- email = BaseMailer.custom_block(true)
+ test "explicit multipart with format(Hash)" do
+ email = BaseMailer.explicit_multipart_with_options(true)
email.ready_to_send!
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
@@ -420,28 +439,23 @@ class BaseTest < ActiveSupport::TestCase
assert_equal("7bit", email.parts[1].content_transfer_encoding)
end
- test "explicit multipart should be multipart" do
- mail = BaseMailer.explicit_multipart
- assert_not_nil(mail.content_type_parameters[:boundary])
- end
-
- test "should set a content type if only has an html part" do
- mail = BaseMailer.html_only
- assert_equal('text/html', mail.mime_type)
- end
-
- test "should set a content type if only has an plain text part" do
- mail = BaseMailer.plain_text_only
- assert_equal('text/plain', mail.mime_type)
- end
-
- test "explicit multipart with one part is rendered as body" do
- email = BaseMailer.custom_block
+ test "explicit multipart with one part is rendered as body and options are merged" do
+ email = BaseMailer.explicit_multipart_with_options
assert_equal(0, email.parts.size)
assert_equal("text/plain", email.mime_type)
assert_equal("base64", email.content_transfer_encoding)
end
+ test "explicit multipart with one template has the expected format" do
+ email = BaseMailer.explicit_multipart_with_one_template
+ assert_equal(2, email.parts.size)
+ assert_equal("multipart/alternative", email.mime_type)
+ assert_equal("text/html", email.parts[0].mime_type)
+ assert_equal("[:html]", email.parts[0].body.encoded)
+ assert_equal("text/plain", email.parts[1].mime_type)
+ assert_equal("[:text]", email.parts[1].body.encoded)
+ end
+
# Class level API with method missing
test "should respond to action methods" do
assert BaseMailer.respond_to?(:welcome)
diff --git a/actionmailer/test/fixtures/base_mailer/explicit_multipart_with_one_template.erb b/actionmailer/test/fixtures/base_mailer/explicit_multipart_with_one_template.erb
new file mode 100644
index 0000000000..8a69657b08
--- /dev/null
+++ b/actionmailer/test/fixtures/base_mailer/explicit_multipart_with_one_template.erb
@@ -0,0 +1 @@
+<%= self.formats.inspect %> \ No newline at end of file
diff --git a/actionmailer/test/fixtures/test_mailer/signed_up_with_url.erb b/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb
index 4c5806d30d..4c5806d30d 100644
--- a/actionmailer/test/fixtures/test_mailer/signed_up_with_url.erb
+++ b/actionmailer/test/fixtures/url_test_mailer/signed_up_with_url.erb
diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/old_base/mail_layout_test.rb
index 5679aa5a64..2c2daa0f28 100644
--- a/actionmailer/test/old_base/mail_layout_test.rb
+++ b/actionmailer/test/old_base/mail_layout_test.rb
@@ -69,47 +69,25 @@ class LayoutMailerTest < Test::Unit::TestCase
def test_should_pickup_multipart_layout
mail = AutoLayoutMailer.multipart
- # CHANGED: content_type returns an object
- # assert_equal "multipart/alternative", mail.content_type
assert_equal "multipart/alternative", mail.mime_type
assert_equal 2, mail.parts.size
- # CHANGED: content_type returns an object
- # assert_equal 'text/plain', mail.parts.first.content_type
assert_equal 'text/plain', mail.parts.first.mime_type
-
- # CHANGED: body returns an object
- # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body
assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s
- # CHANGED: content_type returns an object
- # assert_equal 'text/html', mail.parts.last.content_type
assert_equal 'text/html', mail.parts.last.mime_type
-
- # CHANGED: body returns an object
- # assert_equal "Hello from layout text/html multipart", mail.parts.last.body
assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s
end
def test_should_pickup_multipartmixed_layout
mail = AutoLayoutMailer.multipart("multipart/mixed")
- # CHANGED: content_type returns an object
- # assert_equal "multipart/mixed", mail.content_type
assert_equal "multipart/mixed", mail.mime_type
assert_equal 2, mail.parts.size
- # CHANGED: content_type returns an object
- # assert_equal 'text/plain', mail.parts.first.content_type
assert_equal 'text/plain', mail.parts.first.mime_type
- # CHANGED: body returns an object
- # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body
assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s
- # CHANGED: content_type returns an object
- # assert_equal 'text/html', mail.parts.last.content_type
assert_equal 'text/html', mail.parts.last.mime_type
- # CHANGED: body returns an object
- # assert_equal "Hello from layout text/html multipart", mail.parts.last.body
assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s
end
diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb
index 6d0b2c53a3..e49307bfda 100644
--- a/actionmailer/test/old_base/mail_service_test.rb
+++ b/actionmailer/test/old_base/mail_service_test.rb
@@ -340,6 +340,8 @@ class ActionMailerTest < Test::Unit::TestCase
@original_logger = TestMailer.logger
@recipient = 'test@localhost'
+
+ TestMailer.delivery_method = :test
end
def teardown
@@ -1191,6 +1193,6 @@ class RespondToTest < Test::Unit::TestCase
RespondToMailer.not_a_method
end
- assert_match(/undefined method.*not_a_method/, error.message)
+ assert_match(/method.*not_a_method/, error.message)
end
-end \ No newline at end of file
+end
diff --git a/actionmailer/test/old_base/url_test.rb b/actionmailer/test/old_base/url_test.rb
index 60740d6b0b..17b383cc2a 100644
--- a/actionmailer/test/old_base/url_test.rb
+++ b/actionmailer/test/old_base/url_test.rb
@@ -10,7 +10,7 @@ class ActionMailer::Base
include AppRoutes.url_helpers
end
-class TestMailer < ActionMailer::Base
+class UrlTestMailer < ActionMailer::Base
default_url_options[:host] = 'www.basecamphq.com'
configure do |c|
@@ -26,14 +26,6 @@ class TestMailer < ActionMailer::Base
@recipient = recipient
@welcome_url = url_for :host => "example.com", :controller => "welcome", :action => "greeting"
end
-
- class <<self
- attr_accessor :received_body
- end
-
- def receive(mail)
- self.class.received_body = mail.body
- end
end
class ActionMailerUrlTest < Test::Unit::TestCase
@@ -65,7 +57,7 @@ class ActionMailerUrlTest < Test::Unit::TestCase
end
def test_signed_up_with_url
- TestMailer.delivery_method = :test
+ UrlTestMailer.delivery_method = :test
AppRoutes.draw do |map|
map.connect ':controller/:action/:id'
@@ -80,14 +72,14 @@ class ActionMailerUrlTest < Test::Unit::TestCase
expected.date = Time.local(2004, 12, 12)
created = nil
- assert_nothing_raised { created = TestMailer.signed_up_with_url(@recipient) }
+ assert_nothing_raised { created = UrlTestMailer.signed_up_with_url(@recipient) }
assert_not_nil created
expected.message_id = '<123@456>'
created.message_id = '<123@456>'
assert_equal expected.encoded, created.encoded
- assert_nothing_raised { TestMailer.signed_up_with_url(@recipient).deliver }
+ assert_nothing_raised { UrlTestMailer.signed_up_with_url(@recipient).deliver }
assert_not_nil ActionMailer::Base.deliveries.first
delivered = ActionMailer::Base.deliveries.first
diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb
index f875213afb..53cf6b3931 100644
--- a/actionpack/lib/abstract_controller/helpers.rb
+++ b/actionpack/lib/abstract_controller/helpers.rb
@@ -6,16 +6,10 @@ module AbstractController
include Rendering
- def self.next_serial
- @helper_serial ||= 0
- @helper_serial += 1
- end
-
included do
- class_attribute :_helpers, :_helper_serial
+ class_attribute :_helpers
delegate :_helpers, :to => :'self.class'
self._helpers = Module.new
- self._helper_serial = ::AbstractController::Helpers.next_serial
end
module ClassMethods
@@ -95,8 +89,6 @@ module AbstractController
# helper(:three, BlindHelper) { def mice() 'mice' end }
#
def helper(*args, &block)
- self._helper_serial = AbstractController::Helpers.next_serial + 1
-
modules_for_helpers(args).each do |mod|
add_template_helper(mod)
end
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 95a6101109..319472c937 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/module/remove_method"
+
module AbstractController
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
# repeated setups. The inclusion pattern has pages that look like this:
@@ -182,7 +184,9 @@ module AbstractController
#
# ==== Returns
# Boolean:: True if the action has a layout, false otherwise.
- def _action_has_layout?
+ def action_has_layout?
+ return unless super
+
conditions = _layout_conditions
if only = conditions[:only]
@@ -237,6 +241,8 @@ module AbstractController
# name, return that string. Otherwise, use the superclass'
# layout (which might also be implied)
def _write_layout_method
+ remove_possible_method(:_layout)
+
case defined?(@_layout) ? @_layout : nil
when String
self.class_eval %{def _layout; #{@_layout.inspect} end}
@@ -284,15 +290,20 @@ module AbstractController
layout = options.key?(:layout) ? options.delete(:layout) : :default
value = _layout_for_option(layout)
options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
-
- # TODO Layout for partials should be handled here, because inside the
- # partial renderer it looks for the layout as a partial.
- if options.key?(:partial) && options[:layout]
- options[:layout] = view_context.find_layout(options[:layout])
- end
end
end
+ attr_writer :action_has_layout
+
+ def initialize(*)
+ @action_has_layout = true
+ super
+ end
+
+ def action_has_layout?
+ @action_has_layout
+ end
+
private
# This will be overwritten by _write_layout_method
@@ -332,13 +343,13 @@ module AbstractController
# Template:: The template object for the default layout (or nil)
def _default_layout(require_layout = false)
begin
- layout_name = _layout if _action_has_layout?
+ layout_name = _layout if action_has_layout?
rescue NameError => e
raise NoMethodError,
"You specified #{@_layout.inspect} as the layout, but no such method was found"
end
- if require_layout && _action_has_layout? && !layout_name
+ if require_layout && action_has_layout? && !layout_name
raise ArgumentError,
"There was no default layout for #{self.class} in #{view_paths.inspect}"
end
@@ -349,9 +360,5 @@ module AbstractController
def _include_layout?(options)
(options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
end
-
- def _action_has_layout?
- true
- end
end
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 16664098e5..b251bd6405 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -32,7 +32,6 @@ module AbstractController
module Rendering
extend ActiveSupport::Concern
- include AbstractController::Assigns
include AbstractController::ViewPaths
# Overwrite process to setup I18n proxy.
@@ -43,17 +42,48 @@ module AbstractController
I18n.config = old_config
end
+ module ClassMethods
+ def view_context_class
+ @view_context_class ||= begin
+ controller = self
+ Class.new(ActionView::Base) do
+ if controller.respond_to?(:_helpers)
+ include controller._helpers
+
+ if controller.respond_to?(:_router)
+ include controller._router.url_helpers
+ end
+
+ # TODO: Fix RJS to not require this
+ self.helpers = controller._helpers
+ end
+ end
+ end
+ end
+ end
+
+ attr_writer :view_context_class
+
+ def view_context_class
+ @view_context_class || self.class.view_context_class
+ end
+
+ def initialize(*)
+ @view_context_class = nil
+ super
+ end
+
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
- # View.for_controller[controller]
+ # View.new[lookup_context, assigns, controller]
# Create a new ActionView instance for a controller
- # View#render_template[options]
+ # View#render[options]
# Returns String with the rendered template
#
# Override this method in a module to change the default behavior.
def view_context
- @_view_context ||= ActionView::Base.for_controller(self)
+ view_context_class.new(lookup_context, view_assigns, self)
end
# Normalize arguments, options and then delegates render_to_body and
@@ -76,13 +106,12 @@ module AbstractController
# :api: plugin
def render_to_string(options={})
_normalize_options(options)
- AbstractController::Rendering.body_to_s(render_to_body(options))
+ render_to_body(options)
end
# Find and renders a template based on the options given.
# :api: private
def _render_template(options) #:nodoc:
- _evaluate_assigns(view_context)
view_context.render(options)
end
@@ -91,20 +120,19 @@ module AbstractController
controller_path
end
- # Return a string representation of a Rack-compatible response body.
- def self.body_to_s(body)
- if body.respond_to?(:to_str)
- body
- else
- strings = []
- body.each { |part| strings << part.to_s }
- body.close if body.respond_to?(:close)
- strings.join
- end
- end
-
private
+ # This method should return a hash with assigns.
+ # You can overwrite this configuration per controller.
+ # :api: public
+ def view_assigns
+ hash = {}
+ variables = instance_variable_names
+ variables -= protected_instance_variables if respond_to?(:protected_instance_variables)
+ variables.each { |name| hash[name.to_s[1..-1]] = instance_variable_get(name) }
+ hash
+ end
+
# Normalize options by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
def _normalize_args(action=nil, options={})
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index ad2b68af21..5797282b41 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -19,6 +19,7 @@ module ActionController
include SessionManagement
include ActionController::Caching
include ActionController::MimeResponds
+ include ActionController::PolymorphicRoutes
# Rails 2.x compatibility
include ActionController::Compatibility
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 35111a4b92..43ddf6435a 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -80,6 +80,7 @@ module ActionController #:nodoc:
def caches_action(*actions)
return unless cache_configured?
options = actions.extract_options!
+ options[:layout] = true unless options.key?(:layout)
filter_options = options.extract!(:if, :unless).merge(:only => actions)
cache_options = options.extract!(:layout, :cache_path).merge(:store_options => options)
@@ -87,14 +88,12 @@ module ActionController #:nodoc:
end
end
- def _render_cache_fragment(cache, extension, layout)
- render :text => cache, :layout => layout, :content_type => Mime[extension || :html]
- end
-
- def _save_fragment(name, layout, options)
+ def _save_fragment(name, options)
return unless caching_allowed?
- content = layout ? view_context.content_for(:layout) : response_body
+ content = response_body
+ content = content.join if content.is_a?(Array)
+
write_fragment(name, content, options)
end
@@ -112,7 +111,7 @@ module ActionController #:nodoc:
class ActionCacheFilter #:nodoc:
def initialize(options, &block)
- @cache_path, @store_options, @layout =
+ @cache_path, @store_options, @cache_layout =
options.values_at(:cache_path, :store_options, :layout)
end
@@ -125,12 +124,19 @@ module ActionController #:nodoc:
cache_path = ActionCachePath.new(controller, path_options || {})
- if cache = controller.read_fragment(cache_path.path, @store_options)
- controller._render_cache_fragment(cache, cache_path.extension, @layout == false)
- else
+ body = controller.read_fragment(cache_path.path, @store_options)
+
+ unless body
+ controller.action_has_layout = false unless @cache_layout
yield
- controller._save_fragment(cache_path.path, @layout == false, @store_options)
+ controller.action_has_layout = true
+ body = controller._save_fragment(cache_path.path, @store_options)
end
+
+ body = controller.render_to_string(:text => cache, :layout => true) unless @cache_layout
+
+ controller.response_body = body
+ controller.content_type = Mime[cache_path.extension || :html]
end
end
diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb
index 89787727bd..473a2fe214 100644
--- a/actionpack/lib/action_controller/caching/fragments.rb
+++ b/actionpack/lib/action_controller/caching/fragments.rb
@@ -34,20 +34,6 @@ module ActionController #:nodoc:
ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
end
- def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc:
- if perform_caching
- if fragment_exist?(name, options)
- buffer.safe_concat(read_fragment(name, options))
- else
- pos = buffer.length
- block.call
- write_fragment(name, buffer[pos..-1], options)
- end
- else
- block.call
- end
- end
-
# Writes <tt>content</tt> to the location signified by <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats)
def write_fragment(key, content, options = nil)
return content unless cache_configured?
diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb
index 1d05b3fbd6..bbde570ca9 100644
--- a/actionpack/lib/action_controller/deprecated/base.rb
+++ b/actionpack/lib/action_controller/deprecated/base.rb
@@ -63,7 +63,7 @@ module ActionController
def ip_spoofing_check
ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " <<
"Configuring ip_spoofing_check on the application configures a middleware.", caller
- Rails.application.config.action_disaptch.ip_spoofing_check
+ Rails.application.config.action_dispatch.ip_spoofing_check
end
def trusted_proxies=(value)
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index eebd2c943a..30aa34d956 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -34,11 +34,12 @@ module ActionController
# and response object available. You might wish to control the
# environment and response manually for performance reasons.
- attr_internal :status, :headers, :content_type, :response, :request
+ attr_internal :headers, :response, :request
delegate :session, :to => "@_request"
def initialize(*)
- @_headers = {}
+ @_headers = {"Content-Type" => "text/html"}
+ @_status = 200
super
end
@@ -62,10 +63,19 @@ module ActionController
headers["Location"] = url
end
+ def status
+ @_status
+ end
+
def status=(status)
@_status = Rack::Utils.status_code(status)
end
+ def response_body=(val)
+ body = val.respond_to?(:each) ? val : [val]
+ super body
+ end
+
# :api: private
def dispatch(name, request)
@_request = request
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index ab8d87b2c4..e6cea483bb 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -40,15 +40,6 @@ module ActionController
def initialize_template_class(*) end
def assign_shortcuts(*) end
- def template
- @template ||= view_context
- end
-
- def process_action(*)
- template
- super
- end
-
def _normalize_options(options)
if options[:action] && options[:action].to_s.include?(?/)
ActiveSupport::Deprecation.warn "Giving a path to render :action is deprecated. " <<
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 2ac199265d..4f384d1ec5 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -262,7 +262,7 @@ module ActionController #:nodoc:
if format = request.negotiate_mime(collector.order)
self.content_type ||= format.to_s
- self.formats = [format.to_sym]
+ lookup_context.freeze_formats([format.to_sym])
collector.response_for(format)
else
head :not_acceptable
diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb
index 37106733cb..060117756e 100644
--- a/actionpack/lib/action_controller/metal/rack_delegation.rb
+++ b/actionpack/lib/action_controller/metal/rack_delegation.rb
@@ -5,10 +5,8 @@ module ActionController
module RackDelegation
extend ActiveSupport::Concern
- included do
- delegate :headers, :status=, :location=, :content_type=,
- :status, :location, :content_type, :to => "@_response"
- end
+ delegate :headers, :status=, :location=, :content_type=,
+ :status, :location, :content_type, :to => "@_response"
def dispatch(action, request)
@_response = ActionDispatch::Response.new
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 25e4e18493..b5f1d23ef0 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -76,7 +76,7 @@ module ActionController
# The scheme name consist of a letter followed by any combination of
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
# characters; and is terminated by a colon (":").
- when %r{^\w[\w\d+.-]*:.*}
+ when %r{^\w[\w+.-]*:.*}
options
when String
request.protocol + request.host_with_port + options
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index 08325b468c..d906e1fb5b 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -87,7 +87,7 @@ module ActionController
end
add :update do |proc, options|
- _evaluate_assigns(view_context)
+ view_context = self.view_context
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
self.content_type = Mime::JS
self.response_body = generator.to_s
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index 6178a59029..0b2cee6868 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -1,3 +1,5 @@
+require 'active_support/json'
+
module ActionController #:nodoc:
# Responder is responsible for exposing a resource to different mime requests,
# usually depending on the HTTP verb. The responder is triggered when
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 6a3afbb157..0ec89928af 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -1,16 +1,17 @@
require "rails"
require "action_controller"
+require "action_dispatch/railtie"
require "action_view/railtie"
require "active_support/core_ext/class/subclasses"
require "active_support/deprecation/proxy_wrappers"
require "active_support/deprecation"
+require "action_controller/railties/log_subscriber"
+require "action_controller/railties/url_helpers"
+
module ActionController
class Railtie < Rails::Railtie
- railtie_name :action_controller
-
- require "action_controller/railties/log_subscriber"
- require "action_controller/railties/url_helpers"
+ config.action_controller = ActiveSupport::OrderedOptions.new
ad = config.action_dispatch
config.action_controller.singleton_class.send(:define_method, :session) do
@@ -37,7 +38,7 @@ module ActionController
ad.session_store = val
end
- log_subscriber ActionController::Railties::LogSubscriber.new
+ log_subscriber :action_controller, ActionController::Railties::LogSubscriber.new
initializer "action_controller.logger" do
ActionController.base_hook { self.logger ||= Rails.logger }
@@ -52,7 +53,9 @@ module ActionController
ac.stylesheets_dir = paths.public.stylesheets.to_a.first
ac.secret = app.config.cookie_secret
- ActionController.base_hook { self.config.replace(ac) }
+ ActionController.base_hook do
+ self.config.merge!(ac)
+ end
end
initializer "action_controller.initialize_framework_caches" do
@@ -67,7 +70,7 @@ module ActionController
initializer "action_controller.url_helpers" do |app|
ActionController.base_hook do
- extend ::ActionController::Railtie::UrlHelpers.with(app.routes)
+ extend ::ActionController::Railties::UrlHelpers.with(app.routes)
end
message = "ActionController::Routing::Routes is deprecated. " \
diff --git a/actionpack/lib/action_controller/railties/url_helpers.rb b/actionpack/lib/action_controller/railties/url_helpers.rb
index ad2a8d4ef3..5f95e1c621 100644
--- a/actionpack/lib/action_controller/railties/url_helpers.rb
+++ b/actionpack/lib/action_controller/railties/url_helpers.rb
@@ -1,5 +1,5 @@
module ActionController
- class Railtie
+ module Railties
module UrlHelpers
def self.with(router)
Module.new do
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index cdb5db32aa..120f34460e 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -1,7 +1,107 @@
require 'rack/session/abstract/id'
-require 'action_view/test_case'
module ActionController
+ module TemplateAssertions
+ extend ActiveSupport::Concern
+
+ included do
+ setup :setup_subscriptions
+ teardown :teardown_subscriptions
+ end
+
+ def setup_subscriptions
+ @partials = Hash.new(0)
+ @templates = Hash.new(0)
+ @layouts = Hash.new(0)
+
+ ActiveSupport::Notifications.subscribe("action_view.render_template") do |name, start, finish, id, payload|
+ path = payload[:layout]
+ @layouts[path] += 1
+ end
+
+ ActiveSupport::Notifications.subscribe("action_view.render_template!") do |name, start, finish, id, payload|
+ path = payload[:virtual_path]
+ next unless path
+ partial = path =~ /^.*\/_[^\/]*$/
+ if partial
+ @partials[path] += 1
+ @partials[path.split("/").last] += 1
+ @templates[path] += 1
+ else
+ @templates[path] += 1
+ end
+ end
+ end
+
+ def teardown_subscriptions
+ ActiveSupport::Notifications.unsubscribe("action_view.render_template!")
+ end
+
+ # Asserts that the request was rendered with the appropriate template file or partials
+ #
+ # ==== Examples
+ #
+ # # assert that the "new" view template was rendered
+ # assert_template "new"
+ #
+ # # assert that the "_customer" partial was rendered twice
+ # assert_template :partial => '_customer', :count => 2
+ #
+ # # assert that no partials were rendered
+ # assert_template :partial => false
+ #
+ def assert_template(options = {}, message = nil)
+ validate_request!
+
+ case options
+ when NilClass, String
+ rendered = @templates
+ msg = build_message(message,
+ "expecting <?> but rendering with <?>",
+ options, rendered.keys.join(', '))
+ assert_block(msg) do
+ if options.nil?
+ @templates.blank?
+ else
+ rendered.any? { |t,num| t.match(options) }
+ end
+ end
+ when Hash
+ if expected_partial = options[:partial]
+ if expected_count = options[:count]
+ actual_count = @partials[expected_partial]
+ # actual_count = found.nil? ? 0 : found[1]
+ msg = build_message(message,
+ "expecting ? to be rendered ? time(s) but rendered ? time(s)",
+ expected_partial, expected_count, actual_count)
+ assert(actual_count == expected_count.to_i, msg)
+ elsif options.key?(:layout)
+ msg = build_message(message,
+ "expecting layout <?> but action rendered <?>",
+ expected_layout, @layouts.keys)
+
+ case layout = options[:layout]
+ when String
+ assert(@layouts.include?(expected_layout), msg)
+ when Regexp
+ assert(@layouts.any? {|l| l =~ layout }, msg)
+ when nil
+ assert(@layouts.empty?, msg)
+ end
+ else
+ msg = build_message(message,
+ "expecting partial <?> but action rendered <?>",
+ options[:partial], @partials.keys)
+ assert(@partials.include?(expected_partial), msg)
+ end
+ else
+ assert @partials.empty?,
+ "Expected no partials to be rendered"
+ end
+ end
+ end
+ end
+
class TestRequest < ActionDispatch::TestRequest #:nodoc:
def initialize(env = {})
super
@@ -181,6 +281,7 @@ module ActionController
# assert_redirected_to page_url(:title => 'foo')
class TestCase < ActiveSupport::TestCase
include ActionDispatch::TestProcess
+ include ActionController::TemplateAssertions
# Executes a request simulating GET HTTP method and set/volley the response
def get(action, parameters = nil, session = nil, flash = nil)
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 451b79b190..e42b4d09b0 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -25,7 +25,6 @@ module ActionDispatch
module FilterParameters
extend ActiveSupport::Concern
- mattr_reader :compiled_parameter_filter_for
@@compiled_parameter_filter_for = {}
# Return a hash of parameters with all sensitive data replaced.
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 13c0f2bad0..3f1a77295d 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -52,12 +52,6 @@ module Mime
cattr_reader :browser_generated_types
attr_reader :symbol
- @@unverifiable_types = Set.new [:text, :json, :csv, :xml, :rss, :atom, :yaml]
- def self.unverifiable_types
- ActiveSupport::Deprecation.warn("unverifiable_types is deprecated and has no effect", caller)
- @@unverifiable_types
- end
-
# A simple helper class used in parsing the accept header
class AcceptItem #:nodoc:
attr_accessor :order, :name, :q
@@ -100,7 +94,7 @@ module Mime
end
def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
- Mime.instance_eval { const_set symbol.to_s.upcase, Type.new(string, symbol, mime_type_synonyms) }
+ Mime.const_set(symbol.to_s.upcase, Type.new(string, symbol, mime_type_synonyms))
SET << Mime.const_get(symbol.to_s.upcase)
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 0dc03a1a7e..ab7130ab08 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -84,6 +84,7 @@ module ActionDispatch
options[:path] ||= "/"
@set_cookies[key] = options
+ @delete_cookies.delete(key)
value
end
diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb
index e486bd4079..563df0f256 100644
--- a/actionpack/lib/action_dispatch/railtie.rb
+++ b/actionpack/lib/action_dispatch/railtie.rb
@@ -3,9 +3,8 @@ require "rails"
module ActionDispatch
class Railtie < Rails::Railtie
- railtie_name :action_dispatch
-
- config.action_dispatch.x_sendfile_header = "X-Sendfile"
+ config.action_dispatch = ActiveSupport::OrderedOptions.new
+ config.action_dispatch.x_sendfile_header = ""
config.action_dispatch.ip_spoofing_check = true
# Prepare dispatcher callbacks and run 'prepare' callbacks
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 5bc3205c51..c6e942555f 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/regexp'
+require 'action_controller/polymorphic_routes'
module ActionDispatch
# == Routing
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index f9b27a5a03..5a3868e1d4 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -32,6 +32,8 @@ module ActionDispatch
end
class Mapping
+ IGNORE_OPTIONS = [:to, :as, :controller, :action, :via, :on, :constraints, :defaults, :only, :except, :anchor]
+
def initialize(set, scope, args)
@set, @scope = set, scope
@path, @options = extract_path_and_options(args)
@@ -45,18 +47,21 @@ module ActionDispatch
def extract_path_and_options(args)
options = args.extract_options!
- case
- when using_to_shorthand?(args, options)
+ if using_to_shorthand?(args, options)
path, to = options.find { |name, value| name.is_a?(String) }
options.merge!(:to => to).delete(path) if path
- when using_match_shorthand?(args, options)
- path = args.first
- options = { :to => path.gsub("/", "#"), :as => path.gsub("/", "_") }
else
path = args.first
end
- [ normalize_path(path), options ]
+ path = normalize_path(path)
+
+ if using_match_shorthand?(path, options)
+ options[:to] ||= path[1..-1].sub(%r{/([^/]*)$}, '#\1')
+ options[:as] ||= path[1..-1].gsub("/", "_")
+ end
+
+ [ path, options ]
end
# match "account" => "account#index"
@@ -65,14 +70,13 @@ module ActionDispatch
end
# match "account/overview"
- def using_match_shorthand?(args, options)
- args.present? && options.except(:via, :anchor).empty? && !args.first.include?(':')
+ def using_match_shorthand?(path, options)
+ path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w\/]+$}
end
def normalize_path(path)
- path = "#{@scope[:path]}/#{path}"
- raise ArgumentError, "path is required" if path.empty?
- Mapper.normalize_path(path)
+ raise ArgumentError, "path is required" if @scope[:path].blank? && path.blank?
+ Mapper.normalize_path("#{@scope[:path]}/#{path}")
end
def app
@@ -94,7 +98,15 @@ module ActionDispatch
end
def defaults
- @defaults ||= if to.respond_to?(:call)
+ @defaults ||= (@options[:defaults] || {}).tap do |defaults|
+ defaults.merge!(default_controller_and_action)
+ defaults.reverse_merge!(@scope[:defaults]) if @scope[:defaults]
+ @options.each { |k, v| defaults[k] = v unless v.is_a?(Regexp) || IGNORE_OPTIONS.include?(k.to_sym) }
+ end
+ end
+
+ def default_controller_and_action
+ if to.respond_to?(:call)
{ }
else
defaults = case to
@@ -144,8 +156,8 @@ module ActionDispatch
def segment_keys
@segment_keys ||= Rack::Mount::RegexpWithNamedGroups.new(
- Rack::Mount::Strexp.compile(@path, requirements, SEPARATORS)
- ).names
+ Rack::Mount::Strexp.compile(@path, requirements, SEPARATORS)
+ ).names
end
def to
@@ -297,11 +309,14 @@ module ActionDispatch
scope(:constraints => constraints) { yield }
end
+ def defaults(defaults = {})
+ scope(:defaults => defaults) { yield }
+ end
+
def match(*args)
options = args.extract_options!
options = (@scope[:options] || {}).merge(options)
- options[:anchor] = true unless options.key?(:anchor)
if @scope[:name_prefix] && !options[:as].blank?
options[:as] = "#{@scope[:name_prefix]}_#{options[:as]}"
@@ -342,6 +357,10 @@ module ActionDispatch
merge_options_scope(parent, child)
end
+ def merge_defaults_scope(parent, child)
+ merge_options_scope(parent, child)
+ end
+
def merge_blocks_scope(parent, child)
(parent || []) + [child]
end
@@ -460,7 +479,7 @@ module ActionDispatch
scope(:path => resource.name.to_s, :controller => resource.controller) do
with_scope_level(:resource, resource) do
- scope(:name_prefix => resource.name.to_s) do
+ scope(:name_prefix => resource.name.to_s, :as => "") do
yield if block_given?
end
@@ -563,6 +582,8 @@ module ActionDispatch
def match(*args)
options = args.extract_options!
+ options[:anchor] = true unless options.key?(:anchor)
+
if args.length > 1
args.each { |path| match(path, options) }
return self
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 722be432c7..bb689beed9 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -65,7 +65,7 @@ module ActionDispatch
# named routes.
class NamedRouteCollection #:nodoc:
include Enumerable
- attr_reader :routes, :helpers
+ attr_reader :routes, :helpers, :module
def initialize
clear!
@@ -179,6 +179,7 @@ module ActionDispatch
url_for(options)
end
+ protected :#{selector}
END_EVAL
helpers << selector
end
@@ -219,14 +220,16 @@ module ActionDispatch
end
def finalize!
+ return if @finalized
+ @finalized = true
@set.add_route(NotFound)
- install_helpers
@set.freeze
end
def clear!
# Clear the controller cache so we may discover new ones
@controller_constraints = nil
+ @finalized = false
routes.clear
named_routes.clear
@set = ::Rack::Mount::RouteSet.new(:parameters_key => PARAMETERS_KEY)
@@ -239,21 +242,30 @@ module ActionDispatch
def url_helpers
@url_helpers ||= begin
- router = self
+ routes = self
- Module.new do
+ helpers = Module.new do
extend ActiveSupport::Concern
include UrlFor
+ @routes = routes
+ class << self
+ delegate :url_for, :to => '@routes'
+ end
+ extend routes.named_routes.module
+
# ROUTES TODO: install_helpers isn't great... can we make a module with the stuff that
# we can include?
# Yes plz - JP
included do
- router.install_helpers(self)
+ routes.install_helpers(self)
+ singleton_class.send(:define_method, :_router) { routes }
end
- define_method(:_router) { router }
+ define_method(:_router) { routes }
end
+
+ helpers
end
end
@@ -406,6 +418,7 @@ module ActionDispatch
RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash]
def url_for(options)
+ finalize!
options = default_url_options.merge(options || {})
handle_positional_args(options)
@@ -437,6 +450,7 @@ module ActionDispatch
end
def call(env)
+ finalize!
@set.call(env)
end
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index ec78f53fa6..b8c02f402c 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -72,7 +72,7 @@ module ActionDispatch
# you can do that by including ActionController::UrlFor in your class:
#
# class User < ActiveRecord::Base
- # include ActionController::UrlFor
+ # include Rails.application.routes.url_helpers
#
# def base_uri
# user_path(self)
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 937c9f48d2..ec5e9efe44 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -73,58 +73,6 @@ module ActionDispatch
end
end
- # Asserts that the request was rendered with the appropriate template file or partials
- #
- # ==== Examples
- #
- # # assert that the "new" view template was rendered
- # assert_template "new"
- #
- # # assert that the "_customer" partial was rendered twice
- # assert_template :partial => '_customer', :count => 2
- #
- # # assert that no partials were rendered
- # assert_template :partial => false
- #
- def assert_template(options = {}, message = nil)
- validate_request!
-
- case options
- when NilClass, String
- rendered = (@controller.template.rendered[:template] || []).map { |t| t.identifier }
- msg = build_message(message,
- "expecting <?> but rendering with <?>",
- options, rendered.join(', '))
- assert_block(msg) do
- if options.nil?
- @controller.template.rendered[:template].blank?
- else
- rendered.any? { |t| t.match(options) }
- end
- end
- when Hash
- if expected_partial = options[:partial]
- partials = @controller.template.rendered[:partials]
- if expected_count = options[:count]
- found = partials.detect { |p, _| p.identifier.match(expected_partial) }
- actual_count = found.nil? ? 0 : found.second
- msg = build_message(message,
- "expecting ? to be rendered ? time(s) but rendered ? time(s)",
- expected_partial, expected_count, actual_count)
- assert(actual_count == expected_count.to_i, msg)
- else
- msg = build_message(message,
- "expecting partial <?> but action rendered <?>",
- options[:partial], partials.keys)
- assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
- end
- else
- assert @controller.template.rendered[:partials].empty?,
- "Expected no partials to be rendered"
- end
- end
- end
-
private
# Proxy to to_param if the object will respond to it.
def parameterize(value)
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 1d7e8090e4..1bb81ede3b 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -145,11 +145,25 @@ module ActionDispatch
old_routes, @router = @router, ActionDispatch::Routing::RouteSet.new
old_controller, @controller = @controller, @controller.clone if @controller
_router = @router
- @controller.singleton_class.send(:send, :include, @router.url_helpers) if @controller
+
+ # Unfortunately, there is currently an abstraction leak between AC::Base
+ # and AV::Base which requires having the URL helpers in both AC and AV.
+ # To do this safely at runtime for tests, we need to bump up the helper serial
+ # to that the old AV subclass isn't cached.
+ #
+ # TODO: Make this unnecessary
+ if @controller
+ @controller.singleton_class.send(:include, _router.url_helpers)
+ @controller.view_context_class = Class.new(@controller.view_context_class) do
+ include _router.url_helpers
+ end
+ end
yield @router
ensure
@router = old_routes
- @controller = old_controller if @controller
+ if @controller
+ @controller = old_controller
+ end
end
# ROUTES TODO: These assertions should really work in an integration context
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 0aff4250c1..621d63c5e2 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -2,6 +2,7 @@ require 'stringio'
require 'uri'
require 'active_support/core_ext/object/singleton_class'
require 'rack/test'
+require 'test/unit/assertions'
module ActionDispatch
module Integration #:nodoc:
@@ -177,14 +178,8 @@ module ActionDispatch
reset!
end
- def url_options
- opts = super.reverse_merge(
- :host => host,
- :protocol => https? ? "https" : "http"
- )
-
- opts.merge!(:port => 443) if !opts.key?(:port) && https?
- opts
+ def default_url_options
+ { :host => host, :protocol => https? ? "https" : "http" }
end
# Resets the instance. This can be used to reset the state information
@@ -293,6 +288,8 @@ module ActionDispatch
end
module Runner
+ include ActionDispatch::Assertions
+
def app
@app
end
@@ -300,7 +297,7 @@ module ActionDispatch
# Reset the current session. This is useful for testing multiple sessions
# in a single test case.
def reset!
- @integration_session = open_session
+ @integration_session = Integration::Session.new(app)
end
%w(get post put head delete cookies assigns
@@ -326,30 +323,9 @@ module ActionDispatch
# can use this method to open multiple sessions that ought to be tested
# simultaneously.
def open_session(app = nil)
- session = Integration::Session.new(app || self.app)
-
- # delegate the fixture accessors back to the test instance
- extras = Module.new { attr_accessor :delegate, :test_result }
- if self.class.respond_to?(:fixture_table_names)
- self.class.fixture_table_names.each do |table_name|
- name = table_name.tr(".", "_")
- next unless respond_to?(name)
- extras.__send__(:define_method, name) { |*args|
- delegate.send(name, *args)
- }
- end
+ dup.tap do |session|
+ yield session if block_given?
end
-
- # delegate add_assertion to the test case
- extras.__send__(:define_method, :add_assertion) {
- test_result.add_assertion
- }
- session.extend(extras)
- session.delegate = self
- session.test_result = @_result
-
- yield session if block_given?
- session
end
# Copy the instance variables from the current session instance into the
@@ -460,6 +436,7 @@ module ActionDispatch
# end
class IntegrationTest < ActiveSupport::TestCase
include Integration::Runner
+ include ActionController::TemplateAssertions
@@app = nil
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index afe6386105..5555217ee2 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -44,13 +44,15 @@ module ActionView
autoload :Base
autoload :LookupContext
- autoload :MissingTemplate, 'action_view/base'
autoload :Resolver, 'action_view/template/resolver'
autoload :PathResolver, 'action_view/template/resolver'
autoload :FileSystemResolver, 'action_view/template/resolver'
autoload :PathSet, 'action_view/paths'
+ autoload :MissingTemplate, 'action_view/template/error'
+ autoload :ActionViewError, 'action_view/template/error'
autoload :TemplateError, 'action_view/template/error'
+
autoload :TemplateHandler, 'action_view/template'
autoload :TemplateHandlers, 'action_view/template'
end
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index feaf45c333..919b1e3470 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -1,27 +1,10 @@
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/array/wrap'
module ActionView #:nodoc:
- class ActionViewError < StandardError #:nodoc:
- end
-
- class MissingTemplate < ActionViewError #:nodoc:
- attr_reader :path
-
- def initialize(paths, path, details, partial)
- @path = path
- display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ")
- template_type = if partial
- "partial"
- elsif path =~ /layouts/i
- 'layout'
- else
- 'template'
- end
-
- super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}")
- end
+ class NonConcattingString < ActiveSupport::SafeBuffer
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
@@ -176,14 +159,13 @@ module ActionView #:nodoc:
include Helpers, Rendering, Partials, Layouts, ::ERB::Util, Context
extend ActiveSupport::Memoizable
- ActionView.run_base_hooks(self)
-
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
cattr_accessor :debug_rjs
@@debug_rjs = false
class_attribute :helpers
+ remove_method :helpers
attr_reader :helpers
class << self
@@ -191,8 +173,10 @@ module ActionView #:nodoc:
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
end
+ ActionView.run_base_hooks(self)
+
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
- attr_internal :captures, :request, :layout, :controller, :template, :config
+ attr_internal :captures, :request, :controller, :template, :config
delegate :find_template, :template_exists?, :formats, :formats=, :locale, :locale=,
:view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context
@@ -202,42 +186,17 @@ module ActionView #:nodoc:
delegate :logger, :to => :controller, :allow_nil => true
+ # TODO: HACK FOR RJS
+ def view_context
+ self
+ end
+
def self.xss_safe? #:nodoc:
true
end
def self.process_view_paths(value)
- ActionView::PathSet.new(Array(value))
- end
-
- def self.for_controller(controller)
- @views ||= {}
-
- # TODO: Decouple this so helpers are a separate concern in AV just like
- # they are in AC.
- if controller.class.respond_to?(:_helper_serial)
- klass = @views[controller.class._helper_serial] ||= Class.new(self) do
- # Try to make stack traces clearer
- class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
- def self.name
- "ActionView for #{controller.class}"
- end
-
- def inspect
- "#<#{self.class.name}>"
- end
- ruby_eval
-
- if controller.respond_to?(:_helpers)
- include controller._helpers
- self.helpers = controller._helpers
- end
- end
- else
- klass = self
- end
-
- klass.new(controller.lookup_context, {}, controller)
+ ActionView::PathSet.new(Array.wrap(value))
end
def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc:
@@ -246,7 +205,7 @@ module ActionView #:nodoc:
@helpers = self.class.helpers || Module.new
@_controller = controller
- @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller
+ @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller && controller.respond_to?(:config)
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
@_virtual_path = nil
diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb
index df078a7151..61d2e702a7 100644
--- a/actionpack/lib/action_view/context.rb
+++ b/actionpack/lib/action_view/context.rb
@@ -10,8 +10,6 @@ module ActionView
# In order to work with ActionController, a Context
# must implement:
#
- # Context.for_controller[controller] Create a new ActionView instance for a
- # controller
# Context#render_partial[options]
# - responsible for setting options[:_template]
# - Returns String with the rendered partial
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index e359b0bdac..a50c180f63 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -2,30 +2,32 @@ require 'active_support/benchmarkable'
module ActionView #:nodoc:
module Helpers #:nodoc:
- autoload :ActiveModelHelper, 'action_view/helpers/active_model_helper'
- autoload :AssetTagHelper, 'action_view/helpers/asset_tag_helper'
- autoload :AtomFeedHelper, 'action_view/helpers/atom_feed_helper'
- autoload :CacheHelper, 'action_view/helpers/cache_helper'
- autoload :CaptureHelper, 'action_view/helpers/capture_helper'
- autoload :CsrfHelper, 'action_view/helpers/csrf_helper'
- autoload :DateHelper, 'action_view/helpers/date_helper'
- autoload :DebugHelper, 'action_view/helpers/debug_helper'
- autoload :DeprecatedBlockHelpers, 'action_view/helpers/deprecated_block_helpers'
- autoload :FormHelper, 'action_view/helpers/form_helper'
- autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper'
- autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
- autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper'
- autoload :NumberHelper, 'action_view/helpers/number_helper'
- autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
- autoload :RawOutputHelper, 'action_view/helpers/raw_output_helper'
- autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
- autoload :RecordTagHelper, 'action_view/helpers/record_tag_helper'
- autoload :SanitizeHelper, 'action_view/helpers/sanitize_helper'
- autoload :ScriptaculousHelper, 'action_view/helpers/scriptaculous_helper'
- autoload :TagHelper, 'action_view/helpers/tag_helper'
- autoload :TextHelper, 'action_view/helpers/text_helper'
- autoload :TranslationHelper, 'action_view/helpers/translation_helper'
- autoload :UrlHelper, 'action_view/helpers/url_helper'
+ extend ActiveSupport::Autoload
+
+ autoload :ActiveModelHelper
+ autoload :AssetTagHelper
+ autoload :AtomFeedHelper
+ autoload :CacheHelper
+ autoload :CaptureHelper
+ autoload :CsrfHelper
+ autoload :DateHelper
+ autoload :DebugHelper
+ autoload :DeprecatedBlockHelpers
+ autoload :FormHelper
+ autoload :FormOptionsHelper
+ autoload :FormTagHelper
+ autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
+ autoload :NumberHelper
+ autoload :PrototypeHelper
+ autoload :RawOutputHelper
+ autoload :RecordIdentificationHelper
+ autoload :RecordTagHelper
+ autoload :SanitizeHelper
+ autoload :ScriptaculousHelper
+ autoload :TagHelper
+ autoload :TextHelper
+ autoload :TranslationHelper
+ autoload :UrlHelper
def self.included(base)
base.extend(ClassMethods)
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index e3db2923f7..80b3d3a664 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -3,6 +3,7 @@ require 'action_view/helpers/form_helper'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/object/blank'
module ActionView
ActionView.base_hook do
@@ -127,7 +128,7 @@ module ActionView
object = convert_to_model(object)
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
- (errors = obj.errors[method])
+ (errors = obj.errors[method]).presence
content_tag("div",
"#{options[:prepend_text]}#{ERB::Util.h(errors.first)}#{options[:append_text]}".html_safe,
:class => options[:css_class]
@@ -295,6 +296,10 @@ module ActionView
end
end
+ def error_message
+ object.errors[@method_name]
+ end
+
def column_type
object.send(:column_for_attribute, @method_name).type
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index b594002629..02ad41719b 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -3,6 +3,7 @@ require 'cgi'
require 'action_view/helpers/url_helper'
require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/file'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers #:nodoc:
@@ -623,41 +624,37 @@ module ActionView
@@cache_asset_timestamps = true
private
+ def rewrite_extension?(source, dir, ext)
+ source_ext = File.extname(source)[1..-1]
+ ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
+ end
+
+ def rewrite_host_and_protocol(source, has_request)
+ host = compute_asset_host(source)
+ if has_request && host.present? && !is_uri?(host)
+ host = "#{controller.request.protocol}#{host}"
+ end
+ "#{host}#{source}"
+ end
+
# Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
# Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
# roots. Rewrite the asset path for cache-busting asset ids. Include
# asset host, if configured, with the correct request protocol.
def compute_public_path(source, dir, ext = nil, include_host = true)
- has_request = controller.respond_to?(:request)
-
- source_ext = File.extname(source)[1..-1]
- if ext && !is_uri?(source) && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
- source += ".#{ext}"
- end
+ return source if is_uri?(source)
- unless is_uri?(source)
- source = "/#{dir}/#{source}" unless source[0] == ?/
+ source += ".#{ext}" if rewrite_extension?(source, dir, ext)
+ source = "/#{dir}/#{source}" unless source[0] == ?/
+ source = rewrite_asset_path(source)
- source = rewrite_asset_path(source)
-
- if has_request && include_host
- unless source =~ %r{^#{controller.config.relative_url_root}/}
- source = "#{controller.config.relative_url_root}#{source}"
- end
- end
+ has_request = controller.respond_to?(:request)
+ if has_request && include_host && source !~ %r{^#{controller.config.relative_url_root}/}
+ source = "#{controller.config.relative_url_root}#{source}"
end
+ source = rewrite_host_and_protocol(source, has_request) if include_host
- if include_host && !is_uri?(source)
- host = compute_asset_host(source)
-
- if has_request && !host.blank? && !is_uri?(host)
- host = "#{controller.request.protocol}#{host}"
- end
-
- "#{host}#{source}"
- else
- source
- end
+ source
end
def is_uri?(path)
diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb
index d5cc14b29a..a904af56bb 100644
--- a/actionpack/lib/action_view/helpers/cache_helper.rb
+++ b/actionpack/lib/action_view/helpers/cache_helper.rb
@@ -32,7 +32,28 @@ module ActionView
# <i>Topics listed alphabetically</i>
# <% end %>
def cache(name = {}, options = nil, &block)
- controller.fragment_for(output_buffer, name, options, &block)
+ safe_concat fragment_for(name, options, &block)
+ nil
+ end
+
+ private
+ # TODO: Create an object that has caching read/write on it
+ def fragment_for(name = {}, options = nil, &block) #:nodoc:
+ if controller.perform_caching
+ if controller.fragment_exist?(name, options)
+ controller.read_fragment(name, options)
+ else
+ # VIEW TODO: Make #capture usable outside of ERB
+ # This dance is needed because Builder can't use capture
+ pos = output_buffer.length
+ yield
+ fragment = output_buffer.slice!(pos..-1)
+ controller.write_fragment(name, fragment, options)
+ end
+ else
+ ret = yield
+ ActiveSupport::SafeBuffer.new(ret) if ret.is_a?(String)
+ 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 03c7ba5a87..f0be814700 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -2,22 +2,22 @@ module ActionView
module Helpers
# CaptureHelper exposes methods to let you extract generated markup which
# can be used in other parts of a template or layout file.
- # It provides a method to capture blocks into variables through capture and
+ # It provides a method to capture blocks into variables through capture and
# a way to capture a block of markup for use in a layout through content_for.
module CaptureHelper
- # The capture method allows you to extract part of a template into a
- # variable. You can then use this variable anywhere in your templates or layout.
- #
+ # The capture method allows you to extract part of a template into a
+ # variable. You can then use this variable anywhere in your templates or layout.
+ #
# ==== Examples
# The capture method can be used in ERb templates...
- #
+ #
# <% @greeting = capture do %>
# Welcome to my shiny new web page! The date and time is
# <%= Time.now %>
# <% end %>
#
# ...and Builder (RXML) templates.
- #
+ #
# @timestamp = capture do
# "The current timestamp is #{Time.now}."
# end
@@ -32,16 +32,18 @@ module ActionView
#
def capture(*args)
value = nil
- buffer = with_output_buffer { value = yield *args }
- buffer.presence || value
+ buffer = with_output_buffer { value = yield(*args) }
+ if string = buffer.presence || value and string.is_a?(String)
+ NonConcattingString.new(string)
+ end
end
# Calling content_for stores a block of markup in an identifier for later use.
# You can make subsequent calls to the stored content in other templates or the layout
# by passing the identifier as an argument to <tt>yield</tt>.
- #
+ #
# ==== Examples
- #
+ #
# <% content_for :not_authorized do %>
# alert('You are not authorized to do that!')
# <% end %>
@@ -75,7 +77,7 @@ module ActionView
#
# Then, in another view, you could to do something like this:
#
- # <%= link_to_remote 'Logout', :action => 'logout' %>
+ # <%= link_to 'Logout', :action => 'logout', :remote => true %>
#
# <% content_for :script do %>
# <%= javascript_include_tag :defaults %>
@@ -92,7 +94,7 @@ module ActionView
# <% end %>
#
# <%# Add some other content, or use a different template: %>
- #
+ #
# <% content_for :navigation do %>
# <li><%= link_to 'Login', :action => 'login' %></li>
# <% end %>
@@ -109,13 +111,13 @@ module ActionView
# for elements that will be fragment cached.
def content_for(name, content = nil, &block)
content = capture(&block) if block_given?
- return @_content_for[name] << content if content
- @_content_for[name]
+ @_content_for[name] << content if content
+ @_content_for[name] unless content
end
# content_for? simply checks whether any content has been captured yet using content_for
# Useful to render parts of your layout differently based on what is in your views.
- #
+ #
# ==== Examples
#
# Perhaps you will use different css in you layout if no content_for :right_column
diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb
deleted file mode 100644
index 3d0657e873..0000000000
--- a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module ActionView
- module Helpers
- module DeprecatedBlockHelpers
- extend ActiveSupport::Concern
-
- include ActionView::Helpers::TagHelper
- include ActionView::Helpers::TextHelper
- include ActionView::Helpers::JavaScriptHelper
- include ActionView::Helpers::FormHelper
-
- def content_tag(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- def javascript_tag(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- def form_for(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- def form_tag(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- def fields_for(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- def field_set_tag(*, &block)
- block_called_from_erb?(block) ? safe_concat(super) : super
- end
-
- BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template'
-
- if RUBY_VERSION < '1.9.0'
- # Check whether we're called from an erb template.
- # We'd return a string in any other case, but erb <%= ... %>
- # can't take an <% end %> later on, so we have to use <% ... %>
- # and implicitly concat.
- def block_called_from_erb?(block)
- block && eval(BLOCK_CALLED_FROM_ERB, block)
- end
- else
- def block_called_from_erb?(block)
- block && eval(BLOCK_CALLED_FROM_ERB, block.binding)
- end
- end
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 6176f1fb06..2ba5339b7d 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -1014,7 +1014,7 @@ module ActionView
class FormBuilder #:nodoc:
# The methods which wrap a form helper call.
class_inheritable_accessor :field_helpers
- self.field_helpers = (FormHelper.instance_methods - ['form_for'])
+ self.field_helpers = (FormHelper.instance_method_names - ['form_for'])
attr_accessor :object_name, :object, :options
@@ -1040,7 +1040,7 @@ module ActionView
end
(field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector|
- src = <<-end_src
+ src, file, line = <<-end_src, __FILE__, __LINE__ + 1
def #{selector}(method, options = {}) # def text_field(method, options = {})
@template.send( # @template.send(
#{selector.inspect}, # "text_field",
@@ -1049,7 +1049,7 @@ module ActionView
objectify_options(options)) # objectify_options(options))
end # end
end_src
- class_eval src, __FILE__, __LINE__
+ class_eval src, file, line
end
def fields_for(record_or_name_or_array, *args, &block)
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 07eee3b399..b0a7718f22 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -1,5 +1,4 @@
require 'action_view/helpers/tag_helper'
-require 'action_view/helpers/prototype_helper'
module ActionView
module Helpers
@@ -89,6 +88,93 @@ module ActionView
def javascript_cdata_section(content) #:nodoc:
"\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
end
+
+ # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
+ # onclick handler.
+ #
+ # The first argument +name+ is used as the button's value or display text.
+ #
+ # The next arguments are optional and may include the javascript function definition and a hash of html_options.
+ #
+ # The +function+ argument can be omitted in favor of an +update_page+
+ # block, which evaluates to a string when the template is rendered
+ # (instead of making an Ajax request first).
+ #
+ # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
+ #
+ # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
+ #
+ # Examples:
+ # button_to_function "Greeting", "alert('Hello world!')"
+ # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
+ # button_to_function "Details" do |page|
+ # page[:details].visual_effect :toggle_slide
+ # end
+ # button_to_function "Details", :class => "details_button" do |page|
+ # page[:details].visual_effect :toggle_slide
+ # end
+ def button_to_function(name, *args, &block)
+ html_options = args.extract_options!.symbolize_keys
+
+ function = block_given? ? update_page(&block) : args[0] || ''
+ onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
+
+ tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
+ end
+
+ # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
+ # onclick handler and return false after the fact.
+ #
+ # The first argument +name+ is used as the link text.
+ #
+ # The next arguments are optional and may include the javascript function definition and a hash of html_options.
+ #
+ # The +function+ argument can be omitted in favor of an +update_page+
+ # block, which evaluates to a string when the template is rendered
+ # (instead of making an Ajax request first).
+ #
+ # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
+ #
+ # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
+ #
+ #
+ # Examples:
+ # link_to_function "Greeting", "alert('Hello world!')"
+ # Produces:
+ # <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
+ #
+ # link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
+ # Produces:
+ # <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
+ # <img src="/images/delete.png?" alt="Delete"/>
+ # </a>
+ #
+ # link_to_function("Show me more", nil, :id => "more_link") do |page|
+ # page[:details].visual_effect :toggle_blind
+ # page[:more_link].replace_html "Show me less"
+ # end
+ # Produces:
+ # <a href="#" id="more_link" onclick="try {
+ # $(&quot;details&quot;).visualEffect(&quot;toggle_blind&quot;);
+ # $(&quot;more_link&quot;).update(&quot;Show me less&quot;);
+ # }
+ # catch (e) {
+ # alert('RJS error:\n\n' + e.toString());
+ # alert('$(\&quot;details\&quot;).visualEffect(\&quot;toggle_blind\&quot;);
+ # \n$(\&quot;more_link\&quot;).update(\&quot;Show me less\&quot;);');
+ # throw e
+ # };
+ # return false;">Show me more</a>
+ #
+ def link_to_function(name, *args, &block)
+ html_options = args.extract_options!.symbolize_keys
+
+ function = block_given? ? update_page(&block) : args[0] || ''
+ onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
+ href = html_options[:href] || '#'
+
+ content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 46e41bc406..719b64b940 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -3,10 +3,24 @@ require 'active_support/core_ext/float/rounding'
module ActionView
module Helpers #:nodoc:
+
# Provides methods for converting numbers into formatted strings.
# Methods are provided for phone numbers, currency, percentage,
- # precision, positional notation, and file size.
+ # precision, positional notation, file size and pretty printing.
+ #
+ # Most methods expect a +number+ argument, and will return it
+ # unchanged if can't be converted into a valid number.
module NumberHelper
+
+ # Raised when argument +number+ param given to the helpers is invalid and
+ # the option :raise is set to +true+.
+ class InvalidNumberError < StandardError
+ attr_accessor :number
+ def initialize(number)
+ @number = number
+ end
+ end
+
# Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
# in the +options+ hash.
#
@@ -30,6 +44,17 @@ module ActionView
def number_to_phone(number, options = {})
return nil if number.nil?
+ begin
+ Float(number)
+ is_number_html_safe = true
+ rescue ArgumentError, TypeError
+ if options[:raise]
+ raise InvalidNumberError, number
+ else
+ is_number_html_safe = number.to_s.html_safe?
+ end
+ end
+
number = number.to_s.strip
options = options.symbolize_keys
area_code = options[:area_code] || nil
@@ -46,7 +71,7 @@ module ActionView
number.starts_with?('-') ? number.slice!(1..-1) : number
end
str << " x #{extension}" unless extension.blank?
- str
+ is_number_html_safe ? str.html_safe : str
end
# Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
@@ -72,38 +97,42 @@ module ActionView
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
# # => 1234567890,50 &pound;
def number_to_currency(number, options = {})
+ return nil if number.nil?
+
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
- currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
+ currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
defaults = defaults.merge(currency)
- precision = options[:precision] || defaults[:precision]
- unit = options[:unit] || defaults[:unit]
- separator = options[:separator] || defaults[:separator]
- delimiter = options[:delimiter] || defaults[:delimiter]
- format = options[:format] || defaults[:format]
- separator = '' if precision == 0
+ options = options.reverse_merge(defaults)
- value = number_with_precision(number,
- :precision => precision,
- :delimiter => delimiter,
- :separator => separator)
+ unit = options.delete(:unit)
+ format = options.delete(:format)
- if value
+ begin
+ value = number_with_precision(number, options.merge(:raise => true))
format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
- else
- number
+ rescue InvalidNumberError => e
+ if options[:raise]
+ raise
+ else
+ formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit)
+ e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
+ end
end
+
end
# Formats a +number+ as a percentage string (e.g., 65%). You can customize the
# format in the +options+ hash.
#
# ==== Options
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
+ # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +false+)
#
# ==== Examples
# number_to_percentage(100) # => 100.000%
@@ -111,21 +140,25 @@ module ActionView
# number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
# number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
def number_to_percentage(number, options = {})
+ return nil if number.nil?
+
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
- percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :raise => true) rescue {}
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
+ percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
defaults = defaults.merge(percentage)
- precision = options[:precision] || defaults[:precision]
- separator = options[:separator] || defaults[:separator]
- delimiter = options[:delimiter] || defaults[:delimiter]
+ options = options.reverse_merge(defaults)
- value = number_with_precision(number,
- :precision => precision,
- :separator => separator,
- :delimiter => delimiter)
- value ? value + "%" : number
+ begin
+ "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
+ rescue InvalidNumberError => e
+ if options[:raise]
+ raise
+ else
+ e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
+ end
+ end
end
# Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
@@ -133,7 +166,7 @@ module ActionView
#
# ==== Options
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
#
# ==== Examples
# number_with_delimiter(12345678) # => 12,345,678
@@ -146,148 +179,186 @@ module ActionView
# You can still use <tt>number_with_delimiter</tt> with the old API that accepts the
# +delimiter+ as its optional second and the +separator+ as its
# optional third parameter:
- # number_with_delimiter(12345678, " ") # => 12 345.678
+ # number_with_delimiter(12345678, " ") # => 12 345 678
# number_with_delimiter(12345678.05, ".", ",") # => 12.345.678,05
def number_with_delimiter(number, *args)
options = args.extract_options!
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
+ begin
+ Float(number)
+ rescue ArgumentError, TypeError
+ if options[:raise]
+ raise InvalidNumberError, number
+ else
+ return number
+ end
+ end
+
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
unless args.empty?
ActiveSupport::Deprecation.warn('number_with_delimiter takes an option hash ' +
'instead of separate delimiter and precision arguments.', caller)
- delimiter = args[0] || defaults[:delimiter]
- separator = args[1] || defaults[:separator]
+ options[:delimiter] ||= args[0] if args[0]
+ options[:separator] ||= args[1] if args[1]
end
- delimiter ||= (options[:delimiter] || defaults[:delimiter])
- separator ||= (options[:separator] || defaults[:separator])
+ options = options.reverse_merge(defaults)
parts = number.to_s.split('.')
- if parts[0]
- parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
- parts.join(separator)
- else
- number
- end
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
+ parts.join(options[:separator]).html_safe
+
end
- # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
+ # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision
+ # of 2 if +:significant+ is +false+, and 5 if +:significant+ is +true+).
# You can customize the format in the +options+ hash.
#
# ==== Options
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
+ # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +false+)
#
# ==== Examples
- # number_with_precision(111.2345) # => 111.235
- # number_with_precision(111.2345, :precision => 2) # => 111.23
- # number_with_precision(13, :precision => 5) # => 13.00000
- # number_with_precision(389.32314, :precision => 0) # => 389
+ # number_with_precision(111.2345) # => 111.235
+ # number_with_precision(111.2345, :precision => 2) # => 111.23
+ # number_with_precision(13, :precision => 5) # => 13.00000
+ # number_with_precision(389.32314, :precision => 0) # => 389
+ # number_with_precision(111.2345, :significant => true) # => 111
+ # number_with_precision(111.2345, :precision => 1, :significant => true) # => 100
+ # number_with_precision(13, :precision => 5, :significant => true) # => 13.000
+ # number_with_precision(13, :precision => 5, :significant => true, strip_insignificant_zeros => true)
+ # # => 13
+ # number_with_precision(389.32314, :precision => 4, :significant => true) # => 389.3
# number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
# # => 1.111,23
#
# You can still use <tt>number_with_precision</tt> with the old API that accepts the
# +precision+ as its optional second parameter:
- # number_with_precision(number_with_precision(111.2345, 2) # => 111.23
+ # number_with_precision(111.2345, 2) # => 111.23
def number_with_precision(number, *args)
+
options = args.extract_options!
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
- precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale],
- :raise => true) rescue {}
+ number = begin
+ Float(number)
+ rescue ArgumentError, TypeError
+ if options[:raise]
+ raise InvalidNumberError, number
+ else
+ return number
+ end
+ end
+
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
+ precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
defaults = defaults.merge(precision_defaults)
+ #Backwards compatibility
unless args.empty?
ActiveSupport::Deprecation.warn('number_with_precision takes an option hash ' +
'instead of a separate precision argument.', caller)
- precision = args[0] || defaults[:precision]
+ options[:precision] ||= args[0] if args[0]
end
- precision ||= (options[:precision] || defaults[:precision])
- separator ||= (options[:separator] || defaults[:separator])
- delimiter ||= (options[:delimiter] || defaults[:delimiter])
+ options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
+ precision = options.delete :precision
+ significant = options.delete :significant
+ strip_insignificant_zeros = options.delete :strip_insignificant_zeros
- begin
- value = Float(number)
- rescue ArgumentError, TypeError
- value = nil
+ if significant and precision > 0
+ digits = (Math.log10(number) + 1).floor
+ rounded_number = BigDecimal.new((number / 10 ** (digits - precision)).to_s).round.to_f * 10 ** (digits - precision)
+ precision = precision - digits
+ precision = precision > 0 ? precision : 0 #don't let it be negative
+ else
+ rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision
end
-
- if value
- rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision
- number_with_delimiter("%01.#{precision}f" % rounded_number,
- :separator => separator,
- :delimiter => delimiter)
+ formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options)
+ if strip_insignificant_zeros
+ escaped_separator = Regexp.escape(options[:separator])
+ formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe
else
- number
+ formatted_number
end
+
end
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
- # Formats the bytes in +size+ into a more understandable representation
+ # Formats the bytes in +number+ into a more understandable representation
# (e.g., giving it 1500 yields 1.5 KB). This method is useful for
- # reporting file sizes to users. This method returns nil if
- # +size+ cannot be converted into a number. You can customize the
+ # reporting file sizes to users. You can customize the
# format in the +options+ hash.
#
+ # See <tt>number_to_human</tt> if you want to pretty-print a generic number.
+ #
# ==== Options
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 1).
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
+ # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
- #
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
# ==== Examples
# number_to_human_size(123) # => 123 Bytes
- # number_to_human_size(1234) # => 1.2 KB
+ # number_to_human_size(1234) # => 1.21 KB
# number_to_human_size(12345) # => 12.1 KB
- # number_to_human_size(1234567) # => 1.2 MB
- # number_to_human_size(1234567890) # => 1.1 GB
- # number_to_human_size(1234567890123) # => 1.1 TB
- # number_to_human_size(1234567, :precision => 2) # => 1.18 MB
- # number_to_human_size(483989, :precision => 0) # => 473 KB
- # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB
+ # number_to_human_size(1234567) # => 1.18 MB
+ # number_to_human_size(1234567890) # => 1.15 GB
+ # number_to_human_size(1234567890123) # => 1.12 TB
+ # number_to_human_size(1234567, :precision => 2) # => 1.2 MB
+ # number_to_human_size(483989, :precision => 2) # => 470 KB
+ # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,2 MB
#
- # Zeros after the decimal point are always stripped out, regardless of the
- # specified precision:
- # helper.number_to_human_size(1234567890123, :precision => 5) # => "1.12283 TB"
- # helper.number_to_human_size(524288000, :precision=>5) # => "500 MB"
+ # Unsignificant zeros after the fractional separator are stripped out by default (set
+ # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
+ # number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB"
+ # number_to_human_size(524288000, :precision=>5) # => "500 MB"
#
# You can still use <tt>number_to_human_size</tt> with the old API that accepts the
# +precision+ as its optional second parameter:
- # number_to_human_size(1234567, 2) # => 1.18 MB
- # number_to_human_size(483989, 0) # => 473 KB
+ # number_to_human_size(1234567, 1) # => 1 MB
+ # number_to_human_size(483989, 2) # => 470 KB
def number_to_human_size(number, *args)
- return nil if number.nil?
-
options = args.extract_options!
options.symbolize_keys!
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
- human = I18n.translate(:'number.human.format', :locale => options[:locale], :raise => true) rescue {}
+ number = begin
+ Float(number)
+ rescue ArgumentError, TypeError
+ if options[:raise]
+ raise InvalidNumberError, number
+ else
+ return number
+ end
+ end
+
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
+ human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
defaults = defaults.merge(human)
unless args.empty?
ActiveSupport::Deprecation.warn('number_to_human_size takes an option hash ' +
'instead of a separate precision argument.', caller)
- precision = args[0] || defaults[:precision]
+ options[:precision] ||= args[0] if args[0]
end
- precision ||= (options[:precision] || defaults[:precision])
- separator ||= (options[:separator] || defaults[:separator])
- delimiter ||= (options[:delimiter] || defaults[:delimiter])
+ options = options.reverse_merge(defaults)
+ #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
+ options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
if number.to_i < 1024
unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
- storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit)
+ storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe
else
max_exp = STORAGE_UNITS.size - 1
- number = Float(number)
exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
number /= 1024 ** exponent
@@ -295,15 +366,138 @@ module ActionView
unit_key = STORAGE_UNITS[exponent]
unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
- escaped_separator = Regexp.escape(separator)
- formatted_number = number_with_precision(number,
- :precision => precision,
- :separator => separator,
- :delimiter => delimiter
- ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
- storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
+ formatted_number = number_with_precision(number, options)
+ storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe
+ end
+ end
+
+ DECIMAL_UNITS = {0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
+ -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}.freeze
+
+ # Pretty prints (formats and approximates) a number in a way it is more readable by humans
+ # (eg.: 1200000000 becomes "1.2 Billion"). This is useful for numbers that
+ # can get very large (and too hard to read).
+ #
+ # See <tt>number_to_human_size</tt> if you want to print a file size.
+ #
+ # You can also define you own unit-quantifier names if you want to use other decimal units
+ # (eg.: 1500 becomes "1.5 kilometers", 0.150 becomes "150 mililiters", etc). You may define
+ # a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).
+ #
+ # ==== Options
+ # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
+ # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
+ # * <tt>:units</tt> - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:
+ # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>, <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>, <tt>:billion</tt>, <tt>:trillion</tt>, <tt>:quadrillion</tt>
+ # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>, <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>, <tt>:pico</tt>, <tt>:femto</tt>
+ # * <tt>:format</tt> - Sets the format of the output string (defaults to "%n %u"). The field types are:
+ #
+ # %u The quantifier (ex.: 'thousand')
+ # %n The number
+ #
+ # ==== Examples
+ # number_to_human(123) # => "123"
+ # number_to_human(1234) # => "1.23 Thousand"
+ # number_to_human(12345) # => "12.3 Thousand"
+ # number_to_human(1234567) # => "1.23 Million"
+ # number_to_human(1234567890) # => "1.23 Billion"
+ # number_to_human(1234567890123) # => "1.23 Trillion"
+ # number_to_human(1234567890123456) # => "1.23 Quadrillion"
+ # number_to_human(1234567890123456789) # => "1230 Quadrillion"
+ # number_to_human(489939, :precision => 2) # => "490 Thousand"
+ # number_to_human(489939, :precision => 4) # => "489.9 Thousand"
+ # number_to_human(1234567, :precision => 4,
+ # :significant => false) # => "1.2346 Million"
+ # number_to_human(1234567, :precision => 1,
+ # :separator => ',',
+ # :significant => false) # => "1,2 Million"
+ #
+ # Unsignificant zeros after the decimal separator are stripped out by default (set
+ # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
+ # number_to_human(12345012345, :significant_digits => 6) # => "12.345 Billion"
+ # number_to_human(500000000, :precision=>5) # => "500 Million"
+ #
+ # ==== Custom Unit Quantifiers
+ #
+ # You can also use your own custom unit quantifiers:
+ # number_to_human(500000, :units => {:unit => "ml", :thousand => "lt"}) # => "500 lt"
+ #
+ # If in your I18n locale you have:
+ # distance:
+ # centi:
+ # one: "centimeter"
+ # other: "centimeters"
+ # unit:
+ # one: "meter"
+ # other: "meters"
+ # thousand:
+ # one: "kilometer"
+ # other: "kilometers"
+ # billion: "gazilion-distance"
+ #
+ # Then you could do:
+ #
+ # number_to_human(543934, :units => :distance) # => "544 kilometers"
+ # number_to_human(54393498, :units => :distance) # => "54400 kilometers"
+ # number_to_human(54393498000, :units => :distance) # => "54.4 gazilion-distance"
+ # number_to_human(343, :units => :distance, :precision => 1) # => "300 meters"
+ # number_to_human(1, :units => :distance) # => "1 meter"
+ # number_to_human(0.34, :units => :distance) # => "34 centimeters"
+ #
+ def number_to_human(number, options = {})
+ options.symbolize_keys!
+
+ number = begin
+ Float(number)
+ rescue ArgumentError, TypeError
+ if options[:raise]
+ raise InvalidNumberError, number
+ else
+ return number
+ end
end
+
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
+ human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
+ defaults = defaults.merge(human)
+
+ options = options.reverse_merge(defaults)
+ #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
+ options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
+
+ units = options.delete :units
+ unit_exponents = case units
+ when Hash
+ units
+ when String, Symbol
+ I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
+ when nil
+ I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true)
+ else
+ raise ArgumentError, ":units must be a Hash or String translation scope."
+ end.keys.map{|e_name| DECIMAL_UNITS.invert[e_name] }.sort_by{|e| -e}
+
+ number_exponent = Math.log10(number).floor
+ display_exponent = unit_exponents.find{|e| number_exponent >= e }
+ number /= 10 ** display_exponent
+
+ unit = case units
+ when Hash
+ units[DECIMAL_UNITS[display_exponent]]
+ when String, Symbol
+ I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
+ else
+ I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
+ end
+
+ decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u")
+ formatted_number = number_with_precision(number, options)
+ decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
end
+
end
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index dc3c6d88f5..ccdc8181db 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -102,39 +102,6 @@ module ActionView
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
end
- # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
- # onclick handler.
- #
- # The first argument +name+ is used as the button's value or display text.
- #
- # The next arguments are optional and may include the javascript function definition and a hash of html_options.
- #
- # The +function+ argument can be omitted in favor of an +update_page+
- # block, which evaluates to a string when the template is rendered
- # (instead of making an Ajax request first).
- #
- # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
- #
- # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
- #
- # Examples:
- # button_to_function "Greeting", "alert('Hello world!')"
- # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
- # button_to_function "Details" do |page|
- # page[:details].visual_effect :toggle_slide
- # end
- # button_to_function "Details", :class => "details_button" do |page|
- # page[:details].visual_effect :toggle_slide
- # end
- def button_to_function(name, *args, &block)
- html_options = args.extract_options!.symbolize_keys
-
- function = block_given? ? update_page(&block) : args[0] || ''
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
-
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
- end
-
# Returns the JavaScript needed for a remote function.
# Takes the same arguments as link_to_remote.
#
@@ -181,11 +148,9 @@ module ActionView
class JavaScriptGenerator #:nodoc:
def initialize(context, &block) #:nodoc:
@context, @lines = context, []
- @context.update_details(:formats => [:js, :html]) do
- include_helpers_from_context
- @context.with_output_buffer(@lines) do
- @context.instance_exec(self, &block)
- end
+ include_helpers_from_context
+ @context.with_output_buffer(@lines) do
+ @context.instance_exec(self, &block)
end
end
@@ -615,7 +580,7 @@ module ActionView
# page.hide 'spinner'
# end
def update_page(&block)
- JavaScriptGenerator.new(@template, &block).to_s.html_safe
+ JavaScriptGenerator.new(view_context, &block).to_s.html_safe
end
# Works like update_page but wraps the generated JavaScript in a <script>
@@ -689,6 +654,10 @@ module ActionView
@generator << root if root
end
+ def is_a?(klass)
+ klass == JavaScriptProxy
+ end
+
private
def method_missing(method, *arguments, &block)
if method.to_s =~ /(.*)=$/
@@ -882,5 +851,3 @@ module ActionView
end
end
end
-
-require 'action_view/helpers/javascript_helper'
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index e1ce65f90a..27be1690dd 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -29,7 +29,7 @@ module ActionView
end
def safe_concat(string)
- output_buffer.safe_concat(string)
+ output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
end
# Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
@@ -576,7 +576,7 @@ module ActionView
# each email is yielded and the result is used as the link text.
def auto_link_email_addresses(text, html_options = {})
body = text.dup
- text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
+ text.gsub(/([\w\.!#\$%\-+]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
text = $1
if body.match(/<a\b[^>]*>(.*)(#{Regexp.escape(text)})(.*)<\/a>/)
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index 8a89ee58a0..457944dbb6 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -13,7 +13,7 @@ module ActionView
def translate(key, options = {})
options[:raise] = true
translation = I18n.translate(scope_key_by_partial(key), options)
- translation.is_a?(Array) ? translation.map { |entry| entry.html_safe } : translation.html_safe
+ (translation.respond_to?(:join) ? translation.join : translation).html_safe
rescue I18n::MissingTranslationData => e
keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
content_tag('span', keys.join(', '), :class => 'translation_missing')
@@ -29,9 +29,10 @@ module ActionView
private
def scope_key_by_partial(key)
- if (key.respond_to?(:join) ? key.join : key.to_s).first == "."
+ strkey = key.respond_to?(:join) ? key.join : key.to_s
+ if strkey.first == "."
if @_virtual_path
- @_virtual_path.gsub(%r{/_?}, ".") + key.to_s
+ @_virtual_path.gsub(%r{/_?}, ".") + strkey
else
raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 131e950b18..b23d5fcb68 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -1,6 +1,7 @@
require 'action_view/helpers/javascript_helper'
require 'active_support/core_ext/array/access'
require 'active_support/core_ext/hash/keys'
+require 'action_dispatch'
module ActionView
module Helpers #:nodoc:
@@ -9,6 +10,9 @@ module ActionView
# This allows you to use the same format for links in views
# and controllers.
module UrlHelper
+ extend ActiveSupport::Concern
+
+ include ActionDispatch::Routing::UrlFor
include JavaScriptHelper
# Need to map default url options to controller one.
@@ -16,6 +20,10 @@ module ActionView
controller.send(:default_url_options, *args)
end
+ def url_options
+ controller.url_options
+ end
+
# Returns the URL for the set of +options+ provided. This takes the
# same options as +url_for+ in Action Controller (see the
# documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
@@ -206,7 +214,7 @@ module ActionView
if block_given?
options = args.first || {}
html_options = args.second
- safe_concat(link_to(capture(&block), options, html_options))
+ link_to(capture(&block), options, html_options)
else
name = args[0]
options = args[1] || {}
@@ -578,8 +586,6 @@ module ActionView
add_confirm_to_attributes!(html_options, confirm) if confirm
add_method_to_attributes!(html_options, method) if method
- html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
-
html_options
end
diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml
index a3548051c1..a3e2230f6f 100644
--- a/actionpack/lib/action_view/locale/en.yml
+++ b/actionpack/lib/action_view/locale/en.yml
@@ -9,6 +9,11 @@
delimiter: ","
# Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
precision: 3
+ # If set to true, precision will mean the number of significant digits instead
+ # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
+ significant: false
+ # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
+ strip_insignificant_zeros: false
# Used in number_to_currency()
currency:
@@ -16,34 +21,43 @@
# Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
format: "%u%n"
unit: "$"
- # These three are to override number.format and are optional
+ # These five are to override number.format and are optional
separator: "."
delimiter: ","
precision: 2
+ significant: false
+ strip_insignificant_zeros: false
# Used in number_to_percentage()
percentage:
format:
- # These three are to override number.format and are optional
+ # These five are to override number.format and are optional
# separator:
delimiter: ""
# precision:
+ # significant: false
+ # strip_insignificant_zeros: false
# Used in number_to_precision()
precision:
format:
- # These three are to override number.format and are optional
+ # These five are to override number.format and are optional
# separator:
delimiter: ""
# precision:
+ # significant: false
+ # strip_insignificant_zeros: false
- # Used in number_to_human_size()
+ # Used in number_to_human_size() and number_to_human()
human:
format:
- # These three are to override number.format and are optional
+ # These five are to override number.format and are optional
# separator:
delimiter: ""
- precision: 1
+ precision: 3
+ significant: true
+ strip_insignificant_zeros: true
+ # Used in number_to_human_size()
storage_units:
# Storage units output formatting.
# %u is the storage unit, %n is the number (default: 2 MB)
@@ -56,6 +70,31 @@
mb: "MB"
gb: "GB"
tb: "TB"
+ # Used in number_to_human()
+ decimal_units:
+ format: "%n %u"
+ # Decimal units output formatting
+ # By default we will only quantify some of the exponents
+ # but the commented ones might be defined or overridden
+ # by the user.
+ units:
+ # femto: Quadrillionth
+ # pico: Trillionth
+ # nano: Billionth
+ # micro: Millionth
+ # mili: Thousandth
+ # centi: Hundredth
+ # deci: Tenth
+ unit: ""
+ # ten:
+ # one: Ten
+ # other: Tens
+ # hundred: Hundred
+ thousand: Thousand
+ million: Million
+ billion: Billion
+ trillion: Trillion
+ quadrillion: Quadrillion
# Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
datetime:
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 8eb17bf8f1..9b59aac0eb 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -1,4 +1,4 @@
-require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/object/blank'
module ActionView
@@ -15,23 +15,26 @@ module ActionView
def self.register_detail(name, options = {}, &block)
self.registered_details << name
+ Accessors.send :define_method, :"_#{name}_defaults", &block
+ Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1
+ def #{name}
+ @details[:#{name}]
+ end
- Setters.send :define_method, :"_#{name}_defaults", &block
- Setters.module_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{name}=(value)
- value = Array(value.presence || _#{name}_defaults)
- #{"value << nil unless value.include?(nil)" unless options[:allow_nil] == false}
+ value = Array.wrap(value.presence || _#{name}_defaults)
- unless value == @details[:#{name}]
- @details_key, @details = nil, @details.merge(:#{name} => value)
- @details.freeze
+ if value != @details[:#{name}]
+ @details_key = nil
+ @details = @details.dup if @details.frozen?
+ @details[:#{name}] = value.freeze
end
end
METHOD
end
- # Holds raw setters for the registered details.
- module Setters #:nodoc:
+ # Holds accessors for the registered details.
+ module Accessors #:nodoc:
end
register_detail(:formats) { Mime::SET.symbols }
@@ -45,7 +48,7 @@ module ActionView
@details_keys = Hash.new
def self.get(details)
- @details_keys[details] ||= new
+ @details_keys[details.freeze] ||= new
end
def initialize
@@ -54,9 +57,10 @@ module ActionView
end
def initialize(view_paths, details = {})
- @details, @details_key = {}, nil
+ @details, @details_key = { :handlers => default_handlers }, nil
+ @frozen_formats = false
self.view_paths = view_paths
- self.details = details
+ self.update_details(details, true)
end
module ViewPaths
@@ -69,16 +73,16 @@ module ActionView
end
def find(name, prefix = nil, partial = false)
- @view_paths.find(name, prefix, partial, details, details_key)
+ @view_paths.find(*args_for_lookup(name, prefix, partial))
end
alias :find_template :find
def find_all(name, prefix = nil, partial = false)
- @view_paths.find_all(name, prefix, partial, details, details_key)
+ @view_paths.find_all(*args_for_lookup(name, prefix, partial))
end
def exists?(name, prefix = nil, partial = false)
- @view_paths.exists?(name, prefix, partial, details, details_key)
+ @view_paths.exists?(*args_for_lookup(name, prefix, partial))
end
alias :template_exists? :exists?
@@ -94,51 +98,80 @@ module ActionView
ensure
added_resolvers.times { view_paths.pop }
end
- end
- module Details
- attr_reader :details
+ protected
+
+ def args_for_lookup(name, prefix, partial) #:nodoc:
+ name, prefix = normalize_name(name, prefix)
+ [name, prefix, partial || false, @details, details_key]
+ end
+
+ # Support legacy foo.erb names even though we now ignore .erb
+ # as well as incorrectly putting part of the path in the template
+ # name instead of the prefix.
+ def normalize_name(name, prefix) #:nodoc:
+ name = name.to_s.gsub(handlers_regexp, '')
+ parts = name.split('/')
+ return parts.pop, [prefix, *parts].compact.join("/")
+ end
- def details=(given_details)
- registered_details.each { |key| send(:"#{key}=", given_details[key]) }
+ def default_handlers #:nodoc:
+ @default_handlers ||= Template::Handlers.extensions
end
- def details_key
+ def handlers_regexp #:nodoc:
+ @handlers_regexp ||= /\.(?:#{default_handlers.join('|')})$/
+ end
+ end
+
+ module Details
+ # Calculate the details key. Remove the handlers from calculation to improve performance
+ # since the user cannot modify it explicitly.
+ def details_key #:nodoc:
@details_key ||= DetailsKey.get(@details)
end
- # Shortcut to read formats from details.
- def formats
- @details[:formats].compact
+ # Freeze the current formats in the lookup context. By freezing them, you are guaranteeing
+ # that next template lookups are not going to modify the formats. The controller can also
+ # use this, to ensure that formats won't be further modified (as it does in respond_to blocks).
+ def freeze_formats(formats, unless_frozen=false) #:nodoc:
+ return if unless_frozen && @frozen_formats
+ self.formats = formats
+ @frozen_formats = true
end
# Overload formats= to reject [:"*/*"] values.
- def formats=(value, freeze=true)
- value = nil if value == [:"*/*"]
+ def formats=(value)
+ value = nil if value == [:"*/*"]
+ value << :html if value == [:js]
super(value)
end
- # Shortcut to read locale.
+ # Overload locale to return a symbol instead of array
def locale
- I18n.locale
+ @details[:locale].first
end
# Overload locale= to also set the I18n.locale. If the current I18n.config object responds
# to i18n_config, it means that it's has a copy of the original I18n configuration and it's
# acting as proxy, which we need to skip.
def locale=(value)
- value = value.first if value.is_a?(Array)
- config = I18n.config.respond_to?(:i18n_config) ? I18n.config.i18n_config : I18n.config
- config.locale = value if value
+ if value
+ config = I18n.config.respond_to?(:i18n_config) ? I18n.config.i18n_config : I18n.config
+ config.locale = value
+ end
super(I18n.locale)
end
# Update the details keys by merging the given hash into the current
# details hash. If a block is given, the details are modified just during
# the execution of the block and reverted to the previous value after.
- def update_details(new_details)
- old_details = @details
- self.details = old_details.merge(new_details)
+ def update_details(new_details, force=false)
+ old_details = @details.dup
+
+ registered_details.each do |key|
+ send(:"#{key}=", new_details[key]) if force || new_details.key?(key)
+ end
if block_given?
begin
@@ -150,7 +183,7 @@ module ActionView
end
end
- include Setters
+ include Accessors
include Details
include ViewPaths
end
diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb
index 2e5d115630..9cf007cd2b 100644
--- a/actionpack/lib/action_view/railtie.rb
+++ b/actionpack/lib/action_view/railtie.rb
@@ -3,10 +3,10 @@ require "rails"
module ActionView
class Railtie < Rails::Railtie
- railtie_name :action_view
+ config.action_view = ActiveSupport::OrderedOptions.new
require "action_view/railties/log_subscriber"
- log_subscriber ActionView::Railties::LogSubscriber.new
+ log_subscriber :action_view, ActionView::Railties::LogSubscriber.new
initializer "action_view.cache_asset_timestamps" do |app|
unless app.config.cache_classes
@@ -15,5 +15,13 @@ module ActionView
end
end
end
+
+ initializer "action_view.set_configs" do |app|
+ ActionView.base_hook do
+ app.config.action_view.each do |k,v|
+ send "#{k}=", v
+ end
+ end
+ end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb
index 11ff05ce5b..578f39d817 100644
--- a/actionpack/lib/action_view/render/layouts.rb
+++ b/actionpack/lib/action_view/render/layouts.rb
@@ -43,10 +43,16 @@ module ActionView
# This is the method which actually finds the layout using details in the lookup
# context object. If no layout is found, it checkes if at least a layout with
# the given name exists across all details before raising the error.
- def find_layout(layout) #:nodoc:
+ #
+ # If self.formats contains several formats, just the first one is considered in
+ # the layout lookup.
+ def find_layout(layout)
begin
- layout =~ /^\// ?
- with_fallbacks { find_template(layout) } : find_template(layout)
+ if formats.size == 1
+ _find_layout(layout)
+ else
+ update_details(:formats => self.formats.first){ _find_layout(layout) }
+ end
rescue ActionView::MissingTemplate => e
update_details(:formats => nil) do
raise unless template_exists?(layout)
@@ -54,6 +60,11 @@ module ActionView
end
end
+ def _find_layout(layout) #:nodoc:
+ layout =~ /^\// ?
+ with_fallbacks { find_template(layout) } : find_template(layout)
+ end
+
# Contains the logic that actually renders the layout.
def _render_layout(layout, locals, &block) #:nodoc:
layout.render(self, locals){ |*name| _layout_for(*name, &block) }
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index 310efe40e2..492326964a 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -16,13 +16,12 @@ module ActionView
case options
when Hash
if block_given?
- content = _render_partial(options.merge(:partial => options[:layout]), &block)
- safe_concat(content)
+ _render_partial(options.merge(:partial => options[:layout]), &block)
elsif options.key?(:partial)
_render_partial(options)
else
template = _determine_template(options)
- self.formats = template.formats
+ lookup_context.freeze_formats(template.formats, true)
_render_template(template, options[:layout], options)
end
when :update
@@ -54,16 +53,12 @@ module ActionView
layout = find_layout(layout) if layout
ActiveSupport::Notifications.instrument("action_view.render_template",
- :identifier => template.identifier, :layout => layout.try(:identifier)) do
+ :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
content = template.render(self, locals) { |*name| _layout_for(*name) }
@_content_for[:layout] = content
- if layout
- @_layout = layout.identifier
- content = _render_layout(layout, locals)
- end
-
+ content = _render_layout(layout, locals) if layout
content
end
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index b4fdb49d3b..8abc1633ff 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -1,8 +1,7 @@
# encoding: utf-8
# This is so that templates compiled in this file are UTF-8
-
-require 'set'
-require "action_view/template/resolver"
+require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/object/blank'
module ActionView
class Template
@@ -24,19 +23,20 @@ module ActionView
@identifier = identifier
@handler = handler
- @partial = details[:partial]
@virtual_path = details[:virtual_path]
@method_names = {}
- format = details[:format]
- format ||= handler.default_format.to_sym if handler.respond_to?(:default_format)
- format ||= :html
- @formats = [format.to_sym]
+ format = details[:format] || :html
+ @formats = Array.wrap(format).map(&:to_sym)
end
def render(view, locals, &block)
- method_name = compile(locals, view)
- view.send(method_name, locals, &block)
+ # Notice that we use a bang in this instrumentation because you don't want to
+ # consume this in production. This is only slow if it's being listened to.
+ ActiveSupport::Notifications.instrument("action_view.render_template!", :virtual_path => @virtual_path) do
+ method_name = compile(locals, view)
+ view.send(method_name, locals, &block)
+ end
rescue Exception => e
if e.is_a?(Template::Error)
e.sub_template_of(self)
@@ -58,10 +58,6 @@ module ActionView
@counter_name ||= "#{variable_name}_counter".to_sym
end
- def partial?
- @partial
- end
-
def inspect
if defined?(Rails.root)
identifier.sub("#{Rails.root}/", '')
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index 648f708d3d..5222ffa89c 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -1,6 +1,26 @@
require "active_support/core_ext/enumerable"
module ActionView
+ class ActionViewError < StandardError #:nodoc:
+ end
+
+ class MissingTemplate < ActionViewError #:nodoc:
+ attr_reader :path
+
+ def initialize(paths, path, details, partial)
+ @path = path
+ display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ")
+ template_type = if partial
+ "partial"
+ elsif path =~ /layouts/i
+ 'layout'
+ else
+ 'template'
+ end
+
+ super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}")
+ end
+ end
class Template
# The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a
# bunch of intimate details and uses it to report a very precise exception message.
@@ -73,11 +93,11 @@ module ActionView
end
def to_s
- "\n#{self.class} (#{message}) #{source_location}:\n" +
+ "\n#{self.class} (#{message}) #{source_location}:\n" +
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
end
- # don't do anything nontrivial here. Any raised exception from here becomes fatal
+ # don't do anything nontrivial here. Any raised exception from here becomes fatal
# (and can't be rescued).
def backtrace
@backtrace
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index ac5902cc0e..705c2bf82e 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -8,6 +8,13 @@ module ActionView
super(value.to_s)
end
alias :append= :<<
+
+ def append_if_string=(value)
+ if value.is_a?(String) && !value.is_a?(NonConcattingString)
+ ActiveSupport::Deprecation.warn("<% %> style block helpers are deprecated. Please use <%= %>", caller)
+ self << value
+ end
+ end
end
module Template::Handlers
@@ -21,14 +28,24 @@ module ActionView
src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
end
+ BLOCK_EXPR = /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
+
def add_expr_literal(src, code)
- if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
+ if code =~ BLOCK_EXPR
src << '@output_buffer.append= ' << code
else
src << '@output_buffer.append= (' << code << ');'
end
end
+ def add_stmt(src, code)
+ if code =~ BLOCK_EXPR
+ src << '@output_buffer.append_if_string= ' << code
+ else
+ super
+ end
+ end
+
def add_expr_escaped(src, code)
src << '@output_buffer.append= ' << escaped_expr(code) << ';'
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index a43597e728..8e8afaa43f 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -1,6 +1,5 @@
require "pathname"
require "active_support/core_ext/class"
-require "active_support/core_ext/array/wrap"
require "action_view/template"
module ActionView
@@ -14,15 +13,8 @@ module ActionView
@cached.clear
end
- def find(*args)
- find_all(*args).first
- end
-
# Normalizes the arguments and passes it on to find_template.
def find_all(name, prefix=nil, partial=false, details={}, key=nil)
- name, prefix = normalize_name(name, prefix)
- details = details.merge(:handlers => default_handlers)
-
cached(key, prefix, name, partial) do
find_templates(name, prefix, partial, details)
end
@@ -34,10 +26,6 @@ module ActionView
@caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes
end
- def default_handlers
- Template::Handlers.extensions + [nil]
- end
-
# This is what child classes implement. No defaults are needed
# because Resolver guarantees that the arguments are present and
# normalized.
@@ -45,17 +33,6 @@ module ActionView
raise NotImplementedError
end
- # Support legacy foo.erb names even though we now ignore .erb
- # as well as incorrectly putting part of the path in the template
- # name instead of the prefix.
- def normalize_name(name, prefix)
- handlers = Template::Handlers.extensions.join('|')
- name = name.to_s.gsub(/\.(?:#{handlers})$/, '')
-
- parts = name.split('/')
- return parts.pop, [prefix, *parts].compact.join("/")
- end
-
def cached(key, prefix, name, partial)
return yield unless key && caching?
scope = @cached[key][prefix][name]
@@ -79,7 +56,7 @@ module ActionView
def find_templates(name, prefix, partial, details)
path = build_path(name, prefix, partial, details)
- query(partial, path, EXTENSION_ORDER.map { |ext| details[ext] })
+ query(path, EXTENSION_ORDER.map { |ext| details[ext] }, details[:formats])
end
def build_path(name, prefix, partial, details)
@@ -89,26 +66,32 @@ module ActionView
path
end
- def query(partial, path, exts)
+ def query(path, exts, formats)
query = File.join(@path, path)
exts.each do |ext|
- query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}'
+ query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << ',}'
end
Dir[query].reject { |p| File.directory?(p) }.map do |p|
- handler, format = extract_handler_and_format(p)
+ handler, format = extract_handler_and_format(p, formats)
Template.new(File.read(p), File.expand_path(p), handler,
- :partial => partial, :virtual_path => path, :format => format)
+ :virtual_path => path, :format => format)
end
end
- def extract_handler_and_format(path)
+ # Extract handler and formats from path. If a format cannot be a found neither
+ # from the path, or the handler, we should return the array of formats given
+ # to the resolver.
+ def extract_handler_and_format(path, default_formats)
pieces = File.basename(path).split(".")
pieces.shift
- handler = Template.handler_class_for_extension(pieces.pop)
- format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym
+ handler = Template.handler_class_for_extension(pieces.pop)
+ format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym
+ format ||= handler.default_format if handler.respond_to?(:default_format)
+ format ||= default_formats
+
[handler, format]
end
end
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 1578ac9479..b0ababe344 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -2,29 +2,10 @@ require 'action_controller/test_case'
require 'action_view'
module ActionView
- class Base
- alias_method :initialize_without_template_tracking, :initialize
- def initialize(*args)
- @_rendered = { :template => nil, :partials => Hash.new(0) }
- initialize_without_template_tracking(*args)
- end
-
- attr_internal :rendered
- end
-
- class Template
- alias_method :render_without_tracking, :render
- def render(view, locals, &blk)
- rendered = view.rendered
- rendered[:partials][self] += 1 if partial?
- rendered[:template] ||= []
- rendered[:template] << self
- render_without_tracking(view, locals, &blk)
- end
- end
-
class TestCase < ActiveSupport::TestCase
class TestController < ActionController::Base
+ include ActionDispatch::TestProcess
+
attr_accessor :request, :response, :params
def self.controller_path
@@ -42,6 +23,7 @@ module ActionView
end
include ActionDispatch::Assertions, ActionDispatch::TestProcess
+ include ActionController::TemplateAssertions
include ActionView::Context
include ActionController::PolymorphicRoutes
@@ -64,7 +46,7 @@ module ActionView
end
def config
- @controller.config
+ @controller.config if @controller.respond_to?(:config)
end
def render(options = {}, local_assigns = {}, &block)
@@ -124,7 +106,8 @@ module ActionView
def _view
view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller)
- view.class.send :include, _helpers
+ view.singleton_class.send :include, _helpers
+ view.singleton_class.send :include, @controller._router.url_helpers
view.output_buffer = self.output_buffer
view
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 67aa412d3d..5b2ff3e871 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -44,6 +44,19 @@ ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
FIXTURES = Pathname.new(FIXTURE_LOAD_PATH)
+module RackTestUtils
+ def body_to_string(body)
+ if body.respond_to?(:each)
+ str = ""
+ body.each {|s| str << s }
+ str
+ else
+ body
+ end
+ end
+ extend self
+end
+
module SetupOnce
extend ActiveSupport::Concern
@@ -239,47 +252,6 @@ module ActionController
setup do
@router = SharedTestRoutes
end
-
- def assert_template(options = {}, message = nil)
- validate_request!
-
- hax = @controller.view_context.instance_variable_get(:@_rendered)
-
- case options
- when NilClass, String
- rendered = (hax[:template] || []).map { |t| t.identifier }
- msg = build_message(message,
- "expecting <?> but rendering with <?>",
- options, rendered.join(', '))
- assert_block(msg) do
- if options.nil?
- hax[:template].blank?
- else
- rendered.any? { |t| t.match(options) }
- end
- end
- when Hash
- if expected_partial = options[:partial]
- partials = hax[:partials]
- if expected_count = options[:count]
- found = partials.detect { |p, _| p.identifier.match(expected_partial) }
- actual_count = found.nil? ? 0 : found[1]
- msg = build_message(message,
- "expecting ? to be rendered ? time(s) but rendered ? time(s)",
- expected_partial, expected_count, actual_count)
- assert(actual_count == expected_count.to_i, msg)
- else
- msg = build_message(message,
- "expecting partial <?> but action rendered <?>",
- options[:partial], partials.keys)
- assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
- end
- else
- assert hax[:partials].empty?,
- "Expected no partials to be rendered"
- end
- end
- end
end
end
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index 26e0d6d844..1741b58f72 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -181,6 +181,8 @@ module Admin
end
end
+# require "action_dispatch/test_process"
+
# a test case to exercise the new capabilities TestRequest & TestResponse
class ActionPackAssertionsControllerTest < ActionController::TestCase
# -- assertion-based testing ------------------------------------------------
@@ -303,14 +305,14 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
# make sure that the template objects exist
def test_template_objects_alive
process :assign_this
- assert !@controller.template.instance_variable_get(:"@hi")
- assert @controller.template.instance_variable_get(:"@howdy")
+ assert !@controller.instance_variable_get(:"@hi")
+ assert @controller.instance_variable_get(:"@howdy")
end
# make sure we don't have template objects when we shouldn't
def test_template_object_missing
process :nothing
- assert_nil @controller.template.assigns['howdy']
+ assert_nil @controller.instance_variable_get(:@howdy)
end
# check the empty flashing
@@ -365,11 +367,10 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
# check if we were rendered by a file-based template?
def test_rendered_action
process :nothing
- assert_nil @controller.template.rendered[:template]
+ assert_template nil
process :hello_world
- assert @controller.template.rendered[:template]
- assert 'hello_world', @controller.template.rendered[:template].to_s
+ assert_template 'hello_world'
end
# check the redirection location
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index f047e7da30..49f79681f6 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -56,6 +56,16 @@ protected
end
end
+class AnotherMethodMissingController < ActionController::Base
+ cattr_accessor :_exception
+ rescue_from Exception, :with => :_exception=
+
+ protected
+ def method_missing(*attrs, &block)
+ super
+ end
+end
+
class DefaultUrlOptionsController < ActionController::Base
def from_view
render :inline => "<%= #{params[:route]} %>"
@@ -124,11 +134,11 @@ class ControllerInstanceTests < Test::Unit::TestCase
def test_action_methods
@empty_controllers.each do |c|
- assert_equal Set.new, c.class.__send__(:action_methods), "#{c.controller_path} should be empty!"
+ assert_equal Set.new, c.class.action_methods, "#{c.controller_path} should be empty!"
end
@non_empty_controllers.each do |c|
- assert_equal Set.new(%w(public_action)), c.class.__send__(:action_methods), "#{c.controller_path} should not be empty!"
+ assert_equal Set.new(%w(public_action)), c.class.action_methods, "#{c.controller_path} should not be empty!"
end
end
@@ -173,6 +183,12 @@ class PerformActionTest < ActionController::TestCase
assert_equal 'method_missing', @response.body
end
+ def test_method_missing_should_recieve_symbol
+ use_controller AnotherMethodMissingController
+ get :some_action
+ assert_kind_of NameError, @controller._exception
+ end
+
def test_get_on_hidden_should_fail
use_controller NonEmptyController
assert_raise(ActionController::UnknownAction) { get :hidden_action }
@@ -191,7 +207,7 @@ class UrlOptionsTest < ActionController::TestCase
def test_url_options_override
with_routing do |set|
- set.draw do |map|
+ set.draw do
match 'from_view', :to => 'url_options#from_view', :as => :from_view
match ':controller/:action'
end
@@ -202,7 +218,18 @@ class UrlOptionsTest < ActionController::TestCase
assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url)
assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options')
end
- end
+ end
+
+ def test_url_helpers_does_not_become_actions
+ with_routing do |set|
+ set.draw do
+ match "account/overview"
+ end
+
+ @controller.class.send(:include, set.url_helpers)
+ assert !@controller.class.action_methods.include?("account_overview_path")
+ end
+ end
end
class DefaultUrlOptionsTest < ActionController::TestCase
@@ -216,7 +243,7 @@ class DefaultUrlOptionsTest < ActionController::TestCase
def test_default_url_options_override
with_routing do |set|
- set.draw do |map|
+ set.draw do
match 'from_view', :to => 'default_url_options#from_view', :as => :from_view
match ':controller/:action'
end
@@ -231,7 +258,7 @@ class DefaultUrlOptionsTest < ActionController::TestCase
def test_default_url_options_are_used_in_non_positional_parameters
with_routing do |set|
- set.draw do |map|
+ set.draw do
scope("/:locale") do
resources :descriptions
end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index a792752ef4..f0ad652d50 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -285,6 +285,8 @@ class ActionCacheTest < ActionController::TestCase
assert_not_equal cached_time, @response.body
end
+ include RackTestUtils
+
def test_action_cache_with_layout
get :with_layout
cached_time = content_to_cache
@@ -294,8 +296,8 @@ class ActionCacheTest < ActionController::TestCase
get :with_layout
assert_not_equal cached_time, @response.body
-
- assert_equal @response.body, read_fragment('hostname.com/action_caching_test/with_layout')
+ body = body_to_string(read_fragment('hostname.com/action_caching_test/with_layout'))
+ assert_equal @response.body, body
end
def test_action_cache_with_layout_and_layout_cache_false
@@ -308,7 +310,8 @@ class ActionCacheTest < ActionController::TestCase
get :layout_false
assert_not_equal cached_time, @response.body
- assert_equal cached_time, read_fragment('hostname.com/action_caching_test/layout_false')
+ body = body_to_string(read_fragment('hostname.com/action_caching_test/layout_false'))
+ assert_equal cached_time, body
end
def test_action_cache_conditional_options
@@ -616,8 +619,10 @@ class FragmentCachingTest < ActionController::TestCase
@store.write('views/expensive', 'fragment content')
fragment_computed = false
+ view_context = @controller.view_context
+
buffer = 'generated till now -> '.html_safe
- @controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
+ buffer << view_context.send(:fragment_for, 'expensive') { fragment_computed = true }
assert fragment_computed
assert_equal 'generated till now -> ', buffer
@@ -627,8 +632,10 @@ class FragmentCachingTest < ActionController::TestCase
@store.write('views/expensive', 'fragment content')
fragment_computed = false
+ view_context = @controller.view_context
+
buffer = 'generated till now -> '.html_safe
- @controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
+ buffer << view_context.send(:fragment_for, 'expensive') { fragment_computed = true }
assert !fragment_computed
assert_equal 'generated till now -> fragment content', buffer
@@ -704,8 +711,8 @@ CACHED
def test_fragment_caching_in_partials
get :html_fragment_cached_with_partial
assert_response :success
- assert_match /Fragment caching in a partial/, @response.body
- assert_match "Fragment caching in a partial", @store.read('views/test.host/functional_caching/html_fragment_cached_with_partial')
+ assert_match /Old fragment caching in a partial/, @response.body
+ assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/html_fragment_cached_with_partial')
end
def test_render_inline_before_fragment_caching
@@ -719,14 +726,14 @@ CACHED
def test_fragment_caching_in_rjs_partials
xhr :get, :js_fragment_cached_with_partial
assert_response :success
- assert_match /Fragment caching in a partial/, @response.body
- assert_match "Fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')
+ assert_match /Old fragment caching in a partial/, @response.body
+ assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')
end
def test_html_formatted_fragment_caching
get :formatted_fragment_cached, :format => "html"
assert_response :success
- expected_body = "<body>\n<p>ERB</p>\n</body>"
+ expected_body = "<body>\n<p>ERB</p>\n</body>\n"
assert_equal expected_body, @response.body
@@ -742,15 +749,4 @@ CACHED
assert_equal " <p>Builder</p>\n", @store.read('views/test.host/functional_caching/formatted_fragment_cached')
end
-
- def test_js_formatted_fragment_caching
- get :formatted_fragment_cached, :format => "js"
- assert_response :success
- expected_body = %(title = "Hey";\n$("element_1").visualEffect("highlight");\n) +
- %($("element_2").visualEffect("highlight");\nfooter = "Bye";)
- assert_equal expected_body, @response.body
-
- assert_equal ['$("element_1").visualEffect("highlight");', '$("element_2").visualEffect("highlight");'],
- @store.read('views/test.host/functional_caching/formatted_fragment_cached')
- end
end
diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb
index 908967a110..36498d13a9 100644
--- a/actionpack/test/controller/cookie_test.rb
+++ b/actionpack/test/controller/cookie_test.rb
@@ -64,6 +64,12 @@ class CookieTest < ActionController::TestCase
cookies.permanent.signed[:remember_me] = 100
head :ok
end
+
+ def delete_and_set_cookie
+ cookies.delete :user_name
+ cookies[:user_name] = { :value => "david", :expires => Time.utc(2005, 10, 10,5) }
+ head :ok
+ end
end
tests TestController
@@ -152,6 +158,11 @@ class CookieTest < ActionController::TestCase
assert_equal 100, @controller.send(:cookies).signed[:remember_me]
end
+ def test_delete_and_set_cookie
+ get :delete_and_set_cookie
+ assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"
+ assert_equal({"user_name" => "david"}, @response.cookies)
+ end
private
def assert_cookie_header(expected)
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index 004e1369d3..ea740f7233 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -651,9 +651,9 @@ class FilterTest < ActionController::TestCase
assert_equal %w( ensure_login find_user ), assigns["ran_filter"]
test_process(ConditionalSkippingController, "login")
- assert_nil @controller.template.controller.instance_variable_get("@ran_after_filter")
+ assert_nil @controller.instance_variable_get("@ran_after_filter")
test_process(ConditionalSkippingController, "change_password")
- assert_equal %w( clean_up ), @controller.template.controller.instance_variable_get("@ran_after_filter")
+ assert_equal %w( clean_up ), @controller.instance_variable_get("@ran_after_filter")
end
def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 2180466ca7..c9782856bd 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -173,14 +173,12 @@ class IntegrationTestTest < Test::Unit::TestCase
end
def test_opens_new_session
- @test.class.expects(:fixture_table_names).times(2).returns(['foo'])
-
session1 = @test.open_session { |sess| }
session2 = @test.open_session # implicit session
- assert_kind_of ::ActionController::Integration::Session, session1
- assert_kind_of ::ActionController::Integration::Session, session2
- assert_not_equal session1, session2
+ assert session1.respond_to?(:assert_template), "open_session makes assert_template available"
+ assert session2.respond_to?(:assert_template), "open_session makes assert_template available"
+ assert !session1.equal?(session2)
end
# RSpec mixes Matchers (which has a #method_missing) into
diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb
index f635253156..4d687c1ec6 100644
--- a/actionpack/test/controller/layout_test.rb
+++ b/actionpack/test/controller/layout_test.rb
@@ -120,19 +120,19 @@ class LayoutSetInResponseTest < ActionController::TestCase
def test_layout_set_when_using_default_layout
@controller = DefaultLayoutController.new
get :hello
- assert @controller.template.layout.include?('layouts/layout_test')
+ assert_template :layout => "layouts/layout_test"
end
def test_layout_set_when_set_in_controller
@controller = HasOwnLayoutController.new
get :hello
- assert @controller.template.layout.include?('layouts/item')
+ assert_template :layout => "layouts/item"
end
def test_layout_only_exception_when_included
@controller = OnlyLayoutController.new
get :hello
- assert @controller.template.layout.include?('layouts/item')
+ assert_template :layout => "layouts/item"
end
def test_layout_only_exception_when_excepted
@@ -144,7 +144,7 @@ class LayoutSetInResponseTest < ActionController::TestCase
def test_layout_except_exception_when_included
@controller = ExceptLayoutController.new
get :hello
- assert @controller.template.layout.include?('layouts/item')
+ assert_template :layout => "layouts/item"
end
def test_layout_except_exception_when_excepted
@@ -156,19 +156,19 @@ class LayoutSetInResponseTest < ActionController::TestCase
def test_layout_set_when_using_render
@controller = SetsLayoutInRenderController.new
get :hello
- assert @controller.template.layout.include?('layouts/third_party_template_library')
+ assert_template :layout => "layouts/third_party_template_library"
end
def test_layout_is_not_set_when_none_rendered
@controller = RendersNoLayoutController.new
get :hello
- assert_nil @controller.template.layout
+ assert_template :layout => nil
end
def test_layout_is_picked_from_the_controller_instances_view_path
@controller = PrependsViewPathController.new
get :hello
- assert @controller.template.layout =~ /layouts\/alt\.\w+/
+ assert_template :layout => /layouts\/alt\.\w+/
end
def test_absolute_pathed_layout
@@ -219,7 +219,7 @@ unless RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
@controller = LayoutSymlinkedTest.new
get :hello
assert_response 200
- assert @controller.template.layout.include?("layouts/symlinked/symlinked_layout")
+ assert_template :layout => "layouts/symlinked/symlinked_layout"
end
end
end
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index 5c1eaf453c..53cd3f0801 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -765,7 +765,7 @@ class RespondWithControllerTest < ActionController::TestCase
Customer.any_instance.stubs(:errors).returns(errors)
post :using_resource_with_action
- assert_equal "foo - #{[:html].to_s}", @controller.response_body
+ assert_equal "foo - #{[:html].to_s}", @controller.response.body
end
def test_respond_as_responder_entry_point
diff --git a/actionpack/test/controller/new_base/bare_metal_test.rb b/actionpack/test/controller/new_base/bare_metal_test.rb
new file mode 100644
index 0000000000..df4b39a103
--- /dev/null
+++ b/actionpack/test/controller/new_base/bare_metal_test.rb
@@ -0,0 +1,27 @@
+require "abstract_unit"
+
+module BareMetalTest
+ class BareController < ActionController::Metal
+ def index
+ self.response_body = "Hello world"
+ end
+ end
+
+ class BareTest < ActiveSupport::TestCase
+ test "response body is a Rack-compatible response" do
+ status, headers, body = BareController.action(:index).call(Rack::MockRequest.env_for("/"))
+ assert_equal 200, status
+ string = ""
+
+ body.each do |part|
+ assert part.is_a?(String), "Each part of the body must be a String"
+ string << part
+ end
+
+ assert headers.is_a?(Hash), "Headers must be a Hash"
+ assert headers["Content-Type"], "Content-Type must exist"
+
+ assert_equal "Hello world", string
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/new_base/metal_test.rb b/actionpack/test/controller/new_base/metal_test.rb
index ab61fd98ee..45a6619eb4 100644
--- a/actionpack/test/controller/new_base/metal_test.rb
+++ b/actionpack/test/controller/new_base/metal_test.rb
@@ -18,6 +18,8 @@ module MetalTest
end
class TestMiddleware < ActiveSupport::TestCase
+ include RackTestUtils
+
def setup
@app = Rack::Builder.new do
use MetalTest::MetalMiddleware
@@ -29,14 +31,14 @@ module MetalTest
env = Rack::MockRequest.env_for("/authed")
response = @app.call(env)
- assert_equal "Hello World", response[2]
+ assert_equal "Hello World", body_to_string(response[2])
end
test "it can return a response using the normal AC::Metal techniques" do
env = Rack::MockRequest.env_for("/")
response = @app.call(env)
- assert_equal "Not authed!", response[2]
+ assert_equal "Not authed!", body_to_string(response[2])
assert_equal 401, response[0]
end
end
diff --git a/actionpack/test/controller/new_base/middleware_test.rb b/actionpack/test/controller/new_base/middleware_test.rb
index ada0215b1a..65942ebc15 100644
--- a/actionpack/test/controller/new_base/middleware_test.rb
+++ b/actionpack/test/controller/new_base/middleware_test.rb
@@ -44,7 +44,7 @@ module MiddlewareTest
test "middleware that is 'use'd is called as part of the Rack application" do
result = @app.call(env_for("/"))
- assert_equal "Hello World", result[2]
+ assert_equal "Hello World", RackTestUtils.body_to_string(result[2])
assert_equal "Success", result[1]["Middleware-Test"]
end
diff --git a/actionpack/test/controller/new_base/render_action_test.rb b/actionpack/test/controller/new_base/render_action_test.rb
index 0804d7b09d..d92e9c4bf2 100644
--- a/actionpack/test/controller/new_base/render_action_test.rb
+++ b/actionpack/test/controller/new_base/render_action_test.rb
@@ -117,7 +117,7 @@ module RenderActionWithApplicationLayout
# # ==== Render actions with layouts ====
class BasicController < ::ApplicationController
# Set the view path to an application view structure with layouts
- self.view_paths = self.view_paths = [ActionView::FixtureResolver.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!",
"render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Hello'",
"layouts/application.html.erb" => "Hi <%= yield %> OK, Bye",
@@ -202,7 +202,7 @@ end
module RenderActionWithControllerLayout
class BasicController < ActionController::Base
- self.view_paths = self.view_paths = [ActionView::FixtureResolver.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!",
"layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> Bye"
)]
diff --git a/actionpack/test/controller/new_base/render_rjs_test.rb b/actionpack/test/controller/new_base/render_rjs_test.rb
index f4516ade63..b602b9f8e9 100644
--- a/actionpack/test/controller/new_base/render_rjs_test.rb
+++ b/actionpack/test/controller/new_base/render_rjs_test.rb
@@ -5,8 +5,10 @@ module RenderRjs
self.view_paths = [ActionView::FixtureResolver.new(
"render_rjs/basic/index.js.rjs" => "page[:customer].replace_html render(:partial => 'customer')",
"render_rjs/basic/index_html.js.rjs" => "page[:customer].replace_html :partial => 'customer'",
+ "render_rjs/basic/index_no_js.js.erb" => "<%= render(:partial => 'developer') %>",
"render_rjs/basic/_customer.js.erb" => "JS Partial",
"render_rjs/basic/_customer.html.erb" => "HTML Partial",
+ "render_rjs/basic/_developer.html.erb" => "HTML Partial",
"render_rjs/basic/index_locale.js.rjs" => "page[:customer].replace_html :partial => 'customer'",
"render_rjs/basic/_customer.da.html.erb" => "Danish HTML Partial",
"render_rjs/basic/_customer.da.js.erb" => "Danish JS Partial"
@@ -16,6 +18,12 @@ module RenderRjs
render
end
+ def index_respond_to
+ respond_to do |format|
+ format.js { render :action => "index_no_js" }
+ end
+ end
+
def index_locale
self.locale = :da
end
@@ -37,6 +45,16 @@ module RenderRjs
assert_response("$(\"customer\").update(\"JS Partial\");")
end
+ test "rendering a partial in an RJS template should pick the HTML one if no JS is available" do
+ get :index_no_js, "format" => "js"
+ assert_response("HTML Partial")
+ end
+
+ test "rendering a partial in an RJS template should pick the HTML one if no JS is available on respond_to" do
+ get :index_respond_to, "format" => "js"
+ assert_response("HTML Partial")
+ end
+
test "replacing an element with a partial in an RJS template should pick the HTML template over the JS one" do
get :index_html, "format" => "js"
assert_response("$(\"customer\").update(\"HTML Partial\");")
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 20fcb87da6..2f3997518f 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -18,6 +18,13 @@ class TestController < ActionController::Base
layout :determine_layout
+ def name
+ nil
+ end
+
+ private :name
+ helper_method :name
+
def hello_world
end
@@ -418,7 +425,6 @@ class TestController < ActionController::Base
def rendering_with_conflicting_local_vars
@name = "David"
- def @template.name() nil end
render :action => "potential_conflicts"
end
@@ -507,10 +513,6 @@ class TestController < ActionController::Base
end
end
- def partial_only_with_layout
- render :partial => "partial_only", :layout => true
- end
-
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") }
@@ -526,11 +528,11 @@ class TestController < ActionController::Base
end
def partial_with_form_builder
- render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, @template, {}, Proc.new {})
+ render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}, Proc.new {})
end
def partial_with_form_builder_subclass
- render :partial => LabellingFormBuilder.new(:post, nil, @template, {}, Proc.new {})
+ render :partial => LabellingFormBuilder.new(:post, nil, view_context, {}, Proc.new {})
end
def partial_collection
@@ -634,8 +636,7 @@ class TestController < ActionController::Base
"rendering_nothing_on_layout", "render_text_hello_world",
"render_text_hello_world_with_layout",
"hello_world_with_layout_false",
- "partial_only", "partial_only_with_layout",
- "accessing_params_in_template",
+ "partial_only", "accessing_params_in_template",
"accessing_params_in_template_with_layout",
"render_with_explicit_template",
"render_with_explicit_string_template",
@@ -1198,11 +1199,6 @@ class RenderTest < ActionController::TestCase
assert_equal 'partial html', @response.body
end
- def test_partial_only_with_layout
- get :partial_only_with_layout
- assert_equal "<html>only partial</html>", @response.body
- end
-
def test_render_to_string_partial
get :render_to_string_with_partial
assert_equal "only partial", assigns(:partial_only)
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index f5fcf9b0df..c4e71a8689 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -18,14 +18,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
default_url_options :host => "rubyonrails.org"
controller :sessions do
- get 'login' => :new, :as => :login
+ get 'login' => :new
post 'login' => :create
-
- delete 'logout' => :destroy, :as => :logout
+ delete 'logout' => :destroy
end
resource :session do
get :create
+ post :reset
resource :info
end
@@ -34,6 +34,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
match 'account/login', :to => redirect("/login")
match 'account/overview'
+ match '/account/nested/overview'
+ match 'sign_in' => "sessions#new"
match 'account/modulo/:name', :to => redirect("/%{name}s")
match 'account/proc/:name', :to => redirect {|params| "/#{params[:name].pluralize}" }
@@ -120,7 +122,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
# misc
match 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article
+ # default params
+ match 'inline_pages/(:id)', :to => 'pages#show', :id => 'home'
+ match 'default_pages/(:id)', :to => 'pages#show', :defaults => { :id => 'home' }
+ defaults :id => 'home' do
+ match 'scoped_pages/(:id)', :to => 'pages#show'
+ end
+
namespace :account do
+ match 'shorthand'
match 'description', :to => "account#description", :as => "description"
resource :subscription, :credit, :credit_card
@@ -193,6 +203,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true)
assert_equal 'http://rubyonrails.org/login', Routes.url_for(:controller => 'sessions', :action => 'create')
+ assert_equal 'http://rubyonrails.org/login', Routes.url_helpers.login_url
end
end
@@ -237,6 +248,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get '/session/edit'
assert_equal 'sessions#edit', @response.body
assert_equal '/session/edit', edit_session_path
+
+ post '/session/reset'
+ assert_equal 'sessions#reset', @response.body
+ assert_equal '/session/reset', reset_session_path
end
end
@@ -654,6 +669,30 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_convention_match_inside_namespace
+ with_test_routes do
+ assert_equal '/account/shorthand', account_shorthand_path
+ get '/account/shorthand'
+ assert_equal 'account#shorthand', @response.body
+ end
+ end
+
+ def test_convention_match_nested_and_with_leading_slash
+ with_test_routes do
+ assert_equal '/account/nested/overview', account_nested_overview_path
+ get '/account/nested/overview'
+ assert_equal 'account/nested#overview', @response.body
+ end
+ end
+
+ def test_convention_with_explicit_end
+ with_test_routes do
+ get '/sign_in'
+ assert_equal 'sessions#new', @response.body
+ assert_equal '/sign_in', sign_in_path
+ end
+ end
+
def test_redirect_with_complete_url
with_test_routes do
get '/account/google'
@@ -742,6 +781,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_default_params
+ with_test_routes do
+ get '/inline_pages'
+ assert_equal 'home', @request.params[:id]
+
+ get '/default_pages'
+ assert_equal 'home', @request.params[:id]
+
+ get '/scoped_pages'
+ assert_equal 'home', @request.params[:id]
+ end
+ end
+
private
def with_test_routes
yield
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index 18b5b7ee00..326b336a1a 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -34,5 +34,10 @@ module TestUrlGeneration
get "/foo", {}, 'SCRIPT_NAME' => "/new"
assert_equal "/new/foo", response.body
end
+
+ test "handling http protocol with https set" do
+ https!
+ assert_equal "http://www.example.com/foo", foo_url(:protocol => "http")
+ end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/functional_caching/_partial.erb b/actionpack/test/fixtures/functional_caching/_partial.erb
index d0e4f72b95..ec0da7cf50 100644
--- a/actionpack/test/fixtures/functional_caching/_partial.erb
+++ b/actionpack/test/fixtures/functional_caching/_partial.erb
@@ -1,3 +1,3 @@
<% cache do %>
-Fragment caching in a partial
-<% end %> \ No newline at end of file
+Old fragment caching in a partial
+<% end %>
diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
index d7f43ad95e..9b88fa1f5a 100644
--- a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
+++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
@@ -1,3 +1,3 @@
<body>
-<% cache do %><p>ERB</p><% end %>
-</body> \ No newline at end of file
+<%= cache do %><p>ERB</p><% end %>
+</body>
diff --git a/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
index 268a298a42..c479adb897 100644
--- a/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
+++ b/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
@@ -1,2 +1,2 @@
Hello
-<% cache do %>This bit's fragment cached<% end %>
+<%= cache do %>This bit's fragment cached<% end %>
diff --git a/actionpack/test/fixtures/functional_caching/inline_fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/inline_fragment_cached.html.erb
index 87309b8ccb..41647f1404 100644
--- a/actionpack/test/fixtures/functional_caching/inline_fragment_cached.html.erb
+++ b/actionpack/test/fixtures/functional_caching/inline_fragment_cached.html.erb
@@ -1,2 +1,2 @@
<%= render :inline => 'Some inline content' %>
-<% cache do %>Some cached content<% end %>
+<%= cache do %>Some cached content<% end %>
diff --git a/actionpack/test/fixtures/layouts/block_with_layout.erb b/actionpack/test/fixtures/layouts/block_with_layout.erb
index f25b41271d..73ac833e52 100644
--- a/actionpack/test/fixtures/layouts/block_with_layout.erb
+++ b/actionpack/test/fixtures/layouts/block_with_layout.erb
@@ -1,3 +1,3 @@
-<% render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %>
+<%= render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %>
<%= yield %>
-<% render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %>
+<%= render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %>
diff --git a/actionpack/test/fixtures/test/array_translation.erb b/actionpack/test/fixtures/test/array_translation.erb
new file mode 100644
index 0000000000..12c0763313
--- /dev/null
+++ b/actionpack/test/fixtures/test/array_translation.erb
@@ -0,0 +1 @@
+<%= t(['foo', 'bar']) %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/deprecated_nested_layout.erb b/actionpack/test/fixtures/test/deprecated_nested_layout.erb
new file mode 100644
index 0000000000..7b6dcbb6c7
--- /dev/null
+++ b/actionpack/test/fixtures/test/deprecated_nested_layout.erb
@@ -0,0 +1,3 @@
+<% content_for :title, "title" -%>
+<% content_for :column do -%>column<% end -%>
+<% render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/nested_layout.erb b/actionpack/test/fixtures/test/nested_layout.erb
index 7b6dcbb6c7..6078f74b4c 100644
--- a/actionpack/test/fixtures/test/nested_layout.erb
+++ b/actionpack/test/fixtures/test/nested_layout.erb
@@ -1,3 +1,3 @@
<% content_for :title, "title" -%>
<% content_for :column do -%>column<% end -%>
-<% render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file
+<%= render :layout => 'layouts/column' do -%>content<% end -%> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/scoped_array_translation.erb b/actionpack/test/fixtures/test/scoped_array_translation.erb
new file mode 100644
index 0000000000..0a0c79f717
--- /dev/null
+++ b/actionpack/test/fixtures/test/scoped_array_translation.erb
@@ -0,0 +1 @@
+<%= t(['.foo', '.bar']) %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/using_layout_around_block.html.erb b/actionpack/test/fixtures/test/using_layout_around_block.html.erb
index a93fa02c9c..3d6661df9a 100644
--- a/actionpack/test/fixtures/test/using_layout_around_block.html.erb
+++ b/actionpack/test/fixtures/test/using_layout_around_block.html.erb
@@ -1 +1 @@
-<% render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file
+<%= render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file
diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb
index 02248d84ad..b49ccd39ca 100644
--- a/actionpack/test/lib/fixture_template.rb
+++ b/actionpack/test/lib/fixture_template.rb
@@ -9,17 +9,17 @@ module ActionView #:nodoc:
private
- def query(partial, path, exts)
+ def query(path, exts, formats)
query = Regexp.escape(path)
exts.each do |ext|
- query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')'
+ query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)'
end
templates = []
@hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source|
- handler, format = extract_handler_and_format(path)
+ handler, format = extract_handler_and_format(path, formats)
templates << Template.new(source, path, handler,
- :partial => partial, :virtual_path => path, :format => format)
+ :virtual_path => path, :format => format)
end
templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb
index 371aa53c68..7a665b00bc 100644
--- a/actionpack/test/template/active_model_helper_test.rb
+++ b/actionpack/test/template/active_model_helper_test.rb
@@ -147,6 +147,20 @@ class ActiveModelHelperTest < ActionView::TestCase
)
end
+ def test_field_error_proc
+ old_proc = ActionView::Base.field_error_proc
+ ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
+ %(<div class=\"fieldWithErrors\">#{html_tag} <span class="error">#{[instance.error_message].join(', ')}</span></div>).html_safe
+ end
+
+ assert_dom_equal(
+ %(<div class="fieldWithErrors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /> <span class="error">can't be empty</span></div>),
+ text_field("post", "author_name")
+ )
+ ensure
+ ActionView::Base.field_error_proc = old_proc if old_proc
+ end
+
def test_form_with_string
assert_dom_equal(
%(<form action="create" method="post"><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
@@ -252,6 +266,10 @@ class ActiveModelHelperTest < ActionView::TestCase
assert_dom_equal "<div class=\"differentError\">beforecan't be emptyafter</div>", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
end
+ def test_error_message_on_handles_empty_errors
+ assert_equal "", error_message_on(@post, :tag)
+ end
+
def test_error_messages_for_many_objects
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors 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><li>User email can't be empty</li></ul></div>), error_messages_for("post", "user")
diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb
index defe85107e..69cf684083 100644
--- a/actionpack/test/template/body_parts_test.rb
+++ b/actionpack/test/template/body_parts_test.rb
@@ -8,9 +8,8 @@ class BodyPartsTest < ActionController::TestCase
def index
RENDERINGS.each do |rendering|
- @template.punctuate_body! rendering
+ view_context.punctuate_body! rendering
end
- @performed_render = true
end
end
diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb
index f887c9ab5b..bf541c17d3 100644
--- a/actionpack/test/template/capture_helper_test.rb
+++ b/actionpack/test/template/capture_helper_test.rb
@@ -3,9 +3,33 @@ require 'abstract_unit'
class CaptureHelperTest < ActionView::TestCase
def setup
super
+ @av = ActionView::Base.new
@_content_for = Hash.new {|h,k| h[k] = "" }
end
+ def test_capture_captures_the_temporary_output_buffer_in_its_block
+ assert_nil @av.output_buffer
+ string = @av.capture do
+ @av.output_buffer << 'foo'
+ @av.output_buffer << 'bar'
+ end
+ assert_nil @av.output_buffer
+ assert_equal 'foobar', string
+ assert_kind_of ActionView::NonConcattingString, string
+ end
+
+ def test_capture_captures_the_value_returned_by_the_block_if_the_temporary_buffer_is_blank
+ string = @av.capture('foo', 'bar') do |a, b|
+ a + b
+ end
+ assert_equal 'foobar', string
+ assert_kind_of ActionView::NonConcattingString, string
+ end
+
+ def test_capture_returns_nil_if_the_returned_value_is_not_a_string
+ assert_nil @av.capture { 1 }
+ end
+
def test_content_for
assert ! content_for?(:title)
content_for :title, 'title'
@@ -13,9 +37,85 @@ class CaptureHelperTest < ActionView::TestCase
assert ! content_for?(:something_else)
end
+ def test_with_output_buffer_swaps_the_output_buffer_given_no_argument
+ assert_nil @av.output_buffer
+ buffer = @av.with_output_buffer do
+ @av.output_buffer << '.'
+ end
+ assert_equal '.', buffer
+ assert_nil @av.output_buffer
+ end
+
+ def test_with_output_buffer_swaps_the_output_buffer_with_an_argument
+ assert_nil @av.output_buffer
+ buffer = ActionView::OutputBuffer.new('.')
+ @av.with_output_buffer(buffer) do
+ @av.output_buffer << '.'
+ end
+ assert_equal '..', buffer
+ assert_nil @av.output_buffer
+ end
+
+ def test_with_output_buffer_restores_the_output_buffer
+ buffer = ActionView::OutputBuffer.new
+ @av.output_buffer = buffer
+ @av.with_output_buffer do
+ @av.output_buffer << '.'
+ end
+ assert buffer.equal?(@av.output_buffer)
+ end
+
+ unless RUBY_VERSION < '1.9'
+ def test_with_output_buffer_sets_proper_encoding
+ @av.output_buffer = ActionView::OutputBuffer.new
+
+ # Ensure we set the output buffer to an encoding different than the default one.
+ alt_encoding = alt_encoding(@av.output_buffer)
+ @av.output_buffer.force_encoding(alt_encoding)
+
+ @av.with_output_buffer do
+ assert alt_encoding, @av.output_buffer.encoding
+ end
+ end
+ end
+
def test_with_output_buffer_does_not_assume_there_is_an_output_buffer
- av = ActionView::Base.new
- assert_nil av.output_buffer
- assert_equal "", av.with_output_buffer {}
+ assert_nil @av.output_buffer
+ assert_equal "", @av.with_output_buffer {}
+ end
+
+ def test_flush_output_buffer_concats_output_buffer_to_response
+ view = view_with_controller
+ assert_equal [], view.response.body_parts
+
+ view.output_buffer << 'OMG'
+ view.flush_output_buffer
+ assert_equal ['OMG'], view.response.body_parts
+ assert_equal '', view.output_buffer
+
+ view.output_buffer << 'foobar'
+ view.flush_output_buffer
+ assert_equal ['OMG', 'foobar'], view.response.body_parts
+ assert_equal '', view.output_buffer
+ end
+
+ unless RUBY_VERSION < '1.9'
+ def test_flush_output_buffer_preserves_the_encoding_of_the_output_buffer
+ view = view_with_controller
+ alt_encoding = alt_encoding(view.output_buffer)
+ view.output_buffer.force_encoding(alt_encoding)
+ flush_output_buffer
+ assert_equal alt_encoding, view.output_buffer.encoding
+ end
+ end
+
+ def alt_encoding(output_buffer)
+ output_buffer.encoding == Encoding::US_ASCII ? Encoding::UTF_8 : Encoding::US_ASCII
+ end
+
+ def view_with_controller
+ returning(TestController.new.view_context) do |view|
+ view.output_buffer = ActionView::OutputBuffer.new
+ end
end
end
diff --git a/actionpack/test/template/erb/form_for_test.rb b/actionpack/test/template/erb/form_for_test.rb
new file mode 100644
index 0000000000..482dbb0287
--- /dev/null
+++ b/actionpack/test/template/erb/form_for_test.rb
@@ -0,0 +1,11 @@
+require "abstract_unit"
+require "template/erb/helper"
+
+module ERBTest
+ class TagHelperTest < BlockTestCase
+ test "form_for works" do
+ output = render_content "form_for(:staticpage, :url => {:controller => 'blah', :action => 'update'})", ""
+ assert_equal "<form action=\"/blah/update\" method=\"post\"></form>", output
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/template/erb/helper.rb b/actionpack/test/template/erb/helper.rb
new file mode 100644
index 0000000000..7147178849
--- /dev/null
+++ b/actionpack/test/template/erb/helper.rb
@@ -0,0 +1,30 @@
+module ERBTest
+ class ViewContext
+ mock_controller = Class.new do
+ include SharedTestRoutes.url_helpers
+ end
+
+ include ActionView::Helpers::TagHelper
+ include ActionView::Helpers::JavaScriptHelper
+ include ActionView::Helpers::FormHelper
+
+ attr_accessor :output_buffer
+
+ def protect_against_forgery?() false end
+
+ define_method(:controller) do
+ mock_controller.new
+ end
+ end
+
+ class BlockTestCase < ActiveSupport::TestCase
+ def render_content(start, inside)
+ template = block_helper(start, inside)
+ ActionView::Template::Handlers::Erubis.new(template).evaluate(ViewContext.new)
+ end
+
+ def block_helper(str, rest)
+ "<%= #{str} do %>#{rest}<% end %>"
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb
index cc96a43901..64a88bde1d 100644
--- a/actionpack/test/template/erb/tag_helper_test.rb
+++ b/actionpack/test/template/erb/tag_helper_test.rb
@@ -1,66 +1,44 @@
require "abstract_unit"
+require "template/erb/helper"
module ERBTest
- class ViewContext
- mock_controller = Class.new do
- include SharedTestRoutes.url_helpers
- end
-
- include ActionView::Helpers::TagHelper
- include ActionView::Helpers::JavaScriptHelper
- include ActionView::Helpers::FormHelper
-
- attr_accessor :output_buffer
-
- def protect_against_forgery?() false end
-
- define_method(:controller) do
- mock_controller.new
- end
- end
-
- class DeprecatedViewContext < ViewContext
- include ActionView::Helpers::DeprecatedBlockHelpers
- end
-
module SharedTagHelpers
extend ActiveSupport::Testing::Declarative
- def render_content(start, inside)
- template = block_helper(start, inside)
- ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new)
+ def maybe_deprecated
+ if @deprecated
+ assert_deprecated { yield }
+ else
+ yield
+ end
end
test "percent equals works for content_tag and does not require parenthesis on method call" do
- assert_equal "<div>Hello world</div>", render_content("content_tag :div", "Hello world")
+ maybe_deprecated { assert_equal "<div>Hello world</div>", render_content("content_tag :div", "Hello world") }
end
test "percent equals works for javascript_tag" do
expected_output = "<script type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>"
- assert_equal expected_output, render_content("javascript_tag", "alert('Hello')")
+ maybe_deprecated { assert_equal expected_output, render_content("javascript_tag", "alert('Hello')") }
end
test "percent equals works for javascript_tag with options" do
expected_output = "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>"
- assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')")
+ maybe_deprecated { assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") }
end
test "percent equals works with form tags" do
expected_output = "<form action=\"foo\" method=\"post\">hello</form>"
- assert_equal expected_output, render_content("form_tag('foo')", "<%= 'hello' %>")
+ maybe_deprecated { assert_equal expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") }
end
test "percent equals works with fieldset tags" do
expected_output = "<fieldset><legend>foo</legend>hello</fieldset>"
- assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>")
+ maybe_deprecated { assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") }
end
end
- class TagHelperTest < ActiveSupport::TestCase
- def context
- ViewContext
- end
-
+ class TagHelperTest < BlockTestCase
def block_helper(str, rest)
"<%= #{str} do %>#{rest}<% end %>"
end
@@ -68,15 +46,15 @@ module ERBTest
include SharedTagHelpers
end
- class DeprecatedTagHelperTest < ActiveSupport::TestCase
- def context
- DeprecatedViewContext
- end
-
+ class DeprecatedTagHelperTest < BlockTestCase
def block_helper(str, rest)
"<% __in_erb_template=true %><% #{str} do %>#{rest}<% end %>"
end
+ def setup
+ @deprecated = true
+ end
+
include SharedTagHelpers
end
end \ No newline at end of file
diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb
index f49b763881..c5c2a6b952 100644
--- a/actionpack/test/template/javascript_helper_test.rb
+++ b/actionpack/test/template/javascript_helper_test.rb
@@ -17,7 +17,7 @@ class JavaScriptHelperTest < ActionView::TestCase
ActiveSupport.escape_html_entities_in_json = true
@template = self
end
-
+
def teardown
ActiveSupport.escape_html_entities_in_json = false
end
@@ -60,6 +60,35 @@ class JavaScriptHelperTest < ActionView::TestCase
button_to_function("Greeting")
end
+ def test_link_to_function
+ assert_dom_equal %(<a href="#" onclick="alert('Hello world!'); return false;">Greeting</a>),
+ link_to_function("Greeting", "alert('Hello world!')")
+ end
+
+ def test_link_to_function_with_existing_onclick
+ assert_dom_equal %(<a href="#" onclick="confirm('Sanity!'); alert('Hello world!'); return false;">Greeting</a>),
+ link_to_function("Greeting", "alert('Hello world!')", :onclick => "confirm('Sanity!')")
+ end
+
+ def test_link_to_function_with_rjs_block
+ html = link_to_function( "Greet me!" ) do |page|
+ page.replace_html 'header', "<h1>Greetings</h1>"
+ end
+ assert_dom_equal %(<a href="#" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; return false;">Greet me!</a>), html
+ end
+
+ def test_link_to_function_with_rjs_block_and_options
+ html = link_to_function( "Greet me!", :class => "updater" ) do |page|
+ page.replace_html 'header', "<h1>Greetings</h1>"
+ end
+ assert_dom_equal %(<a href="#" class="updater" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; return false;">Greet me!</a>), html
+ end
+
+ def test_link_to_function_with_href
+ assert_dom_equal %(<a href="http://example.com/" onclick="alert('Hello world!'); return false;">Greeting</a>),
+ link_to_function("Greeting", "alert('Hello world!')", :href => 'http://example.com/')
+ end
+
def test_javascript_tag
self.output_buffer = 'foo'
diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb
index 697ebc694a..df1aa2edb2 100644
--- a/actionpack/test/template/lookup_context_test.rb
+++ b/actionpack/test/template/lookup_context_test.rb
@@ -22,34 +22,35 @@ class LookupContextTest < ActiveSupport::TestCase
end
test "normalizes details on initialization" do
- formats = Mime::SET + [nil]
- locale = [I18n.locale, nil]
- assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details
- end
-
- test "allows me to set details" do
- @lookup_context.details = { :formats => [:html], :locale => :pt }
- assert_equal Hash[:formats => [:html, nil], :locale => [:pt, nil]], @lookup_context.details
+ assert_equal Mime::SET, @lookup_context.formats
+ assert_equal :en, @lookup_context.locale
end
- test "does not allow details to be modified in place" do
- assert @lookup_context.details.frozen?
+ test "allows me to update details" do
+ @lookup_context.update_details(:formats => [:html], :locale => :pt)
+ assert_equal [:html], @lookup_context.formats
+ assert_equal :pt, @lookup_context.locale
end
test "allows me to update an specific detail" do
@lookup_context.update_details(:locale => :pt)
assert_equal :pt, I18n.locale
- formats = Mime::SET + [nil]
- locale = [I18n.locale, nil]
- assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details
+ assert_equal :pt, @lookup_context.locale
+ end
+
+ test "allows me to freeze and retrieve frozen formats" do
+ @lookup_context.formats.freeze
+ assert @lookup_context.formats.frozen?
end
test "allows me to change some details to execute an specific block of code" do
- formats = Mime::SET + [nil]
+ formats = Mime::SET
@lookup_context.update_details(:locale => :pt) do
- assert_equal Hash[:formats => formats, :locale => [:pt, nil]], @lookup_context.details
+ assert_equal formats, @lookup_context.formats
+ assert_equal :pt, @lookup_context.locale
end
- assert_equal Hash[:formats => formats, :locale => [:en, nil]], @lookup_context.details
+ assert_equal formats, @lookup_context.formats
+ assert_equal :en, @lookup_context.locale
end
test "provides getters and setters for formats" do
@@ -62,6 +63,11 @@ class LookupContextTest < ActiveSupport::TestCase
assert_equal Mime::SET, @lookup_context.formats
end
+ test "adds :html fallback to :js formats" do
+ @lookup_context.formats = [:js]
+ assert_equal [:js, :html], @lookup_context.formats
+ end
+
test "provides getters and setters for locale" do
@lookup_context.locale = :pt
assert_equal :pt, @lookup_context.locale
@@ -94,6 +100,13 @@ class LookupContextTest < ActiveSupport::TestCase
assert_equal "Hey verden", template.source
end
+ test "found templates respects given formats if one cannot be found from template or handler" do
+ ActionView::Template::Handlers::ERB.expects(:default_format).returns(nil)
+ @lookup_context.formats = [:text]
+ template = @lookup_context.find("hello_world", "test")
+ assert_equal [:text], template.formats
+ end
+
test "adds fallbacks to view paths when required" do
assert_equal 1, @lookup_context.view_paths.size
diff --git a/actionpack/test/template/number_helper_i18n_test.rb b/actionpack/test/template/number_helper_i18n_test.rb
index bf5b81292f..f730a0d7f5 100644
--- a/actionpack/test/template/number_helper_i18n_test.rb
+++ b/actionpack/test/template/number_helper_i18n_test.rb
@@ -1,69 +1,95 @@
require 'abstract_unit'
-class NumberHelperI18nTests < Test::Unit::TestCase
- include ActionView::Helpers::NumberHelper
-
- attr_reader :request
+class NumberHelperTest < ActionView::TestCase
+ tests ActionView::Helpers::NumberHelper
def setup
- @number_defaults = { :precision => 3, :delimiter => ',', :separator => '.' }
- @currency_defaults = { :unit => '$', :format => '%u%n', :precision => 2 }
- @human_defaults = { :precision => 1 }
- @human_storage_units_format_default = "%n %u"
- @human_storage_units_units_byte_other = "Bytes"
- @human_storage_units_units_kb_other = "KB"
- @percentage_defaults = { :delimiter => '' }
- @precision_defaults = { :delimiter => '' }
+ I18n.backend.store_translations 'ts',
+ :number => {
+ :format => { :precision => 3, :delimiter => ',', :separator => '.', :significant => false, :strip_insignificant_zeros => false },
+ :currency => { :format => { :unit => '&$', :format => '%u - %n', :precision => 2 } },
+ :human => {
+ :format => {
+ :precision => 2,
+ :significant => true,
+ :strip_insignificant_zeros => true
+ },
+ :storage_units => {
+ :format => "%n %u",
+ :units => {
+ :byte => "b",
+ :kb => "k"
+ }
+ },
+ :decimal_units => {
+ :format => "%n %u",
+ :units => {
+ :deci => {:one => "Tenth", :other => "Tenths"},
+ :unit => "u",
+ :ten => {:one => "Ten", :other => "Tens"},
+ :thousand => "t",
+ :million => "m" ,
+ :billion =>"b" ,
+ :trillion =>"t" ,
+ :quadrillion =>"q"
+ }
+ }
+ },
+ :percentage => { :format => {:delimiter => '', :precision => 2, :strip_insignificant_zeros => true} },
+ :precision => { :format => {:delimiter => '', :significant => true} }
+ },
+ :custom_units_for_number_to_human => {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+ end
- I18n.backend.store_translations 'en', :number => { :format => @number_defaults,
- :currency => { :format => @currency_defaults }, :human => @human_defaults }
+ def test_number_to_currency
+ assert_equal("&$ - 10.00", number_to_currency(10, :locale => 'ts'))
end
- def test_number_to_currency_translates_currency_formats
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- I18n.expects(:translate).with(:'number.currency.format', :locale => 'en',
- :raise => true).returns(@currency_defaults)
- number_to_currency(1, :locale => 'en')
+ def test_number_with_precision
+ #Delimiter was set to ""
+ assert_equal("10000", number_with_precision(10000, :locale => 'ts'))
+
+ #Precision inherited and significant was set
+ assert_equal("1.00", number_with_precision(1.0, :locale => 'ts'))
+
end
- def test_number_with_precision_translates_number_formats
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- I18n.expects(:translate).with(:'number.precision.format', :locale => 'en',
- :raise => true).returns(@precision_defaults)
- number_with_precision(1, :locale => 'en')
+ def test_number_with_delimiter
+ #Delimiter "," and separator "."
+ assert_equal("1,000,000.234", number_with_delimiter(1000000.234, :locale => 'ts'))
end
- def test_number_with_delimiter_translates_number_formats
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- number_with_delimiter(1, :locale => 'en')
+ def test_number_to_percentage
+ # to see if strip_insignificant_zeros is true
+ assert_equal("1%", number_to_percentage(1, :locale => 'ts'))
+ # precision is 2, significant should be inherited
+ assert_equal("1.24%", number_to_percentage(1.2434, :locale => 'ts'))
+ # no delimiter
+ assert_equal("12434%", number_to_percentage(12434, :locale => 'ts'))
end
- def test_number_to_percentage_translates_number_formats
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- I18n.expects(:translate).with(:'number.percentage.format', :locale => 'en',
- :raise => true).returns(@percentage_defaults)
- number_to_percentage(1, :locale => 'en')
+ def test_number_to_human_size
+ #b for bytes and k for kbytes
+ assert_equal("2 k", number_to_human_size(2048, :locale => 'ts'))
+ assert_equal("42 b", number_to_human_size(42, :locale => 'ts'))
end
- def test_number_to_human_size_translates_human_formats
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- I18n.expects(:translate).with(:'number.human.format', :locale => 'en',
- :raise => true).returns(@human_defaults)
- I18n.expects(:translate).with(:'number.human.storage_units.format', :locale => 'en',
- :raise => true).returns(@human_storage_units_format_default)
- I18n.expects(:translate).with(:'number.human.storage_units.units.kb', :locale => 'en', :count => 2,
- :raise => true).returns(@human_storage_units_units_kb_other)
- # 2KB
- number_to_human_size(2048, :locale => 'en')
+ def test_number_to_human_with_default_translation_scope
+ #Using t for thousand
+ assert_equal "2 t", number_to_human(2000, :locale => 'ts')
+ #Significant was set to true with precision 2, using b for billion
+ assert_equal "1.2 b", number_to_human(1234567890, :locale => 'ts')
+ #Using pluralization (Ten/Tens and Tenth/Tenths)
+ assert_equal "1 Tenth", number_to_human(0.1, :locale => 'ts')
+ assert_equal "1.3 Tenth", number_to_human(0.134, :locale => 'ts')
+ assert_equal "2 Tenths", number_to_human(0.2, :locale => 'ts')
+ assert_equal "1 Ten", number_to_human(10, :locale => 'ts')
+ assert_equal "1.2 Ten", number_to_human(12, :locale => 'ts')
+ assert_equal "2 Tens", number_to_human(20, :locale => 'ts')
+ end
- I18n.expects(:translate).with(:'number.format', :locale => 'en', :raise => true).returns(@number_defaults)
- I18n.expects(:translate).with(:'number.human.format', :locale => 'en',
- :raise => true).returns(@human_defaults)
- I18n.expects(:translate).with(:'number.human.storage_units.format', :locale => 'en',
- :raise => true).returns(@human_storage_units_format_default)
- I18n.expects(:translate).with(:'number.human.storage_units.units.byte', :locale => 'en', :count => 42,
- :raise => true).returns(@human_storage_units_units_byte_other)
- # 42 Bytes
- number_to_human_size(42, :locale => 'en')
+ def test_number_to_human_with_custom_translation_scope
+ #Significant was set to true with precision 2, with custom translated units
+ assert_equal "4.3 cm", number_to_human(0.0432, :locale => 'ts', :units => :custom_units_for_number_to_human)
end
end
diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb
index 0a2b82bd89..50c57a5588 100644
--- a/actionpack/test/template/number_helper_test.rb
+++ b/actionpack/test/template/number_helper_test.rb
@@ -19,6 +19,15 @@ class NumberHelperTest < ActionView::TestCase
gigabytes(number) * 1024
end
+ def silence_deprecation_warnings
+ @old_deprecatios_silenced = ActiveSupport::Deprecation.silenced
+ ActiveSupport::Deprecation.silenced = true
+ end
+
+ def restore_deprecation_warnings
+ ActiveSupport::Deprecation.silenced = @old_deprecatios_silenced
+ end
+
def test_number_to_phone
assert_equal("555-1234", number_to_phone(5551234))
assert_equal("800-555-1212", number_to_phone(8005551212))
@@ -31,8 +40,6 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("+18005551212", number_to_phone(8005551212, :country_code => 1, :delimiter => ''))
assert_equal("22-555-1212", number_to_phone(225551212))
assert_equal("+45-22-555-1212", number_to_phone(225551212, :country_code => 45))
- assert_equal("x", number_to_phone("x"))
- assert_nil number_to_phone(nil)
end
def test_number_to_currency
@@ -43,9 +50,6 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("&pound;1234567890,50", number_to_currency(1234567890.50, {:unit => "&pound;", :separator => ",", :delimiter => ""}))
assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50"))
assert_equal("1,234,567,890.50 K&#269;", number_to_currency("1234567890.50", {:unit => "K&#269;", :format => "%n %u"}))
- #assert_equal("$x.", number_to_currency("x")) # fails due to API consolidation
- assert_equal("$x", number_to_currency("x"))
- assert_nil number_to_currency(nil)
end
def test_number_to_percentage
@@ -54,9 +58,8 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("302.06%", number_to_percentage(302.0574, {:precision => 2}))
assert_equal("100.000%", number_to_percentage("100"))
assert_equal("1000.000%", number_to_percentage("1000"))
- assert_equal("x%", number_to_percentage("x"))
+ assert_equal("123.4%", number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
assert_equal("1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ','))
- assert_nil number_to_percentage(nil)
end
def test_number_with_delimiter
@@ -70,8 +73,6 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("123,456,789.78901", number_with_delimiter(123456789.78901))
assert_equal("0.78901", number_with_delimiter(0.78901))
assert_equal("123,456.78", number_with_delimiter("123456.78"))
- assert_equal("x", number_with_delimiter("x"))
- assert_nil number_with_delimiter(nil)
end
def test_number_with_delimiter_with_options_hash
@@ -81,6 +82,16 @@ class NumberHelperTest < ActionView::TestCase
assert_equal '12.345.678,05', number_with_delimiter(12345678.05, :delimiter => '.', :separator => ',')
end
+ def test_number_with_delimiter_old_api
+ silence_deprecation_warnings
+ assert_equal '12 345 678', number_with_delimiter(12345678, " ")
+ assert_equal '12-345-678.05', number_with_delimiter(12345678.05, '-')
+ assert_equal '12.345.678,05', number_with_delimiter(12345678.05, '.', ',')
+ assert_equal '12,345,678.05', number_with_delimiter(12345678.05, ',', '.')
+ assert_equal '12 345 678-05', number_with_delimiter(12345678.05, ',', '.', :delimiter => ' ', :separator => '-')
+ restore_deprecation_warnings
+ end
+
def test_number_with_precision
assert_equal("111.235", number_with_precision(111.2346))
assert_equal("31.83", number_with_precision(31.825, :precision => 2))
@@ -91,10 +102,6 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("3268", number_with_precision((32.6751 * 100.00), :precision => 0))
assert_equal("112", number_with_precision(111.50, :precision => 0))
assert_equal("1234567892", number_with_precision(1234567891.50, :precision => 0))
-
- # Return non-numeric params unchanged.
- assert_equal("x", number_with_precision("x"))
- assert_nil number_with_precision(nil)
end
def test_number_with_precision_with_custom_delimiter_and_separator
@@ -102,48 +109,272 @@ class NumberHelperTest < ActionView::TestCase
assert_equal '1.231,83', number_with_precision(1231.825, :precision => 2, :separator => ',', :delimiter => '.')
end
+ def test_number_with_precision_with_significant_digits
+ assert_equal "124000", number_with_precision(123987, :precision => 3, :significant => true)
+ assert_equal "120000000", number_with_precision(123987876, :precision => 2, :significant => true )
+ assert_equal "40000", number_with_precision("43523", :precision => 1, :significant => true )
+ assert_equal "9775", number_with_precision(9775, :precision => 4, :significant => true )
+ assert_equal "5.4", number_with_precision(5.3923, :precision => 2, :significant => true )
+ assert_equal "5", number_with_precision(5.3923, :precision => 1, :significant => true )
+ assert_equal "1", number_with_precision(1.232, :precision => 1, :significant => true )
+ assert_equal "7", number_with_precision(7, :precision => 1, :significant => true )
+ assert_equal "1", number_with_precision(1, :precision => 1, :significant => true )
+ assert_equal "53", number_with_precision(52.7923, :precision => 2, :significant => true )
+ assert_equal "9775.00", number_with_precision(9775, :precision => 6, :significant => true )
+ assert_equal "5.392900", number_with_precision(5.3929, :precision => 7, :significant => true )
+ end
+
+ def test_number_with_precision_with_strip_insignificant_zeros
+ assert_equal "9775.43", number_with_precision(9775.43, :precision => 4, :strip_insignificant_zeros => true )
+ assert_equal "9775.2", number_with_precision(9775.2, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
+ end
+
+ def test_number_with_precision_with_significant_true_and_zero_precision
+ # Zero precision with significant is a mistake (would always return zero),
+ # so we treat it as if significant was false (increases backwards compatibily for number_to_human_size)
+ assert_equal "124", number_with_precision(123.987, :precision => 0, :significant => true)
+ assert_equal "12", number_with_precision(12, :precision => 0, :significant => true )
+ assert_equal "12", number_with_precision("12.3", :precision => 0, :significant => true )
+ end
+
+ def test_number_with_precision_old_api
+ silence_deprecation_warnings
+ assert_equal("31.8250", number_with_precision(31.825, 4))
+ assert_equal("111.235", number_with_precision(111.2346, 3))
+ assert_equal("111.00", number_with_precision(111, 2))
+ assert_equal("111.000", number_with_precision(111, 2, :precision =>3))
+ restore_deprecation_warnings
+ end
+
def test_number_to_human_size
assert_equal '0 Bytes', number_to_human_size(0)
assert_equal '1 Byte', number_to_human_size(1)
assert_equal '3 Bytes', number_to_human_size(3.14159265)
assert_equal '123 Bytes', number_to_human_size(123.0)
assert_equal '123 Bytes', number_to_human_size(123)
- assert_equal '1.2 KB', number_to_human_size(1234)
+ assert_equal '1.21 KB', number_to_human_size(1234)
assert_equal '12.1 KB', number_to_human_size(12345)
- assert_equal '1.2 MB', number_to_human_size(1234567)
- assert_equal '1.1 GB', number_to_human_size(1234567890)
- assert_equal '1.1 TB', number_to_human_size(1234567890123)
- assert_equal '1025 TB', number_to_human_size(terabytes(1025))
+ assert_equal '1.18 MB', number_to_human_size(1234567)
+ assert_equal '1.15 GB', number_to_human_size(1234567890)
+ assert_equal '1.12 TB', number_to_human_size(1234567890123)
+ assert_equal '1030 TB', number_to_human_size(terabytes(1026))
assert_equal '444 KB', number_to_human_size(kilobytes(444))
- assert_equal '1023 MB', number_to_human_size(megabytes(1023))
+ assert_equal '1020 MB', number_to_human_size(megabytes(1023))
assert_equal '3 TB', number_to_human_size(terabytes(3))
- assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2)
+ assert_equal '1.2 MB', number_to_human_size(1234567, :precision => 2)
assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4)
- assert_equal("123 Bytes", number_to_human_size("123"))
- assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2)
+ assert_equal '123 Bytes', number_to_human_size('123')
+ assert_equal '1 KB', number_to_human_size(kilobytes(1.0123), :precision => 2)
assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4)
assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4)
assert_equal '1 Byte', number_to_human_size(1.1)
assert_equal '10 Bytes', number_to_human_size(10)
- #assert_nil number_to_human_size('x') # fails due to API consolidation
- assert_nil number_to_human_size(nil)
end
def test_number_to_human_size_with_options_hash
- assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2)
+ assert_equal '1.2 MB', number_to_human_size(1234567, :precision => 2)
assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4)
- assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2)
+ assert_equal '1 KB', number_to_human_size(kilobytes(1.0123), :precision => 2)
assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4)
assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4)
- assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 0)
- assert_equal '500 MB', number_to_human_size(524288000, :precision=>0)
- assert_equal '40 KB', number_to_human_size(41010, :precision => 0)
- assert_equal '40 KB', number_to_human_size(41100, :precision => 0)
+ assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 1)
+ assert_equal '500 MB', number_to_human_size(524288000, :precision=>3)
+ assert_equal '40 KB', number_to_human_size(41010, :precision => 1)
+ assert_equal '40 KB', number_to_human_size(41100, :precision => 2)
+ assert_equal '1.0 KB', number_to_human_size(kilobytes(1.0123), :precision => 2, :strip_insignificant_zeros => false)
+ assert_equal '1.012 KB', number_to_human_size(kilobytes(1.0123), :precision => 3, :significant => false)
+ assert_equal '1 KB', number_to_human_size(kilobytes(1.0123), :precision => 0, :significant => true) #ignores significant it precision is 0
end
def test_number_to_human_size_with_custom_delimiter_and_separator
- assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2, :separator => ',')
+ assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0123), :precision => 3, :separator => ',')
assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',')
- assert_equal '1.000,1 TB', number_to_human_size(terabytes(1000.1), :delimiter => '.', :separator => ',')
+ assert_equal '1.000,1 TB', number_to_human_size(terabytes(1000.1), :precision => 5, :delimiter => '.', :separator => ',')
+ end
+
+ def test_number_to_human_size_old_api
+ silence_deprecation_warnings
+ assert_equal '1.3143 KB', number_to_human_size(kilobytes(1.3143), 4, :significant => false)
+ assert_equal '10.45 KB', number_to_human_size(kilobytes(10.453), 4)
+ assert_equal '10 KB', number_to_human_size(kilobytes(10.453), 4, :precision => 2)
+ restore_deprecation_warnings
+ end
+
+ def test_number_to_human
+ assert_equal '123', number_to_human(123)
+ assert_equal '1.23 Thousand', number_to_human(1234)
+ assert_equal '12.3 Thousand', number_to_human(12345)
+ assert_equal '1.23 Million', number_to_human(1234567)
+ assert_equal '1.23 Billion', number_to_human(1234567890)
+ assert_equal '1.23 Trillion', number_to_human(1234567890123)
+ assert_equal '1.23 Quadrillion', number_to_human(1234567890123456)
+ assert_equal '1230 Quadrillion', number_to_human(1234567890123456789)
+ assert_equal '490 Thousand', number_to_human(489939, :precision => 2)
+ assert_equal '489.9 Thousand', number_to_human(489939, :precision => 4)
+ assert_equal '489 Thousand', number_to_human(489000, :precision => 4)
+ assert_equal '489.0 Thousand', number_to_human(489000, :precision => 4, :strip_insignificant_zeros => false)
+ assert_equal '1.2346 Million', number_to_human(1234567, :precision => 4, :significant => false)
+ assert_equal '1,2 Million', number_to_human(1234567, :precision => 1, :significant => false, :separator => ',')
+ assert_equal '1 Million', number_to_human(1234567, :precision => 0, :significant => true, :separator => ',') #significant forced to false
+ end
+
+ def test_number_to_human_with_custom_units
+ #Only integers
+ volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+ assert_equal '123 lt', number_to_human(123456, :units => volume)
+ assert_equal '12 ml', number_to_human(12, :units => volume)
+ assert_equal '1.23 m3', number_to_human(1234567, :units => volume)
+
+ #Including fractionals
+ distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+ assert_equal '1.23 mm', number_to_human(0.00123, :units => distance)
+ assert_equal '1.23 cm', number_to_human(0.0123, :units => distance)
+ assert_equal '1.23 dm', number_to_human(0.123, :units => distance)
+ assert_equal '1.23 m', number_to_human(1.23, :units => distance)
+ assert_equal '1.23 dam', number_to_human(12.3, :units => distance)
+ assert_equal '1.23 hm', number_to_human(123, :units => distance)
+ assert_equal '1.23 km', number_to_human(1230, :units => distance)
+ assert_equal '1.23 km', number_to_human(1230, :units => distance)
+ assert_equal '1.23 km', number_to_human(1230, :units => distance)
+ assert_equal '12.3 km', number_to_human(12300, :units => distance)
+
+ #The quantifiers don't need to be a continuous sequence
+ gangster = {:hundred => "hundred bucks", :million => "thousand quids"}
+ assert_equal '1 hundred bucks', number_to_human(100, :units => gangster)
+ assert_equal '25 hundred bucks', number_to_human(2500, :units => gangster)
+ assert_equal '25 thousand quids', number_to_human(25000000, :units => gangster)
+ assert_equal '12300 thousand quids', number_to_human(12345000000, :units => gangster)
+
+ #Spaces are stripped from the resulting string
+ assert_equal '4', number_to_human(4, :units => {:unit => "", :ten => 'tens '})
+ assert_equal '4.5 tens', number_to_human(45, :units => {:unit => "", :ten => ' tens '})
end
+
+ def test_number_to_human_with_custom_format
+ assert_equal '123 times Thousand', number_to_human(123456, :format => "%n times %u")
+ volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+ assert_equal '123.lt', number_to_human(123456, :units => volume, :format => "%n.%u")
+ end
+
+ def test_number_helpers_should_return_nil_when_given_nil
+ assert_nil number_to_phone(nil)
+ assert_nil number_to_currency(nil)
+ assert_nil number_to_percentage(nil)
+ assert_nil number_with_delimiter(nil)
+ assert_nil number_with_precision(nil)
+ assert_nil number_to_human_size(nil)
+ assert_nil number_to_human(nil)
+ end
+
+ def test_number_helpers_should_return_non_numeric_param_unchanged
+ assert_equal("+1-x x 123", number_to_phone("x", :country_code => 1, :extension => 123))
+ assert_equal("x", number_to_phone("x"))
+ assert_equal("$x.", number_to_currency("x."))
+ assert_equal("$x", number_to_currency("x"))
+ assert_equal("x%", number_to_percentage("x"))
+ assert_equal("x", number_with_delimiter("x"))
+ assert_equal("x.", number_with_precision("x."))
+ assert_equal("x", number_with_precision("x"))
+ assert_equal "x", number_to_human_size('x')
+ assert_equal "x", number_to_human('x')
+ end
+
+ def test_number_helpers_outputs_are_html_safe
+ assert number_to_human(1).html_safe?
+ assert !number_to_human("<script></script>").html_safe?
+ assert number_to_human("asdf".html_safe).html_safe?
+
+ assert number_to_human_size(1).html_safe?
+ assert number_to_human_size(1000000).html_safe?
+ assert !number_to_human_size("<script></script>").html_safe?
+ assert number_to_human_size("asdf".html_safe).html_safe?
+
+ assert number_with_precision(1, :strip_insignificant_zeros => false).html_safe?
+ assert number_with_precision(1, :strip_insignificant_zeros => true).html_safe?
+ assert !number_with_precision("<script></script>").html_safe?
+ assert number_with_precision("asdf".html_safe).html_safe?
+
+ assert number_to_currency(1).html_safe?
+ assert !number_to_currency("<script></script>").html_safe?
+ assert number_to_currency("asdf".html_safe).html_safe?
+
+ assert number_to_percentage(1).html_safe?
+ assert !number_to_percentage("<script></script>").html_safe?
+ assert number_to_percentage("asdf".html_safe).html_safe?
+
+ assert number_to_phone(1).html_safe?
+ assert !number_to_phone("<script></script>").html_safe?
+ assert number_to_phone("asdf".html_safe).html_safe?
+
+ assert number_with_delimiter(1).html_safe?
+ assert !number_with_delimiter("<script></script>").html_safe?
+ assert number_with_delimiter("asdf".html_safe).html_safe?
+ end
+
+ def test_number_helpers_should_raise_error_if_invalid_when_specified
+ assert_raise InvalidNumberError do
+ number_to_human("x", :raise => true)
+ end
+ begin
+ number_to_human("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_to_human_size("x", :raise => true)
+ end
+ begin
+ number_to_human_size("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_with_precision("x", :raise => true)
+ end
+ begin
+ number_with_precision("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_to_currency("x", :raise => true)
+ end
+ begin
+ number_with_precision("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_to_percentage("x", :raise => true)
+ end
+ begin
+ number_to_percentage("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_with_delimiter("x", :raise => true)
+ end
+ begin
+ number_with_delimiter("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ assert_raise InvalidNumberError do
+ number_to_phone("x", :raise => true)
+ end
+ begin
+ number_to_phone("x", :raise => true)
+ rescue InvalidNumberError => e
+ assert_equal "x", e.number
+ end
+
+ end
+
end
diff --git a/actionpack/test/template/output_buffer_test.rb b/actionpack/test/template/output_buffer_test.rb
index 36bbaf9099..bd49a11af1 100644
--- a/actionpack/test/template/output_buffer_test.rb
+++ b/actionpack/test/template/output_buffer_test.rb
@@ -10,6 +10,7 @@ class OutputBufferTest < ActionController::TestCase
tests TestController
def setup
+ @vc = @controller.view_context
get :index
assert_equal ['foo'], body_parts
end
@@ -19,21 +20,21 @@ class OutputBufferTest < ActionController::TestCase
end
test 'flushing ignores nil output buffer' do
- @controller.template.flush_output_buffer
+ @controller.view_context.flush_output_buffer
assert_nil output_buffer
assert_equal ['foo'], body_parts
end
test 'flushing ignores empty output buffer' do
- @controller.template.output_buffer = ''
- @controller.template.flush_output_buffer
+ @vc.output_buffer = ''
+ @vc.flush_output_buffer
assert_equal '', output_buffer
assert_equal ['foo'], body_parts
end
test 'flushing appends the output buffer to the body parts' do
- @controller.template.output_buffer = 'bar'
- @controller.template.flush_output_buffer
+ @vc.output_buffer = 'bar'
+ @vc.flush_output_buffer
assert_equal '', output_buffer
assert_equal ['foo', 'bar'], body_parts
end
@@ -41,8 +42,8 @@ class OutputBufferTest < ActionController::TestCase
if '1.9'.respond_to?(:force_encoding)
test 'flushing preserves output buffer encoding' do
original_buffer = ' '.force_encoding(Encoding::EUC_JP)
- @controller.template.output_buffer = original_buffer
- @controller.template.flush_output_buffer
+ @vc.output_buffer = original_buffer
+ @vc.flush_output_buffer
assert_equal ['foo', original_buffer], body_parts
assert_not_equal original_buffer, output_buffer
assert_equal Encoding::EUC_JP, output_buffer.encoding
@@ -51,10 +52,10 @@ class OutputBufferTest < ActionController::TestCase
protected
def output_buffer
- @controller.template.output_buffer
+ @vc.output_buffer
end
def body_parts
- @controller.template.response.body_parts
+ @controller.response.body_parts
end
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index cea8ab1bce..e54ebfbf8d 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -9,7 +9,7 @@ module RenderTestCases
def setup_view(paths)
@assigns = { :secret => 'in the sauce' }
@view = ActionView::Base.new(paths, @assigns)
- @controller_view = ActionView::Base.for_controller(TestController.new)
+ @controller_view = TestController.new.view_context
# Reload and register danish language for testing
I18n.reload!
@@ -228,6 +228,14 @@ module RenderTestCases
@view.render(:file => "test/hello_world.erb", :layout => "layouts/yield")
end
+ # TODO: Move to deprecated_tests.rb
+ def test_render_with_nested_layout_deprecated
+ assert_deprecated do
+ assert_equal %(<title>title</title>\n\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
+ @view.render(:file => "test/deprecated_nested_layout.erb", :layout => "layouts/yield")
+ end
+ end
+
def test_render_with_nested_layout
assert_equal %(<title>title</title>\n\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
@view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield")
diff --git a/actionpack/test/template/translation_helper_test.rb b/actionpack/test/template/translation_helper_test.rb
index 699fb2f5bc..6782bf06d4 100644
--- a/actionpack/test/template/translation_helper_test.rb
+++ b/actionpack/test/template/translation_helper_test.rb
@@ -20,7 +20,14 @@ class TranslationHelperTest < ActiveSupport::TestCase
def test_translation_of_an_array
I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"])
- assert_equal ["foo", "bar"], translate(["foo", "bar"])
+ assert_equal "foobar", translate(["foo", "bar"])
+ end
+
+ def test_translation_of_an_array_with_html
+ expected = '<a href="#">foo</a><a href="#">bar</a>'
+ I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(['<a href="#">foo</a>', '<a href="#">bar</a>'])
+ @view = ActionView::Base.new(ActionController::Base.view_paths, {})
+ assert_equal expected, @view.render(:file => "test/array_translation")
end
def test_delegates_localize_to_i18n
@@ -34,4 +41,10 @@ class TranslationHelperTest < ActiveSupport::TestCase
@view = ActionView::Base.new(ActionController::Base.view_paths, {})
assert_equal "helper", @view.render(:file => "test/translation")
end
+
+ def test_scoping_by_partial_of_an_array
+ I18n.expects(:translate).with("test.scoped_array_translation.foo.bar", :raise => true).returns(["foo", "bar"])
+ @view = ActionView::Base.new(ActionController::Base.view_paths, {})
+ assert_equal "foobar", @view.render(:file => "test/scoped_array_translation")
+ end
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 165cb655da..87b2e59255 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -238,10 +238,7 @@ class UrlHelperTest < ActionView::TestCase
end
def test_link_tag_using_block_in_erb
- __in_erb_template = ''
-
- link_to("http://example.com") { concat("Example site") }
-
+ output_buffer = link_to("http://example.com") { concat("Example site") }
assert_equal '<a href="http://example.com">Example site</a>', output_buffer
end
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index c1334069fa..f04829ef09 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -89,13 +89,20 @@ module ActiveModel
# # => 'address_id'
def define_attr_method(name, value=nil, &block)
sing = singleton_class
- sing.send :alias_method, "original_#{name}", name
+ sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
+ if method_defined?(:original_#{name})
+ undef :original_#{name}
+ end
+ alias_method :original_#{name}, :#{name}
+ eorb
if block_given?
sing.send :define_method, name, &block
else
# use eval instead of a block to work around a memory leak in dev
# mode in fcgi
- sing.class_eval "def #{name}; #{value.to_s.inspect}; end"
+ sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
+ def #{name}; #{value.to_s.inspect}; end
+ eorb
end
end
@@ -256,8 +263,13 @@ module ActiveModel
if respond_to?(generate_method)
send(generate_method, attr_name)
else
+ method_name = matcher.method_name(attr_name)
+
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__+1
- def #{matcher.method_name(attr_name)}(*args)
+ if method_defined?(:#{method_name})
+ undef :#{method_name}
+ end
+ def #{method_name}(*args)
send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
end
STR
diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb
index a7e0cf90c1..d4e98de57b 100644
--- a/activemodel/lib/active_model/callbacks.rb
+++ b/activemodel/lib/active_model/callbacks.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
require 'active_support/callbacks'
module ActiveModel
@@ -91,7 +92,7 @@ module ActiveModel
options = callbacks.extract_options!
options = { :terminator => "result == false", :scope => [:kind, :name] }.merge(options)
- types = Array(options.delete(:only))
+ types = Array.wrap(options.delete(:only))
types = [:before, :around, :after] if types.empty?
callbacks.each do |callback|
@@ -124,10 +125,10 @@ module ActiveModel
def self.after_#{callback}(*args, &block)
options = args.extract_options!
options[:prepend] = true
- options[:if] = Array(options[:if]) << "!halted && value != false"
+ options[:if] = Array.wrap(options[:if]) << "!halted && value != false"
set_callback(:#{callback}, :after, *(args << options), &block)
end
CALLBACK
end
end
-end \ No newline at end of file
+end
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index 5f02929a9d..cb67ef7270 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -1,3 +1,5 @@
+require 'active_support/hash_with_indifferent_access'
+
module ActiveModel
# <tt>ActiveModel::Dirty</tt> provides a way to track changes in your
# object in the same way as ActiveRecord does.
@@ -86,12 +88,17 @@ module ActiveModel
attribute_method_affix :prefix => 'reset_', :suffix => '!'
end
+ def initialize(*)
+ @changed_attributes = {}
+ super
+ end
+
# Do any attributes have unsaved changes?
# person.changed? # => false
# person.name = 'bob'
# person.changed? # => true
def changed?
- !changed_attributes.empty?
+ !@changed_attributes.empty?
end
# List of attributes with unsaved changes.
@@ -99,7 +106,7 @@ module ActiveModel
# person.name = 'bob'
# person.changed # => ['name']
def changed
- changed_attributes.keys
+ @changed_attributes.keys
end
# Map of changed attrs => [original value, new value].
@@ -107,7 +114,7 @@ module ActiveModel
# person.name = 'bob'
# person.changes # => { 'name' => ['bill', 'bob'] }
def changes
- changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
+ changed.inject(HashWithIndifferentAccess.new){ |h, attr| h[attr] = attribute_change(attr); h }
end
# Map of attributes that were changed when the model was saved.
@@ -116,33 +123,23 @@ module ActiveModel
# person.save
# person.previous_changes # => {'name' => ['bob, 'robert']}
def previous_changes
- previously_changed_attributes
+ @previously_changed
end
private
- # Map of change <tt>attr => original value</tt>.
- def changed_attributes
- @changed_attributes ||= {}
- end
-
- # Map of fields that were changed when the model was saved
- def previously_changed_attributes
- @previously_changed || {}
- end
-
# Handle <tt>*_changed?</tt> for +method_missing+.
def attribute_changed?(attr)
- changed_attributes.include?(attr)
+ @changed_attributes.include?(attr)
end
# Handle <tt>*_change</tt> for +method_missing+.
def attribute_change(attr)
- [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
+ [@changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
end
# Handle <tt>*_was</tt> for +method_missing+.
def attribute_was(attr)
- attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
+ attribute_changed?(attr) ? @changed_attributes[attr] : __send__(attr)
end
# Handle <tt>*_will_change!</tt> for +method_missing+.
@@ -153,12 +150,12 @@ module ActiveModel
rescue TypeError, NoMethodError
end
- changed_attributes[attr] = value
+ @changed_attributes[attr] = value
end
# Handle <tt>reset_*!</tt> for +method_missing+.
def reset_attribute!(attr)
- __send__("#{attr}=", changed_attributes[attr]) if attribute_changed?(attr)
+ __send__("#{attr}=", @changed_attributes[attr]) if attribute_changed?(attr)
end
end
end
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index d8320275df..a9a54a90e0 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/string/inflections'
require 'active_support/ordered_hash'
@@ -206,7 +207,7 @@ module ActiveModel
full_messages = []
each do |attribute, messages|
- messages = Array(messages)
+ messages = Array.wrap(messages)
next if messages.empty?
if attribute == :base
diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb
index a185204680..c226359ea7 100644
--- a/activemodel/lib/active_model/serializers/xml.rb
+++ b/activemodel/lib/active_model/serializers/xml.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/hash/conversions'
@@ -108,7 +109,7 @@ module ActiveModel
end
def serializable_method_attributes
- Array(options[:methods]).inject([]) do |methods, name|
+ Array.wrap(options[:methods]).inject([]) do |methods, name|
methods << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
methods
end
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index ba8648f8c9..708557f4ae 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/hash/keys'
require 'active_model/errors'
@@ -112,11 +113,10 @@ module ActiveModel
# end
# end
#
- # This usage applies to +validate_on_create+ and +validate_on_update as well+.
def validate(*args, &block)
options = args.last
if options.is_a?(Hash) && options.key?(:on)
- options[:if] = Array(options[:if])
+ options[:if] = Array.wrap(options[:if])
options[:if] << "@_on_validate == :#{options[:on]}"
end
set_callback(:validate, *args, &block)
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb
index b61f0cb266..b7c52be3f0 100644
--- a/activemodel/lib/active_model/validator.rb
+++ b/activemodel/lib/active_model/validator.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
require "active_support/core_ext/module/anonymous"
module ActiveModel #:nodoc:
@@ -130,7 +131,7 @@ module ActiveModel #:nodoc:
# +options+ reader, however the <tt>:attributes</tt> option will be removed
# and instead be made available through the +attributes+ reader.
def initialize(options)
- @attributes = Array(options.delete(:attributes))
+ @attributes = Array.wrap(options.delete(:attributes))
raise ":attributes cannot be blank" if @attributes.empty?
super
check_validity!
diff --git a/activemodel/test/cases/dirty_test.rb b/activemodel/test/cases/dirty_test.rb
new file mode 100644
index 0000000000..0883363baf
--- /dev/null
+++ b/activemodel/test/cases/dirty_test.rb
@@ -0,0 +1,30 @@
+require "cases/helper"
+
+class DirtyTest < ActiveModel::TestCase
+ class DirtyModel
+ include ActiveModel::Dirty
+ define_attribute_methods [:name]
+
+ def initialize
+ super
+ @name = nil
+ end
+
+ def name
+ @name
+ end
+
+ def name=(val)
+ name_will_change!
+ @name = val
+ end
+ end
+
+ test "changes accessible through both strings and symbols" do
+ model = DirtyModel.new
+ model.name = "David"
+ assert !model.changes[:name].nil?
+ assert !model.changes['name'].nil?
+ end
+
+end
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index 8b1ea8596a..8121530ab3 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -22,5 +22,5 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
- s.add_dependency('arel', '~> 0.3.1')
+ s.add_dependency('arel', '~> 0.3.3')
end
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 9ecf231a66..08389907ef 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -213,6 +213,11 @@ module ActiveRecord
module_eval do
define_method(name) do |*args|
force_reload = args.first || false
+
+ unless instance_variable_defined?("@#{name}")
+ instance_variable_set("@#{name}", nil)
+ end
+
if (instance_variable_get("@#{name}").nil? || force_reload) && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
attrs = mapping.collect {|pair| read_attribute(pair.first)}
object = case constructor
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index c47e0c37b8..d623ddb915 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1545,15 +1545,19 @@ module ActiveRecord
case name
when :destroy, :delete
- define_method(method_name) do
- association = send(reflection.name)
- association.send(name) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.#{name} if association
+ end
+ eoruby
when :nullify
- define_method(method_name) do
- association = send(reflection.name)
- association.update_attribute(reflection.primary_key_name, nil) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.update_attribute(#{reflection.primary_key_name.inspect}, nil) if association
+ end
+ eoruby
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})"
end
@@ -1571,10 +1575,12 @@ module ActiveRecord
end
method_name = :"belongs_to_dependent_#{name}_for_#{reflection.name}"
- define_method(method_name) do
- association = send(reflection.name)
- association.send(name) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.#{name} if association
+ end
+ eoruby
after_destroy method_name
end
end
@@ -1673,15 +1679,6 @@ module ActiveRecord
reflection
end
- def using_limitable_reflections?(reflections)
- reflections.collect(&:collection?).length.zero?
- end
-
- def column_aliases(join_dependency)
- join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name|
- "#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ")
- end
-
def add_association_callbacks(association_name, options)
callbacks = %w(before_add after_add before_remove after_remove)
callbacks.each do |callback_name|
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 0ff89df1e3..4fb1df3ab9 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -53,6 +53,7 @@ module ActiveRecord
def initialize(owner, reflection)
@owner, @reflection = owner, reflection
+ @updated = false
reflection.check_validity!
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
reset
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 146a6ca55f..0464e8ceea 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -5,6 +5,10 @@ module ActiveRecord
# If the association has a <tt>:through</tt> option further specialization
# is provided by its child HasManyThroughAssociation.
class HasManyAssociation < AssociationCollection #:nodoc:
+ def initialize(owner, reflection)
+ @finder_sql = nil
+ super
+ end
protected
def owner_quoted_id
if @reflection.options[:primary_key]
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 4a3ab9ea82..a8698a2f5a 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -18,7 +18,7 @@ module ActiveRecord
def save_with_dirty(*args) #:nodoc:
if status = save_without_dirty(*args)
@previously_changed = changes
- changed_attributes.clear
+ @changed_attributes.clear
end
status
end
@@ -26,16 +26,16 @@ module ActiveRecord
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
def save_with_dirty!(*args) #:nodoc:
save_without_dirty!(*args).tap do
- @previously_changed = changes
- changed_attributes.clear
+ @previously_changed = changes
+ @changed_attributes.clear
end
end
# <tt>reload</tt> the record and clears changed attributes.
def reload_with_dirty(*args) #:nodoc:
reload_without_dirty(*args).tap do
- previously_changed_attributes.clear
- changed_attributes.clear
+ @previously_changed.clear
+ @changed_attributes.clear
end
end
@@ -45,12 +45,12 @@ module ActiveRecord
attr = attr.to_s
# The attribute already has an unsaved change.
- if changed_attributes.include?(attr)
- old = changed_attributes[attr]
- changed_attributes.delete(attr) unless field_changed?(attr, old, value)
+ if attribute_changed?(attr)
+ old = @changed_attributes[attr]
+ @changed_attributes.delete(attr) unless field_changed?(attr, old, value)
else
old = clone_attribute_value(:read_attribute, attr)
- changed_attributes[attr] = old if field_changed?(attr, old, value)
+ @changed_attributes[attr] = old if field_changed?(attr, old, value)
end
# Carry on.
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 1488d9f967..367b4ce217 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1045,6 +1045,8 @@ module ActiveRecord #:nodoc:
object.instance_variable_set(:@readonly, false)
object.instance_variable_set(:@destroyed, false)
object.instance_variable_set(:@marked_for_destruction, false)
+ object.instance_variable_set(:@previously_changed, {})
+ object.instance_variable_set(:@changed_attributes, {})
object.send(:_run_find_callbacks)
object.send(:_run_initialize_callbacks)
@@ -1513,6 +1515,8 @@ module ActiveRecord #:nodoc:
@readonly = false
@destroyed = false
@marked_for_destruction = false
+ @previously_changed = {}
+ @changed_attributes = {}
ensure_proper_type
@@ -2050,26 +2054,6 @@ module ActiveRecord #:nodoc:
end
# Returns a copy of the attributes hash where all the values have been safely quoted for use in
- # an SQL statement.
- def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
- quoted = {}
- connection = self.class.connection
- attribute_names.each do |name|
- if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
- value = read_attribute(name)
-
- # We need explicit to_yaml because quote() does not properly convert Time/Date fields to YAML.
- if value && self.class.serialized_attributes.has_key?(name) && (value.acts_like?(:date) || value.acts_like?(:time))
- value = value.to_yaml
- end
-
- quoted[name] = connection.quote(value, column)
- end
- end
- include_readonly_attributes ? quoted : remove_readonly_attributes(quoted)
- end
-
- # Returns a copy of the attributes hash where all the values have been safely quoted for use in
# an Arel insert/update method.
def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
attrs = {}
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index abb695264e..0c87e052c4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -181,6 +181,29 @@ module ActiveRecord
# done if the transaction block raises an exception or returns false.
def rollback_db_transaction() end
+ # Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
+ # fragment that has the same semantics as LIMIT and OFFSET.
+ #
+ # +options+ must be a Hash which contains a +:limit+ option
+ # and an +:offset+ option.
+ #
+ # This method *modifies* the +sql+ parameter.
+ #
+ # ===== Examples
+ # add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
+ # generates
+ # SELECT * FROM suppliers LIMIT 10 OFFSET 50
+
+ def add_limit_offset!(sql, options)
+ if limit = options[:limit]
+ sql << " LIMIT #{sanitize_limit(limit)}"
+ end
+ if offset = options[:offset]
+ sql << " OFFSET #{offset.to_i}"
+ end
+ sql
+ end
+
def default_sequence_name(table, column)
nil
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 1f1df7e8c3..521bd810d0 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -61,7 +61,7 @@ module ActiveRecord
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.'
+ $stderr.puts '!!! Please install the mysql gem and try again: gem install mysql.'
raise
end
end
@@ -375,6 +375,18 @@ module ActiveRecord
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end
+ def add_limit_offset!(sql, options) #:nodoc:
+ limit, offset = options[:limit], options[:offset]
+ if limit && offset
+ sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
+ elsif limit
+ sql << " LIMIT #{sanitize_limit(limit)}"
+ elsif offset
+ sql << " OFFSET #{offset.to_i}"
+ end
+ sql
+ end
+
# SCHEMA STATEMENTS ========================================
def structure_dump #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index b3ce8c79dd..31d5266da8 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -651,14 +651,33 @@ module ActiveRecord
end
end
+ # Creates a schema for the given user
+ #
+ # Example:
+ # create_schema('products', 'postgres')
+ def create_schema(schema_name, pg_username)
+ execute("CREATE SCHEMA \"#{schema_name}\" AUTHORIZATION \"#{pg_username}\"")
+ end
+
+ # Drops a schema
+ #
+ # Example:
+ # drop_schema('products')
+ def drop_schema(schema_name)
+ execute("DROP SCHEMA \"#{schema_name}\"")
+ end
+
+ # Returns an array of all schemas in the database
+ def all_schemas
+ query('SELECT schema_name FROM information_schema.schemata').flatten
+ end
# Returns the list of all tables in the schema search path or a specified schema.
def tables(name = nil)
- schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
query(<<-SQL, name).map { |row| row[0] }
SELECT tablename
FROM pg_tables
- WHERE schemaname IN (#{schemas})
+ WHERE schemaname = ANY (current_schemas(false))
SQL
end
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 5825482db7..d4cda927ad 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -374,7 +374,7 @@ module ActiveRecord
end
def load_migration
- load(filename)
+ require(File.expand_path(filename))
name.constantize
end
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index d8fae495e7..76ec7eb681 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -243,11 +243,14 @@ module ActiveRecord
# def pirate_attributes=(attributes)
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
# end
- class_eval %{
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ if method_defined?(:#{association_name}_attributes=)
+ remove_method(:#{association_name}_attributes=)
+ end
def #{association_name}_attributes=(attributes)
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
end
- }, __FILE__, __LINE__
+ eoruby
else
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 60addd46c6..de47461c73 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -10,7 +10,7 @@ require "action_controller/railtie"
module ActiveRecord
class Railtie < Rails::Railtie
- railtie_name :active_record
+ config.active_record = ActiveSupport::OrderedOptions.new
config.generators.orm :active_record, :migration => true,
:timestamps => true
@@ -19,9 +19,8 @@ module ActiveRecord
load "active_record/railties/databases.rake"
end
- # TODO If we require the wrong file, the error never comes up.
require "active_record/railties/log_subscriber"
- log_subscriber ActiveRecord::Railties::LogSubscriber.new
+ log_subscriber :active_record, ActiveRecord::Railties::LogSubscriber.new
initializer "active_record.initialize_timezone" do
ActiveRecord.base_hook do
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index fa6caa4910..06485b9033 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -85,8 +85,14 @@ namespace :db do
end
when 'postgresql'
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
+ schema_search_path = config['schema_search_path'] || 'public'
+ first_in_schema_search_path = schema_search_path.split(',').first.strip
begin
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
+ unless ActiveRecord::Base.connection.all_schemas.include?(first_in_schema_search_path)
+ ActiveRecord::Base.connection.create_schema(first_in_schema_search_path, config['username'])
+ $stderr.puts "Schema #{first_in_schema_search_path} has been created."
+ end
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
ActiveRecord::Base.establish_connection(config)
rescue
@@ -435,7 +441,7 @@ namespace :db do
task :create => :environment do
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
require 'rails/generators'
- require 'generators/rails/session_migration/session_migration_generator'
+ require 'rails/generators/rails/session_migration/session_migration_generator'
Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ]
end
diff --git a/activerecord/lib/active_record/railties/log_subscriber.rb b/activerecord/lib/active_record/railties/log_subscriber.rb
index 48b25032ce..31b98bb6ed 100644
--- a/activerecord/lib/active_record/railties/log_subscriber.rb
+++ b/activerecord/lib/active_record/railties/log_subscriber.rb
@@ -1,6 +1,11 @@
module ActiveRecord
module Railties
class LogSubscriber < Rails::LogSubscriber
+ def initialize
+ super
+ @odd_or_even = false
+ end
+
def sql(event)
name = '%s (%.1fms)' % [event.payload[:name], event.duration]
sql = event.payload[:sql].squeeze(' ')
@@ -24,4 +29,4 @@ module ActiveRecord
end
end
end
-end \ No newline at end of file
+end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 1a84f70a8e..a20c152eeb 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -15,13 +15,10 @@ module ActiveRecord
def initialize(klass, table)
@klass, @table = klass, table
- @readonly_value = nil
- @create_with_value = nil
@implicit_readonly = nil
- @limit_value = nil
- @offset_value = nil
@loaded = nil
+ SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
end
@@ -62,7 +59,7 @@ module ActiveRecord
preload = @preload_values
preload += @includes_values unless eager_loading?
- preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
+ preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
# @readonly_value is true only if set explicity. @implicit_readonly is true if there are JOINS and no explicit SELECT.
readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index d6d3d66642..c1cce679b6 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -175,7 +175,7 @@ module ActiveRecord
end
def construct_relation_for_association_find(join_dependency)
- relation = except(:includes, :eager_load, :preload, :select).select(@klass.send(:column_aliases, join_dependency))
+ relation = except(:includes, :eager_load, :preload, :select).select(column_aliases(join_dependency))
apply_join_dependency(relation, join_dependency)
end
@@ -184,7 +184,7 @@ module ActiveRecord
relation = association.join_relation(relation)
end
- limitable_reflections = @klass.send(:using_limitable_reflections?, join_dependency.reflections)
+ limitable_reflections = using_limitable_reflections?(join_dependency.reflections)
if !limitable_reflections && relation.limit_value
limited_id_condition = construct_limited_ids_condition(relation.except(:select))
@@ -311,5 +311,14 @@ module ActiveRecord
end
end
+ def column_aliases(join_dependency)
+ join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name|
+ "#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ")
+ end
+
+ def using_limitable_reflections?(reflections)
+ reflections.collect(&:collection?).length.zero?
+ end
+
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index e00d9cdf27..0250e739b8 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -6,6 +6,7 @@ module ActiveRecord
(ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
attr_accessor :"#{query_method}_values"
+ next if [:where, :having].include?(query_method)
class_eval <<-CEVAL
def #{query_method}(*args)
new_relation = clone
@@ -133,13 +134,8 @@ module ActiveRecord
arel = h.is_a?(String) ? arel.having(h) : arel.having(*h)
end
- if defined?(@limit_value) && @limit_value.present?
- arel = arel.take(@limit_value)
- end
-
- if defined?(@offset_value) && @offset_value.present?
- arel = arel.skip(@offset_value)
- end
+ arel = arel.take(@limit_value) if @limit_value.present?
+ arel = arel.skip(@offset_value) if @offset_value.present?
@group_values.uniq.each do |g|
arel = arel.group(g) if g.present?
@@ -162,19 +158,14 @@ module ActiveRecord
arel = arel.project(quoted_table_name + '.*')
end
- arel =
- if defined?(@from_value) && @from_value.present?
- arel.from(@from_value)
- else
- arel.from(quoted_table_name)
- end
+ arel = @from_value.present? ? arel.from(@from_value) : arel.from(quoted_table_name)
case @lock_value
when TrueClass
arel = arel.lock
when String
arel = arel.lock(@lock_value)
- end if defined?(@lock_value)
+ end if @lock_value.present?
arel
end
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index a18380f01c..2841ff1239 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -4,30 +4,14 @@ module ActiveRecord
merged_relation = clone
return merged_relation unless r
- merged_relation = merged_relation.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values)
-
- merged_relation.readonly_value = r.readonly_value unless r.readonly_value.nil?
- merged_relation.limit_value = r.limit_value if r.limit_value.present?
- merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
- merged_relation.offset_value = r.offset_value if r.offset_value.present?
-
- merged_relation = merged_relation.
- joins(r.joins_values).
- group(r.group_values).
- select(r.select_values).
- from(r.from_value).
- having(r.having_values)
-
- merged_relation.order_values = r.order_values if r.order_values.present?
-
- merged_relation.create_with_value = @create_with_value
-
- if @create_with_value && r.create_with_value
- merged_relation.create_with_value = @create_with_value.merge(r.create_with_value)
- else
- merged_relation.create_with_value = r.create_with_value || @create_with_value
+ (ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).reject {|m| [:joins, :where].include?(m)}.each do |method|
+ unless (value = r.send(:"#{method}_values")).blank?
+ merged_relation.send(:"#{method}_values=", value)
+ end
end
+ merged_relation = merged_relation.joins(r.joins_values)
+
merged_wheres = @where_values
r.where_values.each do |w|
@@ -40,6 +24,14 @@ module ActiveRecord
merged_relation.where_values = merged_wheres
+ ActiveRecord::Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
+ unless (value = r.send(:"#{method}_value")).nil?
+ merged_relation.send(:"#{method}_value=", value)
+ end
+ end
+
+ merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
+
merged_relation
end
diff --git a/activerecord/lib/generators/active_record.rb b/activerecord/lib/rails/generators/active_record.rb
index 1ca838b4f2..1ca838b4f2 100644
--- a/activerecord/lib/generators/active_record.rb
+++ b/activerecord/lib/rails/generators/active_record.rb
diff --git a/activerecord/lib/generators/active_record/migration/migration_generator.rb b/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
index 7939977f72..f6159deeeb 100644
--- a/activerecord/lib/generators/active_record/migration/migration_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
index bbb7c53d86..bbb7c53d86 100644
--- a/activerecord/lib/generators/active_record/migration/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
diff --git a/activerecord/lib/generators/active_record/model/model_generator.rb b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
index 2641083e0d..3e72fbeca8 100644
--- a/activerecord/lib/generators/active_record/model/model_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/model/templates/migration.rb b/activerecord/lib/rails/generators/active_record/model/templates/migration.rb
index 1f68487304..1f68487304 100644
--- a/activerecord/lib/generators/active_record/model/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/model/templates/migration.rb
diff --git a/activerecord/lib/generators/active_record/model/templates/model.rb b/activerecord/lib/rails/generators/active_record/model/templates/model.rb
index 21ae29e9f2..21ae29e9f2 100644
--- a/activerecord/lib/generators/active_record/model/templates/model.rb
+++ b/activerecord/lib/rails/generators/active_record/model/templates/model.rb
diff --git a/activerecord/lib/generators/active_record/observer/observer_generator.rb b/activerecord/lib/rails/generators/active_record/observer/observer_generator.rb
index a6b57423b8..c1c0e3f25b 100644
--- a/activerecord/lib/generators/active_record/observer/observer_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/observer/observer_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/observer/templates/observer.rb b/activerecord/lib/rails/generators/active_record/observer/templates/observer.rb
index b9a3004161..b9a3004161 100644
--- a/activerecord/lib/generators/active_record/observer/templates/observer.rb
+++ b/activerecord/lib/rails/generators/active_record/observer/templates/observer.rb
diff --git a/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb b/activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb
index 59c4792066..afcda2a98a 100644
--- a/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/session_migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb
index 919822af7b..919822af7b 100644
--- a/activerecord/lib/generators/active_record/session_migration/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb
diff --git a/activerecord/test/cases/active_schema_test_postgresql.rb b/activerecord/test/cases/active_schema_test_postgresql.rb
index af80f724f2..67c662d694 100644
--- a/activerecord/test/cases/active_schema_test_postgresql.rb
+++ b/activerecord/test/cases/active_schema_test_postgresql.rb
@@ -17,6 +17,13 @@ class PostgresqlActiveSchemaTest < Test::Unit::TestCase
assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
end
+ def test_create_schema
+ assert_equal %(CREATE SCHEMA "rizwan" AUTHORIZATION "postgres"), create_schema(:rizwan, :postgres)
+ end
+
+ def test_drop_schema
+ assert_equal %(DROP SCHEMA "rizwan"), drop_schema(:rizwan)
+ end
private
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index c59be264a4..9f78ae008c 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -81,6 +81,12 @@ class AdapterTest < ActiveRecord::TestCase
def test_encoding
assert_not_nil @connection.encoding
end
+
+ def test_all_schemas
+ @connection.create_schema(:test_schema, :postgres)
+ assert @connection.all_schemas.include?('test_schema')
+ @connection.drop_schema(:test_schema)
+ end
end
def test_table_alias
@@ -142,4 +148,25 @@ class AdapterTest < ActiveRecord::TestCase
end
end
end
+
+ def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas
+ sql_inject = "1 select * from schema"
+ assert_equal " LIMIT 1", @connection.add_limit_offset!("", :limit => sql_inject)
+ if current_adapter?(:MysqlAdapter)
+ assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
+ else
+ assert_equal " LIMIT 1 OFFSET 7", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
+ end
+ end
+
+ def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
+ sql_inject = "1, 7 procedure help()"
+ if current_adapter?(:MysqlAdapter)
+ assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit => sql_inject)
+ assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit => '1 ; DROP TABLE USERS', :offset => 7)
+ else
+ assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit => sql_inject)
+ assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
+ end
+ end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index ffa6d45948..42a891bc3b 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -805,7 +805,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_include_has_many_using_primary_key
- expected = Firm.find(1).clients_using_primary_key.sort_by &:name
+ expected = Firm.find(1).clients_using_primary_key.sort_by(&:name)
# Oracle adapter truncates alias to 30 characters
if current_adapter?(:OracleAdapter)
firm = Firm.find 1, :include => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies'[0,30]+'.name'
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index d47c8bba7d..ff799191c2 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -291,7 +291,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
], log.last(2)
post.people_with_callbacks = [people(:michael),people(:david), Person.new(:first_name => "Julian"), Person.create!(:first_name => "Roger")]
- assert_equal (%w(Ted Bob Sam Lary) * 2).sort, log[-12..-5].collect(&:last).sort
+ assert_equal((%w(Ted Bob Sam Lary) * 2).sort, log[-12..-5].collect(&:last).sort)
assert_equal [
[:added, :before, "Julian"],
[:added, :after, "Julian"],
@@ -300,7 +300,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
], log.last(4)
post.people_with_callbacks.clear
- assert_equal (%w(Michael David Julian Roger) * 2).sort, log.last(8).collect(&:last).sort
+ assert_equal((%w(Michael David Julian Roger) * 2).sort, log.last(8).collect(&:last).sort)
end
def test_dynamic_find_should_respect_association_include
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index d5dbb88886..7372f2da1b 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -186,15 +186,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal account, firm.account
end
- def test_failing_build_association
- firm = Firm.new("name" => "GlobalMegaCorp")
- firm.save
-
- account = firm.build_account
- assert !account.save
- assert_equal ["can't be empty"], account.errors["credit_limit"]
- end
-
def test_build_association_twice_without_saving_affects_nothing
count_of_account = Account.count
firm = Firm.find(:first)
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb
index 43abcae75e..4ba867dc7c 100644
--- a/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -15,12 +15,12 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase
def test_construct_finder_sql_ignores_empty_joins_hash
sql = Author.joins({}).to_sql
- assert_no_match /JOIN/i, sql
+ assert_no_match(/JOIN/i, sql)
end
def test_construct_finder_sql_ignores_empty_joins_array
sql = Author.joins([]).to_sql
- assert_no_match /JOIN/i, sql
+ assert_no_match(/JOIN/i, sql)
end
def test_find_with_implicit_inner_joins_honors_readonly_without_select
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index e9af5a60d8..8bdf8bcd55 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -52,18 +52,6 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
assert_equal 1, authors(:mary).unique_categorized_posts.find_all_by_title("So I was thinking").size
end
- def test_polymorphic_has_many
- assert posts(:welcome).taggings.include?(taggings(:welcome_general))
- end
-
- def test_polymorphic_has_one
- assert_equal taggings(:welcome_general), posts(:welcome).tagging
- end
-
- def test_polymorphic_belongs_to
- assert_equal posts(:welcome), posts(:welcome).taggings.first.taggable
- end
-
def test_polymorphic_has_many_going_through_join_model
assert_equal tags(:general), tag = posts(:welcome).tags.first
assert_no_queries do
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index e3047fe873..8774ed58aa 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -674,10 +674,10 @@ class BasicsTest < ActiveRecord::TestCase
def test_decrement_counter
Topic.decrement_counter("replies_count", 2)
- assert_equal -1, Topic.find(2).replies_count
+ assert_equal(-1, Topic.find(2).replies_count)
Topic.decrement_counter("replies_count", 2)
- assert_equal -2, Topic.find(2).replies_count
+ assert_equal(-2, Topic.find(2).replies_count)
end
def test_reset_counters
@@ -1533,7 +1533,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_auto_id
auto = AutoId.new
auto.save
- assert (auto.id > 0)
+ assert(auto.id > 0)
end
def quote_column_name(name)
@@ -2181,7 +2181,7 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_inspect_new_instance
- assert_match /Topic id: nil/, Topic.new.inspect
+ assert_match(/Topic id: nil/, Topic.new.inspect)
end
def test_inspect_limited_select_instance
@@ -2240,9 +2240,9 @@ class BasicsTest < ActiveRecord::TestCase
ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count }
ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count }
ActiveRecord::Base.benchmark("Error Topic Count", :level => :error) { Topic.count }
- assert_no_match /Debug Topic Count/, log.string
- assert_match /Warn Topic Count/, log.string
- assert_match /Error Topic Count/, log.string
+ assert_no_match(/Debug Topic Count/, log.string)
+ assert_match(/Warn Topic Count/, log.string)
+ assert_match(/Error Topic Count/, log.string)
ensure
ActiveRecord::Base.logger = original_logger
end
@@ -2253,8 +2253,8 @@ class BasicsTest < ActiveRecord::TestCase
ActiveRecord::Base.logger = Logger.new(log)
ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => true) { ActiveRecord::Base.logger.debug "Loud" }
ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" }
- assert_no_match /Loud/, log.string
- assert_match /Quiet/, log.string
+ assert_no_match(/Loud/, log.string)
+ assert_match(/Quiet/, log.string)
ensure
ActiveRecord::Base.logger = original_logger
end
diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb
index ff2322ac15..dc7f82b001 100644
--- a/activerecord/test/cases/callbacks_test.rb
+++ b/activerecord/test/cases/callbacks_test.rb
@@ -43,6 +43,11 @@ class CallbackDeveloper < ActiveRecord::Base
end
end
+class CallbackDeveloperWithFalseValidation < CallbackDeveloper
+ before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
+ before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
+end
+
class ParentDeveloper < ActiveRecord::Base
set_table_name 'developers'
attr_accessor :after_save_called
@@ -139,7 +144,7 @@ class CallbackCancellationDeveloper < ActiveRecord::Base
attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called
attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy
- before_save { !@cancel_before_save }
+ before_save {defined?(@cancel_before_save) ? !@cancel_before_save : false}
before_create { !@cancel_before_create }
before_update { !@cancel_before_update }
before_destroy { !@cancel_before_destroy }
@@ -437,10 +442,8 @@ class CallbacksTest < ActiveRecord::TestCase
end
private :assert_save_callbacks_not_called
- def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
- david = CallbackDeveloper.find(1)
- CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
- CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
+ def test_callback_returning_false
+ david = CallbackDeveloperWithFalseValidation.find(1)
david.save
assert_equal [
[ :after_find, :method ],
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index b4032c23e6..bba216ae19 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -24,7 +24,7 @@ class DefaultTest < ActiveRecord::TestCase
assert_instance_of Fixnum, default.positive_integer
assert_equal 1, default.positive_integer
assert_instance_of Fixnum, default.negative_integer
- assert_equal -1, default.negative_integer
+ assert_equal(-1, default.negative_integer)
assert_instance_of BigDecimal, default.decimal_number
assert_equal BigDecimal.new("2.78"), default.decimal_number
end
@@ -33,7 +33,7 @@ class DefaultTest < ActiveRecord::TestCase
if current_adapter?(:PostgreSQLAdapter)
def test_multiline_default_text
# older postgres versions represent the default with escapes ("\\012" for a newline)
- assert ( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
+ assert( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
"--- []\\012\\012" == Default.columns_hash['multiline_default'].default)
end
end
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 4961d12a44..a64ccb2120 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -26,6 +26,11 @@ class NumericData < ActiveRecord::Base
end
class DirtyTest < ActiveRecord::TestCase
+ # Dummy to force column loads so query counts are clean.
+ def setup
+ Person.create :first_name => 'foo'
+ end
+
def test_attribute_changes
# New record - no changes.
pirate = Pirate.new
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index d2451f24c1..9e88ec8016 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -502,6 +502,18 @@ class FinderTest < ActiveRecord::TestCase
assert_kind_of Time, Topic.find(:first, :conditions => ["id = :id", { :id => 1 }]).written_on
end
+ class SimpleEnumerable
+ include Enumerable
+
+ def initialize(ary)
+ @ary = ary
+ end
+
+ def each(&b)
+ @ary.each(&b)
+ end
+ end
+
def test_bind_enumerable
quoted_abc = %(#{ActiveRecord::Base.connection.quote('a')},#{ActiveRecord::Base.connection.quote('b')},#{ActiveRecord::Base.connection.quote('c')})
@@ -511,12 +523,11 @@ class FinderTest < ActiveRecord::TestCase
assert_equal '1,2,3', bind(':a', :a => [1, 2, 3])
assert_equal quoted_abc, bind(':a', :a => %w(a b c)) # '
- require 'set'
- assert_equal '1,2,3', bind('?', Set.new([1, 2, 3]))
- assert_equal quoted_abc, bind('?', Set.new(%w(a b c)))
+ assert_equal '1,2,3', bind('?', SimpleEnumerable.new([1, 2, 3]))
+ assert_equal quoted_abc, bind('?', SimpleEnumerable.new(%w(a b c)))
- assert_equal '1,2,3', bind(':a', :a => Set.new([1, 2, 3]))
- assert_equal quoted_abc, bind(':a', :a => Set.new(%w(a b c))) # '
+ assert_equal '1,2,3', bind(':a', :a => SimpleEnumerable.new([1, 2, 3]))
+ assert_equal quoted_abc, bind(':a', :a => SimpleEnumerable.new(%w(a b c))) # '
end
def test_bind_empty_enumerable
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index f965652a9a..e78b522b65 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -244,14 +244,14 @@ class FixturesWithoutInstantiationTest < ActiveRecord::TestCase
fixtures :topics, :developers, :accounts
def test_without_complete_instantiation
- assert_nil @first
- assert_nil @topics
- assert_nil @developers
- assert_nil @accounts
+ assert !defined?(@first)
+ assert !defined?(@topics)
+ assert !defined?(@developers)
+ assert !defined?(@accounts)
end
def test_fixtures_from_root_yml_without_instantiation
- assert_nil @unknown
+ assert !defined?(@unknown), "@unknown is not defined"
end
def test_accessor_methods
@@ -279,7 +279,7 @@ class FixturesWithoutInstanceInstantiationTest < ActiveRecord::TestCase
fixtures :topics, :developers, :accounts
def test_without_instance_instantiation
- assert_nil @first
+ assert !defined?(@first), "@first is not defined"
assert_not_nil @topics
assert_not_nil @developers
assert_not_nil @accounts
diff --git a/activerecord/test/cases/json_serialization_test.rb b/activerecord/test/cases/json_serialization_test.rb
index 54bc8e2343..a3145d2c04 100644
--- a/activerecord/test/cases/json_serialization_test.rb
+++ b/activerecord/test/cases/json_serialization_test.rb
@@ -27,6 +27,8 @@ class JsonSerializationTest < ActiveRecord::TestCase
@contact = NamespacedContact.new :name => 'whatever'
json = @contact.to_json
assert_match %r{^\{"namespaced_contact":\{}, json
+ ensure
+ NamespacedContact.include_root_in_json = false
end
def test_should_include_root_in_json
diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb
index aa7ce2ecb6..fcad3e90d3 100644
--- a/activerecord/test/cases/lifecycle_test.rb
+++ b/activerecord/test/cases/lifecycle_test.rb
@@ -6,25 +6,6 @@ require 'models/minimalistic'
class SpecialDeveloper < Developer; end
-class TopicManualObserver
- include Singleton
-
- attr_reader :action, :object, :callbacks
-
- def initialize
- Topic.add_observer(self)
- @callbacks = []
- end
-
- def update(callback_method, object)
- @callbacks << { "callback_method" => callback_method, "object" => object }
- end
-
- def has_been_notified?
- !@callbacks.empty?
- end
-end
-
class TopicaAuditor < ActiveRecord::Observer
observe :topic
@@ -85,27 +66,6 @@ class LifecycleTest < ActiveRecord::TestCase
assert_equal original_count - (1 + topic_to_be_destroyed.replies.size), Topic.count
end
- def test_after_save
- ActiveRecord::Base.observers = :topic_manual_observer
- ActiveRecord::Base.instantiate_observers
-
- topic = Topic.find(1)
- topic.title = "hello"
- topic.save
-
- assert TopicManualObserver.instance.has_been_notified?
- assert_equal :after_save, TopicManualObserver.instance.callbacks.last["callback_method"]
- end
-
- def test_observer_update_on_save
- ActiveRecord::Base.observers = TopicManualObserver
- ActiveRecord::Base.instantiate_observers
-
- topic = Topic.find(1)
- assert TopicManualObserver.instance.has_been_notified?
- assert_equal :after_find, TopicManualObserver.instance.callbacks.first["callback_method"]
- end
-
def test_auto_observer
topic_observer = TopicaAuditor.instance
assert_nil TopicaAuditor.observed_class
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index f3b94eb829..6ba84fa57b 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -26,8 +26,8 @@ class LogSubscriberTest < ActiveSupport::TestCase
Developer.all
wait
assert_equal 1, @logger.logged(:debug).size
- assert_match /Developer Load/, @logger.logged(:debug).last
- assert_match /SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last
+ assert_match(/Developer Load/, @logger.logged(:debug).last)
+ assert_match(/SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last)
end
def test_cached_queries
@@ -37,7 +37,7 @@ class LogSubscriberTest < ActiveSupport::TestCase
end
wait
assert_equal 2, @logger.logged(:debug).size
- assert_match /CACHE/, @logger.logged(:debug).last
- assert_match /SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last
+ assert_match(/CACHE/, @logger.logged(:debug).last)
+ assert_match(/SELECT .*?FROM .?developers.?/, @logger.logged(:debug).last)
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index 3151457440..a3b496a0e6 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -382,7 +382,7 @@ class NestedScopingTest < ActiveRecord::TestCase
Developer.send(:with_scope, :find => { :conditions => "salary < 100000" }) do
Developer.send(:with_scope, :find => { :offset => 1, :order => 'id asc' }) do
# Oracle adapter does not generated space after asc therefore trailing space removed from regex
- assert_sql /ORDER BY id asc/ do
+ assert_sql(/ORDER BY id asc/) do
assert_equal(poor_jamis, Developer.find(:first, :order => 'id asc'))
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index dd32eeeff2..e213986ede 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -477,7 +477,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_not_equal "Z", bob.moment_of_truth.zone
# US/Eastern is -5 hours from GMT
assert_equal Rational(-5, 24), bob.moment_of_truth.offset
- assert_match /\A-05:?00\Z/, bob.moment_of_truth.zone #ruby 1.8.6 uses HH:MM, prior versions use HHMM
+ assert_match(/\A-05:?00\Z/, bob.moment_of_truth.zone) #ruby 1.8.6 uses HH:MM, prior versions use HHMM
assert_equal DateTime::ITALY, bob.moment_of_truth.start
end
end
@@ -493,7 +493,7 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint
Person.reset_column_information
- assert_match /tinyint/, Person.columns_hash['intelligence_quotient'].sql_type
+ assert_match(/tinyint/, Person.columns_hash['intelligence_quotient'].sql_type)
ensure
ActiveRecord::Migration.remove_column :people, :intelligence_quotient rescue nil
end
@@ -1104,13 +1104,25 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal migrations[0].name, 'InnocentJointable'
end
+ def test_relative_migrations
+ $".delete_if do |fname|
+ fname == (MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
+ end
+ Object.send(:remove_const, :PeopleHaveLastNames)
+
+ Dir.chdir(MIGRATIONS_ROOT) do
+ ActiveRecord::Migrator.up("valid/", 1)
+ end
+
+ assert defined?(PeopleHaveLastNames)
+ end
+
def test_only_loads_pending_migrations
# migrate up to 1
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
# now unload the migrations that have been defined
- PeopleHaveLastNames.unloadable
- ActiveSupport::Dependencies.remove_unloadable_constants!
+ Object.send(:remove_const, :PeopleHaveLastNames)
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 894d96346e..6c2b4fa3a7 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -83,8 +83,8 @@ class NamedScopeTest < ActiveRecord::TestCase
end
def test_scopes_are_composable
- assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
- assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
+ assert_equal((approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved)
+ assert_equal((replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied)
assert !(approved == replied)
assert !(approved & replied).empty?
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 3710f8e40b..91349689bc 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -10,6 +10,10 @@ require 'models/post'
class QueryCacheTest < ActiveRecord::TestCase
fixtures :tasks, :topics, :categories, :posts, :categories_posts
+ def setup
+ Task.connection.clear_query_cache
+ end
+
def test_find_queries
assert_queries(2) { Task.find(1); Task.find(1) }
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 2c9158aa7b..67818622d7 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -22,12 +22,6 @@ class ReflectionTest < ActiveRecord::TestCase
assert_equal "Subscriber", Subscriber.model_name.human
end
- def test_column_null_not_null
- subscriber = Subscriber.find(:first)
- assert subscriber.column_for_attribute("name").null
- assert !subscriber.column_for_attribute("nick").null
- end
-
def test_read_attribute_names
assert_equal(
%w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id parent_title type ).sort,
diff --git a/activerecord/test/cases/schema_authorization_test_postgresql.rb b/activerecord/test/cases/schema_authorization_test_postgresql.rb
index ba7754513d..2860f1ad48 100644
--- a/activerecord/test/cases/schema_authorization_test_postgresql.rb
+++ b/activerecord/test/cases/schema_authorization_test_postgresql.rb
@@ -66,6 +66,15 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
end
end
end
+
+ def test_tables_in_current_schemas
+ assert !@connection.tables.include?(TABLE_NAME)
+ USERS.each do |u|
+ set_session_auth u
+ assert @connection.tables.include?(TABLE_NAME)
+ set_session_auth
+ end
+ end
private
def set_session_auth auth = nil
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index aca70b4238..c550030329 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -51,6 +51,7 @@ class TransactionTest < ActiveRecord::TestCase
assert !Topic.find(2).approved?, "Second should have been unapproved"
ensure
class << Topic.connection
+ remove_method :commit_db_transaction
alias :commit_db_transaction :real_commit_db_transaction rescue nil
end
end
@@ -382,28 +383,53 @@ class TransactionTest < ActiveRecord::TestCase
private
def add_exception_raising_after_save_callback_to_topic
- Topic.class_eval "def after_save_for_transaction; raise 'Make the transaction rollback' end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method(:after_save_for_transaction)
+ def after_save_for_transaction
+ raise 'Make the transaction rollback'
+ end
+ eoruby
end
def remove_exception_raising_after_save_callback_to_topic
- Topic.class_eval "def after_save_for_transaction; end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method :after_save_for_transaction
+ def after_save_for_transaction; end
+ eoruby
end
def add_exception_raising_after_create_callback_to_topic
- Topic.class_eval "def after_create_for_transaction; raise 'Make the transaction rollback' end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method(:after_create_for_transaction)
+ def after_create_for_transaction
+ raise 'Make the transaction rollback'
+ end
+ eoruby
end
def remove_exception_raising_after_create_callback_to_topic
- Topic.class_eval "def after_create_for_transaction; end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method :after_create_for_transaction
+ def after_create_for_transaction; end
+ eoruby
end
%w(validation save destroy).each do |filter|
define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
- Topic.class_eval "def before_#{filter}_for_transaction() Book.create; false end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method :before_#{filter}_for_transaction
+ def before_#{filter}_for_transaction
+ Book.create
+ false
+ end
+ eoruby
end
define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
- Topic.class_eval "def before_#{filter}_for_transaction; end"
+ Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ remove_method :before_#{filter}_for_transaction
+ def before_#{filter}_for_transaction; end
+ eoruby
end
end
end
diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb
index a0ff35f948..38fa2b821d 100644
--- a/activerecord/test/cases/validations/i18n_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_validation_test.rb
@@ -47,25 +47,6 @@ class I18nValidationTest < ActiveRecord::TestCase
@topic.valid?
end
- # validates_uniqueness_of w/o mocha
-
- def test_validates_associated_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:taken => 'custom message'}}}}}}
- I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:taken => 'global message'}}}
-
- Topic.validates_uniqueness_of :title
- unique_topic.valid?
- assert_equal ['custom message'], unique_topic.errors[:replies]
- end
-
- def test_validates_associated_finds_global_default_translation
- I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:taken => 'global message'}}}
-
- Topic.validates_uniqueness_of :title
- unique_topic.valid?
- assert_equal ['global message'], unique_topic.errors[:replies]
- end
-
# validates_associated w/ mocha
def test_validates_associated_generates_message
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index b841108bd1..67296a171a 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -625,6 +625,22 @@ module ActiveResource
"#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}"
end
+ # Gets the new element path for REST resources.
+ #
+ # ==== Options
+ # * +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., <tt>:account_id => 19</tt>
+ # would yield a URL like <tt>/accounts/19/purchases/new.xml</tt>).
+ #
+ # ==== Examples
+ # Post.new_element_path
+ # # => /posts/new.xml
+ #
+ # Comment.collection_path(:post_id => 5)
+ # # => /posts/5/comments/new.xml
+ def new_element_path(prefix_options = {})
+ "#{prefix(prefix_options)}#{collection_name}/new.#{format.extension}"
+ end
+
# Gets the collection path for the REST resources. If the +query_options+ parameter is omitted, Rails
# will split from the +prefix_options+.
#
@@ -653,6 +669,19 @@ module ActiveResource
alias_method :set_primary_key, :primary_key= #:nodoc:
+ # Builds a new, unsaved record using the default values from the remote server so
+ # that it can be used with RESTful forms.
+ #
+ # ==== Options
+ # * +attributes+ - A hash that overrides the default values from the server.
+ #
+ # Returns the new resource instance.
+ #
+ def build(attributes = {})
+ attrs = connection.get("#{new_element_path}").merge(attributes)
+ self.new(attrs)
+ end
+
# Creates a new resource instance and makes a request to the remote service
# that it be saved, making it equivalent to the following simultaneous calls:
#
@@ -989,6 +1018,22 @@ module ActiveResource
end
alias :new_record? :new?
+ # Returns +true+ if this object has been saved, otherwise returns +false+.
+ #
+ # ==== Examples
+ # persisted = Computer.create(:brand => 'Apple', :make => 'MacBook', :vendor => 'MacMall')
+ # persisted.persisted? # => true
+ #
+ # not_persisted = Computer.new(:brand => 'IBM', :make => 'Thinkpad', :vendor => 'IBM')
+ # not_persisted.persisted? # => false
+ #
+ # not_persisted.save
+ # not_persisted.persisted? # => true
+ #
+ def persisted?
+ !new?
+ end
+
# Gets the <tt>\id</tt> attribute of the resource.
def id
attributes[self.class.primary_key]
@@ -1346,6 +1391,10 @@ module ActiveResource
self.class.element_path(to_param, options || prefix_options)
end
+ def new_element_path
+ self.class.new_element_path(prefix_options)
+ end
+
def collection_path(options = nil)
self.class.collection_path(options || prefix_options)
end
diff --git a/activeresource/lib/active_resource/railtie.rb b/activeresource/lib/active_resource/railtie.rb
index 27c88415f6..aa878c7212 100644
--- a/activeresource/lib/active_resource/railtie.rb
+++ b/activeresource/lib/active_resource/railtie.rb
@@ -3,10 +3,10 @@ require "rails"
module ActiveResource
class Railtie < Rails::Railtie
- railtie_name :active_resource
+ config.active_resource = ActiveSupport::OrderedOptions.new
require "active_resource/railties/log_subscriber"
- log_subscriber ActiveResource::Railties::LogSubscriber.new
+ log_subscriber :active_resource, ActiveResource::Railties::LogSubscriber.new
initializer "active_resource.set_configs" do |app|
app.config.active_resource.each do |k,v|
diff --git a/activeresource/test/setter_trap.rb b/activeresource/test/setter_trap.rb
index 7cfd9ca111..437fbdad32 100644
--- a/activeresource/test/setter_trap.rb
+++ b/activeresource/test/setter_trap.rb
@@ -1,3 +1,5 @@
+require 'abstract_unit'
+
class SetterTrap < ActiveSupport::BasicObject
class << self
def rollback_sets(obj)
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index 78fb48924e..bfb1e83002 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
s.has_rdoc = true
- s.add_dependency('i18n', '~> 0.3.6.pre')
+ s.add_dependency('i18n', '~> 0.3.6')
s.add_dependency('tzinfo', '~> 0.3.16')
s.add_dependency('builder', '~> 2.1.2')
- s.add_dependency('memcache-client', '~> 1.7.5')
+ s.add_dependency('memcache-client', '>= 1.7.5')
end
diff --git a/activesupport/lib/active_support/core_ext/array/extract_options.rb b/activesupport/lib/active_support/core_ext/array/extract_options.rb
index 9ca32dc7aa..40ceb3eb9e 100644
--- a/activesupport/lib/active_support/core_ext/array/extract_options.rb
+++ b/activesupport/lib/active_support/core_ext/array/extract_options.rb
@@ -1,3 +1,14 @@
+class Hash
+ # By default, only instances of Hash itself are extractable.
+ # Subclasses of Hash may implement this method and return
+ # true to declare themselves as extractable. If a Hash
+ # is extractable, Array#extract_options! pops it from
+ # the Array when it is the last element of the Array.
+ def extractable_options?
+ instance_of?(Hash)
+ end
+end
+
class Array
# Extracts options from a set of arguments. Removes and returns the last
# element in the array if it's a hash, otherwise returns a blank hash.
@@ -9,6 +20,10 @@ class Array
# options(1, 2) # => {}
# options(1, 2, :a => :b) # => {:a=>:b}
def extract_options!
- last.is_a?(::Hash) ? pop : {}
+ if last.is_a?(Hash) && last.extractable_options?
+ pop
+ else
+ {}
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index c18905b369..9631a7d242 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/object/singleton_class'
require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/module/remove_method'
class Class
# Declare a class-level attribute whose value is inheritable and
@@ -45,12 +46,14 @@ class Class
s.send(:define_method, attr) { }
s.send(:define_method, :"#{attr}?") { !!send(attr) }
s.send(:define_method, :"#{attr}=") do |value|
+ singleton_class.remove_possible_method(attr)
singleton_class.send(:define_method, attr) { value }
end
define_method(attr) { self.class.send(attr) }
define_method(:"#{attr}?") { !!send(attr) }
define_method(:"#{attr}=") do |value|
+ singleton_class.remove_possible_method(attr)
singleton_class.send(:define_method, attr) { value }
end if instance_writer
end
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index 1602a609eb..feef5d2d57 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -10,42 +10,48 @@ require 'active_support/core_ext/array/extract_options'
# Person.hair_colors = [:brown, :black, :blonde, :red]
class Class
def cattr_reader(*syms)
- syms.flatten.each do |sym|
- next if sym.is_a?(Hash)
+ options = syms.extract_options!
+ syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym} # unless defined? @@hair_colors
- @@#{sym} = nil # @@hair_colors = nil
- end # end
- #
- def self.#{sym} # def self.hair_colors
- @@#{sym} # @@hair_colors
- end # end
- #
- def #{sym} # def hair_colors
- @@#{sym} # @@hair_colors
- end # end
+ unless defined? @@#{sym}
+ @@#{sym} = nil
+ end
+
+ def self.#{sym}
+ @@#{sym}
+ end
EOS
+
+ unless options[:instance_reader] == false
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{sym}
+ @@#{sym}
+ end
+ EOS
+ end
end
end
def cattr_writer(*syms)
options = syms.extract_options!
- syms.flatten.each do |sym|
+ syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym} # unless defined? @@hair_colors
- @@#{sym} = nil # @@hair_colors = nil
- end # end
- #
- def self.#{sym}=(obj) # def self.hair_colors=(obj)
- @@#{sym} = obj # @@hair_colors = obj
- end # end
- #
- #{" #
- def #{sym}=(obj) # def hair_colors=(obj)
- @@#{sym} = obj # @@hair_colors = obj
- end # end
- " unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false
+ unless defined? @@#{sym}
+ @@#{sym} = nil
+ end
+
+ def self.#{sym}=(obj)
+ @@#{sym} = obj
+ end
EOS
+
+ unless options[:instance_writer] == false
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{sym}=(obj)
+ @@#{sym} = obj
+ end
+ EOS
+ end
self.send("#{sym}=", yield) if block_given?
end
end
diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
index b5785bdcd3..12caa76c98 100644
--- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/object/singleton_class'
+require 'active_support/core_ext/module/remove_method'
class Class
def superclass_delegating_accessor(name, options = {})
@@ -27,7 +28,9 @@ private
# inheritance behavior, without having to store the object in an instance
# variable and look up the superclass chain manually.
def _stash_object_in_method(object, method, instance_reader = true)
+ singleton_class.remove_possible_method(method)
singleton_class.send(:define_method, method) { object }
+ remove_possible_method(method)
define_method(method) { object } if instance_reader
end
@@ -35,7 +38,7 @@ private
singleton_class.send(:define_method, "#{name}=") do |value|
_stash_object_in_method(value, name, options[:instance_reader] != false)
end
- self.send("#{name}=", nil)
+ send("#{name}=", nil)
end
end
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index 47a31839a6..a9f821b01e 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -1,4 +1,5 @@
require 'active_support/inflector'
+require 'active_support/core_ext/time/conversions'
class DateTime
# Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 48b185d05e..c882434f78 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -54,6 +54,15 @@ class Hash
"string" => Proc.new { |string| string.to_s },
"yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
"base64Binary" => Proc.new { |bin| ActiveSupport::Base64.decode64(bin) },
+ "binary" => Proc.new do |bin, entity|
+ case entity['encoding']
+ when 'base64'
+ ActiveSupport::Base64.decode64(bin)
+ # TODO: Add support for other encodings
+ else
+ bin
+ end
+ end,
"file" => Proc.new do |file, entity|
f = StringIO.new(ActiveSupport::Base64.decode64(file))
f.extend(FileLike)
diff --git a/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
index d9b84e6543..ac35db6ab6 100644
--- a/activesupport/lib/active_support/core_ext/kernel/reporting.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
@@ -37,7 +37,7 @@ module Kernel
# puts 'But this will'
def silence_stream(stream)
old_stream = stream.dup
- stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
+ stream.reopen(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
stream.sync = true
yield
ensure
diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb
index bf272e9e73..f59fcd123c 100644
--- a/activesupport/lib/active_support/core_ext/module.rb
+++ b/activesupport/lib/active_support/core_ext/module.rb
@@ -7,4 +7,6 @@ require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/attr_accessor_with_default'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/synchronization'
-require 'active_support/core_ext/module/deprecation' \ No newline at end of file
+require 'active_support/core_ext/module/deprecation'
+require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/module/method_names' \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 131b512944..9c4d5fae26 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -2,21 +2,25 @@ require 'active_support/core_ext/array/extract_options'
class Module
def mattr_reader(*syms)
- syms.extract_options!
+ options = syms.extract_options!
syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym} # unless defined? @@pagination_options
- @@#{sym} = nil # @@pagination_options = nil
- end # end
-
- def self.#{sym} # def self.pagination_options
- @@#{sym} # @@pagination_options
- end # end
+ unless defined? @@#{sym}
+ @@#{sym} = nil
+ end
- def #{sym} # def pagination_options
- @@#{sym} # @@pagination_options
- end # end
+ def self.#{sym}
+ @@#{sym}
+ end
EOS
+
+ unless options[:instance_reader] == false
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{sym}
+ @@#{sym}
+ end
+ EOS
+ end
end
end
@@ -24,20 +28,20 @@ class Module
options = syms.extract_options!
syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym} # unless defined? @@pagination_options
- @@#{sym} = nil # @@pagination_options = nil
- end # end
+ unless defined? @@#{sym}
+ @@#{sym} = nil
+ end
- def self.#{sym}=(obj) # def self.pagination_options=(obj)
- @@#{sym} = obj # @@pagination_options = obj
- end # end
+ def self.#{sym}=(obj)
+ @@#{sym} = obj
+ end
EOS
unless options[:instance_writer] == false
- class_eval(<<-EOS, __FILE__, __LINE__)
- def #{sym}=(obj) # def pagination_options=(obj)
- @@#{sym} = obj # @@pagination_options = obj
- end # end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{sym}=(obj)
+ @@#{sym} = obj
+ end
EOS
end
end
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 381181b2f4..b73f4c2b59 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/module/remove_method"
+
class Module
# Provides a delegate class method to easily expose contained objects' methods
# as your own. Pass one or more methods (specified as symbols or strings)
@@ -39,7 +41,7 @@ class Module
# class Foo
# CONSTANT_ARRAY = [0,1,2,3]
# @@class_array = [4,5,6,7]
- #
+ #
# def initialize
# @instance_array = [8,9,10,11]
# end
@@ -125,6 +127,10 @@ class Module
end
module_eval(<<-EOS, file, line)
+ if instance_methods(false).map(&:to_s).include?("#{prefix}#{method}")
+ remove_possible_method("#{prefix}#{method}")
+ end
+
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
#{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
rescue NoMethodError # rescue NoMethodError
diff --git a/activesupport/lib/active_support/core_ext/module/method_names.rb b/activesupport/lib/active_support/core_ext/module/method_names.rb
new file mode 100644
index 0000000000..2eb40a83ab
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/module/method_names.rb
@@ -0,0 +1,14 @@
+class Module
+ if instance_methods[0].is_a?(Symbol)
+ def instance_method_names(*args)
+ instance_methods(*args).map(&:to_s)
+ end
+
+ def method_names(*args)
+ methods(*args).map(&:to_s)
+ end
+ else
+ alias_method :instance_method_names, :instance_methods
+ alias_method :method_names, :methods
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/module/remove_method.rb b/activesupport/lib/active_support/core_ext/module/remove_method.rb
new file mode 100644
index 0000000000..2714a46b28
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/module/remove_method.rb
@@ -0,0 +1,6 @@
+class Module
+ def remove_possible_method(method)
+ remove_method(method)
+ rescue NameError
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb
index fbb7b79fc6..48b028bb64 100644
--- a/activesupport/lib/active_support/core_ext/string/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -1,5 +1,3 @@
-require 'active_support/inflector'
-
# String inflections define new methods on the String class to transform names for different purposes.
# For instance, you can figure out the name of a database from the name of a class.
#
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index 9a7c520e75..3ee5bcaab4 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -1,4 +1,5 @@
-require "erb"
+require 'erb'
+require 'active_support/core_ext/object/singleton_class'
class ERB
module Util
@@ -23,12 +24,14 @@ class ERB
end
end
- undef :h
+ remove_method(:h)
alias h html_escape
- module_function :html_escape
module_function :h
+ singleton_class.send(:remove_method, :html_escape)
+ module_function :html_escape
+
# A utility method for escaping HTML entities in JSON strings.
# This method is also aliased as <tt>j</tt>.
#
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index 6d9c080442..86103ebce2 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -1,4 +1,5 @@
require 'active_support/inflector'
+require 'active_support/core_ext/time/publicize_conversion_methods'
require 'active_support/values/time_zone'
class Time
diff --git a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb b/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
index 9de8157eb0..8d46d80251 100644
--- a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
+++ b/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
@@ -7,14 +7,18 @@ if RUBY_VERSION < '1.9'
alias_method :_original_load, :_load
def _load(marshaled_time)
time = _original_load(marshaled_time)
- utc = time.instance_variable_get('@marshal_with_utc_coercion')
- utc ? time.utc : time
+ time.instance_eval do
+ if defined?(@marshal_with_utc_coercion)
+ val = remove_instance_variable("@marshal_with_utc_coercion")
+ end
+ val ? utc : self
+ end
end
end
alias_method :_original_dump, :_dump
def _dump(*args)
- obj = frozen? ? dup : self
+ obj = dup
obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
obj._original_dump(*args)
end
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 543dab4a75..8241b69c8b 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -4,6 +4,10 @@
module ActiveSupport
class HashWithIndifferentAccess < Hash
+ def extractable_options?
+ true
+ end
+
def initialize(constructor = {})
if constructor.is_a?(Hash)
super()
diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb
index 236f2eb628..2ce27cf406 100644
--- a/activesupport/lib/active_support/inflector/transliterate.rb
+++ b/activesupport/lib/active_support/inflector/transliterate.rb
@@ -14,8 +14,8 @@ module ActiveSupport
if RUBY_VERSION >= '1.9'
undef_method :transliterate
def transliterate(string)
- warn "Ruby 1.9 doesn't support Unicode normalization yet"
- string.dup
+ proxy = ActiveSupport::Multibyte.proxy_class.new(string)
+ proxy.normalize(:kd).gsub(/[^\x00-\x7F]+/, '')
end
# The iconv transliteration code doesn't function correctly
diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb
index 7e6f7d754b..428c48a484 100644
--- a/activesupport/lib/active_support/multibyte.rb
+++ b/activesupport/lib/active_support/multibyte.rb
@@ -53,8 +53,8 @@ module ActiveSupport #:nodoc:
\xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf])\z /xn,
# Quick check for valid Shift-JIS characters, disregards the odd-even pairing
'Shift_JIS' => /\A(?:
- [\x00-\x7e \xa1-\xdf] |
- [\x81-\x9f \xe0-\xef] [\x40-\x7e \x80-\x9e \x9f-\xfc])\z /xn
+ [\x00-\x7e\xa1-\xdf] |
+ [\x81-\x9f\xe0-\xef] [\x40-\x7e\x80-\x9e\x9f-\xfc])\z /xn
}
end
end
diff --git a/activesupport/lib/active_support/multibyte/utils.rb b/activesupport/lib/active_support/multibyte/utils.rb
index b243df46d8..94b393cee2 100644
--- a/activesupport/lib/active_support/multibyte/utils.rb
+++ b/activesupport/lib/active_support/multibyte/utils.rb
@@ -27,7 +27,7 @@ module ActiveSupport #:nodoc:
def self.verify(string)
if expression = valid_character
# Splits the string on character boundaries, which are determined based on $KCODE.
- string.split(//).all? { |c| expression.match(c) }
+ string.split(//).all? { |c| expression =~ c }
else
true
end
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index cd60054862..a3ddc7705a 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -44,7 +44,7 @@ module ActiveSupport
when Regexp, NilClass
pattern
else
- /^#{Regexp.escape(pattern.to_s)}/
+ /^#{Regexp.escape(pattern.to_s)}$/
end
end
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index d2c13e030d..e45d16ee96 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -3,7 +3,7 @@ require "rails"
module ActiveSupport
class Railtie < Rails::Railtie
- railtie_name :active_support
+ config.active_support = ActiveSupport::OrderedOptions.new
# Loads support for "whiny nil" (noisy warnings when methods are invoked
# on +nil+ values) if Configuration#whiny_nils is true.
@@ -30,9 +30,7 @@ end
module I18n
class Railtie < Rails::Railtie
- railtie_name :i18n
-
- # Initialize I18n load paths to an array
+ config.i18n = ActiveSupport::OrderedOptions.new
config.i18n.railties_load_path = []
config.i18n.load_path = []
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index f0db5b3021..4a9ac920e8 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -18,3 +18,4 @@ require 'active_support/core_ext/string/interpolation'
require 'active_support/core_ext/rexml'
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/file/path'
+require 'active_support/core_ext/module/method_names' \ No newline at end of file
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index ab30984d62..ed8c02ba3e 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -5,9 +5,10 @@ require 'active_support/testing/deprecation'
require 'active_support/testing/declarative'
require 'active_support/testing/pending'
require 'active_support/testing/isolation'
+require 'active_support/core_ext/kernel/reporting'
begin
- require 'mocha'
+ silence_warnings { require 'mocha' }
rescue LoadError
# Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
Object.const_set :Mocha, Module.new
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index 453f4fcc0f..9507dbf473 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -78,8 +78,8 @@ module ActiveSupport
@@ran_class_setup = true
end
- serialized = run_in_isolation do |runner|
- super(runner)
+ serialized = run_in_isolation do |isolated_runner|
+ super(isolated_runner)
end
retval, proxy = Marshal.load(serialized)
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 4db3dd1705..3cb4d89e02 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -305,8 +305,8 @@ module ActiveSupport
# TODO: Preload instead of lazy load for thread safety
def tzinfo
- require 'tzinfo' unless defined?(TZInfo)
- @tzinfo ||= TZInfo::Timezone.get(MAPPING[name])
+ require 'tzinfo' unless defined?(::TZInfo)
+ @tzinfo ||= ::TZInfo::Timezone.get(MAPPING[name])
end
unless const_defined?(:ZONES)
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index da338a2a26..67f652325e 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -1,10 +1,17 @@
-require File.expand_path('../../../load_paths', __FILE__)
+begin
+ old, $VERBOSE = $VERBOSE, nil
+ require File.expand_path('../../../load_paths', __FILE__)
+ensure
+ $VERBOSE = old
+end
lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
require 'test/unit'
-require 'mocha'
+require 'active_support/core_ext/kernel/reporting'
+
+silence_warnings { require 'mocha' }
ENV['NO_RELOAD'] = '1'
require 'active_support'
diff --git a/activesupport/test/callback_inheritance_test.rb b/activesupport/test/callback_inheritance_test.rb
index e74c64ba8d..8caf000c5d 100644
--- a/activesupport/test/callback_inheritance_test.rb
+++ b/activesupport/test/callback_inheritance_test.rb
@@ -1,3 +1,4 @@
+require 'abstract_unit'
require 'test/unit'
require 'active_support'
diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb
index 3fb940ad3c..49d9de63b0 100644
--- a/activesupport/test/callbacks_test.rb
+++ b/activesupport/test/callbacks_test.rb
@@ -1,4 +1,4 @@
-# require 'abstract_unit'
+require 'abstract_unit'
require 'test/unit'
require 'active_support'
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index b374eca370..aecc644549 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -4,6 +4,7 @@ require 'active_support/core_ext/big_decimal'
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext' # FIXME: pulling in all to_xml extensions
+require 'active_support/hash_with_indifferent_access'
class ArrayExtAccessTests < Test::Unit::TestCase
def test_from
@@ -294,12 +295,45 @@ class ArrayToXmlTests < Test::Unit::TestCase
end
class ArrayExtractOptionsTests < Test::Unit::TestCase
+ class HashSubclass < Hash
+ end
+
+ class ExtractableHashSubclass < Hash
+ def extractable_options?
+ true
+ end
+ end
+
def test_extract_options
assert_equal({}, [].extract_options!)
assert_equal({}, [1].extract_options!)
assert_equal({:a=>:b}, [{:a=>:b}].extract_options!)
assert_equal({:a=>:b}, [1, {:a=>:b}].extract_options!)
end
+
+ def test_extract_options_doesnt_extract_hash_subclasses
+ hash = HashSubclass.new
+ hash[:foo] = 1
+ array = [hash]
+ options = array.extract_options!
+ assert_equal({}, options)
+ assert_equal [hash], array
+ end
+
+ def test_extract_options_extracts_extractable_subclass
+ hash = ExtractableHashSubclass.new
+ hash[:foo] = 1
+ array = [hash]
+ options = array.extract_options!
+ assert_equal({:foo => 1}, options)
+ assert_equal [], array
+ end
+
+ def test_extract_options_extracts_hwia
+ hash = [{:foo => 1}.with_indifferent_access]
+ options = hash.extract_options!
+ assert_equal 1, options[:foo]
+ end
end
class ArrayUniqByTests < Test::Unit::TestCase
diff --git a/activesupport/test/core_ext/class/attribute_accessor_test.rb b/activesupport/test/core_ext/class/attribute_accessor_test.rb
index 2214ba9894..0f579d12e5 100644
--- a/activesupport/test/core_ext/class/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/class/attribute_accessor_test.rb
@@ -5,7 +5,8 @@ class ClassAttributeAccessorTest < Test::Unit::TestCase
def setup
@class = Class.new do
cattr_accessor :foo
- cattr_accessor :bar, :instance_writer => false
+ cattr_accessor :bar, :instance_writer => false
+ cattr_reader :shaq, :instance_reader => false
end
@object = @class.new
end
@@ -29,4 +30,9 @@ class ClassAttributeAccessorTest < Test::Unit::TestCase
assert @object.respond_to?(:bar)
assert !@object.respond_to?(:bar=)
end
+
+ def test_should_not_create_instance_reader
+ assert @class.respond_to?(:shaq)
+ assert !@object.respond_to?(:shaq)
+ end
end
diff --git a/activesupport/test/core_ext/class/delegating_attributes_test.rb b/activesupport/test/core_ext/class/delegating_attributes_test.rb
index 636edb8d4b..6d6cb61571 100644
--- a/activesupport/test/core_ext/class/delegating_attributes_test.rb
+++ b/activesupport/test/core_ext/class/delegating_attributes_test.rb
@@ -11,6 +11,13 @@ module DelegatingFixtures
class Mokopuna < Child
end
+
+ class PercysMom
+ superclass_delegating_accessor :superpower
+ end
+
+ class Percy < PercysMom
+ end
end
class DelegatingAttributesTest < Test::Unit::TestCase
@@ -70,18 +77,17 @@ class DelegatingAttributesTest < Test::Unit::TestCase
end
def test_delegation_stops_at_the_right_level
- assert_nil Mokopuna.some_attribute
- assert_nil Child.some_attribute
- Child.some_attribute="1"
- assert_equal "1", Mokopuna.some_attribute
- ensure
- Child.some_attribute=nil
+ assert_nil Percy.superpower
+ assert_nil PercysMom.superpower
+
+ PercysMom.superpower = :heatvision
+ assert_equal :heatvision, Percy.superpower
end
-
+
def test_delegation_stops_for_nil
Mokopuna.some_attribute = nil
Child.some_attribute="1"
-
+
assert_equal "1", Child.some_attribute
assert_nil Mokopuna.some_attribute
ensure
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 5b1d53ac7b..86272a28c1 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -757,6 +757,7 @@ class HashToXmlTest < Test::Unit::TestCase
<expires-at type="dateTime">2007-12-25T12:34:56+0000</expires-at>
<notes type="string"></notes>
<illustration type="base64Binary">YmFiZS5wbmc=</illustration>
+ <caption type="binary" encoding="base64">VGhhdCdsbCBkbywgcGlnLg==</caption>
</bacon>
EOT
@@ -766,7 +767,8 @@ class HashToXmlTest < Test::Unit::TestCase
:price => BigDecimal("12.50"),
:expires_at => Time.utc(2007,12,25,12,34,56),
:notes => "",
- :illustration => "babe.png"
+ :illustration => "babe.png",
+ :caption => "That'll do, pig."
}.stringify_keys
assert_equal expected_bacon_hash, Hash.from_xml(bacon_xml)["bacon"]
diff --git a/activesupport/test/core_ext/module/attribute_accessor_test.rb b/activesupport/test/core_ext/module/attribute_accessor_test.rb
index bd9461e62c..263e78feaa 100644
--- a/activesupport/test/core_ext/module/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/module/attribute_accessor_test.rb
@@ -6,6 +6,7 @@ class ModuleAttributeAccessorTest < Test::Unit::TestCase
m = @module = Module.new do
mattr_accessor :foo
mattr_accessor :bar, :instance_writer => false
+ mattr_reader :shaq, :instance_reader => false
end
@class = Class.new
@class.instance_eval { include m }
@@ -31,4 +32,9 @@ class ModuleAttributeAccessorTest < Test::Unit::TestCase
assert @object.respond_to?(:bar)
assert !@object.respond_to?(:bar=)
end
+
+ def test_should_not_create_instance_reader
+ assert @module.respond_to?(:shaq)
+ assert !@object.respond_to?(:shaq)
+ end
end
diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb
index 9edd7cc7c0..1712b0649b 100644
--- a/activesupport/test/core_ext/module_test.rb
+++ b/activesupport/test/core_ext/module_test.rb
@@ -141,6 +141,20 @@ class ModuleTest < Test::Unit::TestCase
assert_equal 0.0, nil_project.to_f
end
+ def test_delegation_does_not_raise_error_when_removing_singleton_instance_methods
+ parent = Class.new do
+ def self.parent_method; end
+ end
+
+ assert_nothing_raised do
+ child = Class.new(parent) do
+ class << self
+ delegate :parent_method, :to => :superclass
+ end
+ end
+ end
+ end
+
def test_parent
assert_equal Yz::Zy, Yz::Zy::Cd.parent
assert_equal Yz, Yz::Zy.parent
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index a50e259726..234e41c772 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -285,7 +285,7 @@ class TestGetTextString < Test::Unit::TestCase
def test_percent
assert_equal("% 1", "%% %<num>d" % {:num => 1.0})
- assert_equal("%{num} %<num>d", "%%{num} %%<num>d" % {:num => 1})
+ assert_equal("%{num} %<num>d 1", "%%{num} %%<num>d %<num>d" % {:num => 1})
end
def test_sprintf_percent_in_replacement
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 08c079e113..159b7d8366 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -761,7 +761,7 @@ class TimeExtMarshalingTest < Test::Unit::TestCase
marshaled = Marshal.dump t
unmarshaled = Marshal.load marshaled
assert_equal t, unmarshaled
- assert_equal t.zone, unmarshaled.zone
+ assert_equal "UTC", unmarshaled.zone
end
def test_marshaling_with_local_instance
@@ -777,7 +777,7 @@ class TimeExtMarshalingTest < Test::Unit::TestCase
marshaled = Marshal.dump t
unmarshaled = Marshal.load marshaled
assert_equal t, unmarshaled
- assert_equal t.zone, unmarshaled.zone
+ assert_equal "UTC", unmarshaled.zone
end
def test_marshaling_with_frozen_local_instance
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 6ff6dfb607..2cbf9e5042 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -88,7 +88,7 @@ class DependenciesTest < Test::Unit::TestCase
old_warnings, ActiveSupport::Dependencies.warnings_on_first_load = ActiveSupport::Dependencies.warnings_on_first_load, true
filename = "check_warnings"
- expanded = File.expand_path("test/dependencies/#{filename}")
+ expanded = File.expand_path("#{File.dirname(__FILE__)}/dependencies/#{filename}")
$check_warnings_load_count = 0
assert !ActiveSupport::Dependencies.loaded.include?(expanded)
diff --git a/activesupport/test/flush_cache_on_private_memoization_test.rb b/activesupport/test/flush_cache_on_private_memoization_test.rb
index 1cd313ec81..91b856ed7c 100644
--- a/activesupport/test/flush_cache_on_private_memoization_test.rb
+++ b/activesupport/test/flush_cache_on_private_memoization_test.rb
@@ -1,3 +1,4 @@
+require 'abstract_unit'
require 'active_support'
require 'test/unit'
diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb
index ebd26d3fc6..56372903f3 100644
--- a/activesupport/test/inflector_test_cases.rb
+++ b/activesupport/test/inflector_test_cases.rb
@@ -180,18 +180,10 @@ module InflectorTestCases
"Test with + sign" => "test_with_sign"
}
- # Ruby 1.9 doesn't do Unicode normalization yet.
- if RUBY_VERSION >= '1.9'
- StringToParameterizedAndNormalized = {
- "Malmö" => "malm",
- "Garçons" => "gar-ons"
- }
- else
- StringToParameterizedAndNormalized = {
- "Malmö" => "malmo",
- "Garçons" => "garcons"
- }
- end
+ StringToParameterizedAndNormalized = {
+ "Malmö" => "malmo",
+ "Garçons" => "garcons"
+ }
UnderscoreToHuman = {
"employee_salary" => "Employee salary",
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 67c3527e23..92fbe5b92f 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -65,7 +65,7 @@ module Notifications
assert_equal [[:foo]] * 4, @events
end
- def test_log_subscriber_with_pattern
+ def test_log_subscriber_with_string
events = []
@notifier.subscribe('1') { |*args| events << args }
@@ -74,10 +74,10 @@ module Notifications
@notifier.publish 'a.1'
@notifier.wait
- assert_equal [['1'], ['1.a']], events
+ assert_equal [['1']], events
end
- def test_log_subscriber_with_pattern_as_regexp
+ def test_log_subscriber_with_pattern
events = []
@notifier.subscribe(/\d/) { |*args| events << args }
diff --git a/activesupport/test/ts_isolated.rb b/activesupport/test/ts_isolated.rb
index cbab61a523..58710e0165 100644
--- a/activesupport/test/ts_isolated.rb
+++ b/activesupport/test/ts_isolated.rb
@@ -1,3 +1,5 @@
+$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
+
require 'test/unit'
require 'rbconfig'
require 'active_support/core_ext/kernel/reporting'
diff --git a/ci/ci_build.rb b/ci/ci_build.rb
index 02351729f2..1602c5106d 100755
--- a/ci/ci_build.rb
+++ b/ci/ci_build.rb
@@ -35,7 +35,7 @@ cd "#{root_dir}/activesupport" do
puts "[CruiseControl] Building ActiveSupport"
puts
build_results[:activesupport] = rake 'test'
- build_results[:activesupport_isolated] = rake 'test:isolated'
+ # build_results[:activesupport_isolated] = rake 'test:isolated'
end
cd "#{root_dir}/railties" do
@@ -50,7 +50,7 @@ cd "#{root_dir}/actionpack" do
puts "[CruiseControl] Building ActionPack"
puts
build_results[:actionpack] = rake 'test'
- build_results[:actionpack_isolated] = rake 'test:isolated'
+ # build_results[:actionpack_isolated] = rake 'test:isolated'
end
cd "#{root_dir}/actionmailer" do
@@ -58,7 +58,7 @@ cd "#{root_dir}/actionmailer" do
puts "[CruiseControl] Building ActionMailer"
puts
build_results[:actionmailer] = rake 'test'
- build_results[:actionmailer_isolated] = rake 'test:isolated'
+ # build_results[:actionmailer_isolated] = rake 'test:isolated'
end
cd "#{root_dir}/activemodel" do
@@ -66,7 +66,7 @@ cd "#{root_dir}/activemodel" do
puts "[CruiseControl] Building ActiveModel"
puts
build_results[:activemodel] = rake 'test'
- build_results[:activemodel_isolated] = rake 'test:isolated'
+ # build_results[:activemodel_isolated] = rake 'test:isolated'
end
rm_f "#{root_dir}/activeresource/debug.log"
@@ -75,7 +75,7 @@ cd "#{root_dir}/activeresource" do
puts "[CruiseControl] Building ActiveResource"
puts
build_results[:activeresource] = rake 'test'
- build_results[:activeresource_isolated] = rake 'test:isolated'
+ # build_results[:activeresource_isolated] = rake 'test:isolated'
end
rm_f "#{root_dir}/activerecord/debug.log"
@@ -84,7 +84,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building ActiveRecord with MySQL"
puts
build_results[:activerecord_mysql] = rake 'mysql:rebuild_databases', 'mysql:test'
- build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
+ # build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
end
cd "#{root_dir}/activerecord" do
@@ -92,7 +92,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building ActiveRecord with PostgreSQL"
puts
build_results[:activerecord_postgresql8] = rake 'postgresql:rebuild_databases', 'postgresql:test'
- build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
+ # build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
end
cd "#{root_dir}/activerecord" do
@@ -100,7 +100,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building ActiveRecord with SQLite 3"
puts
build_results[:activerecord_sqlite3] = rake 'sqlite3:test'
- build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
+ # build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
end
diff --git a/load_paths.rb b/load_paths.rb
index b87e0d7235..873315f978 100644
--- a/load_paths.rb
+++ b/load_paths.rb
@@ -2,7 +2,13 @@ begin
require File.expand_path('../.bundle/environment', __FILE__)
rescue LoadError
begin
- require 'rubygems'
+ # bust gem prelude
+ if defined? Gem
+ Gem.cache
+ gem 'bundler'
+ else
+ require 'rubygems'
+ end
require 'bundler'
Bundler.setup
rescue LoadError
diff --git a/railties/Rakefile b/railties/Rakefile
index fe049d565f..6368456366 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -36,7 +36,7 @@ end
desc "Updates application README to the latest version Railties README"
task :update_readme do
- readme = "lib/generators/rails/app/templates/README"
+ readme = "lib/rails/generators/rails/app/templates/README"
rm readme
cp "./README", readme
end
@@ -48,7 +48,7 @@ task :generate_guides do
end
task :update_prototype_ujs do
- system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/generators/rails/app/templates/public/javascripts/rails.js"
+ system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/rails.js"
end
# Generate documentation ------------------------------------------------------------------
@@ -62,8 +62,8 @@ Rake::RDocTask.new { |rdoc|
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/*.rb')
rdoc.rdoc_files.include('lib/rails/*.rb')
- rdoc.rdoc_files.include('lib/generators/*.rb')
- rdoc.rdoc_files.include('lib/commands/**/*.rb')
+ rdoc.rdoc_files.include('lib/rails/generators/*.rb')
+ rdoc.rdoc_files.include('lib/rails/commands/**/*.rb')
}
# Generate GEM ----------------------------------------------------------------------------
diff --git a/railties/builtin/rails_info/rails/info_helper.rb b/railties/builtin/rails_info/rails/info_helper.rb
deleted file mode 100644
index e5605a8d9b..0000000000
--- a/railties/builtin/rails_info/rails/info_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module Rails::InfoHelper
-end
diff --git a/railties/lib/generators/erb.rb b/railties/lib/generators/erb.rb
deleted file mode 100644
index d468d012dc..0000000000
--- a/railties/lib/generators/erb.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails/generators/named_base'
-
-module Erb
- module Generators
- class Base < Rails::Generators::NamedBase #:nodoc:
- end
- end
-end
diff --git a/railties/lib/generators/erb/mailer/mailer_generator.rb b/railties/lib/generators/erb/mailer/mailer_generator.rb
deleted file mode 100644
index 408c942cef..0000000000
--- a/railties/lib/generators/erb/mailer/mailer_generator.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'generators/erb'
-
-module Erb
- module Generators
- class MailerGenerator < Base
- argument :actions, :type => :array, :default => [], :banner => "method method"
-
- def create_view_folder
- empty_directory File.join("app/views", file_path)
- end
-
- def create_view_files
- actions.each do |action|
- @action, @path = action, File.join(file_path, action)
- template "view.text.erb", File.join("app/views", "#{@path}.text.erb")
- end
- end
- end
- end
-end
diff --git a/railties/lib/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/generators/test_unit/controller/templates/functional_test.rb
deleted file mode 100644
index 62fa5d86fd..0000000000
--- a/railties/lib/generators/test_unit/controller/templates/functional_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'test_helper'
-
-class <%= class_name %>ControllerTest < ActionController::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
-end
diff --git a/railties/lib/generators/test_unit/mailer/templates/fixture b/railties/lib/generators/test_unit/mailer/templates/fixture
deleted file mode 100644
index 171648d6fd..0000000000
--- a/railties/lib/generators/test_unit/mailer/templates/fixture
+++ /dev/null
@@ -1,3 +0,0 @@
-<%= class_name %>#<%= @action %>
-
-Hi, find me in app/views/<%= @path %>
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index 3d3151bd8f..9d02da104d 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -26,6 +26,9 @@ else
end
module Rails
+ autoload :Info, 'rails/info'
+ autoload :InfoController, 'rails/info_controller'
+
class << self
def application
@@application ||= nil
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 49388c5060..0084309ea4 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,5 +1,4 @@
require 'fileutils'
-require 'rails/railties_path'
require 'rails/plugin'
require 'rails/engine'
@@ -82,6 +81,8 @@ module Rails
end
end
+ delegate :metal_loader, :to => :config
+
def require_environment!
environment = config.paths.config.environment.to_a.first
require environment if environment
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index d3a0ecb243..44635ff4f6 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -6,7 +6,7 @@ module Rails
include ::Rails::Configuration::Deprecated
attr_accessor :allow_concurrency, :cache_classes, :cache_store,
- :consider_all_requests_local, :dependency_loading,
+ :cookie_secret, :consider_all_requests_local, :dependency_loading,
:filter_parameters, :log_level, :logger, :metals,
:plugins, :preload_frameworks, :reload_engines, :reload_plugins,
:serve_static_assets, :time_zone, :whiny_nils
@@ -19,10 +19,16 @@ module Rails
@serve_static_assets = true
@time_zone = "UTC"
@consider_all_requests_local = true
+ @session_store = :cookie_store
+ @session_options = {}
end
def middleware
- @@default_middleware_stack ||= default_middleware
+ @middleware ||= default_middleware_stack
+ end
+
+ def metal_loader
+ @metal_loader ||= Rails::Application::MetalLoader.new
end
def paths
@@ -78,7 +84,7 @@ module Rails
end
def builtin_controller
- File.join(RAILTIES_PATH, "builtin", "rails_info") if Rails.env.development?
+ File.expand_path('../info_routes', __FILE__) if Rails.env.development?
end
def log_level
@@ -94,6 +100,51 @@ module Rails
Rails::LogSubscriber.colorize_logging = val
self.generators.colorize_logging = val
end
+
+ def session_store(*args)
+ if args.empty?
+ case @session_store
+ when :disabled
+ nil
+ when :active_record_store
+ ActiveRecord::SessionStore
+ when Symbol
+ ActionDispatch::Session.const_get(@session_store.to_s.camelize)
+ else
+ @session_store
+ end
+ else
+ @session_store = args.shift
+ @session_options = args.shift || {}
+ end
+ end
+
+ protected
+
+ def session_options
+ return @session_options unless @session_store == :cookie_store
+ @session_options.merge(:secret => @cookie_secret)
+ end
+
+ def default_middleware_stack
+ ActionDispatch::MiddlewareStack.new.tap do |middleware|
+ middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { serve_static_assets })
+ middleware.use('::Rack::Lock', :if => lambda { !allow_concurrency })
+ middleware.use('::Rack::Runtime')
+ middleware.use('::Rails::Rack::Logger')
+ middleware.use('::ActionDispatch::ShowExceptions', lambda { consider_all_requests_local })
+ middleware.use("::ActionDispatch::RemoteIp", lambda { action_dispatch.ip_spoofing_check }, lambda { action_dispatch.trusted_proxies })
+ middleware.use('::Rack::Sendfile', lambda { action_dispatch.x_sendfile_header })
+ middleware.use('::ActionDispatch::Callbacks', lambda { !cache_classes })
+ middleware.use('::ActionDispatch::Cookies')
+ middleware.use(lambda { session_store }, lambda { session_options })
+ middleware.use('::ActionDispatch::Flash', :if => lambda { session_store })
+ middleware.use(lambda { metal_loader.build_middleware(metals) }, :if => lambda { metal_loader.metals.any? })
+ middleware.use('ActionDispatch::ParamsParser')
+ middleware.use('::Rack::MethodOverride')
+ middleware.use('::ActionDispatch::Head')
+ end
+ end
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index cb38d5a5db..978490f25f 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -23,7 +23,7 @@ module Rails
initializer :add_builtin_route do |app|
if Rails.env.development?
- app.routes_reloader.paths << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
+ app.routes_reloader.paths << File.expand_path('../../info_routes.rb', __FILE__)
end
end
@@ -45,4 +45,4 @@ module Rails
end
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/commands/application.rb b/railties/lib/rails/commands/application.rb
index fe2f89ee98..438c976b35 100644
--- a/railties/lib/rails/commands/application.rb
+++ b/railties/lib/rails/commands/application.rb
@@ -8,6 +8,6 @@ ARGV << "--help" if ARGV.empty?
require 'rubygems' if ARGV.include?("--dev")
require 'rails/generators'
-require 'generators/rails/app/app_generator'
+require 'rails/generators/rails/app/app_generator'
Rails::Generators::AppGenerator.start \ No newline at end of file
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index 593e2d8ee3..68982b9f52 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -91,6 +91,18 @@ module Rails
args << config['database']
exec(find_cmd('sqlite3'), *args)
+
+ when "oracle", "oracle_enhanced"
+ logon = ""
+
+ if config['username']
+ logon = config['username']
+ logon << "/#{config['password']}" if config['password'] && include_password
+ logon << "@#{config['database']}" if config['database']
+ end
+
+ exec(find_cmd('sqlplus'), logon)
+
else
abort "Unknown command-line client for #{config['database']}. Submit a Rails patch to add support!"
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 7ee0f31359..85cae75bce 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -93,11 +93,11 @@ module Rails
class << self
attr_accessor :called_from
- alias :engine_name :railtie_name
- alias :engine_names :railtie_names
+ # TODO Remove this. It's deprecated.
+ alias :engine_name :railtie_name
def inherited(base)
- unless abstract_railtie?(base)
+ unless base.abstract_railtie?
base.called_from = begin
# Remove the line number from backtraces making sure we don't leave anything behind
call_stack = caller.map { |p| p.split(':')[0..-2].join(':') }
@@ -124,7 +124,7 @@ module Rails
end
end
- delegate :middleware, :paths, :metal_loader, :root, :to => :config
+ delegate :middleware, :paths, :root, :to => :config
def load_tasks
super
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 9a51171cf5..57462707f4 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -242,7 +242,7 @@ module Rails
paths = namespaces_to_paths(namespaces)
paths.each do |raw_path|
- ["rails_generators", "generators"].each do |base|
+ ["rails/generators", "generators"].each do |base|
path = "#{base}/#{raw_path}_generator"
begin
@@ -265,7 +265,7 @@ module Rails
load_generators_from_railties!
$LOAD_PATH.each do |base|
- Dir[File.join(base, "{generators,rails_generators}", "**", "*_generator.rb")].each do |path|
+ Dir[File.join(base, "{rails/generators,generators}", "**", "*_generator.rb")].each do |path|
begin
require path
rescue Exception => e
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 9624c35c0b..0da85ea4a4 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -1,4 +1,12 @@
-require 'thor/group'
+begin
+ require 'thor/group'
+rescue LoadError
+ puts "Thor is not available.\nIf you ran this command from a git checkout " \
+ "of Rails, please make sure thor is installed,\nand run this command " \
+ "as `ruby /path/to/rails myapp --dev`"
+ exit
+end
+
require 'rails/generators/actions'
module Rails
@@ -17,7 +25,7 @@ module Rails
def self.source_root
@_rails_source_root ||= begin
if base_name && generator_name
- File.expand_path(File.join("../../generators", base_name, generator_name, 'templates'), File.dirname(__FILE__))
+ File.expand_path(File.join(base_name, generator_name, 'templates'), File.dirname(__FILE__))
end
end
end
diff --git a/railties/lib/rails/generators/erb.rb b/railties/lib/rails/generators/erb.rb
new file mode 100644
index 0000000000..3e6371268f
--- /dev/null
+++ b/railties/lib/rails/generators/erb.rb
@@ -0,0 +1,21 @@
+require 'rails/generators/named_base'
+
+module Erb
+ module Generators
+ class Base < Rails::Generators::NamedBase #:nodoc:
+ protected
+
+ def format
+ :html
+ end
+
+ def handler
+ :erb
+ end
+
+ def filename_with_extensions(name)
+ [name, format, handler].compact.join(".")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/erb/controller/controller_generator.rb b/railties/lib/rails/generators/erb/controller/controller_generator.rb
index ab7b273662..ac57140c23 100644
--- a/railties/lib/generators/erb/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/erb/controller/controller_generator.rb
@@ -1,19 +1,18 @@
-require 'generators/erb'
+require 'rails/generators/erb'
module Erb
module Generators
class ControllerGenerator < Base
argument :actions, :type => :array, :default => [], :banner => "action action"
- def create_view_files
+ def copy_view_files
base_path = File.join("app/views", class_path, file_name)
empty_directory base_path
actions.each do |action|
@action = action
- @path = File.join(base_path, "#{action}.html.erb")
-
- template 'view.html.erb', @path
+ @path = File.join(base_path, filename_with_extensions(action))
+ template filename_with_extensions(:view), @path
end
end
end
diff --git a/railties/lib/generators/erb/controller/templates/view.html.erb b/railties/lib/rails/generators/erb/controller/templates/view.html.erb
index cd54d13d83..cd54d13d83 100644
--- a/railties/lib/generators/erb/controller/templates/view.html.erb
+++ b/railties/lib/rails/generators/erb/controller/templates/view.html.erb
diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
new file mode 100644
index 0000000000..943d0c9f8d
--- /dev/null
+++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
@@ -0,0 +1,13 @@
+require 'rails/generators/erb/controller/controller_generator'
+
+module Erb
+ module Generators
+ class MailerGenerator < ControllerGenerator
+ protected
+
+ def format
+ :text
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/erb/mailer/templates/view.text.erb b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
index 6d597256a6..6d597256a6 100644
--- a/railties/lib/generators/erb/mailer/templates/view.text.erb
+++ b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
diff --git a/railties/lib/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
index 846540476f..f607e580a5 100644
--- a/railties/lib/generators/erb/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/erb'
+require 'rails/generators/erb'
require 'rails/generators/resource_helpers'
module Erb
@@ -15,39 +15,27 @@ module Erb
empty_directory File.join("app/views", controller_file_path)
end
- def copy_index_file
- return if options[:singleton]
- copy_view :index
- end
-
- def copy_edit_file
- copy_view :edit
- end
+ def copy_view_files
+ views = available_views
+ views.delete("index") if options[:singleton]
- def copy_show_file
- copy_view :show
- end
-
- def copy_new_file
- copy_view :new
- end
-
- def copy_form_file
- copy_view :_form
+ views.each do |view|
+ filename = filename_with_extensions(view)
+ template filename, File.join("app/views", controller_file_path, filename)
+ end
end
def copy_layout_file
return unless options[:layout]
- template "layout.html.erb",
- File.join("app/views/layouts", controller_class_path, "#{controller_file_name}.html.erb")
+ template filename_with_extensions(:layout),
+ File.join("app/views/layouts", controller_class_path, filename_with_extensions(controller_file_name))
end
- protected
-
- def copy_view(view)
- template "#{view}.html.erb", File.join("app/views", controller_file_path, "#{view}.html.erb")
- end
+ protected
+ def available_views
+ %w(index edit show new _form)
+ end
end
end
end
diff --git a/railties/lib/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index 01ec58c615..01ec58c615 100644
--- a/railties/lib/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
diff --git a/railties/lib/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
index 5bc507ffc8..5bc507ffc8 100644
--- a/railties/lib/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
diff --git a/railties/lib/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index b5c7fd1e58..d30d306d42 100644
--- a/railties/lib/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -24,4 +24,4 @@
<br />
-<%%= link_to 'New <%= singular_name %>', new_<%= singular_name %>_path %>
+<%%= link_to 'New <%= human_name %>', new_<%= singular_name %>_path %>
diff --git a/railties/lib/generators/erb/scaffold/templates/layout.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb
index 3f64be0c45..3f64be0c45 100644
--- a/railties/lib/generators/erb/scaffold/templates/layout.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb
diff --git a/railties/lib/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
index 9a1c489331..9a1c489331 100644
--- a/railties/lib/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
diff --git a/railties/lib/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index 24f13fc0f8..24f13fc0f8 100644
--- a/railties/lib/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 12e918731e..8d1dfbd947 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -27,6 +27,10 @@ module Rails
@class_name ||= (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
end
+ def human_name
+ @human_name ||= singular_name.humanize
+ end
+
def plural_name
@plural_name ||= singular_name.pluralize
end
diff --git a/railties/lib/generators/rails/app/USAGE b/railties/lib/rails/generators/rails/app/USAGE
index 36d6061a59..36d6061a59 100644
--- a/railties/lib/generators/rails/app/USAGE
+++ b/railties/lib/rails/generators/rails/app/USAGE
diff --git a/railties/lib/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 1e1acc1141..fccae9190a 100644
--- a/railties/lib/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -5,7 +5,7 @@ require 'rails/version' unless defined?(Rails::VERSION)
module Rails::Generators
# We need to store the RAILS_DEV_PATH in a constant, otherwise the path
# can change in Ruby 1.8.7 when we FileUtils.cd.
- RAILS_DEV_PATH = File.expand_path("../../../../..", File.dirname(__FILE__))
+ RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
RESERVED_NAMES = %w[generate console server dbconsole
application destroy benchmarker profiler
diff --git a/railties/lib/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 0dd10f3f2d..0dd10f3f2d 100644
--- a/railties/lib/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
diff --git a/railties/lib/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README
index ded8570c42..ded8570c42 100644
--- a/railties/lib/generators/rails/app/templates/README
+++ b/railties/lib/rails/generators/rails/app/templates/README
diff --git a/railties/lib/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile
index 9cb2046439..9cb2046439 100755
--- a/railties/lib/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile
diff --git a/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb
index e8065d9505..e8065d9505 100644
--- a/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb
diff --git a/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb b/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb
index de6be7945c..de6be7945c 100644
--- a/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb
diff --git a/railties/lib/generators/rails/app/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/app/models/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru
index fcfbc6b07a..fcfbc6b07a 100644
--- a/railties/lib/generators/rails/app/templates/config.ru
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru
diff --git a/railties/lib/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index dc20ffb2fa..dc20ffb2fa 100644
--- a/railties/lib/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
diff --git a/railties/lib/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
index 3cb561d41f..3cb561d41f 100644
--- a/railties/lib/generators/rails/app/templates/config/boot.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
diff --git a/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
index c0c3588be1..c0c3588be1 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
diff --git a/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index 2784a949fb..2784a949fb 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
diff --git a/railties/lib/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index 6bf2f7b1fd..6bf2f7b1fd 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
diff --git a/railties/lib/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
index a1883f6256..a1883f6256 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
diff --git a/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index f600e054cf..f600e054cf 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
diff --git a/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
index 025d62a8d8..025d62a8d8 100644
--- a/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
diff --git a/railties/lib/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
index 1684986a59..1684986a59 100644
--- a/railties/lib/generators/rails/app/templates/config/environment.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
diff --git a/railties/lib/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index f0e917dd96..f0e917dd96 100644
--- a/railties/lib/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
diff --git a/railties/lib/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 917052c3df..f902120453 100644
--- a/railties/lib/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -9,6 +9,15 @@
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
+ # Specifies the header that your server uses for sending files
+ config.action_dispatch.x_sendfile_header = "X-Sendfile"
+
+ # For nginx:
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
+
+ # If you have no front-end server that supports something like X-Sendfile,
+ # just comment this out and Rails will serve the files
+
# See everything in the log (default is :info)
# config.log_level = :debug
diff --git a/railties/lib/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index 0b87b241ec..0b87b241ec 100644
--- a/railties/lib/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
diff --git a/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
index 59385cdf37..59385cdf37 100644
--- a/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
diff --git a/railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt
index be627fbbcc..be627fbbcc 100644
--- a/railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt
diff --git a/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
index d531b8bb82..d531b8bb82 100644
--- a/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
diff --git a/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
index 72aca7e441..72aca7e441 100644
--- a/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
diff --git a/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt
index 9e32fb930e..9e32fb930e 100644
--- a/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt
diff --git a/railties/lib/generators/rails/app/templates/config/locales/en.yml b/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml
index a747bfa698..a747bfa698 100644
--- a/railties/lib/generators/rails/app/templates/config/locales/en.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml
diff --git a/railties/lib/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index d6c0365c04..d6c0365c04 100644
--- a/railties/lib/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
diff --git a/railties/lib/generators/rails/app/templates/db/seeds.rb b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb
index 664d8c74c8..664d8c74c8 100644
--- a/railties/lib/generators/rails/app/templates/db/seeds.rb
+++ b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb
diff --git a/railties/lib/generators/rails/app/templates/doc/README_FOR_APP b/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP
index fe41f5cc24..fe41f5cc24 100644
--- a/railties/lib/generators/rails/app/templates/doc/README_FOR_APP
+++ b/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP
diff --git a/railties/lib/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index af64fae5e7..af64fae5e7 100644
--- a/railties/lib/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
diff --git a/railties/lib/generators/rails/app/templates/public/404.html b/railties/lib/rails/generators/rails/app/templates/public/404.html
index 9a48320a5f..9a48320a5f 100644
--- a/railties/lib/generators/rails/app/templates/public/404.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/404.html
diff --git a/railties/lib/generators/rails/app/templates/public/422.html b/railties/lib/rails/generators/rails/app/templates/public/422.html
index 83660ab187..83660ab187 100644
--- a/railties/lib/generators/rails/app/templates/public/422.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/422.html
diff --git a/railties/lib/generators/rails/app/templates/public/500.html b/railties/lib/rails/generators/rails/app/templates/public/500.html
index b80307fc16..b80307fc16 100644
--- a/railties/lib/generators/rails/app/templates/public/500.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/500.html
diff --git a/railties/lib/generators/rails/app/templates/public/favicon.ico b/railties/lib/rails/generators/rails/app/templates/public/favicon.ico
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/public/favicon.ico
+++ b/railties/lib/rails/generators/rails/app/templates/public/favicon.ico
diff --git a/railties/lib/generators/rails/app/templates/public/images/rails.png b/railties/lib/rails/generators/rails/app/templates/public/images/rails.png
index d5edc04e65..d5edc04e65 100644
--- a/railties/lib/generators/rails/app/templates/public/images/rails.png
+++ b/railties/lib/rails/generators/rails/app/templates/public/images/rails.png
Binary files differ
diff --git a/railties/lib/generators/rails/app/templates/public/index.html b/railties/lib/rails/generators/rails/app/templates/public/index.html
index 836da1b689..836da1b689 100644
--- a/railties/lib/generators/rails/app/templates/public/index.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/index.html
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/application.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js
index fe4577696b..fe4577696b 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/application.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/controls.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js
index 7392fb664c..7392fb664c 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/controls.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js
index 15c6dbca68..15c6dbca68 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/effects.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js
index 066ee5909c..066ee5909c 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/effects.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js
index 9fe6e1243b..9fe6e1243b 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/rails.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
index f7ddba390a..7342e1b830 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/rails.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
@@ -15,8 +15,7 @@ document.observe("dom:loaded", function() {
params = element.serialize(true);
} else {
method = element.readAttribute('data-method') || 'get';
- // TODO: data-url support is going away, just use href
- url = element.readAttribute('data-url') || element.readAttribute('href');
+ url = element.readAttribute('href');
params = {};
}
diff --git a/railties/lib/generators/rails/app/templates/public/robots.txt b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
index 085187fa58..085187fa58 100644
--- a/railties/lib/generators/rails/app/templates/public/robots.txt
+++ b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
diff --git a/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory b/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/script/rails b/railties/lib/rails/generators/rails/app/templates/script/rails
index b01d1ee183..b01d1ee183 100644
--- a/railties/lib/generators/rails/app/templates/script/rails
+++ b/railties/lib/rails/generators/rails/app/templates/script/rails
diff --git a/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/functional/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/test/functional/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/integration/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/test/integration/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
index a3dc38d9e4..a3dc38d9e4 100644
--- a/railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
diff --git a/railties/lib/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
index 8bf1192ffe..8bf1192ffe 100644
--- a/railties/lib/generators/rails/app/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
diff --git a/railties/lib/generators/rails/app/templates/test/unit/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/app/templates/test/unit/.empty_directory
+++ b/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory
diff --git a/railties/lib/generators/rails/controller/USAGE b/railties/lib/rails/generators/rails/controller/USAGE
index 70618a3906..70618a3906 100644
--- a/railties/lib/generators/rails/controller/USAGE
+++ b/railties/lib/rails/generators/rails/controller/USAGE
diff --git a/railties/lib/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb
index 91470be833..9788c0d0bc 100644
--- a/railties/lib/generators/rails/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb
@@ -8,6 +8,12 @@ module Rails
template 'controller.rb', File.join('app/controllers', class_path, "#{file_name}_controller.rb")
end
+ def add_routes
+ actions.reverse.each do |action|
+ route %{get "#{file_name}/#{action}"}
+ end
+ end
+
hook_for :template_engine, :test_framework, :helper
end
end
diff --git a/railties/lib/generators/rails/controller/templates/controller.rb b/railties/lib/rails/generators/rails/controller/templates/controller.rb
index cda2659e69..cda2659e69 100644
--- a/railties/lib/generators/rails/controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/controller/templates/controller.rb
diff --git a/railties/lib/generators/rails/generator/USAGE b/railties/lib/rails/generators/rails/generator/USAGE
index d8c3f7f634..d8c3f7f634 100644
--- a/railties/lib/generators/rails/generator/USAGE
+++ b/railties/lib/rails/generators/rails/generator/USAGE
diff --git a/railties/lib/generators/rails/generator/generator_generator.rb b/railties/lib/rails/generators/rails/generator/generator_generator.rb
index 5b5d1884bc..5b5d1884bc 100644
--- a/railties/lib/generators/rails/generator/generator_generator.rb
+++ b/railties/lib/rails/generators/rails/generator/generator_generator.rb
diff --git a/railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt b/railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt
index d8757460e4..d8757460e4 100644
--- a/railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt
+++ b/railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt
diff --git a/railties/lib/generators/rails/generator/templates/USAGE.tt b/railties/lib/rails/generators/rails/generator/templates/USAGE.tt
index 1bb8df840d..1bb8df840d 100644
--- a/railties/lib/generators/rails/generator/templates/USAGE.tt
+++ b/railties/lib/rails/generators/rails/generator/templates/USAGE.tt
diff --git a/railties/lib/generators/rails/generator/templates/templates/.empty_directory b/railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/lib/generators/rails/generator/templates/templates/.empty_directory
+++ b/railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory
diff --git a/railties/lib/generators/rails/helper/USAGE b/railties/lib/rails/generators/rails/helper/USAGE
index c0ddb0f606..c0ddb0f606 100644
--- a/railties/lib/generators/rails/helper/USAGE
+++ b/railties/lib/rails/generators/rails/helper/USAGE
diff --git a/railties/lib/generators/rails/helper/helper_generator.rb b/railties/lib/rails/generators/rails/helper/helper_generator.rb
index ad66388591..ad66388591 100644
--- a/railties/lib/generators/rails/helper/helper_generator.rb
+++ b/railties/lib/rails/generators/rails/helper/helper_generator.rb
diff --git a/railties/lib/generators/rails/helper/templates/helper.rb b/railties/lib/rails/generators/rails/helper/templates/helper.rb
index 3fe2ecdc74..3fe2ecdc74 100644
--- a/railties/lib/generators/rails/helper/templates/helper.rb
+++ b/railties/lib/rails/generators/rails/helper/templates/helper.rb
diff --git a/railties/lib/generators/rails/integration_test/USAGE b/railties/lib/rails/generators/rails/integration_test/USAGE
index 57ee3543e6..57ee3543e6 100644
--- a/railties/lib/generators/rails/integration_test/USAGE
+++ b/railties/lib/rails/generators/rails/integration_test/USAGE
diff --git a/railties/lib/generators/rails/integration_test/integration_test_generator.rb b/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb
index 363a327fcb..363a327fcb 100644
--- a/railties/lib/generators/rails/integration_test/integration_test_generator.rb
+++ b/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb
diff --git a/railties/lib/generators/rails/mailer/USAGE b/railties/lib/rails/generators/rails/mailer/USAGE
index a08d459739..a08d459739 100644
--- a/railties/lib/generators/rails/mailer/USAGE
+++ b/railties/lib/rails/generators/rails/mailer/USAGE
diff --git a/railties/lib/generators/rails/mailer/mailer_generator.rb b/railties/lib/rails/generators/rails/mailer/mailer_generator.rb
index 8993181d79..8993181d79 100644
--- a/railties/lib/generators/rails/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/rails/mailer/mailer_generator.rb
diff --git a/railties/lib/generators/rails/mailer/templates/mailer.rb b/railties/lib/rails/generators/rails/mailer/templates/mailer.rb
index 7343eb28b3..7343eb28b3 100644
--- a/railties/lib/generators/rails/mailer/templates/mailer.rb
+++ b/railties/lib/rails/generators/rails/mailer/templates/mailer.rb
diff --git a/railties/lib/generators/rails/metal/USAGE b/railties/lib/rails/generators/rails/metal/USAGE
index c88325a444..c88325a444 100644
--- a/railties/lib/generators/rails/metal/USAGE
+++ b/railties/lib/rails/generators/rails/metal/USAGE
diff --git a/railties/lib/generators/rails/metal/metal_generator.rb b/railties/lib/rails/generators/rails/metal/metal_generator.rb
index fe4f945cad..fe4f945cad 100644
--- a/railties/lib/generators/rails/metal/metal_generator.rb
+++ b/railties/lib/rails/generators/rails/metal/metal_generator.rb
diff --git a/railties/lib/generators/rails/metal/templates/metal.rb b/railties/lib/rails/generators/rails/metal/templates/metal.rb
index 8cc3f1f258..8cc3f1f258 100644
--- a/railties/lib/generators/rails/metal/templates/metal.rb
+++ b/railties/lib/rails/generators/rails/metal/templates/metal.rb
diff --git a/railties/lib/generators/rails/migration/USAGE b/railties/lib/rails/generators/rails/migration/USAGE
index d21c81b760..d21c81b760 100644
--- a/railties/lib/generators/rails/migration/USAGE
+++ b/railties/lib/rails/generators/rails/migration/USAGE
diff --git a/railties/lib/generators/rails/migration/migration_generator.rb b/railties/lib/rails/generators/rails/migration/migration_generator.rb
index 39fa5b63b1..39fa5b63b1 100644
--- a/railties/lib/generators/rails/migration/migration_generator.rb
+++ b/railties/lib/rails/generators/rails/migration/migration_generator.rb
diff --git a/railties/lib/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE
index d97e9ac103..d97e9ac103 100644
--- a/railties/lib/generators/rails/model/USAGE
+++ b/railties/lib/rails/generators/rails/model/USAGE
diff --git a/railties/lib/generators/rails/model/model_generator.rb b/railties/lib/rails/generators/rails/model/model_generator.rb
index 629d5eed3f..629d5eed3f 100644
--- a/railties/lib/generators/rails/model/model_generator.rb
+++ b/railties/lib/rails/generators/rails/model/model_generator.rb
diff --git a/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb b/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb
index 99fd2f45bc..99fd2f45bc 100644
--- a/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb
+++ b/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb
diff --git a/railties/lib/generators/rails/observer/USAGE b/railties/lib/rails/generators/rails/observer/USAGE
index d8f32a6a48..d8f32a6a48 100644
--- a/railties/lib/generators/rails/observer/USAGE
+++ b/railties/lib/rails/generators/rails/observer/USAGE
diff --git a/railties/lib/generators/rails/observer/observer_generator.rb b/railties/lib/rails/generators/rails/observer/observer_generator.rb
index f5cedee91f..f5cedee91f 100644
--- a/railties/lib/generators/rails/observer/observer_generator.rb
+++ b/railties/lib/rails/generators/rails/observer/observer_generator.rb
diff --git a/railties/lib/generators/rails/performance_test/USAGE b/railties/lib/rails/generators/rails/performance_test/USAGE
index 9dc799559c..9dc799559c 100644
--- a/railties/lib/generators/rails/performance_test/USAGE
+++ b/railties/lib/rails/generators/rails/performance_test/USAGE
diff --git a/railties/lib/generators/rails/performance_test/performance_test_generator.rb b/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb
index d1c71ab8ed..d1c71ab8ed 100644
--- a/railties/lib/generators/rails/performance_test/performance_test_generator.rb
+++ b/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb
diff --git a/railties/lib/generators/rails/plugin/USAGE b/railties/lib/rails/generators/rails/plugin/USAGE
index 00a429c585..00a429c585 100644
--- a/railties/lib/generators/rails/plugin/USAGE
+++ b/railties/lib/rails/generators/rails/plugin/USAGE
diff --git a/railties/lib/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 8f01dcd589..40ed2062d3 100644
--- a/railties/lib/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/rails/generator/generator_generator'
+require 'rails/generators/rails/generator/generator_generator'
module Rails
module Generators
diff --git a/railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt
index 8717df053d..8717df053d 100644
--- a/railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt
diff --git a/railties/lib/generators/rails/plugin/templates/README.tt b/railties/lib/rails/generators/rails/plugin/templates/README.tt
index 702db07cb1..702db07cb1 100644
--- a/railties/lib/generators/rails/plugin/templates/README.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/README.tt
diff --git a/railties/lib/generators/rails/plugin/templates/Rakefile.tt b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
index e94c0bfc77..e94c0bfc77 100644
--- a/railties/lib/generators/rails/plugin/templates/Rakefile.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
diff --git a/railties/lib/generators/rails/plugin/templates/init.rb b/railties/lib/rails/generators/rails/plugin/templates/init.rb
index 3c19a743c9..3c19a743c9 100644
--- a/railties/lib/generators/rails/plugin/templates/init.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/init.rb
diff --git a/railties/lib/generators/rails/plugin/templates/install.rb b/railties/lib/rails/generators/rails/plugin/templates/install.rb
index f7732d3796..f7732d3796 100644
--- a/railties/lib/generators/rails/plugin/templates/install.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/install.rb
diff --git a/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt
index d8d908a959..d8d908a959 100644
--- a/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt
diff --git a/railties/lib/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt
index 72920a9d3a..72920a9d3a 100644
--- a/railties/lib/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt
diff --git a/railties/lib/generators/rails/plugin/templates/uninstall.rb b/railties/lib/rails/generators/rails/plugin/templates/uninstall.rb
index 9738333463..9738333463 100644
--- a/railties/lib/generators/rails/plugin/templates/uninstall.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/uninstall.rb
diff --git a/railties/lib/generators/rails/resource/USAGE b/railties/lib/rails/generators/rails/resource/USAGE
index e359cd574f..e359cd574f 100644
--- a/railties/lib/generators/rails/resource/USAGE
+++ b/railties/lib/rails/generators/rails/resource/USAGE
diff --git a/railties/lib/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 5acb839f39..1e78945a7e 100644
--- a/railties/lib/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -1,5 +1,5 @@
require 'rails/generators/resource_helpers'
-require 'generators/rails/model/model_generator'
+require 'rails/generators/rails/model/model_generator'
module Rails
module Generators
@@ -16,6 +16,7 @@ module Rails
class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
def add_resource_route
+ return if options[:actions].present?
route "resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
end
diff --git a/railties/lib/generators/rails/scaffold/USAGE b/railties/lib/rails/generators/rails/scaffold/USAGE
index be1d113ed8..be1d113ed8 100644
--- a/railties/lib/generators/rails/scaffold/USAGE
+++ b/railties/lib/rails/generators/rails/scaffold/USAGE
diff --git a/railties/lib/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
index fdea5bf52b..779f933785 100644
--- a/railties/lib/generators/rails/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/rails/resource/resource_generator'
+require 'rails/generators/rails/resource/resource_generator'
module Rails
module Generators
diff --git a/railties/lib/generators/rails/scaffold_controller/USAGE b/railties/lib/rails/generators/rails/scaffold_controller/USAGE
index 673f69bc81..673f69bc81 100644
--- a/railties/lib/generators/rails/scaffold_controller/USAGE
+++ b/railties/lib/rails/generators/rails/scaffold_controller/USAGE
diff --git a/railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
index 49af2974cd..49af2974cd 100644
--- a/railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
diff --git a/railties/lib/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index 874e96a2b4..bbdce669dc 100644
--- a/railties/lib/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -46,7 +46,7 @@ class <%= controller_class_name %>Controller < ApplicationController
respond_to do |format|
if @<%= orm_instance.save %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= class_name %> was successfully created.') }
+ format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully created.') }
format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
else
format.html { render :action => "new" }
@@ -62,7 +62,7 @@ class <%= controller_class_name %>Controller < ApplicationController
respond_to do |format|
if @<%= orm_instance.update_attributes("params[:#{file_name}]") %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= class_name %> was successfully updated.') }
+ format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
diff --git a/railties/lib/generators/rails/session_migration/USAGE b/railties/lib/rails/generators/rails/session_migration/USAGE
index 564d1ffd78..564d1ffd78 100644
--- a/railties/lib/generators/rails/session_migration/USAGE
+++ b/railties/lib/rails/generators/rails/session_migration/USAGE
diff --git a/railties/lib/generators/rails/session_migration/session_migration_generator.rb b/railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb
index 258cc5b4a0..258cc5b4a0 100644
--- a/railties/lib/generators/rails/session_migration/session_migration_generator.rb
+++ b/railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb
diff --git a/railties/lib/generators/rails/stylesheets/USAGE b/railties/lib/rails/generators/rails/stylesheets/USAGE
index 59e5495d0b..59e5495d0b 100644
--- a/railties/lib/generators/rails/stylesheets/USAGE
+++ b/railties/lib/rails/generators/rails/stylesheets/USAGE
diff --git a/railties/lib/generators/rails/stylesheets/stylesheets_generator.rb b/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb
index ce68443c39..ce68443c39 100644
--- a/railties/lib/generators/rails/stylesheets/stylesheets_generator.rb
+++ b/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb
diff --git a/railties/lib/generators/rails/stylesheets/templates/scaffold.css b/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css
index ea3dc9b8b5..ea3dc9b8b5 100644
--- a/railties/lib/generators/rails/stylesheets/templates/scaffold.css
+++ b/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css
diff --git a/railties/lib/generators/test_unit.rb b/railties/lib/rails/generators/test_unit.rb
index 62b9afaa2c..62b9afaa2c 100644
--- a/railties/lib/generators/test_unit.rb
+++ b/railties/lib/rails/generators/test_unit.rb
diff --git a/railties/lib/generators/test_unit/controller/controller_generator.rb b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb
index b57a6e794f..20f3bd8965 100644
--- a/railties/lib/generators/test_unit/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb
@@ -1,8 +1,9 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
class ControllerGenerator < Base
+ argument :actions, :type => :array, :default => [], :banner => "action action"
check_class_collision :suffix => "ControllerTest"
def create_test_files
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
new file mode 100644
index 0000000000..0d4185846d
--- /dev/null
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
@@ -0,0 +1,18 @@
+require 'test_helper'
+
+class <%= class_name %>ControllerTest < ActionController::TestCase
+<% if actions.empty? -%>
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+<% else -%>
+<% for action in actions -%>
+ test "should get <%= action %>" do
+ get :<%= action %>
+ assert_response :success
+ end
+
+<% end -%>
+<% end -%>
+end
diff --git a/railties/lib/generators/test_unit/helper/helper_generator.rb b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb
index 9ecfaa45ab..4ea80bf7be 100644
--- a/railties/lib/generators/test_unit/helper/helper_generator.rb
+++ b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/helper/templates/helper_test.rb b/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb
index 591e40900e..591e40900e 100644
--- a/railties/lib/generators/test_unit/helper/templates/helper_test.rb
+++ b/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb
diff --git a/railties/lib/generators/test_unit/integration/integration_generator.rb b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb
index d9d9b3bf1d..32d0fac029 100644
--- a/railties/lib/generators/test_unit/integration/integration_generator.rb
+++ b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/integration/templates/integration_test.rb b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
index 2c57158b1c..2c57158b1c 100644
--- a/railties/lib/generators/test_unit/integration/templates/integration_test.rb
+++ b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
diff --git a/railties/lib/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
index a0d73db1b0..1a49286d41 100644
--- a/railties/lib/generators/test_unit/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
@@ -9,13 +9,6 @@ module TestUnit
def create_test_files
template "functional_test.rb", File.join('test/functional', class_path, "#{file_name}_test.rb")
end
-
- def create_fixtures_files
- actions.each do |action|
- @action, @path = action, File.join(file_path, action)
- template "fixture", File.join("test/fixtures", @path)
- end
- end
end
end
end
diff --git a/railties/lib/generators/test_unit/mailer/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
index a2b1f1ed05..80ac7f0feb 100644
--- a/railties/lib/generators/test_unit/mailer/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
@@ -3,12 +3,11 @@ require 'test_helper'
class <%= class_name %>Test < ActionMailer::TestCase
<% for action in actions -%>
test "<%= action %>" do
- @expected.subject = <%= action.to_s.humanize.inspect %>
- @expected.to = "to@example.org"
- @expected.from = "from@example.com"
- @expected.body = read_fixture("<%= action %>")
-
- assert_equal @expected, <%= class_name %>.<%= action %>
+ mail = <%= class_name %>.<%= action %>
+ assert_equal <%= action.to_s.humanize.inspect %>, mail.subject
+ assert_equal ["to@example.org"], mail.to
+ assert_equal ["from@example.com"], mail.from
+ assert_match "Hi", mail.body.encoded
end
<% end -%>
diff --git a/railties/lib/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb
index 469306e6c5..609b815683 100644
--- a/railties/lib/generators/test_unit/model/model_generator.rb
+++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
index a30132bc99..a30132bc99 100644
--- a/railties/lib/generators/test_unit/model/templates/fixtures.yml
+++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
diff --git a/railties/lib/generators/test_unit/model/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
index 3e0bc29d3a..3e0bc29d3a 100644
--- a/railties/lib/generators/test_unit/model/templates/unit_test.rb
+++ b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
diff --git a/railties/lib/generators/test_unit/observer/observer_generator.rb b/railties/lib/rails/generators/test_unit/observer/observer_generator.rb
index 14181f4e49..6cc1158c21 100644
--- a/railties/lib/generators/test_unit/observer/observer_generator.rb
+++ b/railties/lib/rails/generators/test_unit/observer/observer_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/observer/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb
index 03f6d5666e..03f6d5666e 100644
--- a/railties/lib/generators/test_unit/observer/templates/unit_test.rb
+++ b/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb
diff --git a/railties/lib/generators/test_unit/performance/performance_generator.rb b/railties/lib/rails/generators/test_unit/performance/performance_generator.rb
index 0d9c646b26..99edda5461 100644
--- a/railties/lib/generators/test_unit/performance/performance_generator.rb
+++ b/railties/lib/rails/generators/test_unit/performance/performance_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/performance/templates/performance_test.rb b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
index 362e3dc09f..362e3dc09f 100644
--- a/railties/lib/generators/test_unit/performance/templates/performance_test.rb
+++ b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
diff --git a/railties/lib/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb
index 05adf58c4f..4d65cd7d89 100644
--- a/railties/lib/generators/test_unit/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
module TestUnit
module Generators
diff --git a/railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt b/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
index 3e0bc29d3a..3e0bc29d3a 100644
--- a/railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
+++ b/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
diff --git a/railties/lib/generators/test_unit/plugin/templates/test_helper.rb b/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb
index 2ca36a1e44..2ca36a1e44 100644
--- a/railties/lib/generators/test_unit/plugin/templates/test_helper.rb
+++ b/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb
diff --git a/railties/lib/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index a95916ae13..c0315c7fe6 100644
--- a/railties/lib/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/test_unit'
+require 'rails/generators/test_unit'
require 'rails/generators/resource_helpers'
module TestUnit
diff --git a/railties/lib/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 9380aa49b6..4f8ddbffcf 100644
--- a/railties/lib/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -1,6 +1,10 @@
require 'test_helper'
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
+ setup do
+ @<%= file_name %> = <%= table_name %>(:one)
+ end
+
<% unless options[:singleton] -%>
test "should get index" do
get :index
@@ -16,30 +20,30 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
test "should create <%= file_name %>" do
assert_difference('<%= class_name %>.count') do
- post :create, :<%= file_name %> => <%= table_name %>(:one).attributes
+ post :create, :<%= file_name %> => @<%= file_name %>.attributes
end
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
end
test "should show <%= file_name %>" do
- get :show, :id => <%= table_name %>(:one).to_param
+ get :show, :id => @<%= file_name %>.to_param
assert_response :success
end
test "should get edit" do
- get :edit, :id => <%= table_name %>(:one).to_param
+ get :edit, :id => @<%= file_name %>.to_param
assert_response :success
end
test "should update <%= file_name %>" do
- put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => <%= table_name %>(:one).attributes
+ put :update, :id => @<%= file_name %>.to_param, :<%= file_name %> => @<%= file_name %>.attributes
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
end
test "should destroy <%= file_name %>" do
assert_difference('<%= class_name %>.count', -1) do
- delete :destroy, :id => <%= table_name %>(:one).to_param
+ delete :destroy, :id => @<%= file_name %>.to_param
end
assert_redirected_to <%= table_name %>_path
diff --git a/railties/builtin/rails_info/rails/info.rb b/railties/lib/rails/info.rb
index 5a496f6536..5a496f6536 100644
--- a/railties/builtin/rails_info/rails/info.rb
+++ b/railties/lib/rails/info.rb
diff --git a/railties/builtin/rails_info/rails/info_controller.rb b/railties/lib/rails/info_controller.rb
index 196eeb4a6c..196eeb4a6c 100644
--- a/railties/builtin/rails_info/rails/info_controller.rb
+++ b/railties/lib/rails/info_controller.rb
diff --git a/railties/builtin/routes.rb b/railties/lib/rails/info_routes.rb
index bd58034d8f..bd58034d8f 100644
--- a/railties/builtin/routes.rb
+++ b/railties/lib/rails/info_routes.rb
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index 96a07844e5..0d68abb323 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -179,7 +179,7 @@ module Rails
include Initializable
- ABSTRACT_RAILTIES = %w(Rails::Plugin Rails::Engine Rails::Application)
+ ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Plugin Rails::Engine Rails::Application)
class << self
def subclasses
@@ -187,23 +187,18 @@ module Rails
end
def inherited(base)
- unless abstract_railtie?(base)
+ unless base.abstract_railtie?
base.send(:include, self::Configurable)
subclasses << base
end
end
- def railtie_name(railtie_name = nil)
- @railtie_name = railtie_name if railtie_name
- @railtie_name ||= default_name
+ def railtie_name(*)
+ ActiveSupport::Deprecation.warn "railtie_name is deprecated and has no effect", caller
end
- def railtie_names
- subclasses.map { |p| p.railtie_name }
- end
-
- def log_subscriber(log_subscriber)
- Rails::LogSubscriber.add(railtie_name, log_subscriber)
+ def log_subscriber(name, log_subscriber)
+ Rails::LogSubscriber.add(name, log_subscriber)
end
def rake_tasks(&blk)
@@ -218,14 +213,8 @@ module Rails
@generators
end
- protected
-
- def abstract_railtie?(base)
- ABSTRACT_RAILTIES.include?(base.name)
- end
-
- def default_name
- ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(name))
+ def abstract_railtie?
+ ABSTRACT_RAILTIES.include?(name)
end
end
diff --git a/railties/lib/rails/railtie/configuration.rb b/railties/lib/rails/railtie/configuration.rb
index 828ccec3d0..16eccaccc4 100644
--- a/railties/lib/rails/railtie/configuration.rb
+++ b/railties/lib/rails/railtie/configuration.rb
@@ -3,11 +3,8 @@ require 'rails/configuration'
module Rails
class Railtie
class Configuration
- attr_accessor :cookie_secret
-
def initialize
- @session_store = :cookie_store
- @session_options = {}
+ @@options ||= {}
end
# Holds generators configuration:
@@ -48,76 +45,18 @@ module Rails
end
def respond_to?(name)
- super || name.to_s =~ config_key_regexp
- end
-
- def metal_loader
- @metal_loader ||= Rails::Application::MetalLoader.new
- end
-
- def session_store(*args)
- if args.empty?
- case @session_store
- when :disabled
- nil
- when :active_record_store
- ActiveRecord::SessionStore
- when Symbol
- ActionDispatch::Session.const_get(@session_store.to_s.camelize)
- else
- @session_store
- end
- else
- @session_store = args.shift
- @session_options = args.shift || {}
- end
+ super || @@options.key?(name.to_sym)
end
private
def method_missing(name, *args, &blk)
- if name.to_s =~ config_key_regexp
- return $2 == '=' ? options[$1] = args.first : options[$1]
- end
- super
- end
-
- def session_options
- return @session_options unless @session_store == :cookie_store
- @session_options.merge(:secret => @cookie_secret)
- end
-
- def config_key_regexp
- bits = config_keys.map { |n| Regexp.escape(n.to_s) }.join('|')
- /^(#{bits})(?:=)?$/
- end
-
- def config_keys
- (Railtie.railtie_names + Engine.engine_names).map { |n| n.to_s }.uniq
- end
-
- def options
- @@options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }
- end
-
- def default_middleware
- require 'action_dispatch'
- ActionDispatch::MiddlewareStack.new.tap do |middleware|
- middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { serve_static_assets })
- middleware.use('::Rack::Lock', :if => lambda { !allow_concurrency })
- middleware.use('::Rack::Runtime')
- middleware.use('::Rails::Rack::Logger')
- middleware.use('::ActionDispatch::ShowExceptions', lambda { consider_all_requests_local })
- middleware.use("::ActionDispatch::RemoteIp", lambda { action_dispatch.ip_spoofing_check }, lambda { action_dispatch.trusted_proxies })
- middleware.use('::Rack::Sendfile', lambda { action_dispatch.x_sendfile_header })
- middleware.use('::ActionDispatch::Callbacks', lambda { !cache_classes })
- middleware.use('::ActionDispatch::Cookies')
- middleware.use(lambda { session_store }, lambda { session_options })
- middleware.use('::ActionDispatch::Flash', :if => lambda { session_store })
- middleware.use(lambda { metal_loader.build_middleware(metals) }, :if => lambda { metal_loader.metals.any? })
- middleware.use('ActionDispatch::ParamsParser')
- middleware.use('::Rack::MethodOverride')
- middleware.use('::ActionDispatch::Head')
+ if name.to_s =~ /=$/
+ @@options[$`.to_sym] = args.first
+ elsif @@options.key?(name)
+ @@options[name]
+ else
+ super
end
end
end
diff --git a/railties/lib/rails/railties_path.rb b/railties/lib/rails/railties_path.rb
deleted file mode 100644
index e291fc23ea..0000000000
--- a/railties/lib/rails/railties_path.rb
+++ /dev/null
@@ -1 +0,0 @@
-RAILTIES_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake
index abf9b33ae5..f2fee45594 100644
--- a/railties/lib/rails/tasks/documentation.rake
+++ b/railties/lib/rails/tasks/documentation.rake
@@ -66,13 +66,14 @@ namespace :doc do
task :plugins => plugins.collect { |plugin| "doc:plugins:#{plugin}" }
desc "Remove plugin documentation"
- task :clobber_plugins do
+ task :clobber_plugins do
rm_rf 'doc/plugins' rescue nil
end
desc "Generate Rails guides"
task :guides do
- require File.join(RAILTIES_PATH, "guides/rails_guides")
+ # FIXME: Reaching outside lib directory is a bad idea
+ require File.expand_path('../../../../guides/rails_guides', __FILE__)
RailsGuides::Generator.new(Rails.root.join("doc/guides")).generate
end
@@ -92,7 +93,7 @@ namespace :doc do
files.include("#{plugin_base}/lib/**/*.rb")
if File.exist?("#{plugin_base}/README")
- files.include("#{plugin_base}/README")
+ files.include("#{plugin_base}/README")
options << "--main '#{plugin_base}/README'"
end
files.include("#{plugin_base}/CHANGELOG") if File.exist?("#{plugin_base}/CHANGELOG")
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index dbe2ac54ed..738f7f5301 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -2,18 +2,18 @@ namespace :rails do
namespace :freeze do
desc "The rails:freeze:gems is deprecated, please use bundle install instead"
task :gems do
- puts "The rails:freeze:gems is deprecated, please use bundle install instead"
+ abort "The rails:freeze:gems is deprecated, please use bundle install instead"
end
desc 'The freeze:edge command has been deprecated, specify the path setting in your app Gemfile instead and bundle install'
task :edge do
- puts 'The freeze:edge command has been deprecated, specify the path setting in your app Gemfile instead and bundle install'
+ abort 'The freeze:edge command has been deprecated, specify the path setting in your app Gemfile instead and bundle install'
end
end
desc 'The unfreeze command has been deprecated, please use bundler commands instead'
task :unfreeze do
- puts 'The unfreeze command has been deprecated, please use bundler commands instead'
+ abort 'The unfreeze command has been deprecated, please use bundler commands instead'
end
desc "Update both configs, scripts and public/javascripts from Rails"
@@ -25,7 +25,7 @@ namespace :rails do
template = File.expand_path(template) if template !~ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}
require 'rails/generators'
- require 'generators/rails/app/app_generator'
+ require 'rails/generators/rails/app/app_generator'
generator = Rails::Generators::AppGenerator.new [ Rails.root ], {}, :destination_root => Rails.root
generator.apply template, :verbose => false
end
@@ -38,10 +38,11 @@ namespace :rails do
def app_generator
@app_generator ||= begin
require 'rails/generators'
- require 'generators/rails/app/app_generator'
+ require 'rails/generators/rails/app/app_generator'
gen = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true },
:destination_root => Rails.root
- gen.send(:valid_app_const?)
+ File.exists?(Rails.root.join("config", "application.rb")) ?
+ gen.send(:app_const) : gen.send(:valid_app_const?)
gen
end
end
diff --git a/railties/lib/rails/tasks/misc.rake b/railties/lib/rails/tasks/misc.rake
index 48fce92215..0926707a04 100644
--- a/railties/lib/rails/tasks/misc.rake
+++ b/railties/lib/rails/tasks/misc.rake
@@ -15,8 +15,6 @@ end
desc 'Explain the current environment'
task :about do
- $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
- require 'rails/info'
puts Rails::Info
end
@@ -26,12 +24,12 @@ namespace :time do
task :all do
build_time_zone_list(:all)
end
-
+
desc 'Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset. Results can be filtered with optional OFFSET parameter, e.g., OFFSET=-6'
task :us do
build_time_zone_list(:us_zones)
end
-
+
desc 'Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time'
task :local do
require 'active_support'
@@ -41,7 +39,7 @@ namespace :time do
offset = jan_offset < jul_offset ? jan_offset : jul_offset
build_time_zone_list(:all, offset)
end
-
+
# to find UTC -06:00 zones, OFFSET can be set to either -6, -6:00 or 21600
def build_time_zone_list(method, offset = ENV['OFFSET'])
require 'active_support'
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index 2ed5353755..6522c94ad6 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -4,14 +4,18 @@ abort("Abort testing: Your Rails environment is not running in test mode!") unle
require 'test/unit'
require 'active_support/core_ext/kernel/requires'
+require 'active_support/test_case'
+require 'action_controller/test_case'
+require 'action_dispatch/testing/integration'
-# TODO: Figure out how to get the Rails::BacktraceFilter into minitest/unit
if defined?(Test::Unit::Util::BacktraceFilter) && ENV['BACKTRACE'].nil?
require 'rails/backtrace_cleaner'
Test::Unit::Util::BacktraceFilter.module_eval { include Rails::BacktraceFilterForTestUnit }
end
if defined?(ActiveRecord)
+ require 'active_record/test_case'
+
class ActiveSupport::TestCase
include ActiveRecord::TestFixtures
self.fixture_path = "#{Rails.root}/test/fixtures/"
diff --git a/railties/lib/rails/test_unit/railtie.rb b/railties/lib/rails/test_unit/railtie.rb
index d99325a6d8..e3fafc4b9d 100644
--- a/railties/lib/rails/test_unit/railtie.rb
+++ b/railties/lib/rails/test_unit/railtie.rb
@@ -1,7 +1,5 @@
module Rails
class TestUnitRailtie < Rails::Railtie
- railtie_name :test_unit
-
config.generators do |c|
c.test_framework :test_unit, :fixture => true,
:fixture_replacement => nil
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index b9d2739539..aea07efe96 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.homepage = 'http://www.rubyonrails.org'
s.rubyforge_project = 'rails'
- s.files = Dir['CHANGELOG', 'README', 'bin/**/*', 'builtin/**/*', 'guides/**/*', 'lib/**/{*,.[a-z]*}']
+ s.files = Dir['CHANGELOG', 'README', 'bin/**/*', 'guides/**/*', 'lib/**/{*,.[a-z]*}']
s.require_path = 'lib'
s.bindir = 'bin'
s.executables = ['rails']
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index aa66dbb9be..d04a2aa1f3 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -1,7 +1,6 @@
ORIG_ARGV = ARGV.dup
require File.expand_path("../../../load_paths", __FILE__)
-$:.unshift File.expand_path("../../builtin/rails_info", __FILE__)
require 'stringio'
require 'test/unit'
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 54cd751f4e..68ca2acaad 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -140,7 +140,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
end
end
-
+
test "filter_parameters should be able to set via config.filter_parameters" do
add_to_config <<-RUBY
config.filter_parameters += [ :foo, 'bar', lambda { |key, value|
@@ -172,16 +172,27 @@ module ApplicationTests
assert $prepared
end
- test "config.action_dispatch.x_sendfile_header defaults to X-Sendfile" do
+ def make_basic_app
require "rails"
require "action_controller/railtie"
- class MyApp < Rails::Application
- config.cookie_secret = "3b7cd727ee24e8444053437c36cc66c4"
- config.session_store :cookie_store, :key => "_myapp_session"
+ app = Class.new(Rails::Application)
+
+ yield app if block_given?
+
+ app.config.session_store :disabled
+ app.initialize!
+
+ app.routes.draw do
+ match "/" => "omg#index"
end
- MyApp.initialize!
+ require 'rack/test'
+ extend Rack::Test::Methods
+ end
+
+ test "config.action_dispatch.x_sendfile_header defaults to ''" do
+ make_basic_app
class ::OmgController < ActionController::Base
def index
@@ -189,44 +200,53 @@ module ApplicationTests
end
end
- MyApp.routes.draw do
- match "/" => "omg#index"
+ get "/"
+ assert_equal File.read(__FILE__), last_response.body
+ end
+
+ test "config.action_dispatch.x_sendfile_header can be set" do
+ make_basic_app do |app|
+ app.config.action_dispatch.x_sendfile_header = "X-Sendfile"
end
- require 'rack/test'
- extend Rack::Test::Methods
+ class ::OmgController < ActionController::Base
+ def index
+ send_file __FILE__
+ end
+ end
get "/"
assert_equal File.expand_path(__FILE__), last_response.headers["X-Sendfile"]
end
test "config.action_dispatch.x_sendfile_header is sent to Rack::Sendfile" do
- require "rails"
- require "action_controller/railtie"
-
- class MyApp < Rails::Application
- config.cookie_secret = "3b7cd727ee24e8444053437c36cc66c4"
- config.session_store :cookie_store, :key => "_myapp_session"
- config.action_dispatch.x_sendfile_header = 'X-Lighttpd-Send-File'
+ make_basic_app do |app|
+ app.config.action_dispatch.x_sendfile_header = 'X-Lighttpd-Send-File'
end
- MyApp.initialize!
-
class ::OmgController < ActionController::Base
def index
send_file __FILE__
end
end
- MyApp.routes.draw do
- match "/" => "omg#index"
- end
+ get "/"
+ assert_equal File.expand_path(__FILE__), last_response.headers["X-Lighttpd-Send-File"]
+ end
- require 'rack/test'
- extend Rack::Test::Methods
+ test "protect from forgery is the default in a new app" do
+ make_basic_app
+
+ class ::OmgController < ActionController::Base
+ protect_from_forgery
+
+ def index
+ render :inline => "<%= csrf_meta_tag %>"
+ end
+ end
get "/"
- assert_equal File.expand_path(__FILE__), last_response.headers["X-Lighttpd-Send-File"]
+ assert last_response.body =~ /csrf\-param/
end
end
end
diff --git a/railties/test/application/paths_test.rb b/railties/test/application/paths_test.rb
index 511b8b629a..589e515d05 100644
--- a/railties/test/application/paths_test.rb
+++ b/railties/test/application/paths_test.rb
@@ -51,8 +51,6 @@ module ApplicationTests
assert_path @paths.config.environment, "config", "environments", "development.rb"
assert_equal root("app", "controllers"), @paths.app.controllers.to_a.first
- assert_equal Pathname.new(File.dirname(__FILE__)).join("..", "..", "builtin", "rails_info").expand_path,
- Pathname.new(@paths.app.controllers.to_a[1]).expand_path
end
test "booting up Rails yields a list of paths that are eager" do
@@ -80,21 +78,5 @@ module ApplicationTests
assert_not_in_load_path "tmp"
assert_not_in_load_path "tmp", "cache"
end
-
- test "controller paths include builtin in development mode" do
- Rails.env.replace "development"
- assert Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
- end
-
- test "controller paths does not have builtin_directories in test mode" do
- Rails.env.replace "test"
- assert !Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
- end
-
- test "controller paths does not have builtin_directories in production mode" do
- Rails.env.replace "production"
- assert !Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
- end
-
end
end
diff --git a/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb b/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb
index 7a4edb8bcb..a7d079a1bc 100644
--- a/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb
+++ b/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/railties/test/fixtures/lib/rails_generators/foobar/foobar_generator.rb b/railties/test/fixtures/lib/rails/generators/foobar/foobar_generator.rb
index d1de8c56fa..d1de8c56fa 100644
--- a/railties/test/fixtures/lib/rails_generators/foobar/foobar_generator.rb
+++ b/railties/test/fixtures/lib/rails/generators/foobar/foobar_generator.rb
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 3585e6e7c0..44e0640552 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -1,8 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/app/app_generator'
-
-# TODO This line shouldn't be required
-require 'generators/rails/model/model_generator'
+require 'rails/generators/rails/app/app_generator'
class ActionsTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 4fc26563ff..95ca2acf2c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
require 'generators/generators_test_helper'
-require 'generators/rails/app/app_generator'
+require 'rails/generators/rails/app/app_generator'
class AppGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index 79a4e5bf17..be99dc068d 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -1,10 +1,12 @@
require 'generators/generators_test_helper'
-require 'generators/rails/controller/controller_generator'
+require 'rails/generators/rails/controller/controller_generator'
class ControllerGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments %w(Account foo bar)
+ setup :copy_routes
+
def test_help_does_not_show_invoked_generators_options_if_they_already_exist
content = run_generator ["--help"]
assert_no_match /Helper options\:/, content
@@ -23,8 +25,6 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
Object.send :remove_const, :ObjectController
end
- # No need to spec content since it's already spec'ed on helper generator.
- #
def test_invokes_helper
run_generator
assert_file "app/helpers/account_helper.rb"
@@ -49,8 +49,13 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_invokes_default_template_engine
run_generator
- assert_file "app/views/account/foo.html.erb", /app\/views\/account\/foo/
- assert_file "app/views/account/bar.html.erb", /app\/views\/account\/bar/
+ assert_file "app/views/account/foo.html.erb", %r(app/views/account/foo\.html\.erb)
+ assert_file "app/views/account/bar.html.erb", %r(app/views/account/bar\.html\.erb)
+ end
+
+ def test_add_routes
+ run_generator
+ assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/
end
def test_invokes_default_template_engine_even_with_no_action
diff --git a/railties/test/generators/generator_generator_test.rb b/railties/test/generators/generator_generator_test.rb
index f3fd688e4f..26f975a191 100644
--- a/railties/test/generators/generator_generator_test.rb
+++ b/railties/test/generators/generator_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/generator/generator_generator'
+require 'rails/generators/rails/generator/generator_generator'
class GeneratorGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 32be99b144..d8bdb344f2 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -26,4 +26,11 @@ module GeneratorsTestHelper
end
end
end
+
+ def copy_routes
+ routes = File.expand_path("../../../lib/rails/generators/rails/app/templates/config/routes.rb", __FILE__)
+ destination = File.join(destination_root, "config")
+ FileUtils.mkdir_p(destination)
+ FileUtils.cp File.expand_path(routes), destination
+ end
end \ No newline at end of file
diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb
index 6d7168738e..f0bfebd57f 100644
--- a/railties/test/generators/helper_generator_test.rb
+++ b/railties/test/generators/helper_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/helper/helper_generator'
+require 'rails/generators/rails/helper/helper_generator'
ObjectHelper = Class.new
AnotherObjectHelperTest = Class.new
diff --git a/railties/test/generators/integration_test_generator_test.rb b/railties/test/generators/integration_test_generator_test.rb
index d7fc324c88..cf282a0911 100644
--- a/railties/test/generators/integration_test_generator_test.rb
+++ b/railties/test/generators/integration_test_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/integration_test/integration_test_generator'
+require 'rails/generators/rails/integration_test/integration_test_generator'
class IntegrationTestGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
index e6fc1bbb5c..81d6afa221 100644
--- a/railties/test/generators/mailer_generator_test.rb
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/mailer/mailer_generator'
+require 'rails/generators/rails/mailer/mailer_generator'
class MailerGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -28,20 +28,22 @@ class MailerGeneratorTest < Rails::Generators::TestCase
def test_invokes_default_test_framework
run_generator
- assert_file "test/functional/notifier_test.rb", /class NotifierTest < ActionMailer::TestCase/
- assert_file "test/fixtures/notifier/foo", /app\/views\/notifier\/foo/
- assert_file "test/fixtures/notifier/bar", /app\/views\/notifier\/bar/
+ assert_file "test/functional/notifier_test.rb" do |test|
+ assert_match /class NotifierTest < ActionMailer::TestCase/, test
+ assert_match /test "foo"/, test
+ assert_match /test "bar"/, test
+ end
end
def test_invokes_default_template_engine
run_generator
assert_file "app/views/notifier/foo.text.erb" do |view|
- assert_match /app\/views\/notifier\/foo/, view
+ assert_match %r(app/views/notifier/foo\.text\.erb), view
assert_match /<%= @greeting %>/, view
end
assert_file "app/views/notifier/bar.text.erb" do |view|
- assert_match /app\/views\/notifier\/bar/, view
+ assert_match %r(app/views/notifier/bar\.text\.erb), view
assert_match /<%= @greeting %>/, view
end
end
diff --git a/railties/test/generators/metal_generator_test.rb b/railties/test/generators/metal_generator_test.rb
index e3a2384885..615122c882 100644
--- a/railties/test/generators/metal_generator_test.rb
+++ b/railties/test/generators/metal_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/metal/metal_generator'
+require 'rails/generators/rails/metal/metal_generator'
class MetalGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index 811a712fd5..762f84d579 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/migration/migration_generator'
+require 'rails/generators/rails/migration/migration_generator'
class MigrationGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 79ce9a2a7b..f5cfd8eeca 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/model/model_generator'
+require 'rails/generators/rails/model/model_generator'
class ModelGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb
index f327fb1282..e73dd237fb 100644
--- a/railties/test/generators/named_base_test.rb
+++ b/railties/test/generators/named_base_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/scaffold_controller/scaffold_controller_generator'
+require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
# Mock out what we need from AR::Base.
module ActiveRecord
@@ -15,6 +15,20 @@ class NamedBaseTest < Rails::Generators::TestCase
include GeneratorsTestHelper
tests Rails::Generators::ScaffoldControllerGenerator
+ def test_named_generator_with_underscore
+ g = generator ['line_item']
+ assert_name g, 'line_item', :name
+ assert_name g, %w(), :class_path
+ assert_name g, 'LineItem', :class_name
+ assert_name g, 'line_item', :file_path
+ assert_name g, 'line_item', :file_name
+ assert_name g, 'Line item', :human_name
+ assert_name g, 'line_item', :singular_name
+ assert_name g, 'line_items', :plural_name
+ assert_name g, 'line_item', :i18n_scope
+ assert_name g, 'line_items', :table_name
+ end
+
def test_named_generator_attributes
g = generator ['admin/foo']
assert_name g, 'admin/foo', :name
@@ -22,6 +36,7 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, 'Admin::Foo', :class_name
assert_name g, 'admin/foo', :file_path
assert_name g, 'foo', :file_name
+ assert_name g, 'Foo', :human_name
assert_name g, 'foo', :singular_name
assert_name g, 'foos', :plural_name
assert_name g, 'admin.foo', :i18n_scope
@@ -36,6 +51,7 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, 'admin/foo', :file_path
assert_name g, 'foo', :file_name
assert_name g, 'foo', :singular_name
+ assert_name g, 'Foo', :human_name
assert_name g, 'foos', :plural_name
assert_name g, 'admin.foo', :i18n_scope
assert_name g, 'admin_foos', :table_name
@@ -45,6 +61,8 @@ class NamedBaseTest < Rails::Generators::TestCase
ActiveRecord::Base.pluralize_table_names = false
g = generator ['admin/foo']
assert_name g, 'admin_foo', :table_name
+ ensure
+ ActiveRecord::Base.pluralize_table_names = true
end
def test_scaffold_plural_names
diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb
index 058a19228d..45fe8dfbd3 100644
--- a/railties/test/generators/observer_generator_test.rb
+++ b/railties/test/generators/observer_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/observer/observer_generator'
+require 'rails/generators/rails/observer/observer_generator'
class ObserverGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/performance_test_generator_test.rb b/railties/test/generators/performance_test_generator_test.rb
index c95063a127..8fda83b36f 100644
--- a/railties/test/generators/performance_test_generator_test.rb
+++ b/railties/test/generators/performance_test_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/performance_test/performance_test_generator'
+require 'rails/generators/rails/performance_test/performance_test_generator'
class PerformanceTestGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index 065dbe1423..c1f646f7c1 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/plugin/plugin_generator'
+require 'rails/generators/rails/plugin/plugin_generator'
class PluginGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 959934bd71..96fd7a0a72 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -1,19 +1,11 @@
require 'generators/generators_test_helper'
-require 'generators/rails/resource/resource_generator'
+require 'rails/generators/rails/resource/resource_generator'
class ResourceGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments %w(account)
- def setup
- super
- routes = Rails::Generators::ResourceGenerator.source_root
- routes = File.join(routes, "..", "..", "app", "templates", "config", "routes.rb")
- destination = File.join(destination_root, "config")
-
- FileUtils.mkdir_p(destination)
- FileUtils.cp File.expand_path(routes), destination
- end
+ setup :copy_routes
def test_help_with_inherited_options
content = run_generator ["--help"]
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index f971598d18..77ed63b1bb 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/scaffold_controller/scaffold_controller_generator'
+require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
module Unknown
module Generators
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index a7e9c8a231..6cf2efca45 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -1,19 +1,11 @@
require 'generators/generators_test_helper'
-require 'generators/rails/scaffold/scaffold_generator'
+require 'rails/generators/rails/scaffold/scaffold_generator'
class ScaffoldGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments %w(product_line title:string price:integer)
- def setup
- super
- routes = Rails::Generators::ResourceGenerator.source_root
- routes = File.join(routes, "..", "..", "app", "templates", "config", "routes.rb")
- destination = File.join(destination_root, "config")
-
- FileUtils.mkdir_p(destination)
- FileUtils.cp File.expand_path(routes), destination
- end
+ setup :copy_routes
def test_scaffold_on_invoke
run_generator
diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb
index de28b4c75b..9fee948d7c 100644
--- a/railties/test/generators/session_migration_generator_test.rb
+++ b/railties/test/generators/session_migration_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/session_migration/session_migration_generator'
+require 'rails/generators/rails/session_migration/session_migration_generator'
class SessionMigrationGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/stylesheets_generator_test.rb b/railties/test/generators/stylesheets_generator_test.rb
index 718fcb1fa7..aaeb686daa 100644
--- a/railties/test/generators/stylesheets_generator_test.rb
+++ b/railties/test/generators/stylesheets_generator_test.rb
@@ -1,5 +1,5 @@
require 'generators/generators_test_helper'
-require 'generators/rails/stylesheets/stylesheets_generator'
+require 'rails/generators/rails/stylesheets/stylesheets_generator'
class StylesheetsGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 2975e3e3ef..16f8f43b99 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -1,6 +1,6 @@
require 'generators/generators_test_helper'
-require 'generators/rails/model/model_generator'
-require 'generators/test_unit/model/model_generator'
+require 'rails/generators/rails/model/model_generator'
+require 'rails/generators/test_unit/model/model_generator'
require 'mocha'
class GeneratorsTest < Rails::Generators::TestCase
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index d904d7b461..05ec359f61 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -1,9 +1,6 @@
require 'abstract_unit'
require 'action_controller'
-require 'rails/info'
-require 'rails/info_controller'
-
module ActionController
class Base
include ActionController::Testing
diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb
index 9fefb285b4..546bf5e143 100644
--- a/railties/test/railties/railtie_test.rb
+++ b/railties/test/railties/railtie_test.rb
@@ -32,28 +32,25 @@ module RailtiesTest
end
test "config name is available for the railtie" do
- class Foo < Rails::Railtie ; config.foo.greetings = "hello" ; end
+ class Foo < Rails::Railtie
+ config.foo = ActiveSupport::OrderedOptions.new
+ config.foo.greetings = "hello"
+ end
assert_equal "hello", Foo.config.foo.greetings
end
test "railtie configurations are available in the application" do
- class Foo < Rails::Railtie ; config.foo.greetings = "hello" ; end
+ class Foo < Rails::Railtie
+ config.foo = ActiveSupport::OrderedOptions.new
+ config.foo.greetings = "hello"
+ end
require "#{app_path}/config/application"
assert_equal "hello", AppTemplate::Application.config.foo.greetings
end
- test "railtie config merges are deep" do
- class Foo < Rails::Railtie ; config.foo.greetings = 'hello' ; end
- class Bar < Rails::Railtie
- config.foo.bar = "bar"
- end
- assert_equal "hello", Bar.config.foo.greetings
- assert_equal "bar", Bar.config.foo.bar
- end
-
test "railtie can add log subscribers" do
begin
- class Foo < Rails::Railtie ; log_subscriber(Rails::LogSubscriber.new) ; end
+ class Foo < Rails::Railtie ; log_subscriber(:foo, Rails::LogSubscriber.new) ; end
assert_kind_of Rails::LogSubscriber, Rails::LogSubscriber.log_subscribers[0]
ensure
Rails::LogSubscriber.log_subscribers.clear