mirror of
https://github.com/github/rails.git
synced 2026-04-04 03:00:58 -04:00
Fixed JSON encoding to use quoted keys according to the JSON standard (closes #8762) [choonkat/chuyeow]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7697 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -209,19 +209,19 @@ class RenderTest < Test::Unit::TestCase
|
||||
|
||||
def test_do_with_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_do_with_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_do_with_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
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ require 'fixtures/comment'
|
||||
|
||||
class JsonSerializationTest < Test::Unit::TestCase
|
||||
def setup
|
||||
# Quote all keys (so that we can test against strictly valid JSON).
|
||||
ActiveSupport::JSON.unquote_hash_key_identifiers = false
|
||||
|
||||
@contact = Contact.new(
|
||||
:name => 'Konata Izumi',
|
||||
:age => 16,
|
||||
@@ -70,8 +67,6 @@ class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
|
||||
fixtures :authors, :posts, :comments, :tags, :taggings
|
||||
|
||||
def setup
|
||||
ActiveSupport::JSON.unquote_hash_key_identifiers = false
|
||||
|
||||
@david = authors(:david)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
*2.0.0 [Preview Release]* (September 29th, 2007)
|
||||
|
||||
* Fixed JSON encoding to use quoted keys according to the JSON standard #8762 [choonkat/chuyeow]
|
||||
|
||||
* Alias Object#send to send! for Ruby 1.9 forward compatibility. [Jeremy Kemper]
|
||||
|
||||
* Backport Object#instance_variable_defined? for Ruby < 1.8.6. [Jeremy Kemper]
|
||||
|
||||
@@ -2,8 +2,6 @@ class Hash
|
||||
def to_json #:nodoc:
|
||||
returning result = '{' do
|
||||
result << map do |key, value|
|
||||
key = ActiveSupport::JSON::Variable.new(key.to_s) if
|
||||
ActiveSupport::JSON.can_unquote_identifier?(key)
|
||||
"#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(value)}"
|
||||
end * ', '
|
||||
result << '}'
|
||||
|
||||
@@ -10,13 +10,6 @@ end
|
||||
|
||||
module ActiveSupport
|
||||
module JSON
|
||||
# When +true+, Hash#to_json will omit quoting string or symbol keys
|
||||
# if the keys are valid JavaScript identifiers. Note that this is
|
||||
# technically improper JSON (all object keys must be quoted), so if
|
||||
# you need strict JSON compliance, set this option to +false+.
|
||||
mattr_accessor :unquote_hash_key_identifiers
|
||||
@@unquote_hash_key_identifiers = true
|
||||
|
||||
class CircularReferenceError < StandardError
|
||||
end
|
||||
|
||||
@@ -30,11 +23,6 @@ module ActiveSupport
|
||||
end
|
||||
end
|
||||
|
||||
def can_unquote_identifier?(key) #:nodoc:
|
||||
unquote_hash_key_identifiers &&
|
||||
ActiveSupport::JSON.valid_identifier?(key)
|
||||
end
|
||||
|
||||
protected
|
||||
def raise_on_circular_reference(value) #:nodoc:
|
||||
stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module ActiveSupport
|
||||
module JSON
|
||||
# A string that returns itself as as its JSON-encoded form.
|
||||
# A string that returns itself as its JSON-encoded form.
|
||||
class Variable < String
|
||||
def to_json
|
||||
self
|
||||
|
||||
@@ -41,21 +41,12 @@ class TestJSONEncoding < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
unquote(false)
|
||||
end
|
||||
|
||||
def teardown
|
||||
unquote(true)
|
||||
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
|
||||
|
||||
sorted_json =
|
||||
'{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
|
||||
|
||||
sorted_json = '{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
|
||||
assert_equal %({\"a\": \"b\", \"c\": \"d\"}), sorted_json
|
||||
end
|
||||
|
||||
@@ -72,29 +63,14 @@ class TestJSONEncoding < Test::Unit::TestCase
|
||||
a << a
|
||||
assert_raises(ActiveSupport::JSON::CircularReferenceError) { a.to_json }
|
||||
end
|
||||
|
||||
def test_unquote_hash_key_identifiers
|
||||
|
||||
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 ), object_keys(values.to_json)
|
||||
unquote(true) { assert_equal %w( $ 0 1 A A0 A0B _ a ), object_keys(values.to_json) }
|
||||
end
|
||||
|
||||
def test_unquote_hash_key_identifiers_ignores_javascript_reserved_words
|
||||
values = {"hello" => "world", "this" => "that", "with" => "foo"}
|
||||
unquote(true) { assert_equal %w( "this" "with" hello ), object_keys(values.to_json) }
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
def unquote(value)
|
||||
previous_value = ActiveSupport::JSON.unquote_hash_key_identifiers
|
||||
ActiveSupport::JSON.unquote_hash_key_identifiers = value
|
||||
yield if block_given?
|
||||
ensure
|
||||
ActiveSupport::JSON.unquote_hash_key_identifiers = previous_value if block_given?
|
||||
end
|
||||
|
||||
def object_keys(json_object)
|
||||
json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user