diff --git a/actionmailer/lib/rails/generators/mailer/USAGE b/actionmailer/lib/rails/generators/mailer/USAGE index a08d4597396209e4b58f3ac008132687eed379c7..448ddbd5dfd45d0e1363367e2b1c99f78867ce31 100644 --- a/actionmailer/lib/rails/generators/mailer/USAGE +++ b/actionmailer/lib/rails/generators/mailer/USAGE @@ -1,4 +1,5 @@ Description: +============ Stubs out a new mailer and its views. Pass the mailer name, either CamelCased or under_scored, and an optional list of emails as arguments. @@ -6,10 +7,12 @@ Description: engine and test framework generators. Example: - `rails generate mailer Notifications signup forgot_password invoice` +======== + rails generate mailer Notifications signup forgot_password invoice creates a Notifications mailer class, views, test, and fixtures: Mailer: app/mailers/notifications.rb Views: app/views/notifications/signup.erb [...] Test: test/functional/notifications_test.rb Fixtures: test/fixtures/notifications/signup [...] + diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 1b793d255e5350b50a84cd67dd1135b7cce10df3..6a7931da8c2688af3c988f67c977aacb3eddc661 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -153,8 +153,8 @@ def teardown assert_equal(2, email.parts.length) assert_equal("multipart/related", email.mime_type) assert_equal("multipart/alternative", email.parts[0].mime_type) - assert_equal("text/plain", email.parts[0].parts[0].mime_type) - assert_equal("text/html", email.parts[0].parts[1].mime_type) + assert_equal("text/plain", email.parts[0].parts[0].mime_type) + assert_equal("text/html", email.parts[0].parts[1].mime_type) assert_equal("logo.png", email.parts[1].filename) end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 0f43527a56966e9baf2d5b8045df9f3d028c7d01..bc4f8bb9ce58da97b35fc2da6e2c1bb128ba47e7 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -172,6 +172,10 @@ def assign_parameters(routes, controller_path, action, parameters = {}) end def recycle! + write_cookies! + @env.delete('HTTP_COOKIE') if @cookies.blank? + @env.delete('action_dispatch.cookies') + @cookies = nil @formats = nil @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ } @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ } @@ -301,7 +305,11 @@ def exists? # and cookies, though. For sessions, you just do: # # @request.session[:key] = "value" - # @request.cookies["key"] = "value" + # @request.cookies[:key] = "value" + # + # To clear the cookies for a test just clear the request's cookies hash: + # + # @request.cookies.clear # # == \Testing named routes # @@ -416,6 +424,7 @@ def process(action, parameters = nil, session = nil, flash = nil, http_method = @controller.process_with_new_base_test(@request, @response) @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {} @request.session.delete('flash') if @request.session['flash'].blank? + @request.cookies.merge!(@response.cookies) @response end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index fc86d52a3a486c6c1020f98d57faf704bff3d8e9..61053d4464ad28e72b7571c93db4fd4c03d82346 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -1,5 +1,6 @@ require 'rack/mount' require 'forwardable' +require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/to_query' require 'active_support/core_ext/hash/slice' @@ -330,6 +331,7 @@ def empty? end def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true) + raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i) route = Route.new(self, app, conditions, requirements, defaults, name, anchor) @set.add_route(*route) named_routes[name] = route if name diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index 16f36741646737783cef1892c0a142a22cec872a..d430691429e9ab18bc6c0d650137bf885424c84e 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -22,7 +22,7 @@ def flash end def cookies - HashWithIndifferentAccess.new(@request.cookies.merge(@response.cookies)) + @request.cookies.merge(@response.cookies).with_indifferent_access end def redirect_to_url diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index cf440a1fade79d96559bb50660582151f8653ad2..822adb6a47082537e2f8667ce8bd84c6491348ee 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/object/blank' require 'active_support/core_ext/hash/reverse_merge' +require 'rack/utils' module ActionDispatch class TestRequest < Request @@ -77,10 +78,14 @@ def cookies private def write_cookies! unless @cookies.blank? - @env['HTTP_COOKIE'] = @cookies.map { |name, value| "#{name}=#{value};" }.join(' ') + @env['HTTP_COOKIE'] = @cookies.map { |name, value| escape_cookie(name, value) }.join('; ') end end + def escape_cookie(name, value) + "#{Rack::Utils.escape(name)}=#{Rack::Utils.escape(value)}" + end + def delete_nil_values! @env.delete_if { |k, v| v.nil? } end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 669ccd2a2d86ac3794fbca1d9b80288afb400da8..6df86ae65a14ec7e7b970f59f193427e733e0ce2 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -6,6 +6,7 @@ require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/array/extract_options' module ActionView # = Action View Form Helpers @@ -880,9 +881,9 @@ def range_field(object_name, method, options = {}) private - def instantiate_builder(record, record_object = nil, options = nil, &block) - options, record_object = record_object, nil if record_object.is_a?(Hash) - options ||= {} + def instantiate_builder(record, *args, &block) + options = args.extract_options! + record_object = args.shift case record when String, Symbol diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 1cfea6aa123f181f53f26cfb2483c5bb59c7efe9..39159fd629d3e6bd8cd42d3bc69190d9a7926e77 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -124,6 +124,20 @@ def string_key cookies['user_name'] = "david" head :ok end + + def symbol_key_mock + cookies[:user_name] = "david" if cookies[:user_name] == "andrew" + head :ok + end + + def string_key_mock + cookies['user_name'] = "david" if cookies['user_name'] == "andrew" + head :ok + end + + def noop + head :ok + end end tests TestController @@ -411,6 +425,57 @@ def test_cookies_hash_is_indifferent_access end end + def test_setting_request_cookies_is_indifferent_access + @request.cookies.clear + @request.cookies[:user_name] = "andrew" + get :string_key_mock + assert_equal "david", cookies[:user_name] + + @request.cookies.clear + @request.cookies['user_name'] = "andrew" + get :symbol_key_mock + assert_equal "david", cookies['user_name'] + end + + def test_cookies_retained_across_requests + get :symbol_key + assert_equal "user_name=david; path=/", @response.headers["Set-Cookie"] + assert_equal "david", cookies[:user_name] + + get :noop + assert_nil @response.headers["Set-Cookie"] + assert_equal "user_name=david", @request.env['HTTP_COOKIE'] + assert_equal "david", cookies[:user_name] + + get :noop + assert_nil @response.headers["Set-Cookie"] + assert_equal "user_name=david", @request.env['HTTP_COOKIE'] + assert_equal "david", cookies[:user_name] + end + + def test_cookies_can_be_cleared + get :symbol_key + assert_equal "user_name=david; path=/", @response.headers["Set-Cookie"] + assert_equal "david", cookies[:user_name] + + @request.cookies.clear + get :noop + assert_nil @response.headers["Set-Cookie"] + assert_nil @request.env['HTTP_COOKIE'] + assert_nil cookies[:user_name] + + get :symbol_key + assert_equal "user_name=david; path=/", @response.headers["Set-Cookie"] + assert_equal "david", cookies[:user_name] + end + + def test_cookies_are_escaped + @request.cookies[:user_ids] = '1;2' + get :noop + assert_equal "user_ids=1%3B2", @request.env['HTTP_COOKIE'] + assert_equal "1;2", cookies[:user_ids] + end + private def assert_cookie_header(expected) header = @response.headers["Set-Cookie"] diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 1a96587836b89408152eca52ea1763eeca5207b8..5e5758a60e7c06e5bef73295645e9677d2b39226 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -2313,6 +2313,38 @@ def test_controller_name_with_leading_slash_raise_error end end + def test_invalid_route_name_raises_error + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/products', :to => 'products#index', :as => 'products ' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/products', :to => 'products#index', :as => ' products' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/products', :to => 'products#index', :as => 'products!' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/products', :to => 'products#index', :as => 'products index' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/products', :to => 'products#index', :as => '1products' } + end + end + end + def test_nested_route_in_nested_resource get "/posts/1/comments/2/views" assert_equal "comments#views", @response.body diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index e42ade73d1afedc66f4c32b0c3155b2cda09d974..81a8c24525565caa418a92c439d20f39aa109824 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -36,10 +36,10 @@ class TestRequestTest < ActiveSupport::TestCase req.cookies["user_name"] = "david" assert_equal({"user_name" => "david"}, req.cookies) - assert_equal "user_name=david;", req.env["HTTP_COOKIE"] + assert_equal "user_name=david", req.env["HTTP_COOKIE"] req.cookies["login"] = "XJ-122" assert_equal({"user_name" => "david", "login" => "XJ-122"}, req.cookies) - assert_equal %w(login=XJ-122 user_name=david), req.env["HTTP_COOKIE"].split(/; ?/).sort + assert_equal %w(login=XJ-122 user_name=david), req.env["HTTP_COOKIE"].split(/; /).sort end end diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 69b1d4ff7bda46dbfa1e380af3cc88bca65ad585..93ff7ba0fd4ec197ff4dd8eb29913b4f82d6906e 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -1,6 +1,12 @@ require 'abstract_unit' require 'tzinfo' +class Map < Hash + def category + "" + end +end + TZInfo::Timezone.cattr_reader :loaded_zones class FormOptionsHelperTest < ActionView::TestCase @@ -394,6 +400,19 @@ def test_select_under_fields_for ) end + def test_fields_for_with_record_inherited_from_hash + map = Map.new + + output_buffer = fields_for :map, map do |f| + concat f.select(:category, %w( abe hest)) + end + + assert_dom_equal( + "", + output_buffer + ) + end + def test_select_under_fields_for_with_index @post = Post.new @post.category = "" diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index af036b560e0976b86983d9f04a32767ee7bedba4..ef36f80bec3230bb1727a3baafdbbb129f09fa27 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -72,7 +72,7 @@ def count_observers def instantiate_observer(observer) #:nodoc: # string/symbol if observer.respond_to?(:to_sym) - observer = observer.to_s.camelize.constantize.instance + observer.to_s.camelize.constantize.instance elsif observer.respond_to?(:instance) observer.instance else diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb index 8465bc1e105f484de559f15f5a555cc8813e0cea..0e6bc30fa296e08cad15bc69d8fb4fdc90d2f9d5 100644 --- a/activesupport/lib/active_support/backtrace_cleaner.rb +++ b/activesupport/lib/active_support/backtrace_cleaner.rb @@ -8,7 +8,7 @@ module ActiveSupport # filter or modify the paths of any lines of the backtrace, you can call BacktraceCleaner#remove_filters! These two methods # will give you a completely untouched backtrace. # - # Example: + # ==== Example: # # bc = BacktraceCleaner.new # bc.add_filter { |line| line.gsub(Rails.root, '') } diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index b4f0c42e3774822f13eeba2eb2e26a8176370b0d..10c457bb1de061440206cd1e97386cbdea577ee0 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -484,19 +484,20 @@ def merged_options(call_options) # :nodoc: # object responds to +cache_key+. Otherwise, to_param method will be # called. If the key is a Hash, then keys will be sorted alphabetically. def expanded_key(key) # :nodoc: - if key.respond_to?(:cache_key) - key = key.cache_key.to_s - elsif key.is_a?(Array) + return key.cache_key.to_s if key.respond_to?(:cache_key) + + case key + when Array if key.size > 1 - key.collect{|element| expanded_key(element)}.to_param + key = key.collect{|element| expanded_key(element)} else - key.first.to_param + key = key.first end - elsif key.is_a?(Hash) - key = key.to_a.sort{|a,b| a.first.to_s <=> b.first.to_s}.collect{|k,v| "#{k}=#{v}"}.to_param - else - key = key.to_param + when Hash + key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"} end + + key.to_param end # Prefix a key with the namespace. Namespace and key will be delimited with a colon. @@ -589,11 +590,7 @@ def compressed? # Check if the entry is expired. The +expires_in+ parameter can override the # value set when the entry was created. def expired? - if @expires_in && @created_at + @expires_in <= Time.now.to_f - true - else - false - end + @expires_in && @created_at + @expires_in <= Time.now.to_f end # Set a new time when the entry will expire. diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb index be19189c042eb2ce8030d1e3c78a1f22df3e7367..8c56a21ef77eb08cd806d527a620aaa13255f82c 100644 --- a/activesupport/lib/active_support/configurable.rb +++ b/activesupport/lib/active_support/configurable.rb @@ -64,21 +64,21 @@ def #{name}=(value); config.#{name} = value; end end # Reads and writes attributes from a configuration OrderedHash. - # - # require 'active_support/configurable' - # + # + # require 'active_support/configurable' + # # class User # include ActiveSupport::Configurable - # end + # end # # user = User.new - # + # # user.config.allowed_access = true # user.config.level = 1 # # user.config.allowed_access # => true # user.config.level # => 1 - # + # def config @_config ||= self.class.config.inheritable_copy end diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index 6a344867ee0b9e73b87c034824a7cd966d49d350..79a0de7940ff4b9d89b80e1b8317d3197391e1be 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -1,7 +1,7 @@ require 'active_support/core_ext/hash/keys' # This class has dubious semantics and we only have it so that -# people can write params[:key] instead of params['key'] +# people can write params[:key] instead of params['key'] # and they get the same value for both keys. module ActiveSupport @@ -109,7 +109,7 @@ def merge(hash) end # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second. - # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess. + # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess. def reverse_merge(other_hash) super self.class.new_from_hash_copying_default(other_hash) end diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb index 4a9ee5a769bd1e6e35188a8dcae4854e6ef13258..a25e95108016020983e3130c0bd912a9466ff84d 100644 --- a/activesupport/lib/active_support/i18n_railtie.rb +++ b/activesupport/lib/active_support/i18n_railtie.rb @@ -14,7 +14,7 @@ def self.reloader @reloader ||= ActiveSupport::FileUpdateChecker.new([]){ I18n.reload! } end - # Add I18n::Railtie.reloader to ActionDispatch callbacks. Since, at this + # Add I18n::Railtie.reloader to ActionDispatch callbacks. Since, at this # point, no path was added to the reloader, I18n.reload! is not triggered # on to_prepare callbacks. This will only happen on the config.after_initialize # callback below. diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb index df335af841a734f2480c218cf1c30d0e03fafead..10675edac594f7fcb917cb9a676aa524b4c4783d 100644 --- a/activesupport/lib/active_support/log_subscriber.rb +++ b/activesupport/lib/active_support/log_subscriber.rb @@ -21,7 +21,7 @@ module ActiveSupport # ActiveRecord::LogSubscriber.attach_to :active_record # # Since we need to know all instance methods before attaching the log subscriber, - # the line above should be called after your ActiveRecord::LogSubscriber definition. + # the line above should be called after your ActiveRecord::LogSubscriber definition. # # After configured, whenever a "sql.active_record" notification is published, # it will properly dispatch the event (ActiveSupport::Notifications::Event) to diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index d21f90f8b7d65d343a9021603f9046cb22540393..4f7cd12d48eb203a6142531e2525a8ab4a6e5b33 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -7,7 +7,7 @@ module ActiveSupport # # The cipher text and initialization vector are base64 encoded and returned to you. # - # This can be used in situations similar to the MessageVerifier, but where you don't + # This can be used in situations similar to the MessageVerifier, but where you don't # want users to be able to determine the value of the payload. class MessageEncryptor class InvalidMessage < StandardError; end diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index 9a4468f73c6aebde94cff3e6a25bdf7235356911..8f3946325a4a70486b8c6a3047f2e6084873fb5a 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -2,7 +2,7 @@ require 'active_support/core_ext/object/blank' module ActiveSupport - # MessageVerifier makes it easy to generate and verify messages which are signed + # +MessageVerifier+ makes it easy to generate and verify messages which are signed # to prevent tampering. # # This is useful for cases like remember-me tokens and auto-unsubscribe links where the diff --git a/activesupport/lib/active_support/whiny_nil.rb b/activesupport/lib/active_support/whiny_nil.rb index 91ddef26197f3615b7b4e69dc6838e048596aeac..bcedbfd57a66f83f8457a3289db716be50fb6e69 100644 --- a/activesupport/lib/active_support/whiny_nil.rb +++ b/activesupport/lib/active_support/whiny_nil.rb @@ -37,7 +37,7 @@ def self.add_whiner(klass) # Raises a RuntimeError when you attempt to call +id+ on +nil+. def id - raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller + raise RuntimeError, "Called id for nil, which would mistakenly be #{object_id} -- if you really wanted the id of nil, use object_id", caller end private diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 579d5dad243038a01e9fea14b1246ae5d38454e7..e5668e29d70cf2fdeca1be551ecd7c2996974979 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -679,12 +679,12 @@ def test_create_raw_entry def test_expired entry = ActiveSupport::Cache::Entry.new("value") - assert_equal false, entry.expired? + assert !entry.expired?, 'entry not expired' entry = ActiveSupport::Cache::Entry.new("value", :expires_in => 60) - assert_equal false, entry.expired? + assert !entry.expired?, 'entry not expired' time = Time.now + 61 Time.stubs(:now).returns(time) - assert_equal true, entry.expired? + assert entry.expired?, 'entry is expired' end def test_compress_values diff --git a/activesupport/test/whiny_nil_test.rb b/activesupport/test/whiny_nil_test.rb index 4b9f06deada2968cffe24a81686ea3f67e968e7d..ec3ca99ee693c0993d265892d92c31d648f5ccda 100644 --- a/activesupport/test/whiny_nil_test.rb +++ b/activesupport/test/whiny_nil_test.rb @@ -33,9 +33,11 @@ def test_array end def test_id + nil.stubs(:object_id).returns(999) nil.id rescue RuntimeError => nme assert_no_match(/nil:NilClass/, nme.message) + assert_match(/999/, nme.message) end def test_no_to_ary_coercion diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 64a68f7592c23561cb30b3b06ffb735d21527319..ed3968e2265b63322463f09fd6714b3c9345261a 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -420,7 +420,7 @@ Client.limit(5).offset(30) will return instead a maximum of 5 clients beginning with the 31st. The SQL looks like: -SELECT * FROM clients LIMIT 5, 30 +SELECT * FROM clients LIMIT 5 OFFSET 30 h3. Group diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index 3454b8b7a38d82c83482baf48b32bfb4df6218ce..82e7edfc84a485f802fd33cf7a9ac5b41791c662 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -364,6 +364,20 @@ Please make sure the patch does not introduce whitespace errors: $ git apply --whitespace=error-all mynew_patch.diff +You can check your patches by applying your patch to an different dedicated branch: + + +$ git checkout -b testing_branch +$ git apply --check my_new_patch.diff + + +You can make sure your patches don't add any whitespace by applying it yourself using the --whitespace=error-all option. Make sure you are on your dedicated test branche and: + + +$ git apply --whitespace=error-all mynew_patch.diff + + + h4. Create a Lighthouse Ticket Now create a ticket with your patch. Go to the "new ticket":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/new page at Lighthouse. Fill in a reasonable title and description, remember to attach your patch file, and tag the ticket with the ‘patch’ tag and whatever other subject area tags make sense.