diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2009-11-17 14:21:48 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2009-11-17 14:21:48 -0800 |
commit | bffb39d682675904158f43bfafebace0c50ed879 (patch) | |
tree | cc1f4d2fe3db4e84431eb6d8c16e907fb7771f23 | |
parent | 59f905bc00da88a6cb4d0edf73aa5b8201124bd1 (diff) | |
download | psych-bffb39d682675904158f43bfafebace0c50ed879.zip |
integrating some yaml tests
-rw-r--r-- | Rakefile | 8 | ||||
-rw-r--r-- | ext/psych/emitter.c | 2 | ||||
-rw-r--r-- | ext/psych/psych.c | 1 | ||||
-rw-r--r-- | ext/psych/to_ruby.c | 22 | ||||
-rw-r--r-- | ext/psych/to_ruby.h | 8 | ||||
-rw-r--r-- | lib/psych/ruby.rb | 2 | ||||
-rw-r--r-- | lib/psych/scalar_scanner.rb | 8 | ||||
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 50 | ||||
-rw-r--r-- | lib/psych/visitors/yast_builder.rb | 16 | ||||
-rw-r--r-- | test/helper.rb | 2 | ||||
-rw-r--r-- | test/yaml/test_array.rb | 17 | ||||
-rw-r--r-- | test/yaml/test_class.rb | 17 | ||||
-rw-r--r-- | test/yaml/test_exception.rb | 45 | ||||
-rw-r--r-- | test/yaml/test_hash.rb | 17 | ||||
-rw-r--r-- | test/yaml/test_string.rb | 5 | ||||
-rw-r--r-- | test/yaml/test_symbol.rb | 21 | ||||
-rw-r--r-- | test/yaml/test_yaml.rb | 2 |
17 files changed, 213 insertions, 30 deletions
@@ -1,5 +1,13 @@ # -*- ruby -*- +$: << File.join(File.dirname(__FILE__), 'lib') + +begin + require 'psych' + $" << "yaml.rb" +rescue LoadError +end + require 'rubygems' require 'hoe' diff --git a/ext/psych/emitter.c b/ext/psych/emitter.c index e5290e2..b9cda96 100644 --- a/ext/psych/emitter.c +++ b/ext/psych/emitter.c @@ -229,7 +229,7 @@ static VALUE alias(VALUE self, VALUE anchor) void Init_psych_emitter() { VALUE psych = rb_define_module("Psych"); - VALUE handler = rb_define_class_under(psych, "Handler", rb_cObject); + VALUE handler = rb_define_class_under(psych, "Handler", rb_cObject); cPsychEmitter = rb_define_class_under(psych, "Emitter", handler); rb_define_alloc_func(cPsychEmitter, allocate); diff --git a/ext/psych/psych.c b/ext/psych/psych.c index 9d40fe3..a218117 100644 --- a/ext/psych/psych.c +++ b/ext/psych/psych.c @@ -25,4 +25,5 @@ void Init_psych() Init_psych_parser(); Init_psych_emitter(); + Init_psych_to_ruby(); } diff --git a/ext/psych/to_ruby.c b/ext/psych/to_ruby.c new file mode 100644 index 0000000..a0421e7 --- /dev/null +++ b/ext/psych/to_ruby.c @@ -0,0 +1,22 @@ +#include <psych.h> + +VALUE cPsychVisitorsToRuby; + +static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg) +{ + VALUE e = rb_obj_alloc(klass); + + rb_iv_set(e, "mesg", mesg); + + return e; +} + +void Init_psych_to_ruby(void) +{ + VALUE psych = rb_define_module("Psych"); + VALUE visitors = rb_define_module_under(psych, "Visitors"); + VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); + cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor); + + rb_define_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); +} diff --git a/ext/psych/to_ruby.h b/ext/psych/to_ruby.h new file mode 100644 index 0000000..d4936a8 --- /dev/null +++ b/ext/psych/to_ruby.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_TO_RUBY_H +#define PSYCH_TO_RUBY_H + +#include <psych.h> + +void Init_psych_to_ruby(); + +#endif diff --git a/lib/psych/ruby.rb b/lib/psych/ruby.rb index 47e4421..3a2e124 100644 --- a/lib/psych/ruby.rb +++ b/lib/psych/ruby.rb @@ -2,6 +2,8 @@ require 'complex' require 'rational' require 'date' +YAML = Psych + [ Object, String, Class, Hash, Array, NilClass, Float, FalseClass, TrueClass, Range, Complex, Rational, Date, Time, Regexp, Exception, Struct diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb index f6412eb..2a3afa9 100644 --- a/lib/psych/scalar_scanner.rb +++ b/lib/psych/scalar_scanner.rb @@ -36,8 +36,12 @@ module Psych [:NEGATIVE_INFINITY, -1 / 0.0] when /^\.nan$/i [:NAN, 0.0 / 0.0] - when /^:.+/i - [:SYMBOL, @string.sub(/^:/, '').to_sym] + when /^:.+/ + if @string =~ /^:(["'])(.*)\1/ + [:SYMBOL, $2.sub(/^:/, '').to_sym] + else + [:SYMBOL, @string.sub(/^:/, '').to_sym] + end when /^[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+$/ i = 0 @string.split(':').each_with_index do |n,e| diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index f91537f..d4a48a1 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -84,26 +84,11 @@ module Psych end string when /!ruby\/struct:?(.*)?$/ - klassname = $1 + klass = resolve_class($1) members = o.children.map { |c| accept c } - if klassname && klassname.length > 1 - name = klassname - s = nil - retried = false - - begin - s = name.split('::').inject(Object) { |k,sub| - k.const_get sub - }.allocate - rescue NameError => ex - name = "Struct::#{name}" - unless retried - retried = true - retry - end - raise ex - end + if klass + s = klass.allocate struct_members = s.members.map { |x| x.to_sym } members.each_slice(2) { |k,v| if struct_members.include? k.to_sym @@ -122,9 +107,13 @@ module Psych h = Hash[*o.children.map { |c| accept c }] Range.new(h['begin'], h['end'], h['excl']) - when "!ruby/exception" + when /!ruby\/exception:?(.*)?$/ h = Hash[*o.children.map { |c| accept c }] - Exception.new h['message'] + + e = build_exception((resolve_class($1) || Exception), h.delete('message')) + + h.each { |k,v| e.instance_variable_set :"@#{k}", v } + e when '!ruby/object:Complex' h = Hash[*o.children.map { |c| accept c }] @@ -166,6 +155,27 @@ module Psych end private + # Convert +klassname+ to a Class + def resolve_class klassname + return nil unless klassname and not klassname.empty? + + name = klassname + retried = false + + begin + name.split('::').inject(Object) { |k,sub| + k.const_get sub + } + rescue NameError => ex + name = "Struct::#{name}" + unless retried + retried = true + retry + end + raise ex + end + end + def resolve_unknown o token = ScalarScanner.new(o.value).tokenize diff --git a/lib/psych/visitors/yast_builder.rb b/lib/psych/visitors/yast_builder.rb index 6e2295c..4eb21fd 100644 --- a/lib/psych/visitors/yast_builder.rb +++ b/lib/psych/visitors/yast_builder.rb @@ -62,10 +62,24 @@ module Psych end def visit_Exception o - @stack.push append Nodes::Mapping.new(nil, '!ruby/exception', false) + tag = ['!ruby/exception', o.class.name].compact.join(':') + @stack.push append Nodes::Mapping.new(nil, tag, false) + ['message', o.message].each do |m| accept m end + + if o.respond_to? :to_yaml_properties + ivars = o.to_yaml_properties + else + ivars = o.instance_variables + end + + ivars.each do |iv| + accept iv.to_s.sub(/^@/, '') + accept o.instance_variable_get(iv) + end + @stack.pop end diff --git a/test/helper.rb b/test/helper.rb new file mode 100644 index 0000000..0ca324c --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,2 @@ +require 'test/unit' +require 'psych' diff --git a/test/yaml/test_array.rb b/test/yaml/test_array.rb new file mode 100644 index 0000000..208c996 --- /dev/null +++ b/test/yaml/test_array.rb @@ -0,0 +1,17 @@ +require 'helper' + +module YAML + class TestArray < Test::Unit::TestCase + def setup + @list = [{ :a => 'b' }, 'foo'] + end + + def test_to_yaml + assert_equal @list, YAML.load(@list.to_yaml) + end + + def test_dump + assert_equal @list, YAML.load(YAML.dump(@list)) + end + end +end diff --git a/test/yaml/test_class.rb b/test/yaml/test_class.rb new file mode 100644 index 0000000..effa852 --- /dev/null +++ b/test/yaml/test_class.rb @@ -0,0 +1,17 @@ +require 'helper' + +module YAML + class TestClass < Test::Unit::TestCase + def test_to_yaml + assert_raises(::TypeError) do + TestClass.to_yaml + end + end + + def test_dump + assert_raises(::TypeError) do + YAML.dump TestClass + end + end + end +end diff --git a/test/yaml/test_exception.rb b/test/yaml/test_exception.rb new file mode 100644 index 0000000..f646008 --- /dev/null +++ b/test/yaml/test_exception.rb @@ -0,0 +1,45 @@ +require 'helper' + +module YAML + class TestException < Test::Unit::TestCase + class Wups < Exception + attr_reader :foo, :bar + def initialize *args + super + @foo = 1 + @bar = 2 + end + end + + def setup + @wups = Wups.new + end + + def test_to_yaml + w = YAML.load(@wups.to_yaml) + assert_equal @wups, w + assert_equal 1, w.foo + assert_equal 2, w.bar + end + + def test_dump + w = YAML.load(@wups.to_yaml) + assert_equal @wups, w + assert_equal 1, w.foo + assert_equal 2, w.bar + end + + def test_to_yaml_properties + class << @wups + def to_yaml_properties + [:@foo] + end + end + + w = YAML.load(YAML.dump(@wups)) + assert_equal @wups, w + assert_equal 1, w.foo + assert_nil w.bar + end + end +end diff --git a/test/yaml/test_hash.rb b/test/yaml/test_hash.rb new file mode 100644 index 0000000..e8869ae --- /dev/null +++ b/test/yaml/test_hash.rb @@ -0,0 +1,17 @@ +require 'helper' + +module YAML + class TestHash < Test::Unit::TestCase + def setup + @hash = { :a => 'b' } + end + + def test_to_yaml + assert_equal @hash, YAML.load(@hash.to_yaml) + end + + def test_dump + assert_equal @hash, YAML.load(YAML.dump(@hash)) + end + end +end diff --git a/test/yaml/test_string.rb b/test/yaml/test_string.rb index 7857672..637d65b 100644 --- a/test/yaml/test_string.rb +++ b/test/yaml/test_string.rb @@ -1,7 +1,4 @@ -require 'test/unit' -require 'psych' - -YAML = Psych +require 'helper' module YAML class TestString < Test::Unit::TestCase diff --git a/test/yaml/test_symbol.rb b/test/yaml/test_symbol.rb new file mode 100644 index 0000000..c4f77c4 --- /dev/null +++ b/test/yaml/test_symbol.rb @@ -0,0 +1,21 @@ +require 'helper' + +module YAML + class TestSymbol < Test::Unit::TestCase + def test_to_yaml + assert_equal :a, YAML.load(:a.to_yaml) + end + + def test_dump + assert_equal :a, YAML.load(YAML.dump(:a)) + end + + def test_stringy + assert_equal :"1", YAML.load(YAML.dump(:"1")) + end + + def test_load_quoted + assert_equal :"1", YAML.load("--- :'1'\n") + end + end +end diff --git a/test/yaml/test_yaml.rb b/test/yaml/test_yaml.rb index fbe33cd..b40279f 100644 --- a/test/yaml/test_yaml.rb +++ b/test/yaml/test_yaml.rb @@ -6,8 +6,6 @@ require 'test/unit' require 'rational' require 'psych' -YAML = Psych - # [ruby-core:01946] module YAML_Tests StructTest = Struct::new( :c ) |