summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2009-11-17 14:21:48 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2009-11-17 14:21:48 -0800
commitbffb39d682675904158f43bfafebace0c50ed879 (patch)
treecc1f4d2fe3db4e84431eb6d8c16e907fb7771f23
parent59f905bc00da88a6cb4d0edf73aa5b8201124bd1 (diff)
downloadpsych-bffb39d682675904158f43bfafebace0c50ed879.zip
integrating some yaml tests
-rw-r--r--Rakefile8
-rw-r--r--ext/psych/emitter.c2
-rw-r--r--ext/psych/psych.c1
-rw-r--r--ext/psych/to_ruby.c22
-rw-r--r--ext/psych/to_ruby.h8
-rw-r--r--lib/psych/ruby.rb2
-rw-r--r--lib/psych/scalar_scanner.rb8
-rw-r--r--lib/psych/visitors/to_ruby.rb50
-rw-r--r--lib/psych/visitors/yast_builder.rb16
-rw-r--r--test/helper.rb2
-rw-r--r--test/yaml/test_array.rb17
-rw-r--r--test/yaml/test_class.rb17
-rw-r--r--test/yaml/test_exception.rb45
-rw-r--r--test/yaml/test_hash.rb17
-rw-r--r--test/yaml/test_string.rb5
-rw-r--r--test/yaml/test_symbol.rb21
-rw-r--r--test/yaml/test_yaml.rb2
17 files changed, 213 insertions, 30 deletions
diff --git a/Rakefile b/Rakefile
index 7068c40..d5fa904 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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 )