mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
1fb7969154
Rails 4.1 has switched away from MultiJson, and does not currently support any options on `ActiveSupport::JSON.decode`. Passing in unsupported options (i.e. any non-empty options hash) will now raise an ArgumentError. Rationale: 1. We cannot guarantee the underlying JSON parser won't change in the future, hence we cannot guarantee a consistent set of options the method could take 2. The `json` gem, which happens to be the current JSON parser, takes many dangerous options that is irrelevant to the purpose of AS's JSON decoding API 3. To reserve the options hash for future use, e.g. overriding default global options like ActiveSupport.parse_json_times This change *DOES NOT* introduce any changes in the public API. The signature of the method is still decode(json_text, options). The difference is this method previously accepted undocumented options which does different things when the underlying adapter changes. It now correctly raises an ArgumentError when it encounters options that it does not recognize (and currently it does not support any options).
105 lines
5 KiB
Ruby
105 lines
5 KiB
Ruby
# encoding: utf-8
|
|
require 'abstract_unit'
|
|
require 'active_support/json'
|
|
require 'active_support/time'
|
|
|
|
class TestJSONDecoding < ActiveSupport::TestCase
|
|
class Foo
|
|
def self.json_create(object)
|
|
"Foo"
|
|
end
|
|
end
|
|
|
|
TESTS = {
|
|
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
|
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
|
|
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
|
|
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
|
|
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
|
|
%({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
|
|
%({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
|
|
# multibyte
|
|
%({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
|
|
%({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
|
|
%({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
|
|
%(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
|
|
%(["2007-01-01 01:12:34 Z", "2007-01-01 01:12:35 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34), Time.utc(2007, 1, 1, 1, 12, 35)],
|
|
# no time zone
|
|
%({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
|
|
# invalid date
|
|
%({"a": "1089-10-40"}) => {'a' => "1089-10-40"},
|
|
# xmlschema date notation
|
|
%({"a": "2009-08-10T19:01:02Z"}) => {'a' => Time.utc(2009, 8, 10, 19, 1, 2)},
|
|
%({"a": "2009-08-10T19:01:02+02:00"}) => {'a' => Time.utc(2009, 8, 10, 17, 1, 2)},
|
|
%({"a": "2009-08-10T19:01:02-05:00"}) => {'a' => Time.utc(2009, 8, 11, 00, 1, 2)},
|
|
# needs to be *exact*
|
|
%({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
|
|
%({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
|
|
%([]) => [],
|
|
%({}) => {},
|
|
%({"a":1}) => {"a" => 1},
|
|
%({"a": ""}) => {"a" => ""},
|
|
%({"a":"\\""}) => {"a" => "\""},
|
|
%({"a": null}) => {"a" => nil},
|
|
%({"a": true}) => {"a" => true},
|
|
%({"a": false}) => {"a" => false},
|
|
%q({"bad":"\\\\","trailing":""}) => {"bad" => "\\", "trailing" => ""},
|
|
%q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
|
|
%q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
|
|
%q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
|
|
%q({"a": "\u003cbr /\u003e"}) => {'a' => "<br />"},
|
|
%q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]},
|
|
# test combination of dates and escaped or unicode encoded data in arrays
|
|
%q([{"d":"1970-01-01", "s":"\u0020escape"},{"d":"1970-01-01", "s":"\u0020escape"}]) =>
|
|
[{'d' => Date.new(1970, 1, 1), 's' => ' escape'},{'d' => Date.new(1970, 1, 1), 's' => ' escape'}],
|
|
%q([{"d":"1970-01-01","s":"http:\/\/example.com"},{"d":"1970-01-01","s":"http:\/\/example.com"}]) =>
|
|
[{'d' => Date.new(1970, 1, 1), 's' => 'http://example.com'},
|
|
{'d' => Date.new(1970, 1, 1), 's' => 'http://example.com'}],
|
|
# tests escaping of "\n" char with Yaml backend
|
|
%q({"a":"\n"}) => {"a"=>"\n"},
|
|
%q({"a":"\u000a"}) => {"a"=>"\n"},
|
|
%q({"a":"Line1\u000aLine2"}) => {"a"=>"Line1\nLine2"},
|
|
# prevent json unmarshalling
|
|
%q({"json_class":"TestJSONDecoding::Foo"}) => {"json_class"=>"TestJSONDecoding::Foo"},
|
|
# json "fragments" - these are invalid JSON, but ActionPack relies on this
|
|
%q("a string") => "a string",
|
|
%q(1.1) => 1.1,
|
|
%q(1) => 1,
|
|
%q(-1) => -1,
|
|
%q(true) => true,
|
|
%q(false) => false,
|
|
%q(null) => nil
|
|
}
|
|
|
|
TESTS.each_with_index do |(json, expected), index|
|
|
test "json decodes #{index}" do
|
|
prev = ActiveSupport.parse_json_times
|
|
ActiveSupport.parse_json_times = true
|
|
silence_warnings do
|
|
assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
|
|
failed for #{json}"
|
|
end
|
|
ActiveSupport.parse_json_times = prev
|
|
end
|
|
end
|
|
|
|
test "json decodes time json with time parsing disabled" do
|
|
prev = ActiveSupport.parse_json_times
|
|
ActiveSupport.parse_json_times = false
|
|
expected = {"a" => "2007-01-01 01:12:34 Z"}
|
|
assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
|
|
ActiveSupport.parse_json_times = prev
|
|
end
|
|
|
|
def test_failed_json_decoding
|
|
assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%(undefined)) }
|
|
assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({a: 1})) }
|
|
assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({: 1})) }
|
|
assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%()) }
|
|
end
|
|
|
|
def test_cannot_pass_unsupported_options
|
|
assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) }
|
|
end
|
|
end
|
|
|