Properly dump primitive-like AS::SafeBuffer strings as YAML

`coder.represent_scalar` means something along the lines of "Here is a quoted
string, you can just add it to the output", which is not the case here. It only
works for simple strings that can appear unquoted in YAML, but causes problems
for e.g. primitive-like strings ("1", "true").

`coder.represent_object` on the other hand, means that "This is the Ruby-object
representation for this thing suitable for use in YAML dumping", which is what
we want here.

Before:

   YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml  # => "Hello"
   YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml   # => true
   YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml  # => false
   YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml      # => 1
   YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml    # => 1.1

 After:

   YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml  # => "Hello"
   YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml   # => "true"
   YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml  # => "false"
   YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml      # => "1"
   YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml    # => "1.1"

If we ever want Ruby to behave more like PHP or JavaScript though, this is an
excellent trick to use ;)
This commit is contained in:
Godfrey Chan 2015-02-11 17:04:23 -08:00
parent 933decceaf
commit debe7aedda
3 changed files with 29 additions and 1 deletions

View File

@ -1,3 +1,24 @@
* Fixed a roundtrip problem with AS::SafeBuffer where primitive-like strings
will be dumped as primitives:
Before:
YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml # => "Hello"
YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml # => true
YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml # => false
YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml # => 1
YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml # => 1.1
After:
YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml # => "Hello"
YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml # => "true"
YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml # => "false"
YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml # => "1"
YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml # => "1.1"
*Godfrey Chan*
* Enable number_to_percentage to keep the number's precision by allowing :precision to be nil
*Jack Xu*

View File

@ -222,7 +222,7 @@ module ActiveSupport #:nodoc:
end
def encode_with(coder)
coder.represent_scalar nil, to_str
coder.represent_object nil, to_str
end
UNSAFE_STRING_METHODS.each do |unsafe_method|

View File

@ -61,6 +61,13 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_equal({'str' => str}, YAML.load(yaml))
end
test "Should work with primitive-like-strings in to_yaml conversion" do
assert_equal 'true', YAML.load(ActiveSupport::SafeBuffer.new('true').to_yaml)
assert_equal 'false', YAML.load(ActiveSupport::SafeBuffer.new('false').to_yaml)
assert_equal '1', YAML.load(ActiveSupport::SafeBuffer.new('1').to_yaml)
assert_equal '1.1', YAML.load(ActiveSupport::SafeBuffer.new('1.1').to_yaml)
end
test "Should work with underscore" do
str = "MyTest".html_safe.underscore
assert_equal "my_test", str