From 664552ac021ce4b366092adbb32dbce3a2fbce2a Mon Sep 17 00:00:00 2001
From: Jacques Distler
Date: Tue, 4 Aug 2009 10:16:03 -0500
Subject: [PATCH] Rails 2.3.3.1
Update to latest Rails.
A little bit of jiggery-pokery is involved, since they
neglected to re-include vendored Rack in this release.
---
test/functional/admin_controller_test.rb | 21 +-
test/functional/wiki_controller_test.rb | 46 +-
vendor/rails/actionmailer/CHANGELOG | 4 +
vendor/rails/actionmailer/Rakefile | 5 +-
.../actionmailer/lib/action_mailer/base.rb | 2 +-
.../actionmailer/lib/action_mailer/version.rb | 2 +-
.../rails/actionmailer/test/abstract_unit.rb | 3 -
vendor/rails/actionpack/CHANGELOG | 5 +
vendor/rails/actionpack/Rakefile | 6 +-
.../rails/actionpack/lib/action_controller.rb | 5 +-
.../assertions/response_assertions.rb | 14 +-
.../actionpack/lib/action_controller/base.rb | 9 +-
.../lib/action_controller/caching.rb | 2 +-
.../lib/action_controller/caching/actions.rb | 10 +-
.../lib/action_controller/caching/sweeper.rb | 45 ++
.../lib/action_controller/caching/sweeping.rb | 42 --
.../lib/action_controller/failsafe.rb | 46 +-
.../actionpack/lib/action_controller/flash.rb | 14 +-
.../action_controller/http_authentication.rb | 7 +-
.../lib/action_controller/integration.rb | 15 +-
.../lib/action_controller/middlewares.rb | 1 -
.../lib/action_controller/reloader.rb | 37 +-
.../lib/action_controller/request.rb | 8 +-
.../lib/action_controller/response.rb | 4 +-
.../lib/action_controller/rewindable_input.rb | 28 --
.../action_controller/routing/route_set.rb | 3 +-
.../lib/action_controller/streaming.rb | 2 +-
.../lib/action_controller/test_process.rb | 10 +-
.../vendor/rack-1.0/rack/reloader.rb | 64 ---
.../vendor/{rack-1.0 => rack-1.1.pre}/rack.rb | 7 +-
.../rack/adapter/camping.rb | 0
.../rack/auth/abstract/handler.rb | 0
.../rack/auth/abstract/request.rb | 0
.../rack/auth/basic.rb | 0
.../rack/auth/digest/md5.rb | 0
.../rack/auth/digest/nonce.rb | 0
.../rack/auth/digest/params.rb | 0
.../rack/auth/digest/request.rb | 0
.../rack/auth/openid.rb | 0
.../rack/builder.rb | 0
.../rack/cascade.rb | 0
.../rack/chunked.rb | 0
.../rack/commonlogger.rb | 0
.../rack/conditionalget.rb | 2 +
.../rack/content_length.rb | 0
.../rack/content_type.rb | 0
.../rack/deflater.rb | 71 +--
.../rack/directory.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/file.rb | 0
.../rack/handler.rb | 23 +-
.../rack/handler/cgi.rb | 2 +-
.../rack/handler/evented_mongrel.rb | 0
.../rack/handler/fastcgi.rb | 47 +-
.../rack/handler/lsws.rb | 2 +-
.../rack/handler/mongrel.rb | 4 +-
.../rack/handler/scgi.rb | 8 +-
.../rack/handler/swiftiplied_mongrel.rb | 0
.../rack/handler/thin.rb | 0
.../rack/handler/webrick.rb | 2 +-
.../{rack-1.0 => rack-1.1.pre}/rack/head.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/lint.rb | 127 ++++-
.../rack/lobster.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/lock.rb | 0
.../rack/methodoverride.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/mime.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/mock.rb | 30 +-
.../rack/recursive.rb | 0
.../vendor/rack-1.1.pre/rack/reloader.rb | 106 +++++
.../rack/request.rb | 37 +-
.../rack/response.rb | 6 +-
.../rack-1.1.pre/rack/rewindable_input.rb | 98 ++++
.../rack/session/abstract/id.rb | 0
.../rack/session/cookie.rb | 0
.../rack/session/memcache.rb | 0
.../rack/session/pool.rb | 0
.../rack/showexceptions.rb | 0
.../rack/showstatus.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/static.rb | 0
.../{rack-1.0 => rack-1.1.pre}/rack/urlmap.rb | 2 +-
.../{rack-1.0 => rack-1.1.pre}/rack/utils.rb | 158 +++++-
.../actionpack/lib/action_pack/version.rb | 2 +-
.../actionpack/lib/action_view/helpers.rb | 2 +-
.../action_view/helpers/asset_tag_helper.rb | 30 +-
.../lib/action_view/helpers/form_helper.rb | 37 +-
.../helpers/form_options_helper.rb | 2 +
.../action_view/helpers/form_tag_helper.rb | 14 +-
.../action_view/helpers/prototype_helper.rb | 14 +-
.../helpers/scriptaculous_helper.rb | 10 +-
.../lib/action_view/helpers/text_helper.rb | 6 +-
.../lib/action_view/helpers/url_helper.rb | 2 +-
.../rails/actionpack/lib/action_view/paths.rb | 2 +-
.../actionpack/lib/action_view/template.rb | 59 +--
vendor/rails/actionpack/test/abstract_unit.rb | 2 +-
.../activerecord/active_record_store_test.rb | 6 +-
.../controller/action_pack_assertions_test.rb | 27 ++
.../test/controller/caching_test.rb | 39 ++
.../actionpack/test/controller/cookie_test.rb | 10 +
.../test/controller/dispatcher_test.rb | 16 +-
.../test/controller/failsafe_test.rb | 60 +++
.../test/controller/filter_params_test.rb | 3 +-
.../actionpack/test/controller/flash_test.rb | 7 +-
.../http_digest_authentication_test.rb | 37 +-
.../test/controller/integration_test.rb | 28 ++
.../test/controller/redirect_test.rb | 5 +-
.../test/controller/reloader_test.rb | 97 ++++
.../actionpack/test/controller/render_test.rb | 28 +-
.../request/multipart_params_parsing_test.rb | 63 +--
.../controller/request/test_request_test.rb | 35 ++
.../url_encoded_params_parsing_test.rb | 38 --
.../test/controller/request_test.rb | 448 +++++++++---------
.../test/controller/resources_test.rb | 8 +
.../test/controller/routing_test.rb | 21 +
.../test/controller/send_file_test.rb | 2 +-
.../controller/session/cookie_store_test.rb | 21 -
.../actionpack/test/controller/test_test.rb | 8 +
.../test/fixtures/failsafe/500.html | 1 +
.../template/active_record_helper_test.rb | 2 +-
.../test/template/asset_tag_helper_test.rb | 46 ++
.../test/template/form_helper_test.rb | 123 ++++-
.../test/template/form_options_helper_test.rb | 22 +
.../test/template/form_tag_helper_test.rb | 29 +-
.../test/template/prototype_helper_test.rb | 22 +-
.../actionpack/test/template/template_test.rb | 32 ++
vendor/rails/activerecord/CHANGELOG | 11 +
vendor/rails/activerecord/Rakefile | 5 +-
.../lib/active_record/associations.rb | 97 ++--
.../associations/association_proxy.rb | 4 +-
.../associations/belongs_to_association.rb | 26 +-
.../belongs_to_polymorphic_association.rb | 6 +-
.../has_one_through_association.rb | 16 +-
.../lib/active_record/autosave_association.rb | 17 +-
.../activerecord/lib/active_record/base.rb | 33 +-
.../lib/active_record/calculations.rb | 18 +-
.../connection_adapters/postgresql_adapter.rb | 88 +++-
.../connection_adapters/sqlite_adapter.rb | 3 +
.../lib/active_record/fixtures.rb | 9 +-
.../lib/active_record/named_scope.rb | 4 +-
.../lib/active_record/schema_dumper.rb | 6 +-
.../lib/active_record/serialization.rb | 5 +-
.../serializers/json_serializer.rb | 26 +-
.../lib/active_record/session_store.rb | 10 +-
.../lib/active_record/timestamp.rb | 48 +-
.../activerecord/lib/active_record/version.rb | 2 +-
.../belongs_to_associations_test.rb | 106 ++++-
.../test/cases/associations/eager_test.rb | 12 +
.../has_many_associations_test.rb | 6 +
.../has_one_through_associations_test.rb | 9 +-
.../inner_join_association_test.rb | 5 +
.../test/cases/autosave_association_test.rb | 22 +
.../activerecord/test/cases/base_test.rb | 4 +-
.../test/cases/calculations_test.rb | 22 +-
.../test/cases/copy_table_test_sqlite.rb | 10 +-
.../activerecord/test/cases/finder_test.rb | 6 +
.../activerecord/test/cases/fixtures_test.rb | 5 +
.../rails/activerecord/test/cases/helper.rb | 3 +-
.../test/cases/json_serialization_test.rb | 114 ++---
.../test/cases/method_scoping_test.rb | 16 +-
.../test/cases/reflection_test.rb | 10 +-
.../test/cases/schema_dumper_test.rb | 24 +-
.../test/cases/schema_test_postgresql.rb | 76 +++
.../activerecord/test/cases/timestamp_test.rb | 75 +++
.../rails/activerecord/test/models/author.rb | 4 +
.../rails/activerecord/test/models/company.rb | 14 +-
.../activerecord/test/models/developer.rb | 10 +
.../rails/activerecord/test/models/essay.rb | 3 +
vendor/rails/activerecord/test/models/pet.rb | 2 +-
.../rails/activerecord/test/models/project.rb | 2 +-
.../rails/activerecord/test/models/reply.rb | 3 +-
.../rails/activerecord/test/models/topic.rb | 1 +
vendor/rails/activerecord/test/models/toy.rb | 2 +
.../rails/activerecord/test/schema/schema.rb | 15 +
vendor/rails/activeresource/CHANGELOG | 4 +
vendor/rails/activeresource/Rakefile | 5 +-
.../lib/active_resource/base.rb | 18 +-
.../active_resource/formats/json_format.rb | 4 +-
.../lib/active_resource/version.rb | 2 +-
.../activeresource/test/abstract_unit.rb | 4 +-
vendor/rails/activesupport/CHANGELOG | 7 +
.../activesupport/lib/active_support/cache.rb | 15 +-
.../active_support/cache/mem_cache_store.rb | 26 +-
.../cache/strategy/local_cache.rb | 2 +-
.../core_ext/hash/conversions.rb | 17 +-
.../core_ext/kernel/debugger.rb | 6 +-
.../core_ext/module/attribute_accessors.rb | 2 +
.../core_ext/module/delegation.rb | 15 +-
.../core_ext/module/model_naming.rb | 14 +-
.../active_support/core_ext/numeric/bytes.rb | 24 +-
.../active_support/core_ext/string/access.rb | 34 +-
.../lib/active_support/duration.rb | 6 +-
.../activesupport/lib/active_support/json.rb | 23 +-
.../active_support/json/backends/jsongem.rb | 38 ++
.../lib/active_support/json/backends/yaml.rb | 85 ++++
.../lib/active_support/json/decoding.rb | 95 +---
.../lib/active_support/json/encoders/date.rb | 17 +-
.../active_support/json/encoders/date_time.rb | 17 +-
.../json/encoders/enumerable.rb | 23 +-
.../json/encoders/false_class.rb | 6 +-
.../lib/active_support/json/encoders/hash.rb | 32 +-
.../active_support/json/encoders/nil_class.rb | 6 +-
.../active_support/json/encoders/numeric.rb | 16 +
.../active_support/json/encoders/object.rb | 8 +-
.../active_support/json/encoders/regexp.rb | 4 +
.../active_support/json/encoders/string.rb | 37 +-
.../active_support/json/encoders/symbol.rb | 4 +-
.../lib/active_support/json/encoders/time.rb | 17 +-
.../json/encoders/true_class.rb | 6 +-
.../lib/active_support/json/encoding.rb | 89 +++-
.../lib/active_support/ordered_hash.rb | 28 ++
.../lib/active_support/test_case.rb | 14 +-
.../lib/active_support/testing/deprecation.rb | 2 +
.../lib/active_support/time_with_zone.rb | 17 +-
.../lib/active_support/vendor.rb | 13 +-
.../i18n-0.1.3/test/i18n_exceptions_test.rb | 1 -
.../vendor/i18n-0.1.3/test/i18n_test.rb | 1 -
.../i18n-0.1.3/test/simple_backend_test.rb | 1 -
.../memcache.rb | 316 +++++++++---
.../lib/active_support/version.rb | 2 +-
.../lib/active_support/xml_mini/jdom.rb | 162 +++++++
.../activesupport/memcached_get_multi.diff | 0
.../rails/activesupport/test/abstract_unit.rb | 3 +-
.../rails/activesupport/test/caching_test.rb | 57 ++-
.../test/core_ext/duration_test.rb | 9 +-
.../test/core_ext/hash_ext_test.rb | 82 +++-
.../test/core_ext/module/model_naming_test.rb | 8 +
.../test/core_ext/module_test.rb | 2 +-
.../test/core_ext/string_ext_test.rb | 2 +
.../test/core_ext/time_with_zone_test.rb | 4 +-
.../activesupport/test/json/decoding_test.rb | 82 ++--
.../activesupport/test/json/encoding_test.rb | 58 ++-
.../activesupport/test/ordered_hash_test.rb | 33 ++
.../test/xml_mini/jdom_engine_test.rb | 153 ++++++
vendor/rails/ci/geminstaller.yml | 4 +-
vendor/rails/railties/CHANGELOG | 4 +
vendor/rails/railties/Rakefile | 19 +-
vendor/rails/railties/configs/routes.rb | 2 +-
vendor/rails/railties/guides/rails_guides.rb | 30 +-
.../railties/guides/rails_guides/generator.rb | 34 --
.../guides/rails_guides/levenshtein.rb | 112 -----
.../lib/commands/performance/profiler.rb | 2 +-
vendor/rails/railties/lib/initializer.rb | 31 +-
.../railties/lib/rails/gem_dependency.rb | 41 +-
vendor/rails/railties/lib/rails/rack/metal.rb | 2 +-
vendor/rails/railties/lib/rails/version.rb | 2 +-
vendor/rails/railties/lib/tasks/gems.rake | 25 +-
vendor/rails/railties/lib/test_help.rb | 5 +-
vendor/rails/railties/test/abstract_unit.rb | 3 -
.../railties/test/gem_dependency_test.rb | 74 ++-
.../rails/railties/test/initializer_test.rb | 23 +-
.../gems/dummy-gem-h-1.0.0/.specification | 29 ++
.../gems/dummy-gem-h-1.0.0/lib/dummy-gem-h.rb | 1 +
.../gems/dummy-gem-i-1.0.0/.specification | 41 ++
.../ext/dummy-gem-i/Makefile | 0
.../gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb | 1 +
.../gems/dummy-gem-j-1.0.0/.specification | 41 ++
.../gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb | 1 +
.../gems/dummy-gem-k-1.0.0/.specification | 49 ++
.../gems/dummy-gem-k-1.0.0/lib/dummy-gem-k.rb | 1 +
257 files changed, 4346 insertions(+), 1682 deletions(-)
create mode 100644 vendor/rails/actionpack/lib/action_controller/caching/sweeper.rb
delete mode 100644 vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
delete mode 100644 vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack.rb (95%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/adapter/camping.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/abstract/handler.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/abstract/request.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/basic.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/digest/md5.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/digest/nonce.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/digest/params.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/digest/request.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/auth/openid.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/builder.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/cascade.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/chunked.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/commonlogger.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/conditionalget.rb (94%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/content_length.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/content_type.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/deflater.rb (54%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/directory.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/file.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler.rb (68%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/cgi.rb (97%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/evented_mongrel.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/fastcgi.rb (72%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/lsws.rb (97%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/mongrel.rb (97%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/scgi.rb (96%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/swiftiplied_mongrel.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/thin.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/handler/webrick.rb (97%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/head.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/lint.rb (77%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/lobster.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/lock.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/methodoverride.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/mime.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/mock.rb (75%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/recursive.rb (100%)
create mode 100644 vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/reloader.rb
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/request.rb (88%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/response.rb (97%)
create mode 100644 vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/rewindable_input.rb
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/session/abstract/id.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/session/cookie.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/session/memcache.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/session/pool.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/showexceptions.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/showstatus.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/static.rb (100%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/urlmap.rb (95%)
rename vendor/rails/actionpack/lib/action_controller/vendor/{rack-1.0 => rack-1.1.pre}/rack/utils.rb (69%)
create mode 100644 vendor/rails/actionpack/test/controller/failsafe_test.rb
create mode 100644 vendor/rails/actionpack/test/controller/reloader_test.rb
create mode 100644 vendor/rails/actionpack/test/controller/request/test_request_test.rb
create mode 100644 vendor/rails/actionpack/test/fixtures/failsafe/500.html
create mode 100644 vendor/rails/actionpack/test/template/template_test.rb
create mode 100644 vendor/rails/activerecord/test/cases/timestamp_test.rb
create mode 100644 vendor/rails/activerecord/test/models/essay.rb
create mode 100644 vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb
create mode 100644 vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb
rename vendor/rails/activesupport/lib/active_support/vendor/{memcache-client-1.6.5 => memcache-client-1.7.4}/memcache.rb (73%)
create mode 100644 vendor/rails/activesupport/lib/active_support/xml_mini/jdom.rb
create mode 100644 vendor/rails/activesupport/memcached_get_multi.diff
create mode 100644 vendor/rails/activesupport/test/xml_mini/jdom_engine_test.rb
delete mode 100644 vendor/rails/railties/guides/rails_guides/levenshtein.rb
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/.specification
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/lib/dummy-gem-h.rb
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/ext/dummy-gem-i/Makefile
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/.specification
create mode 100644 vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/lib/dummy-gem-k.rb
diff --git a/test/functional/admin_controller_test.rb b/test/functional/admin_controller_test.rb
index 4ad3c225..11de0795 100644
--- a/test/functional/admin_controller_test.rb
+++ b/test/functional/admin_controller_test.rb
@@ -58,7 +58,7 @@ class AdminControllerTest < ActionController::TestCase
process 'create_system', 'password' => 'a_password', 'web_name' => 'My Wiki',
'web_address' => 'my_wiki'
- assert_redirected_to :web => @wiki.webs.keys.first, :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => @wiki.webs.keys.first, :controller => 'wiki', :action => 'show', :id => 'HomePage'
assert_equal wiki_before, @wiki
# and no new web should be created either
assert_equal old_size, @wiki.webs.size
@@ -68,7 +68,7 @@ class AdminControllerTest < ActionController::TestCase
def test_create_system_no_form_and_wiki_already_initialized
assert @wiki.setup?
process('create_system')
- assert_redirected_to :web => @wiki.webs.keys.first, :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => @wiki.webs.keys.first, :controller => 'wiki', :action => 'show', :id => 'HomePage'
assert(@response.has_flash_object?(:error))
end
@@ -78,7 +78,7 @@ class AdminControllerTest < ActionController::TestCase
process 'create_web', 'system_password' => 'pswd', 'name' => 'Wiki Two', 'address' => 'wiki2'
- assert_redirected_to :web => 'wiki2', :action => 'new', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki2', :controller => 'wiki', :action => 'new', :id => 'HomePage'
wiki2 = @wiki.webs['wiki2']
assert wiki2
assert_equal 'Wiki Two', wiki2.name
@@ -90,7 +90,7 @@ class AdminControllerTest < ActionController::TestCase
process 'create_web', 'system_password' => 'instiki', 'name' => 'Wiki Two', 'address' => 'wiki2'
- assert_redirected_to :web => 'wiki2', :action => 'new', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki2', :controller => 'wiki', :action => 'new', :id => 'HomePage'
end
def test_create_web_failed_authentication
@@ -98,7 +98,7 @@ class AdminControllerTest < ActionController::TestCase
process 'create_web', 'system_password' => 'wrong', 'name' => 'Wiki Two', 'address' => 'wiki2'
- assert_redirected_to :web => nil, :action => 'create_web'
+ assert_redirected_to :controller => 'admin', :action => 'create_web'
assert_nil @wiki.webs['wiki2']
end
@@ -108,7 +108,6 @@ class AdminControllerTest < ActionController::TestCase
assert_response :success
end
-
def test_edit_web_no_form
process 'edit_web', 'web' => 'wiki1'
# this action simply renders a form
@@ -125,7 +124,7 @@ class AdminControllerTest < ActionController::TestCase
'brackets_only' => 'on', 'count_pages' => 'on', 'allow_uploads' => 'on',
'max_upload_size' => '300')
- assert_redirected_to :web => 'renamed_wiki1', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'renamed_wiki1', :controller => 'wiki', :action => 'show', :id => 'HomePage'
@web = Web.find(@web.id)
assert_equal 'renamed_wiki1', @web.address
assert_equal 'Renamed Wiki1', @web.name
@@ -164,7 +163,7 @@ class AdminControllerTest < ActionController::TestCase
# safe_mode, published, brackets_only, count_pages, allow_uploads not set
# and should become false
- assert_redirected_to :web => 'renamed_wiki1', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'renamed_wiki1', :controller => 'wiki', :action => 'show', :id => 'HomePage'
@web = Web.find(@web.id)
assert !@web.safe_mode?
assert !@web.published?
@@ -237,7 +236,7 @@ class AdminControllerTest < ActionController::TestCase
# third pass does not destroy HomePage
r = process('remove_orphaned_pages', 'web' => 'wiki1', 'system_password_orphaned' => 'pswd')
- assert_redirected_to :action => 'list'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'list'
@web.pages(true)
assert_equal page_order, @web.select.sort,
"Pages are not as expected: #{@web.select.sort.map {|p| p.name}.inspect}"
@@ -271,14 +270,14 @@ class AdminControllerTest < ActionController::TestCase
# third pass does does nothing, since there are no pages in the
# 'leaves' category.
r = process('remove_orphaned_pages_in_category', 'web' => 'wiki1', 'category' => 'leaves', 'system_password_orphaned_in_category' => 'pswd')
- assert_redirected_to :action => 'list'
+ assert_redirected_to :controller => 'wiki', :web => 'wiki1', :action => 'list'
@web.pages(true)
assert_equal page_order, @web.select.sort,
"Pages are not as expected: #{@web.select.sort.map {|p| p.name}.inspect}"
# fourth pass destroys Oak
r = process('remove_orphaned_pages_in_category', 'web' => 'wiki1', 'category' => 'trees', 'system_password_orphaned_in_category' => 'pswd')
- assert_redirected_to :action => 'list'
+ assert_redirected_to :controller => 'wiki', :web => 'wiki1', :action => 'list'
@web.pages(true)
page_order.delete(@oak)
assert_equal page_order, @web.select.sort,
diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb
index dc226443..dc0a64a1 100755
--- a/test/functional/wiki_controller_test.rb
+++ b/test/functional/wiki_controller_test.rb
@@ -39,7 +39,7 @@ class WikiControllerTest < ActionController::TestCase
set_web_property :password, 'pswd'
get :authenticate, :web => 'wiki1', :password => 'pswd'
- assert_redirected_to :web => 'wiki1', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'show', :id => 'HomePage'
assert_equal 'pswd', @response.cookies['wiki1']
end
@@ -47,7 +47,7 @@ class WikiControllerTest < ActionController::TestCase
set_web_property :password, 'pswd'
r = process('authenticate', 'web' => 'wiki1', 'password' => 'wrong password')
- assert_redirected_to :action => 'login', :web => 'wiki1'
+ assert_redirected_to :action => 'login', :controller => 'wiki', :web => 'wiki1'
assert_nil r.cookies['web_address']
end
@@ -72,7 +72,7 @@ class WikiControllerTest < ActionController::TestCase
r = process('cancel_edit', 'web' => 'wiki1', 'id' => 'Oak')
- assert_redirected_to :action => 'show', :id => 'Oak'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'show', :id => 'Oak'
assert !Page.find(@oak.id).locked?(Time.now)
end
@@ -85,7 +85,7 @@ class WikiControllerTest < ActionController::TestCase
def test_edit_page_locked_page
@home.lock(Time.now, 'Locky')
process 'edit', 'web' => 'wiki1', 'id' => 'HomePage'
- assert_redirected_to :action => 'locked'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'locked', :id => 'HomePage'
end
def test_edit_page_break_lock
@@ -233,19 +233,19 @@ class WikiControllerTest < ActionController::TestCase
# delete extra web fixture
webs(:instiki).destroy
process('index')
- assert_redirected_to :web => 'wiki1', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'show', :id => 'HomePage'
end
def test_index_multiple_webs
@wiki.create_web('Test Wiki 2', 'wiki2')
process('index')
- assert_redirected_to :action => 'web_list'
+ assert_redirected_to :controller => 'wiki', :action => 'web_list'
end
def test_index_multiple_webs_web_explicit
@wiki.create_web('Test Wiki 2', 'wiki2')
process('index', 'web' => 'wiki2')
- assert_redirected_to :web => 'wiki2', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki2', :controller => 'wiki', :action => 'show', :id => 'HomePage'
end
def test_index_wiki_not_initialized
@@ -598,7 +598,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'NewPage', 'content' => 'Contents of a new page',
'author' => 'AuthorOfNewPage'
- assert_redirected_to :web => 'wiki1', :action => 'show', :id => 'NewPage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'show', :id => 'NewPage'
assert_equal 'AuthorOfNewPage', r.cookies['author']
assert_match @eternity, r.headers["Set-Cookie"][0]
new_page = @wiki.read_page('wiki1', 'NewPage')
@@ -610,7 +610,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'NewPage', 'content' => "Contents of a new page\r\n\000",
'author' => 'AuthorOfNewPage'
- assert_redirected_to :web => 'wiki1', :action => 'new', :id => 'NewPage', :content => ''
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'new', :id => 'NewPage', :content => ''
assert_equal 'AuthorOfNewPage', r.cookies['author']
assert_match @eternity, r.headers["Set-Cookie"][0]
end
@@ -619,7 +619,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'NewPage', 'content' => "Contents of a new page\r\n",
'author' => 'AuthorOfNewPage'
- assert_redirected_to :web => 'wiki1', :action => 'new', :id => 'NewPage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'new', :id => 'NewPage', :content => ''
assert_equal 'AuthorOfNewPage', r.cookies['author']
assert_match @eternity, r.headers["Set-Cookie"][0]
end
@@ -628,7 +628,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'NewPage', 'content' => "Contents of a new page\r\n",
'author' => 'AuthorOfNewPage'
- assert_redirected_to :web => 'wiki1', :action => 'new', :id => 'NewPage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'new', :id => 'NewPage', :content => ''
assert_equal 'AuthorOfNewPage', r.cookies['author']
assert_match @eternity, r.headers["Set-Cookie"][0]
end
@@ -640,7 +640,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'HomePage', 'content' => 'Revised HomePage',
'author' => 'Batman'
- assert_redirected_to :web => 'wiki1', :action => 'show', :id => 'HomePage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'show', :id => 'HomePage'
assert_equal 'Batman', r.cookies['author']
home_page = @wiki.read_page('wiki1', 'HomePage')
assert_equal current_revisions+1, home_page.revisions.size
@@ -656,7 +656,7 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', 'web' => 'wiki1', 'id' => 'HomePage', 'content' => "Revised HomePage\000",
'author' => 'Batman'
- assert_redirected_to :web => 'wiki1', :action => 'edit', :id => 'HomePage',
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'edit', :id => 'HomePage',
:content => 'HisWay would be MyWay $\sin(x)\begin{svg} \end{svg}\includegraphics[width' +
'=3em]{foo}$ in kinda ThatWay in HisWay though MyWay \OverThere -- see SmartEng' +
'ine in that SmartEngineGUI'
@@ -688,7 +688,10 @@ class WikiControllerTest < ActionController::TestCase
r = process 'save', {'web' => 'wiki1', 'id' => 'HomePage',
'content' => @home.revisions.last.content.dup + "\n Try viagra.\n",
'author' => 'SomeOtherAuthor'}, {:return_to => '/wiki1/show/HomePage'}
- assert_redirected_to :action => 'edit', :web => 'wiki1', :id => 'HomePage'
+ assert_redirected_to :action => 'edit', :controller => 'wiki', :web => 'wiki1', :id => 'HomePage',
+ :content => 'HisWay would be MyWay $\sin(x)\begin{svg} \end{svg}\includegraphics[width=3e'+
+ 'm]{foo}$ in kinda ThatWay in HisWay though MyWay \OverThere -- see SmartEngine in'+
+ " that SmartEngineGUI\n Try viagra.\n"
assert r.flash[:error].to_s == "Your edit was blocked by spam filtering"
end
@@ -700,7 +703,10 @@ class WikiControllerTest < ActionController::TestCase
'content' => @home.revisions.last.content.dup,
'author' => 'SomeOtherAuthor'}, {:return_to => '/wiki1/show/HomePage'}
- assert_redirected_to :action => 'edit', :web => 'wiki1', :id => 'HomePage'
+ assert_redirected_to :action => 'edit', :controller => 'wiki', :web => 'wiki1', :id => 'HomePage',
+ :content => 'HisWay would be MyWay $\sin(x)\begin{svg} \end{svg}\includegraphics[width=3e'+
+ 'm]{foo}$ in kinda ThatWay in HisWay though MyWay \OverThere -- see SmartEngine in'+
+ ' that SmartEngineGUI'
assert r.flash[:error].to_s == "You have tried to save page 'HomePage' without changing its content"
revisions_after = @home.revisions.size
@@ -717,7 +723,7 @@ class WikiControllerTest < ActionController::TestCase
'content' => @liquor.revisions.last.content.dup, 'new_name' => 'booze',
'author' => 'SomeOtherAuthor'}, {:return_to => '/wiki1/show/booze'}
- assert_redirected_to :action => 'show', :web => 'wiki1', :id => 'booze'
+ assert_redirected_to :action => 'show', :controller => 'wiki', :web => 'wiki1', :id => 'booze'
revisions_after = @liquor.revisions.size
assert_equal revisions_before + 1, revisions_after
@@ -741,20 +747,20 @@ class WikiControllerTest < ActionController::TestCase
def test_save_invalid_author_name
r = process 'save', 'web' => 'wiki1', 'id' => 'NewPage', 'content' => 'Contents of a new page',
'author' => 'foo.bar'
- assert_redirected_to :action => 'new', :web => 'wiki1', :id => 'NewPage'
+ assert_redirected_to :action => 'new', :controller => 'wiki', :web => 'wiki1', :id => 'NewPage'
assert r.flash[:error].to_s == 'Your name cannot contain a "."'
r = process 'save', 'web' => 'wiki1', 'id' => 'AnotherPage', 'content' => 'Contents of a new page',
'author' => "\000"
- assert_redirected_to :action => 'new', :web => 'wiki1', :id => 'AnotherPage'
+ assert_redirected_to :action => 'new', :controller => 'wiki', :web => 'wiki1', :id => 'AnotherPage'
assert r.flash[:error].to_s == "Your name was not valid utf-8"
end
def test_search
r = process 'search', 'web' => 'wiki1', 'query' => '\s[A-Z]ak'
- assert_redirected_to :action => 'show', :id => 'Oak'
+ assert_redirected_to :web => 'wiki1', :action => 'show', :controller => 'wiki', :id => 'Oak'
end
def test_search_multiple_results
@@ -873,7 +879,7 @@ class WikiControllerTest < ActionController::TestCase
def test_show_page_nonexistant_page
process('show', 'id' => 'UnknownPage', 'web' => 'wiki1')
- assert_redirected_to :web => 'wiki1', :action => 'new', :id => 'UnknownPage'
+ assert_redirected_to :web => 'wiki1', :controller => 'wiki', :action => 'new', :id => 'UnknownPage'
end
def test_show_no_page
diff --git a/vendor/rails/actionmailer/CHANGELOG b/vendor/rails/actionmailer/CHANGELOG
index 773e603d..4090dd81 100644
--- a/vendor/rails/actionmailer/CHANGELOG
+++ b/vendor/rails/actionmailer/CHANGELOG
@@ -1,3 +1,7 @@
+*2.3.3 (July 12, 2009)*
+
+* No changes, just a version bump.
+
*2.3.2 [Final] (March 15, 2009)*
* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 [Matt Jones]
diff --git a/vendor/rails/actionmailer/Rakefile b/vendor/rails/actionmailer/Rakefile
index f06f18ff..e6dc2591 100644
--- a/vendor/rails/actionmailer/Rakefile
+++ b/vendor/rails/actionmailer/Rakefile
@@ -4,7 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require 'rake/contrib/sshpublisher'
require File.join(File.dirname(__FILE__), 'lib', 'action_mailer', 'version')
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
@@ -55,7 +54,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"
- s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 2.3.3' + PKG_BUILD)
s.has_rdoc = true
s.requirements << 'none'
@@ -76,12 +75,14 @@ end
desc "Publish the API documentation"
task :pgem => [:package] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/am", "doc").upload
end
diff --git a/vendor/rails/actionmailer/lib/action_mailer/base.rb b/vendor/rails/actionmailer/lib/action_mailer/base.rb
index b77409b6..000c05d1 100644
--- a/vendor/rails/actionmailer/lib/action_mailer/base.rb
+++ b/vendor/rails/actionmailer/lib/action_mailer/base.rb
@@ -674,7 +674,7 @@ module ActionMailer #:nodoc:
def perform_delivery_smtp(mail)
destinations = mail.destinations
mail.ready_to_send
- sender = (mail['return-path'] && mail['return-path'].spec) || mail.from
+ sender = (mail['return-path'] && mail['return-path'].spec) || mail['from']
smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
diff --git a/vendor/rails/actionmailer/lib/action_mailer/version.rb b/vendor/rails/actionmailer/lib/action_mailer/version.rb
index 08ff0d2f..db86a297 100644
--- a/vendor/rails/actionmailer/lib/action_mailer/version.rb
+++ b/vendor/rails/actionmailer/lib/action_mailer/version.rb
@@ -2,7 +2,7 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/actionmailer/test/abstract_unit.rb b/vendor/rails/actionmailer/test/abstract_unit.rb
index 3e772557..9728ae5b 100644
--- a/vendor/rails/actionmailer/test/abstract_unit.rb
+++ b/vendor/rails/actionmailer/test/abstract_unit.rb
@@ -1,9 +1,6 @@
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
-
$:.unshift "#{File.dirname(__FILE__)}/../lib"
$:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib"
$:.unshift "#{File.dirname(__FILE__)}/../../actionpack/lib"
diff --git a/vendor/rails/actionpack/CHANGELOG b/vendor/rails/actionpack/CHANGELOG
index 8c9486cc..5f6fec67 100644
--- a/vendor/rails/actionpack/CHANGELOG
+++ b/vendor/rails/actionpack/CHANGELOG
@@ -1,3 +1,8 @@
+*2.3.3 (July 12, 2009)*
+
+* Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes]
+
+
*2.3.2 [Final] (March 15, 2009)*
* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #") [DHH]
diff --git a/vendor/rails/actionpack/Rakefile b/vendor/rails/actionpack/Rakefile
index 6cacdf3c..17f6f1ac 100644
--- a/vendor/rails/actionpack/Rakefile
+++ b/vendor/rails/actionpack/Rakefile
@@ -4,7 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require 'rake/contrib/sshpublisher'
require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version')
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
@@ -80,7 +79,8 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.requirements << 'none'
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.3.3' + PKG_BUILD)
+ s.add_dependency('rack', '~> 1.0.0')
s.require_path = 'lib'
s.autorequire = 'action_controller'
@@ -136,12 +136,14 @@ task :update_js => [ :update_scriptaculous ]
desc "Publish the API documentation"
task :pgem => [:package] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ap", "doc").upload
end
diff --git a/vendor/rails/actionpack/lib/action_controller.rb b/vendor/rails/actionpack/lib/action_controller.rb
index d03f4cb2..187c958c 100644
--- a/vendor/rails/actionpack/lib/action_controller.rb
+++ b/vendor/rails/actionpack/lib/action_controller.rb
@@ -32,10 +32,10 @@ rescue LoadError
end
begin
- gem 'rack', '~> 1.0.0'
+ gem 'rack', '~> 1.1.0'
require 'rack'
rescue Gem::LoadError
- require 'action_controller/vendor/rack-1.0/rack'
+ require 'action_controller/vendor/rack-1.1.pre/rack'
end
module ActionController
@@ -45,7 +45,6 @@ module ActionController
[Base, CGIHandler, CgiRequest, Request, Response, Http::Headers, UrlRewriter, UrlWriter]
end
- autoload :AbstractRequest, 'action_controller/request'
autoload :Base, 'action_controller/base'
autoload :Benchmarking, 'action_controller/benchmarking'
autoload :Caching, 'action_controller/caching'
diff --git a/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb b/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb
index 59760902..989be2db 100644
--- a/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb
+++ b/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb
@@ -63,7 +63,10 @@ module ActionController
# Support partial arguments for hash redirections
if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
- return true if options.all? {|(key, value)| @response.redirected_to[key] == value}
+ if options.all? {|(key, value)| @response.redirected_to[key] == value}
+ ::ActiveSupport::Deprecation.warn("Using assert_redirected_to with partial hash arguments is deprecated. Specify the full set arguments instead", caller)
+ return true
+ end
end
redirected_to_after_normalisation = normalize_argument_to_redirection(@response.redirected_to)
@@ -82,6 +85,9 @@ module ActionController
# # assert that the "new" view template was rendered
# assert_template "new"
#
+ # # assert that the "new" view template was rendered with Symbol
+ # assert_template :new
+ #
# # assert that the "_customer" partial was rendered twice
# assert_template :partial => '_customer', :count => 2
#
@@ -91,7 +97,7 @@ module ActionController
def assert_template(options = {}, message = nil)
clean_backtrace do
case options
- when NilClass, String
+ when NilClass, String, Symbol
rendered = @response.rendered[:template].to_s
msg = build_message(message,
"expecting > but rendering with >",
@@ -100,7 +106,7 @@ module ActionController
if options.nil?
@response.rendered[:template].blank?
else
- rendered.to_s.match(options)
+ rendered.to_s.match(options.to_s)
end
end
when Hash
@@ -123,6 +129,8 @@ module ActionController
assert @response.rendered[:partials].empty?,
"Expected no partials to be rendered"
end
+ else
+ raise ArgumentError
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/base.rb b/vendor/rails/actionpack/lib/action_controller/base.rb
index 0facf706..3c89fc8b 100644
--- a/vendor/rails/actionpack/lib/action_controller/base.rb
+++ b/vendor/rails/actionpack/lib/action_controller/base.rb
@@ -491,6 +491,10 @@ module ActionController #:nodoc:
filtered_parameters[key] = '[FILTERED]'
elsif value.is_a?(Hash)
filtered_parameters[key] = filter_parameters(value)
+ elsif value.is_a?(Array)
+ filtered_parameters[key] = value.collect do |item|
+ filter_parameters(item)
+ end
elsif block_given?
key = key.dup
value = value.dup if value
@@ -950,8 +954,9 @@ module ActionController #:nodoc:
response.content_type ||= Mime::JS
render_for_text(js, options[:status])
- elsif json = options[:json]
- json = json.to_json unless json.is_a?(String)
+ elsif options.include?(:json)
+ json = options[:json]
+ json = ActiveSupport::JSON.encode(json) unless json.is_a?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
render_for_text(json, options[:status])
diff --git a/vendor/rails/actionpack/lib/action_controller/caching.rb b/vendor/rails/actionpack/lib/action_controller/caching.rb
index 80d13e25..f6862230 100644
--- a/vendor/rails/actionpack/lib/action_controller/caching.rb
+++ b/vendor/rails/actionpack/lib/action_controller/caching.rb
@@ -27,7 +27,7 @@ module ActionController #:nodoc:
autoload :Actions, 'action_controller/caching/actions'
autoload :Fragments, 'action_controller/caching/fragments'
autoload :Pages, 'action_controller/caching/pages'
- autoload :Sweeper, 'action_controller/caching/sweeping'
+ autoload :Sweeper, 'action_controller/caching/sweeper'
autoload :Sweeping, 'action_controller/caching/sweeping'
def self.included(base) #:nodoc:
diff --git a/vendor/rails/actionpack/lib/action_controller/caching/actions.rb b/vendor/rails/actionpack/lib/action_controller/caching/actions.rb
index 87b5029e..21ee9bd3 100644
--- a/vendor/rails/actionpack/lib/action_controller/caching/actions.rb
+++ b/vendor/rails/actionpack/lib/action_controller/caching/actions.rb
@@ -61,7 +61,9 @@ module ActionController #:nodoc:
filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) }
cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
- around_filter(cache_filter, filter_options)
+ around_filter(filter_options) do |controller, action|
+ cache_filter.filter(controller, action)
+ end
end
end
@@ -83,6 +85,12 @@ module ActionController #:nodoc:
@options = options
end
+ def filter(controller, action)
+ should_continue = before(controller)
+ action.call if should_continue
+ after(controller)
+ end
+
def before(controller)
cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path)))
if cache = controller.read_fragment(cache_path.path, @options[:store_options])
diff --git a/vendor/rails/actionpack/lib/action_controller/caching/sweeper.rb b/vendor/rails/actionpack/lib/action_controller/caching/sweeper.rb
new file mode 100644
index 00000000..4885d8b2
--- /dev/null
+++ b/vendor/rails/actionpack/lib/action_controller/caching/sweeper.rb
@@ -0,0 +1,45 @@
+require 'active_record'
+
+module ActionController #:nodoc:
+ module Caching
+ class Sweeper < ActiveRecord::Observer #:nodoc:
+ attr_accessor :controller
+
+ def before(controller)
+ self.controller = controller
+ callback(:before) if controller.perform_caching
+ end
+
+ def after(controller)
+ callback(:after) if controller.perform_caching
+ # Clean up, so that the controller can be collected after this request
+ self.controller = nil
+ end
+
+ protected
+ # gets the action cache path for the given options.
+ def action_path_for(options)
+ ActionController::Caching::Actions::ActionCachePath.path_for(controller, options)
+ end
+
+ # Retrieve instance variables set in the controller.
+ def assigns(key)
+ controller.instance_variable_get("@#{key}")
+ end
+
+ private
+ def callback(timing)
+ controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
+ action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
+
+ __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
+ __send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
+ end
+
+ def method_missing(method, *arguments, &block)
+ return if @controller.nil?
+ @controller.__send__(method, *arguments, &block)
+ end
+ end
+ end
+end
diff --git a/vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb b/vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb
index c1be264f..9b320021 100644
--- a/vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb
+++ b/vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb
@@ -51,47 +51,5 @@ module ActionController #:nodoc:
end
end
end
-
- if defined?(ActiveRecord) and defined?(ActiveRecord::Observer)
- class Sweeper < ActiveRecord::Observer #:nodoc:
- attr_accessor :controller
-
- def before(controller)
- self.controller = controller
- callback(:before) if controller.perform_caching
- end
-
- def after(controller)
- callback(:after) if controller.perform_caching
- # Clean up, so that the controller can be collected after this request
- self.controller = nil
- end
-
- protected
- # gets the action cache path for the given options.
- def action_path_for(options)
- ActionController::Caching::Actions::ActionCachePath.path_for(controller, options)
- end
-
- # Retrieve instance variables set in the controller.
- def assigns(key)
- controller.instance_variable_get("@#{key}")
- end
-
- private
- def callback(timing)
- controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
- action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
-
- __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
- __send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
- end
-
- def method_missing(method, *arguments, &block)
- return if @controller.nil?
- @controller.__send__(method, *arguments, &block)
- end
- end
- end
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/failsafe.rb b/vendor/rails/actionpack/lib/action_controller/failsafe.rb
index 56758114..7f8aee82 100644
--- a/vendor/rails/actionpack/lib/action_controller/failsafe.rb
+++ b/vendor/rails/actionpack/lib/action_controller/failsafe.rb
@@ -1,4 +1,19 @@
+require 'erb'
+
module ActionController
+ # The Failsafe middleware is usually the top-most middleware in the Rack
+ # middleware chain. It returns the underlying middleware's response, but if
+ # the underlying middle raises an exception then Failsafe will log the
+ # exception into the Rails log file, and will attempt to return an error
+ # message response.
+ #
+ # Failsafe is a last resort for logging errors and for telling the HTTP
+ # client that something went wrong. Do not confuse this with the
+ # ActionController::Rescue module, which is responsible for catching
+ # exceptions at deeper levels. Unlike Failsafe, which is as simple as
+ # possible, Rescue provides features that allow developers to hook into
+ # the error handling logic, and can customize the error message response
+ # based on the HTTP client's IP.
class Failsafe
cattr_accessor :error_file_path
self.error_file_path = Rails.public_path if defined?(Rails.public_path)
@@ -11,7 +26,7 @@ module ActionController
@app.call(env)
rescue Exception => exception
# Reraise exception in test environment
- if env["rack.test"]
+ if defined?(Rails) && Rails.env.test?
raise exception
else
failsafe_response(exception)
@@ -21,18 +36,37 @@ module ActionController
private
def failsafe_response(exception)
log_failsafe_exception(exception)
- [500, {'Content-Type' => 'text/html'}, failsafe_response_body]
+ [500, {'Content-Type' => 'text/html'}, [failsafe_response_body]]
rescue Exception => failsafe_error # Logger or IO errors
$stderr.puts "Error during failsafe response: #{failsafe_error}"
end
def failsafe_response_body
- error_path = "#{self.class.error_file_path}/500.html"
- if File.exist?(error_path)
- File.read(error_path)
+ error_template_path = "#{self.class.error_file_path}/500.html"
+ if File.exist?(error_template_path)
+ begin
+ result = render_template(error_template_path)
+ rescue Exception
+ result = nil
+ end
else
- "500 Internal Server Error "
+ result = nil
end
+ if result.nil?
+ result = "500 Internal Server Error " <<
+ "If you are the administrator of this website, then please read this web " <<
+ "application's log file to find out what went wrong."
+ end
+ result
+ end
+
+ # The default 500.html uses the h() method.
+ def h(text) # :nodoc:
+ ERB::Util.h(text)
+ end
+
+ def render_template(filename)
+ ERB.new(File.read(filename)).result(binding)
end
def log_failsafe_exception(exception)
diff --git a/vendor/rails/actionpack/lib/action_controller/flash.rb b/vendor/rails/actionpack/lib/action_controller/flash.rb
index 56ee9c67..93912073 100644
--- a/vendor/rails/actionpack/lib/action_controller/flash.rb
+++ b/vendor/rails/actionpack/lib/action_controller/flash.rb
@@ -120,6 +120,11 @@ module ActionController #:nodoc:
(@used.keys - keys).each{ |k| @used.delete(k) }
end
+ def store(session, key = "flash")
+ return if self.empty?
+ session[key] = self
+ end
+
private
# Used internally by the keep and discard methods
# use() # marks the entire flash as used
@@ -139,7 +144,10 @@ module ActionController #:nodoc:
protected
def perform_action_with_flash
perform_action_without_flash
- remove_instance_variable(:@_flash) if defined? @_flash
+ if defined? @_flash
+ @_flash.store(session)
+ remove_instance_variable(:@_flash)
+ end
end
def reset_session_with_flash
@@ -151,8 +159,8 @@ module ActionController #:nodoc:
# read a notice you put there or flash["notice"] = "hello"
# to put a new one.
def flash #:doc:
- unless defined? @_flash
- @_flash = session["flash"] ||= FlashHash.new
+ if !defined?(@_flash)
+ @_flash = session["flash"] || FlashHash.new
@_flash.sweep
end
diff --git a/vendor/rails/actionpack/lib/action_controller/http_authentication.rb b/vendor/rails/actionpack/lib/action_controller/http_authentication.rb
index b6b5267c..88c289bc 100644
--- a/vendor/rails/actionpack/lib/action_controller/http_authentication.rb
+++ b/vendor/rails/actionpack/lib/action_controller/http_authentication.rb
@@ -183,7 +183,7 @@ module ActionController
request.env['REDIRECT_X_HTTP_AUTHORIZATION']
end
- # Raises error unless the request credentials response value matches the expected value.
+ # Returns false unless the request credentials response value matches the expected value.
# First try the password as a ha1 digest password. If this fails, then try it as a plain
# text password.
def validate_digest_response(request, realm, &password_procedure)
@@ -192,9 +192,12 @@ module ActionController
if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque]
password = password_procedure.call(credentials[:username])
+ return false unless password
+
+ method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
[true, false].any? do |password_is_ha1|
- expected = expected_response(request.env['REQUEST_METHOD'], request.env['REQUEST_URI'], credentials, password, password_is_ha1)
+ expected = expected_response(method, request.env['REQUEST_URI'], credentials, password, password_is_ha1)
expected == credentials[:response]
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/integration.rb b/vendor/rails/actionpack/lib/action_controller/integration.rb
index 26b69557..58b64762 100644
--- a/vendor/rails/actionpack/lib/action_controller/integration.rb
+++ b/vendor/rails/actionpack/lib/action_controller/integration.rb
@@ -292,9 +292,7 @@ module ActionController
"rack.errors" => StringIO.new,
"rack.multithread" => true,
"rack.multiprocess" => true,
- "rack.run_once" => false,
-
- "rack.test" => true
+ "rack.run_once" => false
)
(headers || {}).each do |key, value|
@@ -311,12 +309,7 @@ module ActionController
ActionController::Base.clear_last_instantiation!
- app = @application
- # Rack::Lint doesn't accept String headers or bodies in Ruby 1.9
- unless RUBY_VERSION >= '1.9.0' && Rack.release <= '0.9.0'
- app = Rack::Lint.new(app)
- end
-
+ app = Rack::Lint.new(@application)
status, headers, body = app.call(env)
@request_count += 1
@@ -333,7 +326,7 @@ module ActionController
end
@body = ""
- if body.is_a?(String)
+ if body.respond_to?(:to_str)
@body << body
else
body.each { |part| @body << part }
@@ -416,7 +409,7 @@ module ActionController
def multipart_requestify(params, first=true)
returning Hash.new do |p|
params.each do |key, value|
- k = first ? CGI.escape(key.to_s) : "[#{CGI.escape(key.to_s)}]"
+ k = first ? key.to_s : "[#{key.to_s}]"
if Hash === value
multipart_requestify(value, false).each do |subkey, subvalue|
p[k + subkey] = subvalue
diff --git a/vendor/rails/actionpack/lib/action_controller/middlewares.rb b/vendor/rails/actionpack/lib/action_controller/middlewares.rb
index 371cf6d8..dda25fc2 100644
--- a/vendor/rails/actionpack/lib/action_controller/middlewares.rb
+++ b/vendor/rails/actionpack/lib/action_controller/middlewares.rb
@@ -7,7 +7,6 @@ use "ActionController::Failsafe"
use lambda { ActionController::Base.session_store },
lambda { ActionController::Base.session_options }
-use "ActionController::RewindableInput"
use "ActionController::ParamsParser"
use "Rack::MethodOverride"
use "Rack::Head"
diff --git a/vendor/rails/actionpack/lib/action_controller/reloader.rb b/vendor/rails/actionpack/lib/action_controller/reloader.rb
index 46789309..459dece1 100644
--- a/vendor/rails/actionpack/lib/action_controller/reloader.rb
+++ b/vendor/rails/actionpack/lib/action_controller/reloader.rb
@@ -1,14 +1,45 @@
module ActionController
class Reloader
+ class BodyWrapper
+ def initialize(body)
+ @body = body
+ end
+
+ def close
+ @body.close if @body.respond_to?(:close)
+ ensure
+ Dispatcher.cleanup_application
+ end
+
+ def method_missing(*args, &block)
+ @body.send(*args, &block)
+ end
+
+ def respond_to?(symbol, include_private = false)
+ symbol == :close || @body.respond_to?(symbol, include_private)
+ end
+ end
+
def initialize(app)
@app = app
end
def call(env)
Dispatcher.reload_application
- @app.call(env)
- ensure
- Dispatcher.cleanup_application
+ status, headers, body = @app.call(env)
+ # We do not want to call 'cleanup_application' in an ensure block
+ # because the returned Rack response body may lazily generate its data. This
+ # is for example the case if one calls
+ #
+ # render :text => lambda { ... code here which refers to application models ... }
+ #
+ # in an ActionController.
+ #
+ # Instead, we will want to cleanup the application code after the request is
+ # completely finished. So we wrap the body in a BodyWrapper class so that
+ # when the Rack handler calls #close during the end of the request, we get to
+ # run our cleanup code.
+ [status, headers, BodyWrapper.new(body)]
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/request.rb b/vendor/rails/actionpack/lib/action_controller/request.rb
index ef223f15..1c3c1c83 100755
--- a/vendor/rails/actionpack/lib/action_controller/request.rb
+++ b/vendor/rails/actionpack/lib/action_controller/request.rb
@@ -95,6 +95,10 @@ module ActionController
end
end
+ def media_type
+ content_type.to_s
+ end
+
# Returns the accepted MIME type for the request.
def accepts
@accepts ||= begin
@@ -383,7 +387,7 @@ EOM
alias_method :params, :parameters
def path_parameters=(parameters) #:nodoc:
- @env["rack.routing_args"] = parameters
+ @env["action_controller.request.path_parameters"] = parameters
@symbolized_path_parameters = @parameters = nil
end
@@ -399,7 +403,7 @@ EOM
#
# See symbolized_path_parameters for symbolized keys.
def path_parameters
- @env["rack.routing_args"] ||= {}
+ @env["action_controller.request.path_parameters"] ||= {}
end
# The request body is an IO input stream. If the RAW_POST_DATA environment
diff --git a/vendor/rails/actionpack/lib/action_controller/response.rb b/vendor/rails/actionpack/lib/action_controller/response.rb
index ccff473d..def03fac 100644
--- a/vendor/rails/actionpack/lib/action_controller/response.rb
+++ b/vendor/rails/actionpack/lib/action_controller/response.rb
@@ -151,8 +151,8 @@ module ActionController # :nodoc:
if @body.respond_to?(:call)
@writer = lambda { |x| callback.call(x) }
@body.call(self, self)
- elsif @body.is_a?(String)
- @body.each_line(&callback)
+ elsif @body.respond_to?(:to_str)
+ yield @body
else
@body.each(&callback)
end
diff --git a/vendor/rails/actionpack/lib/action_controller/rewindable_input.rb b/vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
deleted file mode 100644
index cedfb7fd..00000000
--- a/vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module ActionController
- class RewindableInput
- class RewindableIO < ActiveSupport::BasicObject
- def initialize(io)
- @io = io
- @rewindable = io.is_a?(::StringIO)
- end
-
- def method_missing(method, *args, &block)
- unless @rewindable
- @io = ::StringIO.new(@io.read)
- @rewindable = true
- end
-
- @io.__send__(method, *args, &block)
- end
- end
-
- def initialize(app)
- @app = app
- end
-
- def call(env)
- env['rack.input'] = RewindableIO.new(env['rack.input'])
- @app.call(env)
- end
- end
-end
diff --git a/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb b/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb
index 044ace7d..a983d376 100644
--- a/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb
+++ b/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb
@@ -305,6 +305,7 @@ module ActionController
end
def add_route(path, options = {})
+ options.each { |k, v| options[k] = v.to_s if [:controller, :action].include?(k) && v.is_a?(Symbol) }
route = builder.build(path, options)
routes << route
route
@@ -436,7 +437,7 @@ module ActionController
def recognize(request)
params = recognize_path(request.path, extract_request_environment(request))
request.path_parameters = params.with_indifferent_access
- "#{params[:controller].camelize}Controller".constantize
+ "#{params[:controller].to_s.camelize}Controller".constantize
end
def recognize_path(path, environment={})
diff --git a/vendor/rails/actionpack/lib/action_controller/streaming.rb b/vendor/rails/actionpack/lib/action_controller/streaming.rb
index 9f80f48c..8a9fbfc1 100644
--- a/vendor/rails/actionpack/lib/action_controller/streaming.rb
+++ b/vendor/rails/actionpack/lib/action_controller/streaming.rb
@@ -161,7 +161,7 @@ module ActionController #:nodoc:
content_type = content_type.to_s.strip # fixes a problem with extra '\r' with some browsers
headers.merge!(
- 'Content-Length' => options[:length],
+ 'Content-Length' => options[:length].to_s,
'Content-Type' => content_type,
'Content-Disposition' => disposition,
'Content-Transfer-Encoding' => 'binary'
diff --git a/vendor/rails/actionpack/lib/action_controller/test_process.rb b/vendor/rails/actionpack/lib/action_controller/test_process.rb
index dbaec00b..9de3faba 100644
--- a/vendor/rails/actionpack/lib/action_controller/test_process.rb
+++ b/vendor/rails/actionpack/lib/action_controller/test_process.rb
@@ -1,3 +1,4 @@
+require 'rack/session/abstract/id'
module ActionController #:nodoc:
class TestRequest < Request #:nodoc:
attr_accessor :cookies, :session_options
@@ -13,6 +14,8 @@ module ActionController #:nodoc:
@query_parameters = {}
@session = TestSession.new
+ default_rack_options = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
+ @session_options ||= {:id => generate_sid(default_rack_options[:sidbits])}.merge(default_rack_options)
initialize_default_values
initialize_containers
@@ -110,6 +113,7 @@ module ActionController #:nodoc:
end
def recycle!
+ @env["action_controller.request.request_parameters"] = {}
self.query_parameters = {}
self.path_parameters = {}
@headers, @request_method, @accepts, @content_type = nil, nil, nil, nil
@@ -120,6 +124,10 @@ module ActionController #:nodoc:
end
private
+ def generate_sid(sidbits)
+ "%0#{sidbits / 4}x" % rand(2**sidbits - 1)
+ end
+
def initialize_containers
@cookies = {}
end
@@ -250,7 +258,7 @@ module ActionController #:nodoc:
def cookies
cookies = {}
Array(headers['Set-Cookie']).each do |cookie|
- key, value = cookie.split(";").first.split("=")
+ key, value = cookie.split(";").first.split("=").map {|val| Rack::Utils.unescape(val)}
cookies[key] = value
end
cookies
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
deleted file mode 100644
index b17d8c09..00000000
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require 'thread'
-
-module Rack
- # Rack::Reloader checks on every request, but at most every +secs+
- # seconds, if a file loaded changed, and reloads it, logging to
- # rack.errors.
- #
- # It is recommended you use ShowExceptions to catch SyntaxErrors etc.
-
- class Reloader
- def initialize(app, secs=10)
- @app = app
- @secs = secs # reload every @secs seconds max
- @last = Time.now
- end
-
- def call(env)
- if Time.now > @last + @secs
- Thread.exclusive {
- reload!(env['rack.errors'])
- @last = Time.now
- }
- end
-
- @app.call(env)
- end
-
- def reload!(stderr=$stderr)
- need_reload = $LOADED_FEATURES.find_all { |loaded|
- begin
- if loaded =~ /\A[.\/]/ # absolute filename or 1.9
- abs = loaded
- else
- abs = $LOAD_PATH.map { |path| ::File.join(path, loaded) }.
- find { |file| ::File.exist? file }
- end
-
- if abs
- ::File.mtime(abs) > @last - @secs rescue false
- else
- false
- end
- end
- }
-
- need_reload.each { |l|
- $LOADED_FEATURES.delete l
- }
-
- need_reload.each { |to_load|
- begin
- if require to_load
- stderr.puts "#{self.class}: reloaded `#{to_load}'"
- end
- rescue LoadError, SyntaxError => e
- raise e # Possibly ShowExceptions
- end
- }
-
- stderr.flush
- need_reload
- end
- end
-end
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack.rb
similarity index 95%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack.rb
index 6349b950..371d0156 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack.rb
@@ -3,7 +3,8 @@
# Rack is freely distributable under the terms of an MIT-style license.
# See COPYING or http://www.opensource.org/licenses/mit-license.php.
-$:.unshift(File.expand_path(File.dirname(__FILE__)))
+path = File.expand_path(File.dirname(__FILE__))
+$:.unshift(path) unless $:.include?(path)
# The Rack main module, serving as a namespace for all core Rack
@@ -14,7 +15,7 @@ $:.unshift(File.expand_path(File.dirname(__FILE__)))
module Rack
# The Rack protocol version number implemented.
- VERSION = [0,1]
+ VERSION = [1,0]
# Return the Rack protocol version as a dotted string.
def self.version
@@ -23,7 +24,7 @@ module Rack
# Return the Rack release as a dotted string.
def self.release
- "1.0 bundled"
+ "1.0"
end
autoload :Builder, "rack/builder"
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/adapter/camping.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/adapter/camping.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/abstract/handler.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/abstract/handler.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/abstract/request.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/abstract/request.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/basic.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/basic.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/md5.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/md5.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/nonce.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/nonce.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/params.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/params.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/request.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/digest/request.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/openid.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/auth/openid.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/builder.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/builder.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/cascade.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/cascade.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/chunked.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/chunked.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/commonlogger.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/commonlogger.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/conditionalget.rb
similarity index 94%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/conditionalget.rb
index 7bec8241..046ebdb0 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/conditionalget.rb
@@ -26,6 +26,8 @@ module Rack
headers = Utils::HeaderHash.new(headers)
if etag_matches?(env, headers) || modified_since?(env, headers)
status = 304
+ headers.delete('Content-Type')
+ headers.delete('Content-Length')
body = []
end
[status, headers, body]
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/content_length.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/content_length.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/content_type.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/content_type.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/deflater.rb
similarity index 54%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/deflater.rb
index a42b7477..14137a94 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/deflater.rb
@@ -33,17 +33,15 @@ module Rack
case encoding
when "gzip"
+ headers['Content-Encoding'] = "gzip"
+ headers.delete('Content-Length')
mtime = headers.key?("Last-Modified") ?
Time.httpdate(headers["Last-Modified"]) : Time.now
- body = self.class.gzip(body, mtime)
- size = Rack::Utils.bytesize(body)
- headers = headers.merge("Content-Encoding" => "gzip", "Content-Length" => size.to_s)
- [status, headers, [body]]
+ [status, headers, GzipStream.new(body, mtime)]
when "deflate"
- body = self.class.deflate(body)
- size = Rack::Utils.bytesize(body)
- headers = headers.merge("Content-Encoding" => "deflate", "Content-Length" => size.to_s)
- [status, headers, [body]]
+ headers['Content-Encoding'] = "deflate"
+ headers.delete('Content-Length')
+ [status, headers, DeflateStream.new(body)]
when "identity"
[status, headers, body]
when nil
@@ -52,34 +50,47 @@ module Rack
end
end
- def self.gzip(body, mtime)
- io = StringIO.new
- gzip = Zlib::GzipWriter.new(io)
- gzip.mtime = mtime
+ class GzipStream
+ def initialize(body, mtime)
+ @body = body
+ @mtime = mtime
+ end
- # TODO: Add streaming
- body.each { |part| gzip << part }
+ def each(&block)
+ @writer = block
+ gzip =::Zlib::GzipWriter.new(self)
+ gzip.mtime = @mtime
+ @body.each { |part| gzip << part }
+ @body.close if @body.respond_to?(:close)
+ gzip.close
+ @writer = nil
+ end
- gzip.close
- return io.string
+ def write(data)
+ @writer.call(data)
+ end
end
- DEFLATE_ARGS = [
- Zlib::DEFAULT_COMPRESSION,
- # drop the zlib header which causes both Safari and IE to choke
- -Zlib::MAX_WBITS,
- Zlib::DEF_MEM_LEVEL,
- Zlib::DEFAULT_STRATEGY
- ]
+ class DeflateStream
+ DEFLATE_ARGS = [
+ Zlib::DEFAULT_COMPRESSION,
+ # drop the zlib header which causes both Safari and IE to choke
+ -Zlib::MAX_WBITS,
+ Zlib::DEF_MEM_LEVEL,
+ Zlib::DEFAULT_STRATEGY
+ ]
- # Loosely based on Mongrel's Deflate handler
- def self.deflate(body)
- deflater = Zlib::Deflate.new(*DEFLATE_ARGS)
+ def initialize(body)
+ @body = body
+ end
- # TODO: Add streaming
- body.each { |part| deflater << part }
-
- return deflater.finish
+ def each
+ deflater = ::Zlib::Deflate.new(*DEFLATE_ARGS)
+ @body.each { |part| yield deflater.deflate(part) }
+ @body.close if @body.respond_to?(:close)
+ yield deflater.finish
+ nil
+ end
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/directory.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/directory.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/file.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/file.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler.rb
similarity index 68%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler.rb
index 1018af64..5624a1e7 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler.rb
@@ -10,16 +10,37 @@ module Rack
module Handler
def self.get(server)
return unless server
+ server = server.to_s
if klass = @handlers[server]
obj = Object
klass.split("::").each { |x| obj = obj.const_get(x) }
obj
else
- Rack::Handler.const_get(server.capitalize)
+ try_require('rack/handler', server)
+ const_get(server)
end
end
+ # Transforms server-name constants to their canonical form as filenames,
+ # then tries to require them but silences the LoadError if not found
+ #
+ # Naming convention:
+ #
+ # Foo # => 'foo'
+ # FooBar # => 'foo_bar.rb'
+ # FooBAR # => 'foobar.rb'
+ # FOObar # => 'foobar.rb'
+ # FOOBAR # => 'foobar.rb'
+ # FooBarBaz # => 'foo_bar_baz.rb'
+ def self.try_require(prefix, const_name)
+ file = const_name.gsub(/^[A-Z]+/) { |pre| pre.downcase }.
+ gsub(/[A-Z]+[^A-Z]/, '_\&').downcase
+
+ require(::File.join(prefix, file))
+ rescue LoadError
+ end
+
def self.register(server, klass)
@handlers ||= {}
@handlers[server] = klass
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/cgi.rb
similarity index 97%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/cgi.rb
index e38156c7..f45f3d73 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/cgi.rb
@@ -15,7 +15,7 @@ module Rack
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
- env.update({"rack.version" => [0,1],
+ env.update({"rack.version" => [1,0],
"rack.input" => $stdin,
"rack.errors" => $stderr,
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/evented_mongrel.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/evented_mongrel.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/fastcgi.rb
similarity index 72%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/fastcgi.rb
index 6324c7d2..2cbb5025 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/fastcgi.rb
@@ -1,6 +1,17 @@
require 'fcgi'
require 'socket'
require 'rack/content_length'
+require 'rack/rewindable_input'
+
+class FCGI::Stream
+ alias _rack_read_without_buffer read
+
+ def read(n, buffer=nil)
+ buf = _rack_read_without_buffer n
+ buffer.replace(buf.to_s) if buffer
+ buf
+ end
+end
module Rack
module Handler
@@ -13,34 +24,18 @@ module Rack
}
end
- module ProperStream # :nodoc:
- def each # This is missing by default.
- while line = gets
- yield line
- end
- end
-
- def read(*args)
- if args.empty?
- super || "" # Empty string on EOF.
- else
- super
- end
- end
- end
-
def self.serve(request, app)
app = Rack::ContentLength.new(app)
env = request.env
env.delete "HTTP_CONTENT_LENGTH"
- request.in.extend ProperStream
-
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
- env.update({"rack.version" => [0,1],
- "rack.input" => request.in,
+ rack_input = RewindableInput.new(request.in)
+
+ env.update({"rack.version" => [1,0],
+ "rack.input" => rack_input,
"rack.errors" => request.err,
"rack.multithread" => false,
@@ -57,12 +52,16 @@ module Rack
env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == ""
env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == ""
- status, headers, body = app.call(env)
begin
- send_headers request.out, status, headers
- send_body request.out, body
+ status, headers, body = app.call(env)
+ begin
+ send_headers request.out, status, headers
+ send_body request.out, body
+ ensure
+ body.close if body.respond_to? :close
+ end
ensure
- body.close if body.respond_to? :close
+ rack_input.close
request.finish
end
end
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/lsws.rb
similarity index 97%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/lsws.rb
index c65ba3ec..7231336d 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/lsws.rb
@@ -15,7 +15,7 @@ module Rack
env = ENV.to_hash
env.delete "HTTP_CONTENT_LENGTH"
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
- env.update({"rack.version" => [0,1],
+ env.update({"rack.version" => [1,0],
"rack.input" => StringIO.new($stdin.read.to_s),
"rack.errors" => $stderr,
"rack.multithread" => false,
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/mongrel.rb
similarity index 97%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/mongrel.rb
index f0c0d583..a6b4fa93 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/mongrel.rb
@@ -10,7 +10,7 @@ module Rack
server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
options[:Port] || 8080)
# Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
- # Use is similar to #run, replacing the app argument with a hash of
+ # Use is similar to #run, replacing the app argument with a hash of
# { path=>app, ... } or an instance of Rack::URLMap.
if options[:map]
if app.is_a? Hash
@@ -45,7 +45,7 @@ module Rack
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
- env.update({"rack.version" => [0,1],
+ env.update({"rack.version" => [1,0],
"rack.input" => request.body || StringIO.new(""),
"rack.errors" => $stderr,
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/scgi.rb
similarity index 96%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/scgi.rb
index 9495c663..df0e764d 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/scgi.rb
@@ -7,14 +7,14 @@ module Rack
module Handler
class SCGI < ::SCGI::Processor
attr_accessor :app
-
+
def self.run(app, options=nil)
new(options.merge(:app=>app,
:host=>options[:Host],
:port=>options[:Port],
:socket=>options[:Socket])).listen
end
-
+
def initialize(settings = {})
@app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
@log = Object.new
@@ -22,7 +22,7 @@ module Rack
def @log.error(*args); end
super(settings)
end
-
+
def process_request(request, input_body, socket)
env = {}.replace(request)
env.delete "HTTP_CONTENT_TYPE"
@@ -32,7 +32,7 @@ module Rack
env["PATH_INFO"] = env["REQUEST_PATH"]
env["QUERY_STRING"] ||= ""
env["SCRIPT_NAME"] = ""
- env.update({"rack.version" => [0,1],
+ env.update({"rack.version" => [1,0],
"rack.input" => StringIO.new(input_body),
"rack.errors" => $stderr,
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/swiftiplied_mongrel.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/swiftiplied_mongrel.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/thin.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/thin.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/webrick.rb
similarity index 97%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/webrick.rb
index 22ae14b3..619632a9 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/handler/webrick.rb
@@ -23,7 +23,7 @@ module Rack
env = req.meta_vars
env.delete_if { |k, v| v.nil? }
- env.update({"rack.version" => [0,1],
+ env.update({"rack.version" => [1,0],
"rack.input" => StringIO.new(req.body.to_s),
"rack.errors" => $stderr,
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/head.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/head.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lint.rb
similarity index 77%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lint.rb
index 44a33ce3..bb0693d3 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lint.rb
@@ -88,9 +88,9 @@ module Rack
## within the application. This may be an
## empty string, if the request URL targets
## the application root and does not have a
- ## trailing slash. This information should be
- ## decoded by the server if it comes from a
- ## URL.
+ ## trailing slash. This value may be
+ ## percent-encoded when I originating from
+ ## a URL.
## QUERY_STRING :: The portion of the request URL that
## follows the ? , if any. May be
@@ -111,19 +111,48 @@ module Rack
## In addition to this, the Rack environment must include these
## Rack-specific variables:
- ## rack.version :: The Array [0,1], representing this version of Rack.
+ ## rack.version :: The Array [1,0], representing this version of Rack.
## rack.url_scheme :: +http+ or +https+, depending on the request URL.
## rack.input :: See below, the input stream.
## rack.errors :: See below, the error stream.
## rack.multithread :: true if the application object may be simultaneously invoked by another thread in the same process, false otherwise.
## rack.multiprocess :: true if an equivalent application object may be simultaneously invoked by another process, false otherwise.
## rack.run_once :: true if the server expects (but does not guarantee!) that the application will only be invoked this one time during the life of its containing process. Normally, this will only be true for a server based on CGI (or something similar).
+ ##
+
+ ## Additional environment specifications have approved to
+ ## standardized middleware APIs. None of these are required to
+ ## be implemented by the server.
+
+ ## rack.session :: A hash like interface for storing request session data.
+ ## The store must implement:
+ if session = env['rack.session']
+ ## store(key, value) (aliased as []=);
+ assert("session #{session.inspect} must respond to store and []=") {
+ session.respond_to?(:store) && session.respond_to?(:[]=)
+ }
+
+ ## fetch(key, default = nil) (aliased as []);
+ assert("session #{session.inspect} must respond to fetch and []") {
+ session.respond_to?(:fetch) && session.respond_to?(:[])
+ }
+
+ ## delete(key);
+ assert("session #{session.inspect} must respond to delete") {
+ session.respond_to?(:delete)
+ }
+
+ ## clear;
+ assert("session #{session.inspect} must respond to clear") {
+ session.respond_to?(:clear)
+ }
+ end
## The server or the application can store their own data in the
## environment, too. The keys must contain at least one dot,
## and should be prefixed uniquely. The prefix rack.
- ## is reserved for use with the Rack core distribution and must
- ## not be used otherwise.
+ ## is reserved for use with the Rack core distribution and other
+ ## accepted specifications and must not be used otherwise.
##
%w[REQUEST_METHOD SERVER_NAME SERVER_PORT
@@ -202,9 +231,12 @@ module Rack
end
## === The Input Stream
+ ##
+ ## The input stream is an IO-like object which contains the raw HTTP
+ ## POST data. If it is a file then it must be opened in binary mode.
def check_input(input)
- ## The input stream must respond to +gets+, +each+ and +read+.
- [:gets, :each, :read].each { |method|
+ ## The input stream must respond to +gets+, +each+, +read+ and +rewind+.
+ [:gets, :each, :read, :rewind].each { |method|
assert("rack.input #{input} does not respond to ##{method}") {
input.respond_to? method
}
@@ -222,10 +254,6 @@ module Rack
@input.size
end
- def rewind
- @input.rewind
- end
-
## * +gets+ must be called without arguments and return a string,
## or +nil+ on EOF.
def gets(*args)
@@ -237,21 +265,44 @@ module Rack
v
end
- ## * +read+ must be called without or with one integer argument
- ## and return a string, or +nil+ on EOF.
+ ## * +read+ behaves like IO#read. Its signature is read([length, [buffer]]) .
+ ## If given, +length+ must be an non-negative Integer (>= 0) or +nil+, and +buffer+ must
+ ## be a String and may not be nil. If +length+ is given and not nil, then this method
+ ## reads at most +length+ bytes from the input stream. If +length+ is not given or nil,
+ ## then this method reads all data until EOF.
+ ## When EOF is reached, this method returns nil if +length+ is given and not nil, or ""
+ ## if +length+ is not given or is nil.
+ ## If +buffer+ is given, then the read data will be placed into +buffer+ instead of a
+ ## newly created String object.
def read(*args)
assert("rack.input#read called with too many arguments") {
- args.size <= 1
+ args.size <= 2
}
- if args.size == 1
- assert("rack.input#read called with non-integer argument") {
- args.first.kind_of? Integer
+ if args.size >= 1
+ assert("rack.input#read called with non-integer and non-nil length") {
+ args.first.kind_of?(Integer) || args.first.nil?
+ }
+ assert("rack.input#read called with a negative length") {
+ args.first.nil? || args.first >= 0
}
end
+ if args.size >= 2
+ assert("rack.input#read called with non-String buffer") {
+ args[1].kind_of?(String)
+ }
+ end
+
v = @input.read(*args)
- assert("rack.input#read didn't return a String") {
+
+ assert("rack.input#read didn't return nil or a String") {
v.nil? or v.instance_of? String
}
+ if args[0].nil?
+ assert("rack.input#read(nil) returned nil on EOF") {
+ !v.nil?
+ }
+ end
+
v
end
@@ -266,6 +317,23 @@ module Rack
}
end
+ ## * +rewind+ must be called without arguments. It rewinds the input
+ ## stream back to the beginning. It must not raise Errno::ESPIPE:
+ ## that is, it may not be a pipe or a socket. Therefore, handler
+ ## developers must buffer the input data into some rewindable object
+ ## if the underlying input stream is not rewindable.
+ def rewind(*args)
+ assert("rack.input#rewind called with arguments") { args.size == 0 }
+ assert("rack.input#rewind raised Errno::ESPIPE") {
+ begin
+ @input.rewind
+ true
+ rescue Errno::ESPIPE
+ false
+ end
+ }
+ end
+
## * +close+ must never be called on the input stream.
def close(*args)
assert("rack.input#close must not be called") { false }
@@ -316,13 +384,14 @@ module Rack
## === The Status
def check_status(status)
- ## The status, if parsed as integer (+to_i+), must be greater than or equal to 100.
+ ## This is an HTTP status. When parsed as integer (+to_i+), it must be
+ ## greater than or equal to 100.
assert("Status must be >=100 seen as integer") { status.to_i >= 100 }
end
## === The Headers
def check_headers(header)
- ## The header must respond to each, and yield values of key and value.
+ ## The header must respond to +each+, and yield values of key and value.
assert("headers object should respond to #each, but doesn't (got #{header.class} as headers)") {
header.respond_to? :each
}
@@ -344,7 +413,8 @@ module Rack
## The values of the header must be Strings,
assert("a header value must be a String, but the value of " +
"'#{key}' is a #{value.class}") { value.kind_of? String }
- ## consisting of lines (for multiple header values) seperated by "\n".
+ ## consisting of lines (for multiple header values, e.g. multiple
+ ## Set-Cookie values) seperated by "\n".
value.split("\n").each { |item|
## The lines must not contain characters below 037.
assert("invalid header value #{key}: #{item.inspect}") {
@@ -416,7 +486,7 @@ module Rack
## === The Body
def each
@closed = false
- ## The Body must respond to #each
+ ## The Body must respond to +each+
@body.each { |part|
## and must only yield String values.
assert("Body yielded non-string value #{part.inspect}") {
@@ -425,14 +495,19 @@ module Rack
yield part
}
##
- ## If the Body responds to #close, it will be called after iteration.
+ ## The Body itself should not be an instance of String, as this will
+ ## break in Ruby 1.9.
+ ##
+ ## If the Body responds to +close+, it will be called after iteration.
# XXX howto: assert("Body has not been closed") { @closed }
##
- ## If the Body responds to #to_path, it must return a String
+ ## If the Body responds to +to_path+, it must return a String
## identifying the location of a file whose contents are identical
- ## to that produced by calling #each.
+ ## to that produced by calling +each+; this may be used by the
+ ## server as an alternative, possibly more efficient way to
+ ## transport the response.
if @body.respond_to?(:to_path)
assert("The file identified by body.to_path does not exist") {
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lobster.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lobster.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lock.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/lock.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/methodoverride.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/methodoverride.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/mime.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/mime.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/mock.rb
similarity index 75%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/mock.rb
index 70852da3..fdefb034 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/mock.rb
@@ -40,7 +40,7 @@ module Rack
end
DEFAULT_ENV = {
- "rack.version" => [0,1],
+ "rack.version" => [1,0],
"rack.input" => StringIO.new,
"rack.errors" => StringIO.new,
"rack.multithread" => true,
@@ -73,14 +73,17 @@ module Rack
# Return the Rack environment used for a request to +uri+.
def self.env_for(uri="", opts={})
uri = URI(uri)
+ uri.path = "/#{uri.path}" unless uri.path[0] == ?/
+
env = DEFAULT_ENV.dup
- env["REQUEST_METHOD"] = opts[:method] || "GET"
+ env["REQUEST_METHOD"] = opts[:method] ? opts[:method].to_s.upcase : "GET"
env["SERVER_NAME"] = uri.host || "example.org"
env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
env["QUERY_STRING"] = uri.query.to_s
env["PATH_INFO"] = (!uri.path || uri.path.empty?) ? "/" : uri.path
env["rack.url_scheme"] = uri.scheme || "http"
+ env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
env["SCRIPT_NAME"] = opts[:script_name] || ""
@@ -90,6 +93,27 @@ module Rack
env["rack.errors"] = StringIO.new
end
+ if params = opts[:params]
+ if env["REQUEST_METHOD"] == "GET"
+ params = Utils.parse_nested_query(params) if params.is_a?(String)
+ params.update(Utils.parse_nested_query(env["QUERY_STRING"]))
+ env["QUERY_STRING"] = Utils.build_nested_query(params)
+ elsif !opts.has_key?(:input)
+ opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
+ if params.is_a?(Hash)
+ if data = Utils::Multipart.build_multipart(params)
+ opts[:input] = data
+ opts["CONTENT_LENGTH"] ||= data.length.to_s
+ opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Utils::Multipart::MULTIPART_BOUNDARY}"
+ else
+ opts[:input] = Utils.build_nested_query(params)
+ end
+ else
+ opts[:input] = params
+ end
+ end
+ end
+
opts[:input] ||= ""
if String === opts[:input]
env["rack.input"] = StringIO.new(opts[:input])
@@ -125,7 +149,7 @@ module Rack
@body = ""
body.each { |part| @body << part }
- @errors = errors.string
+ @errors = errors.string if errors.respond_to?(:string)
end
# Status
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/recursive.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/recursive.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/reloader.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/reloader.rb
new file mode 100644
index 00000000..aa2f060b
--- /dev/null
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/reloader.rb
@@ -0,0 +1,106 @@
+# Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
+# All files in this distribution are subject to the terms of the Ruby license.
+
+require 'pathname'
+
+module Rack
+
+ # High performant source reloader
+ #
+ # This class acts as Rack middleware.
+ #
+ # What makes it especially suited for use in a production environment is that
+ # any file will only be checked once and there will only be made one system
+ # call stat(2).
+ #
+ # Please note that this will not reload files in the background, it does so
+ # only when actively called.
+ #
+ # It is performing a check/reload cycle at the start of every request, but
+ # also respects a cool down time, during which nothing will be done.
+ class Reloader
+ def initialize(app, cooldown = 10, backend = Stat)
+ @app = app
+ @cooldown = cooldown
+ @last = (Time.now - cooldown)
+ @cache = {}
+ @mtimes = {}
+
+ extend backend
+ end
+
+ def call(env)
+ if @cooldown and Time.now > @last + @cooldown
+ if Thread.list.size > 1
+ Thread.exclusive{ reload! }
+ else
+ reload!
+ end
+
+ @last = Time.now
+ end
+
+ @app.call(env)
+ end
+
+ def reload!(stderr = $stderr)
+ rotation do |file, mtime|
+ previous_mtime = @mtimes[file] ||= mtime
+ safe_load(file, mtime, stderr) if mtime > previous_mtime
+ end
+ end
+
+ # A safe Kernel::load, issuing the hooks depending on the results
+ def safe_load(file, mtime, stderr = $stderr)
+ load(file)
+ stderr.puts "#{self.class}: reloaded `#{file}'"
+ file
+ rescue LoadError, SyntaxError => ex
+ stderr.puts ex
+ ensure
+ @mtimes[file] = mtime
+ end
+
+ module Stat
+ def rotation
+ files = [$0, *$LOADED_FEATURES].uniq
+ paths = ['./', *$LOAD_PATH].uniq
+
+ files.map{|file|
+ next if file =~ /\.(so|bundle)$/ # cannot reload compiled files
+
+ found, stat = figure_path(file, paths)
+ next unless found and stat and mtime = stat.mtime
+
+ @cache[file] = found
+
+ yield(found, mtime)
+ }.compact
+ end
+
+ # Takes a relative or absolute +file+ name, a couple possible +paths+ that
+ # the +file+ might reside in. Returns the full path and File::Stat for the
+ # path.
+ def figure_path(file, paths)
+ found = @cache[file]
+ found = file if !found and Pathname.new(file).absolute?
+ found, stat = safe_stat(found)
+ return found, stat if found
+
+ paths.each do |possible_path|
+ path = ::File.join(possible_path, file)
+ found, stat = safe_stat(path)
+ return ::File.expand_path(found), stat if found
+ end
+ end
+
+ def safe_stat(file)
+ return unless file
+ stat = ::File.stat(file)
+ return file, stat if stat.file?
+ rescue Errno::ENOENT, Errno::ENOTDIR
+ @cache.delete(file) and false
+ end
+ end
+ end
+end
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/request.rb
similarity index 88%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/request.rb
index d77fa265..04cdde00 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/request.rb
@@ -17,7 +17,7 @@ module Rack
# The environment of the request.
attr_reader :env
- def self.new(env)
+ def self.new(env, *args)
if self == Rack::Request
env["rack.request"] ||= super
else
@@ -38,6 +38,8 @@ module Rack
def query_string; @env["QUERY_STRING"].to_s end
def content_length; @env['CONTENT_LENGTH'] end
def content_type; @env['CONTENT_TYPE'] end
+ def session; @env['rack.session'] ||= {} end
+ def session_options; @env['rack.session.options'] ||= {} end
# The media type (type/subtype) portion of the CONTENT_TYPE header
# without any media type parameters. e.g., when CONTENT_TYPE is
@@ -46,7 +48,7 @@ module Rack
# For more information on the use of media types in HTTP, see:
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
def media_type
- content_type && content_type.split(/\s*[;,]\s*/, 2)[0].downcase
+ content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase
end
# The media type parameters provided in CONTENT_TYPE as a Hash, or
@@ -92,6 +94,14 @@ module Rack
'multipart/form-data'
]
+ # The set of media-types. Requests that do not indicate
+ # one of the media types presents in this list will not be eligible
+ # for param parsing like soap attachments or generic multiparts
+ PARSEABLE_DATA_MEDIA_TYPES = [
+ 'multipart/related',
+ 'multipart/mixed'
+ ]
+
# Determine whether the request body contains form-data by checking
# the request media_type against registered form-data media-types:
# "application/x-www-form-urlencoded" and "multipart/form-data". The
@@ -101,6 +111,12 @@ module Rack
FORM_DATA_MEDIA_TYPES.include?(media_type)
end
+ # Determine whether the request body contains data by checking
+ # the request media_type against registered parse-data media-types
+ def parseable_data?
+ PARSEABLE_DATA_MEDIA_TYPES.include?(media_type)
+ end
+
# Returns the data recieved in the query string.
def GET
if @env["rack.request.query_string"] == query_string
@@ -119,7 +135,7 @@ module Rack
def POST
if @env["rack.request.form_input"].eql? @env["rack.input"]
@env["rack.request.form_hash"]
- elsif form_data?
+ elsif form_data? || parseable_data?
@env["rack.request.form_input"] = @env["rack.input"]
unless @env["rack.request.form_hash"] =
Utils::Multipart.parse_multipart(env)
@@ -131,12 +147,7 @@ module Rack
@env["rack.request.form_vars"] = form_vars
@env["rack.request.form_hash"] = Utils.parse_nested_query(form_vars)
- begin
- @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
- rescue Errno::ESPIPE
- # Handles exceptions raised by input streams that cannot be rewound
- # such as when using plain CGI under Apache
- end
+ @env["rack.input"].rewind
end
@env["rack.request.form_hash"]
else
@@ -212,10 +223,12 @@ module Rack
url
end
+ def path
+ script_name + path_info
+ end
+
def fullpath
- path = script_name + path_info
- path << "?" << query_string unless query_string.empty?
- path
+ query_string.empty? ? path : "#{path}?#{query_string}"
end
def accept_encoding
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/response.rb
similarity index 97%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/response.rb
index caf60d5b..28b4d830 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/response.rb
@@ -95,6 +95,10 @@ module Rack
:expires => Time.at(0) }.merge(value))
end
+ def redirect(target, status=302)
+ self.status = status
+ self["Location"] = target
+ end
def finish(&block)
@block = block
@@ -120,7 +124,7 @@ module Rack
#
def write(str)
s = str.to_s
- @length += s.size
+ @length += Rack::Utils.bytesize(s)
@writer.call s
header["Content-Length"] = @length.to_s
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/rewindable_input.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/rewindable_input.rb
new file mode 100644
index 00000000..2347dc35
--- /dev/null
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/rewindable_input.rb
@@ -0,0 +1,98 @@
+require 'tempfile'
+
+module Rack
+ # Class which can make any IO object rewindable, including non-rewindable ones. It does
+ # this by buffering the data into a tempfile, which is rewindable.
+ #
+ # rack.input is required to be rewindable, so if your input stream IO is non-rewindable
+ # by nature (e.g. a pipe or a socket) then you can wrap it in an object of this class
+ # to easily make it rewindable.
+ #
+ # Don't forget to call #close when you're done. This frees up temporary resources that
+ # RewindableInput uses, though it does *not* close the original IO object.
+ class RewindableInput
+ def initialize(io)
+ @io = io
+ @rewindable_io = nil
+ @unlinked = false
+ end
+
+ def gets
+ make_rewindable unless @rewindable_io
+ @rewindable_io.gets
+ end
+
+ def read(*args)
+ make_rewindable unless @rewindable_io
+ @rewindable_io.read(*args)
+ end
+
+ def each(&block)
+ make_rewindable unless @rewindable_io
+ @rewindable_io.each(&block)
+ end
+
+ def rewind
+ make_rewindable unless @rewindable_io
+ @rewindable_io.rewind
+ end
+
+ # Closes this RewindableInput object without closing the originally
+ # wrapped IO oject. Cleans up any temporary resources that this RewindableInput
+ # has created.
+ #
+ # This method may be called multiple times. It does nothing on subsequent calls.
+ def close
+ if @rewindable_io
+ if @unlinked
+ @rewindable_io.close
+ else
+ @rewindable_io.close!
+ end
+ @rewindable_io = nil
+ end
+ end
+
+ private
+
+ # Ruby's Tempfile class has a bug. Subclass it and fix it.
+ class Tempfile < ::Tempfile
+ def _close
+ @tmpfile.close if @tmpfile
+ @data[1] = nil if @data
+ @tmpfile = nil
+ end
+ end
+
+ def make_rewindable
+ # Buffer all data into a tempfile. Since this tempfile is private to this
+ # RewindableInput object, we chmod it so that nobody else can read or write
+ # it. On POSIX filesystems we also unlink the file so that it doesn't
+ # even have a file entry on the filesystem anymore, though we can still
+ # access it because we have the file handle open.
+ @rewindable_io = Tempfile.new('RackRewindableInput')
+ @rewindable_io.chmod(0000)
+ if filesystem_has_posix_semantics?
+ @rewindable_io.unlink
+ @unlinked = true
+ end
+
+ buffer = ""
+ while @io.read(1024 * 4, buffer)
+ entire_buffer_written_out = false
+ while !entire_buffer_written_out
+ written = @rewindable_io.write(buffer)
+ entire_buffer_written_out = written == buffer.size
+ if !entire_buffer_written_out
+ buffer.slice!(0 .. written - 1)
+ end
+ end
+ end
+ @rewindable_io.rewind
+ end
+
+ def filesystem_has_posix_semantics?
+ RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/
+ end
+ end
+end
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/abstract/id.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/abstract/id.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/cookie.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/cookie.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/memcache.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/memcache.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/pool.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/session/pool.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/showexceptions.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/showexceptions.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/showstatus.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/showstatus.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/static.rb
similarity index 100%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/static.rb
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/urlmap.rb
similarity index 95%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/urlmap.rb
index 0ff32df1..fcf6616c 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/urlmap.rb
@@ -30,7 +30,7 @@ module Rack
location = location.chomp('/')
[host, location, app]
- }.sort_by { |(h, l, a)| [-l.size, h.to_s.size] } # Longest path first
+ }.sort_by { |(h, l, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first
end
def call(env)
diff --git a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/utils.rb
similarity index 69%
rename from vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
rename to vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/utils.rb
index 0a61bce7..42e2e698 100644
--- a/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
+++ b/vendor/rails/actionpack/lib/action_controller/vendor/rack-1.1.pre/rack/utils.rb
@@ -1,3 +1,5 @@
+# -*- encoding: binary -*-
+
require 'set'
require 'tempfile'
@@ -63,7 +65,7 @@ module Rack
module_function :parse_nested_query
def normalize_params(params, name, v = nil)
- name =~ %r([\[\]]*([^\[\]]+)\]*)
+ name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
k = $1 || ''
after = $' || ''
@@ -73,12 +75,12 @@ module Rack
params[k] = v
elsif after == "[]"
params[k] ||= []
- raise TypeError unless params[k].is_a?(Array)
+ raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
params[k] << v
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
child_key = $1
params[k] ||= []
- raise TypeError unless params[k].is_a?(Array)
+ raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
normalize_params(params[k].last, child_key, v)
else
@@ -86,6 +88,7 @@ module Rack
end
else
params[k] ||= {}
+ raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
params[k] = normalize_params(params[k], after, v)
end
@@ -104,6 +107,25 @@ module Rack
end
module_function :build_query
+ def build_nested_query(value, prefix = nil)
+ case value
+ when Array
+ value.map { |v|
+ build_nested_query(v, "#{prefix}[]")
+ }.join("&")
+ when Hash
+ value.map { |k, v|
+ build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
+ }.join("&")
+ when String
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
+ "#{prefix}=#{escape(value)}"
+ else
+ prefix
+ end
+ end
+ module_function :build_nested_query
+
# Escape ampersands, brackets and quotes to their HTML/XML entities.
def escape_html(string)
string.to_s.gsub("&", "&").
@@ -288,11 +310,39 @@ module Rack
# Usually, Rack::Request#POST takes care of calling this.
module Multipart
+ class UploadedFile
+ # The filename, *not* including the path, of the "uploaded" file
+ attr_reader :original_filename
+
+ # The content type of the "uploaded" file
+ attr_accessor :content_type
+
+ def initialize(path, content_type = "text/plain", binary = false)
+ raise "#{path} file does not exist" unless ::File.exist?(path)
+ @content_type = content_type
+ @original_filename = ::File.basename(path)
+ @tempfile = Tempfile.new(@original_filename)
+ @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
+ @tempfile.binmode if binary
+ FileUtils.copy_file(path, @tempfile.path)
+ end
+
+ def path
+ @tempfile.path
+ end
+ alias_method :local_path, :path
+
+ def method_missing(method_name, *args, &block) #:nodoc:
+ @tempfile.__send__(method_name, *args, &block)
+ end
+ end
+
EOL = "\r\n"
+ MULTIPART_BOUNDARY = "AaB03x"
def self.parse_multipart(env)
unless env['CONTENT_TYPE'] =~
- %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
+ %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n
nil
else
boundary = "--#{$1}"
@@ -301,13 +351,16 @@ module Rack
buf = ""
content_length = env['CONTENT_LENGTH'].to_i
input = env['rack.input']
+ input.rewind
- boundary_size = boundary.size + EOL.size
+ boundary_size = Utils.bytesize(boundary) + EOL.size
bufsize = 16384
content_length -= boundary_size
- status = input.read(boundary_size)
+ read_buffer = ''
+
+ status = input.read(boundary_size, read_buffer)
raise EOFError, "bad content body" unless status == boundary + EOL
rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n
@@ -318,15 +371,15 @@ module Rack
filename = content_type = name = nil
until head && buf =~ rx
- if !head && i = buf.index("\r\n\r\n")
+ if !head && i = buf.index(EOL+EOL)
head = buf.slice!(0, i+2) # First \r\n
buf.slice!(0, 2) # Second \r\n
filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
- content_type = head[/Content-Type: (.*)\r\n/ni, 1]
- name = head[/Content-Disposition:.* name="?([^\";]*)"?/ni, 1]
+ content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
+ name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
- if filename
+ if content_type || filename
body = Tempfile.new("RackMultipart")
body.binmode if body.respond_to?(:binmode)
end
@@ -339,7 +392,7 @@ module Rack
body << buf.slice!(0, buf.size - (boundary_size+4))
end
- c = input.read(bufsize < content_length ? bufsize : content_length)
+ c = input.read(bufsize < content_length ? bufsize : content_length, read_buffer)
raise EOFError, "bad content body" if c.nil? || c.empty?
buf << c
content_length -= c.size
@@ -368,6 +421,12 @@ module Rack
data = {:filename => filename, :type => content_type,
:name => name, :tempfile => body, :head => head}
+ elsif !filename && content_type
+ body.rewind
+
+ # Generic multipart cases, not coming from a form
+ data = {:type => content_type,
+ :name => name, :tempfile => body, :head => head}
else
data = body
end
@@ -377,16 +436,81 @@ module Rack
break if buf.empty? || content_length == -1
}
- begin
- input.rewind if input.respond_to?(:rewind)
- rescue Errno::ESPIPE
- # Handles exceptions raised by input streams that cannot be rewound
- # such as when using plain CGI under Apache
- end
+ input.rewind
params
end
end
+
+ def self.build_multipart(params, first = true)
+ if first
+ unless params.is_a?(Hash)
+ raise ArgumentError, "value must be a Hash"
+ end
+
+ multipart = false
+ query = lambda { |value|
+ case value
+ when Array
+ value.each(&query)
+ when Hash
+ value.values.each(&query)
+ when UploadedFile
+ multipart = true
+ end
+ }
+ params.values.each(&query)
+ return nil unless multipart
+ end
+
+ flattened_params = Hash.new
+
+ params.each do |key, value|
+ k = first ? key.to_s : "[#{key}]"
+
+ case value
+ when Array
+ value.map { |v|
+ build_multipart(v, false).each { |subkey, subvalue|
+ flattened_params["#{k}[]#{subkey}"] = subvalue
+ }
+ }
+ when Hash
+ build_multipart(value, false).each { |subkey, subvalue|
+ flattened_params[k + subkey] = subvalue
+ }
+ else
+ flattened_params[k] = value
+ end
+ end
+
+ if first
+ flattened_params.map { |name, file|
+ if file.respond_to?(:original_filename)
+ ::File.open(file.path, "rb") do |f|
+ f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
+<<-EOF
+--#{MULTIPART_BOUNDARY}\r
+Content-Disposition: form-data; name="#{name}"; filename="#{Utils.escape(file.original_filename)}"\r
+Content-Type: #{file.content_type}\r
+Content-Length: #{::File.stat(file.path).size}\r
+\r
+#{f.read}\r
+EOF
+ end
+ else
+<<-EOF
+--#{MULTIPART_BOUNDARY}\r
+Content-Disposition: form-data; name="#{name}"\r
+\r
+#{file}\r
+EOF
+ end
+ }.join + "--#{MULTIPART_BOUNDARY}--\r"
+ else
+ flattened_params
+ end
+ end
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_pack/version.rb b/vendor/rails/actionpack/lib/action_pack/version.rb
index e0aa2a5f..66fca7df 100644
--- a/vendor/rails/actionpack/lib/action_pack/version.rb
+++ b/vendor/rails/actionpack/lib/action_pack/version.rb
@@ -2,7 +2,7 @@ module ActionPack #:nodoc:
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers.rb b/vendor/rails/actionpack/lib/action_view/helpers.rb
index 693ab7c2..97fa2d80 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers.rb
@@ -11,7 +11,7 @@ module ActionView #:nodoc:
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 :JavaScriptHelper, 'action_view/helpers/javascript_helper'
autoload :NumberHelper, 'action_view/helpers/number_helper'
autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index a32beb61..babb9db3 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -272,14 +272,17 @@ module ActionView
# javascript_include_tag :all, :cache => true, :recursive => true
def javascript_include_tag(*sources)
options = sources.extract_options!.stringify_keys
- cache = options.delete("cache")
+ concat = options.delete("concat")
+ cache = concat || options.delete("cache")
recursive = options.delete("recursive")
- if ActionController::Base.perform_caching && cache
+ if concat || (ActionController::Base.perform_caching && cache)
joined_javascript_name = (cache == true ? "all" : cache) + ".js"
- joined_javascript_path = File.join(JAVASCRIPTS_DIR, joined_javascript_name)
+ joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? ASSETS_DIR : JAVASCRIPTS_DIR, joined_javascript_name)
- write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive)) unless File.exists?(joined_javascript_path)
+ unless ActionController::Base.perform_caching && File.exists?(joined_javascript_path)
+ write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
+ end
javascript_src_tag(joined_javascript_name, options)
else
expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
@@ -410,16 +413,25 @@ module ActionView
# The :recursive option is also available for caching:
#
# stylesheet_link_tag :all, :cache => true, :recursive => true
+ #
+ # To force concatenation (even in development mode) set :concat to true. This is useful if
+ # you have too many stylesheets for IE to load.
+ #
+ # stylesheet_link_tag :all, :concat => true
+ #
def stylesheet_link_tag(*sources)
options = sources.extract_options!.stringify_keys
- cache = options.delete("cache")
+ concat = options.delete("concat")
+ cache = concat || options.delete("cache")
recursive = options.delete("recursive")
- if ActionController::Base.perform_caching && cache
+ if concat || (ActionController::Base.perform_caching && cache)
joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
- joined_stylesheet_path = File.join(STYLESHEETS_DIR, joined_stylesheet_name)
+ joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? ASSETS_DIR : STYLESHEETS_DIR, joined_stylesheet_name)
- write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive)) unless File.exists?(joined_stylesheet_path)
+ unless ActionController::Base.perform_caching && File.exists?(joined_stylesheet_path)
+ write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
+ end
stylesheet_tag(joined_stylesheet_name, options)
else
expand_stylesheet_sources(sources, recursive).collect { |source| stylesheet_tag(source, options) }.join("\n")
@@ -679,4 +691,4 @@ module ActionView
end
end
end
-end
\ No newline at end of file
+end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
index a589bcba..2ac407c7 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
@@ -493,7 +493,8 @@ module ActionView
# Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
# assigned to the template (identified by +object+). The text of label will default to the attribute name unless you specify
# it explicitly. Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
- # onto the HTML as an HTML element attribute as in the example shown.
+ # onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to
+ # target labels for radio_button tags (where the value is used in the ID of the input tag).
#
# ==== Examples
# label(:post, :title)
@@ -505,6 +506,9 @@ module ActionView
# label(:post, :title, "A short title", :class => "title_label")
# # => A short title
#
+ # label(:post, :privacy, "Public Post", :value => "public")
+ # # => Public Post
+ #
def label(object_name, method, text = nil, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options)
end
@@ -720,8 +724,9 @@ module ActionView
def to_label_tag(text = nil, options = {})
options = options.stringify_keys
+ tag_value = options.delete("value")
name_and_id = options.dup
- add_default_name_and_id(name_and_id)
+ add_default_name_and_id_for_value(tag_value, name_and_id)
options.delete("index")
options["for"] ||= name_and_id["id"]
content = (text.blank? ? nil : text.to_s) || method_name.humanize
@@ -753,11 +758,7 @@ module ActionView
checked = self.class.radio_button_checked?(value(object), tag_value)
end
options["checked"] = "checked" if checked
- pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase
- options["id"] ||= defined?(@auto_index) ?
- "#{tag_id_with_index(@auto_index)}_#{pretty_tag_value}" :
- "#{tag_id}_#{pretty_tag_value}"
- add_default_name_and_id(options)
+ add_default_name_and_id_for_value(tag_value, options)
tag("input", options)
end
@@ -858,6 +859,17 @@ module ActionView
end
private
+ def add_default_name_and_id_for_value(tag_value, options)
+ if tag_value
+ pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase
+ specified_id = options["id"]
+ add_default_name_and_id(options)
+ options["id"] += "_#{pretty_tag_value}" unless specified_id
+ else
+ add_default_name_and_id(options)
+ end
+ end
+
def add_default_name_and_id(options)
if options.has_key?("index")
options["name"] ||= tag_name_with_index(options["index"])
@@ -905,6 +917,7 @@ module ActionView
attr_accessor :object_name, :object, :options
def initialize(object_name, object, template, options, proc)
+ @nested_child_index = {}
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
@default_options = @options ? @options.slice(:index) : {}
if @object_name.to_s.match(/\[\]$/)
@@ -1007,7 +1020,7 @@ module ActionView
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)
children.map do |child|
- fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block)
+ fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block)
end.join
else
fields_for_nested_model(name, explicit_object || association, args, block)
@@ -1025,9 +1038,9 @@ module ActionView
end
end
- def nested_child_index
- @nested_child_index ||= -1
- @nested_child_index += 1
+ def nested_child_index(name)
+ @nested_child_index[name] ||= -1
+ @nested_child_index[name] += 1
end
end
end
@@ -1036,4 +1049,4 @@ module ActionView
cattr_accessor :default_form_builder
self.default_form_builder = ::ActionView::Helpers::FormBuilder
end
-end
\ No newline at end of file
+end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb
index 6b385ef7..6adbab17 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -230,6 +230,8 @@ module ActionView
#
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def options_for_select(container, selected = nil)
+ return container if String === container
+
container = container.to_a if Hash === container
selected, disabled = extract_selected_and_disabled(selected)
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 6d39a53a..c2171916 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -230,6 +230,8 @@ module ActionView
# * :rows - Specify the number of rows in the textarea
# * :cols - Specify the number of columns in the textarea
# * :disabled - If set to true, the user will not be able to use this input.
+ # * :escape - By default, the contents of the text input are HTML escaped.
+ # If you need unescaped contents, set this to false.
# * Any other key creates standard HTML attributes for the tag.
#
# ==== Examples
@@ -257,7 +259,10 @@ module ActionView
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
end
- content_tag :textarea, content, { "name" => name, "id" => name }.update(options.stringify_keys)
+ escape = options.key?("escape") ? options.delete("escape") : true
+ content = html_escape(content) if escape
+
+ content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
end
# Creates a check box form input tag.
@@ -353,7 +358,8 @@ module ActionView
disable_with << ";#{options.delete('onclick')}" if options['onclick']
options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
- options["onclick"] << "else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }"
+ options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
+ options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
@@ -444,10 +450,10 @@ module ActionView
''
when /^post$/i, "", nil
html_options["method"] = "post"
- protect_against_forgery? ? content_tag(:div, token_tag, :style => 'margin:0;padding:0') : ''
+ protect_against_forgery? ? content_tag(:div, token_tag, :style => 'margin:0;padding:0;display:inline') : ''
else
html_options["method"] = "post"
- content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0')
+ content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0;display:inline')
end
end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb
index 91ef72e5..448d6f5f 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -686,7 +686,7 @@ module ActionView
# Returns an object whose to_json evaluates to +code+. Use this to pass a literal JavaScript
# expression as an argument to another JavaScriptGenerator method.
def literal(code)
- ActiveSupport::JSON::Variable.new(code.to_s)
+ ::ActiveSupport::JSON::Variable.new(code.to_s)
end
# Returns a collection reference by finding it through a CSS +pattern+ in the DOM. This collection can then be
@@ -973,7 +973,7 @@ module ActionView
def loop_on_multiple_args(method, ids)
record(ids.size>1 ?
"#{javascript_object_for(ids)}.each(#{method})" :
- "#{method}(#{ids.first.to_json})")
+ "#{method}(#{::ActiveSupport::JSON.encode(ids.first)})")
end
def page
@@ -997,7 +997,7 @@ module ActionView
end
def javascript_object_for(object)
- object.respond_to?(:to_json) ? object.to_json : object.inspect
+ ::ActiveSupport::JSON.encode(object)
end
def arguments_for_call(arguments, block = nil)
@@ -1139,7 +1139,7 @@ module ActionView
class JavaScriptElementProxy < JavaScriptProxy #:nodoc:
def initialize(generator, id)
@id = id
- super(generator, "$(#{id.to_json})")
+ super(generator, "$(#{::ActiveSupport::JSON.encode(id)})")
end
# Allows access of element attributes through +attribute+. Examples:
@@ -1211,7 +1211,7 @@ module ActionView
enumerate :eachSlice, :variable => variable, :method_args => [number], :yield_args => %w(value index), :return => true, &block
else
add_variable_assignment!(variable)
- append_enumerable_function!("eachSlice(#{number.to_json});")
+ append_enumerable_function!("eachSlice(#{::ActiveSupport::JSON.encode(number)});")
end
end
@@ -1232,7 +1232,7 @@ module ActionView
def pluck(variable, property)
add_variable_assignment!(variable)
- append_enumerable_function!("pluck(#{property.to_json});")
+ append_enumerable_function!("pluck(#{::ActiveSupport::JSON.encode(property)});")
end
def zip(variable, *arguments, &block)
@@ -1296,7 +1296,7 @@ module ActionView
class JavaScriptElementCollectionProxy < JavaScriptCollectionProxy #:nodoc:\
def initialize(generator, pattern)
- super(generator, "$$(#{pattern.to_json})")
+ super(generator, "$$(#{::ActiveSupport::JSON.encode(pattern)})")
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
index e16935ea..04af2781 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
@@ -43,7 +43,7 @@ module ActionView
# You can change the behaviour with various options, see
# http://script.aculo.us for more documentation.
def visual_effect(name, element_id = false, js_options = {})
- element = element_id ? element_id.to_json : "element"
+ element = element_id ? ActiveSupport::JSON.encode(element_id) : "element"
js_options[:queue] = if js_options[:queue].is_a?(Hash)
'{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}'
@@ -138,7 +138,7 @@ module ActionView
end
def sortable_element_js(element_id, options = {}) #:nodoc:
- options[:with] ||= "Sortable.serialize(#{element_id.to_json})"
+ options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})"
options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
@@ -149,7 +149,7 @@ module ActionView
options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment]
options[:only] = array_or_string_for_javascript(options[:only]) if options[:only]
- %(Sortable.create(#{element_id.to_json}, #{options_for_javascript(options)});)
+ %(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
# Makes the element with the DOM ID specified by +element_id+ draggable.
@@ -164,7 +164,7 @@ module ActionView
end
def draggable_element_js(element_id, options = {}) #:nodoc:
- %(new Draggable(#{element_id.to_json}, #{options_for_javascript(options)});)
+ %(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
# Makes the element with the DOM ID specified by +element_id+ receive
@@ -219,7 +219,7 @@ module ActionView
# Confirmation happens during the onDrop callback, so it can be removed from the options
options.delete(:confirm) if options[:confirm]
- %(Droppables.add(#{element_id.to_json}, #{options_for_javascript(options)});)
+ %(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb
index 48bf4717..8463af97 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb
@@ -271,8 +271,8 @@ module ActionView
end
# Returns the text with all the Markdown codes turned into HTML tags.
- # This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth]
- # to be available .
+ # This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth] or another
+ # Markdown library to be installed. .
#
# ==== Examples
# markdown("We are using __Markdown__ now!")
@@ -288,7 +288,7 @@ module ActionView
# markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
# # => '
'
def markdown(text)
- text.blank? ? "" : BlueCloth.new(text).to_html
+ text.blank? ? "" : Markdown.new(text).to_html
end
# Returns +text+ transformed into HTML using simple formatting rules.
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb
index 36e0a78e..92708861 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb
@@ -1,4 +1,4 @@
-require 'action_view/helpers/javascript_helper'
+#require 'action_view/helpers/javascript_helper'
module ActionView
module Helpers #:nodoc:
diff --git a/vendor/rails/actionpack/lib/action_view/paths.rb b/vendor/rails/actionpack/lib/action_view/paths.rb
index 8cc3fe29..a0a2f968 100644
--- a/vendor/rails/actionpack/lib/action_view/paths.rb
+++ b/vendor/rails/actionpack/lib/action_view/paths.rb
@@ -61,7 +61,7 @@ module ActionView #:nodoc:
end
end
- return Template.new(original_template_path, original_template_path.to_s =~ /\A\// ? "" : ".") if File.file?(original_template_path)
+ return Template.new(original_template_path) if File.file?(original_template_path)
raise MissingTemplate.new(self, original_template_path, format)
end
diff --git a/vendor/rails/actionpack/lib/action_view/template.rb b/vendor/rails/actionpack/lib/action_view/template.rb
index c339c8a5..a974f265 100644
--- a/vendor/rails/actionpack/lib/action_view/template.rb
+++ b/vendor/rails/actionpack/lib/action_view/template.rb
@@ -107,9 +107,8 @@ module ActionView #:nodoc:
attr_accessor :locale, :name, :format, :extension
delegate :to_s, :to => :path
- def initialize(template_path, load_path)
- @template_path = template_path.dup
- @load_path, @filename = load_path, File.join(load_path, template_path)
+ def initialize(template_path, load_path = nil)
+ @template_path, @load_path = template_path.dup, load_path
@base_path, @name, @locale, @format, @extension = split(template_path)
@base_path.to_s.gsub!(/\/$/, '') # Push to split method
@@ -180,6 +179,12 @@ module ActionView #:nodoc:
@@exempt_from_layout.any? { |exempted| path =~ exempted }
end
+ def filename
+ # no load_path means this is an "absolute pathed" template
+ load_path ? File.join(load_path, template_path) : template_path
+ end
+ memoize :filename
+
def source
File.read(filename)
end
@@ -212,46 +217,30 @@ module ActionView #:nodoc:
end
def valid_locale?(locale)
- I18n.available_locales.include?(locale.to_sym)
+ locale && I18n.available_locales.include?(locale.to_sym)
end
# Returns file split into an array
# [base_path, name, locale, format, extension]
def split(file)
if m = file.to_s.match(/^(.*\/)?([^\.]+)\.(.*)$/)
- base_path = m[1]
- name = m[2]
- extensions = m[3]
- else
- return
+ [m[1], m[2], *parse_extensions(m[3])]
+ end
+ end
+
+ # returns parsed extensions as an array
+ # [locale, format, extension]
+ def parse_extensions(extensions)
+ exts = extensions.split(".")
+
+ if extension = valid_extension?(exts.last) && exts.pop || nil
+ locale = valid_locale?(exts.first) && exts.shift || nil
+ format = exts.join('.') if exts.any? # join('.') is needed for multipart templates
+ else # no extension, just format
+ format = exts.last
end
- locale = nil
- format = nil
- extension = nil
-
- if m = extensions.split(".")
- if valid_locale?(m[0]) && m[1] && valid_extension?(m[2]) # All three
- locale = m[0]
- format = m[1]
- extension = m[2]
- elsif m[0] && m[1] && valid_extension?(m[2]) # Multipart formats
- format = "#{m[0]}.#{m[1]}"
- extension = m[2]
- elsif valid_locale?(m[0]) && valid_extension?(m[1]) # locale and extension
- locale = m[0]
- extension = m[1]
- elsif valid_extension?(m[1]) # format and extension
- format = m[0]
- extension = m[1]
- elsif valid_extension?(m[0]) # Just extension
- extension = m[0]
- else # No extension
- format = m[0]
- end
- end
-
- [base_path, name, locale, format, extension]
+ [locale, format, extension]
end
end
end
diff --git a/vendor/rails/actionpack/test/abstract_unit.rb b/vendor/rails/actionpack/test/abstract_unit.rb
index cdeee934..0b67e56d 100644
--- a/vendor/rails/actionpack/test/abstract_unit.rb
+++ b/vendor/rails/actionpack/test/abstract_unit.rb
@@ -8,7 +8,7 @@ require 'yaml'
require 'stringio'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
+gem 'mocha', '>= 0.9.7'
require 'mocha'
begin
diff --git a/vendor/rails/actionpack/test/activerecord/active_record_store_test.rb b/vendor/rails/actionpack/test/activerecord/active_record_store_test.rb
index c98892ed..bde36eb9 100644
--- a/vendor/rails/actionpack/test/activerecord/active_record_store_test.rb
+++ b/vendor/rails/actionpack/test/activerecord/active_record_store_test.rb
@@ -27,9 +27,9 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
end
def call_reset_session
- session[:bar]
+ session[:foo]
reset_session
- session[:bar] = "baz"
+ session[:foo] = "baz"
head :ok
end
@@ -86,7 +86,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
get '/get_session_value'
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal 'foo: "baz"', response.body
get '/get_session_id'
assert_response :success
diff --git a/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb b/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb
index cb7922ef..6e92eff0 100644
--- a/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb
@@ -11,6 +11,9 @@ class ActionPackAssertionsController < ActionController::Base
# a standard template
def hello_xml_world() render :template => "test/hello_xml_world"; end
+
+ # a standard partial
+ def partial() render :partial => 'test/partial'; end
# a redirect to an internal location
def redirect_internal() redirect_to "/nothing"; end
@@ -332,6 +335,30 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
assert @response.rendered[:template]
assert 'hello_world', @response.rendered[:template].to_s
end
+
+ def test_assert_template_with_partial
+ get :partial
+ assert_template :partial => '_partial'
+ end
+
+ def test_assert_template_with_nil
+ get :nothing
+ assert_template nil
+ end
+
+ def test_assert_template_with_string
+ get :hello_world
+ assert_template 'hello_world'
+ end
+
+ def test_assert_template_with_symbol
+ get :hello_world
+ assert_template :hello_world
+ end
+
+ def test_assert_template_with_bad_argument
+ assert_raise(ArgumentError) { assert_template 1 }
+ end
# check the redirection location
def test_redirection_location
diff --git a/vendor/rails/actionpack/test/controller/caching_test.rb b/vendor/rails/actionpack/test/controller/caching_test.rb
index 86dafd92..6dcb67e5 100644
--- a/vendor/rails/actionpack/test/controller/caching_test.rb
+++ b/vendor/rails/actionpack/test/controller/caching_test.rb
@@ -1,5 +1,6 @@
require 'fileutils'
require 'abstract_unit'
+require 'active_record_unit'
CACHE_DIR = 'test_cache'
# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
@@ -7,6 +8,10 @@ FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
ActionController::Base.page_cache_directory = FILE_STORE_PATH
ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
+# Force sweeper classes to load
+ActionController::Caching::Sweeper
+ActionController::Caching::Sweeping
+
class PageCachingTestController < ActionController::Base
caches_page :ok, :no_content, :if => Proc.new { |c| !c.request.format.json? }
caches_page :found, :not_found
@@ -152,6 +157,7 @@ class ActionCachingTestController < ActionController::Base
caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
caches_action :with_layout
caches_action :layout_false, :layout => false
+ caches_action :record_not_found, :four_oh_four, :simple_runtime_error
layout 'talk_from_action.erb'
@@ -174,6 +180,18 @@ class ActionCachingTestController < ActionController::Base
render :text => @cache_this, :layout => true
end
+ def record_not_found
+ raise ActiveRecord::RecordNotFound, "oops!"
+ end
+
+ def four_oh_four
+ render :text => "404'd!", :status => 404
+ end
+
+ def simple_runtime_error
+ raise "oops!"
+ end
+
alias_method :show, :index
alias_method :edit, :index
alias_method :destroy, :index
@@ -456,6 +474,27 @@ class ActionCacheTest < ActionController::TestCase
assert_response :success
end
+ def test_record_not_found_returns_404_for_multiple_requests
+ get :record_not_found
+ assert_response 404
+ get :record_not_found
+ assert_response 404
+ end
+
+ def test_four_oh_four_returns_404_for_multiple_requests
+ get :four_oh_four
+ assert_response 404
+ get :four_oh_four
+ assert_response 404
+ end
+
+ def test_simple_runtime_error_returns_500_for_multiple_requests
+ get :simple_runtime_error
+ assert_response 500
+ get :simple_runtime_error
+ assert_response 500
+ end
+
private
def content_to_cache
assigns(:cache_this)
diff --git a/vendor/rails/actionpack/test/controller/cookie_test.rb b/vendor/rails/actionpack/test/controller/cookie_test.rb
index 657be3c4..f7d97e16 100644
--- a/vendor/rails/actionpack/test/controller/cookie_test.rb
+++ b/vendor/rails/actionpack/test/controller/cookie_test.rb
@@ -6,6 +6,10 @@ class CookieTest < ActionController::TestCase
cookies["user_name"] = "david"
end
+ def set_with_with_escapable_characters
+ cookies["that & guy"] = "foo & bar => baz"
+ end
+
def authenticate_for_fourteen_days
cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
end
@@ -53,6 +57,12 @@ class CookieTest < ActionController::TestCase
assert_equal({"user_name" => "david"}, @response.cookies)
end
+ def test_setting_with_escapable_characters
+ get :set_with_with_escapable_characters
+ assert_equal ["that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"], @response.headers["Set-Cookie"]
+ assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
+ end
+
def test_setting_cookie_for_fourteen_days
get :authenticate_for_fourteen_days
assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
diff --git a/vendor/rails/actionpack/test/controller/dispatcher_test.rb b/vendor/rails/actionpack/test/controller/dispatcher_test.rb
index 7887b711..3aa5bf98 100644
--- a/vendor/rails/actionpack/test/controller/dispatcher_test.rb
+++ b/vendor/rails/actionpack/test/controller/dispatcher_test.rb
@@ -25,7 +25,8 @@ class DispatcherTest < Test::Unit::TestCase
def test_clears_dependencies_after_dispatch_if_in_loading_mode
ActiveSupport::Dependencies.expects(:clear).once
- dispatch(false)
+ # Close the response so dependencies kicks in
+ dispatch(false).last.close
end
def test_reloads_routes_before_dispatch_if_in_loading_mode
@@ -49,13 +50,14 @@ class DispatcherTest < Test::Unit::TestCase
Dispatcher.any_instance.expects(:dispatch).raises('b00m')
ActionController::Failsafe.any_instance.expects(:log_failsafe_exception)
+ response = nil
assert_nothing_raised do
- assert_equal [
- 500,
- {"Content-Type" => "text/html"},
- "500 Internal Server Error "
- ], dispatch
+ response = dispatch
end
+ assert_equal 3, response.size
+ assert_equal 500, response[0]
+ assert_equal({"Content-Type" => "text/html"}, response[1])
+ assert_match /500 Internal Server Error/, response[2].join
end
def test_prepare_callbacks
@@ -94,7 +96,7 @@ class DispatcherTest < Test::Unit::TestCase
def dispatch(cache_classes = true)
ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
Dispatcher.define_dispatcher_callbacks(cache_classes)
- Dispatcher.new.call({})
+ Dispatcher.new.call({'rack.input' => StringIO.new('')})
end
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
diff --git a/vendor/rails/actionpack/test/controller/failsafe_test.rb b/vendor/rails/actionpack/test/controller/failsafe_test.rb
new file mode 100644
index 00000000..9008f645
--- /dev/null
+++ b/vendor/rails/actionpack/test/controller/failsafe_test.rb
@@ -0,0 +1,60 @@
+require 'abstract_unit'
+require 'stringio'
+require 'logger'
+
+class FailsafeTest < ActionController::TestCase
+ FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures/failsafe".freeze
+
+ def setup
+ @old_error_file_path = ActionController::Failsafe.error_file_path
+ ActionController::Failsafe.error_file_path = FIXTURE_PUBLIC
+ @app = mock
+ @log_io = StringIO.new
+ @logger = Logger.new(@log_io)
+ @failsafe = ActionController::Failsafe.new(@app)
+ @failsafe.stubs(:failsafe_logger).returns(@logger)
+ end
+
+ def teardown
+ ActionController::Failsafe.error_file_path = @old_error_file_path
+ end
+
+ def app_will_raise_error!
+ @app.expects(:call).then.raises(RuntimeError.new("Printer on fire"))
+ end
+
+ def test_calls_app_and_returns_its_return_value
+ @app.expects(:call).returns([200, { "Content-Type" => "text/html" }, "ok"])
+ assert_equal [200, { "Content-Type" => "text/html" }, "ok"], @failsafe.call({})
+ end
+
+ def test_writes_to_log_file_on_exception
+ app_will_raise_error!
+ @failsafe.call({})
+ assert_match /Printer on fire/, @log_io.string # Logs exception message.
+ assert_match /failsafe_test\.rb/, @log_io.string # Logs backtrace.
+ end
+
+ def test_returns_500_internal_server_error_on_exception
+ app_will_raise_error!
+ response = @failsafe.call({})
+ assert_equal 3, response.size # It is a valid Rack response.
+ assert_equal 500, response[0] # Status is 500.
+ end
+
+ def test_renders_error_page_file_with_erb
+ app_will_raise_error!
+ response = @failsafe.call({})
+ assert_equal 500, response[0]
+ assert_equal "hello my world", response[2].join
+ end
+
+ def test_returns_a_default_message_if_erb_rendering_failed
+ app_will_raise_error!
+ @failsafe.expects(:render_template).raises(RuntimeError.new("Harddisk is crashing"))
+ response = @failsafe.call({})
+ assert_equal 500, response[0]
+ assert_match /500 Internal Server Error/, response[2].join
+ assert_match %r(please read this web application's log file), response[2].join
+ end
+end
diff --git a/vendor/rails/actionpack/test/controller/filter_params_test.rb b/vendor/rails/actionpack/test/controller/filter_params_test.rb
index 0b259a79..0f480881 100644
--- a/vendor/rails/actionpack/test/controller/filter_params_test.rb
+++ b/vendor/rails/actionpack/test/controller/filter_params_test.rb
@@ -23,7 +23,8 @@ class FilterParamTest < Test::Unit::TestCase
[{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
[{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
[{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
- [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']]
+ [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
+ [{'baz'=>[{'foo'=>'baz'}]}, {'baz'=>[{'foo'=>'[FILTERED]'}]}, %w(foo)]]
test_hashes.each do |before_filter, after_filter, filter_words|
FilterParamController.filter_parameter_logging(*filter_words)
diff --git a/vendor/rails/actionpack/test/controller/flash_test.rb b/vendor/rails/actionpack/test/controller/flash_test.rb
index d8a89281..81c724a5 100644
--- a/vendor/rails/actionpack/test/controller/flash_test.rb
+++ b/vendor/rails/actionpack/test/controller/flash_test.rb
@@ -121,7 +121,7 @@ class FlashTest < ActionController::TestCase
assert_nil @response.template.assigns["flash_copy"]["that"], "On second flash"
assert_equal "hello again", @response.template.assigns["flash_copy"]["this"], "On second flash"
end
-
+
def test_flash_after_reset_session
get :use_flash_after_reset_session
assert_equal "hello", @response.template.assigns["flashy_that"]
@@ -139,4 +139,9 @@ class FlashTest < ActionController::TestCase
get :std_action
assert_nil @response.template.assigns["flash_copy"]["foo"]
end
+
+ def test_does_not_set_the_session_if_the_flash_is_empty
+ get :std_action
+ assert_nil session["flash"]
+ end
end
diff --git a/vendor/rails/actionpack/test/controller/http_digest_authentication_test.rb b/vendor/rails/actionpack/test/controller/http_digest_authentication_test.rb
index 00789eea..5cc47ee7 100644
--- a/vendor/rails/actionpack/test/controller/http_digest_authentication_test.rb
+++ b/vendor/rails/actionpack/test/controller/http_digest_authentication_test.rb
@@ -67,6 +67,15 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
assert_equal 'SuperSecret', credentials[:realm]
end
+ test "authentication request with nil credentials" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
+ get :index
+
+ assert_response :unauthorized
+ assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request"
+ assert_not_equal 'Hello Secret', @response.body, "Authentication didn't fail for request"
+ end
+
test "authentication request with invalid password" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo')
get :display
@@ -151,6 +160,21 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
assert_equal 'Definitely Maybe', @response.body
end
+ test "authentication request with _method" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :method => :post)
+ @request.env['rack.methodoverride.original_method'] = 'POST'
+ put :display
+
+ assert_response :success
+ assert assigns(:logged_in)
+ assert_equal 'Definitely Maybe', @response.body
+ end
+
+ test "validate_digest_response should fail with nil returning password_procedure" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
+ assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
+ end
+
private
def encode_credentials(options)
@@ -161,15 +185,22 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
# to prevent tampering of timestamp
ActionController::Base.session_options[:secret] = "session_options_secret"
- # Perform unauthenticated GET to retrieve digest parameters to use on subsequent request
- get :index
+ # Perform unauthenticated request to retrieve digest parameters to use on subsequent request
+ method = options.delete(:method) || 'GET'
+
+ case method.to_s.upcase
+ when 'GET'
+ get :index
+ when 'POST'
+ post :index
+ end
assert_response :unauthorized
credentials = decode_credentials(@response.headers['WWW-Authenticate'])
credentials.merge!(options)
credentials.reverse_merge!(:uri => "#{@request.env['REQUEST_URI']}")
- ActionController::HttpAuthentication::Digest.encode_credentials("GET", credentials, password, options[:password_is_ha1])
+ ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
end
def decode_credentials(header)
diff --git a/vendor/rails/actionpack/test/controller/integration_test.rb b/vendor/rails/actionpack/test/controller/integration_test.rb
index e39a934c..b8281b54 100644
--- a/vendor/rails/actionpack/test/controller/integration_test.rb
+++ b/vendor/rails/actionpack/test/controller/integration_test.rb
@@ -240,6 +240,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest
render :text => "foo: #{params[:foo]}", :status => 200
end
+ def post_with_multiparameter_params
+ render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}", :status => 200
+ end
+
+ def multipart_post_with_multiparameter_params
+ render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, filesize: #{params[:file].size}", :status => 200
+ end
+
def post
render :text => "Created", :status => 201
end
@@ -255,6 +263,8 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
+ FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
+
def test_get
with_test_route_set do
get '/get'
@@ -360,6 +370,24 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
+ def test_post_with_multiparameter_attribute_parameters
+ with_test_route_set do
+ post '/post_with_multiparameter_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz"
+
+ assert_equal 200, status
+ assert_equal "foo(1i): bar, foo(2i): baz", response.body
+ end
+ end
+
+ def test_multipart_post_with_multiparameter_attribute_parameters
+ with_test_route_set do
+ post '/multipart_post_with_multiparameter_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz", :file => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
+
+ assert_equal 200, status
+ assert_equal "foo(1i): bar, foo(2i): baz, filesize: 159528", response.body
+ end
+ end
+
def test_head
with_test_route_set do
head '/get'
diff --git a/vendor/rails/actionpack/test/controller/redirect_test.rb b/vendor/rails/actionpack/test/controller/redirect_test.rb
index 91e21db8..c4574869 100644
--- a/vendor/rails/actionpack/test/controller/redirect_test.rb
+++ b/vendor/rails/actionpack/test/controller/redirect_test.rb
@@ -235,7 +235,10 @@ class RedirectTest < ActionController::TestCase
def test_redirect_with_partial_params
get :module_redirect
- assert_redirected_to :action => 'hello_world'
+
+ assert_deprecated do
+ assert_redirected_to :action => 'hello_world'
+ end
end
def test_redirect_to_nil
diff --git a/vendor/rails/actionpack/test/controller/reloader_test.rb b/vendor/rails/actionpack/test/controller/reloader_test.rb
new file mode 100644
index 00000000..6f1f3c85
--- /dev/null
+++ b/vendor/rails/actionpack/test/controller/reloader_test.rb
@@ -0,0 +1,97 @@
+require 'abstract_unit'
+
+class ReloaderTests < ActiveSupport::TestCase
+ Reloader = ActionController::Reloader
+ Dispatcher = ActionController::Dispatcher
+
+ class MyBody < Array
+ def initialize(&block)
+ @on_close = block
+ end
+
+ def foo
+ "foo"
+ end
+
+ def bar
+ "bar"
+ end
+
+ def close
+ @on_close.call if @on_close
+ end
+ end
+
+ def setup_and_return_body(app = lambda { })
+ Dispatcher.expects(:reload_application)
+ reloader = Reloader.new(app)
+ headers, status, body = reloader.call({ })
+ body
+ end
+
+ def test_it_reloads_the_application_before_the_request
+ Dispatcher.expects(:reload_application)
+ reloader = Reloader.new(lambda {
+ [200, { "Content-Type" => "text/html" }, [""]]
+ })
+ reloader.call({ })
+ end
+
+ def test_returned_body_object_always_responds_to_close
+ body = setup_and_return_body(lambda {
+ [200, { "Content-Type" => "text/html" }, [""]]
+ })
+ assert body.respond_to?(:close)
+ end
+
+ def test_returned_body_object_behaves_like_underlying_object
+ body = setup_and_return_body(lambda {
+ b = MyBody.new
+ b << "hello"
+ b << "world"
+ [200, { "Content-Type" => "text/html" }, b]
+ })
+ assert_equal 2, body.size
+ assert_equal "hello", body[0]
+ assert_equal "world", body[1]
+ assert_equal "foo", body.foo
+ assert_equal "bar", body.bar
+ end
+
+ def test_it_calls_close_on_underlying_object_when_close_is_called_on_body
+ close_called = false
+ body = setup_and_return_body(lambda {
+ b = MyBody.new do
+ close_called = true
+ end
+ [200, { "Content-Type" => "text/html" }, b]
+ })
+ body.close
+ assert close_called
+ end
+
+ def test_returned_body_object_responds_to_all_methods_supported_by_underlying_object
+ body = setup_and_return_body(lambda {
+ [200, { "Content-Type" => "text/html" }, MyBody.new]
+ })
+ assert body.respond_to?(:size)
+ assert body.respond_to?(:each)
+ assert body.respond_to?(:foo)
+ assert body.respond_to?(:bar)
+ end
+
+ def test_it_doesnt_clean_up_the_application_after_call
+ Dispatcher.expects(:cleanup_application).never
+ body = setup_and_return_body(lambda {
+ [200, { "Content-Type" => "text/html" }, MyBody.new]
+ })
+ end
+
+ def test_it_cleans_up_the_application_when_close_is_called_on_body
+ Dispatcher.expects(:cleanup_application)
+ body = setup_and_return_body(lambda {
+ [200, { "Content-Type" => "text/html" }, MyBody.new]
+ })
+ body.close
+ end
+end
diff --git a/vendor/rails/actionpack/test/controller/render_test.rb b/vendor/rails/actionpack/test/controller/render_test.rb
index a5293156..112e9efc 100644
--- a/vendor/rails/actionpack/test/controller/render_test.rb
+++ b/vendor/rails/actionpack/test/controller/render_test.rb
@@ -193,20 +193,24 @@ class TestController < ActionController::Base
render :inline => "<%= controller_name %>"
end
+ def render_json_nil
+ render :json => nil
+ end
+
def render_json_hello_world
- render :json => {:hello => 'world'}.to_json
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
end
def render_json_hello_world_with_callback
- render :json => {:hello => 'world'}.to_json, :callback => 'alert'
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
end
def render_json_with_custom_content_type
- render :json => {:hello => 'world'}.to_json, :content_type => 'text/javascript'
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
end
def render_symbol_json
- render :json => {:hello => 'world'}.to_json
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
end
def render_json_with_render_to_string
@@ -886,33 +890,39 @@ class RenderTest < ActionController::TestCase
assert_equal "The secret is in the sauce\n", @response.body
end
+ def test_render_json_nil
+ get :render_json_nil
+ assert_equal 'null', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
def test_render_json
get :render_json_hello_world
- assert_equal '{"hello": "world"}', @response.body
+ assert_equal '{"hello":"world"}', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_callback
get :render_json_hello_world_with_callback
- assert_equal 'alert({"hello": "world"})', @response.body
+ assert_equal 'alert({"hello":"world"})', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_custom_content_type
get :render_json_with_custom_content_type
- assert_equal '{"hello": "world"}', @response.body
+ assert_equal '{"hello":"world"}', @response.body
assert_equal 'text/javascript', @response.content_type
end
def test_render_symbol_json
get :render_symbol_json
- assert_equal '{"hello": "world"}', @response.body
+ assert_equal '{"hello":"world"}', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_render_to_string
get :render_json_with_render_to_string
- assert_equal '{"hello": "partial html"}', @response.body
+ assert_equal '{"hello":"partial html"}', @response.body
assert_equal 'application/json', @response.content_type
end
diff --git a/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb b/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb
index b812072e..cc81a87c 100644
--- a/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb
+++ b/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb
@@ -96,7 +96,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
# Ruby CGI doesn't handle multipart/mixed for us.
files = params['files']
- assert_kind_of String, files
+ assert_kind_of Tempfile, files
files.force_encoding('ASCII-8BIT') if files.respond_to?(:force_encoding)
assert_equal 19756, files.size
end
@@ -133,46 +133,6 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
end
end
- # The lint wrapper is used in integration tests
- # instead of a normal StringIO class
- InputWrapper = Rack::Lint::InputWrapper
-
- test "parses unwindable stream" do
- InputWrapper.any_instance.stubs(:rewind).raises(Errno::ESPIPE)
- params = parse_multipart('large_text_file')
- assert_equal %w(file foo), params.keys.sort
- assert_equal 'bar', params['foo']
- end
-
- test "uploads and reads file with unwindable input" do
- InputWrapper.any_instance.stubs(:rewind).raises(Errno::ESPIPE)
-
- with_test_routing do
- post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
- assert_equal "File: Hello", response.body
- end
- end
-
- test "passes through rack middleware and uploads file" do
- with_muck_middleware do
- with_test_routing do
- post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
- assert_equal "File: Hello", response.body
- end
- end
- end
-
- test "passes through rack middleware and uploads file with unwindable input" do
- InputWrapper.any_instance.stubs(:rewind).raises(Errno::ESPIPE)
-
- with_muck_middleware do
- with_test_routing do
- post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
- assert_equal "File: Hello", response.body
- end
- end
- end
-
private
def fixture(name)
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
@@ -199,25 +159,4 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
yield
end
end
-
- class MuckMiddleware
- def initialize(app)
- @app = app
- end
-
- def call(env)
- req = Rack::Request.new(env)
- req.params # Parse params
- @app.call(env)
- end
- end
-
- def with_muck_middleware
- original_middleware = ActionController::Dispatcher.middleware
- middleware = original_middleware.dup
- middleware.insert_after ActionController::RewindableInput, MuckMiddleware
- ActionController::Dispatcher.middleware = middleware
- yield
- ActionController::Dispatcher.middleware = original_middleware
- end
end
diff --git a/vendor/rails/actionpack/test/controller/request/test_request_test.rb b/vendor/rails/actionpack/test/controller/request/test_request_test.rb
new file mode 100644
index 00000000..81551b4b
--- /dev/null
+++ b/vendor/rails/actionpack/test/controller/request/test_request_test.rb
@@ -0,0 +1,35 @@
+require 'abstract_unit'
+require 'stringio'
+
+class ActionController::TestRequestTest < ActiveSupport::TestCase
+
+ def setup
+ @request = ActionController::TestRequest.new
+ end
+
+ def test_test_request_has_session_options_initialized
+ assert @request.session_options
+ end
+
+ Rack::Session::Abstract::ID::DEFAULT_OPTIONS.each_key do |option|
+ test "test_rack_default_session_options_#{option}_exists_in_session_options_and_is_default" do
+ assert_equal(Rack::Session::Abstract::ID::DEFAULT_OPTIONS[option],
+ @request.session_options[option],
+ "Missing rack session default option #{option} in request.session_options")
+ end
+ test "test_rack_default_session_options_#{option}_exists_in_session_options" do
+ assert(@request.session_options.has_key?(option),
+ "Missing rack session option #{option} in request.session_options")
+ end
+ end
+
+ def test_session_id_exists_by_default
+ assert_not_nil(@request.session_options[:id])
+ end
+
+ def test_session_id_different_on_each_call
+ prev_id =
+ assert_not_equal(@request.session_options[:id], ActionController::TestRequest.new.session_options[:id])
+ end
+
+end
\ No newline at end of file
diff --git a/vendor/rails/actionpack/test/controller/request/url_encoded_params_parsing_test.rb b/vendor/rails/actionpack/test/controller/request/url_encoded_params_parsing_test.rb
index 7e6099a0..7167cdaf 100644
--- a/vendor/rails/actionpack/test/controller/request/url_encoded_params_parsing_test.rb
+++ b/vendor/rails/actionpack/test/controller/request/url_encoded_params_parsing_test.rb
@@ -126,45 +126,7 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
assert_parses expected, query
end
- test "passes through rack middleware and parses params" do
- with_muck_middleware do
- assert_parses({ "a" => { "b" => "c" } }, "a[b]=c")
- end
- end
-
- # The lint wrapper is used in integration tests
- # instead of a normal StringIO class
- InputWrapper = Rack::Lint::InputWrapper
-
- test "passes through rack middleware and parses params with unwindable input" do
- InputWrapper.any_instance.stubs(:rewind).raises(Errno::ESPIPE)
- with_muck_middleware do
- assert_parses({ "a" => { "b" => "c" } }, "a[b]=c")
- end
- end
-
private
- class MuckMiddleware
- def initialize(app)
- @app = app
- end
-
- def call(env)
- req = Rack::Request.new(env)
- req.params # Parse params
- @app.call(env)
- end
- end
-
- def with_muck_middleware
- original_middleware = ActionController::Dispatcher.middleware
- middleware = original_middleware.dup
- middleware.insert_after ActionController::RewindableInput, MuckMiddleware
- ActionController::Dispatcher.middleware = middleware
- yield
- ActionController::Dispatcher.middleware = original_middleware
- end
-
def with_test_routing
with_routing do |set|
set.draw do |map|
diff --git a/vendor/rails/actionpack/test/controller/request_test.rb b/vendor/rails/actionpack/test/controller/request_test.rb
index c72f885a..c4cc63e6 100644
--- a/vendor/rails/actionpack/test/controller/request_test.rb
+++ b/vendor/rails/actionpack/test/controller/request_test.rb
@@ -3,7 +3,6 @@ require 'abstract_unit'
class RequestTest < ActiveSupport::TestCase
def setup
ActionController::Base.relative_url_root = nil
- @request = ActionController::TestRequest.new
end
def teardown
@@ -11,60 +10,52 @@ class RequestTest < ActiveSupport::TestCase
end
def test_remote_ip
- assert_equal '0.0.0.0', @request.remote_ip
+ request = stub_request 'REMOTE_ADDR' => '1.2.3.4'
+ assert_equal '1.2.3.4', request.remote_ip
- @request.remote_addr = '1.2.3.4'
- assert_equal '1.2.3.4', @request.remote_ip
+ request = stub_request 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6'
+ assert_equal '1.2.3.4', request.remote_ip
- @request.remote_addr = '1.2.3.4,3.4.5.6'
- assert_equal '1.2.3.4', @request.remote_ip
+ request = stub_request 'REMOTE_ADDR' => '1.2.3.4',
+ 'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
+ assert_equal '1.2.3.4', request.remote_ip
- @request.env['HTTP_CLIENT_IP'] = '2.3.4.5'
- assert_equal '1.2.3.4', @request.remote_ip
+ request = stub_request 'REMOTE_ADDR' => '127.0.0.1',
+ 'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.remote_addr = '192.168.0.1'
- assert_equal '2.3.4.5', @request.remote_ip
- @request.env.delete 'HTTP_CLIENT_IP'
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.remote_addr = '1.2.3.4'
- @request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
- assert_equal '1.2.3.4', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '172.16.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.remote_addr = '127.0.0.1'
- @request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '192.168.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '10.0.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = '172.16.0.1,3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '10.0.0.1, 10.0.0.1, 3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = '192.168.0.1,3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '127.0.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,192.168.0.1'
+ assert_equal 'unknown', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1, 10.0.0.1, 3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4'
+ assert_equal '3.4.5.6', request.remote_ip
- @request.env['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,3.4.5.6'
- assert_equal '3.4.5.6', @request.remote_ip
-
- @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,192.168.0.1'
- assert_equal 'unknown', @request.remote_ip
-
- @request.env['HTTP_X_FORWARDED_FOR'] = '9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4'
- assert_equal '3.4.5.6', @request.remote_ip
-
- @request.env['HTTP_CLIENT_IP'] = '8.8.8.8'
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1',
+ 'HTTP_CLIENT_IP' => '2.2.2.2'
e = assert_raise(ActionController::ActionControllerError) {
- @request.remote_ip
+ request.remote_ip
}
assert_match /IP spoofing attack/, e.message
- assert_match /HTTP_X_FORWARDED_FOR="9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4"/, e.message
- assert_match /HTTP_CLIENT_IP="8.8.8.8"/, e.message
+ assert_match /HTTP_X_FORWARDED_FOR="1.1.1.1"/, e.message
+ assert_match /HTTP_CLIENT_IP="2.2.2.2"/, e.message
# turn IP Spoofing detection off.
# This is useful for sites that are aimed at non-IP clients. The typical
@@ -72,336 +63,333 @@ class RequestTest < ActiveSupport::TestCase
# leap of faith to assume that their proxies are ever going to set the
# HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly.
ActionController::Base.ip_spoofing_check = false
- assert_equal('8.8.8.8', @request.remote_ip)
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1',
+ 'HTTP_CLIENT_IP' => '2.2.2.2'
+ assert_equal '2.2.2.2', request.remote_ip
ActionController::Base.ip_spoofing_check = true
- @request.env['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 9.9.9.9'
- assert_equal '8.8.8.8', @request.remote_ip
-
- @request.env.delete 'HTTP_CLIENT_IP'
- @request.env.delete 'HTTP_X_FORWARDED_FOR'
+ request = stub_request 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9'
+ assert_equal '9.9.9.9', request.remote_ip
end
def test_domains
- @request.host = "www.rubyonrails.org"
- assert_equal "rubyonrails.org", @request.domain
+ request = stub_request 'HTTP_HOST' => 'www.rubyonrails.org'
+ assert_equal "rubyonrails.org", request.domain
- @request.host = "www.rubyonrails.co.uk"
- assert_equal "rubyonrails.co.uk", @request.domain(2)
+ request = stub_request 'HTTP_HOST' => "www.rubyonrails.co.uk"
+ assert_equal "rubyonrails.co.uk", request.domain(2)
- @request.host = "192.168.1.200"
- assert_nil @request.domain
+ request = stub_request 'HTTP_HOST' => "192.168.1.200"
+ assert_nil request.domain
- @request.host = "foo.192.168.1.200"
- assert_nil @request.domain
+ request = stub_request 'HTTP_HOST' => "foo.192.168.1.200"
+ assert_nil request.domain
- @request.host = "192.168.1.200.com"
- assert_equal "200.com", @request.domain
-
- @request.host = nil
- assert_nil @request.domain
+ request = stub_request 'HTTP_HOST' => "192.168.1.200.com"
+ assert_equal "200.com", request.domain
end
def test_subdomains
- @request.host = "www.rubyonrails.org"
- assert_equal %w( www ), @request.subdomains
+ request = stub_request 'HTTP_HOST' => "www.rubyonrails.org"
+ assert_equal %w( www ), request.subdomains
- @request.host = "www.rubyonrails.co.uk"
- assert_equal %w( www ), @request.subdomains(2)
+ request = stub_request 'HTTP_HOST' => "www.rubyonrails.co.uk"
+ assert_equal %w( www ), request.subdomains(2)
- @request.host = "dev.www.rubyonrails.co.uk"
- assert_equal %w( dev www ), @request.subdomains(2)
+ request = stub_request 'HTTP_HOST' => "dev.www.rubyonrails.co.uk"
+ assert_equal %w( dev www ), request.subdomains(2)
- @request.host = "foobar.foobar.com"
- assert_equal %w( foobar ), @request.subdomains
+ request = stub_request 'HTTP_HOST' => "foobar.foobar.com"
+ assert_equal %w( foobar ), request.subdomains
- @request.host = "192.168.1.200"
- assert_equal [], @request.subdomains
+ request = stub_request 'HTTP_HOST' => "192.168.1.200"
+ assert_equal [], request.subdomains
- @request.host = "foo.192.168.1.200"
- assert_equal [], @request.subdomains
+ request = stub_request 'HTTP_HOST' => "foo.192.168.1.200"
+ assert_equal [], request.subdomains
- @request.host = "192.168.1.200.com"
- assert_equal %w( 192 168 1 ), @request.subdomains
+ request = stub_request 'HTTP_HOST' => "192.168.1.200.com"
+ assert_equal %w( 192 168 1 ), request.subdomains
- @request.host = nil
- assert_equal [], @request.subdomains
+ request = stub_request 'HTTP_HOST' => nil
+ assert_equal [], request.subdomains
end
def test_port_string
- @request.port = 80
- assert_equal "", @request.port_string
+ request = stub_request 'HTTP_HOST' => 'www.example.org:80'
+ assert_equal "", request.port_string
- @request.port = 8080
- assert_equal ":8080", @request.port_string
+ request = stub_request 'HTTP_HOST' => 'www.example.org:8080'
+ assert_equal ":8080", request.port_string
end
def test_request_uri
- @request.env['SERVER_SOFTWARE'] = 'Apache 42.342.3432'
+ request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri?mapped=1"
+ assert_equal "/path/of/some/uri?mapped=1", request.request_uri
+ assert_equal "/path/of/some/uri", request.path
- @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri?mapped=1"
- assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
- assert_equal "/path/of/some/uri", @request.path
+ request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri"
+ assert_equal "/path/of/some/uri", request.request_uri
+ assert_equal "/path/of/some/uri", request.path
- @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri"
- assert_equal "/path/of/some/uri", @request.request_uri
- assert_equal "/path/of/some/uri", @request.path
+ request = stub_request 'REQUEST_URI' => "/path/of/some/uri"
+ assert_equal "/path/of/some/uri", request.request_uri
+ assert_equal "/path/of/some/uri", request.path
- @request.set_REQUEST_URI "/path/of/some/uri"
- assert_equal "/path/of/some/uri", @request.request_uri
- assert_equal "/path/of/some/uri", @request.path
+ request = stub_request 'REQUEST_URI' => "/"
+ assert_equal "/", request.request_uri
+ assert_equal "/", request.path
- @request.set_REQUEST_URI "/"
- assert_equal "/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'REQUEST_URI' => "/?m=b"
+ assert_equal "/?m=b", request.request_uri
+ assert_equal "/", request.path
- @request.set_REQUEST_URI "/?m=b"
- assert_equal "/?m=b", @request.request_uri
- assert_equal "/", @request.path
-
- @request.set_REQUEST_URI "/"
- @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
- assert_equal "/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'REQUEST_URI' => "/", 'SCRIPT_NAME' => '/dispatch.cgi'
+ assert_equal "/", request.request_uri
+ assert_equal "/", request.path
ActionController::Base.relative_url_root = "/hieraki"
- @request.set_REQUEST_URI "/hieraki/"
- @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
- assert_equal "/hieraki/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'REQUEST_URI' => "/hieraki/", 'SCRIPT_NAME' => "/hieraki/dispatch.cgi"
+ assert_equal "/hieraki/", request.request_uri
+ assert_equal "/", request.path
ActionController::Base.relative_url_root = nil
ActionController::Base.relative_url_root = "/collaboration/hieraki"
- @request.set_REQUEST_URI "/collaboration/hieraki/books/edit/2"
- @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi"
- assert_equal "/collaboration/hieraki/books/edit/2", @request.request_uri
- assert_equal "/books/edit/2", @request.path
+ request = stub_request 'REQUEST_URI' => "/collaboration/hieraki/books/edit/2",
+ 'SCRIPT_NAME' => "/collaboration/hieraki/dispatch.cgi"
+ assert_equal "/collaboration/hieraki/books/edit/2", request.request_uri
+ assert_equal "/books/edit/2", request.path
ActionController::Base.relative_url_root = nil
# The following tests are for when REQUEST_URI is not supplied (as in IIS)
- @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
- @request.env['SCRIPT_NAME'] = nil #"/path/dispatch.rb"
- @request.set_REQUEST_URI nil
- assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
- assert_equal "/path/of/some/uri", @request.path
+ request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1",
+ 'SCRIPT_NAME' => nil,
+ 'REQUEST_URI' => nil
+ assert_equal "/path/of/some/uri?mapped=1", request.request_uri
+ assert_equal "/path/of/some/uri", request.path
ActionController::Base.relative_url_root = '/path'
- @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
- @request.env['SCRIPT_NAME'] = "/path/dispatch.rb"
- @request.set_REQUEST_URI nil
- assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
- assert_equal "/of/some/uri", @request.path
+ request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1",
+ 'SCRIPT_NAME' => "/path/dispatch.rb",
+ 'REQUEST_URI' => nil
+ assert_equal "/path/of/some/uri?mapped=1", request.request_uri
+ assert_equal "/of/some/uri", request.path
ActionController::Base.relative_url_root = nil
- @request.env['PATH_INFO'] = "/path/of/some/uri"
- @request.env['SCRIPT_NAME'] = nil
- @request.set_REQUEST_URI nil
- assert_equal "/path/of/some/uri", @request.request_uri
- assert_equal "/path/of/some/uri", @request.path
+ request = stub_request 'PATH_INFO' => "/path/of/some/uri",
+ 'SCRIPT_NAME' => nil,
+ 'REQUEST_URI' => nil
+ assert_equal "/path/of/some/uri", request.request_uri
+ assert_equal "/path/of/some/uri", request.path
- @request.env['PATH_INFO'] = "/"
- @request.set_REQUEST_URI nil
- assert_equal "/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'PATH_INFO' => '/', 'REQUEST_URI' => nil
+ assert_equal "/", request.request_uri
+ assert_equal "/", request.path
- @request.env['PATH_INFO'] = "/?m=b"
- @request.set_REQUEST_URI nil
- assert_equal "/?m=b", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'PATH_INFO' => '/?m=b', 'REQUEST_URI' => nil
+ assert_equal "/?m=b", request.request_uri
+ assert_equal "/", request.path
- @request.env['PATH_INFO'] = "/"
- @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
- @request.set_REQUEST_URI nil
- assert_equal "/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'PATH_INFO' => "/",
+ 'SCRIPT_NAME' => "/dispatch.cgi",
+ 'REQUEST_URI' => nil
+ assert_equal "/", request.request_uri
+ assert_equal "/", request.path
ActionController::Base.relative_url_root = '/hieraki'
- @request.env['PATH_INFO'] = "/hieraki/"
- @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
- @request.set_REQUEST_URI nil
- assert_equal "/hieraki/", @request.request_uri
- assert_equal "/", @request.path
+ request = stub_request 'PATH_INFO' => "/hieraki/",
+ 'SCRIPT_NAME' => "/hieraki/dispatch.cgi",
+ 'REQUEST_URI' => nil
+ assert_equal "/hieraki/", request.request_uri
+ assert_equal "/", request.path
ActionController::Base.relative_url_root = nil
- @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
+ request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi'
ActionController::Base.relative_url_root = '/hieraki'
- assert_equal "/dispatch.cgi", @request.path
+ assert_equal "/dispatch.cgi", request.path
ActionController::Base.relative_url_root = nil
- @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
+ request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi'
ActionController::Base.relative_url_root = '/foo'
- assert_equal "/hieraki/dispatch.cgi", @request.path
+ assert_equal "/hieraki/dispatch.cgi", request.path
ActionController::Base.relative_url_root = nil
# This test ensures that Rails uses REQUEST_URI over PATH_INFO
ActionController::Base.relative_url_root = nil
- @request.env['REQUEST_URI'] = "/some/path"
- @request.env['PATH_INFO'] = "/another/path"
- @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
- assert_equal "/some/path", @request.request_uri
- assert_equal "/some/path", @request.path
+ request = stub_request 'REQUEST_URI' => "/some/path",
+ 'PATH_INFO' => "/another/path",
+ 'SCRIPT_NAME' => "/dispatch.cgi"
+ assert_equal "/some/path", request.request_uri
+ assert_equal "/some/path", request.path
end
def test_host_with_default_port
- @request.host = "rubyonrails.org"
- @request.port = 80
- assert_equal "rubyonrails.org", @request.host_with_port
+ request = stub_request 'HTTP_HOST' => 'rubyonrails.org:80'
+ assert_equal "rubyonrails.org", request.host_with_port
end
def test_host_with_non_default_port
- @request.host = "rubyonrails.org"
- @request.port = 81
- assert_equal "rubyonrails.org:81", @request.host_with_port
+ request = stub_request 'HTTP_HOST' => 'rubyonrails.org:81'
+ assert_equal "rubyonrails.org:81", request.host_with_port
end
def test_server_software
- assert_equal nil, @request.server_software
+ request = stub_request
+ assert_equal nil, request.server_software
- @request.env['SERVER_SOFTWARE'] = 'Apache3.422'
- assert_equal 'apache', @request.server_software
+ request = stub_request 'SERVER_SOFTWARE' => 'Apache3.422'
+ assert_equal 'apache', request.server_software
- @request.env['SERVER_SOFTWARE'] = 'lighttpd(1.1.4)'
- assert_equal 'lighttpd', @request.server_software
+ request = stub_request 'SERVER_SOFTWARE' => 'lighttpd(1.1.4)'
+ assert_equal 'lighttpd', request.server_software
end
def test_xml_http_request
- assert !@request.xml_http_request?
- assert !@request.xhr?
+ request = stub_request
- @request.env['HTTP_X_REQUESTED_WITH'] = "DefinitelyNotAjax1.0"
- assert !@request.xml_http_request?
- assert !@request.xhr?
+ assert !request.xml_http_request?
+ assert !request.xhr?
- @request.env['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest"
- assert @request.xml_http_request?
- assert @request.xhr?
+ request = stub_request 'HTTP_X_REQUESTED_WITH' => 'DefinitelyNotAjax1.0'
+ assert !request.xml_http_request?
+ assert !request.xhr?
+
+ request = stub_request 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
+ assert request.xml_http_request?
+ assert request.xhr?
end
def test_reports_ssl
- assert !@request.ssl?
- @request.env['HTTPS'] = 'on'
- assert @request.ssl?
+ request = stub_request
+ assert !request.ssl?
+
+ request = stub_request 'HTTPS' => 'on'
+ assert request.ssl?
end
def test_reports_ssl_when_proxied_via_lighttpd
- assert !@request.ssl?
- @request.env['HTTP_X_FORWARDED_PROTO'] = 'https'
- assert @request.ssl?
+ request = stub_request
+ assert !request.ssl?
+
+ request = stub_request 'HTTP_X_FORWARDED_PROTO' => 'https'
+ assert request.ssl?
end
def test_symbolized_request_methods
[:get, :post, :put, :delete].each do |method|
- self.request_method = method
- assert_equal method, @request.method
+ request = stub_request 'REQUEST_METHOD' => method.to_s.upcase
+ assert_equal method, request.method
end
end
def test_invalid_http_method_raises_exception
assert_raise(ActionController::UnknownHttpMethod) do
- self.request_method = :random_method
- @request.request_method
+ request = stub_request 'REQUEST_METHOD' => 'RANDOM_METHOD'
+ request.request_method
end
end
def test_allow_method_hacking_on_post
[:get, :head, :options, :put, :post, :delete].each do |method|
- self.request_method = method
- assert_equal(method == :head ? :get : method, @request.method)
- end
- end
-
- def test_invalid_method_hacking_on_post_raises_exception
- assert_raise(ActionController::UnknownHttpMethod) do
- self.request_method = :_random_method
- @request.request_method
+ request = stub_request 'REQUEST_METHOD' => method.to_s.upcase
+ assert_equal(method == :head ? :get : method, request.method)
end
end
def test_restrict_method_hacking
- @request.instance_eval { @parameters = { :_method => 'put' } }
[:get, :put, :delete].each do |method|
- self.request_method = method
- assert_equal method, @request.method
+ request = stub_request 'REQUEST_METHOD' => method.to_s.upcase,
+ 'action_controller.request.request_parameters' => { :_method => 'put' }
+ assert_equal method, request.method
end
end
def test_head_masquerading_as_get
- self.request_method = :head
- assert_equal :get, @request.method
- assert @request.get?
- assert @request.head?
+ request = stub_request 'REQUEST_METHOD' => 'HEAD'
+ assert_equal :get, request.method
+ assert request.get?
+ assert request.head?
end
def test_xml_format
- @request.instance_eval { @parameters = { :format => 'xml' } }
- assert_equal Mime::XML, @request.format
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => 'xml' })
+ assert_equal Mime::XML, request.format
end
def test_xhtml_format
- @request.instance_eval { @parameters = { :format => 'xhtml' } }
- assert_equal Mime::HTML, @request.format
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => 'xhtml' })
+ assert_equal Mime::HTML, request.format
end
def test_txt_format
- @request.instance_eval { @parameters = { :format => 'txt' } }
- assert_equal Mime::TEXT, @request.format
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => 'txt' })
+ assert_equal Mime::TEXT, request.format
end
- def test_nil_format
+ def test_xml_http_request
ActionController::Base.use_accept_header, old =
false, ActionController::Base.use_accept_header
- @request.instance_eval { @parameters = {} }
- @request.env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest"
- assert @request.xhr?
- assert_equal Mime::JS, @request.format
-
+ request = stub_request 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
+ request.expects(:parameters).at_least_once.returns({})
+ assert request.xhr?
+ assert_equal Mime::JS, request.format
ensure
ActionController::Base.use_accept_header = old
end
def test_content_type
- @request.env["CONTENT_TYPE"] = "text/html"
- assert_equal Mime::HTML, @request.content_type
+ request = stub_request 'CONTENT_TYPE' => 'text/html'
+ assert_equal Mime::HTML, request.content_type
end
- def test_format_assignment_should_set_format
- @request.instance_eval { self.format = :txt }
- assert !@request.format.xml?
- @request.instance_eval { self.format = :xml }
- assert @request.format.xml?
+ def test_can_override_format_with_parameter
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => :txt })
+ assert !request.format.xml?
+
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => :xml })
+ assert request.format.xml?
end
def test_content_no_type
- assert_equal nil, @request.content_type
+ request = stub_request
+ assert_equal nil, request.content_type
end
def test_content_type_xml
- @request.env["CONTENT_TYPE"] = "application/xml"
- assert_equal Mime::XML, @request.content_type
+ request = stub_request 'CONTENT_TYPE' => 'application/xml'
+ assert_equal Mime::XML, request.content_type
end
def test_content_type_with_charset
- @request.env["CONTENT_TYPE"] = "application/xml; charset=UTF-8"
- assert_equal Mime::XML, @request.content_type
+ request = stub_request 'CONTENT_TYPE' => 'application/xml; charset=UTF-8'
+ assert_equal Mime::XML, request.content_type
end
def test_user_agent
- assert_not_nil @request.user_agent
+ request = stub_request 'HTTP_USER_AGENT' => 'TestAgent'
+ assert_equal 'TestAgent', request.user_agent
end
def test_parameters
- @request.stubs(:request_parameters).returns({ "foo" => 1 })
- @request.stubs(:query_parameters).returns({ "bar" => 2 })
+ request = stub_request
+ request.stubs(:request_parameters).returns({ "foo" => 1 })
+ request.stubs(:query_parameters).returns({ "bar" => 2 })
- assert_equal({"foo" => 1, "bar" => 2}, @request.parameters)
- assert_equal({"foo" => 1}, @request.request_parameters)
- assert_equal({"bar" => 2}, @request.query_parameters)
+ assert_equal({"foo" => 1, "bar" => 2}, request.parameters)
+ assert_equal({"foo" => 1}, request.request_parameters)
+ assert_equal({"bar" => 2}, request.query_parameters)
+ end
+
+protected
+
+ def stub_request(env={})
+ ActionController::Request.new(env)
end
- protected
- def request_method=(method)
- @request.env['REQUEST_METHOD'] = method.to_s.upcase
- @request.request_method = nil # Reset the ivar cache
- end
end
diff --git a/vendor/rails/actionpack/test/controller/resources_test.rb b/vendor/rails/actionpack/test/controller/resources_test.rb
index c807e71c..30ab110e 100644
--- a/vendor/rails/actionpack/test/controller/resources_test.rb
+++ b/vendor/rails/actionpack/test/controller/resources_test.rb
@@ -120,6 +120,14 @@ class ResourcesTest < ActionController::TestCase
end
end
+ def test_irregular_id_requirements_should_get_passed_to_member_actions
+ expected_options = {:controller => 'messages', :action => 'custom', :id => '1.1.1'}
+
+ with_restful_routing(:messages, :member => {:custom => :get}, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}) do
+ assert_recognizes(expected_options, :path => 'messages/1.1.1/custom', :method => :get)
+ end
+ end
+
def test_with_path_prefix
with_restful_routing :messages, :path_prefix => '/thread/:thread_id' do
assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
diff --git a/vendor/rails/actionpack/test/controller/routing_test.rb b/vendor/rails/actionpack/test/controller/routing_test.rb
index ef561197..93759425 100644
--- a/vendor/rails/actionpack/test/controller/routing_test.rb
+++ b/vendor/rails/actionpack/test/controller/routing_test.rb
@@ -1662,6 +1662,17 @@ class RouteSetTest < Test::Unit::TestCase
assert_equal 1, set.routes.size
end
+ def test_draw_symbol_controller_name
+ assert_equal 0, set.routes.size
+ set.draw do |map|
+ map.connect '/users/index', :controller => :users, :action => :index
+ end
+ @request = ActionController::TestRequest.new
+ @request.request_uri = '/users/index'
+ assert_nothing_raised { set.recognize(@request) }
+ assert_equal 1, set.routes.size
+ end
+
def test_named_draw
assert_equal 0, set.routes.size
set.draw do |map|
@@ -2476,6 +2487,16 @@ class RouteSetTest < Test::Unit::TestCase
end
assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS'))
end
+
+ def test_routes_with_symbols
+ set.draw do |map|
+ map.connect 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol
+ map.named 'named', :controller => :pages, :action => :show, :name => :as_symbol
+ end
+ assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/unnamed'))
+ assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named'))
+ end
+
end
class RouteLoadingTest < Test::Unit::TestCase
diff --git a/vendor/rails/actionpack/test/controller/send_file_test.rb b/vendor/rails/actionpack/test/controller/send_file_test.rb
index a27e9519..26c7f9bd 100644
--- a/vendor/rails/actionpack/test/controller/send_file_test.rb
+++ b/vendor/rails/actionpack/test/controller/send_file_test.rb
@@ -108,7 +108,7 @@ class SendFileTest < ActionController::TestCase
@controller.send(:send_file_headers!, options)
h = @controller.headers
- assert_equal 1, h['Content-Length']
+ assert_equal '1', h['Content-Length']
assert_equal 'image/png', h['Content-Type']
assert_equal 'disposition; filename="filename"', h['Content-Disposition']
assert_equal 'binary', h['Content-Transfer-Encoding']
diff --git a/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb b/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb
index 48a961ca..40fcd568 100644
--- a/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb
+++ b/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb
@@ -193,27 +193,6 @@ class CookieStoreTest < ActionController::IntegrationTest
end
end
- def test_session_store_with_expire_after
- app = ActionController::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret, :expire_after => 5.hours)
- @integration_session = open_session(app)
-
- with_test_route_set do
- # First request accesses the session
- cookies[SessionKey] = SignedBar
-
- get '/set_session_value'
- assert_response :success
- cookie = headers['Set-Cookie']
-
- # Second request does not access the session so the
- # expires header should not be changed
- get '/no_session_access'
- assert_response :success
- assert_equal cookie, headers['Set-Cookie'],
- "#{unmarshal_session(cookie).inspect} expected but was #{unmarshal_session(headers['Set-Cookie']).inspect}"
- end
- end
-
private
def with_test_route_set
with_routing do |set|
diff --git a/vendor/rails/actionpack/test/controller/test_test.rb b/vendor/rails/actionpack/test/controller/test_test.rb
index 65c894c2..3924b282 100644
--- a/vendor/rails/actionpack/test/controller/test_test.rb
+++ b/vendor/rails/actionpack/test/controller/test_test.rb
@@ -515,6 +515,14 @@ XML
assert_nil @request.instance_variable_get("@request_method")
end
+ def test_params_reset_after_post_request
+ post :no_op, :foo => "bar"
+ assert_equal "bar", @request.params[:foo]
+ @request.recycle!
+ post :no_op
+ assert @request.params[:foo].blank?
+ end
+
%w(controller response request).each do |variable|
%w(get post put delete head process).each do |method|
define_method("test_#{variable}_missing_for_#{method}_raises_error") do
diff --git a/vendor/rails/actionpack/test/fixtures/failsafe/500.html b/vendor/rails/actionpack/test/fixtures/failsafe/500.html
new file mode 100644
index 00000000..f3af84d6
--- /dev/null
+++ b/vendor/rails/actionpack/test/fixtures/failsafe/500.html
@@ -0,0 +1 @@
+hello <%= "my" %> world
\ No newline at end of file
diff --git a/vendor/rails/actionpack/test/template/active_record_helper_test.rb b/vendor/rails/actionpack/test/template/active_record_helper_test.rb
index 83c028b5..11812e78 100644
--- a/vendor/rails/actionpack/test/template/active_record_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/active_record_helper_test.rb
@@ -170,7 +170,7 @@ class ActiveRecordHelperTest < ActionView::TestCase
@request_forgery_protection_token = 'authenticity_token'
@form_authenticity_token = '123'
assert_dom_equal(
- %(
),
+ %(
Title
\nBody
Back to the hill and over it again!
),
form("post")
)
end
diff --git a/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb b/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb
index 32ad87c1..7ffabfff 100644
--- a/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb
@@ -316,9 +316,17 @@ class AssetTagHelperTest < ActionView::TestCase
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js'))
+ assert_dom_equal(
+ %(),
+ javascript_include_tag(:all, :cache => "/absolute/test")
+ )
+
+ assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.js'))
+
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js'))
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host
@@ -546,9 +554,47 @@ class AssetTagHelperTest < ActionView::TestCase
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+
+ assert_dom_equal(
+ %( ),
+ stylesheet_link_tag(:all, :cache => "/absolute/test")
+ )
+
+ assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
+ end
+
+ def test_concat_stylesheet_link_tag_when_caching_off
+ ENV["RAILS_ASSET_ID"] = ""
+
+ assert_dom_equal(
+ %( ),
+ stylesheet_link_tag(:all, :concat => true)
+ )
+
+ expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
+ assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+
+ assert_dom_equal(
+ %( ),
+ stylesheet_link_tag(:all, :concat => "money")
+ )
+
+ assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+
+ assert_dom_equal(
+ %( ),
+ stylesheet_link_tag(:all, :concat => "/absolute/test")
+ )
+
+ assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css'))
+ ensure
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
+ FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
diff --git a/vendor/rails/actionpack/test/template/form_helper_test.rb b/vendor/rails/actionpack/test/template/form_helper_test.rb
index 654eee40..e92f62d8 100644
--- a/vendor/rails/actionpack/test/template/form_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/form_helper_test.rb
@@ -21,6 +21,9 @@ silence_warnings do
attr_accessor :comments
def comments_attributes=(attributes); end
+
+ attr_accessor :tags
+ def tags_attributes=(attributes); end
end
class Comment
@@ -33,6 +36,50 @@ silence_warnings do
def name
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
+
+ attr_accessor :relevances
+ def relevances_attributes=(attributes); end
+
+ end
+
+ class Tag
+ attr_reader :id
+ attr_reader :post_id
+ def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
+ def save; @id = 1; @post_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+
+ attr_accessor :relevances
+ def relevances_attributes=(attributes); end
+
+ end
+
+ class CommentRelevance
+ attr_reader :id
+ attr_reader :comment_id
+ def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
+ def save; @id = 1; @comment_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+ end
+
+ class TagRelevance
+ attr_reader :id
+ attr_reader :tag_id
+ def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
+ def save; @id = 1; @tag_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
end
class Author < Comment
@@ -98,6 +145,11 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal('Title ', label(:post, :title, nil, "for" => "my_for"))
end
+ def test_label_for_radio_buttons_with_value
+ assert_dom_equal('The title goes here ', label("post", "title", "The title goes here", :value => "great_title"))
+ assert_dom_equal('The title goes here ', label("post", "title", "The title goes here", :value => "great title"))
+ end
+
def test_text_field
assert_dom_equal(
' ', text_field("post", "title")
@@ -377,7 +429,7 @@ class FormHelperTest < ActionView::TestCase
expected =
"" +
- "
" +
+ "
" +
" " +
"Back to the hill and over it again! " +
" " +
@@ -531,6 +583,20 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_for_with_index_radio_button
+ form_for(:post, @post) do |f|
+ f.fields_for(:comment, @post, :index => 5) do |c|
+ concat c.radio_button(:title, "hello")
+ end
+ end
+
+ expected = " " +
+ "" +
+ " "
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_nested_fields_for_with_auto_index_on_both
form_for("post[]", @post) do |f|
f.fields_for("comment[]", @post) do |c|
@@ -720,6 +786,51 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_uses_unique_indices_for_different_collection_associations
+ @post.comments = [Comment.new(321)]
+ @post.tags = [Tag.new(123), Tag.new(456)]
+ @post.comments[0].relevances = []
+ @post.tags[0].relevances = []
+ @post.tags[1].relevances = []
+ form_for(:post, @post) do |f|
+ f.fields_for(:comments, @post.comments[0]) do |cf|
+ concat cf.text_field(:name)
+ cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
+ concat crf.text_field(:value)
+ end
+ end
+ f.fields_for(:tags, @post.tags[0]) do |tf|
+ concat tf.text_field(:value)
+ tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
+ concat trf.text_field(:value)
+ end
+ end
+ f.fields_for('tags', @post.tags[1]) do |tf|
+ concat tf.text_field(:value)
+ tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
+ concat trf.text_field(:value)
+ end
+ end
+ end
+
+ expected = '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' '
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_fields_for
fields_for(:post, @post) do |f|
concat f.text_field(:title)
@@ -1072,7 +1183,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_existing_object
form_for(@post) do |f| end
- expected = "
"
+ expected = "
"
assert_equal expected, output_buffer
end
@@ -1093,7 +1204,7 @@ class FormHelperTest < ActionView::TestCase
form_for([@post, @comment]) {}
- expected = %()
+ expected = %()
assert_dom_equal expected, output_buffer
end
@@ -1112,7 +1223,7 @@ class FormHelperTest < ActionView::TestCase
form_for([:admin, @post, @comment]) {}
- expected = %()
+ expected = %()
assert_dom_equal expected, output_buffer
end
@@ -1128,7 +1239,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_existing_object_and_custom_url
form_for(@post, :url => "/super_posts") do |f| end
- expected = "
"
+ expected = "
"
assert_equal expected, output_buffer
end
@@ -1173,4 +1284,4 @@ class FormHelperTest < ActionView::TestCase
def protect_against_forgery?
false
end
-end
\ No newline at end of file
+end
diff --git a/vendor/rails/actionpack/test/template/form_options_helper_test.rb b/vendor/rails/actionpack/test/template/form_options_helper_test.rb
index 78db8797..73624406 100644
--- a/vendor/rails/actionpack/test/template/form_options_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/form_options_helper_test.rb
@@ -80,6 +80,14 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_string_options_for_select
+ options = "Denmark USA Sweden "
+ assert_dom_equal(
+ options,
+ options_for_select(options)
+ )
+ end
+
def test_array_options_for_select
assert_dom_equal(
"<Denmark> \nUSA \nSweden ",
@@ -324,6 +332,20 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_under_fields_for_with_string_and_given_prompt
+ @post = Post.new
+ options = "abe mus hest "
+
+ fields_for :post, @post do |f|
+ concat f.select(:category, options, :prompt => 'The prompt')
+ end
+
+ assert_dom_equal(
+ "The prompt \n#{options} ",
+ output_buffer
+ )
+ end
+
def test_select_with_blank
@post = Post.new
@post.category = ""
diff --git a/vendor/rails/actionpack/test/template/form_tag_helper_test.rb b/vendor/rails/actionpack/test/template/form_tag_helper_test.rb
index c713b8da..09a0c646 100644
--- a/vendor/rails/actionpack/test/template/form_tag_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/form_tag_helper_test.rb
@@ -39,13 +39,13 @@ class FormTagHelperTest < ActionView::TestCase
def test_form_tag_with_method_put
actual = form_tag({}, { :method => :put })
- expected = %(
)
+ expected = %(
)
assert_dom_equal expected, actual
end
def test_form_tag_with_method_delete
actual = form_tag({}, { :method => :delete })
- expected = %(
)
+ expected = %(
)
assert_dom_equal expected, actual
end
@@ -61,7 +61,7 @@ class FormTagHelperTest < ActionView::TestCase
__in_erb_template = ''
form_tag("http://example.com", :method => :put) { concat "Hello world!" }
- expected = %(
Hello world! )
+ expected = %(
Hello world! )
assert_dom_equal expected, output_buffer
end
@@ -153,6 +153,23 @@ class FormTagHelperTest < ActionView::TestCase
assert_dom_equal expected, actual
end
+ def test_text_area_tag_id_sanitized
+ input_elem = root_elem(text_area_tag("item[][description]"))
+ assert_match VALID_HTML_ID, input_elem['id']
+ end
+
+ def test_text_area_tag_escape_content
+ actual = text_area_tag "body", "hello world ", :size => "20x40"
+ expected = %(<b>hello world</b> )
+ assert_dom_equal expected, actual
+ end
+
+ def test_text_area_tag_unescaped_content
+ actual = text_area_tag "body", "hello world ", :size => "20x40", :escape => false
+ expected = %(hello world )
+ assert_dom_equal expected, actual
+ end
+
def test_text_field_tag
actual = text_field_tag "title", "Hello!"
expected = %( )
@@ -252,14 +269,14 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag
assert_dom_equal(
- %( ),
+ %( ),
submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
)
end
def test_submit_tag_with_no_onclick_options
assert_dom_equal(
- %( ),
+ %( ),
submit_tag("Save", :disable_with => "Saving...")
)
end
@@ -273,7 +290,7 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag_with_confirmation_and_with_disable_with
assert_dom_equal(
- %( ),
+ %( ),
submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
)
end
diff --git a/vendor/rails/actionpack/test/template/prototype_helper_test.rb b/vendor/rails/actionpack/test/template/prototype_helper_test.rb
index d6b86a39..3bcf5327 100644
--- a/vendor/rails/actionpack/test/template/prototype_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/prototype_helper_test.rb
@@ -130,7 +130,7 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
end
def test_form_remote_tag_with_method
- assert_dom_equal %(
),
+ assert_dom_equal %(
),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :html => { :method => :put })
end
@@ -158,7 +158,7 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
@record.save
remote_form_for(@record) {}
- expected = %(
)
+ expected = %(
)
assert_dom_equal expected, output_buffer
end
@@ -174,7 +174,7 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
@article.save
remote_form_for([@author, @article]) {}
- expected = %(
)
+ expected = %(
)
assert_dom_equal expected, output_buffer
end
@@ -327,28 +327,28 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest
def test_remove
assert_equal 'Element.remove("foo");',
@generator.remove('foo')
- assert_equal '["foo", "bar", "baz"].each(Element.remove);',
+ assert_equal '["foo","bar","baz"].each(Element.remove);',
@generator.remove('foo', 'bar', 'baz')
end
def test_show
assert_equal 'Element.show("foo");',
@generator.show('foo')
- assert_equal '["foo", "bar", "baz"].each(Element.show);',
+ assert_equal '["foo","bar","baz"].each(Element.show);',
@generator.show('foo', 'bar', 'baz')
end
def test_hide
assert_equal 'Element.hide("foo");',
@generator.hide('foo')
- assert_equal '["foo", "bar", "baz"].each(Element.hide);',
+ assert_equal '["foo","bar","baz"].each(Element.hide);',
@generator.hide('foo', 'bar', 'baz')
end
def test_toggle
assert_equal 'Element.toggle("foo");',
@generator.toggle('foo')
- assert_equal '["foo", "bar", "baz"].each(Element.toggle);',
+ assert_equal '["foo","bar","baz"].each(Element.toggle);',
@generator.toggle('foo', 'bar', 'baz')
end
@@ -385,7 +385,7 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest
assert_equal <<-EOS.chomp, @generator.to_s
Element.insert("element", { top: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });
Element.insert("element", { bottom: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });
-["foo", "bar"].each(Element.remove);
+["foo","bar"].each(Element.remove);
Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
EOS
end
@@ -554,8 +554,8 @@ return (value.className == "welcome");
end
assert_equal <<-EOS.strip, @generator.to_s
-var a = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]);
-var b = [1, 2, 3].zip([4, 5, 6], [7, 8, 9], function(array) {
+var a = [1, 2, 3].zip([4,5,6], [7,8,9]);
+var b = [1, 2, 3].zip([4,5,6], [7,8,9], function(array) {
return array.reverse();
});
EOS
@@ -606,7 +606,7 @@ return value.reverse();
def test_literal
literal = @generator.literal("function() {}")
- assert_equal "function() {}", literal.to_json
+ assert_equal "function() {}", ActiveSupport::JSON.encode(literal)
assert_equal "", @generator.to_s
end
diff --git a/vendor/rails/actionpack/test/template/template_test.rb b/vendor/rails/actionpack/test/template/template_test.rb
new file mode 100644
index 00000000..7caec7ad
--- /dev/null
+++ b/vendor/rails/actionpack/test/template/template_test.rb
@@ -0,0 +1,32 @@
+require 'abstract_unit'
+
+class TemplateTest < Test::Unit::TestCase
+ def test_template_path_parsing
+ with_options :base_path => nil, :name => 'abc', :locale => nil, :format => 'html', :extension => 'erb' do |t|
+ t.assert_parses_template_path 'abc.en.html.erb', :locale => 'en'
+ t.assert_parses_template_path 'abc.en.plain.html.erb', :locale => 'en', :format => 'plain.html'
+ t.assert_parses_template_path 'abc.html.erb'
+ t.assert_parses_template_path 'abc.plain.html.erb', :format => 'plain.html'
+ t.assert_parses_template_path 'abc.erb', :format => nil
+ t.assert_parses_template_path 'abc.html', :extension => nil
+
+ t.assert_parses_template_path '_abc.html.erb', :name => '_abc'
+
+ t.assert_parses_template_path 'test/abc.html.erb', :base_path => 'test'
+ t.assert_parses_template_path './test/abc.html.erb', :base_path => './test'
+ t.assert_parses_template_path '../test/abc.html.erb', :base_path => '../test'
+
+ t.assert_parses_template_path 'abc', :extension => nil, :format => nil, :name => nil
+ t.assert_parses_template_path 'abc.xxx', :extension => nil, :format => 'xxx', :name => 'abc'
+ t.assert_parses_template_path 'abc.html.xxx', :extension => nil, :format => 'xxx', :name => 'abc'
+ end
+ end
+
+ private
+ def assert_parses_template_path(path, parse_results)
+ template = ActionView::Template.new(path, '')
+ parse_results.each_pair do |k, v|
+ assert_block(%Q{Expected template to parse #{k.inspect} from "#{path}" as #{v.inspect}, but got #{template.send(k).inspect}}) { v == template.send(k) }
+ end
+ end
+end
diff --git a/vendor/rails/activerecord/CHANGELOG b/vendor/rails/activerecord/CHANGELOG
index c73ac464..5593a22e 100644
--- a/vendor/rails/activerecord/CHANGELOG
+++ b/vendor/rails/activerecord/CHANGELOG
@@ -1,3 +1,14 @@
+*2.3.3 (July 12, 2009)*
+
+* Added :primary_key option to belongs_to associations. #765 [Szymon Nowak, Philip Hallstrom, Noel Rocha]
+ # employees.company_name references companies.name
+ Employee.belongs_to :company, :primary_key => 'name', :foreign_key => 'company_name'
+
+* Added :touch option to belongs_to associations that will touch the parent record when the current record is saved or destroyed [DHH]
+
+* Added ActiveRecord::Base#touch to update the updated_at/on attributes (or another specified timestamp) with the current time [DHH]
+
+
*2.3.2 [Final] (March 15, 2009)*
* Added ActiveRecord::Base.find_each and ActiveRecord::Base.find_in_batches for batch processing [DHH/Jamis Buck]
diff --git a/vendor/rails/activerecord/Rakefile b/vendor/rails/activerecord/Rakefile
index b50008c9..78550536 100644
--- a/vendor/rails/activerecord/Rakefile
+++ b/vendor/rails/activerecord/Rakefile
@@ -4,7 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require 'rake/contrib/sshpublisher'
require File.join(File.dirname(__FILE__), 'lib', 'active_record', 'version')
require File.expand_path(File.dirname(__FILE__)) + "/test/config"
@@ -177,7 +176,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.3.3' + PKG_BUILD)
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
@@ -231,12 +230,14 @@ end
desc "Publish the beta gem"
task :pgem => [:package] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload
end
diff --git a/vendor/rails/activerecord/lib/active_record/associations.rb b/vendor/rails/activerecord/lib/active_record/associations.rb
index 6d25b36a..66db63ac 100755
--- a/vendor/rails/activerecord/lib/active_record/associations.rb
+++ b/vendor/rails/activerecord/lib/active_record/associations.rb
@@ -957,6 +957,8 @@ module ActiveRecord
# of the association with an "_id" suffix. So a class that defines a belongs_to :person association will use
# "person_id" as the default :foreign_key . Similarly, belongs_to :favorite_person, :class_name => "Person"
# will use a foreign key of "favorite_person_id".
+ # [:primary_key]
+ # Specify the method that returns the primary key of associated object used for the association. By default this is id.
# [:dependent]
# If set to :destroy , the associated object is destroyed when this object is. If set to
# :delete , the associated object is deleted *without* calling its destroy method. This option should not be specified when
@@ -981,15 +983,21 @@ module ActiveRecord
# If false, don't validate the associated objects when saving the parent object. +false+ by default.
# [:autosave]
# If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default.
+ # [:touch]
+ # If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or
+ # destroyed. If you specify a symbol, that attribute will be updated with the current time instead of the updated_at/on attribute.
#
# Option examples:
# belongs_to :firm, :foreign_key => "client_of"
+ # belongs_to :person, :primary_key => "name", :foreign_key => "person_name"
# belongs_to :author, :class_name => "Person", :foreign_key => "author_id"
# belongs_to :valid_coupon, :class_name => "Coupon", :foreign_key => "coupon_id",
# :conditions => 'discounts > #{payments_count}'
# belongs_to :attachable, :polymorphic => true
# belongs_to :project, :readonly => true
# belongs_to :post, :counter_cache => true
+ # belongs_to :company, :touch => true
+ # belongs_to :company, :touch => :employees_last_updated_at
def belongs_to(association_id, options = {})
reflection = create_belongs_to_reflection(association_id, options)
@@ -1001,28 +1009,8 @@ module ActiveRecord
association_constructor_method(:create, reflection, BelongsToAssociation)
end
- # Create the callbacks to update counter cache
- if options[:counter_cache]
- cache_column = reflection.counter_cache_column
-
- method_name = "belongs_to_counter_cache_after_create_for_#{reflection.name}".to_sym
- define_method(method_name) do
- association = send(reflection.name)
- association.class.increment_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
- end
- after_create method_name
-
- method_name = "belongs_to_counter_cache_before_destroy_for_#{reflection.name}".to_sym
- define_method(method_name) do
- association = send(reflection.name)
- association.class.decrement_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
- end
- before_destroy method_name
-
- module_eval(
- "#{reflection.class_name}.send(:attr_readonly,\"#{cache_column}\".intern) if defined?(#{reflection.class_name}) && #{reflection.class_name}.respond_to?(:attr_readonly)"
- )
- end
+ add_counter_cache_callbacks(reflection) if options[:counter_cache]
+ add_touch_callbacks(reflection, options[:touch]) if options[:touch]
configure_dependency_for_belongs_to(reflection)
end
@@ -1329,6 +1317,43 @@ module ActiveRecord
end
end
+ def add_counter_cache_callbacks(reflection)
+ cache_column = reflection.counter_cache_column
+
+ method_name = "belongs_to_counter_cache_after_create_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ association = send(reflection.name)
+ association.class.increment_counter(cache_column, association.id) unless association.nil?
+ end
+ after_create(method_name)
+
+ method_name = "belongs_to_counter_cache_before_destroy_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ association = send(reflection.name)
+ association.class.decrement_counter(cache_column, association.id) unless association.nil?
+ end
+ before_destroy(method_name)
+
+ module_eval(
+ "#{reflection.class_name}.send(:attr_readonly,\"#{cache_column}\".intern) if defined?(#{reflection.class_name}) && #{reflection.class_name}.respond_to?(:attr_readonly)"
+ )
+ end
+
+ def add_touch_callbacks(reflection, touch_attribute)
+ method_name = "belongs_to_touch_after_save_or_destroy_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ association = send(reflection.name)
+
+ if touch_attribute == true
+ association.touch unless association.nil?
+ else
+ association.touch(touch_attribute) unless association.nil?
+ end
+ end
+ after_save(method_name)
+ after_destroy(method_name)
+ end
+
def find_with_associations(options = {})
catch :invalid_query do
join_dependency = JoinDependency.new(self, merge_includes(scope(:find, :include), options[:include]), options[:joins])
@@ -1353,7 +1378,7 @@ module ActiveRecord
dependent_conditions = []
dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}"
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
- dependent_conditions << sanitize_sql(reflection.options[:conditions]) if reflection.options[:conditions]
+ dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.quoted_table_name) if reflection.options[:conditions]
dependent_conditions << extra_conditions if extra_conditions
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
dependent_conditions = dependent_conditions.gsub('@', '\@')
@@ -1497,9 +1522,9 @@ module ActiveRecord
mattr_accessor :valid_keys_for_belongs_to_association
@@valid_keys_for_belongs_to_association = [
- :class_name, :foreign_key, :foreign_type, :remote, :select, :conditions,
+ :class_name, :primary_key, :foreign_key, :foreign_type, :remote, :select, :conditions,
:include, :dependent, :counter_cache, :extend, :polymorphic, :readonly,
- :validate
+ :validate, :touch
]
def create_belongs_to_reflection(association_id, options)
@@ -1643,17 +1668,29 @@ module ActiveRecord
string.scan(/([\.a-zA-Z_]+).?\./).flatten
end
+ def tables_in_hash(hash)
+ return [] if hash.blank?
+ tables = hash.map do |key, value|
+ if value.is_a?(Hash)
+ key.to_s
+ else
+ tables_in_string(key) if key.is_a?(String)
+ end
+ end
+ tables.flatten.compact
+ end
+
def conditions_tables(options)
# look in both sets of conditions
conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond|
case cond
when nil then all
- when Array then all << cond.first
- when Hash then all << cond.keys
- else all << cond
+ when Array then all << tables_in_string(cond.first)
+ when Hash then all << tables_in_hash(cond)
+ else all << tables_in_string(cond)
end
end
- tables_in_string(conditions.join(' '))
+ conditions.flatten
end
def order_tables(options)
@@ -2101,7 +2138,7 @@ module ActiveRecord
klass.send(:type_condition, aliased_table_name)] unless klass.descends_from_active_record?
[through_reflection, reflection].each do |ref|
- join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions]))} " if ref && ref.options[:conditions]
+ join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
end
join
diff --git a/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb b/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb
index 676c4ace..241b9bfe 100644
--- a/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb
@@ -169,8 +169,8 @@ module ActiveRecord
end
# Forwards the call to the reflection class.
- def sanitize_sql(sql)
- @reflection.klass.send(:sanitize_sql, sql)
+ def sanitize_sql(sql, table_name = @reflection.klass.quoted_table_name)
+ @reflection.klass.send(:sanitize_sql, sql, table_name)
end
# Assigns the ID of the owner to the corresponding foreign key in +record+.
diff --git a/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb b/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb
index f05c6be0..05f8f4fe 100644
--- a/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb
+++ b/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -14,7 +14,7 @@ module ActiveRecord
if record.nil?
if counter_cache_name && !@owner.new_record?
- @reflection.klass.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
+ @reflection.klass.decrement_counter(counter_cache_name, previous_record_id) if @owner[@reflection.primary_key_name]
end
@target = @owner[@reflection.primary_key_name] = nil
@@ -27,7 +27,7 @@ module ActiveRecord
end
@target = (AssociationProxy === record ? record.target : record)
- @owner[@reflection.primary_key_name] = record.id unless record.new_record?
+ @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record?
@updated = true
end
@@ -41,18 +41,36 @@ module ActiveRecord
private
def find_target
- @reflection.klass.find(
+ find_method = if @reflection.options[:primary_key]
+ "find_by_#{@reflection.options[:primary_key]}"
+ else
+ "find"
+ end
+ @reflection.klass.send(find_method,
@owner[@reflection.primary_key_name],
:select => @reflection.options[:select],
:conditions => conditions,
:include => @reflection.options[:include],
:readonly => @reflection.options[:readonly]
- )
+ ) if @owner[@reflection.primary_key_name]
end
def foreign_key_present
!@owner[@reflection.primary_key_name].nil?
end
+
+ def record_id(record)
+ record.send(@reflection.options[:primary_key] || :id)
+ end
+
+ def previous_record_id
+ @previous_record_id ||= if @reflection.options[:primary_key]
+ previous_record = @owner.send(@reflection.name)
+ previous_record.nil? ? nil : previous_record.id
+ else
+ @owner[@reflection.primary_key_name]
+ end
+ end
end
end
end
diff --git a/vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
index d8146daa..67e18d69 100644
--- a/vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
+++ b/vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
@@ -7,7 +7,7 @@ module ActiveRecord
else
@target = (AssociationProxy === record ? record.target : record)
- @owner[@reflection.primary_key_name] = record.id
+ @owner[@reflection.primary_key_name] = record_id(record)
@owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
@updated = true
@@ -41,6 +41,10 @@ module ActiveRecord
!@owner[@reflection.primary_key_name].nil?
end
+ def record_id(record)
+ record.send(@reflection.options[:primary_key] || :id)
+ end
+
def association_class
@owner[@reflection.options[:foreign_type]] ? @owner[@reflection.options[:foreign_type]].constantize : nil
end
diff --git a/vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb b/vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb
index 8073ebaf..d93c8e78 100644
--- a/vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -1,31 +1,31 @@
module ActiveRecord
module Associations
class HasOneThroughAssociation < HasManyThroughAssociation
-
+
def create_through_record(new_value) #nodoc:
klass = @reflection.through_reflection.klass
current_object = @owner.send(@reflection.through_reflection.name)
-
+
if current_object
- current_object.update_attributes(construct_join_attributes(new_value))
+ new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy
else
- @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
+ @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value))) if new_value
end
end
-
+
private
def find(*args)
super(args.merge(:limit => 1))
end
-
+
def find_target
super.first
end
def reset_target!
@target = nil
- end
- end
+ end
+ end
end
end
diff --git a/vendor/rails/activerecord/lib/active_record/autosave_association.rb b/vendor/rails/activerecord/lib/active_record/autosave_association.rb
index 741aa2ac..4f63b52c 100644
--- a/vendor/rails/activerecord/lib/active_record/autosave_association.rb
+++ b/vendor/rails/activerecord/lib/active_record/autosave_association.rb
@@ -311,11 +311,13 @@ module ActiveRecord
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_has_one_association(reflection)
if (association = association_instance_get(reflection.name)) && !association.target.nil?
- if reflection.options[:autosave] && association.marked_for_destruction?
+ autosave = reflection.options[:autosave]
+
+ if autosave && association.marked_for_destruction?
association.destroy
- elsif new_record? || association.new_record? || association[reflection.primary_key_name] != id || reflection.options[:autosave]
+ elsif new_record? || association.new_record? || association[reflection.primary_key_name] != id || autosave
association[reflection.primary_key_name] = id
- association.save(false)
+ association.save(!autosave)
end
end
end
@@ -330,13 +332,16 @@ module ActiveRecord
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_belongs_to_association(reflection)
if association = association_instance_get(reflection.name)
- if reflection.options[:autosave] && association.marked_for_destruction?
+ autosave = reflection.options[:autosave]
+
+ if autosave && association.marked_for_destruction?
association.destroy
else
- association.save(false) if association.new_record? || reflection.options[:autosave]
+ association.save(!autosave) if association.new_record? || autosave
if association.updated?
- self[reflection.primary_key_name] = association.id
+ association_id = association.send(reflection.options[:primary_key] || :id)
+ self[reflection.primary_key_name] = association_id
# TODO: Removing this code doesn't seem to matter…
if reflection.options[:polymorphic]
self[reflection.options[:foreign_type]] = association.class.base_class.name.to_s
diff --git a/vendor/rails/activerecord/lib/active_record/base.rb b/vendor/rails/activerecord/lib/active_record/base.rb
index 2a538511..d155837d 100755
--- a/vendor/rails/activerecord/lib/active_record/base.rb
+++ b/vendor/rails/activerecord/lib/active_record/base.rb
@@ -687,14 +687,9 @@ module ActiveRecord #:nodoc:
# Person.exists?(['name LIKE ?', "%#{query}%"])
# Person.exists?
def exists?(id_or_conditions = {})
- connection.select_all(
- construct_finder_sql(
- :select => "#{quoted_table_name}.#{primary_key}",
- :conditions => expand_id_conditions(id_or_conditions),
- :limit => 1
- ),
- "#{name} Exists"
- ).size > 0
+ find_initial(
+ :select => "#{quoted_table_name}.#{primary_key}",
+ :conditions => expand_id_conditions(id_or_conditions)) ? true : false
end
# Creates an object (or multiple objects) and saves it to the database, if validations pass.
@@ -2168,7 +2163,7 @@ module ActiveRecord #:nodoc:
# default_scope :order => 'last_name, first_name'
# end
def default_scope(options = {})
- self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} }
+ self.default_scoping << { :find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {} }
end
# Test whether the given method and optional key are scoped.
@@ -2228,12 +2223,12 @@ module ActiveRecord #:nodoc:
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
- def sanitize_sql_for_conditions(condition)
+ def sanitize_sql_for_conditions(condition, table_name = quoted_table_name)
return nil if condition.blank?
case condition
when Array; sanitize_sql_array(condition)
- when Hash; sanitize_sql_hash_for_conditions(condition)
+ when Hash; sanitize_sql_hash_for_conditions(condition, table_name)
else condition
end
end
@@ -3034,11 +3029,11 @@ module ActiveRecord #:nodoc:
def execute_callstack_for_multiparameter_attributes(callstack)
errors = []
callstack.each do |name, values|
- klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
- if values.empty?
- send(name + "=", nil)
- else
- begin
+ begin
+ klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
+ if values.empty?
+ send(name + "=", nil)
+ else
value = if Time == klass
instantiate_time_object(name, values)
elsif Date == klass
@@ -3052,9 +3047,9 @@ module ActiveRecord #:nodoc:
end
send(name + "=", value)
- rescue => ex
- errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
end
+ rescue => ex
+ errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
end
end
unless errors.empty?
@@ -3080,7 +3075,7 @@ module ActiveRecord #:nodoc:
end
def type_cast_attribute_value(multiparameter_name, value)
- multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
end
def find_parameter_position(multiparameter_name)
diff --git a/vendor/rails/activerecord/lib/active_record/calculations.rb b/vendor/rails/activerecord/lib/active_record/calculations.rb
index f077818d..7af97d72 100644
--- a/vendor/rails/activerecord/lib/active_record/calculations.rb
+++ b/vendor/rails/activerecord/lib/active_record/calculations.rb
@@ -141,30 +141,22 @@ module ActiveRecord
def construct_count_options_from_args(*args)
options = {}
column_name = :all
-
+
# We need to handle
# count()
# count(:column_name=:all)
# count(options={})
# count(column_name=:all, options={})
- # selects specified by scopes
case args.size
- when 0
- column_name = scope(:find)[:select] if scope(:find)
when 1
- if args[0].is_a?(Hash)
- column_name = scope(:find)[:select] if scope(:find)
- options = args[0]
- else
- column_name = args[0]
- end
+ args[0].is_a?(Hash) ? options = args[0] : column_name = args[0]
when 2
column_name, options = args
else
raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}"
- end
-
- [column_name || :all, options]
+ end if args.size > 0
+
+ [column_name, options]
end
def construct_calculation_sql(operation, column_name, options) #:nodoc:
diff --git a/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 913bb521..8440223d 100644
--- a/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -287,7 +287,13 @@ module ActiveRecord
# Escapes binary strings for bytea input to the database.
def escape_bytea(value)
- if PGconn.respond_to?(:escape_bytea)
+ if @connection.respond_to?(:escape_bytea)
+ self.class.instance_eval do
+ define_method(:escape_bytea) do |value|
+ @connection.escape_bytea(value) if value
+ end
+ end
+ elsif PGconn.respond_to?(:escape_bytea)
self.class.instance_eval do
define_method(:escape_bytea) do |value|
PGconn.escape_bytea(value) if value
@@ -376,7 +382,13 @@ module ActiveRecord
# Quotes strings for use in SQL input in the postgres driver for better performance.
def quote_string(s) #:nodoc:
- if PGconn.respond_to?(:escape)
+ if @connection.respond_to?(:escape)
+ self.class.instance_eval do
+ define_method(:quote_string) do |s|
+ @connection.escape(s)
+ end
+ end
+ elsif PGconn.respond_to?(:escape)
self.class.instance_eval do
define_method(:quote_string) do |s|
PGconn.escape(s)
@@ -392,9 +404,28 @@ module ActiveRecord
quote_string(s)
end
+ # Checks the following cases:
+ #
+ # - table_name
+ # - "table.name"
+ # - schema_name.table_name
+ # - schema_name."table.name"
+ # - "schema.name".table_name
+ # - "schema.name"."table.name"
+ def quote_table_name(name)
+ schema, name_part = extract_pg_identifier_from_name(name.to_s)
+
+ unless name_part
+ quote_column_name(schema)
+ else
+ table_name, name_part = extract_pg_identifier_from_name(name_part)
+ "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
+ end
+ end
+
# Quotes column names for use in SQL queries.
def quote_column_name(name) #:nodoc:
- %("#{name}")
+ PGconn.quote_ident(name.to_s)
end
# Quote date/time values for use in SQL input. Includes microseconds
@@ -621,33 +652,36 @@ module ActiveRecord
def indexes(table_name, name = nil)
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
result = query(<<-SQL, name)
- SELECT distinct i.relname, d.indisunique, a.attname
- FROM pg_class t, pg_class i, pg_index d, pg_attribute a
+ SELECT distinct i.relname, d.indisunique, d.indkey, t.oid
+ FROM pg_class t, pg_class i, pg_index d
WHERE i.relkind = 'i'
AND d.indexrelid = i.oid
AND d.indisprimary = 'f'
AND t.oid = d.indrelid
AND t.relname = '#{table_name}'
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
- AND a.attrelid = t.oid
- AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum
- OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum
- OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum
- OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum
- OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum )
ORDER BY i.relname
SQL
- current_index = nil
+
indexes = []
- result.each do |row|
- if current_index != row[0]
- indexes << IndexDefinition.new(table_name, row[0], row[1] == "t", [])
- current_index = row[0]
- end
+ indexes = result.map do |row|
+ index_name = row[0]
+ unique = row[1] == 't'
+ indkey = row[2].split(" ")
+ oid = row[3]
+
+ columns = query(<<-SQL, "Columns for index #{row[0]} on #{table_name}").inject({}) {|attlist, r| attlist[r[1]] = r[0]; attlist}
+ SELECT a.attname, a.attnum
+ FROM pg_attribute a
+ WHERE a.attrelid = #{oid}
+ AND a.attnum IN (#{indkey.join(",")})
+ SQL
+
+ column_names = indkey.map {|attnum| columns[attnum] }
+ IndexDefinition.new(table_name, index_name, unique, column_names)
- indexes.last.columns << row[2]
end
indexes
@@ -745,7 +779,7 @@ module ActiveRecord
AND attr.attrelid = cons.conrelid
AND attr.attnum = cons.conkey[1]
AND cons.contype = 'p'
- AND dep.refobjid = '#{table}'::regclass
+ AND dep.refobjid = '#{quote_table_name(table)}'::regclass
end_sql
if result.nil? or result.empty?
@@ -764,7 +798,7 @@ module ActiveRecord
JOIN pg_attribute attr ON (t.oid = attrelid)
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
- WHERE t.oid = '#{table}'::regclass
+ WHERE t.oid = '#{quote_table_name(table)}'::regclass
AND cons.contype = 'p'
AND def.adsrc ~* 'nextval'
end_sql
@@ -839,7 +873,7 @@ module ActiveRecord
# Drops an index from a table.
def remove_index(table_name, options = {})
- execute "DROP INDEX #{index_name(table_name, options)}"
+ execute "DROP INDEX #{quote_table_name(index_name(table_name, options))}"
end
# Maps logical Rails types to PostgreSQL-specific data types.
@@ -1040,11 +1074,21 @@ module ActiveRecord
SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
- WHERE a.attrelid = '#{table_name}'::regclass
+ WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
end_sql
end
+
+ def extract_pg_identifier_from_name(name)
+ match_data = name[0,1] == '"' ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)
+
+ if match_data
+ rest = name[match_data[0].length..-1]
+ rest = rest[1..-1] if rest[0,1] == "."
+ [match_data[1], (rest.length > 0 ? rest : nil)]
+ end
+ end
end
end
end
diff --git a/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index afd6472d..69f79755 100644
--- a/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -1,3 +1,4 @@
+# encoding: binary
require 'active_record/connection_adapters/abstract_adapter'
module ActiveRecord
@@ -46,6 +47,7 @@ module ActiveRecord
class SQLiteColumn < Column #:nodoc:
class << self
def string_to_binary(value)
+ value = value.dup.force_encoding(Encoding::BINARY) if value.respond_to?(:force_encoding)
value.gsub(/\0|\%/n) do |b|
case b
when "\0" then "%00"
@@ -55,6 +57,7 @@ module ActiveRecord
end
def binary_to_string(value)
+ value = value.dup.force_encoding(Encoding::BINARY) if value.respond_to?(:force_encoding)
value.gsub(/%00|%25/n) do |b|
case b
when "%00" then "\0"
diff --git a/vendor/rails/activerecord/lib/active_record/fixtures.rb b/vendor/rails/activerecord/lib/active_record/fixtures.rb
index c6501113..77f0931e 100644
--- a/vendor/rails/activerecord/lib/active_record/fixtures.rb
+++ b/vendor/rails/activerecord/lib/active_record/fixtures.rb
@@ -1,6 +1,7 @@
require 'erb'
require 'yaml'
require 'csv'
+require 'zlib'
require 'active_support/dependencies'
require 'active_support/test_case'
@@ -433,6 +434,7 @@ end
# Any fixture labeled "DEFAULTS" is safely ignored.
class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
+ MAX_ID = 2 ** 31 - 1
DEFAULT_FILTER_RE = /\.ya?ml$/
@@all_cached_fixtures = {}
@@ -524,11 +526,10 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
cached_fixtures(connection, table_names)
end
- # Returns a consistent identifier for +label+. This will always
- # be a positive integer, and will always be the same for a given
- # label, assuming the same OS, platform, and version of Ruby.
+ # Returns a consistent, platform-independent identifier for +label+.
+ # Identifiers are positive integers less than 2^32.
def self.identify(label)
- label.to_s.hash.abs
+ Zlib.crc32(label.to_s) % MAX_ID
end
attr_reader :table_name, :name
diff --git a/vendor/rails/activerecord/lib/active_record/named_scope.rb b/vendor/rails/activerecord/lib/active_record/named_scope.rb
index 1f3ef300..3df70890 100644
--- a/vendor/rails/activerecord/lib/active_record/named_scope.rb
+++ b/vendor/rails/activerecord/lib/active_record/named_scope.rb
@@ -114,7 +114,7 @@ module ActiveRecord
end
end
- delegate :scopes, :with_scope, :to => :proxy_scope
+ delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope
def initialize(proxy_scope, options, &block)
options ||= {}
@@ -178,7 +178,7 @@ module ActiveRecord
else
with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {}}, :reverse_merge) do
method = :new if method == :build
- if current_scoped_methods_when_defined
+ if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined)
with_scope current_scoped_methods_when_defined do
proxy_scope.send(method, *args, &block)
end
diff --git a/vendor/rails/activerecord/lib/active_record/schema_dumper.rb b/vendor/rails/activerecord/lib/active_record/schema_dumper.rb
index 557a5549..651cd361 100644
--- a/vendor/rails/activerecord/lib/active_record/schema_dumper.rb
+++ b/vendor/rails/activerecord/lib/active_record/schema_dumper.rb
@@ -78,11 +78,14 @@ HEADER
begin
tbl = StringIO.new
+ # first dump primary key column
if @connection.respond_to?(:pk_and_sequence_for)
pk, pk_seq = @connection.pk_and_sequence_for(table)
+ elsif @connection.respond_to?(:primary_key)
+ pk = @connection.primary_key(table)
end
pk ||= 'id'
-
+
tbl.print " create_table #{table.inspect}"
if columns.detect { |c| c.name == pk }
if pk != 'id'
@@ -94,6 +97,7 @@ HEADER
tbl.print ", :force => true"
tbl.puts " do |t|"
+ # then dump all non-primary key columns
column_specs = columns.map do |column|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
next if column.name == pk
diff --git a/vendor/rails/activerecord/lib/active_record/serialization.rb b/vendor/rails/activerecord/lib/active_record/serialization.rb
index 870b4b2d..629ce9a1 100644
--- a/vendor/rails/activerecord/lib/active_record/serialization.rb
+++ b/vendor/rails/activerecord/lib/active_record/serialization.rb
@@ -5,8 +5,9 @@ module ActiveRecord #:nodoc:
class Serializer #:nodoc:
attr_reader :options
- def initialize(record, options = {})
- @record, @options = record, options.dup
+ def initialize(record, options = nil)
+ @record = record
+ @options = options ? options.dup : {}
end
# To replicate the behavior in ActiveRecord#attributes,
diff --git a/vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb b/vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb
index 1fd65ed0..085d4f17 100644
--- a/vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb
+++ b/vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb
@@ -1,8 +1,10 @@
+require 'active_support/json'
+require 'active_support/core_ext/module/model_naming'
+
module ActiveRecord #:nodoc:
module Serialization
def self.included(base)
base.cattr_accessor :include_root_in_json, :instance_writer => false
- base.extend ClassMethods
end
# Returns a JSON string representing the model. Some configuration is
@@ -72,28 +74,16 @@ module ActiveRecord #:nodoc:
# {"comments": [{"body": "Don't think too hard"}],
# "title": "So I was thinking"}]}
def to_json(options = {})
- if include_root_in_json
- "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
- else
- JsonSerializer.new(self, options).to_s
- end
+ hash = Serializer.new(self, options).serializable_record
+ hash = { self.class.model_name.element => hash } if include_root_in_json
+ ActiveSupport::JSON.encode(hash)
end
+ def as_json(options = nil) self end #:nodoc:
+
def from_json(json)
self.attributes = ActiveSupport::JSON.decode(json)
self
end
-
- class JsonSerializer < ActiveRecord::Serialization::Serializer #:nodoc:
- def serialize
- serializable_record.to_json
- end
- end
-
- module ClassMethods
- def json_class_name
- @json_class_name ||= name.demodulize.underscore.inspect
- end
- end
end
end
diff --git a/vendor/rails/activerecord/lib/active_record/session_store.rb b/vendor/rails/activerecord/lib/active_record/session_store.rb
index 3cc4640f..c91b9433 100644
--- a/vendor/rails/activerecord/lib/active_record/session_store.rb
+++ b/vendor/rails/activerecord/lib/active_record/session_store.rb
@@ -295,7 +295,7 @@ module ActiveRecord
def set_session(env, sid, session_data)
Base.silence do
- record = env[SESSION_RECORD_KEY] ||= find_session(sid)
+ record = get_session_model(env, sid)
record.data = session_data
return false unless record.save
@@ -309,6 +309,14 @@ module ActiveRecord
return true
end
+
+ def get_session_model(env, sid)
+ if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
+ env[SESSION_RECORD_KEY] = find_session(sid)
+ else
+ env[SESSION_RECORD_KEY] ||= find_session(sid)
+ end
+ end
def find_session(id)
@@session_class.find_by_session_id(id) ||
diff --git a/vendor/rails/activerecord/lib/active_record/timestamp.rb b/vendor/rails/activerecord/lib/active_record/timestamp.rb
index 8dbe80a0..d9e1ef35 100644
--- a/vendor/rails/activerecord/lib/active_record/timestamp.rb
+++ b/vendor/rails/activerecord/lib/active_record/timestamp.rb
@@ -15,27 +15,57 @@ module ActiveRecord
base.class_inheritable_accessor :record_timestamps, :instance_writer => false
base.record_timestamps = true
end
+
+ # Saves the record with the updated_at/on attributes set to the current time.
+ # If the save fails because of validation errors, an ActiveRecord::RecordInvalid exception is raised.
+ # If an attribute name is passed, that attribute is used for the touch instead of the updated_at/on attributes.
+ #
+ # Examples:
+ #
+ # product.touch # updates updated_at
+ # product.touch(:designed_at) # updates the designed_at attribute
+ def touch(attribute = nil)
+ current_time = current_time_from_proper_timezone
+
+ if attribute
+ write_attribute(attribute, current_time)
+ else
+ write_attribute('updated_at', current_time) if respond_to?(:updated_at)
+ write_attribute('updated_on', current_time) if respond_to?(:updated_on)
+ end
+
+ save!
+ end
+
private
def create_with_timestamps #:nodoc:
if record_timestamps
- t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
- write_attribute('created_at', t) if respond_to?(:created_at) && created_at.nil?
- write_attribute('created_on', t) if respond_to?(:created_on) && created_on.nil?
+ current_time = current_time_from_proper_timezone
- write_attribute('updated_at', t) if respond_to?(:updated_at) && updated_at.nil?
- write_attribute('updated_on', t) if respond_to?(:updated_on) && updated_on.nil?
+ write_attribute('created_at', current_time) if respond_to?(:created_at) && created_at.nil?
+ write_attribute('created_on', current_time) if respond_to?(:created_on) && created_on.nil?
+
+ write_attribute('updated_at', current_time) if respond_to?(:updated_at) && updated_at.nil?
+ write_attribute('updated_on', current_time) if respond_to?(:updated_on) && updated_on.nil?
end
+
create_without_timestamps
end
def update_with_timestamps(*args) #:nodoc:
if record_timestamps && (!partial_updates? || changed?)
- t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
- write_attribute('updated_at', t) if respond_to?(:updated_at)
- write_attribute('updated_on', t) if respond_to?(:updated_on)
+ current_time = current_time_from_proper_timezone
+
+ write_attribute('updated_at', current_time) if respond_to?(:updated_at)
+ write_attribute('updated_on', current_time) if respond_to?(:updated_on)
end
+
update_without_timestamps(*args)
end
+
+ def current_time_from_proper_timezone
+ self.class.default_timezone == :utc ? Time.now.utc : Time.now
+ end
end
-end
+end
\ No newline at end of file
diff --git a/vendor/rails/activerecord/lib/active_record/version.rb b/vendor/rails/activerecord/lib/active_record/version.rb
index 852807b4..cbd6958a 100644
--- a/vendor/rails/activerecord/lib/active_record/version.rb
+++ b/vendor/rails/activerecord/lib/active_record/version.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/activerecord/test/cases/associations/belongs_to_associations_test.rb b/vendor/rails/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 13a78a18..970601cd 100644
--- a/vendor/rails/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/vendor/rails/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -14,6 +14,7 @@ require 'models/tagging'
require 'models/comment'
require 'models/sponsor'
require 'models/member'
+require 'models/essay'
class BelongsToAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
@@ -25,6 +26,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
end
+ def test_belongs_to_with_primary_key
+ client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
+ assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
+ end
+
def test_proxy_assignment
account = Account.find(1)
assert_nothing_raised { account.firm = account.firm }
@@ -47,6 +53,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple.id, citibank.firm_id
end
+ def test_natural_assignment_with_primary_key
+ apple = Firm.create("name" => "Apple")
+ citibank = Client.create("name" => "Primary key client")
+ citibank.firm_with_primary_key = apple
+ assert_equal apple.name, citibank.firm_name
+ end
+
def test_no_unexpected_aliasing
first_firm = companies(:first_firm)
another_firm = companies(:another_firm)
@@ -69,6 +82,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple, citibank.firm
end
+ def test_creating_the_belonging_object_with_primary_key
+ client = Client.create(:name => "Primary key client")
+ apple = client.create_firm_with_primary_key("name" => "Apple")
+ assert_equal apple, client.firm_with_primary_key
+ client.save
+ client.reload
+ assert_equal apple, client.firm_with_primary_key
+ end
+
def test_building_the_belonging_object
citibank = Account.create("credit_limit" => 10)
apple = citibank.build_firm("name" => "Apple")
@@ -76,6 +98,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple.id, citibank.firm_id
end
+ def test_building_the_belonging_object_with_primary_key
+ client = Client.create(:name => "Primary key client")
+ apple = client.build_firm_with_primary_key("name" => "Apple")
+ client.save
+ assert_equal apple.name, client.firm_name
+ end
+
def test_natural_assignment_to_nil
client = Client.find(3)
client.firm = nil
@@ -84,6 +113,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_nil client.client_of
end
+ def test_natural_assignment_to_nil_with_primary_key
+ client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
+ client.firm_with_primary_key = nil
+ client.save
+ assert_nil client.firm_with_primary_key(true)
+ assert_nil client.client_of
+ end
+
def test_with_different_class_name
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
@@ -110,6 +147,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
end
+ def test_belongs_to_with_primary_key_counter
+ debate = Topic.create("title" => "debate")
+ assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
+
+ trash = debate.replies_with_primary_key.create("title" => "blah!", "content" => "world around!")
+ assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
+
+ trash.destroy
+ assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
+ end
+
def test_belongs_to_counter_with_assigning_nil
p = Post.find(1)
c = Comment.find(1)
@@ -122,6 +170,18 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal 1, Post.find(p.id).comments.size
end
+ def test_belongs_to_with_primary_key_counter_with_assigning_nil
+ debate = Topic.create("title" => "debate")
+ reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
+
+ assert_equal debate.title, reply.parent_title
+ assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count")
+
+ reply.topic_with_primary_key = nil
+
+ assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count")
+ end
+
def test_belongs_to_counter_with_reassigning
t1 = Topic.create("title" => "t1")
t2 = Topic.create("title" => "t2")
@@ -219,6 +279,18 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal firm, final_cut.firm(true)
end
+ def test_assignment_before_child_saved_with_primary_key
+ final_cut = Client.new("name" => "Final Cut")
+ firm = Firm.find(1)
+ final_cut.firm_with_primary_key = firm
+ assert final_cut.new_record?
+ assert final_cut.save
+ assert !final_cut.new_record?
+ assert !firm.new_record?
+ assert_equal firm, final_cut.firm_with_primary_key
+ assert_equal firm, final_cut.firm_with_primary_key(true)
+ end
+
def test_new_record_with_foreign_key_but_no_object
c = Client.new("firm_id" => 1)
assert_equal Firm.find(:first), c.firm_with_basic_id
@@ -297,26 +369,52 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
member = Member.create
sponsor.sponsorable = member
assert_equal "Member", sponsor.sponsorable_type
-
+
# should update when assigning a new record
sponsor = Sponsor.new
member = Member.new
sponsor.sponsorable = member
assert_equal "Member", sponsor.sponsorable_type
end
-
+
+ def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating
+ # should update when assigning a saved record
+ essay = Essay.new
+ writer = Author.create(:name => "David")
+ essay.writer = writer
+ assert_equal "Author", essay.writer_type
+
+ # should update when assigning a new record
+ essay = Essay.new
+ writer = Author.new
+ essay.writer = writer
+ assert_equal "Author", essay.writer_type
+ end
+
def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
sponsor = Sponsor.new
saved_member = Member.create
new_member = Member.new
-
+
sponsor.sponsorable = saved_member
assert_equal saved_member.id, sponsor.sponsorable_id
-
+
sponsor.sponsorable = new_member
assert_equal nil, sponsor.sponsorable_id
end
+ def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
+ essay = Essay.new
+ saved_writer = Author.create(:name => "David")
+ new_writer = Author.new
+
+ essay.writer = saved_writer
+ assert_equal saved_writer.name, essay.writer_id
+
+ essay.writer = new_writer
+ assert_equal nil, essay.writer_id
+ end
+
def test_belongs_to_proxy_should_not_respond_to_private_methods
assert_raise(NoMethodError) { companies(:first_firm).private_method }
assert_raise(NoMethodError) { companies(:second_client).firm.private_method }
diff --git a/vendor/rails/activerecord/test/cases/associations/eager_test.rb b/vendor/rails/activerecord/test/cases/associations/eager_test.rb
index 40723814..d23f86b7 100644
--- a/vendor/rails/activerecord/test/cases/associations/eager_test.rb
+++ b/vendor/rails/activerecord/test/cases/associations/eager_test.rb
@@ -223,6 +223,18 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
end
+ def test_eager_association_loading_with_belongs_to_and_conditions_hash
+ comments = []
+ assert_nothing_raised do
+ comments = Comment.find(:all, :include => :post, :conditions => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id')
+ end
+ assert_equal 3, comments.length
+ assert_equal [5,6,7], comments.collect { |c| c.id }
+ assert_no_queries do
+ comments.first.post
+ end
+ end
+
def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name
quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
assert_nothing_raised do
diff --git a/vendor/rails/activerecord/test/cases/associations/has_many_associations_test.rb b/vendor/rails/activerecord/test/cases/associations/has_many_associations_test.rb
index 30edf79a..5df74fcd 100644
--- a/vendor/rails/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/vendor/rails/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -719,6 +719,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
end
+ def test_dependence_for_associations_with_hash_condition
+ david = authors(:david)
+ post = posts(:thinking).id
+ assert_difference('Post.count', -1) { assert david.destroy }
+ end
+
def test_destroy_dependent_when_deleted_from_association
firm = Firm.find(:first)
assert_equal 2, firm.clients.size
diff --git a/vendor/rails/activerecord/test/cases/associations/has_one_through_associations_test.rb b/vendor/rails/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 12c59875..ab6e6d20 100644
--- a/vendor/rails/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/vendor/rails/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -43,7 +43,14 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
@member.reload
end
end
-
+
+ def test_set_record_to_nil_should_delete_association
+ @member.club = nil
+ @member.reload
+ assert_equal nil, @member.current_membership
+ assert_nil @member.club
+ end
+
def test_has_one_through_polymorphic
assert_equal clubs(:moustache_club), @member.sponsor_club
end
diff --git a/vendor/rails/activerecord/test/cases/associations/inner_join_association_test.rb b/vendor/rails/activerecord/test/cases/associations/inner_join_association_test.rb
index f87c9141..71415317 100644
--- a/vendor/rails/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/vendor/rails/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -29,6 +29,11 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase
assert_match /INNER JOIN .?categories.? ON.*AND.*.?General.?.*TERMINATING_MARKER/, sql
end
+ def test_construct_finder_sql_applies_aliases_tables_on_association_conditions
+ result = Author.find(:all, :joins => [:thinking_posts, :welcome_posts])
+ assert_equal authors(:david), result.first
+ end
+
def test_construct_finder_sql_unpacks_nested_joins
sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]})
assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present"
diff --git a/vendor/rails/activerecord/test/cases/autosave_association_test.rb b/vendor/rails/activerecord/test/cases/autosave_association_test.rb
index 436f50d3..919b6f85 100644
--- a/vendor/rails/activerecord/test/cases/autosave_association_test.rb
+++ b/vendor/rails/activerecord/test/cases/autosave_association_test.rb
@@ -38,6 +38,17 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
end
class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
+ def test_should_save_parent_but_not_invalid_child
+ firm = Firm.new(:name => 'GlobalMegaCorp')
+ assert firm.valid?
+
+ firm.build_account_using_primary_key
+ assert !firm.build_account_using_primary_key.valid?
+
+ assert firm.save
+ assert firm.account_using_primary_key.new_record?
+ end
+
def test_save_fails_for_invalid_has_one
firm = Firm.find(:first)
assert firm.valid?
@@ -126,6 +137,17 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
end
class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
+ def test_should_save_parent_but_not_invalid_child
+ client = Client.new(:name => 'Joe (the Plumber)')
+ assert client.valid?
+
+ client.build_firm
+ assert !client.firm.valid?
+
+ assert client.save
+ assert client.firm.new_record?
+ end
+
def test_save_fails_for_invalid_belongs_to
assert log = AuditLog.create(:developer_id => 0, :message => "")
diff --git a/vendor/rails/activerecord/test/cases/base_test.rb b/vendor/rails/activerecord/test/cases/base_test.rb
index 99d77961..604271e8 100755
--- a/vendor/rails/activerecord/test/cases/base_test.rb
+++ b/vendor/rails/activerecord/test/cases/base_test.rb
@@ -1756,7 +1756,7 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_scoped_find_with_group_and_having
- developers = Developer.with_scope(:find => { :group => 'salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
+ developers = Developer.with_scope(:find => { :group => 'developers.salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
Developer.find(:all)
end
assert_equal 3, developers.size
@@ -2014,7 +2014,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_inspect_instance
topic = topics(:first)
- assert_equal %(#), topic.inspect
+ assert_equal %(#), topic.inspect
end
def test_inspect_new_instance
diff --git a/vendor/rails/activerecord/test/cases/calculations_test.rb b/vendor/rails/activerecord/test/cases/calculations_test.rb
index 56dcdea1..b4f76cbc 100644
--- a/vendor/rails/activerecord/test/cases/calculations_test.rb
+++ b/vendor/rails/activerecord/test/cases/calculations_test.rb
@@ -2,6 +2,9 @@ require "cases/helper"
require 'models/company'
require 'models/topic'
require 'models/edge'
+require 'models/owner'
+require 'models/pet'
+require 'models/toy'
Company.has_many :accounts
@@ -10,7 +13,7 @@ class NumericData < ActiveRecord::Base
end
class CalculationsTest < ActiveRecord::TestCase
- fixtures :companies, :accounts, :topics
+ fixtures :companies, :accounts, :topics, :owners, :pets, :toys
def test_should_sum_field
assert_equal 318, Account.sum(:credit_limit)
@@ -264,19 +267,6 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
end
- def test_should_count_scoped_select
- Account.update_all("credit_limit = NULL")
- assert_equal 0, Account.scoped(:select => "credit_limit").count
- end
-
- def test_should_count_scoped_select_with_options
- Account.update_all("credit_limit = NULL")
- Account.last.update_attribute('credit_limit', 49)
- Account.first.update_attribute('credit_limit', 51)
-
- assert_equal 1, Account.scoped(:select => "credit_limit").count(:conditions => ['credit_limit >= 50'])
- end
-
def test_should_count_manual_select_with_include
assert_equal 6, Account.count(:select => "DISTINCT accounts.id", :include => :firm)
end
@@ -297,6 +287,10 @@ class CalculationsTest < ActiveRecord::TestCase
assert_raise(ArgumentError) { Account.count(1, 2, 3) }
end
+ def test_count_with_scoped_has_many_through_association
+ assert_equal 1, owners(:blackbeard).toys.with_name('Bone').count
+ end
+
def test_should_sum_expression
assert_equal '636', Account.sum("2 * credit_limit")
end
diff --git a/vendor/rails/activerecord/test/cases/copy_table_test_sqlite.rb b/vendor/rails/activerecord/test/cases/copy_table_test_sqlite.rb
index 72bd7e2d..de8af309 100644
--- a/vendor/rails/activerecord/test/cases/copy_table_test_sqlite.rb
+++ b/vendor/rails/activerecord/test/cases/copy_table_test_sqlite.rb
@@ -10,7 +10,7 @@ class CopyTableTest < ActiveRecord::TestCase
end
end
- def test_copy_table(from = 'companies', to = 'companies2', options = {})
+ def test_copy_table(from = 'customers', to = 'customers2', options = {})
assert_nothing_raised {copy_table(from, to, options)}
assert_equal row_count(from), row_count(to)
@@ -24,11 +24,11 @@ class CopyTableTest < ActiveRecord::TestCase
end
def test_copy_table_renaming_column
- test_copy_table('companies', 'companies2',
- :rename => {'client_of' => 'fan_of'}) do |from, to, options|
- expected = column_values(from, 'client_of')
+ test_copy_table('customers', 'customers2',
+ :rename => {'name' => 'person_name'}) do |from, to, options|
+ expected = column_values(from, 'name')
assert expected.any?, 'only nils in resultset; real values are needed'
- assert_equal expected, column_values(to, 'fan_of')
+ assert_equal expected, column_values(to, 'person_name')
end
end
diff --git a/vendor/rails/activerecord/test/cases/finder_test.rb b/vendor/rails/activerecord/test/cases/finder_test.rb
index d8778957..25e339f5 100644
--- a/vendor/rails/activerecord/test/cases/finder_test.rb
+++ b/vendor/rails/activerecord/test/cases/finder_test.rb
@@ -119,6 +119,12 @@ class FinderTest < ActiveRecord::TestCase
Address.new(existing_address.street + "1", existing_address.city, existing_address.country))
end
+ def test_exists_with_scoped_include
+ Developer.with_scope(:find => { :include => :projects, :order => "projects.name" }) do
+ assert Developer.exists?
+ end
+ end
+
def test_find_by_array_of_one_id
assert_kind_of(Array, Topic.find([ 1 ]))
assert_equal(1, Topic.find([ 1 ]).length)
diff --git a/vendor/rails/activerecord/test/cases/fixtures_test.rb b/vendor/rails/activerecord/test/cases/fixtures_test.rb
index 252bf4ff..b07d4f35 100644
--- a/vendor/rails/activerecord/test/cases/fixtures_test.rb
+++ b/vendor/rails/activerecord/test/cases/fixtures_test.rb
@@ -518,6 +518,11 @@ class FoxyFixturesTest < ActiveRecord::TestCase
assert_equal(Fixtures.identify(:foo), Fixtures.identify(:foo))
end
+ def test_identifies_consistently
+ assert_equal 1281023246, Fixtures.identify(:ruby)
+ assert_equal 2140105598, Fixtures.identify(:sapphire_2)
+ end
+
TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on)
def test_populates_timestamp_columns
diff --git a/vendor/rails/activerecord/test/cases/helper.rb b/vendor/rails/activerecord/test/cases/helper.rb
index 1ec52ac2..1ef38c99 100644
--- a/vendor/rails/activerecord/test/cases/helper.rb
+++ b/vendor/rails/activerecord/test/cases/helper.rb
@@ -5,8 +5,7 @@ require 'config'
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
+require 'stringio'
require 'active_record'
require 'active_record/test_case'
diff --git a/vendor/rails/activerecord/test/cases/json_serialization_test.rb b/vendor/rails/activerecord/test/cases/json_serialization_test.rb
index 975acde0..54bc8e23 100644
--- a/vendor/rails/activerecord/test/cases/json_serialization_test.rb
+++ b/vendor/rails/activerecord/test/cases/json_serialization_test.rb
@@ -26,19 +26,19 @@ class JsonSerializationTest < ActiveRecord::TestCase
NamespacedContact.include_root_in_json = true
@contact = NamespacedContact.new :name => 'whatever'
json = @contact.to_json
- assert_match %r{^\{"namespaced_contact": \{}, json
+ assert_match %r{^\{"namespaced_contact":\{}, json
end
def test_should_include_root_in_json
Contact.include_root_in_json = true
json = @contact.to_json
- assert_match %r{^\{"contact": \{}, json
- assert_match %r{"name": "Konata Izumi"}, json
- assert_match %r{"age": 16}, json
- assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
- assert_match %r{"awesome": true}, json
- assert_match %r{"preferences": \{"shows": "anime"\}}, json
+ assert_match %r{^\{"contact":\{}, json
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"awesome":true}, json
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
ensure
Contact.include_root_in_json = false
end
@@ -46,31 +46,31 @@ class JsonSerializationTest < ActiveRecord::TestCase
def test_should_encode_all_encodable_attributes
json = @contact.to_json
- assert_match %r{"name": "Konata Izumi"}, json
- assert_match %r{"age": 16}, json
- assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
- assert_match %r{"awesome": true}, json
- assert_match %r{"preferences": \{"shows": "anime"\}}, json
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"awesome":true}, json
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
end
def test_should_allow_attribute_filtering_with_only
json = @contact.to_json(:only => [:name, :age])
- assert_match %r{"name": "Konata Izumi"}, json
- assert_match %r{"age": 16}, json
- assert_no_match %r{"awesome": true}, json
- assert !json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
- assert_no_match %r{"preferences": \{"shows": "anime"\}}, json
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert_no_match %r{"awesome":true}, json
+ assert !json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_no_match %r{"preferences":\{"shows":"anime"\}}, json
end
def test_should_allow_attribute_filtering_with_except
json = @contact.to_json(:except => [:name, :age])
- assert_no_match %r{"name": "Konata Izumi"}, json
- assert_no_match %r{"age": 16}, json
- assert_match %r{"awesome": true}, json
- assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
- assert_match %r{"preferences": \{"shows": "anime"\}}, json
+ assert_no_match %r{"name":"Konata Izumi"}, json
+ assert_no_match %r{"age":16}, json
+ assert_match %r{"awesome":true}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
end
def test_methods_are_called_on_object
@@ -79,12 +79,12 @@ class JsonSerializationTest < ActiveRecord::TestCase
def @contact.favorite_quote; "Constraints are liberating"; end
# Single method.
- assert_match %r{"label": "Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label)
+ assert_match %r{"label":"Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label)
# Both methods.
methods_json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote])
- assert_match %r{"label": "Has cheezburger"}, methods_json
- assert_match %r{"favorite_quote": "Constraints are liberating"}, methods_json
+ assert_match %r{"label":"Has cheezburger"}, methods_json
+ assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json
end
end
@@ -99,42 +99,42 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
def test_includes_uses_association_name
json = @david.to_json(:include => :posts)
- assert_match %r{"posts": \[}, json
+ assert_match %r{"posts":\[}, json
- assert_match %r{"id": 1}, json
- assert_match %r{"name": "David"}, json
+ assert_match %r{"id":1}, json
+ assert_match %r{"name":"David"}, json
- assert_match %r{"author_id": 1}, json
- assert_match %r{"title": "Welcome to the weblog"}, json
- assert_match %r{"body": "Such a lovely day"}, json
+ assert_match %r{"author_id":1}, json
+ assert_match %r{"title":"Welcome to the weblog"}, json
+ assert_match %r{"body":"Such a lovely day"}, json
- assert_match %r{"title": "So I was thinking"}, json
- assert_match %r{"body": "Like I hopefully always am"}, json
+ assert_match %r{"title":"So I was thinking"}, json
+ assert_match %r{"body":"Like I hopefully always am"}, json
end
def test_includes_uses_association_name_and_applies_attribute_filters
json = @david.to_json(:include => { :posts => { :only => :title } })
- assert_match %r{"name": "David"}, json
- assert_match %r{"posts": \[}, json
+ assert_match %r{"name":"David"}, json
+ assert_match %r{"posts":\[}, json
- assert_match %r{"title": "Welcome to the weblog"}, json
- assert_no_match %r{"body": "Such a lovely day"}, json
+ assert_match %r{"title":"Welcome to the weblog"}, json
+ assert_no_match %r{"body":"Such a lovely day"}, json
- assert_match %r{"title": "So I was thinking"}, json
- assert_no_match %r{"body": "Like I hopefully always am"}, json
+ assert_match %r{"title":"So I was thinking"}, json
+ assert_no_match %r{"body":"Like I hopefully always am"}, json
end
def test_includes_fetches_second_level_associations
json = @david.to_json(:include => { :posts => { :include => { :comments => { :only => :body } } } })
- assert_match %r{"name": "David"}, json
- assert_match %r{"posts": \[}, json
+ assert_match %r{"name":"David"}, json
+ assert_match %r{"posts":\[}, json
- assert_match %r{"comments": \[}, json
- assert_match %r{\{"body": "Thank you again for the welcome"\}}, json
- assert_match %r{\{"body": "Don't think too hard"\}}, json
- assert_no_match %r{"post_id": }, json
+ assert_match %r{"comments":\[}, json
+ assert_match %r{\{"body":"Thank you again for the welcome"\}}, json
+ assert_match %r{\{"body":"Don't think too hard"\}}, json
+ assert_no_match %r{"post_id":}, json
end
def test_includes_fetches_nth_level_associations
@@ -151,11 +151,11 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
}
})
- assert_match %r{"name": "David"}, json
- assert_match %r{"posts": \[}, json
+ assert_match %r{"name":"David"}, json
+ assert_match %r{"posts":\[}, json
- assert_match %r{"taggings": \[}, json
- assert_match %r{"tag": \{"name": "General"\}}, json
+ assert_match %r{"taggings":\[}, json
+ assert_match %r{"tag":\{"name":"General"\}}, json
end
def test_should_not_call_methods_on_associations_that_dont_respond
@@ -163,33 +163,33 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
json = @david.to_json(:include => :posts, :methods => :favorite_quote)
assert !@david.posts.first.respond_to?(:favorite_quote)
- assert_match %r{"favorite_quote": "Constraints are liberating"}, json
- assert_equal %r{"favorite_quote": }.match(json).size, 1
+ assert_match %r{"favorite_quote":"Constraints are liberating"}, json
+ assert_equal %r{"favorite_quote":}.match(json).size, 1
end
def test_should_allow_only_option_for_list_of_authors
authors = [@david, @mary]
- assert_equal %([{"name": "David"}, {"name": "Mary"}]), authors.to_json(:only => :name)
+ assert_equal %([{"name":"David"},{"name":"Mary"}]), ActiveSupport::JSON.encode(authors, :only => :name)
end
def test_should_allow_except_option_for_list_of_authors
authors = [@david, @mary]
- assert_equal %([{"id": 1}, {"id": 2}]), authors.to_json(:except => [:name, :author_address_id, :author_address_extra_id])
+ assert_equal %([{"id":1},{"id":2}]), ActiveSupport::JSON.encode(authors, :except => [:name, :author_address_id, :author_address_extra_id])
end
def test_should_allow_includes_for_list_of_authors
authors = [@david, @mary]
- json = authors.to_json(
+ json = ActiveSupport::JSON.encode(authors,
:only => :name,
:include => {
:posts => { :only => :id }
}
)
- ['"name": "David"', '"posts": [', '{"id": 1}', '{"id": 2}', '{"id": 4}',
- '{"id": 5}', '{"id": 6}', '"name": "Mary"', '"posts": [{"id": 7}]'].each do |fragment|
+ ['"name":"David"', '"posts":[', '{"id":1}', '{"id":2}', '{"id":4}',
+ '{"id":5}', '{"id":6}', '"name":"Mary"', '"posts":[{"id":7}]'].each do |fragment|
assert json.include?(fragment), json
end
end
@@ -200,6 +200,6 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
2 => @mary
}
- assert_equal %({"1": {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
+ assert_equal %({"1":{"name":"David"}}), ActiveSupport::JSON.encode(authors_hash, :only => [1, :name])
end
end
diff --git a/vendor/rails/activerecord/test/cases/method_scoping_test.rb b/vendor/rails/activerecord/test/cases/method_scoping_test.rb
index 3c34cdea..2f660a3e 100644
--- a/vendor/rails/activerecord/test/cases/method_scoping_test.rb
+++ b/vendor/rails/activerecord/test/cases/method_scoping_test.rb
@@ -591,6 +591,16 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal expected, received
end
+ def test_default_scope_with_conditions_string
+ assert_equal Developer.find_all_by_name('David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort
+ assert_equal nil, DeveloperCalledDavid.create!.name
+ end
+
+ def test_default_scope_with_conditions_hash
+ assert_equal Developer.find_all_by_name('Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort
+ assert_equal 'Jamis', DeveloperCalledJamis.create!.name
+ end
+
def test_default_scoping_with_threads
scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]
@@ -628,9 +638,9 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal expected, received
end
- def test_named_scope
- expected = Developer.find(:all, :order => 'salary DESC, name DESC').collect { |dev| dev.salary }
- received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.salary }
+ def test_named_scope_overwrites_default
+ expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.name }
+ received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name }
assert_equal expected, received
end
diff --git a/vendor/rails/activerecord/test/cases/reflection_test.rb b/vendor/rails/activerecord/test/cases/reflection_test.rb
index db64bbb8..30ec157d 100644
--- a/vendor/rails/activerecord/test/cases/reflection_test.rb
+++ b/vendor/rails/activerecord/test/cases/reflection_test.rb
@@ -21,25 +21,25 @@ class ReflectionTest < ActiveRecord::TestCase
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 type ).sort,
+ %w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id parent_title type ).sort,
@first.attribute_names
)
end
def test_columns
- assert_equal 12, Topic.columns.length
+ assert_equal 13, Topic.columns.length
end
def test_columns_are_returned_in_the_order_they_were_declared
column_names = Topic.columns.map { |column| column.name }
- assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id type), column_names
+ assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type), column_names
end
def test_content_columns
content_columns = Topic.content_columns
content_column_names = content_columns.map {|column| column.name}
- assert_equal 8, content_columns.length
- assert_equal %w(title author_name author_email_address written_on bonus_time last_read content approved).sort, content_column_names.sort
+ assert_equal 9, content_columns.length
+ assert_equal %w(title author_name author_email_address written_on bonus_time last_read content approved parent_title).sort, content_column_names.sort
end
def test_column_string_type_and_limit
diff --git a/vendor/rails/activerecord/test/cases/schema_dumper_test.rb b/vendor/rails/activerecord/test/cases/schema_dumper_test.rb
index 17e4c755..972700df 100644
--- a/vendor/rails/activerecord/test/cases/schema_dumper_test.rb
+++ b/vendor/rails/activerecord/test/cases/schema_dumper_test.rb
@@ -22,6 +22,11 @@ class SchemaDumperTest < ActiveRecord::TestCase
assert_no_match %r{create_table "sqlite_sequence"}, output
end
+ def test_schema_dump_includes_camelcase_table_name
+ output = standard_dump
+ assert_match %r{create_table "CamelCase"}, output
+ end
+
def assert_line_up(lines, pattern, required = false)
return assert(true) if lines.empty?
matches = lines.map { |line| line.match(pattern) }
@@ -147,19 +152,24 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
end
+ def test_schema_dumps_index_columns_in_right_order
+ index_definition = standard_dump.split(/\n/).grep(/add_index.*companies/).first.strip
+ assert_equal 'add_index "companies", ["firm_id", "type", "rating", "ruby_type"], :name => "company_index"', index_definition
+ end
+
+ def test_schema_dump_should_honor_nonstandard_primary_keys
+ output = standard_dump
+ match = output.match(%r{create_table "movies"(.*)do})
+ assert_not_nil(match, "nonstandardpk table not found")
+ assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
+ end
+
if current_adapter?(:MysqlAdapter)
def test_schema_dump_should_not_add_default_value_for_mysql_text_field
output = standard_dump
assert_match %r{t.text\s+"body",\s+:null => false$}, output
end
- def test_mysql_schema_dump_should_honor_nonstandard_primary_keys
- output = standard_dump
- match = output.match(%r{create_table "movies"(.*)do})
- assert_not_nil(match, "nonstandardpk table not found")
- assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
- end
-
def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
output = standard_dump
assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
diff --git a/vendor/rails/activerecord/test/cases/schema_test_postgresql.rb b/vendor/rails/activerecord/test/cases/schema_test_postgresql.rb
index 336a3876..a294848f 100644
--- a/vendor/rails/activerecord/test/cases/schema_test_postgresql.rb
+++ b/vendor/rails/activerecord/test/cases/schema_test_postgresql.rb
@@ -6,6 +6,7 @@ class SchemaTest < ActiveRecord::TestCase
SCHEMA_NAME = 'test_schema'
SCHEMA2_NAME = 'test_schema2'
TABLE_NAME = 'things'
+ CAPITALIZED_TABLE_NAME = 'Things'
INDEX_A_NAME = 'a_index_things_on_name'
INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
INDEX_A_COLUMN = 'name'
@@ -18,9 +19,27 @@ class SchemaTest < ActiveRecord::TestCase
'moment timestamp without time zone default now()'
]
+ class Thing1 < ActiveRecord::Base
+ set_table_name "test_schema.things"
+ end
+
+ class Thing2 < ActiveRecord::Base
+ set_table_name "test_schema2.things"
+ end
+
+ class Thing3 < ActiveRecord::Base
+ set_table_name 'test_schema."things.table"'
+ end
+
+ class Thing4 < ActiveRecord::Base
+ set_table_name 'test_schema."Things"'
+ end
+
def setup
@connection = ActiveRecord::Base.connection
@connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})"
@connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@@ -39,6 +58,12 @@ class SchemaTest < ActiveRecord::TestCase
end
end
+ def test_with_schema_prefixed_capitalized_table_name
+ assert_nothing_raised do
+ assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{CAPITALIZED_TABLE_NAME}")
+ end
+ end
+
def test_with_schema_search_path
assert_nothing_raised do
with_schema_search_path(SCHEMA_NAME) do
@@ -47,6 +72,47 @@ class SchemaTest < ActiveRecord::TestCase
end
end
+
+ def test_proper_encoding_of_table_name
+ assert_equal '"table_name"', @connection.quote_table_name('table_name')
+ assert_equal '"table.name"', @connection.quote_table_name('"table.name"')
+ assert_equal '"schema_name"."table_name"', @connection.quote_table_name('schema_name.table_name')
+ assert_equal '"schema_name"."table.name"', @connection.quote_table_name('schema_name."table.name"')
+ assert_equal '"schema.name"."table_name"', @connection.quote_table_name('"schema.name".table_name')
+ assert_equal '"schema.name"."table.name"', @connection.quote_table_name('"schema.name"."table.name"')
+ end
+
+ def test_classes_with_qualified_schema_name
+ assert_equal 0, Thing1.count
+ assert_equal 0, Thing2.count
+ assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
+
+ Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ assert_equal 1, Thing1.count
+ assert_equal 0, Thing2.count
+ assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
+
+ Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ assert_equal 1, Thing1.count
+ assert_equal 1, Thing2.count
+ assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
+
+ Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ assert_equal 1, Thing1.count
+ assert_equal 1, Thing2.count
+ assert_equal 1, Thing3.count
+ assert_equal 0, Thing4.count
+
+ Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ assert_equal 1, Thing1.count
+ assert_equal 1, Thing2.count
+ assert_equal 1, Thing3.count
+ assert_equal 1, Thing4.count
+ end
+
def test_raise_on_unquoted_schema_name
assert_raise(ActiveRecord::StatementInvalid) do
with_schema_search_path '$user,public'
@@ -69,6 +135,16 @@ class SchemaTest < ActiveRecord::TestCase
do_dump_index_tests_for_schema(SCHEMA2_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S2)
end
+ def test_with_uppercase_index_name
+ ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
+ assert_nothing_raised { ActiveRecord::Base.connection.remove_index :things, :name => "#{SCHEMA_NAME}.things_Index"}
+
+ ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
+ ActiveRecord::Base.connection.schema_search_path = SCHEMA_NAME
+ assert_nothing_raised { ActiveRecord::Base.connection.remove_index :things, :name => "things_Index"}
+ ActiveRecord::Base.connection.schema_search_path = "public"
+ end
+
private
def columns(table_name)
@connection.send(:column_definitions, table_name).map do |name, type, default|
diff --git a/vendor/rails/activerecord/test/cases/timestamp_test.rb b/vendor/rails/activerecord/test/cases/timestamp_test.rb
new file mode 100644
index 00000000..24b237a7
--- /dev/null
+++ b/vendor/rails/activerecord/test/cases/timestamp_test.rb
@@ -0,0 +1,75 @@
+require 'cases/helper'
+require 'models/developer'
+require 'models/owner'
+require 'models/pet'
+
+class TimestampTest < ActiveRecord::TestCase
+ fixtures :developers, :owners, :pets
+
+ def setup
+ @developer = Developer.first
+ @previously_updated_at = @developer.updated_at
+ end
+
+ def test_saving_a_changed_record_updates_its_timestamp
+ @developer.name = "Jack Bauer"
+ @developer.save!
+
+ assert @previously_updated_at != @developer.updated_at
+ end
+
+ def test_saving_a_unchanged_record_doesnt_update_its_timestamp
+ @developer.save!
+
+ assert @previously_updated_at == @developer.updated_at
+ end
+
+ def test_touching_a_record_updates_its_timestamp
+ @developer.touch
+
+ assert @previously_updated_at != @developer.updated_at
+ end
+
+ def test_touching_a_different_attribute
+ previously_created_at = @developer.created_at
+ @developer.touch(:created_at)
+
+ assert previously_created_at != @developer.created_at
+ end
+
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
+ pet = Pet.first
+ owner = pet.owner
+ previously_owner_updated_at = owner.updated_at
+
+ pet.name = "Fluffy the Third"
+ pet.save
+
+ assert previously_owner_updated_at != pet.owner.updated_at
+ end
+
+ def test_destroying_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
+ pet = Pet.first
+ owner = pet.owner
+ previously_owner_updated_at = owner.updated_at
+
+ pet.destroy
+
+ assert previously_owner_updated_at != pet.owner.updated_at
+ end
+
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_a_specific_attribute_the_parent_should_update_that_attribute
+ Pet.belongs_to :owner, :touch => :happy_at
+
+ pet = Pet.first
+ owner = pet.owner
+ previously_owner_happy_at = owner.happy_at
+
+ pet.name = "Fluffy the Third"
+ pet.save
+
+ assert previously_owner_happy_at != pet.owner.happy_at
+ ensure
+ Pet.belongs_to :owner, :touch => true
+ end
+end
\ No newline at end of file
diff --git a/vendor/rails/activerecord/test/models/author.rb b/vendor/rails/activerecord/test/models/author.rb
index 4ffac4fe..b844c7cc 100644
--- a/vendor/rails/activerecord/test/models/author.rb
+++ b/vendor/rails/activerecord/test/models/author.rb
@@ -25,6 +25,8 @@ class Author < ActiveRecord::Base
has_many :comments_with_order_and_conditions, :through => :posts, :source => :comments, :order => 'comments.body', :conditions => "comments.body like 'Thank%'"
has_many :comments_with_include, :through => :posts, :source => :comments, :include => :post
+ has_many :thinking_posts, :class_name => 'Post', :conditions => { :title => 'So I was thinking' }, :dependent => :delete_all
+ has_many :welcome_posts, :class_name => 'Post', :conditions => { :title => 'Welcome to the weblog' }
has_many :comments_desc, :through => :posts, :source => :comments, :order => 'comments.id DESC'
has_many :limited_comments, :through => :posts, :source => :comments, :limit => 1
@@ -85,6 +87,8 @@ class Author < ActiveRecord::Base
has_many :tags, :through => :posts # through has_many :through
has_many :post_categories, :through => :posts, :source => :categories
+ has_one :essay, :primary_key => :name, :as => :writer
+
belongs_to :author_address, :dependent => :destroy
belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress"
diff --git a/vendor/rails/activerecord/test/models/company.rb b/vendor/rails/activerecord/test/models/company.rb
index 02a775f9..2a65b034 100644
--- a/vendor/rails/activerecord/test/models/company.rb
+++ b/vendor/rails/activerecord/test/models/company.rb
@@ -78,19 +78,13 @@ class DependentFirm < Company
has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify
end
-class ExclusivelyDependentFirm < Company
- has_one :account, :foreign_key => "firm_id", :dependent => :delete
- has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'"
- has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.']
- has_many :dependent_hash_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => {:name => 'BigShot Inc.'}
-end
-
class Client < Company
belongs_to :firm, :foreign_key => "client_of"
belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
belongs_to :firm_with_select, :class_name => "Firm", :foreign_key => "firm_id", :select => "id"
belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => ["1 = ?", 1]
+ belongs_to :firm_with_primary_key, :class_name => "Firm", :primary_key => "name", :foreign_key => "firm_name"
belongs_to :readonly_firm, :class_name => "Firm", :foreign_key => "firm_id", :readonly => true
# Record destruction so we can test whether firm.clients.clear has
@@ -125,6 +119,12 @@ class Client < Company
end
end
+class ExclusivelyDependentFirm < Company
+ has_one :account, :foreign_key => "firm_id", :dependent => :delete
+ has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'"
+ has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.']
+ has_many :dependent_hash_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => {:name => 'BigShot Inc.'}
+end
class SpecialClient < Client
end
diff --git a/vendor/rails/activerecord/test/models/developer.rb b/vendor/rails/activerecord/test/models/developer.rb
index 92039a4f..05897033 100644
--- a/vendor/rails/activerecord/test/models/developer.rb
+++ b/vendor/rails/activerecord/test/models/developer.rb
@@ -89,3 +89,13 @@ class DeveloperOrderedBySalary < ActiveRecord::Base
end
end
end
+
+class DeveloperCalledDavid < ActiveRecord::Base
+ self.table_name = 'developers'
+ default_scope :conditions => "name = 'David'"
+end
+
+class DeveloperCalledJamis < ActiveRecord::Base
+ self.table_name = 'developers'
+ default_scope :conditions => { :name => 'Jamis' }
+end
diff --git a/vendor/rails/activerecord/test/models/essay.rb b/vendor/rails/activerecord/test/models/essay.rb
new file mode 100644
index 00000000..6c28f5e4
--- /dev/null
+++ b/vendor/rails/activerecord/test/models/essay.rb
@@ -0,0 +1,3 @@
+class Essay < ActiveRecord::Base
+ belongs_to :writer, :primary_key => :name, :polymorphic => true
+end
diff --git a/vendor/rails/activerecord/test/models/pet.rb b/vendor/rails/activerecord/test/models/pet.rb
index dc1a3c5e..a8bf94dd 100644
--- a/vendor/rails/activerecord/test/models/pet.rb
+++ b/vendor/rails/activerecord/test/models/pet.rb
@@ -1,5 +1,5 @@
class Pet < ActiveRecord::Base
set_primary_key :pet_id
- belongs_to :owner
+ belongs_to :owner, :touch => true
has_many :toys
end
diff --git a/vendor/rails/activerecord/test/models/project.rb b/vendor/rails/activerecord/test/models/project.rb
index 550d4ae2..f25b2ddf 100644
--- a/vendor/rails/activerecord/test/models/project.rb
+++ b/vendor/rails/activerecord/test/models/project.rb
@@ -13,7 +13,7 @@ class Project < ActiveRecord::Base
:after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || ''}"},
:before_remove => Proc.new {|o, r| o.developers_log << "before_removing#{r.id}"},
:after_remove => Proc.new {|o, r| o.developers_log << "after_removing#{r.id}"}
- has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
+ has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "developers.salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
attr_accessor :developers_log
diff --git a/vendor/rails/activerecord/test/models/reply.rb b/vendor/rails/activerecord/test/models/reply.rb
index 1c990aca..4063785f 100644
--- a/vendor/rails/activerecord/test/models/reply.rb
+++ b/vendor/rails/activerecord/test/models/reply.rb
@@ -4,12 +4,13 @@ class Reply < Topic
named_scope :base
belongs_to :topic, :foreign_key => "parent_id", :counter_cache => true
+ belongs_to :topic_with_primary_key, :class_name => "Topic", :primary_key => "title", :foreign_key => "parent_title", :counter_cache => "replies_count"
has_many :replies, :class_name => "SillyReply", :dependent => :destroy, :foreign_key => "parent_id"
validate :errors_on_empty_content
validate_on_create :title_is_wrong_create
- attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read
+ attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read, :parent_title
def validate
errors.add("title", "Empty") unless attribute_present? "title"
diff --git a/vendor/rails/activerecord/test/models/topic.rb b/vendor/rails/activerecord/test/models/topic.rb
index 51012d22..201d96dc 100644
--- a/vendor/rails/activerecord/test/models/topic.rb
+++ b/vendor/rails/activerecord/test/models/topic.rb
@@ -39,6 +39,7 @@ class Topic < ActiveRecord::Base
named_scope :by_rejected_ids, lambda {{ :conditions => { :id => all(:conditions => {:approved => false}).map(&:id) } }}
has_many :replies, :dependent => :destroy, :foreign_key => "parent_id"
+ has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title"
serialize :content
before_create :default_written_on
diff --git a/vendor/rails/activerecord/test/models/toy.rb b/vendor/rails/activerecord/test/models/toy.rb
index 79a88db0..0e68ba57 100644
--- a/vendor/rails/activerecord/test/models/toy.rb
+++ b/vendor/rails/activerecord/test/models/toy.rb
@@ -1,4 +1,6 @@
class Toy < ActiveRecord::Base
set_primary_key :toy_id
belongs_to :pet
+
+ named_scope :with_name, lambda { |name| {:conditions => {:name => name}} }
end
diff --git a/vendor/rails/activerecord/test/schema/schema.rb b/vendor/rails/activerecord/test/schema/schema.rb
index ea848a29..d080140e 100644
--- a/vendor/rails/activerecord/test/schema/schema.rb
+++ b/vendor/rails/activerecord/test/schema/schema.rb
@@ -68,6 +68,10 @@ ActiveRecord::Schema.define do
t.boolean :value
end
+ create_table "CamelCase", :force => true do |t|
+ t.string :name
+ end
+
create_table :categories, :force => true do |t|
t.string :name, :null => false
t.string :type
@@ -114,6 +118,8 @@ ActiveRecord::Schema.define do
t.integer :rating, :default => 1
end
+ add_index :companies, [:firm_id, :type, :rating, :ruby_type], :name => "company_index"
+
create_table :computers, :force => true do |t|
t.integer :developer, :null => false
t.integer :extendedWarranty, :null => false
@@ -155,6 +161,12 @@ ActiveRecord::Schema.define do
t.integer :course_id, :null => false
end
+ create_table :essays, :force => true do |t|
+ t.string :name
+ t.string :writer_id
+ t.string :writer_type
+ end
+
create_table :events, :force => true do |t|
t.string :title, :limit => 5
end
@@ -281,6 +293,8 @@ ActiveRecord::Schema.define do
create_table :owners, :primary_key => :owner_id ,:force => true do |t|
t.string :name
+ t.column :updated_at, :datetime
+ t.column :happy_at, :datetime
end
@@ -410,6 +424,7 @@ ActiveRecord::Schema.define do
t.boolean :approved, :default => true
t.integer :replies_count, :default => 0
t.integer :parent_id
+ t.string :parent_title
t.string :type
end
diff --git a/vendor/rails/activeresource/CHANGELOG b/vendor/rails/activeresource/CHANGELOG
index 65729348..11424163 100644
--- a/vendor/rails/activeresource/CHANGELOG
+++ b/vendor/rails/activeresource/CHANGELOG
@@ -1,3 +1,7 @@
+*2.3.3 (July 12, 2009)*
+
+* No changes, just a version bump.
+
*2.3.2 [Final] (March 15, 2009)*
* Nothing new, just included in 2.3.2
diff --git a/vendor/rails/activeresource/Rakefile b/vendor/rails/activeresource/Rakefile
index bf7bbb02..c6591ccd 100644
--- a/vendor/rails/activeresource/Rakefile
+++ b/vendor/rails/activeresource/Rakefile
@@ -4,7 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require 'rake/contrib/sshpublisher'
require File.join(File.dirname(__FILE__), 'lib', 'active_resource', 'version')
@@ -67,7 +66,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.3.3' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'active_resource'
@@ -117,12 +116,14 @@ end
desc "Publish the beta gem"
task :pgem => [:package] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload
end
diff --git a/vendor/rails/activeresource/lib/active_resource/base.rb b/vendor/rails/activeresource/lib/active_resource/base.rb
index a8c0da31..4a4ee9f4 100644
--- a/vendor/rails/activeresource/lib/active_resource/base.rb
+++ b/vendor/rails/activeresource/lib/active_resource/base.rb
@@ -832,7 +832,7 @@ module ActiveResource
!new? && self.class.exists?(to_param, :params => prefix_options)
end
- # A method to convert the the resource to an XML string.
+ # Converts the resource to an XML string representation.
#
# ==== Options
# The +options+ parameter is handed off to the +to_xml+ method on each
@@ -841,7 +841,14 @@ module ActiveResource
#
# * :indent - Set the indent level for the XML output (default is +2+).
# * :dasherize - Boolean option to determine whether or not element names should
- # replace underscores with dashes (default is false ).
+ # replace underscores with dashes. Default is true . The default can be set to false
+ # by setting the module attribute ActiveSupport.dasherize_xml = false in an initializer. Because save
+ # uses this method, and there are no options on save, then you will have to set the default if you don't
+ # want underscores in element names to become dashes when the resource is saved. This is important when
+ # integrating with non-Rails applications.
+ # * :camelize - Boolean option to determine whether or not element names should be converted
+ # to camel case, e.g some_name to SomeName. Default is false . Like :dasherize you can
+ # change the default by setting the module attribute ActiveSupport.camelise_xml = true in an initializer.
# * :skip_instruct - Toggle skipping the +instruct!+ call on the XML builder
# that generates the XML declaration (default is false ).
#
@@ -861,8 +868,7 @@ module ActiveResource
attributes.to_xml({:root => self.class.element_name}.merge(options))
end
- # Returns a JSON string representing the model. Some configuration is
- # available through +options+.
+ # Coerces to a hash for JSON encoding.
#
# ==== Options
# The +options+ are passed to the +to_json+ method on each
@@ -886,8 +892,8 @@ module ActiveResource
#
# person.to_json(:except => ["first_name"])
# # => {"last_name": "Smith"}
- def to_json(options={})
- attributes.to_json(options)
+ def as_json(options = nil)
+ attributes.as_json(options)
end
# Returns the serialized string representation of the resource in the configured
diff --git a/vendor/rails/activeresource/lib/active_resource/formats/json_format.rb b/vendor/rails/activeresource/lib/active_resource/formats/json_format.rb
index 1d88fc5f..127e8288 100644
--- a/vendor/rails/activeresource/lib/active_resource/formats/json_format.rb
+++ b/vendor/rails/activeresource/lib/active_resource/formats/json_format.rb
@@ -11,8 +11,8 @@ module ActiveResource
"application/json"
end
- def encode(hash, options={})
- hash.to_json(options)
+ def encode(hash, options = nil)
+ ActiveSupport::JSON.encode(hash, options)
end
def decode(json)
diff --git a/vendor/rails/activeresource/lib/active_resource/version.rb b/vendor/rails/activeresource/lib/active_resource/version.rb
index 3df2555d..8c68de74 100644
--- a/vendor/rails/activeresource/lib/active_resource/version.rb
+++ b/vendor/rails/activeresource/lib/active_resource/version.rb
@@ -2,7 +2,7 @@ module ActiveResource
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/activeresource/test/abstract_unit.rb b/vendor/rails/activeresource/test/abstract_unit.rb
index 0f11ea48..07d201a7 100644
--- a/vendor/rails/activeresource/test/abstract_unit.rb
+++ b/vendor/rails/activeresource/test/abstract_unit.rb
@@ -1,8 +1,6 @@
require 'rubygems'
require 'test/unit'
-
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
+require 'active_support/test_case'
$:.unshift "#{File.dirname(__FILE__)}/../lib"
$:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib"
diff --git a/vendor/rails/activesupport/CHANGELOG b/vendor/rails/activesupport/CHANGELOG
index ab40e1a1..cb57790d 100644
--- a/vendor/rails/activesupport/CHANGELOG
+++ b/vendor/rails/activesupport/CHANGELOG
@@ -1,3 +1,10 @@
+*2.3.3 (July 12, 2009)*
+
+* JSON: +Object#to_json+ calls +as_json+ to coerce itself into something natively encodable like +Hash+, +Integer+, or +String+. Override +as_json+ instead of +to_json+ so you're JSON-library-agnostic. [Jeremy Kemper]
+
+* Allow MemCacheStore to be initialized with a MemCache-like object instead of addresses and options [Bryan Helmkamp]
+
+
*2.3.2 [Final] (March 15, 2009)*
* XmlMini supports LibXML and Nokogiri backends. #2084, #2190 [Bart ten Brinke, Aaron Patterson]
diff --git a/vendor/rails/activesupport/lib/active_support/cache.rb b/vendor/rails/activesupport/lib/active_support/cache.rb
index 83174d3a..3f311852 100644
--- a/vendor/rails/activesupport/lib/active_support/cache.rb
+++ b/vendor/rails/activesupport/lib/active_support/cache.rb
@@ -91,11 +91,16 @@ module ActiveSupport
class Store
cattr_accessor :logger
+ attr_reader :silence, :logger_off
+
def silence!
@silence = true
self
end
+ alias silence? silence
+ alias logger_off? logger_off
+
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned.
#
@@ -220,8 +225,16 @@ module ActiveSupport
end
private
+ def expires_in(options)
+ expires_in = options && options[:expires_in]
+
+ raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
+
+ expires_in || 0
+ end
+
def log(operation, key, options)
- logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
+ logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !silence? && !logger_off?
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb b/vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb
index 4d8e1fdd..954d0f54 100644
--- a/vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -23,7 +23,12 @@ module ActiveSupport
DELETED = "DELETED\r\n"
end
- attr_reader :addresses
+ def self.build_mem_cache(*addresses)
+ addresses = addresses.flatten
+ options = addresses.extract_options!
+ addresses = ["localhost"] if addresses.empty?
+ MemCache.new(addresses, options)
+ end
# Creates a new MemCacheStore object, with the given memcached server
# addresses. Each address is either a host name, or a host-with-port string
@@ -34,15 +39,20 @@ module ActiveSupport
# If no addresses are specified, then MemCacheStore will connect to
# localhost port 11211 (the default memcached port).
def initialize(*addresses)
- addresses = addresses.flatten
- options = addresses.extract_options!
- addresses = ["localhost"] if addresses.empty?
- @addresses = addresses
- @data = MemCache.new(addresses, options)
+ if addresses.first.respond_to?(:get)
+ @data = addresses.first
+ else
+ @data = self.class.build_mem_cache(*addresses)
+ end
extend Strategy::LocalCache
end
+ # Reads multiple keys from the cache.
+ def read_multi(*keys)
+ @data.get_multi keys
+ end
+
def read(key, options = nil) # :nodoc:
super
@data.get(key, raw?(options))
@@ -120,10 +130,6 @@ module ActiveSupport
end
private
- def expires_in(options)
- (options && options[:expires_in]) || 0
- end
-
def raw?(options)
options && options[:raw]
end
diff --git a/vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb b/vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
index d83e259a..ea59375c 100644
--- a/vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -38,7 +38,7 @@ module ActiveSupport
elsif value.nil?
value = super
local_cache.write(key, value || NULL) if local_cache
- value
+ value.duplicable? ? value.dup : value
else
# forcing the value to be immutable
value.duplicable? ? value.dup : value
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb b/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 10435975..5ae43c0c 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -1,6 +1,14 @@
require 'date'
+require 'active_support/core_ext/module/attribute_accessors'
module ActiveSupport #:nodoc:
+ # these accessors are here because people using ActiveResource and REST to integrate with other systems
+ # have to be able to control the default behavior of rename_key. dasherize_xml is set to true to emulate
+ # existing behavior. In a future version it should be set to false by default.
+ mattr_accessor :dasherize_xml
+ mattr_accessor :camelize_xml
+ self.dasherize_xml = true
+ self.camelize_xml = false
module CoreExtensions #:nodoc:
module Hash #:nodoc:
module Conversions
@@ -143,10 +151,11 @@ module ActiveSupport #:nodoc:
end
def rename_key(key, options = {})
- camelize = options.has_key?(:camelize) && options[:camelize]
- dasherize = !options.has_key?(:dasherize) || options[:dasherize]
+ camelize = options.has_key?(:camelize) ? options[:camelize] : ActiveSupport.camelize_xml
+ dasherize = options.has_key?(:dasherize) ? options[:dasherize] : ActiveSupport.dasherize_xml
key = key.camelize if camelize
- dasherize ? key.dasherize : key
+ key = key.dasherize if dasherize
+ key
end
module ClassMethods
@@ -221,7 +230,7 @@ module ActiveSupport #:nodoc:
case params.class.to_s
when "Hash"
params.inject({}) do |h,(k,v)|
- h[k.to_s.underscore.tr("-", "_")] = unrename_keys(v)
+ h[k.to_s.tr("-", "_")] = unrename_keys(v)
h
end
when "Array"
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb
index 4007a647..0813a513 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb
@@ -2,12 +2,14 @@ module Kernel
unless respond_to?(:debugger)
# Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it).
def debugger
- Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
+ message = "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
+ defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
end
end
def breakpoint
- Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
+ message = "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
+ defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
debugger
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 9402cb85..9359b22b 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/array"
+
# Extends the module object with module and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
#
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb b/vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb
index fb4b5f0f..9377bff2 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -108,12 +108,21 @@ class Module
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
- allow_nil = options[:allow_nil] && "#{to} && "
+ file, line = caller.first.split(':', 2)
+ line = line.to_i
methods.each do |method|
- module_eval(<<-EOS, "(__DELEGATION__)", 1)
+ on_nil =
+ if options[:allow_nil]
+ 'return'
+ else
+ %(raise "#{prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
+ end
+
+ module_eval(<<-EOS, file, line)
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
- #{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block)
+ #{on_nil} if #{to}.nil?
+ #{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block)
end # end
EOS
end
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb b/vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb
index 3ec4f3ba..9686be01 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb
@@ -1,13 +1,15 @@
module ActiveSupport
class ModelName < String
- attr_reader :singular, :plural, :cache_key, :partial_path
+ attr_reader :singular, :plural, :element, :collection, :partial_path
+ alias_method :cache_key, :collection
def initialize(name)
super
- @singular = underscore.tr('/', '_').freeze
- @plural = @singular.pluralize.freeze
- @cache_key = tableize.freeze
- @partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze
+ @singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
+ @plural = ActiveSupport::Inflector.pluralize(@singular).freeze
+ @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze
+ @collection = ActiveSupport::Inflector.tableize(self).freeze
+ @partial_path = "#{@collection}/#{@element}".freeze
end
end
@@ -16,7 +18,7 @@ module ActiveSupport
# Returns an ActiveSupport::ModelName object for module. It can be
# used to retrieve all kinds of naming-related information.
def model_name
- @model_name ||= ModelName.new(name)
+ @model_name ||= ::ActiveSupport::ModelName.new(name)
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb b/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb
index 56477673..d3ff615e 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb
@@ -3,41 +3,47 @@ module ActiveSupport #:nodoc:
module Numeric #:nodoc:
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
module Bytes
+ KILOBYTE = 1024
+ MEGABYTE = KILOBYTE * 1024
+ GIGABYTE = MEGABYTE * 1024
+ TERABYTE = GIGABYTE * 1024
+ PETABYTE = TERABYTE * 1024
+ EXABYTE = PETABYTE * 1024
+
def bytes
self
end
alias :byte :bytes
def kilobytes
- self * 1024
+ self * KILOBYTE
end
alias :kilobyte :kilobytes
def megabytes
- self * 1024.kilobytes
+ self * MEGABYTE
end
alias :megabyte :megabytes
def gigabytes
- self * 1024.megabytes
+ self * GIGABYTE
end
alias :gigabyte :gigabytes
def terabytes
- self * 1024.gigabytes
+ self * TERABYTE
end
alias :terabyte :terabytes
-
+
def petabytes
- self * 1024.terabytes
+ self * PETABYTE
end
alias :petabyte :petabytes
-
+
def exabytes
- self * 1024.petabytes
+ self * EXABYTE
end
alias :exabyte :exabytes
-
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb b/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb
index 7fb21fa4..e806b321 100644
--- a/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb
+++ b/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb
@@ -41,9 +41,15 @@ module ActiveSupport #:nodoc:
# "hello".first(2) # => "he"
# "hello".first(10) # => "hello"
def first(limit = 1)
- mb_chars[0..(limit - 1)].to_s
+ if limit == 0
+ ''
+ elsif limit >= size
+ self
+ else
+ mb_chars[0...limit].to_s
+ end
end
-
+
# Returns the last character of the string or the last +limit+ characters.
#
# Examples:
@@ -51,7 +57,13 @@ module ActiveSupport #:nodoc:
# "hello".last(2) # => "lo"
# "hello".last(10) # => "hello"
def last(limit = 1)
- (mb_chars[(-limit)..-1] || self).to_s
+ if limit == 0
+ ''
+ elsif limit >= size
+ self
+ else
+ mb_chars[(-limit)..-1].to_s
+ end
end
end
else
@@ -69,11 +81,23 @@ module ActiveSupport #:nodoc:
end
def first(limit = 1)
- self[0..(limit - 1)]
+ if limit == 0
+ ''
+ elsif limit >= size
+ self
+ else
+ to(limit - 1)
+ end
end
def last(limit = 1)
- from(-limit) || self
+ if limit == 0
+ ''
+ elsif limit >= size
+ self
+ else
+ from(-limit)
+ end
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/duration.rb b/vendor/rails/activesupport/lib/active_support/duration.rb
index f64661c5..aa6d1aa3 100644
--- a/vendor/rails/activesupport/lib/active_support/duration.rb
+++ b/vendor/rails/activesupport/lib/active_support/duration.rb
@@ -67,10 +67,12 @@ module ActiveSupport
def inspect #:nodoc:
consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h }
- [:years, :months, :days, :minutes, :seconds].map do |length|
+ parts = [:years, :months, :days, :minutes, :seconds].map do |length|
n = consolidated[length]
"#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
- end.compact.to_sentence(:locale => :en)
+ end.compact
+ parts = ["0 seconds"] if parts.empty?
+ parts.to_sentence(:locale => :en)
end
protected
diff --git a/vendor/rails/activesupport/lib/active_support/json.rb b/vendor/rails/activesupport/lib/active_support/json.rb
index 2bdb4a7b..3e1d9b1d 100644
--- a/vendor/rails/activesupport/lib/active_support/json.rb
+++ b/vendor/rails/activesupport/lib/active_support/json.rb
@@ -1,23 +1,2 @@
-module ActiveSupport
- # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
- mattr_accessor :use_standard_json_time_format
-
- class << self
- def escape_html_entities_in_json
- @escape_html_entities_in_json
- end
-
- def escape_html_entities_in_json=(value)
- ActiveSupport::JSON::Encoding.escape_regex = \
- if value
- /[\010\f\n\r\t"\\><&]/
- else
- /[\010\f\n\r\t"\\]/
- end
- @escape_html_entities_in_json = value
- end
- end
-end
-
-require 'active_support/json/encoding'
require 'active_support/json/decoding'
+require 'active_support/json/encoding'
diff --git a/vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb b/vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb
new file mode 100644
index 00000000..a6da27d5
--- /dev/null
+++ b/vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb
@@ -0,0 +1,38 @@
+require 'json' unless defined?(JSON)
+
+module ActiveSupport
+ module JSON
+ ParseError = ::JSON::ParserError unless const_defined?(:ParseError)
+
+ module Backends
+ module JSONGem
+ extend self
+
+ # Converts a JSON string into a Ruby object.
+ def decode(json)
+ data = ::JSON.parse(json)
+ if ActiveSupport.parse_json_times
+ convert_dates_from(data)
+ else
+ data
+ end
+ end
+
+ private
+ def convert_dates_from(data)
+ case data
+ when DATE_REGEX
+ DateTime.parse(data)
+ when Array
+ data.map! { |d| convert_dates_from(d) }
+ when Hash
+ data.each do |key, value|
+ data[key] = convert_dates_from(value)
+ end
+ else data
+ end
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb b/vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb
new file mode 100644
index 00000000..a2797ccd
--- /dev/null
+++ b/vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb
@@ -0,0 +1,85 @@
+require 'active_support/core_ext/string/starts_ends_with'
+
+module ActiveSupport
+ module JSON
+ unless const_defined?(:ParseError)
+ class ParseError < StandardError
+ end
+ end
+
+ module Backends
+ module Yaml
+ extend self
+
+ # Converts a JSON string into a Ruby object.
+ def decode(json)
+ YAML.load(convert_json_to_yaml(json))
+ rescue ArgumentError => e
+ raise ParseError, "Invalid JSON string"
+ end
+
+ protected
+ # Ensure that ":" and "," are always followed by a space
+ def convert_json_to_yaml(json) #:nodoc:
+ require 'strscan' unless defined? ::StringScanner
+ scanner, quoting, marks, pos, times = ::StringScanner.new(json), false, [], nil, []
+ while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
+ case char = scanner[1]
+ when '"', "'"
+ if !quoting
+ quoting = char
+ pos = scanner.pos
+ elsif quoting == char
+ if json[pos..scanner.pos-2] =~ DATE_REGEX
+ # found a date, track the exact positions of the quotes so we can remove them later.
+ # oh, and increment them for each current mark, each one is an extra padded space that bumps
+ # the position in the final YAML output
+ total_marks = marks.size
+ times << pos+total_marks << scanner.pos+total_marks
+ end
+ quoting = false
+ end
+ when ":",","
+ marks << scanner.pos - 1 unless quoting
+ end
+ end
+
+ if marks.empty?
+ json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.start_with?('u')
+ [ustr[1..-1].to_i(16)].pack("U")
+ elsif ustr == '\\'
+ '\\\\'
+ else
+ ustr
+ end
+ end
+ else
+ left_pos = [-1].push(*marks)
+ right_pos = marks << scanner.pos + scanner.rest_size
+ output = []
+ left_pos.each_with_index do |left, i|
+ scanner.pos = left.succ
+ output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.start_with?('u')
+ [ustr[1..-1].to_i(16)].pack("U")
+ elsif ustr == '\\'
+ '\\\\'
+ else
+ ustr
+ end
+ end
+ end
+ output = output * " "
+
+ times.each { |i| output[i-1] = ' ' }
+ output.gsub!(/\\\//, '/')
+ output
+ end
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/rails/activesupport/lib/active_support/json/decoding.rb b/vendor/rails/activesupport/lib/active_support/json/decoding.rb
index 0e079341..b4e41777 100644
--- a/vendor/rails/activesupport/lib/active_support/json/decoding.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/decoding.rb
@@ -1,82 +1,33 @@
-require 'yaml'
-require 'strscan'
+require 'active_support/core_ext/module/attribute_accessors'
module ActiveSupport
+ # Look for and parse json strings that look like ISO 8601 times.
+ mattr_accessor :parse_json_times
+
module JSON
- class ParseError < StandardError
- end
-
class << self
- # Converts a JSON string into a Ruby object.
- def decode(json)
- YAML.load(convert_json_to_yaml(json))
- rescue ArgumentError => e
- raise ParseError, "Invalid JSON string"
+ delegate :decode, :to => :backend
+
+ def backend
+ self.backend = "Yaml" unless defined?(@backend)
+ @backend
end
-
- protected
- # matches YAML-formatted dates
- DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
- # Ensure that ":" and "," are always followed by a space
- def convert_json_to_yaml(json) #:nodoc:
- scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
- while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
- case char = scanner[1]
- when '"', "'"
- if !quoting
- quoting = char
- pos = scanner.pos
- elsif quoting == char
- if json[pos..scanner.pos-2] =~ DATE_REGEX
- # found a date, track the exact positions of the quotes so we can remove them later.
- # oh, and increment them for each current mark, each one is an extra padded space that bumps
- # the position in the final YAML output
- total_marks = marks.size
- times << pos+total_marks << scanner.pos+total_marks
- end
- quoting = false
- end
- when ":",","
- marks << scanner.pos - 1 unless quoting
- end
- end
-
- if marks.empty?
- json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
- ustr = $1
- if ustr.starts_with?('u')
- [ustr[1..-1].to_i(16)].pack("U")
- elsif ustr == '\\'
- '\\\\'
- else
- ustr
- end
- end
- else
- left_pos = [-1].push(*marks)
- right_pos = marks << scanner.pos + scanner.rest_size
- output = []
- left_pos.each_with_index do |left, i|
- scanner.pos = left.succ
- output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
- ustr = $1
- if ustr.starts_with?('u')
- [ustr[1..-1].to_i(16)].pack("U")
- elsif ustr == '\\'
- '\\\\'
- else
- ustr
- end
- end
- end
- output = output * " "
-
- times.each { |i| output[i-1] = ' ' }
- output.gsub!(/\\\//, '/')
- output
- end
+ def backend=(name)
+ if name.is_a?(Module)
+ @backend = name
+ else
+ require "active_support/json/backends/#{name.to_s.downcase}.rb"
+ @backend = ActiveSupport::JSON::Backends::const_get(name)
end
+ end
+
+ def with_backend(name)
+ old_backend, self.backend = backend, name
+ yield
+ ensure
+ self.backend = old_backend
+ end
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/date.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/date.rb
index cc84de13..0df1b8ed 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/date.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/date.rb
@@ -1,21 +1,22 @@
class Date
- # Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
+ # Coerces the date to a string for JSON encoding.
+ #
+ # ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
#
# ==== Examples
#
- # # With ActiveSupport.use_standard_json_time_format = true
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
# Date.new(2005,2,1).to_json
# # => "2005-02-01"
#
- # # With ActiveSupport.use_standard_json_time_format = false
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
# Date.new(2005,2,1).to_json
# # => "2005/02/01"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- %("#{strftime("%Y-%m-%d")}")
+ def as_json(options = nil)
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+ strftime("%Y-%m-%d")
else
- %("#{strftime("%Y/%m/%d")}")
+ strftime("%Y/%m/%d")
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb
index 6c858241..20c12a76 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb
@@ -1,21 +1,22 @@
class DateTime
- # Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
+ # Coerces the datetime to a string for JSON encoding.
+ #
+ # ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
#
# ==== Examples
#
- # # With ActiveSupport.use_standard_json_time_format = true
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
# DateTime.civil(2005,2,1,15,15,10).to_json
# # => "2005-02-01T15:15:10+00:00"
#
- # # With ActiveSupport.use_standard_json_time_format = false
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
# DateTime.civil(2005,2,1,15,15,10).to_json
# # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
+ def as_json(options = nil)
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+ xmlschema
else
- strftime('"%Y/%m/%d %H:%M:%S %z"')
+ strftime('%Y/%m/%d %H:%M:%S %z')
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb
index 881b1d62..65924e38 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb
@@ -1,12 +1,17 @@
module Enumerable
- # Returns a JSON string representing the enumerable. Any +options+
- # given will be passed on to its elements. For example:
- #
- # users = User.find(:all)
- # # => users.to_json(:only => :name)
- #
- # will pass the :only => :name option to each user.
- def to_json(options = {}) #:nodoc:
- "[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ', '}]"
+ # Coerces the enumerable to an array for JSON encoding.
+ def as_json(options = nil) #:nodoc:
+ to_a
+ end
+end
+
+class Array
+ # Returns a JSON string representing the Array. +options+ are passed to each element.
+ def to_json(options = nil) #:nodoc:
+ "[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"
+ end
+
+ def as_json(options = nil) #:nodoc:
+ self
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/false_class.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/false_class.rb
index bf084433..c2bb1ee2 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/false_class.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/false_class.rb
@@ -1,5 +1,7 @@
class FalseClass
- def to_json(options = nil) #:nodoc:
- 'false'
+ AS_JSON = ActiveSupport::JSON::Variable.new('false').freeze
+
+ def as_json(options = nil) #:nodoc:
+ AS_JSON
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/hash.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/hash.rb
index e38b4f3e..cfe21e4a 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/hash.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/hash.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/wrapper'
+
class Hash
# Returns a JSON string representing the hash.
#
@@ -28,19 +30,27 @@ class Hash
# would pass the :include => :posts option to users ,
# allowing the posts association in the User model to be converted to JSON
# as well.
- def to_json(options = {}) #:nodoc:
- hash_keys = self.keys
-
- if except = options[:except]
- hash_keys = hash_keys - Array.wrap(except)
- elsif only = options[:only]
- hash_keys = hash_keys & Array.wrap(only)
- end
+ def to_json(options = nil) #:nodoc:
+ hash = as_json(options)
result = '{'
- result << hash_keys.map do |key|
- "#{ActiveSupport::JSON.encode(key.to_s)}: #{ActiveSupport::JSON.encode(self[key], options)}"
- end * ', '
+ result << hash.map do |key, value|
+ "#{ActiveSupport::JSON.encode(key.to_s)}:#{ActiveSupport::JSON.encode(value, options)}"
+ end * ','
result << '}'
end
+
+ def as_json(options = nil) #:nodoc:
+ if options
+ if attrs = options[:except]
+ except(*Array.wrap(attrs))
+ elsif attrs = options[:only]
+ slice(*Array.wrap(attrs))
+ else
+ self
+ end
+ else
+ self
+ end
+ end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/nil_class.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/nil_class.rb
index 4763471a..041c1a26 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/nil_class.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/nil_class.rb
@@ -1,5 +1,7 @@
class NilClass
- def to_json(options = nil) #:nodoc:
- 'null'
+ AS_JSON = ActiveSupport::JSON::Variable.new('null').freeze
+
+ def as_json(options = nil) #:nodoc:
+ AS_JSON
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/numeric.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/numeric.rb
index 38713fb3..6493bd67 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/numeric.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/numeric.rb
@@ -2,4 +2,20 @@ class Numeric
def to_json(options = nil) #:nodoc:
to_s
end
+
+ def as_json(options = nil) #:nodoc:
+ self
+ end
+end
+
+class Float
+ def to_json(options = nil) #:nodoc:
+ to_s
+ end
+end
+
+class Integer
+ def to_json(options = nil) #:nodoc:
+ to_s
+ end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/object.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/object.rb
index ca215d49..09941005 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/object.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/object.rb
@@ -1,6 +1,10 @@
class Object
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
- def to_json(options = {})
- ActiveSupport::JSON.encode(instance_values, options)
+ def to_json(options = nil)
+ ActiveSupport::JSON.encode(as_json(options))
+ end
+
+ def as_json(options = nil)
+ instance_values
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/regexp.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/regexp.rb
index b6116b70..14fdbf24 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/regexp.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/regexp.rb
@@ -2,4 +2,8 @@ class Regexp
def to_json(options = nil) #:nodoc:
inspect
end
+
+ def as_json(options = nil) #:nodoc:
+ self
+ end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/string.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/string.rb
index 5ef79795..697658ec 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/string.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/string.rb
@@ -1,36 +1,9 @@
-module ActiveSupport
- module JSON
- module Encoding
- mattr_accessor :escape_regex
-
- ESCAPED_CHARS = {
- "\010" => '\b',
- "\f" => '\f',
- "\n" => '\n',
- "\r" => '\r',
- "\t" => '\t',
- '"' => '\"',
- '\\' => '\\\\',
- '>' => '\u003E',
- '<' => '\u003C',
- '&' => '\u0026'
- }
- end
- end
-end
-
-ActiveSupport.escape_html_entities_in_json = true
-
class String
def to_json(options = nil) #:nodoc:
- json = '"' + gsub(ActiveSupport::JSON::Encoding.escape_regex) { |s|
- ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
- }
- json.force_encoding('ascii-8bit') if respond_to?(:force_encoding)
- json.gsub(/([\xC0-\xDF][\x80-\xBF]|
- [\xE0-\xEF][\x80-\xBF]{2}|
- [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
- s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
- } + '"'
+ ActiveSupport::JSON::Encoding.escape(self)
+ end
+
+ def as_json(options = nil) #:nodoc:
+ self
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/symbol.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/symbol.rb
index 485112f9..f7dcd491 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/symbol.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/symbol.rb
@@ -1,5 +1,5 @@
class Symbol
- def to_json(options = {}) #:nodoc:
- ActiveSupport::JSON.encode(to_s, options)
+ def as_json(options = nil) #:nodoc:
+ to_s
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/time.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/time.rb
index f45a0059..fa54e9e3 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/time.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/time.rb
@@ -1,21 +1,22 @@
class Time
- # Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
+ # Coerces the time to a string for JSON encoding.
+ #
+ # ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
#
# ==== Examples
#
- # # With ActiveSupport.use_standard_json_time_format = true
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
# Time.utc(2005,2,1,15,15,10).to_json
# # => "2005-02-01T15:15:10Z"
#
- # # With ActiveSupport.use_standard_json_time_format = false
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
# Time.utc(2005,2,1,15,15,10).to_json
# # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
+ def as_json(options = nil)
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+ xmlschema
else
- %("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
+ %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoders/true_class.rb b/vendor/rails/activesupport/lib/active_support/json/encoders/true_class.rb
index 037d812b..4b65dee3 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoders/true_class.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoders/true_class.rb
@@ -1,5 +1,7 @@
class TrueClass
- def to_json(options = nil) #:nodoc:
- 'true'
+ AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze
+
+ def as_json(options = nil) #:nodoc:
+ AS_JSON
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/json/encoding.rb b/vendor/rails/activesupport/lib/active_support/json/encoding.rb
index aaaa3cdf..ffd20500 100644
--- a/vendor/rails/activesupport/lib/active_support/json/encoding.rb
+++ b/vendor/rails/activesupport/lib/active_support/json/encoding.rb
@@ -1,20 +1,91 @@
+# encoding: utf-8
+require 'active_support/core_ext/module/delegation'
+require 'active_support/deprecation'
+
module ActiveSupport
+ class << self
+ delegate :use_standard_json_time_format, :use_standard_json_time_format=,
+ :escape_html_entities_in_json, :escape_html_entities_in_json=,
+ :to => :'ActiveSupport::JSON::Encoding'
+ end
+
module JSON
- class CircularReferenceError < StandardError
+ # matches YAML-formatted dates
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+
+ class << self
+ delegate :encode, :to => :'ActiveSupport::JSON::Encoding'
end
- # Converts a Ruby object into a JSON string.
- def self.encode(value, options = {})
- seen = (options[:seen] ||= [])
- raise CircularReferenceError, 'object references itself' if seen.include?(value)
- seen << value
- value.send(:to_json, options)
- ensure
- seen.pop
+ module Encoding #:nodoc:
+ class CircularReferenceError < StandardError
+ end
+
+ ESCAPED_CHARS = {
+ "\010" => '\b',
+ "\f" => '\f',
+ "\n" => '\n',
+ "\r" => '\r',
+ "\t" => '\t',
+ '"' => '\"',
+ '\\' => '\\\\',
+ '>' => '\u003E',
+ '<' => '\u003C',
+ '&' => '\u0026' }
+
+ class << self
+ # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
+ attr_accessor :use_standard_json_time_format
+
+ attr_accessor :escape_regex
+ attr_reader :escape_html_entities_in_json
+
+ def escape_html_entities_in_json=(value)
+ self.escape_regex = \
+ if @escape_html_entities_in_json = value
+ /[\010\f\n\r\t"\\><&]/
+ else
+ /[\010\f\n\r\t"\\]/
+ end
+ end
+
+ def escape(string)
+ string = string.dup.force_encoding(::Encoding::BINARY) if string.respond_to?(:force_encoding)
+ json = string.
+ gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
+ gsub(/([\xC0-\xDF][\x80-\xBF]|
+ [\xE0-\xEF][\x80-\xBF]{2}|
+ [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
+ s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
+ }
+ %("#{json}")
+ end
+
+ # Converts a Ruby object into a JSON string.
+ def encode(value, options = nil)
+ options = {} unless Hash === options
+ seen = (options[:seen] ||= [])
+ raise CircularReferenceError, 'object references itself' if seen.include?(value)
+ seen << value
+ value.to_json(options)
+ ensure
+ seen.pop
+ end
+ end
+
+ self.escape_html_entities_in_json = true
end
+
+ CircularReferenceError = Deprecation::DeprecatedConstantProxy.new('ActiveSupport::JSON::CircularReferenceError', Encoding::CircularReferenceError)
end
end
+# Hack to load json gem first so we can overwrite its to_json.
+begin
+ require 'json'
+rescue LoadError
+end
+
require 'active_support/json/variable'
require 'active_support/json/encoders/date'
require 'active_support/json/encoders/date_time'
diff --git a/vendor/rails/activesupport/lib/active_support/ordered_hash.rb b/vendor/rails/activesupport/lib/active_support/ordered_hash.rb
index fed8094a..4324e40c 100644
--- a/vendor/rails/activesupport/lib/active_support/ordered_hash.rb
+++ b/vendor/rails/activesupport/lib/active_support/ordered_hash.rb
@@ -10,6 +10,30 @@ module ActiveSupport
@keys = []
end
+ def self.[](*args)
+ ordered_hash = new
+
+ if (args.length == 1 && args.first.is_a?(Array))
+ args.first.each do |key_value_pair|
+ next unless (key_value_pair.is_a?(Array))
+ ordered_hash[key_value_pair[0]] = key_value_pair[1]
+ end
+
+ return ordered_hash
+ end
+
+ unless (args.size % 2 == 0)
+ raise ArgumentError.new("odd number of arguments for Hash")
+ end
+
+ args.each_with_index do |val, ind|
+ next if (ind % 2 != 0)
+ ordered_hash[val] = args[ind + 1]
+ end
+
+ ordered_hash
+ end
+
def initialize_copy(other)
super
# make a deep copy of keys
@@ -57,6 +81,10 @@ module ActiveSupport
self
end
+ def to_a
+ @keys.map { |key| [ key, self[key] ] }
+ end
+
def each_key
@keys.each { |key| yield key }
end
diff --git a/vendor/rails/activesupport/lib/active_support/test_case.rb b/vendor/rails/activesupport/lib/active_support/test_case.rb
index f05d4098..62fe7f5f 100644
--- a/vendor/rails/activesupport/lib/active_support/test_case.rb
+++ b/vendor/rails/activesupport/lib/active_support/test_case.rb
@@ -1,5 +1,11 @@
+require 'test/unit/testcase'
+require 'active_support/testing/setup_and_teardown'
+require 'active_support/testing/assertions'
+require 'active_support/testing/deprecation'
+require 'active_support/testing/declarative'
+
begin
- gem 'mocha', '>= 0.9.3'
+ gem 'mocha', ">= 0.9.7"
require 'mocha'
rescue LoadError
# Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
@@ -7,12 +13,6 @@ rescue LoadError
Mocha.const_set :ExpectationError, Class.new(StandardError)
end
-require 'test/unit/testcase'
-require 'active_support/testing/setup_and_teardown'
-require 'active_support/testing/assertions'
-require 'active_support/testing/deprecation'
-require 'active_support/testing/declarative'
-
module ActiveSupport
class TestCase < ::Test::Unit::TestCase
if defined? MiniTest
diff --git a/vendor/rails/activesupport/lib/active_support/testing/deprecation.rb b/vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
index e9220605..2271caf8 100644
--- a/vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
+++ b/vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/module"
+
module ActiveSupport
module Testing
module Deprecation #:nodoc:
diff --git a/vendor/rails/activesupport/lib/active_support/time_with_zone.rb b/vendor/rails/activesupport/lib/active_support/time_with_zone.rb
index 518ca774..2e5a2332 100644
--- a/vendor/rails/activesupport/lib/active_support/time_with_zone.rb
+++ b/vendor/rails/activesupport/lib/active_support/time_with_zone.rb
@@ -108,23 +108,24 @@ module ActiveSupport
end
alias_method :iso8601, :xmlschema
- # Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to
- # true, the ISO 8601 format is used.
+ # Coerces the date to a string for JSON encoding.
+ #
+ # ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
#
# ==== Examples
#
- # # With ActiveSupport.use_standard_json_time_format = true
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
# # => "2005-02-01T15:15:10Z"
#
- # # With ActiveSupport.use_standard_json_time_format = false
+ # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
# # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
+ def as_json(options = nil)
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+ xmlschema
else
- %("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
+ %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
end
diff --git a/vendor/rails/activesupport/lib/active_support/vendor.rb b/vendor/rails/activesupport/lib/active_support/vendor.rb
index 28852e65..5b51af0a 100644
--- a/vendor/rails/activesupport/lib/active_support/vendor.rb
+++ b/vendor/rails/activesupport/lib/active_support/vendor.rb
@@ -9,9 +9,9 @@ end
require 'builder'
begin
- gem 'memcache-client', '>= 1.6.5'
+ gem 'memcache-client', '>= 1.7.4'
rescue Gem::LoadError
- $:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.6.5"
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.7.4"
end
begin
@@ -20,10 +20,9 @@ rescue Gem::LoadError
$:.unshift "#{File.dirname(__FILE__)}/vendor/tzinfo-0.3.12"
end
-# TODO I18n gem has not been released yet
-# begin
-# gem 'i18n', '~> 0.1.3'
-# rescue Gem::LoadError
+begin
+ gem 'i18n', '~> 0.1.3'
+rescue Gem::LoadError
$:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.1.3/lib"
require 'i18n'
-# end
+end
diff --git a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
index dfcba690..4e78e71b 100644
--- a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
+++ b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
@@ -2,7 +2,6 @@ $:.unshift "lib"
require 'rubygems'
require 'test/unit'
-require 'mocha'
require 'i18n'
require 'active_support'
diff --git a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
index 50d6832c..2835ec4e 100644
--- a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
+++ b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
@@ -2,7 +2,6 @@ $:.unshift "lib"
require 'rubygems'
require 'test/unit'
-require 'mocha'
require 'i18n'
require 'active_support'
diff --git a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
index 65f3ac11..a1696c77 100644
--- a/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
+++ b/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
@@ -3,7 +3,6 @@ $:.unshift "lib"
require 'rubygems'
require 'test/unit'
-require 'mocha'
require 'i18n'
require 'time'
require 'yaml'
diff --git a/vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb b/vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb
similarity index 73%
rename from vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
rename to vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb
index 4d594c20..f249da79 100644
--- a/vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
+++ b/vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb
@@ -2,9 +2,9 @@ $TESTING = defined?($TESTING) && $TESTING
require 'socket'
require 'thread'
-require 'timeout'
require 'zlib'
require 'digest/sha1'
+require 'net/protocol'
##
# A Ruby client library for memcached.
@@ -15,7 +15,7 @@ class MemCache
##
# The version of MemCache you are using.
- VERSION = '1.6.4.99'
+ VERSION = '1.7.4'
##
# Default options for the cache object.
@@ -27,6 +27,7 @@ class MemCache
:failover => true,
:timeout => 0.5,
:logger => nil,
+ :no_reply => false,
}
##
@@ -71,6 +72,12 @@ class MemCache
attr_reader :logger
+ ##
+ # Don't send or look for a reply from the memcached server for write operations.
+ # Please note this feature only works in memcached 1.2.5 and later. Earlier
+ # versions will reply with "ERROR".
+ attr_reader :no_reply
+
##
# Accepts a list of +servers+ and a list of +opts+. +servers+ may be
# omitted. See +servers=+ for acceptable server list arguments.
@@ -79,12 +86,17 @@ class MemCache
#
# [:namespace] Prepends this value to all keys added or retrieved.
# [:readonly] Raises an exception on cache writes when true.
- # [:multithread] Wraps cache access in a Mutex for thread safety.
+ # [:multithread] Wraps cache access in a Mutex for thread safety. Defaults to true.
# [:failover] Should the client try to failover to another server if the
# first server is down? Defaults to true.
# [:timeout] Time to use as the socket read timeout. Defaults to 0.5 sec,
- # set to nil to disable timeouts (this is a major performance penalty in Ruby 1.8).
+ # set to nil to disable timeouts (this is a major performance penalty in Ruby 1.8,
+ # "gem install SystemTimer' to remove most of the penalty).
# [:logger] Logger to use for info/debug output, defaults to nil
+ # [:no_reply] Don't bother looking for a reply for write operations (i.e. they
+ # become 'fire and forget'), memcached 1.2.5 and later only, speeds up
+ # set/add/delete/incr/decr significantly.
+ #
# Other options are ignored.
def initialize(*args)
@@ -114,6 +126,7 @@ class MemCache
@timeout = opts[:timeout]
@failover = opts[:failover]
@logger = opts[:logger]
+ @no_reply = opts[:no_reply]
@mutex = Mutex.new if @multithread
logger.info { "memcache-client #{VERSION} #{Array(servers).inspect}" } if logger
@@ -192,8 +205,8 @@ class MemCache
def get(key, raw = false)
with_server(key) do |server, cache_key|
+ logger.debug { "get #{key} from #{server.inspect}" } if logger
value = cache_get server, cache_key
- logger.debug { "GET #{key} from #{server.inspect}: #{value ? value.to_s.size : 'nil'}" } if logger
return nil if value.nil?
value = Marshal.load value unless raw
return value
@@ -202,6 +215,25 @@ class MemCache
handle_error nil, err
end
+ ##
+ # Performs a +get+ with the given +key+. If
+ # the value does not exist and a block was given,
+ # the block will be called and the result saved via +add+.
+ #
+ # If you do not provide a block, using this
+ # method is the same as using +get+.
+ #
+ def fetch(key, expiry = 0, raw = false)
+ value = get(key, raw)
+
+ if value.nil? && block_given?
+ value = yield
+ add(key, value, expiry, raw)
+ end
+
+ value
+ end
+
##
# Retrieves multiple values from memcached in parallel, if possible.
#
@@ -283,15 +315,60 @@ class MemCache
with_server(key) do |server, cache_key|
value = Marshal.dump value unless raw
- logger.debug { "SET #{key} to #{server.inspect}: #{value ? value.to_s.size : 'nil'}" } if logger
+ logger.debug { "set #{key} to #{server.inspect}: #{value.to_s.size}" } if logger
- data = value.to_s
- raise MemCacheError, "Value too large, memcached can only store 1MB of data per key" if data.size > ONE_MB
+ raise MemCacheError, "Value too large, memcached can only store 1MB of data per key" if value.to_s.size > ONE_MB
- command = "set #{cache_key} 0 #{expiry} #{data.size}\r\n#{data}\r\n"
+ command = "set #{cache_key} 0 #{expiry} #{value.to_s.size}#{noreply}\r\n#{value}\r\n"
with_socket_management(server) do |socket|
socket.write command
+ break nil if @no_reply
+ result = socket.gets
+ raise_on_error_response! result
+
+ if result.nil?
+ server.close
+ raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
+ end
+
+ result
+ end
+ end
+ end
+
+ ##
+ # "cas" is a check and set operation which means "store this data but
+ # only if no one else has updated since I last fetched it." This can
+ # be used as a form of optimistic locking.
+ #
+ # Works in block form like so:
+ # cache.cas('some-key') do |value|
+ # value + 1
+ # end
+ #
+ # Returns:
+ # +nil+ if the value was not found on the memcached server.
+ # +STORED+ if the value was updated successfully
+ # +EXISTS+ if the value was updated by someone else since last fetch
+
+ def cas(key, expiry=0, raw=false)
+ raise MemCacheError, "Update of readonly cache" if @readonly
+ raise MemCacheError, "A block is required" unless block_given?
+
+ (value, token) = gets(key, raw)
+ return nil unless value
+ updated = yield value
+
+ with_server(key) do |server, cache_key|
+
+ value = Marshal.dump updated unless raw
+ logger.debug { "cas #{key} to #{server.inspect}: #{value.to_s.size}" } if logger
+ command = "cas #{cache_key} 0 #{expiry} #{value.to_s.size} #{token}#{noreply}\r\n#{value}\r\n"
+
+ with_socket_management(server) do |socket|
+ socket.write command
+ break nil if @no_reply
result = socket.gets
raise_on_error_response! result
@@ -311,17 +388,79 @@ class MemCache
# If +raw+ is true, +value+ will not be Marshalled.
#
# Readers should call this method in the event of a cache miss, not
- # MemCache#set or MemCache#[]=.
+ # MemCache#set.
def add(key, value, expiry = 0, raw = false)
raise MemCacheError, "Update of readonly cache" if @readonly
with_server(key) do |server, cache_key|
value = Marshal.dump value unless raw
- logger.debug { "ADD #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
- command = "add #{cache_key} 0 #{expiry} #{value.to_s.size}\r\n#{value}\r\n"
+ logger.debug { "add #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
+ command = "add #{cache_key} 0 #{expiry} #{value.to_s.size}#{noreply}\r\n#{value}\r\n"
with_socket_management(server) do |socket|
socket.write command
+ break nil if @no_reply
+ result = socket.gets
+ raise_on_error_response! result
+ result
+ end
+ end
+ end
+
+ ##
+ # Add +key+ to the cache with value +value+ that expires in +expiry+
+ # seconds, but only if +key+ already exists in the cache.
+ # If +raw+ is true, +value+ will not be Marshalled.
+ def replace(key, value, expiry = 0, raw = false)
+ raise MemCacheError, "Update of readonly cache" if @readonly
+ with_server(key) do |server, cache_key|
+ value = Marshal.dump value unless raw
+ logger.debug { "replace #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
+ command = "replace #{cache_key} 0 #{expiry} #{value.to_s.size}#{noreply}\r\n#{value}\r\n"
+
+ with_socket_management(server) do |socket|
+ socket.write command
+ break nil if @no_reply
+ result = socket.gets
+ raise_on_error_response! result
+ result
+ end
+ end
+ end
+
+ ##
+ # Append - 'add this data to an existing key after existing data'
+ # Please note the value is always passed to memcached as raw since it
+ # doesn't make a lot of sense to concatenate marshalled data together.
+ def append(key, value)
+ raise MemCacheError, "Update of readonly cache" if @readonly
+ with_server(key) do |server, cache_key|
+ logger.debug { "append #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
+ command = "append #{cache_key} 0 0 #{value.to_s.size}#{noreply}\r\n#{value}\r\n"
+
+ with_socket_management(server) do |socket|
+ socket.write command
+ break nil if @no_reply
+ result = socket.gets
+ raise_on_error_response! result
+ result
+ end
+ end
+ end
+
+ ##
+ # Prepend - 'add this data to an existing key before existing data'
+ # Please note the value is always passed to memcached as raw since it
+ # doesn't make a lot of sense to concatenate marshalled data together.
+ def prepend(key, value)
+ raise MemCacheError, "Update of readonly cache" if @readonly
+ with_server(key) do |server, cache_key|
+ logger.debug { "prepend #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
+ command = "prepend #{cache_key} 0 0 #{value.to_s.size}#{noreply}\r\n#{value}\r\n"
+
+ with_socket_management(server) do |socket|
+ socket.write command
+ break nil if @no_reply
result = socket.gets
raise_on_error_response! result
result
@@ -336,7 +475,9 @@ class MemCache
raise MemCacheError, "Update of readonly cache" if @readonly
with_server(key) do |server, cache_key|
with_socket_management(server) do |socket|
- socket.write "delete #{cache_key} #{expiry}\r\n"
+ logger.debug { "delete #{cache_key} on #{server}" } if logger
+ socket.write "delete #{cache_key} #{expiry}#{noreply}\r\n"
+ break nil if @no_reply
result = socket.gets
raise_on_error_response! result
result
@@ -346,19 +487,33 @@ class MemCache
##
# Flush the cache from all memcache servers.
+ # A non-zero value for +delay+ will ensure that the flush
+ # is propogated slowly through your memcached server farm.
+ # The Nth server will be flushed N*delay seconds from now,
+ # asynchronously so this method returns quickly.
+ # This prevents a huge database spike due to a total
+ # flush all at once.
- def flush_all
+ def flush_all(delay=0)
raise MemCacheError, 'No active servers' unless active?
raise MemCacheError, "Update of readonly cache" if @readonly
begin
+ delay_time = 0
@servers.each do |server|
with_socket_management(server) do |socket|
- socket.write "flush_all\r\n"
+ logger.debug { "flush_all #{delay_time} on #{server}" } if logger
+ if delay == 0 # older versions of memcached will fail silently otherwise
+ socket.write "flush_all#{noreply}\r\n"
+ else
+ socket.write "flush_all #{delay_time}#{noreply}\r\n"
+ end
+ break nil if @no_reply
result = socket.gets
raise_on_error_response! result
result
end
+ delay_time += delay
end
rescue IndexError => err
handle_error nil, err
@@ -500,7 +655,7 @@ class MemCache
break unless failover
hkey = hash_for "#{try}#{key}"
end
-
+
raise MemCacheError, "No servers available"
end
@@ -510,7 +665,8 @@ class MemCache
def cache_decr(server, cache_key, amount)
with_socket_management(server) do |socket|
- socket.write "decr #{cache_key} #{amount}\r\n"
+ socket.write "decr #{cache_key} #{amount}#{noreply}\r\n"
+ break nil if @no_reply
text = socket.gets
raise_on_error_response! text
return nil if text == "NOT_FOUND\r\n"
@@ -546,6 +702,38 @@ class MemCache
end
end
+ def gets(key, raw = false)
+ with_server(key) do |server, cache_key|
+ logger.debug { "gets #{key} from #{server.inspect}" } if logger
+ result = with_socket_management(server) do |socket|
+ socket.write "gets #{cache_key}\r\n"
+ keyline = socket.gets # "VALUE \r\n"
+
+ if keyline.nil? then
+ server.close
+ raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
+ end
+
+ raise_on_error_response! keyline
+ return nil if keyline == "END\r\n"
+
+ unless keyline =~ /(\d+) (\w+)\r/ then
+ server.close
+ raise MemCacheError, "unexpected response #{keyline.inspect}"
+ end
+ value = socket.read $1.to_i
+ socket.read 2 # "\r\n"
+ socket.gets # "END\r\n"
+ [value, $2]
+ end
+ result[0] = Marshal.load result[0] unless raw
+ result
+ end
+ rescue TypeError => err
+ handle_error nil, err
+ end
+
+
##
# Fetches +cache_keys+ from +server+ using a multi-get.
@@ -579,7 +767,8 @@ class MemCache
def cache_incr(server, cache_key, amount)
with_socket_management(server) do |socket|
- socket.write "incr #{cache_key} #{amount}\r\n"
+ socket.write "incr #{cache_key} #{amount}#{noreply}\r\n"
+ break nil if @no_reply
text = socket.gets
raise_on_error_response! text
return nil if text == "NOT_FOUND\r\n"
@@ -617,7 +806,7 @@ class MemCache
block.call(socket)
- rescue SocketError => err
+ rescue SocketError, Errno::EAGAIN, Timeout::Error => err
logger.warn { "Socket failure: #{err.message}" } if logger
server.mark_dead(err)
handle_error(server, err)
@@ -659,6 +848,10 @@ class MemCache
raise new_error
end
+ def noreply
+ @no_reply ? ' noreply' : ''
+ end
+
##
# Performs setup for making a request with +key+ from memcached. Returns
# the server to fetch the key from and the complete key to use.
@@ -712,13 +905,6 @@ class MemCache
class Server
- ##
- # The amount of time to wait to establish a connection with a memcached
- # server. If a connection cannot be established within this time limit,
- # the server will be marked as down.
-
- CONNECT_TIMEOUT = 0.25
-
##
# The amount of time to wait before attempting to re-establish a
# connection with a server that is marked dead.
@@ -802,14 +988,11 @@ class MemCache
# Attempt to connect if not already connected.
begin
- @sock = @timeout ? TCPTimeoutSocket.new(@host, @port, @timeout) : TCPSocket.new(@host, @port)
-
- if Socket.constants.include? 'TCP_NODELAY' then
- @sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
- end
+ @sock = connect_to(@host, @port, @timeout)
+ @sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
@retry = nil
@status = 'CONNECTED'
- rescue SocketError, SystemCallError, IOError, Timeout::Error => err
+ rescue SocketError, SystemCallError, IOError => err
logger.warn { "Unable to open socket: #{err.class.name}, #{err.message}" } if logger
mark_dead err
end
@@ -817,6 +1000,12 @@ class MemCache
return @sock
end
+ def connect_to(host, port, timeout=nil)
+ io = MemCache::BufferedIO.new(TCPSocket.new(host, port))
+ io.read_timeout = timeout
+ io
+ end
+
##
# Close the connection to the memcached server targeted by this
# object. The server is not considered dead.
@@ -848,51 +1037,33 @@ class MemCache
class MemCacheError < RuntimeError; end
-end
+ class BufferedIO < Net::BufferedIO # :nodoc:
+ BUFSIZE = 1024 * 16
-# TCPSocket facade class which implements timeouts.
-class TCPTimeoutSocket
+ # An implementation similar to this is in *trunk* for 1.9. When it
+ # gets released, this method can be removed when using 1.9
+ def rbuf_fill
+ begin
+ @rbuf << @io.read_nonblock(BUFSIZE)
+ rescue Errno::EWOULDBLOCK
+ retry unless @read_timeout
+ if IO.select([@io], nil, nil, @read_timeout)
+ retry
+ else
+ raise Timeout::Error, 'IO timeout'
+ end
+ end
+ end
- def initialize(host, port, timeout)
- Timeout::timeout(MemCache::Server::CONNECT_TIMEOUT, SocketError) do
- @sock = TCPSocket.new(host, port)
- @len = timeout
+ def setsockopt *args
+ @io.setsockopt *args
+ end
+
+ def gets
+ readuntil("\n")
end
end
- def write(*args)
- Timeout::timeout(@len, SocketError) do
- @sock.write(*args)
- end
- end
-
- def gets(*args)
- Timeout::timeout(@len, SocketError) do
- @sock.gets(*args)
- end
- end
-
- def read(*args)
- Timeout::timeout(@len, SocketError) do
- @sock.read(*args)
- end
- end
-
- def _socket
- @sock
- end
-
- def method_missing(meth, *args)
- @sock.__send__(meth, *args)
- end
-
- def closed?
- @sock.closed?
- end
-
- def close
- @sock.close
- end
end
module Continuum
@@ -932,4 +1103,5 @@ module Continuum
"<#{value}, #{server.host}:#{server.port}>"
end
end
+
end
diff --git a/vendor/rails/activesupport/lib/active_support/version.rb b/vendor/rails/activesupport/lib/active_support/version.rb
index 30f598a8..24ce690c 100644
--- a/vendor/rails/activesupport/lib/active_support/version.rb
+++ b/vendor/rails/activesupport/lib/active_support/version.rb
@@ -2,7 +2,7 @@ module ActiveSupport
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/activesupport/lib/active_support/xml_mini/jdom.rb b/vendor/rails/activesupport/lib/active_support/xml_mini/jdom.rb
new file mode 100644
index 00000000..d795d556
--- /dev/null
+++ b/vendor/rails/activesupport/lib/active_support/xml_mini/jdom.rb
@@ -0,0 +1,162 @@
+raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/
+
+require 'jruby'
+include Java
+
+import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder
+import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory
+import java.io.StringReader unless defined? StringReader
+import org.xml.sax.InputSource unless defined? InputSource
+import org.xml.sax.Attributes unless defined? Attributes
+import org.w3c.dom.Node unless defined? Node
+
+# = XmlMini JRuby JDOM implementation
+module ActiveSupport
+ module XmlMini_JDOM #:nodoc:
+ extend self
+
+ CONTENT_KEY = '__content__'.freeze
+
+ NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
+ DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
+ PROCESSING_INSTRUCTION_NODE TEXT_NODE}
+
+ node_type_map = {}
+ NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
+
+ # Parse an XML Document string into a simple hash using Java's jdom.
+ # string::
+ # XML Document string to parse
+ def parse(string)
+ if string.blank?
+ {}
+ else
+ @dbf = DocumentBuilderFactory.new_instance
+ xml_string_reader = StringReader.new(string)
+ xml_input_source = InputSource.new(xml_string_reader)
+ doc = @dbf.new_document_builder.parse(xml_input_source)
+ merge_element!({}, doc.document_element)
+ end
+ end
+
+ private
+
+ # Convert an XML element and merge into the hash
+ #
+ # hash::
+ # Hash to merge the converted element into.
+ # element::
+ # XML element to merge into hash
+ def merge_element!(hash, element)
+ merge!(hash, element.tag_name, collapse(element))
+ end
+
+ # Actually converts an XML document element into a data structure.
+ #
+ # element::
+ # The document element to be collapsed.
+ def collapse(element)
+ hash = get_attributes(element)
+
+ child_nodes = element.child_nodes
+ if child_nodes.length > 0
+ for i in 0...child_nodes.length
+ child = child_nodes.item(i)
+ merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE
+ end
+ merge_texts!(hash, element) unless empty_content?(element)
+ hash
+ else
+ merge_texts!(hash, element)
+ end
+ end
+
+ # Merge all the texts of an element into the hash
+ #
+ # hash::
+ # Hash to add the converted emement to.
+ # element::
+ # XML element whose texts are to me merged into the hash
+ def merge_texts!(hash, element)
+ text_children = texts(element)
+ if text_children.join.empty?
+ hash
+ else
+ # must use value to prevent double-escaping
+ merge!(hash, CONTENT_KEY, text_children.join)
+ end
+ end
+
+ # Adds a new key/value pair to an existing Hash. If the key to be added
+ # already exists and the existing value associated with key is not
+ # an Array, it will be wrapped in an Array. Then the new value is
+ # appended to that Array.
+ #
+ # hash::
+ # Hash to add key/value pair to.
+ # key::
+ # Key to be added.
+ # value::
+ # Value to be associated with key.
+ def merge!(hash, key, value)
+ if hash.has_key?(key)
+ if hash[key].instance_of?(Array)
+ hash[key] << value
+ else
+ hash[key] = [hash[key], value]
+ end
+ elsif value.instance_of?(Array)
+ hash[key] = [value]
+ else
+ hash[key] = value
+ end
+ hash
+ end
+
+ # Converts the attributes array of an XML element into a hash.
+ # Returns an empty Hash if node has no attributes.
+ #
+ # element::
+ # XML element to extract attributes from.
+ def get_attributes(element)
+ attribute_hash = {}
+ attributes = element.attributes
+ for i in 0...attributes.length
+ attribute_hash[attributes.item(i).name] = attributes.item(i).value
+ end
+ attribute_hash
+ end
+
+ # Determines if a document element has text content
+ #
+ # element::
+ # XML element to be checked.
+ def texts(element)
+ texts = []
+ child_nodes = element.child_nodes
+ for i in 0...child_nodes.length
+ item = child_nodes.item(i)
+ if item.node_type == Node.TEXT_NODE
+ texts << item.get_data
+ end
+ end
+ texts
+ end
+
+ # Determines if a document element has text content
+ #
+ # element::
+ # XML element to be checked.
+ def empty_content?(element)
+ text = ''
+ child_nodes = element.child_nodes
+ for i in 0...child_nodes.length
+ item = child_nodes.item(i)
+ if item.node_type == Node.TEXT_NODE
+ text << item.get_data.strip
+ end
+ end
+ text.strip.length == 0
+ end
+ end
+end
diff --git a/vendor/rails/activesupport/memcached_get_multi.diff b/vendor/rails/activesupport/memcached_get_multi.diff
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/rails/activesupport/test/abstract_unit.rb b/vendor/rails/activesupport/test/abstract_unit.rb
index a0c0c59e..9ded5f83 100644
--- a/vendor/rails/activesupport/test/abstract_unit.rb
+++ b/vendor/rails/activesupport/test/abstract_unit.rb
@@ -1,8 +1,7 @@
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
+ENV['NO_RELOAD'] = '1'
$:.unshift "#{File.dirname(__FILE__)}/../lib"
require 'active_support'
diff --git a/vendor/rails/activesupport/test/caching_test.rb b/vendor/rails/activesupport/test/caching_test.rb
index 4e212f16..94c130de 100644
--- a/vendor/rails/activesupport/test/caching_test.rb
+++ b/vendor/rails/activesupport/test/caching_test.rb
@@ -1,3 +1,4 @@
+require 'logger'
require 'abstract_unit'
class CacheKeyTest < ActiveSupport::TestCase
@@ -20,22 +21,34 @@ class CacheStoreSettingTest < ActiveSupport::TestCase
end
def test_mem_cache_fragment_cache_store
+ MemCache.expects(:new).with(%w[localhost], {})
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost"
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost), store.addresses
+ end
+
+ def test_mem_cache_fragment_cache_store_with_given_mem_cache
+ mem_cache = MemCache.new
+ MemCache.expects(:new).never
+ store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache
+ assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+ end
+
+ def test_mem_cache_fragment_cache_store_with_given_mem_cache_like_object
+ MemCache.expects(:new).never
+ store = ActiveSupport::Cache.lookup_store :mem_cache_store, stub("memcache", :get => true)
+ assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
end
def test_mem_cache_fragment_cache_store_with_multiple_servers
+ MemCache.expects(:new).with(%w[localhost 192.168.1.1], {})
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1'
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost 192.168.1.1), store.addresses
end
def test_mem_cache_fragment_cache_store_with_options
+ MemCache.expects(:new).with(%w[localhost 192.168.1.1], { :namespace => "foo" })
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1', :namespace => 'foo'
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost 192.168.1.1), store.addresses
- assert_equal 'foo', store.instance_variable_get('@data').instance_variable_get('@namespace')
end
def test_object_assigned_fragment_cache_store
@@ -161,6 +174,8 @@ uses_memcached 'memcached backed store' do
@cache = ActiveSupport::Cache.lookup_store(:mem_cache_store)
@data = @cache.instance_variable_get(:@data)
@cache.clear
+ @cache.silence!
+ @cache.logger = Logger.new("/dev/null")
end
include CacheStoreBehavior
@@ -173,6 +188,15 @@ uses_memcached 'memcached backed store' do
end
end
+ def test_stored_objects_should_not_be_frozen
+ @cache.with_local_cache do
+ @cache.write('foo', 'bar')
+ end
+ @cache.with_local_cache do
+ assert !@cache.read('foo').frozen?
+ end
+ end
+
def test_write_should_return_true_on_success
@cache.with_local_cache do
result = @cache.write('foo', 'bar')
@@ -256,6 +280,15 @@ uses_memcached 'memcached backed store' do
end
end
+ def test_multi_get
+ @cache.with_local_cache do
+ @cache.write('foo', 1)
+ @cache.write('goo', 2)
+ result = @cache.read_multi('foo', 'goo')
+ assert_equal({'foo' => 1, 'goo' => 2}, result)
+ end
+ end
+
def test_middleware
app = lambda { |env|
result = @cache.write('foo', 'bar')
@@ -265,6 +298,22 @@ uses_memcached 'memcached backed store' do
app = @cache.middleware.new(app)
app.call({})
end
+
+ def test_expires_in
+ result = @cache.write('foo', 'bar', :expires_in => 1)
+ assert_equal 'bar', @cache.read('foo')
+ sleep 2
+ assert_equal nil, @cache.read('foo')
+ end
+
+ def test_expires_in_with_invalid_value
+ @cache.write('baz', 'bat')
+ assert_raise(RuntimeError) do
+ @cache.write('foo', 'bar', :expires_in => 'Mon Jun 29 13:10:40 -0700 2150')
+ end
+ assert_equal 'bat', @cache.read('baz')
+ assert_equal nil, @cache.read('foo')
+ end
end
class CompressedMemCacheStore < ActiveSupport::TestCase
diff --git a/vendor/rails/activesupport/test/core_ext/duration_test.rb b/vendor/rails/activesupport/test/core_ext/duration_test.rb
index ab5a8666..e33eeb72 100644
--- a/vendor/rails/activesupport/test/core_ext/duration_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/duration_test.rb
@@ -2,6 +2,7 @@ require 'abstract_unit'
class DurationTest < ActiveSupport::TestCase
def test_inspect
+ assert_equal '0 seconds', 0.seconds.inspect
assert_equal '1 month', 1.month.inspect
assert_equal '1 month and 1 day', (1.month + 1.day).inspect
assert_equal '6 months and -2 days', (6.months - 2.days).inspect
@@ -44,20 +45,20 @@ class DurationTest < ActiveSupport::TestCase
Time.stubs(:now).returns Time.local(2000)
# since
assert_equal 36.hours.since, 1.5.days.since
- assert_equal((24 * 1.7).hours.since, 1.7.days.since)
+ assert_in_delta((24 * 1.7).hours.since, 1.7.days.since, 0.01)
# ago
assert_equal 36.hours.ago, 1.5.days.ago
- assert_equal((24 * 1.7).hours.ago, 1.7.days.ago)
+ assert_in_delta((24 * 1.7).hours.ago, 1.7.days.ago, 0.01)
end
def test_since_and_ago_with_fractional_weeks
Time.stubs(:now).returns Time.local(2000)
# since
assert_equal((7 * 36).hours.since, 1.5.weeks.since)
- assert_equal((7 * 24 * 1.7).hours.since, 1.7.weeks.since)
+ assert_in_delta((7 * 24 * 1.7).hours.since, 1.7.weeks.since, 0.01)
# ago
assert_equal((7 * 36).hours.ago, 1.5.weeks.ago)
- assert_equal((7 * 24 * 1.7).hours.ago, 1.7.weeks.ago)
+ assert_in_delta((7 * 24 * 1.7).hours.ago, 1.7.weeks.ago, 0.01)
end
def test_deprecated_fractional_years
diff --git a/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb b/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb
index 0edac72f..c58c0acb 100644
--- a/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb
@@ -403,29 +403,87 @@ class HashToXmlTest < Test::Unit::TestCase
@xml_options = { :root => :person, :skip_instruct => true, :indent => 0 }
end
+ def test_default_values_for_rename_keys
+ assert_equal true,ActiveSupport.dasherize_xml
+ assert_equal false,ActiveSupport.camelize_xml
+ end
+
def test_one_level
xml = { :name => "David", :street => "Paulina" }.to_xml(@xml_options)
assert_equal "", xml.first(8)
assert xml.include?(%(Paulina ))
assert xml.include?(%(David ))
end
-
+ # we add :camelize => false because otherwise we'd be accidentally testing the default value for :camelize
def test_one_level_dasherize_false
- xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => false))
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => false,:camelize=>false))
assert_equal "", xml.first(8)
assert xml.include?(%(Paulina ))
assert xml.include?(%(David ))
end
def test_one_level_dasherize_true
- xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => true))
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => true,:camelize=>false))
assert_equal "", xml.first(8)
assert xml.include?(%(Paulina ))
assert xml.include?(%(David ))
end
+ def test_one_level_dasherize_default_false
+ current_default = ActiveSupport.dasherize_xml
+ ActiveSupport.dasherize_xml = false
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize=>false))
+ assert_equal "", xml.first(8)
+ assert xml.include?(%(Paulina ))
+ assert xml.include?(%(David ))
+ ensure
+ ActiveSupport.dasherize_xml = current_default
+ end
+
+ def test_one_level_dasherize_default_true
+ current_default = ActiveSupport.dasherize_xml
+ ActiveSupport.dasherize_xml = true
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize=>false))
+ assert_equal "", xml.first(8)
+ assert xml.include?(%(Paulina ))
+ assert xml.include?(%(David ))
+ ensure
+ ActiveSupport.dasherize_xml = current_default
+ end
+
def test_one_level_camelize_true
- xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => true))
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => true,:dasherize => false))
+ assert_equal "", xml.first(8)
+ assert xml.include?(%(Paulina ))
+ assert xml.include?(%(David ))
+ end
+
+ #camelize=>false is already tested above
+
+ def test_one_level_camelize_default_false
+ current_default = ActiveSupport.camelize_xml
+ ActiveSupport.camelize_xml = false
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => false))
+ assert_equal "", xml.first(8)
+ assert xml.include?(%(Paulina ))
+ assert xml.include?(%(David ))
+ ensure
+ ActiveSupport.camelize_xml = current_default
+ end
+
+ def test_one_level_camelize_default_true
+ current_default = ActiveSupport.camelize_xml
+ ActiveSupport.camelize_xml = true
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => false))
+ assert_equal "", xml.first(8)
+ assert xml.include?(%(Paulina ))
+ assert xml.include?(%(David ))
+ ensure
+ ActiveSupport.camelize_xml = current_default
+ end
+
+ def test_one_level_camelize_true_dasherize_true
+ xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => true,:camelize=>true))
assert_equal "", xml.first(8)
assert xml.include?(%(Paulina ))
assert xml.include?(%(David ))
@@ -654,6 +712,22 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
end
+ def test_all_caps_key_from_xml
+ test_xml = <<-EOT
+
+ Lorem Ipsum
+
+ EOT
+
+ expected_hash = {
+ "ABC3XYZ" => {
+ "TEST" => "Lorem Ipsum"
+ }
+ }
+
+ assert_equal expected_hash, Hash.from_xml(test_xml)
+ end
+
def test_empty_array_with_whitespace_from_xml
blog_xml = <<-XML
diff --git a/vendor/rails/activesupport/test/core_ext/module/model_naming_test.rb b/vendor/rails/activesupport/test/core_ext/module/model_naming_test.rb
index d08349dd..b0e46c4d 100644
--- a/vendor/rails/activesupport/test/core_ext/module/model_naming_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/module/model_naming_test.rb
@@ -13,6 +13,14 @@ class ModelNamingTest < Test::Unit::TestCase
assert_equal 'post_track_backs', @model_name.plural
end
+ def test_element
+ assert_equal 'track_back', @model_name.element
+ end
+
+ def test_collection
+ assert_equal 'post/track_backs', @model_name.collection
+ end
+
def test_partial_path
assert_equal 'post/track_backs/track_back', @model_name.partial_path
end
diff --git a/vendor/rails/activesupport/test/core_ext/module_test.rb b/vendor/rails/activesupport/test/core_ext/module_test.rb
index 0d3d10f3..7fb6e14d 100644
--- a/vendor/rails/activesupport/test/core_ext/module_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/module_test.rb
@@ -141,7 +141,7 @@ class ModuleTest < Test::Unit::TestCase
def test_delegation_without_allow_nil_and_nil_value
david = Someone.new("David")
- assert_raise(NoMethodError) { david.street }
+ assert_raise(RuntimeError) { david.street }
end
def test_parent
diff --git a/vendor/rails/activesupport/test/core_ext/string_ext_test.rb b/vendor/rails/activesupport/test/core_ext/string_ext_test.rb
index 6c9b7e72..7d51e81f 100644
--- a/vendor/rails/activesupport/test/core_ext/string_ext_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/string_ext_test.rb
@@ -132,10 +132,12 @@ class StringInflectionsTest < Test::Unit::TestCase
assert_equal "h", s.first
assert_equal "he", s.first(2)
+ assert_equal "", s.first(0)
assert_equal "o", s.last
assert_equal "llo", s.last(3)
assert_equal "hello", s.last(10)
+ assert_equal "", s.last(0)
assert_equal 'x', 'x'.first
assert_equal 'x', 'x'.first(4)
diff --git a/vendor/rails/activesupport/test/core_ext/time_with_zone_test.rb b/vendor/rails/activesupport/test/core_ext/time_with_zone_test.rb
index accfe51e..03ed783c 100644
--- a/vendor/rails/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/vendor/rails/activesupport/test/core_ext/time_with_zone_test.rb
@@ -55,12 +55,12 @@ class TimeWithZoneTest < Test::Unit::TestCase
end
def test_to_json
- assert_equal "\"1999/12/31 19:00:00 -0500\"", @twz.to_json
+ assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(@twz)
end
def test_to_json_with_use_standard_json_time_format_config_set_to_true
old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, true
- assert_equal "\"1999-12-31T19:00:00-05:00\"", @twz.to_json
+ assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(@twz)
ensure
ActiveSupport.use_standard_json_time_format = old
end
diff --git a/vendor/rails/activesupport/test/json/decoding_test.rb b/vendor/rails/activesupport/test/json/decoding_test.rb
index 8fe40557..86053c9f 100644
--- a/vendor/rails/activesupport/test/json/decoding_test.rb
+++ b/vendor/rails/activesupport/test/json/decoding_test.rb
@@ -1,49 +1,77 @@
# encoding: UTF-8
require 'abstract_unit'
-class TestJSONDecoding < Test::Unit::TestCase
+class TestJSONDecoding < ActiveSupport::TestCase
TESTS = {
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
- %q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
- %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
- %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
+ %({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
+ %({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
# multibyte
%({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
- %({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
- %({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
+ %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
+ %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
# no time zone
- %({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
+ %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
# needs to be *exact*
- %({a: " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
- %({a: "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
+ %({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
+ %({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
%([]) => [],
%({}) => {},
- %(1) => 1,
- %("") => "",
- %("\\"") => "\"",
- %(null) => nil,
- %(true) => true,
- %(false) => false,
- %q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1",
- %q("\u003cunicode\u0020escape\u003e") => "",
- %q("\\\\u0020skip double backslashes") => "\\u0020skip double backslashes",
- %q({a: "\u003cbr /\u003e"}) => {'a' => " "},
- %q({b:["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["","",""]}
+ %({"a":1}) => {"a" => 1},
+ %({"a": ""}) => {"a" => ""},
+ %({"a":"\\""}) => {"a" => "\""},
+ %({"a": null}) => {"a" => nil},
+ %({"a": true}) => {"a" => true},
+ %({"a": false}) => {"a" => false},
+ %q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
+ %q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => ""},
+ %q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
+ %q({"a": "\u003cbr /\u003e"}) => {'a' => " "},
+ %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["","",""]}
}
-
- TESTS.each do |json, expected|
- define_method :"test_json_decoding_#{json}" do
- assert_nothing_raised do
- assert_equal expected, ActiveSupport::JSON.decode(json)
+
+ # load the default JSON backend
+ ActiveSupport::JSON.backend
+
+ backends = %w(Yaml)
+ begin
+ gem 'json', '>= 1.1'
+ require 'json'
+ backends << "JSONGem"
+ rescue Gem::LoadError
+ # Skip JSON gem tests
+ end
+
+ backends.each do |backend|
+ TESTS.each do |json, expected|
+ test "json decodes #{json} with the #{backend} backend" do
+ ActiveSupport.parse_json_times = true
+ silence_warnings do
+ ActiveSupport::JSON.with_backend backend do
+ assert_nothing_raised do
+ assert_equal expected, ActiveSupport::JSON.decode(json)
+ end
+ end
+ end
end
end
end
-
+
+ if backends.include?("JSONGem")
+ test "json decodes time json with time parsing disabled" do
+ ActiveSupport.parse_json_times = false
+ expected = {"a" => "2007-01-01 01:12:34 Z"}
+ ActiveSupport::JSON.with_backend "JSONGem" do
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
+ end
+ end
+ end
+
def test_failed_json_decoding
assert_raise(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
end
-end
+end
\ No newline at end of file
diff --git a/vendor/rails/activesupport/test/json/encoding_test.rb b/vendor/rails/activesupport/test/json/encoding_test.rb
index 7d2eedad..ab8e4e80 100644
--- a/vendor/rails/activesupport/test/json/encoding_test.rb
+++ b/vendor/rails/activesupport/test/json/encoding_test.rb
@@ -8,6 +8,12 @@ class TestJSONEncoding < Test::Unit::TestCase
end
end
+ class Custom
+ def to_json(options)
+ '"custom"'
+ end
+ end
+
TrueTests = [[ true, %(true) ]]
FalseTests = [[ false, %(false) ]]
NilTests = [[ nil, %(null) ]]
@@ -18,14 +24,15 @@ class TestJSONEncoding < Test::Unit::TestCase
[ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ],
[ 'http://test.host/posts/1', %("http://test.host/posts/1")]]
- ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ],
- [ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]
+ ArrayTests = [[ ['a', 'b', 'c'], %([\"a\",\"b\",\"c\"]) ],
+ [ [1, 'a', :b, nil, false], %([1,\"a\",\"b\",null,false]) ]]
SymbolTests = [[ :a, %("a") ],
[ :this, %("this") ],
[ :"a b", %("a b") ]]
- ObjectTests = [[ Foo.new(1, 2), %({\"a\": 1, \"b\": 2}) ]]
+ ObjectTests = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]]
+ CustomTests = [[ Custom.new, '"custom"' ]]
VariableTests = [[ ActiveSupport::JSON::Variable.new('foo'), 'foo'],
[ ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")']]
@@ -46,7 +53,7 @@ class TestJSONEncoding < Test::Unit::TestCase
ActiveSupport.escape_html_entities_in_json = class_tests !~ /^Standard/
ActiveSupport.use_standard_json_time_format = class_tests =~ /^Standard/
self.class.const_get(class_tests).each do |pair|
- assert_equal pair.last, pair.first.to_json
+ assert_equal pair.last, ActiveSupport::JSON.encode(pair.first)
end
ensure
ActiveSupport.escape_html_entities_in_json = false
@@ -56,45 +63,50 @@ class TestJSONEncoding < Test::Unit::TestCase
end
def test_hash_encoding
- assert_equal %({\"a\": \"b\"}), { :a => :b }.to_json
- assert_equal %({\"a\": 1}), { 'a' => 1 }.to_json
- assert_equal %({\"a\": [1, 2]}), { 'a' => [1,2] }.to_json
- assert_equal %({"1": 2}), { 1 => 2 }.to_json
+ assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b)
+ assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1)
+ assert_equal %({\"a\":[1,2]}), ActiveSupport::JSON.encode('a' => [1,2])
+ assert_equal %({"1":2}), ActiveSupport::JSON.encode(1 => 2)
- sorted_json = '{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
- assert_equal %({\"a\": \"b\", \"c\": \"d\"}), sorted_json
+ sorted_json = '{' + ActiveSupport::JSON.encode(:a => :b, :c => :d)[1..-2].split(',').sort.join(',') + '}'
+ assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json
end
def test_utf8_string_encoded_properly_when_kcode_is_utf8
with_kcode 'UTF8' do
- assert_equal '"\\u20ac2.99"', '€2.99'.to_json
- assert_equal '"\\u270e\\u263a"', '✎☺'.to_json
+ result = ActiveSupport::JSON.encode('€2.99')
+ assert_equal '"\\u20ac2.99"', result
+ assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding)
+
+ result = ActiveSupport::JSON.encode('✎☺')
+ assert_equal '"\\u270e\\u263a"', result
+ assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding)
end
end
def test_exception_raised_when_encoding_circular_reference
a = [1]
a << a
- assert_raise(ActiveSupport::JSON::CircularReferenceError) { a.to_json }
+ assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
end
def test_hash_key_identifiers_are_always_quoted
values = {0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B"}
- assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(values.to_json)
+ assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
end
def test_hash_should_allow_key_filtering_with_only
- assert_equal %({"a": 1}), { 'a' => 1, :b => 2, :c => 3 }.to_json(:only => 'a')
+ assert_equal %({"a":1}), ActiveSupport::JSON.encode({'a' => 1, :b => 2, :c => 3}, :only => 'a')
end
def test_hash_should_allow_key_filtering_with_except
- assert_equal %({"b": 2}), { 'foo' => 'bar', :b => 2, :c => 3 }.to_json(:except => ['foo', :c])
+ assert_equal %({"b":2}), ActiveSupport::JSON.encode({'foo' => 'bar', :b => 2, :c => 3}, :except => ['foo', :c])
end
def test_time_to_json_includes_local_offset
ActiveSupport.use_standard_json_time_format = true
with_env_tz 'US/Eastern' do
- assert_equal %("2005-02-01T15:15:10-05:00"), Time.local(2005,2,1,15,15,10).to_json
+ assert_equal %("2005-02-01T15:15:10-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
end
ensure
ActiveSupport.use_standard_json_time_format = false
@@ -108,7 +120,7 @@ class TestJSONEncoding < Test::Unit::TestCase
:latitude => 123.234
}
}
- result = hash.to_json
+ result = ActiveSupport::JSON.encode(hash)
end
end
@@ -127,6 +139,16 @@ class TestJSONEncoding < Test::Unit::TestCase
end
class JsonOptionsTests < Test::Unit::TestCase
+ # The json extension passes internal state to to_json
+ def test_non_hash_options_should_be_tolerated
+ faux_internal_state_object = Object.new
+
+ value = Object.new
+ def value.to_json(options) options end
+
+ assert_kind_of Hash, ActiveSupport::JSON.encode(value, faux_internal_state_object)
+ end
+
def test_enumerable_should_passthrough_options_to_elements
json_options = { :include => :posts }
ActiveSupport::JSON.expects(:encode).with(1, json_options)
diff --git a/vendor/rails/activesupport/test/ordered_hash_test.rb b/vendor/rails/activesupport/test/ordered_hash_test.rb
index 7cd8c8a8..15bd5718 100644
--- a/vendor/rails/activesupport/test/ordered_hash_test.rb
+++ b/vendor/rails/activesupport/test/ordered_hash_test.rb
@@ -51,6 +51,10 @@ class OrderedHashTest < Test::Unit::TestCase
assert_same @ordered_hash, @ordered_hash.to_hash
end
+ def test_to_a
+ assert_equal @keys.zip(@values), @ordered_hash.to_a
+ end
+
def test_has_key
assert_equal true, @ordered_hash.has_key?('blue')
assert_equal true, @ordered_hash.key?('blue')
@@ -158,4 +162,33 @@ class OrderedHashTest < Test::Unit::TestCase
def test_inspect
assert @ordered_hash.inspect.include?(@hash.inspect)
end
+
+ def test_alternate_initialization_with_splat
+ alternate = ActiveSupport::OrderedHash[1,2,3,4]
+ assert_kind_of ActiveSupport::OrderedHash, alternate
+ assert_equal [1, 3], alternate.keys
+ end
+
+ def test_alternate_initialization_with_array
+ alternate = ActiveSupport::OrderedHash[ [
+ [1, 2],
+ [3, 4],
+ "bad key value pair",
+ [ 'missing value' ]
+ ]]
+
+ assert_kind_of ActiveSupport::OrderedHash, alternate
+ assert_equal [1, 3, 'missing value'], alternate.keys
+ assert_equal [2, 4, nil ], alternate.values
+ end
+
+ def test_alternate_initialization_raises_exception_on_odd_length_args
+ begin
+ alternate = ActiveSupport::OrderedHash[1,2,3,4,5]
+ flunk "Hash::[] should have raised an exception on initialization " +
+ "with an odd number of parameters"
+ rescue
+ assert_equal "odd number of arguments for Hash", $!.message
+ end
+ end
end
diff --git a/vendor/rails/activesupport/test/xml_mini/jdom_engine_test.rb b/vendor/rails/activesupport/test/xml_mini/jdom_engine_test.rb
new file mode 100644
index 00000000..b7452289
--- /dev/null
+++ b/vendor/rails/activesupport/test/xml_mini/jdom_engine_test.rb
@@ -0,0 +1,153 @@
+require 'abstract_unit'
+require 'active_support/xml_mini'
+
+if RUBY_PLATFORM =~ /java/
+
+class JDOMEngineTest < Test::Unit::TestCase
+ include ActiveSupport
+
+ def setup
+ @default_backend = XmlMini.backend
+ XmlMini.backend = 'JDOM'
+ end
+
+ def teardown
+ XmlMini.backend = @default_backend
+ end
+
+ # def test_file_from_xml
+ # hash = Hash.from_xml(<<-eoxml)
+ #
+ #
+ #
+ #
+ # eoxml
+ # assert hash.has_key?('blog')
+ # assert hash['blog'].has_key?('logo')
+ #
+ # file = hash['blog']['logo']
+ # assert_equal 'logo.png', file.original_filename
+ # assert_equal 'image/png', file.content_type
+ # end
+
+ def test_exception_thrown_on_expansion_attack
+ assert_raise NativeException do
+ attack_xml = <<-EOT
+
+
+
+
+
+
+
+
+ ]>
+
+ &a;
+
+ EOT
+ Hash.from_xml(attack_xml)
+ end
+ end
+
+ def test_setting_JDOM_as_backend
+ XmlMini.backend = 'JDOM'
+ assert_equal XmlMini_JDOM, XmlMini.backend
+ end
+
+ def test_blank_returns_empty_hash
+ assert_equal({}, XmlMini.parse(nil))
+ assert_equal({}, XmlMini.parse(''))
+ end
+
+ def test_array_type_makes_an_array
+ assert_equal_rexml(<<-eoxml)
+
+
+ a post
+ another post
+
+
+ eoxml
+ end
+
+ def test_one_node_document_as_hash
+ assert_equal_rexml(<<-eoxml)
+
+ eoxml
+ end
+
+ def test_one_node_with_attributes_document_as_hash
+ assert_equal_rexml(<<-eoxml)
+
+ eoxml
+ end
+
+ def test_products_node_with_book_node_as_hash
+ assert_equal_rexml(<<-eoxml)
+
+
+
+ eoxml
+ end
+
+ def test_products_node_with_two_book_nodes_as_hash
+ assert_equal_rexml(<<-eoxml)
+
+
+
+
+ eoxml
+ end
+
+ def test_single_node_with_content_as_hash
+ assert_equal_rexml(<<-eoxml)
+
+ hello world
+
+ eoxml
+ end
+
+ def test_children_with_children
+ assert_equal_rexml(<<-eoxml)
+
+
+
+
+
+ eoxml
+ end
+
+ def test_children_with_text
+ assert_equal_rexml(<<-eoxml)
+
+
+ hello everyone
+
+
+ eoxml
+ end
+
+ def test_children_with_non_adjacent_text
+ assert_equal_rexml(<<-eoxml)
+
+ good
+
+ hello everyone
+
+ morning
+
+ eoxml
+ end
+
+ private
+ def assert_equal_rexml(xml)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+ assert_equal(hash, XmlMini.parse(xml))
+ end
+end
+
+else
+ # don't run these test because we aren't running in JRuby
+end
diff --git a/vendor/rails/ci/geminstaller.yml b/vendor/rails/ci/geminstaller.yml
index 33f1e811..a04bf944 100644
--- a/vendor/rails/ci/geminstaller.yml
+++ b/vendor/rails/ci/geminstaller.yml
@@ -7,14 +7,14 @@ gems:
- name: memcache-client
version: >= 1.5.0
- name: mocha
- version: >= 0.9.5
+ version: >= 0.9.7
- name: mysql
#version: >= 2.7
version: = 2.7
- name: pg
version: >= 0.7.9.2008.10.13
- name: rack
- version: '~> 0.9.0'
+ version: '~> 1.0.0'
- name: rake
version: >= 0.8.1
- name: sqlite-ruby
diff --git a/vendor/rails/railties/CHANGELOG b/vendor/rails/railties/CHANGELOG
index e8e8434a..b095fab8 100644
--- a/vendor/rails/railties/CHANGELOG
+++ b/vendor/rails/railties/CHANGELOG
@@ -1,3 +1,7 @@
+*2.3.3 (July 12 2009)
+
+* Version bump
+
*2.3.2 [Final] (March 15, 2009)*
* Allow metal to live in plugins #2045 [Matthew Rudy]
diff --git a/vendor/rails/railties/Rakefile b/vendor/rails/railties/Rakefile
index 6c0fc226..9bdb3372 100644
--- a/vendor/rails/railties/Rakefile
+++ b/vendor/rails/railties/Rakefile
@@ -2,7 +2,6 @@ require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
require 'date'
require 'rbconfig'
@@ -246,7 +245,7 @@ def copy_with_rewritten_ruby_path(src_file, dest_file)
end
desc 'Generate guides (for authors), use ONLY=foo to process just "foo.textile"'
-task :guides do
+task :generate_guides do
ruby "guides/rails_guides.rb"
end
@@ -294,6 +293,7 @@ PKG_FILES = FileList[
'doc/**/*',
'dispatches/**/*',
'environments/**/*',
+ 'guides/**/*',
'helpers/**/*',
'generators/**/*',
'html/**/*',
@@ -311,16 +311,16 @@ spec = Gem::Specification.new do |s|
EOF
s.add_dependency('rake', '>= 0.8.3')
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
- s.add_dependency('activerecord', '= 2.3.2' + PKG_BUILD)
- s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)
- s.add_dependency('actionmailer', '= 2.3.2' + PKG_BUILD)
- s.add_dependency('activeresource', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.3.3' + PKG_BUILD)
+ s.add_dependency('activerecord', '= 2.3.3' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 2.3.3' + PKG_BUILD)
+ s.add_dependency('actionmailer', '= 2.3.3' + PKG_BUILD)
+ s.add_dependency('activeresource', '= 2.3.3' + PKG_BUILD)
s.rdoc_options << '--exclude' << '.'
s.has_rdoc = false
- s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
+ s.files = PKG_FILES.to_a.delete_if {|f| f =~ %r{\.svn|guides/output}}
s.require_path = 'lib'
s.bindir = "bin" # Use these for applications.
s.executables = ["rails"]
@@ -345,7 +345,7 @@ task :pgem => [:gem] do
end
desc "Publish the guides"
-task :pguides => :guides do
+task :pguides => :generate_guides do
mkdir_p 'pkg'
`tar -czf pkg/guides.gz guides/output`
Rake::SshFilePublisher.new("web.rubyonrails.org", "/u/sites/guides.rubyonrails.org/public", "pkg", "guides.gz").upload
@@ -354,6 +354,7 @@ end
desc "Publish the release files to RubyForge."
task :release => [ :package ] do
+ require 'rake/contrib/rubyforgepublisher'
require 'rubyforge'
packages = %w( gem ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
diff --git a/vendor/rails/railties/configs/routes.rb b/vendor/rails/railties/configs/routes.rb
index 4f3d9d22..ea14ce1b 100644
--- a/vendor/rails/railties/configs/routes.rb
+++ b/vendor/rails/railties/configs/routes.rb
@@ -37,7 +37,7 @@ ActionController::Routing::Routes.draw do |map|
# Install the default routes as the lowest priority.
# Note: These default routes make all actions in every controller accessible via GET requests. You should
- # consider removing the them or commenting them out if you're using named routes and resources.
+ # consider removing or commenting them out if you're using named routes and resources.
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
diff --git a/vendor/rails/railties/guides/rails_guides.rb b/vendor/rails/railties/guides/rails_guides.rb
index 725f4cd8..b73e10e4 100644
--- a/vendor/rails/railties/guides/rails_guides.rb
+++ b/vendor/rails/railties/guides/rails_guides.rb
@@ -1,17 +1,28 @@
pwd = File.dirname(__FILE__)
$: << pwd
-$: << File.join(pwd, "../../activesupport/lib")
-$: << File.join(pwd, "../../actionpack/lib")
-require "action_controller"
-require "action_view"
-
-# Require rubygems after loading Action View
-require 'rubygems'
begin
- gem 'RedCloth', '>= 4.1.1'# Need exactly 4.1.1
+ as_lib = File.join(pwd, "../../activesupport/lib")
+ ap_lib = File.join(pwd, "../../actionpack/lib")
+
+ $: << as_lib if File.directory?(as_lib)
+ $: << ap_lib if File.directory?(ap_lib)
+
+ require "action_controller"
+ require "action_view"
+rescue LoadError
+ require 'rubygems'
+ gem "actionpack", '>= 2.3'
+
+ require "action_controller"
+ require "action_view"
+end
+
+begin
+ require 'rubygems'
+ gem 'RedCloth', '>= 4.1.1'
rescue Gem::LoadError
- $stderr.puts %(Missing the RedCloth 4.1.1 gem.\nPlease `gem install -v=4.1.1 RedCloth` to generate the guides.)
+ $stderr.puts %(Generating Guides requires RedCloth 4.1.1+)
exit 1
end
@@ -22,7 +33,6 @@ module RailsGuides
autoload :Indexer, "rails_guides/indexer"
autoload :Helpers, "rails_guides/helpers"
autoload :TextileExtensions, "rails_guides/textile_extensions"
- autoload :Levenshtein, "rails_guides/levenshtein"
end
RedCloth.send(:include, RailsGuides::TextileExtensions)
diff --git a/vendor/rails/railties/guides/rails_guides/generator.rb b/vendor/rails/railties/guides/rails_guides/generator.rb
index 8e69af5b..6c0d9f3c 100644
--- a/vendor/rails/railties/guides/rails_guides/generator.rb
+++ b/vendor/rails/railties/guides/rails_guides/generator.rb
@@ -57,7 +57,6 @@ module RailsGuides
result = view.render(:layout => 'layout', :text => textile(body))
f.write result
- warn_about_broken_links(result)
end
end
end
@@ -135,38 +134,5 @@ module RailsGuides
code_blocks[$1.to_i]
end
end
-
- def warn_about_broken_links(html)
- anchors = extract_anchors(html)
- check_fragment_identifiers(html, anchors)
- end
-
- def extract_anchors(html)
- # Textile generates headers with IDs computed from titles.
- anchors = Set.new
- html.scan(/ Levenshtein.distance(fragment_identifier, b)
- }
- puts "*** BROKEN LINK: ##{fragment_identifier}, perhaps you meant ##{guess}."
- end
- end
- end
end
end
diff --git a/vendor/rails/railties/guides/rails_guides/levenshtein.rb b/vendor/rails/railties/guides/rails_guides/levenshtein.rb
deleted file mode 100644
index 02e35f60..00000000
--- a/vendor/rails/railties/guides/rails_guides/levenshtein.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-#
-# Levenshtein distance algorithm implementation for Ruby, with UTF-8 support
-#
-# Author:: Paul BATTLEY (pbattley @ gmail.com)
-# Version:: 1.3
-# Date:: 2005-04-19
-#
-# == About
-#
-# The Levenshtein distance is a measure of how similar two strings s and t are,
-# calculated as the number of deletions/insertions/substitutions needed to
-# transform s into t. The greater the distance, the more the strings differ.
-#
-# The Levenshtein distance is also sometimes referred to as the
-# easier-to-pronounce-and-spell 'edit distance'.
-#
-# == Revision history
-#
-# * 2005-05-19 1.3 Repairing an oversight, distance can now be called via
-# Levenshtein.distance(s, t)
-# * 2005-05-04 1.2 Now uses just one 1-dimensional array. I think this is as
-# far as optimisation can go.
-# * 2005-05-04 1.1 Now storing only the current and previous rows of the matrix
-# instead of the whole lot.
-#
-# == Licence
-#
-# Copyright (c) 2005 Paul Battley
-#
-# Usage of the works is permitted provided that this instrument is retained
-# with the works, so that any entity that uses the works is notified of this
-# instrument.
-#
-# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
-#
-
-module Levenshtein
-
- #
- # Calculate the Levenshtein distance between two strings +str1+ and +str2+.
- # +str1+ and +str2+ should be ASCII or UTF-8.
- #
- def distance(str1, str2)
- s = str1.unpack('U*')
- t = str2.unpack('U*')
- n = s.length
- m = t.length
- return m if (0 == n)
- return n if (0 == m)
-
- d = (0..m).to_a
- x = nil
-
- (0...n).each do |i|
- e = i+1
- (0...m).each do |j|
- cost = (s[i] == t[j]) ? 0 : 1
- x = [
- d[j+1] + 1, # insertion
- e + 1, # deletion
- d[j] + cost # substitution
- ].min
- d[j] = e
- e = x
- end
- d[m] = x
- end
-
- return x
- end
-
- extend self
-end
-
-if (__FILE__ == $0)
- require 'test/unit'
-
- class LevenshteinTest < Test::Unit::TestCase
- include Levenshtein
-
- EXPECTED = [
- # Easy ones
- ['test', 'test', 0],
- ['test', 'tent', 1],
- ['gumbo', 'gambol', 2],
- ['kitten', 'sitting', 3],
- # Empty strings
- ['foo', '', 3],
- ['', '', 0],
- ['a', '', 1],
- # UTF-8
- ["f\303\266o", 'foo', 1],
- ["fran\303\247ais", 'francais', 1],
- ["fran\303\247ais", "fran\303\246ais", 1],
- ["\347\247\201\343\201\256\345\220\215\345\211\215\343\201\257"<<
- "\343\203\235\343\203\274\343\203\253\343\201\247\343\201\231",
- "\343\201\274\343\201\217\343\201\256\345\220\215\345\211\215\343\201"<<
- "\257\343\203\235\343\203\274\343\203\253\343\201\247\343\201\231",
- 2], # Japanese
- # Edge cases
- ['a', 'a', 0],
- ['0123456789', 'abcdefghijklmnopqrstuvwxyz', 26]
- ]
-
- def test_known_distances
- EXPECTED.each do |a,b,x|
- assert_equal(x, distance(a, b))
- assert_equal(x, distance(b, a))
- end
- end
- end
-end
diff --git a/vendor/rails/railties/lib/commands/performance/profiler.rb b/vendor/rails/railties/lib/commands/performance/profiler.rb
index fd111bae..7df840f1 100644
--- a/vendor/rails/railties/lib/commands/performance/profiler.rb
+++ b/vendor/rails/railties/lib/commands/performance/profiler.rb
@@ -29,7 +29,7 @@ begin
printer_class = RubyProf::FlatPrinter
end
printer = printer_class.new(results)
- printer.print($stderr, 0)
+ printer.print($stderr)
rescue LoadError
require "prof"
$stderr.puts 'Using the old ruby-prof extension.'
diff --git a/vendor/rails/railties/lib/initializer.rb b/vendor/rails/railties/lib/initializer.rb
index a04405a7..5f5e557d 100644
--- a/vendor/rails/railties/lib/initializer.rb
+++ b/vendor/rails/railties/lib/initializer.rb
@@ -159,6 +159,8 @@ module Rails
add_support_load_paths
+ check_for_unbuilt_gems
+
load_gems
load_plugins
@@ -301,11 +303,30 @@ module Rails
end
def load_gems
- unless $gems_build_rake_task
+ unless $gems_rake_task
@configuration.gems.each { |gem| gem.load }
end
end
+ def check_for_unbuilt_gems
+ unbuilt_gems = @configuration.gems.select(&:frozen?).reject(&:built?)
+ if unbuilt_gems.size > 0
+ # don't print if the gems:build rake tasks are being run
+ unless $gems_build_rake_task
+ abort <<-end_error
+The following gems have native components that need to be built
+ #{unbuilt_gems.map { |gem| "#{gem.name} #{gem.requirement}" } * "\n "}
+
+You're running:
+ ruby #{Gem.ruby_version} at #{Gem.ruby}
+ rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
+
+Run `rake gems:build` to build the unbuilt gems.
+ end_error
+ end
+ end
+ end
+
def check_gem_dependencies
unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
if unloaded_gems.size > 0
@@ -420,7 +441,8 @@ Run `rake gems:install` to install the missing gems.
def initialize_database_middleware
if configuration.frameworks.include?(:active_record)
- if ActionController::Base.session_store == ActiveRecord::SessionStore
+ if configuration.frameworks.include?(:action_controller) &&
+ ActionController::Base.session_store == ActiveRecord::SessionStore
configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache
else
@@ -565,7 +587,7 @@ Run `rake gems:install` to install the missing gems.
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
configuration.middleware.insert_before(
- :"ActionController::RewindableInput",
+ :"ActionController::ParamsParser",
Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
end
@@ -862,7 +884,7 @@ Run `rake gems:install` to install the missing gems.
# Enable threaded mode. Allows concurrent requests to controller actions and
# multiple database connections. Also disables automatic dependency loading
- # after boot, and disables reloading code on every request, as these are
+ # after boot, and disables reloading code on every request, as these are
# fundamentally incompatible with thread safety.
def threadsafe!
self.preload_frameworks = true
@@ -1103,3 +1125,4 @@ class Rails::OrderedOptions < Array #:nodoc:
return false
end
end
+
diff --git a/vendor/rails/railties/lib/rails/gem_dependency.rb b/vendor/rails/railties/lib/rails/gem_dependency.rb
index 3062a771..06d830ba 100644
--- a/vendor/rails/railties/lib/rails/gem_dependency.rb
+++ b/vendor/rails/railties/lib/rails/gem_dependency.rb
@@ -29,6 +29,22 @@ module Rails
end
end
+ def self.from_directory_name(directory_name, load_spec=true)
+ directory_name_parts = File.basename(directory_name).split('-')
+ name = directory_name_parts[0..-2].join('-')
+ version = directory_name_parts.last
+ result = self.new(name, :version => version)
+ spec_filename = File.join(directory_name, '.specification')
+ if load_spec
+ raise "Missing specification file in #{File.dirname(spec_filename)}. Perhaps you need to do a 'rake gems:refresh_specs'?" unless File.exists?(spec_filename)
+ spec = YAML::load_file(spec_filename)
+ result.specification = spec
+ end
+ result
+ rescue ArgumentError => e
+ raise "Unable to determine gem name and version from '#{directory_name}'"
+ end
+
def initialize(name, options = {})
require 'rubygems' unless Object.const_defined?(:Gem)
@@ -95,14 +111,26 @@ module Rails
end
end
+ def specification=(s)
+ @spec = s
+ end
+
def requirement
r = version_requirements
(r == Gem::Requirement.default) ? nil : r
end
def built?
- # TODO: If Rubygems ever gives us a way to detect this, we should use it
- false
+ return false unless frozen?
+
+ if vendor_gem?
+ specification.extensions.each do |ext|
+ makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile')
+ return false unless File.exists?(makefile)
+ end
+ end
+
+ true
end
def framework_gem?
@@ -155,15 +183,16 @@ module Rails
specification && File.exists?(unpacked_gem_directory)
end
- def build
+ def build(options={})
require 'rails/gem_builder'
- unless built?
+ return if specification.nil?
+ if options[:force] || !built?
return unless File.exists?(unpacked_specification_filename)
spec = YAML::load_file(unpacked_specification_filename)
Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions
puts "Built gem: '#{unpacked_gem_directory}'"
end
- dependencies.each { |dep| dep.build }
+ dependencies.each { |dep| dep.build(options) }
end
def install
@@ -223,7 +252,7 @@ module Rails
real_spec = Gem::Specification.load(specification.loaded_from)
write_specification(real_spec)
end
- dependencies.each { |dep| dep.unpack } if options[:recursive]
+ dependencies.each { |dep| dep.unpack(options) } if options[:recursive]
end
def write_specification(spec)
diff --git a/vendor/rails/railties/lib/rails/rack/metal.rb b/vendor/rails/railties/lib/rails/rack/metal.rb
index adc43da8..8719a5c5 100644
--- a/vendor/rails/railties/lib/rails/rack/metal.rb
+++ b/vendor/rails/railties/lib/rails/rack/metal.rb
@@ -26,7 +26,7 @@ module Rails
load_list.map do |requested_metal|
if metal = all_metals[requested_metal]
- require metal
+ require_dependency metal
requested_metal.constantize
end
end.compact
diff --git a/vendor/rails/railties/lib/rails/version.rb b/vendor/rails/railties/lib/rails/version.rb
index 99c7516a..d3f81d88 100644
--- a/vendor/rails/railties/lib/rails/version.rb
+++ b/vendor/rails/railties/lib/rails/version.rb
@@ -2,7 +2,7 @@ module Rails
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 2
+ TINY = 3
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/vendor/rails/railties/lib/tasks/gems.rake b/vendor/rails/railties/lib/tasks/gems.rake
index ed07bf20..f1c34c7c 100644
--- a/vendor/rails/railties/lib/tasks/gems.rake
+++ b/vendor/rails/railties/lib/tasks/gems.rake
@@ -20,18 +20,25 @@ namespace :gems do
desc "Build any native extensions for unpacked gems"
task :build do
$gems_build_rake_task = true
- Rake::Task['gems:unpack'].invoke
- current_gems.each &:build
+ frozen_gems.each { |gem| gem.build }
+ end
+
+ namespace :build do
+ desc "Force the build of all gems"
+ task :force do
+ $gems_build_rake_task = true
+ frozen_gems.each { |gem| gem.build(:force => true) }
+ end
end
desc "Installs all required gems."
task :install => :base do
- current_gems.each &:install
+ current_gems.each { |gem| gem.install }
end
desc "Unpacks all required gems into vendor/gems."
task :unpack => :install do
- current_gems.each &:unpack
+ current_gems.each { |gem| gem.unpack }
end
namespace :unpack do
@@ -42,8 +49,8 @@ namespace :gems do
end
desc "Regenerate gem specifications in correct format."
- task :refresh_specs => :base do
- current_gems.each &:refresh
+ task :refresh_specs do
+ frozen_gems(false).each { |gem| gem.refresh }
end
end
@@ -53,6 +60,12 @@ def current_gems
gems
end
+def frozen_gems(load_specs=true)
+ Dir[File.join(RAILS_ROOT, 'vendor', 'gems', '*-*')].map do |gem_dir|
+ Rails::GemDependency.from_directory_name(gem_dir, load_specs)
+ end
+end
+
def print_gem_status(gem, indent=1)
code = case
when gem.framework_gem? then 'R'
diff --git a/vendor/rails/railties/lib/test_help.rb b/vendor/rails/railties/lib/test_help.rb
index ee24ea3a..f8608925 100644
--- a/vendor/rails/railties/lib/test_help.rb
+++ b/vendor/rails/railties/lib/test_help.rb
@@ -29,7 +29,10 @@ end
begin
require_library_or_gem 'ruby-debug'
Debugger.start
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
+ if Debugger.respond_to?(:settings)
+ Debugger.settings[:autoeval] = true
+ Debugger.settings[:autolist] = 1
+ end
rescue LoadError
# ruby-debug wasn't available so neither can the debugging be
end
diff --git a/vendor/rails/railties/test/abstract_unit.rb b/vendor/rails/railties/test/abstract_unit.rb
index 0addcb8b..85f680da 100644
--- a/vendor/rails/railties/test/abstract_unit.rb
+++ b/vendor/rails/railties/test/abstract_unit.rb
@@ -9,9 +9,6 @@ require 'stringio'
require 'rubygems'
require 'test/unit'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
-
require 'active_support'
require 'active_support/test_case'
diff --git a/vendor/rails/railties/test/gem_dependency_test.rb b/vendor/rails/railties/test/gem_dependency_test.rb
index 189ad02b..a4cf6f76 100644
--- a/vendor/rails/railties/test/gem_dependency_test.rb
+++ b/vendor/rails/railties/test/gem_dependency_test.rb
@@ -18,7 +18,7 @@ class GemDependencyTest < Test::Unit::TestCase
def test_configuration_adds_gem_dependency
config = Rails::Configuration.new
config.gem "xaws-s3x", :lib => "aws/s3", :version => "0.4.0"
- assert_equal [["install", "xaws-s3x", "--version", '"= 0.4.0"']], config.gems.collect(&:install_command)
+ assert_equal [["install", "xaws-s3x", "--version", '"= 0.4.0"']], config.gems.collect { |g| g.install_command }
end
def test_gem_creates_install_command
@@ -144,4 +144,76 @@ class GemDependencyTest < Test::Unit::TestCase
end
end
+ def test_gem_ignores_development_dependencies
+ dummy_gem = Rails::GemDependency.new "dummy-gem-k"
+ dummy_gem.add_load_paths
+ dummy_gem.load
+ assert_equal 1, dummy_gem.dependencies.size
+ end
+
+ def test_gem_guards_against_duplicate_unpacks
+ dummy_gem = Rails::GemDependency.new "dummy-gem-a"
+ dummy_gem.stubs(:frozen?).returns(true)
+ dummy_gem.expects(:unpack_base).never
+ dummy_gem.unpack
+ end
+
+ def test_gem_does_not_unpack_framework_gems
+ dummy_gem = Rails::GemDependency.new "dummy-gem-a"
+ dummy_gem.stubs(:framework_gem?).returns(true)
+ dummy_gem.expects(:unpack_base).never
+ dummy_gem.unpack
+ end
+
+ def test_gem_from_directory_name_attempts_to_load_specification
+ assert_raises RuntimeError do
+ dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem-1.1')
+ end
+ end
+
+ def test_gem_from_directory_name
+ dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem-1.1', false)
+ assert_equal 'dummy-gem', dummy_gem.name
+ assert_equal '= 1.1', dummy_gem.version_requirements.to_s
+ end
+
+ def test_gem_from_directory_name_loads_specification_successfully
+ assert_nothing_raised do
+ dummy_gem = Rails::GemDependency.from_directory_name(File.join(Rails::GemDependency.unpacked_path, 'dummy-gem-g-1.0.0'))
+ assert_not_nil dummy_gem.specification
+ end
+ end
+
+ def test_gem_from_invalid_directory_name
+ assert_raises RuntimeError do
+ dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem')
+ end
+ assert_raises RuntimeError do
+ dummy_gem = Rails::GemDependency.from_directory_name('dummy')
+ end
+ end
+
+ def test_gem_determines_build_status
+ assert_equal true, Rails::GemDependency.new("dummy-gem-a").built?
+ assert_equal true, Rails::GemDependency.new("dummy-gem-i").built?
+ assert_equal false, Rails::GemDependency.new("dummy-gem-j").built?
+ end
+
+ def test_gem_determines_build_status_only_on_vendor_gems
+ framework_gem = Rails::GemDependency.new('dummy-framework-gem')
+ framework_gem.stubs(:framework_gem?).returns(true) # already loaded
+ framework_gem.stubs(:vendor_rails?).returns(false) # but not in vendor/rails
+ framework_gem.stubs(:vendor_gem?).returns(false) # and not in vendor/gems
+ framework_gem.add_load_paths # freeze framework gem early
+ assert framework_gem.built?
+ end
+
+ def test_gem_build_passes_options_to_dependencies
+ start_gem = Rails::GemDependency.new("dummy-gem-g")
+ dep_gem = Rails::GemDependency.new("dummy-gem-f")
+ start_gem.stubs(:dependencies).returns([dep_gem])
+ dep_gem.expects(:build).with({ :force => true }).once
+ start_gem.build(:force => true)
+ end
+
end
diff --git a/vendor/rails/railties/test/initializer_test.rb b/vendor/rails/railties/test/initializer_test.rb
index 561f7b8b..ace0ccaf 100644
--- a/vendor/rails/railties/test/initializer_test.rb
+++ b/vendor/rails/railties/test/initializer_test.rb
@@ -309,7 +309,7 @@ class InitializerSetupI18nTests < Test::Unit::TestCase
config.i18n.load_path << "my/other/locale.yml"
Rails::Initializer.run(:initialize_i18n, config)
- assert_equal [
+ assert_equal [
File.expand_path(File.dirname(__FILE__) + "/../../activesupport/lib/active_support/locale/en.yml"),
File.expand_path(File.dirname(__FILE__) + "/../../actionpack/lib/action_view/locale/en.yml"),
File.expand_path(File.dirname(__FILE__) + "/../../activerecord/lib/active_record/locale/en.yml"),
@@ -363,17 +363,31 @@ class InitializerDatabaseMiddlewareTest < Test::Unit::TestCase
ensure
ActionController::Base.session_store = store
end
+
+ def test_ensure_database_middleware_doesnt_use_action_controller_on_initializing
+ @config.frameworks -= [:action_controller]
+ store = ActionController::Base.session_store
+ ActionController::Base.session_store = ActiveRecord::SessionStore
+
+ @config.middleware.expects(:use).with(ActiveRecord::ConnectionAdapters::ConnectionManagement)
+ @config.middleware.expects(:use).with(ActiveRecord::QueryCache)
+
+ Rails::Initializer.run(:initialize_database_middleware, @config)
+ ensure
+ ActionController::Base.session_store = store
+ @config.frameworks += [:action_controller]
+ end
end
class InitializerViewPathsTest < Test::Unit::TestCase
def setup
@config = Rails::Configuration.new
@config.frameworks = [:action_view, :action_controller, :action_mailer]
-
+
ActionController::Base.stubs(:view_paths).returns(stub)
ActionMailer::Base.stubs(:view_paths).returns(stub)
end
-
+
def test_load_view_paths_doesnt_perform_anything_when_action_view_not_in_frameworks
@config.frameworks -= [:action_view]
ActionController::Base.view_paths.expects(:load!).never
@@ -396,4 +410,5 @@ class RailsRootTest < Test::Unit::TestCase
def test_rails_dot_root_should_be_a_pathname
assert_equal File.join(RAILS_ROOT, 'app', 'controllers'), Rails.root.join('app', 'controllers').to_s
end
-end
\ No newline at end of file
+end
+
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/.specification b/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/.specification
new file mode 100644
index 00000000..b3f79309
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/.specification
@@ -0,0 +1,29 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-h
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+files:
+- lib
+- lib/dummy-gem-h.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem H
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/lib/dummy-gem-h.rb b/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/lib/dummy-gem-h.rb
new file mode 100644
index 00000000..0f912349
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-h-1.0.0/lib/dummy-gem-h.rb
@@ -0,0 +1 @@
+DUMMY_GEM_H_VERSION="1.0.0"
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification b/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification
new file mode 100644
index 00000000..50b4969d
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification
@@ -0,0 +1,41 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-i
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: dummy-gem-i
+ type: :runtime
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+extensions:
+- ext/dummy-gem-i/extconf.rb
+files:
+- lib
+- lib/dummy-gem-i.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem G
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/ext/dummy-gem-i/Makefile b/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/ext/dummy-gem-i/Makefile
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb b/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb
new file mode 100644
index 00000000..2f9a376c
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb
@@ -0,0 +1 @@
+DUMMY_GEM_I_VERSION="1.0.0"
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification b/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification
new file mode 100644
index 00000000..2c456546
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification
@@ -0,0 +1,41 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-j
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: dummy-gem-j
+ type: :runtime
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+extensions:
+- ext/dummy-gem-j/extconf.rb
+files:
+- lib
+- lib/dummy-gem-j.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem G
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb b/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb
new file mode 100644
index 00000000..8ecd363f
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb
@@ -0,0 +1 @@
+DUMMY_GEM_J_VERSION="1.0.0"
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/.specification b/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/.specification
new file mode 100644
index 00000000..20edd0f8
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/.specification
@@ -0,0 +1,49 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-k
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: dummy-gem-k
+ type: :runtime
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+- !ruby/object:Gem::Dependency
+ name: dummy-gem-h
+ type: :development
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+files:
+- lib
+- lib/dummy-gem-k.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem I
diff --git a/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/lib/dummy-gem-k.rb b/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/lib/dummy-gem-k.rb
new file mode 100644
index 00000000..97fb1d69
--- /dev/null
+++ b/vendor/rails/railties/test/vendor/gems/dummy-gem-k-1.0.0/lib/dummy-gem-k.rb
@@ -0,0 +1 @@
+DUMMY_GEM_K_VERSION="1.0.0"