diff options
-rw-r--r-- | actionpack/lib/action_view/helpers/controller_helper.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/form_helper.rb | 15 | ||||
-rw-r--r-- | actionpack/test/template/form_helper_test.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb | 3 | ||||
-rw-r--r-- | activerecord/test/cases/connection_specification/resolver_test.rb | 3 | ||||
-rw-r--r-- | activerecord/test/cases/dirty_test.rb | 11 | ||||
-rw-r--r-- | activesupport/CHANGELOG.md | 12 | ||||
-rw-r--r-- | activesupport/lib/active_support/configurable.rb | 57 | ||||
-rw-r--r-- | activesupport/test/configurable_test.rb | 22 | ||||
-rw-r--r-- | railties/lib/rails/generators/rails/plugin_new/templates/Gemfile | 15 | ||||
-rw-r--r-- | railties/test/generators/plugin_new_generator_test.rb | 26 |
11 files changed, 161 insertions, 15 deletions
diff --git a/actionpack/lib/action_view/helpers/controller_helper.rb b/actionpack/lib/action_view/helpers/controller_helper.rb index 1a583e62ae..74ef25f7c1 100644 --- a/actionpack/lib/action_view/helpers/controller_helper.rb +++ b/actionpack/lib/action_view/helpers/controller_helper.rb @@ -10,14 +10,16 @@ module ActionView delegate :request_forgery_protection_token, :params, :session, :cookies, :response, :headers, :flash, :action_name, :controller_name, :controller_path, :to => :controller - delegate :logger, :to => :controller, :allow_nil => true - def assign_controller(controller) if @_controller = controller @_request = controller.request if controller.respond_to?(:request) @_config = controller.config.inheritable_copy if controller.respond_to?(:config) end end + + def logger + controller.logger if controller.respond_to?(:logger) + end end end end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ac150882b1..7dd35f7357 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1311,10 +1311,21 @@ module ActionView # post: # create: "Add %{model}" # - def button(value=nil, options={}) + # ==== Examples + # button("Create a post") + # # => <button name='button' type='submit'>Create post</button> + # + # button do + # content_tag(:strong, 'Ask me!') + # end + # # => <button name='button' type='submit'> + # # <strong>Ask me!</strong> + # # </button> + # + def button(value = nil, options = {}, &block) value, options = nil, value if value.is_a?(Hash) value ||= submit_default_value - @template.button_tag(value, options) + @template.button_tag(value, options, &block) end def emitted_hidden_id? diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index c9b39ed18f..b3e0c0256a 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -1054,6 +1054,9 @@ class FormHelperTest < ActionView::TestCase concat f.check_box(:secret) concat f.submit('Create post') concat f.button('Create post') + concat f.button { + concat content_tag(:span, 'Create post') + } end expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch') do @@ -1063,7 +1066,8 @@ class FormHelperTest < ActionView::TestCase "<input name='post[secret]' type='hidden' value='0' />" + "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" + "<input name='commit' type='submit' value='Create post' />" + - "<button name='button' type='submit'>Create post</button>" + "<button name='button' type='submit'>Create post</button>" + + "<button name='button' type='submit'><span>Create post</span></button>" end assert_dom_equal expected, output_buffer diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index ac31b636db..58a5d82e14 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -57,8 +57,9 @@ module ActiveRecord time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time end time = time.in_time_zone rescue nil if time + changed = read_attribute(:#{attr_name}) != time write_attribute(:#{attr_name}, original_time) - #{attr_name}_will_change! + #{attr_name}_will_change! if changed @attributes_cache["#{attr_name}"] = time end EOV diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb index e6cb1b9521..673a2b2b88 100644 --- a/activerecord/test/cases/connection_specification/resolver_test.rb +++ b/activerecord/test/cases/connection_specification/resolver_test.rb @@ -9,6 +9,7 @@ module ActiveRecord end def test_url_host_no_db + skip "only if mysql is available" unless defined?(MysqlAdapter) spec = resolve 'mysql://foo?encoding=utf8' assert_equal({ :adapter => "mysql", @@ -18,6 +19,7 @@ module ActiveRecord end def test_url_host_db + skip "only if mysql is available" unless defined?(MysqlAdapter) spec = resolve 'mysql://foo/bar?encoding=utf8' assert_equal({ :adapter => "mysql", @@ -27,6 +29,7 @@ module ActiveRecord end def test_url_port + skip "only if mysql is available" unless defined?(MysqlAdapter) spec = resolve 'mysql://foo:123?encoding=utf8' assert_equal({ :adapter => "mysql", diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index 2650040a80..46d485135f 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -78,6 +78,17 @@ class DirtyTest < ActiveRecord::TestCase assert_equal old_created_on, pirate.created_on_was end end + + def test_setting_time_attributes_with_time_zone_field_to_itself_should_not_be_marked_as_a_change + in_time_zone 'Paris' do + target = Class.new(ActiveRecord::Base) + target.table_name = 'pirates' + + pirate = target.create + pirate.created_on = pirate.created_on + assert !pirate.created_on_changed? + end + end def test_time_attributes_changes_without_time_zone_by_skip in_time_zone 'Paris' do diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index af9e8c27c7..c778647ea5 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,5 +1,17 @@ ## Rails 4.0.0 (unreleased) ## +* Add `:instance_accessor` option for `config_accessor`. + + class User + include ActiveSupport::Configurable + config_accessor :allowed_access, instance_accessor: false + end + + User.new.allowed_access = true # => NoMethodError + User.new.allowed_access # => NoMethodError + + *Francesco Rodriguez* + * ActionView::Helpers::NumberHelper methods have been moved to ActiveSupport::NumberHelper and are now available via Numeric#to_s. Numeric#to_s now accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size. *Andrew Mutz* diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb index a8aa53a80f..4fb8c7af3f 100644 --- a/activesupport/lib/active_support/configurable.rb +++ b/activesupport/lib/active_support/configurable.rb @@ -37,29 +37,77 @@ module ActiveSupport yield config end - # Allows you to add shortcut so that you don't have to refer to attribute through config. - # Also look at the example for config to contrast. + # Allows you to add shortcut so that you don't have to refer to attribute + # through config. Also look at the example for config to contrast. + # + # Defines both class and instance config accessors. # # class User # include ActiveSupport::Configurable # config_accessor :allowed_access # end # + # User.allowed_access # => nil + # User.allowed_access = false + # User.allowed_access # => false + # # user = User.new + # user.allowed_access # => false # user.allowed_access = true # user.allowed_access # => true # + # User.allowed_access # => false + # + # The attribute name must be a valid method name in Ruby. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :"1_Badname" + # end + # # => NameError: invalid config attribute name + # + # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>. + # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_reader: false, instance_writer: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError + # + # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_accessor: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError def config_accessor(*names) options = names.extract_options! names.each do |name| + raise NameError.new('invalid config attribute name') unless name =~ /^[_A-Za-z]\w*$/ + reader, line = "def #{name}; config.#{name}; end", __LINE__ writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__ singleton_class.class_eval reader, __FILE__, line singleton_class.class_eval writer, __FILE__, line - class_eval reader, __FILE__, line unless options[:instance_reader] == false - class_eval writer, __FILE__, line unless options[:instance_writer] == false + + unless options[:instance_accessor] == false + class_eval reader, __FILE__, line unless options[:instance_reader] == false + class_eval writer, __FILE__, line unless options[:instance_writer] == false + end end end end @@ -79,7 +127,6 @@ module ActiveSupport # # user.config.allowed_access # => true # user.config.level # => 1 - # def config @_config ||= self.class.config.inheritable_copy end diff --git a/activesupport/test/configurable_test.rb b/activesupport/test/configurable_test.rb index 2e5ea2c360..da7729d066 100644 --- a/activesupport/test/configurable_test.rb +++ b/activesupport/test/configurable_test.rb @@ -5,7 +5,8 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase class Parent include ActiveSupport::Configurable config_accessor :foo - config_accessor :bar, :instance_reader => false, :instance_writer => false + config_accessor :bar, instance_reader: false, instance_writer: false + config_accessor :baz, instance_accessor: false end class Child < Parent @@ -19,13 +20,13 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase end test "adds a configuration hash" do - assert_equal({ :foo => :bar }, Parent.config) + assert_equal({ foo: :bar }, Parent.config) end test "adds a configuration hash to a module as well" do mixin = Module.new { include ActiveSupport::Configurable } mixin.config.foo = :bar - assert_equal({ :foo => :bar }, mixin.config) + assert_equal({ foo: :bar }, mixin.config) end test "configuration hash is inheritable" do @@ -39,8 +40,12 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase test "configuration accessors is not available on instance" do instance = Parent.new + assert !instance.respond_to?(:bar) assert !instance.respond_to?(:bar=) + + assert !instance.respond_to?(:baz) + assert !instance.respond_to?(:baz=) end test "configuration hash is available on instance" do @@ -71,6 +76,15 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase assert_method_defined child.new.config, :bar end + test "should raise name error if attribute name is invalid" do + assert_raises NameError do + Class.new do + include ActiveSupport::Configurable + config_accessor "invalid attribute name" + end + end + end + def assert_method_defined(object, method) methods = object.public_methods.map(&:to_s) assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}" @@ -80,4 +94,4 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase methods = object.public_methods.map(&:to_s) assert !methods.include?(method.to_s), "Expected #{methods.inspect} to not include #{method.to_s.inspect}" end -end +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile index 9399c9cb77..7448b386c5 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile @@ -1,17 +1,32 @@ source "http://rubygems.org" +<% if options[:skip_gemspec] -%> +<%= '# ' if options.dev? || options.edge? -%>gem "rails", "~> <%= Rails::VERSION::STRING %>" +<% if full? && !options[:skip_javascript] -%> +# gem "<%= "#{options[:javascript]}-rails" %>" +<% end -%> +<% else -%> # Declare your gem's dependencies in <%= name %>.gemspec. # Bundler will treat runtime dependencies like base dependencies, and # development dependencies will be added by default to the :development group. gemspec +<% end -%> +<% unless options[:javascript] == 'jquery' -%> # jquery-rails is used by the dummy application gem "jquery-rails" +<% end -%> +<% if options[:skip_gemspec] -%> +group :development do + gem "<%= gem_for_database %>" +end +<% else -%> # Declare any dependencies that are still in development here instead of in # your gemspec. These might include edge Rails or gems from your path or # Git. Remember to move these dependencies to your gemspec before releasing # your gem to rubygems.org. +<% end -%> <% if options.dev? || options.edge? -%> # Your gem is dependent on dev or edge Rails. Once you can lock this diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 58740978aa..f7dffe9a5c 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -269,6 +269,32 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_skipping_gemspec run_generator [destination_root, "--skip-gemspec"] assert_no_file "bukkits.gemspec" + assert_file "Gemfile" do |contents| + assert_no_match('gemspec', contents) + assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/group :development do\n gem "sqlite3"\nend/, contents) + assert_no_match(/# gem "jquery-rails"/, contents) + end + end + + def test_skipping_gemspec_in_full_mode + run_generator [destination_root, "--skip-gemspec", "--full"] + assert_no_file "bukkits.gemspec" + assert_file "Gemfile" do |contents| + assert_no_match('gemspec', contents) + assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/group :development do\n gem "sqlite3"\nend/, contents) + assert_match(/# gem "jquery-rails"/, contents) + assert_no_match(/# jquery-rails is used by the dummy application\ngem "jquery-rails"/, contents) + end + end + + def test_skipping_gemspec_in_full_mode_with_javascript_option + run_generator [destination_root, "--skip-gemspec", "--full", "--javascript=prototype"] + assert_file "Gemfile" do |contents| + assert_match(/# gem "prototype-rails"/, contents) + assert_match(/# jquery-rails is used by the dummy application\ngem "jquery-rails"/, contents) + end end def test_creating_plugin_in_app_directory_adds_gemfile_entry |