From 6df507e884baa8566b685bb1c555e42185570160 Mon Sep 17 00:00:00 2001
From: Pavel Pravosud <pavel@pravosud.com>
Date: Mon, 31 Mar 2014 22:33:53 -0400
Subject: Make AS::SafeBuffer#prepend act like String#prepend

Make `#prepend` method modify instance in-place and return self
instead of just returning modified value. That is exactly what
`#prepend!` method was doing previously, so it's deprecated from
now on.
---
 activesupport/CHANGELOG.md                         |  6 ++++++
 .../core_ext/string/output_safety.rb               | 19 +++++++++++++------
 activesupport/test/core_ext/string_ext_test.rb     | 22 ++++++++++++++++++++++
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 556e94d184..f65d9ea120 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,9 @@
+*   `ActiveSupport::SafeBuffer#prepend` acts like `String#prepend` and modifies
+    instance in-place, returning self. `ActiveSupport::SafeBuffer#prepend!` is
+    deprecated.
+
+    *Pavel Pravosud*
+
 *   `HashWithIndifferentAccess` better respects `#to_hash` on objects it's
     given. In particular, `.new`, `#update`, `#merge`, `#replace` all accept
     objects which respond to `#to_hash`, even if those objects are not Hashes
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index eb02b6a442..db80cfa737 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -124,7 +124,7 @@ module ActiveSupport #:nodoc:
   class SafeBuffer < String
     UNSAFE_STRING_METHODS = %w(
       capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
-      slice squeeze strip sub succ swapcase tr tr_s upcase prepend
+      slice squeeze strip sub succ swapcase tr tr_s upcase
     )
 
     alias_method :original_concat, :concat
@@ -169,15 +169,22 @@ module ActiveSupport #:nodoc:
       self[0, 0]
     end
 
-    def concat(value)
-      if !html_safe? || value.html_safe?
-        super(value)
-      else
-        super(ERB::Util.h(value))
+    %w[concat prepend].each do |method_name|
+      define_method method_name do |value|
+        if !html_safe? || value.html_safe?
+          super(value)
+        else
+          super(ERB::Util.h(value))
+        end
       end
     end
     alias << concat
 
+    def prepend!(value)
+      ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
+      prepend value
+    end
+
     def +(other)
       dup.concat(other)
     end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 072b970a2d..4a7c2dac39 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -4,6 +4,7 @@ require 'abstract_unit'
 require 'inflector_test_cases'
 require 'constantize_test_cases'
 
+require 'active_support/deprecation/reporting'
 require 'active_support/inflector'
 require 'active_support/core_ext/string'
 require 'active_support/time'
@@ -608,6 +609,27 @@ class OutputSafetyTest < ActiveSupport::TestCase
     assert !@other_combination.html_safe?
   end
 
+  test "Prepending safe onto unsafe yields unsafe" do
+    @string.prepend "other".html_safe
+    assert !@string.html_safe?
+    assert_equal @string, "otherhello"
+  end
+
+  test "Prepending unsafe onto safe yields escaped safe" do
+    other = "other".html_safe
+    other.prepend "<foo>"
+    assert other.html_safe?
+    assert_equal other, "&lt;foo&gt;other"
+  end
+
+  test "Deprecated #prepend! method is still present" do
+    ActiveSupport::Deprecation.silence do
+      other = "other".html_safe
+      other.prepend! "<foo>"
+      assert_equal other, "&lt;foo&gt;other"
+    end
+  end
+
   test "Concatting safe onto unsafe yields unsafe" do
     @other_string = "other"
 
-- 
cgit v1.2.3