summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2012-09-20 10:03:17 +0200
committerFlorian Frank <flori@ping.de>2012-12-31 01:34:52 +0100
commit29d4a4f19ff2e64a606e23d18cc8a02ecacd4e4a (patch)
tree34032a9608db3a2f008a56e26683d72e6db1530f
parentb24ea03d2dbdb20e676eb40d03042bea2dbd80be (diff)
downloadjson-29d4a4f19ff2e64a606e23d18cc8a02ecacd4e4a.tar.gz
Increase hash likeness of State objects
-rw-r--r--.travis.yml7
-rw-r--r--CHANGES1
-rw-r--r--Gemfile9
-rw-r--r--ext/json/ext/generator/generator.c37
-rw-r--r--ext/json/ext/generator/generator.h8
-rw-r--r--java/src/json/ext/GeneratorState.java20
-rw-r--r--lib/json/pure/generator.rb44
-rwxr-xr-xtests/test_json.rb2
-rw-r--r--tests/test_json_encoding.rb2
-rwxr-xr-xtests/test_json_fixtures.rb2
-rwxr-xr-xtests/test_json_generate.rb44
-rw-r--r--tests/test_json_generic_object.rb2
-rw-r--r--tests/test_json_string_matching.rb2
-rwxr-xr-xtests/test_json_unicode.rb2
14 files changed, 131 insertions, 51 deletions
diff --git a/.travis.yml b/.travis.yml
index 647a707..185b3e5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,18 +3,17 @@ bundler_args: --binstubs
# Specify which ruby versions you wish to run your tests on, each version will be used
rvm:
- - 1.8.6
- 1.8.7
- 1.9.2
- 1.9.3
+ - ree
- rbx-18mode
- rbx-19mode
- - ree
- jruby-18mode
- jruby-19mode
- ruby-head
matrix:
allow_failures:
- - rvm: 1.8.6
-
+ - rvm: rbx-18mode
+ - rvm: rbx-19mode
script: "bundle exec rake"
diff --git a/CHANGES b/CHANGES
index 00f042d..5d2cc61 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
2012-11-29 (1.7.6)
* Add GeneratorState#merge alias for JRuby, fix state accessor methods. Thx to
jvshahid@github.
+ * Increase hash likeness of state objects.
2012-08-17 (1.7.5)
* Fix compilation of extension on older rubies.
2012-07-26 (1.7.4)
diff --git a/Gemfile b/Gemfile
index 5a97c8c..de6df47 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,11 +6,4 @@ gemspec :name => 'json'
gemspec :name => 'json_pure'
gemspec :name => 'json-java'
-group :development, :test do
- gem 'simplecov', :platform => :mri_19
- gem 'utils'
-end
-
-group :test do
- gem 'test-unit', '~> 2.5', :platform => :mri_19
-end
+gem 'utils'
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c
index e64ea50..ae4593c 100644
--- a/ext/json/ext/generator/generator.c
+++ b/ext/json/ext/generator/generator.c
@@ -598,6 +598,18 @@ static VALUE cState_configure(VALUE self, VALUE opts)
return self;
}
+static void set_state_ivars(VALUE hash, VALUE state)
+{
+ VALUE ivars = rb_obj_instance_variables(state);
+ int i = 0;
+ for (i = 0; i < RARRAY_LEN(ivars); i++) {
+ VALUE key = rb_funcall(rb_ary_entry(ivars, i), i_to_s, 0);
+ long key_len = RSTRING_LEN(key);
+ VALUE value = rb_iv_get(state, StringValueCStr(key));
+ rb_hash_aset(hash, rb_str_intern(rb_str_substr(key, 1, key_len - 1)), value);
+ }
+}
+
/*
* call-seq: to_h
*
@@ -608,6 +620,7 @@ static VALUE cState_to_h(VALUE self)
{
VALUE result = rb_hash_new();
GET_STATE(self);
+ set_state_ivars(result, self);
rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
@@ -629,11 +642,31 @@ static VALUE cState_to_h(VALUE self)
*/
static VALUE cState_aref(VALUE self, VALUE name)
{
+ name = rb_funcall(name, i_to_s, 0);
if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
return rb_funcall(self, i_send, 1, name);
} else {
- return Qnil;
+ return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
+ }
+}
+
+/*
+* call-seq: []=(name, value)
+*
+* Set the attribute name to value.
+*/
+static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
+{
+ VALUE name_writer;
+
+ name = rb_funcall(name, i_to_s, 0);
+ name_writer = rb_str_cat2(rb_str_dup(name), "=");
+ if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) {
+ return rb_funcall(self, i_send, 2, name_writer, value);
+ } else {
+ rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value);
}
+ return Qnil;
}
static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -1326,7 +1359,9 @@ void Init_generator()
rb_define_method(cState, "configure", cState_configure, 1);
rb_define_alias(cState, "merge", "configure");
rb_define_method(cState, "to_h", cState_to_h, 0);
+ rb_define_alias(cState, "to_hash", "to_h");
rb_define_method(cState, "[]", cState_aref, 1);
+ rb_define_method(cState, "[]=", cState_aset, 2);
rb_define_method(cState, "generate", cState_generate, 1);
mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h
index 7d429d5..1b7074c 100644
--- a/ext/json/ext/generator/generator.h
+++ b/ext/json/ext/generator/generator.h
@@ -14,6 +14,14 @@
#include "re.h"
#endif
+#ifndef rb_intern_str
+#define rb_intern_str(string) SYM2ID(rb_str_intern(string))
+#endif
+
+#ifndef rb_obj_instance_variables
+#define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0)
+#endif
+
#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
/* unicode defintions */
diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java
index 58904ee..658d6d0 100644
--- a/java/src/json/ext/GeneratorState.java
+++ b/java/src/json/ext/GeneratorState.java
@@ -262,6 +262,19 @@ public class GeneratorState extends RubyObject {
String name = vName.asJavaString();
if (getMetaClass().isMethodBound(name, true)) {
return send(context, vName, Block.NULL_BLOCK);
+ } else {
+ return getInstanceVariables().getInstanceVariable("@" + name);
+ }
+ }
+
+ @JRubyMethod(name="[]=", required=2)
+ public IRubyObject op_aset(ThreadContext context, IRubyObject vName, IRubyObject value) {
+ String name = vName.asJavaString();
+ String nameWriter = name + "=";
+ if (getMetaClass().isMethodBound(nameWriter, true)) {
+ return send(context, context.getRuntime().newString(nameWriter), value, Block.NULL_BLOCK);
+ } else {
+ getInstanceVariables().setInstanceVariable("@" + name, value);
}
return context.getRuntime().getNil();
}
@@ -480,9 +493,9 @@ public class GeneratorState extends RubyObject {
*
* <p>Returns the configuration instance variables as a hash, that can be
* passed to the configure method.
- * @return
+ * @return the hash
*/
- @JRubyMethod
+ @JRubyMethod(alias = "to_hash")
public RubyHash to_h(ThreadContext context) {
Ruby runtime = context.getRuntime();
RubyHash result = RubyHash.newHash(runtime);
@@ -498,6 +511,9 @@ public class GeneratorState extends RubyObject {
result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
+ for (String name: getInstanceVariableNameList()) {
+ result.op_aset(context, runtime.newSymbol(name.substring(1)), getInstanceVariables().getInstanceVariable(name));
+ }
return result;
}
diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb
index 6916678..fcbc604 100644
--- a/lib/json/pure/generator.rb
+++ b/lib/json/pure/generator.rb
@@ -220,15 +220,20 @@ module JSON
# Configure this State instance with the Hash _opts_, and return
# itself.
def configure(opts)
- @indent = opts[:indent] if opts.key?(:indent)
- @space = opts[:space] if opts.key?(:space)
- @space_before = opts[:space_before] if opts.key?(:space_before)
- @object_nl = opts[:object_nl] if opts.key?(:object_nl)
- @array_nl = opts[:array_nl] if opts.key?(:array_nl)
- @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
- @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
- @depth = opts[:depth] || 0
- @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
+ for key, value in opts
+ instance_variable_set "@#{key}", value
+ end
+ @indent = opts[:indent] if opts.key?(:indent)
+ @space = opts[:space] if opts.key?(:space)
+ @space_before = opts[:space_before] if opts.key?(:space_before)
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
+ @depth = opts[:depth] || 0
+ @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
+ @buffer_initial_length ||= opts[:buffer_initial_length]
+
if !opts.key?(:max_nesting) # defaults to 100
@max_nesting = 100
elsif opts[:max_nesting]
@@ -244,12 +249,15 @@ module JSON
# passed to the configure method.
def to_h
result = {}
- for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only quirks_mode buffer_initial_length depth]
- result[iv.intern] = instance_variable_get("@#{iv}")
+ for iv in instance_variables
+ iv = iv.to_s[1..-1]
+ result[iv.to_sym] = self[iv]
end
result
end
+ alias to_hash to_h
+
# Generates a valid JSON document from object +obj+ and returns the
# result. If no valid JSON document can be created this method raises a
# GeneratorError exception.
@@ -267,7 +275,19 @@ module JSON
# Return the value returned by method +name+.
def [](name)
- __send__ name
+ if respond_to?(name)
+ __send__(name)
+ else
+ instance_variable_get("@#{name}")
+ end
+ end
+
+ def []=(name, value)
+ if respond_to?(name_writer = "#{name}=")
+ __send__ name_writer, value
+ else
+ instance_variable_set "@#{name}", value
+ end
end
end
diff --git a/tests/test_json.rb b/tests/test_json.rb
index 5ebe5ec..be974cd 100755
--- a/tests/test_json.rb
+++ b/tests/test_json.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
diff --git a/tests/test_json_encoding.rb b/tests/test_json_encoding.rb
index caa0c6c..fa7d878 100644
--- a/tests/test_json_encoding.rb
+++ b/tests/test_json_encoding.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
diff --git a/tests/test_json_fixtures.rb b/tests/test_json_fixtures.rb
index 37e5145..584dffd 100755
--- a/tests/test_json_fixtures.rb
+++ b/tests/test_json_fixtures.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb
index 5a96b05..5947bf6 100755
--- a/tests/test_json_generate.rb
+++ b/tests/test_json_generate.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
@@ -227,7 +227,7 @@ EOT
GC.stress = stress
end if GC.respond_to?(:stress=)
- def test_configure_using_merge
+ def test_configure_using_configure_and_merge
numbered_state = {
:indent => "1",
:space => '2',
@@ -252,22 +252,6 @@ EOT
end
if defined?(JSON::Ext::Generator)
- [:merge, :configure].each do |method|
- define_method "test_configure_using_#{method}" do
- state = JSON::Ext::Generator::State.new
- state.send method, :indent => "1",
- :space => '2',
- :space_before => '3',
- :object_nl => '4',
- :array_nl => '5'
- assert_equal '1', state.indent
- assert_equal '2', state.space
- assert_equal '3', state.space_before
- assert_equal '4', state.object_nl
- assert_equal '5', state.array_nl
- end
- end
-
def test_broken_bignum # [ruby-core:38867]
pid = fork do
Bignum.class_eval do
@@ -288,4 +272,28 @@ EOT
# introducing race conditions of tests are run in parallel
end
end
+
+ def test_hash_likeness_set_symbol
+ state = JSON.state.new
+ assert_equal nil, state[:foo]
+ assert_equal nil, state['foo']
+ state[:foo] = :bar
+ assert_equal :bar, state[:foo]
+ assert_equal :bar, state['foo']
+ state_hash = state.to_hash
+ assert_kind_of Hash, state_hash
+ assert_equal :bar, state_hash[:foo]
+ end
+
+ def test_hash_likeness_set_string
+ state = JSON.state.new
+ assert_equal nil, state[:foo]
+ assert_equal nil, state['foo']
+ state['foo'] = :bar
+ assert_equal :bar, state[:foo]
+ assert_equal :bar, state['foo']
+ state_hash = state.to_hash
+ assert_kind_of Hash, state_hash
+ assert_equal :bar, state_hash[:foo]
+ end
end
diff --git a/tests/test_json_generic_object.rb b/tests/test_json_generic_object.rb
index 1cec795..83093b8 100644
--- a/tests/test_json_generic_object.rb
+++ b/tests/test_json_generic_object.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
diff --git a/tests/test_json_string_matching.rb b/tests/test_json_string_matching.rb
index 97e8c07..2ddedfa 100644
--- a/tests/test_json_string_matching.rb
+++ b/tests/test_json_string_matching.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')
diff --git a/tests/test_json_unicode.rb b/tests/test_json_unicode.rb
index c328811..8352d5c 100755
--- a/tests/test_json_unicode.rb
+++ b/tests/test_json_unicode.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
+# encoding: utf-8
require 'test/unit'
require File.join(File.dirname(__FILE__), 'setup_variant')