From 914dd77899ccc28ae2fd32e2bd4f378788b978c3 Mon Sep 17 00:00:00 2001 From: Watson Date: Tue, 28 Aug 2012 18:17:49 +0900 Subject: [PATCH] update json to v1.7.5 --- ext/json/fbuffer/fbuffer.h | 31 ++++++++++++++- ext/json/generator/extconf.rb | 1 + ext/json/generator/generator.c | 25 ++++++++---- ext/json/generator/generator.h | 22 +---------- ext/json/lib/json/add/time.rb | 5 ++- ext/json/lib/json/common.rb | 14 ++++++- ext/json/lib/json/generic_object.rb | 39 +++++++++++++++++++ ext/json/lib/json/pure/generator.rb | 20 ++++++---- ext/json/lib/json/version.rb | 2 +- ext/json/parser/parser.c | 35 +++++++++-------- ext/json/parser/parser.rl | 1 + test-mri/test/json/test_json.rb | 20 ++++++++-- test-mri/test/json/test_json_addition.rb | 10 ++--- test-mri/test/json/test_json_encoding.rb | 2 +- test-mri/test/json/test_json_fixtures.rb | 2 +- test-mri/test/json/test_json_generate.rb | 36 +++++++++-------- .../test/json/test_json_generic_object.rb | 35 +++++++++++++++++ .../test/json/test_json_string_matching.rb | 8 ++-- test-mri/test/json/test_json_unicode.rb | 2 +- 19 files changed, 218 insertions(+), 92 deletions(-) create mode 100644 ext/json/lib/json/generic_object.rb create mode 100644 test-mri/test/json/test_json_generic_object.rb diff --git a/ext/json/fbuffer/fbuffer.h b/ext/json/fbuffer/fbuffer.h index 778fd675c..697a50dd6 100644 --- a/ext/json/fbuffer/fbuffer.h +++ b/ext/json/fbuffer/fbuffer.h @@ -2,8 +2,8 @@ #ifndef _FBUFFER_H_ #define _FBUFFER_H_ -#include #include "ruby.h" +#include #ifdef __MACRUBY__ /* We cannot use the GC memory functions here @@ -19,6 +19,27 @@ # define ruby_xfree(x) free(x) #endif +#ifndef RHASH_SIZE +#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) +#endif + +#ifndef RFLOAT_VALUE +#define RFLOAT_VALUE(val) (RFLOAT(val)->value) +#endif + +#ifndef RARRAY_PTR +#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr +#endif +#ifndef RARRAY_LEN +#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len +#endif +#ifndef RSTRING_PTR +#define RSTRING_PTR(string) RSTRING(string)->ptr +#endif +#ifndef RSTRING_LEN +#define RSTRING_LEN(string) RSTRING(string)->len +#endif + #ifdef HAVE_RUBY_ENCODING_H #include "ruby/encoding.h" #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) @@ -49,10 +70,14 @@ static FBuffer *fbuffer_alloc(unsigned long initial_length); static void fbuffer_free(FBuffer *fb); static void fbuffer_clear(FBuffer *fb); static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); +#ifdef JSON_GENERATOR static void fbuffer_append_long(FBuffer *fb, long number); +#endif static void fbuffer_append_char(FBuffer *fb, char newchr); +#ifdef JSON_GENERATOR static FBuffer *fbuffer_dup(FBuffer *fb); static VALUE fbuffer_to_s(FBuffer *fb); +#endif static FBuffer *fbuffer_alloc(unsigned long initial_length) { @@ -101,6 +126,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) } } +#ifdef JSON_GENERATOR static void fbuffer_append_str(FBuffer *fb, VALUE str) { const char *newstr = StringValuePtr(str); @@ -110,6 +136,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str) fbuffer_append(fb, newstr, len); } +#endif static void fbuffer_append_char(FBuffer *fb, char newchr) { @@ -118,6 +145,7 @@ static void fbuffer_append_char(FBuffer *fb, char newchr) fb->len++; } +#ifdef JSON_GENERATOR static void freverse(char *start, char *end) { char c; @@ -168,3 +196,4 @@ static VALUE fbuffer_to_s(FBuffer *fb) return result; } #endif +#endif diff --git a/ext/json/generator/extconf.rb b/ext/json/generator/extconf.rb index 32aed7f9b..c9475019d 100644 --- a/ext/json/generator/extconf.rb +++ b/ext/json/generator/extconf.rb @@ -10,4 +10,5 @@ end end +$defs << "-DJSON_GENERATOR" create_makefile 'json/ext/generator' diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 8f6abfc3e..0e7e6fd29 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -852,6 +852,21 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj) return fbuffer_to_s(buffer); } +/* + * This function returns true if string is either a JSON array or JSON object. + * It might suffer from false positives, e. g. syntactically incorrect JSON in + * the string or certain UTF-8 characters on the right hand side. + */ +static int isArrayOrObject(VALUE string) +{ + long string_len = RSTRING_LEN(string); + char *p = RSTRING_PTR(string), *q = p + string_len - 1; + if (string_len < 2) return 0; + for (; p < q && isspace(*p); p++); + for (; q > p && isspace(*q); q--); + return (*p == '[' && *q == ']') || (*p == '{' && *q == '}'); +} + /* * call-seq: generate(obj) * @@ -862,15 +877,9 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj) static VALUE cState_generate(VALUE self, VALUE obj) { VALUE result = cState_partial_generate(self, obj); - VALUE re, args[2]; GET_STATE(self); - if (!state->quirks_mode) { - args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z"); - args[1] = CRegexp_MULTILINE; - re = rb_class_new_instance(2, args, rb_cRegexp); - if (NIL_P(rb_funcall(re, i_match, 1, result))) { - rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed"); - } + if (!state->quirks_mode && !isArrayOrObject(result)) { + rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed"); } return result; } diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h index 3220178a8..7d429d512 100644 --- a/ext/json/generator/generator.h +++ b/ext/json/generator/generator.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ruby.h" @@ -15,27 +16,6 @@ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) -#ifndef RHASH_SIZE -#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) -#endif - -#ifndef RFLOAT_VALUE -#define RFLOAT_VALUE(val) (RFLOAT(val)->value) -#endif - -#ifndef RARRAY_PTR -#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr -#endif -#ifndef RARRAY_LEN -#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len -#endif -#ifndef RSTRING_PTR -#define RSTRING_PTR(string) RSTRING(string)->ptr -#endif -#ifndef RSTRING_LEN -#define RSTRING_LEN(string) RSTRING(string)->len -#endif - /* unicode defintions */ #define UNI_STRICT_CONVERSION 1 diff --git a/ext/json/lib/json/add/time.rb b/ext/json/lib/json/add/time.rb index 9755707e6..338209d89 100644 --- a/ext/json/lib/json/add/time.rb +++ b/ext/json/lib/json/add/time.rb @@ -20,10 +20,13 @@ def self.json_create(object) # Returns a hash, that will be turned into a JSON object and represent this # object. def as_json(*) + nanoseconds = [ tv_usec * 1000 ] + respond_to?(:tv_nsec) and nanoseconds << tv_nsec + nanoseconds = nanoseconds.max { JSON.create_id => self.class.name, 's' => tv_sec, - 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000 + 'n' => nanoseconds, } end diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index 22e893b87..5a10a9117 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -1,4 +1,5 @@ require 'json/version' +require 'json/generic_object' module JSON class << self @@ -110,7 +111,13 @@ def generator=(generator) # :nodoc: MinusInfinity = -Infinity # The base exception for JSON errors. - class JSONError < StandardError; end + class JSONError < StandardError + def self.wrap(exception) + obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}") + obj.set_backtrace exception.backtrace + obj + end + end # This exception is raised if a parser error occurs. class ParserError < JSONError; end @@ -406,7 +413,10 @@ def self.swap!(string) # :nodoc: end # Shortuct for iconv. - if ::String.method_defined?(:encode) + if ::String.method_defined?(:encode) && + # XXX Rubinius doesn't support ruby 1.9 encoding yet + defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx' + then # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) string.encode(to, from) diff --git a/ext/json/lib/json/generic_object.rb b/ext/json/lib/json/generic_object.rb new file mode 100644 index 000000000..7f3dbbd78 --- /dev/null +++ b/ext/json/lib/json/generic_object.rb @@ -0,0 +1,39 @@ +require 'ostruct' + +module JSON + class GenericObject < OpenStruct + class << self + alias [] new + + def json_create(data) + data = data.dup + data.delete JSON.create_id + self[data] + end + end + + def to_hash + table + end + + def [](name) + table[name.to_sym] + end + + def []=(name, value) + __send__ "#{name}=", value + end + + def |(other) + self.class[other.to_hash.merge(to_hash)] + end + + def as_json(*) + { JSON.create_id => self.class.name }.merge to_hash + end + + def to_json(*a) + as_json.to_json(*a) + end + end +end diff --git a/ext/json/lib/json/pure/generator.rb b/ext/json/lib/json/pure/generator.rb index 9141ae56f..3c81915ec 100644 --- a/ext/json/lib/json/pure/generator.rb +++ b/ext/json/lib/json/pure/generator.rb @@ -41,7 +41,6 @@ module JSON if defined?(::Encoding) def utf8_to_json(string) # :nodoc: string = string.dup - string << '' # XXX workaround: avoid buffer sharing string.force_encoding(::Encoding::ASCII_8BIT) string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } string.force_encoding(::Encoding::UTF_8) @@ -50,9 +49,8 @@ def utf8_to_json(string) # :nodoc: def utf8_to_json_ascii(string) # :nodoc: string = string.dup - string << '' # XXX workaround: avoid buffer sharing string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } string.gsub!(/( (?: [\xc2-\xdf][\x80-\xbf] | @@ -63,16 +61,18 @@ def utf8_to_json_ascii(string) # :nodoc: )/nx) { |c| c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] + s.force_encoding(::Encoding::ASCII_8BIT) s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) } string.force_encoding(::Encoding::UTF_8) string rescue => e - raise GeneratorError, "Caught #{e.class}: #{e}" + raise GeneratorError.wrap(e) end else def utf8_to_json(string) # :nodoc: - string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] } end def utf8_to_json_ascii(string) # :nodoc: @@ -91,7 +91,7 @@ def utf8_to_json_ascii(string) # :nodoc: } string rescue => e - raise GeneratorError, "Caught #{e.class}: #{e}" + raise GeneratorError.wrap(e) end end module_function :utf8_to_json, :utf8_to_json_ascii @@ -255,8 +255,12 @@ def to_h # GeneratorError exception. def generate(obj) result = obj.to_json(self) - if !@quirks_mode && result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m - raise GeneratorError, "only generation of JSON objects or arrays allowed" + unless @quirks_mode + unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ || + result =~ /\A\s*\{/ && result =~ /\}\s*\Z/ + then + raise GeneratorError, "only generation of JSON objects or arrays allowed" + end end result end diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index 229556324..45af03fd4 100644 --- a/ext/json/lib/json/version.rb +++ b/ext/json/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.6.5' + VERSION = '1.7.5' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index d4adb8e62..c140fdb2f 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -1721,6 +1721,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) source = convert_encoding(StringValue(source)); } json->current_nesting = 0; + StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; json->Vsource = source; @@ -1728,7 +1729,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1732 "parser.c" +#line 1733 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1736,7 +1737,7 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 739 "parser.rl" +#line 740 "parser.rl" static VALUE cParser_parse_strict(VALUE self) @@ -1747,16 +1748,16 @@ static VALUE cParser_parse_strict(VALUE self) GET_PARSER; -#line 1751 "parser.c" +#line 1752 "parser.c" { cs = JSON_start; } -#line 749 "parser.rl" +#line 750 "parser.rl" p = json->source; pe = p + json->len; -#line 1760 "parser.c" +#line 1761 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1812,7 +1813,7 @@ case 5: goto st1; goto st5; tr3: -#line 728 "parser.rl" +#line 729 "parser.rl" { char *np; json->current_nesting = 1; @@ -1821,7 +1822,7 @@ case 5: } goto st10; tr4: -#line 721 "parser.rl" +#line 722 "parser.rl" { char *np; json->current_nesting = 1; @@ -1833,7 +1834,7 @@ case 5: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1837 "parser.c" +#line 1838 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1890,7 +1891,7 @@ case 9: _out: {} } -#line 752 "parser.rl" +#line 753 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -1902,7 +1903,7 @@ case 9: -#line 1906 "parser.c" +#line 1907 "parser.c" static const int JSON_quirks_mode_start = 1; static const int JSON_quirks_mode_first_final = 10; static const int JSON_quirks_mode_error = 0; @@ -1910,7 +1911,7 @@ static const int JSON_quirks_mode_error = 0; static const int JSON_quirks_mode_en_main = 1; -#line 777 "parser.rl" +#line 778 "parser.rl" static VALUE cParser_parse_quirks_mode(VALUE self) @@ -1921,16 +1922,16 @@ static VALUE cParser_parse_quirks_mode(VALUE self) GET_PARSER; -#line 1925 "parser.c" +#line 1926 "parser.c" { cs = JSON_quirks_mode_start; } -#line 787 "parser.rl" +#line 788 "parser.rl" p = json->source; pe = p + json->len; -#line 1934 "parser.c" +#line 1935 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1964,7 +1965,7 @@ case 1: cs = 0; goto _out; tr2: -#line 769 "parser.rl" +#line 770 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1974,7 +1975,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1978 "parser.c" +#line 1979 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2063,7 +2064,7 @@ case 9: _out: {} } -#line 790 "parser.rl" +#line 791 "parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl index c96b0a822..20ecc486e 100644 --- a/ext/json/parser/parser.rl +++ b/ext/json/parser/parser.rl @@ -705,6 +705,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) source = convert_encoding(StringValue(source)); } json->current_nesting = 0; + StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; json->Vsource = source; diff --git a/test-mri/test/json/test_json.rb b/test-mri/test/json/test_json.rb index c06fd1923..22cd5ee5a 100755 --- a/test-mri/test/json/test_json.rb +++ b/test-mri/test/json/test_json.rb @@ -21,7 +21,7 @@ def permutation end end -class TC_JSON < Test::Unit::TestCase +class TestJSON < Test::Unit::TestCase include JSON def setup @@ -109,6 +109,8 @@ def test_parse_simple_objects def test_parse_json_primitive_values assert_raise(JSON::ParserError) { JSON.parse('') } assert_raise(JSON::ParserError) { JSON.parse('', :quirks_mode => true) } + assert_raise(TypeError) { JSON::Parser.new(nil).parse } + assert_raise(TypeError) { JSON::Parser.new(nil, :quirks_mode => true).parse } assert_raise(TypeError) { JSON.parse(nil) } assert_raise(TypeError) { JSON.parse(nil, :quirks_mode => true) } assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') } @@ -314,7 +316,17 @@ def test_parse_object_custom_non_hash_derived_class assert res.item_set? end - def test_generation_of_core_subclasses_with_new_to_json + def test_parse_generic_object + res = parse('{"foo":"bar", "baz":{}}', :object_class => JSON::GenericObject) + assert_equal(JSON::GenericObject, res.class) + assert_equal "bar", res.foo + assert_equal "bar", res["foo"] + assert_equal "bar", res[:foo] + assert_equal "bar", res.to_hash[:foo] + assert_equal(JSON::GenericObject, res.baz.class) + end + + def test_generate_core_subclasses_with_new_to_json obj = SubHash2["foo" => SubHash2["bar" => true]] obj_json = JSON(obj) obj_again = JSON(obj_json) @@ -325,12 +337,12 @@ def test_generation_of_core_subclasses_with_new_to_json assert_equal ["foo"], JSON(JSON(SubArray2["foo"])) end - def test_generation_of_core_subclasses_with_default_to_json + def test_generate_core_subclasses_with_default_to_json assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"]) assert_equal '["foo"]', JSON(SubArray["foo"]) end - def test_generation_of_core_subclasses + def test_generate_of_core_subclasses obj = SubHash["foo" => SubHash["bar" => true]] obj_json = JSON(obj) obj_again = JSON(obj_json) diff --git a/test-mri/test/json/test_json_addition.rb b/test-mri/test/json/test_json_addition.rb index e262e2595..707aa322d 100755 --- a/test-mri/test/json/test_json_addition.rb +++ b/test-mri/test/json/test_json_addition.rb @@ -10,7 +10,7 @@ require 'json/add/ostruct' require 'date' -class TC_JSONAddition < Test::Unit::TestCase +class TestJSONAddition < Test::Unit::TestCase include JSON class A @@ -64,7 +64,7 @@ def self.json_creatable? def to_json(*args) { - 'json_class' => 'TC_JSONAddition::Nix', + 'json_class' => 'TestJSONAddition::Nix', }.to_json(*args) end end @@ -88,7 +88,7 @@ def test_extended_json_disabled a_hash = JSON.parse(json, :create_additions => false) assert_kind_of Hash, a_hash assert_equal( - {"args"=>[666], "json_class"=>"TC_JSONAddition::A"}.sort_by { |k,| k }, + {"args"=>[666], "json_class"=>"TestJSONAddition::A"}.sort_by { |k,| k }, a_hash.sort_by { |k,| k } ) end @@ -97,7 +97,7 @@ def test_extended_json_fail1 b = B.new assert !B.json_creatable? json = generate(b) - assert_equal({ "json_class"=>"TC_JSONAddition::B" }, JSON.parse(json)) + assert_equal({ "json_class"=>"TestJSONAddition::B" }, JSON.parse(json)) end def test_extended_json_fail2 @@ -119,7 +119,7 @@ def test_raw_strings json_raw_object = raw.to_json_raw_object hash = { 'json_class' => 'String', 'raw'=> raw_array } assert_equal hash, json_raw_object - assert_match(/\A\{.*\}\Z/, json) + assert_match(/\A\{.*\}\z/, json) assert_match(/"json_class":"String"/, json) assert_match(/"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json) raw_again = JSON.parse(json) diff --git a/test-mri/test/json/test_json_encoding.rb b/test-mri/test/json/test_json_encoding.rb index 7af5e63a7..caa0c6c50 100644 --- a/test-mri/test/json/test_json_encoding.rb +++ b/test-mri/test/json/test_json_encoding.rb @@ -4,7 +4,7 @@ require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') -class TC_JSONEncoding < Test::Unit::TestCase +class TestJSONEncoding < Test::Unit::TestCase include JSON def setup diff --git a/test-mri/test/json/test_json_fixtures.rb b/test-mri/test/json/test_json_fixtures.rb index e9df8f5b1..37e51457d 100755 --- a/test-mri/test/json/test_json_fixtures.rb +++ b/test-mri/test/json/test_json_fixtures.rb @@ -4,7 +4,7 @@ require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') -class TC_JSONFixtures < Test::Unit::TestCase +class TestJSONFixtures < Test::Unit::TestCase def setup fixtures = File.join(File.dirname(__FILE__), 'fixtures/*.json') passed, failed = Dir[fixtures].partition { |f| f['pass'] } diff --git a/test-mri/test/json/test_json_generate.rb b/test-mri/test/json/test_json_generate.rb index b363de1b9..1c7ae34e6 100755 --- a/test-mri/test/json/test_json_generate.rb +++ b/test-mri/test/json/test_json_generate.rb @@ -4,7 +4,7 @@ require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') -class TC_JSONGenerate < Test::Unit::TestCase +class TestJSONGenerate < Test::Unit::TestCase include JSON def setup @@ -227,23 +227,25 @@ def test_gc GC.stress = stress end if GC.respond_to?(:stress=) - def test_broken_bignum # [ruby-core:38867] - pid = fork do - Bignum.class_eval do - def to_s + if defined?(JSON::Ext::Generator) + def test_broken_bignum # [ruby-core:38867] + pid = fork do + Bignum.class_eval do + def to_s + end + end + begin + JSON::Ext::Generator::State.new.generate(1<<64) + exit 1 + rescue TypeError + exit 0 end end - begin - JSON::Ext::Generator::State.new.generate(1<<64) - exit 1 - rescue TypeError - exit 0 - end + _, status = Process.waitpid2(pid) + assert status.success? + rescue NotImplementedError + # forking to avoid modifying core class of a parent process and + # introducing race conditions of tests are run in parallel end - _, status = Process.waitpid2(pid) - assert status.success? - rescue NotImplementedError - # forking to avoid modifying core class of a parent process and - # introducing race conditions of tests are run in parallel - end if defined?(JSON::Ext) + end end diff --git a/test-mri/test/json/test_json_generic_object.rb b/test-mri/test/json/test_json_generic_object.rb new file mode 100644 index 000000000..e13a49217 --- /dev/null +++ b/test-mri/test/json/test_json_generic_object.rb @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +require 'test/unit' +require File.join(File.dirname(__FILE__), 'setup_variant') +class TestJSONGenericObject < Test::Unit::TestCase + include JSON + + def setup + @go = GenericObject[ :a => 1, :b => 2 ] + end + + def test_attributes + assert_equal 1, @go.a + assert_equal 1, @go[:a] + assert_equal 2, @go.b + assert_equal 2, @go[:b] + assert_nil @go.c + assert_nil @go[:c] + end + + def test_generate_json + assert_equal @go, JSON(JSON(@go)) + end + + def test_parse_json + assert_equal @go, l = JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }') + assert_equal 1, l.a + assert_equal @go, l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject) + assert_equal 1, l.a + assert_equal GenericObject[:a => GenericObject[:b => 2]], + l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject) + assert_equal 2, l.a.b + end +end diff --git a/test-mri/test/json/test_json_string_matching.rb b/test-mri/test/json/test_json_string_matching.rb index df26a68a4..97e8c0788 100644 --- a/test-mri/test/json/test_json_string_matching.rb +++ b/test-mri/test/json/test_json_string_matching.rb @@ -6,7 +6,7 @@ require 'stringio' require 'time' -class TestJsonStringMatching < Test::Unit::TestCase +class TestJSONStringMatching < Test::Unit::TestCase include JSON class TestTime < ::Time @@ -28,13 +28,13 @@ def test_match_date t_json = [ t ].to_json assert_equal [ t ], JSON.parse(t_json, - :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\Z/ => TestTime }) + :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }) assert_equal [ t.strftime('%FT%T%z') ], JSON.parse(t_json, - :match_string => { /\A\d{3}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\Z/ => TestTime }) + :match_string => { /\A\d{3}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }) assert_equal [ t.strftime('%FT%T%z') ], JSON.parse(t_json, - :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\Z/ => TestTime }, + :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }, :create_additions => false) end end diff --git a/test-mri/test/json/test_json_unicode.rb b/test-mri/test/json/test_json_unicode.rb index ace56cae3..c32881110 100755 --- a/test-mri/test/json/test_json_unicode.rb +++ b/test-mri/test/json/test_json_unicode.rb @@ -4,7 +4,7 @@ require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') -class TC_JSONUnicode < Test::Unit::TestCase +class TestJSONUnicode < Test::Unit::TestCase include JSON def test_unicode