Skip to content

Commit

Permalink
integrating some yaml tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tenderlove committed Nov 17, 2009
1 parent 59f905b commit bffb39d
Show file tree
Hide file tree
Showing 17 changed files with 213 additions and 30 deletions.
8 changes: 8 additions & 0 deletions Rakefile
@@ -1,5 +1,13 @@
# -*- ruby -*-

$: << File.join(File.dirname(__FILE__), 'lib')

begin
require 'psych'
$" << "yaml.rb"
rescue LoadError
end

require 'rubygems'
require 'hoe'

Expand Down
2 changes: 1 addition & 1 deletion ext/psych/emitter.c
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions ext/psych/psych.c
Expand Up @@ -25,4 +25,5 @@ void Init_psych()

Init_psych_parser();
Init_psych_emitter();
Init_psych_to_ruby();
}
22 changes: 22 additions & 0 deletions 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);
}
8 changes: 8 additions & 0 deletions 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
2 changes: 2 additions & 0 deletions lib/psych/ruby.rb
Expand Up @@ -2,6 +2,8 @@
require 'rational'
require 'date'

YAML = Psych

[
Object, String, Class, Hash, Array, NilClass, Float, FalseClass, TrueClass,
Range, Complex, Rational, Date, Time, Regexp, Exception, Struct
Expand Down
8 changes: 6 additions & 2 deletions lib/psych/scalar_scanner.rb
Expand Up @@ -36,8 +36,12 @@ def tokenize
[: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|
Expand Down
50 changes: 30 additions & 20 deletions lib/psych/visitors/to_ruby.rb
Expand Up @@ -84,26 +84,11 @@ def visit_Psych_Nodes_Mapping o
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
Expand All @@ -122,9 +107,13 @@ def visit_Psych_Nodes_Mapping o
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 }]
Expand Down Expand Up @@ -166,6 +155,27 @@ def visit_Psych_Nodes_Alias o
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

Expand Down
16 changes: 15 additions & 1 deletion lib/psych/visitors/yast_builder.rb
Expand Up @@ -62,10 +62,24 @@ def visit_Struct o
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

Expand Down
2 changes: 2 additions & 0 deletions test/helper.rb
@@ -0,0 +1,2 @@
require 'test/unit'
require 'psych'
17 changes: 17 additions & 0 deletions 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
17 changes: 17 additions & 0 deletions 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
45 changes: 45 additions & 0 deletions 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
17 changes: 17 additions & 0 deletions 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
5 changes: 1 addition & 4 deletions 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
Expand Down
21 changes: 21 additions & 0 deletions 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
2 changes: 0 additions & 2 deletions test/yaml/test_yaml.rb
Expand Up @@ -6,8 +6,6 @@
require 'rational'
require 'psych'

YAML = Psych

# [ruby-core:01946]
module YAML_Tests
StructTest = Struct::new( :c )
Expand Down

0 comments on commit bffb39d

Please sign in to comment.