summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/json/generator/generator.c6
-rwxr-xr-xtest/json/json_generator_test.rb66
2 files changed, 71 insertions, 1 deletions
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 1213f42497..c32b5ce093 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -732,7 +732,11 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
VALUE key_to_s;
switch(rb_type(key)) {
case T_STRING:
- key_to_s = key;
+ if (RB_LIKELY(RBASIC_CLASS(key) == rb_cString)) {
+ key_to_s = key;
+ } else {
+ key_to_s = rb_funcall(key, i_to_s, 0);
+ }
break;
case T_SYMBOL:
key_to_s = rb_sym2str(key);
diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb
index 6716eb82f2..112c03b220 100755
--- a/test/json/json_generator_test.rb
+++ b/test/json/json_generator_test.rb
@@ -536,6 +536,72 @@ class JSONGeneratorTest < Test::Unit::TestCase
assert_instance_of JSON::State, argument
end
+ module CustomToJSON
+ def to_json(*)
+ %{"#{self.class.name}#to_json"}
+ end
+ end
+
+ module CustomToS
+ def to_s
+ "#{self.class.name}#to_s"
+ end
+ end
+
+ class ArrayWithToJSON < Array
+ include CustomToJSON
+ end
+
+ def test_array_subclass_with_to_json
+ assert_equal '["JSONGeneratorTest::ArrayWithToJSON#to_json"]', JSON.generate([ArrayWithToJSON.new])
+ assert_equal '{"[]":1}', JSON.generate(ArrayWithToJSON.new => 1)
+ end
+
+ class ArrayWithToS < Array
+ include CustomToS
+ end
+
+ def test_array_subclass_with_to_s
+ assert_equal '[[]]', JSON.generate([ArrayWithToS.new])
+ assert_equal '{"JSONGeneratorTest::ArrayWithToS#to_s":1}', JSON.generate(ArrayWithToS.new => 1)
+ end
+
+ class HashWithToJSON < Hash
+ include CustomToJSON
+ end
+
+ def test_hash_subclass_with_to_json
+ assert_equal '["JSONGeneratorTest::HashWithToJSON#to_json"]', JSON.generate([HashWithToJSON.new])
+ assert_equal '{"{}":1}', JSON.generate(HashWithToJSON.new => 1)
+ end
+
+ class HashWithToS < Hash
+ include CustomToS
+ end
+
+ def test_hash_subclass_with_to_s
+ assert_equal '[{}]', JSON.generate([HashWithToS.new])
+ assert_equal '{"JSONGeneratorTest::HashWithToS#to_s":1}', JSON.generate(HashWithToS.new => 1)
+ end
+
+ class StringWithToJSON < String
+ include CustomToJSON
+ end
+
+ def test_string_subclass_with_to_json
+ assert_equal '["JSONGeneratorTest::StringWithToJSON#to_json"]', JSON.generate([StringWithToJSON.new])
+ assert_equal '{"":1}', JSON.generate(StringWithToJSON.new => 1)
+ end
+
+ class StringWithToS < String
+ include CustomToS
+ end
+
+ def test_string_subclass_with_to_s
+ assert_equal '[""]', JSON.generate([StringWithToS.new])
+ assert_equal '{"JSONGeneratorTest::StringWithToS#to_s":1}', JSON.generate(StringWithToS.new => 1)
+ end
+
if defined?(JSON::Ext::Generator) and RUBY_PLATFORM != "java"
def test_valid_utf8_in_different_encoding
utf8_string = "€™"