From d8a5a0a33345755bd5b60b4bb6dd535c2139d53b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sat, 9 Jan 2010 17:46:16 -0800 Subject: adding init api --- ext/psych/emitter.c | 6 +++++ lib/psych/visitors/to_ruby.rb | 6 ++++- lib/psych/visitors/yaml_tree.rb | 23 ++++++++++++++------ test/psych/test_emitter.rb | 41 ++++++++++++++++++++++++++++------- test/psych/test_to_yaml_properties.rb | 25 +++++++++++++++++++++ 5 files changed, 85 insertions(+), 16 deletions(-) diff --git a/ext/psych/emitter.c b/ext/psych/emitter.c index 0c728f2..1cbee93 100644 --- a/ext/psych/emitter.c +++ b/ext/psych/emitter.c @@ -46,6 +46,7 @@ static VALUE start_stream(VALUE self, VALUE encoding) { yaml_emitter_t * emitter; Data_Get_Struct(self, yaml_emitter_t, emitter); + Check_Type(encoding, T_FIXNUM); yaml_event_t event; yaml_stream_start_event_initialize(&event, (yaml_encoding_t)NUM2INT(encoding)); @@ -75,6 +76,8 @@ static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) yaml_version_directive_t version_directive; + Check_Type(version, T_ARRAY); + if(RARRAY_LEN(version) > 0) { VALUE major = rb_ary_entry(version, (long)0); VALUE minor = rb_ary_entry(version, (long)1); @@ -89,11 +92,14 @@ static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) if(RTEST(tags)) { int i = 0; + Check_Type(tags, T_ARRAY); + head = xcalloc(RARRAY_LEN(tags), sizeof(yaml_tag_directive_t)); tail = head; for(i = 0; i < RARRAY_LEN(tags); i++) { VALUE tuple = RARRAY_PTR(tags)[i]; + Check_Type(tuple, T_ARRAY); if(RARRAY_LEN(tuple) < 2) { xfree(head); diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index ab5e766..3b53edb 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -173,7 +173,11 @@ module Psych private def init_with o, h - h.each { |k,v| o.instance_variable_set(:"@#{k}", v) } + if o.respond_to?(:init_with) + o.init_with h + else + h.each { |k,v| o.instance_variable_set(:"@#{k}", v) } + end o end diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index 52f5595..bbcb1c0 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -233,13 +233,22 @@ module Psych end def dump_ivars target, map - ivars = target.respond_to?(:to_yaml_properties) ? - target.to_yaml_properties : - target.instance_variables - - ivars.each do |iv| - map.children << Nodes::Scalar.new("#{iv.to_s.sub(/^@/, '')}") - accept target.instance_variable_get(iv) + if target.respond_to?(:encode_with) + coder = {} + target.encode_with(coder) + coder.each do |k,v| + map.children << Nodes::Scalar.new(k) + accept v + end + else + ivars = target.respond_to?(:to_yaml_properties) ? + target.to_yaml_properties : + target.instance_variables + + ivars.each do |iv| + map.children << Nodes::Scalar.new("#{iv.to_s.sub(/^@/, '')}") + accept target.instance_variable_get(iv) + end end end end diff --git a/test/psych/test_emitter.rb b/test/psych/test_emitter.rb index d617353..c296e6f 100644 --- a/test/psych/test_emitter.rb +++ b/test/psych/test_emitter.rb @@ -6,15 +6,40 @@ require 'stringio' module Psych class TestEmitter < MiniTest::Unit::TestCase + def setup + @out = StringIO.new + @emitter = Psych::Emitter.new @out + end + def test_emit_utf_8 - out = StringIO.new - emitter = Psych::Emitter.new out - emitter.start_stream Psych::Nodes::Stream::UTF8 - emitter.start_document [], [], false - emitter.scalar '日本語', nil, nil, false, true, 1 - emitter.end_document true - emitter.end_stream - assert_match('日本語', out.string) + @emitter.start_stream Psych::Nodes::Stream::UTF8 + @emitter.start_document [], [], false + @emitter.scalar '日本語', nil, nil, false, true, 1 + @emitter.end_document true + @emitter.end_stream + assert_match('日本語', @out.string) + end + + def test_start_stream_arg_error + assert_raises(TypeError) do + @emitter.start_stream 'asdfasdf' + end + end + + def test_start_doc_arg_error + @emitter.start_stream Psych::Nodes::Stream::UTF8 + + [ + [nil, [], false], + [[nil, nil], [], false], + [[], 'foo', false], + [[], ['foo'], false], + [[], [nil,nil], false], + ].each do |args| + assert_raises(TypeError) do + @emitter.start_document *args + end + end end end end diff --git a/test/psych/test_to_yaml_properties.rb b/test/psych/test_to_yaml_properties.rb index ff35fcd..358c7f1 100644 --- a/test/psych/test_to_yaml_properties.rb +++ b/test/psych/test_to_yaml_properties.rb @@ -16,6 +16,31 @@ module Psych end end + class InitApi < Foo + def init_with coder + @a = coder['aa'] + @b = coder['bb'] + end + + def encode_with coder + coder['aa'] = @a + coder['bb'] = @b + end + end + + def test_dump_encode_with + foo = InitApi.new + assert_match(/aa/, Psych.dump(foo)) + end + + def test_dump_init_with + foo = InitApi.new + bar = Psych.load(Psych.dump(foo)) + assert_equal foo.a, bar.a + assert_equal foo.b, bar.b + assert_nil bar.c + end + def test_object_dump_yaml_properties foo = Psych.load(Psych.dump(Foo.new)) assert_equal 1, foo.a -- cgit v1.2.3