Skip to content

Commit

Permalink
testing strings along with binary strings
Browse files Browse the repository at this point in the history
  • Loading branch information
tenderlove committed Nov 14, 2009
1 parent ff397b1 commit 59f905b
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Manifest.txt
Expand Up @@ -32,10 +32,12 @@ lib/psych/visitors/visitor.rb
lib/psych/visitors/yast_builder.rb
test/psych/test_parser.rb
test/psych/test_serialize_subclasses.rb
test/psych/test_to_yaml_properties.rb
test/psych/test_tree_builder.rb
test/test_psych.rb
test/test_scalar_scanner.rb
test/visitors/test_emitter.rb
test/visitors/test_to_ruby.rb
test/visitors/test_yast_builder.rb
test/yaml/test_string.rb
test/yaml/test_yaml.rb
6 changes: 4 additions & 2 deletions lib/psych.rb
Expand Up @@ -42,8 +42,10 @@ def self.yaml_ast yaml

###
# Dump object +o+ to a YAML string
def self.dump o
o.to_yaml
def self.dump o, options = {}
visitor = Psych::Visitors::YASTBuilder.new options
visitor.accept o
visitor.tree.to_yaml
end

###
Expand Down
4 changes: 1 addition & 3 deletions lib/psych/ruby.rb
Expand Up @@ -13,8 +13,6 @@ class Object
include Psych::Visitable

def to_yaml options = {}
visitor = Psych::Visitors::YASTBuilder.new options
visitor.accept self
visitor.tree.to_yaml
Psych.dump self, options
end
end
8 changes: 8 additions & 0 deletions lib/psych/visitors/to_ruby.rb
Expand Up @@ -75,6 +75,14 @@ def visit_Psych_Nodes_Sequence o

def visit_Psych_Nodes_Mapping o
case o.tag
when '!str', 'tag:yaml.org,2002:str'
members = Hash[*o.children.map { |c| accept c }]
string = members.delete 'str'

members.each do |k,v|
string.instance_variable_set k, v
end
string
when /!ruby\/struct:?(.*)?$/
klassname = $1
members = o.children.map { |c| accept c }
Expand Down
56 changes: 51 additions & 5 deletions lib/psych/visitors/yast_builder.rb
Expand Up @@ -26,7 +26,13 @@ def visit_Object o
klass = o.class == Object ? nil : o.class.name
tag = ['!ruby/object', klass].compact.join(':')
@stack.push append Nodes::Mapping.new(nil, tag, false)
o.instance_variables.each do |iv|
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
Expand All @@ -41,7 +47,14 @@ def visit_Struct o
accept member
accept o[member]
end
o.instance_variables.each do |iv|

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
Expand Down Expand Up @@ -114,10 +127,43 @@ def visit_Float o
end

def visit_String o
quote = ScalarScanner.new(o).tokenize.first != :SCALAR
plain = false
quote = false

if o.index("\x00") || o.count("^ -~\t\r\n").fdiv(o.length) > 0.3
str = [o].pack('m').chomp
tag = '!binary'
else
str = o
tag = nil
quote = ScalarScanner.new(o).tokenize.first != :SCALAR
plain = !quote
end

scalar = Nodes::Scalar.new(o, nil, nil, !quote, quote)
@stack.last.children << scalar

if o.respond_to? :to_yaml_properties
ivars = o.to_yaml_properties
else
ivars = o.instance_variables
end

scalar = Nodes::Scalar.new str, nil, tag, plain, quote

if ivars.empty?
append scalar
else
mapping = append Nodes::Mapping.new(nil, '!str', false)

mapping.children << Nodes::Scalar.new('str')
mapping.children << scalar

@stack.push mapping
ivars.each do |iv|
mapping.children << Nodes::Scalar.new(":#{iv}")
accept o.instance_variable_get(iv)
end
@stack.pop
end
end

def visit_Class o
Expand Down
64 changes: 64 additions & 0 deletions test/psych/test_to_yaml_properties.rb
@@ -0,0 +1,64 @@
require 'minitest/autorun'
require 'psych'

module Psych
class TestToYamlProperties < MiniTest::Unit::TestCase
class Foo
attr_accessor :a, :b, :c
def initialize
@a = 1
@b = 2
@c = 3
end

def to_yaml_properties
[:@a, :@b]
end
end

def test_object_dump_yaml_properties
foo = Psych.load(Psych.dump(Foo.new))
assert_equal 1, foo.a
assert_equal 2, foo.b
assert_nil foo.c
end

class Bar < Struct.new(:foo, :bar)
attr_reader :baz
def initialize *args
super
@baz = 'hello'
end

def to_yaml_properties
[]
end
end

def test_struct_dump_yaml_properties
bar = Psych.load(Psych.dump(Bar.new('a', 'b')))
assert_equal 'a', bar.foo
assert_equal 'b', bar.bar
assert_nil bar.baz
end

def test_string_dump
string = "okonomiyaki"
class << string
def to_yaml_properties
[:@tastes]
end
end

string.instance_variable_set(:@tastes, 'delicious')
v = Psych.load Psych.dump string
assert_equal 'delicious', v.instance_variable_get(:@tastes)
end

def test_string_load_syck
str = Psych.load("--- !str \nstr: okonomiyaki\n:@tastes: delicious\n")
assert_equal 'okonomiyaki', str
assert_equal 'delicious', str.instance_variable_get(:@tastes)
end
end
end
15 changes: 15 additions & 0 deletions test/visitors/test_emitter.rb
Expand Up @@ -59,6 +59,21 @@ def test_scalar
assert_equal @io.string, s.to_yaml
end

def test_scalar_with_tag
s = Nodes::Stream.new
doc = Nodes::Document.new
scalar = Nodes::Scalar.new 'hello world', nil, '!str', false, false, 5

doc.children << scalar
s.children << doc

@visitor.accept s

assert_match(/str/, @io.string)
assert_match(/hello/, @io.string)
assert_equal @io.string, s.to_yaml
end

def test_sequence
s = Nodes::Stream.new
doc = Nodes::Document.new
Expand Down
47 changes: 47 additions & 0 deletions test/yaml/test_string.rb
@@ -0,0 +1,47 @@
require 'test/unit'
require 'psych'

YAML = Psych

module YAML
class TestString < Test::Unit::TestCase
def test_binary_string_null
string = "\x00"
yml = YAML.dump string
assert_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end

def test_binary_string
string = binary_string
yml = YAML.dump string
assert_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end

def test_non_binary_string
string = binary_string(0.29)
yml = YAML.dump string
refute_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end

def test_string_with_ivars
food = "is delicious"
ivar = "on rock and roll"
food.instance_variable_set(:@we_built_this_city, ivar)

str = YAML.load YAML.dump food
assert_equal ivar, food.instance_variable_get(:@we_built_this_city)
end

def binary_string percentage = 0.31, length = 100
string = ''
(percentage * length).to_i.times do |i|
string << "\b"
end
string << 'a' * (length - string.length)
string
end
end
end

0 comments on commit 59f905b

Please sign in to comment.