From a5f05e7ee9823fb04dea5219cafce5c5d879e305 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Sun, 11 Apr 2010 00:37:42 +0000 Subject: * test/syck/*: Moved test/yaml to test/syck since it's actually testing the syck YAML engine. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27292 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/syck/test_array.rb | 18 + test/syck/test_boolean.rb | 37 ++ test/syck/test_class.rb | 18 + test/syck/test_engine_manager.rb | 3 + test/syck/test_exception.rb | 46 ++ test/syck/test_hash.rb | 29 + test/syck/test_null.rb | 20 + test/syck/test_omap.rb | 56 ++ test/syck/test_set.rb | 31 + test/syck/test_string.rb | 45 ++ test/syck/test_struct.rb | 33 + test/syck/test_symbol.rb | 22 + test/syck/test_yaml.rb | 1329 +++++++++++++++++++++++++++++++++++++ test/syck/test_yaml_properties.rb | 64 ++ test/syck/test_yamlstore.rb | 76 +++ 15 files changed, 1827 insertions(+) create mode 100644 test/syck/test_array.rb create mode 100644 test/syck/test_boolean.rb create mode 100644 test/syck/test_class.rb create mode 100644 test/syck/test_engine_manager.rb create mode 100644 test/syck/test_exception.rb create mode 100644 test/syck/test_hash.rb create mode 100644 test/syck/test_null.rb create mode 100644 test/syck/test_omap.rb create mode 100644 test/syck/test_set.rb create mode 100644 test/syck/test_string.rb create mode 100644 test/syck/test_struct.rb create mode 100644 test/syck/test_symbol.rb create mode 100644 test/syck/test_yaml.rb create mode 100644 test/syck/test_yaml_properties.rb create mode 100644 test/syck/test_yamlstore.rb (limited to 'test/syck') diff --git a/test/syck/test_array.rb b/test/syck/test_array.rb new file mode 100644 index 0000000000..7ffa1b404f --- /dev/null +++ b/test/syck/test_array.rb @@ -0,0 +1,18 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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/syck/test_boolean.rb b/test/syck/test_boolean.rb new file mode 100644 index 0000000000..615b0b0c8f --- /dev/null +++ b/test/syck/test_boolean.rb @@ -0,0 +1,37 @@ +require 'test/unit' +require 'yaml' + +module Syck + ### + # Test booleans from YAML spec: + # http://yaml.org/type/bool.html + class TestBoolean < Test::Unit::TestCase + %w{ yes Yes YES true True TRUE on On ON }.each do |truth| + define_method(:"test_#{truth}") do + assert_equal true, YAML.load("--- #{truth}") + end + end + + %w{ no No NO false False FALSE off Off OFF }.each do |truth| + define_method(:"test_#{truth}") do + assert_equal false, YAML.load("--- #{truth}") + end + end + + ### + # YAML spec says "y" and "Y" may be used as true, but Syck treats them + # as literal strings + def test_y + assert_equal "y", YAML.load("--- y") + assert_equal "Y", YAML.load("--- Y") + end + + ### + # YAML spec says "n" and "N" may be used as false, but Syck treats them + # as literal strings + def test_n + assert_equal "n", YAML.load("--- n") + assert_equal "N", YAML.load("--- N") + end + end +end diff --git a/test/syck/test_class.rb b/test/syck/test_class.rb new file mode 100644 index 0000000000..803a1f14b4 --- /dev/null +++ b/test/syck/test_class.rb @@ -0,0 +1,18 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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/syck/test_engine_manager.rb b/test/syck/test_engine_manager.rb new file mode 100644 index 0000000000..529fc49d38 --- /dev/null +++ b/test/syck/test_engine_manager.rb @@ -0,0 +1,3 @@ +require 'test/unit' +require 'yaml' + diff --git a/test/syck/test_exception.rb b/test/syck/test_exception.rb new file mode 100644 index 0000000000..b85cabcd6b --- /dev/null +++ b/test/syck/test_exception.rb @@ -0,0 +1,46 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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/syck/test_hash.rb b/test/syck/test_hash.rb new file mode 100644 index 0000000000..0690f77ec3 --- /dev/null +++ b/test/syck/test_hash.rb @@ -0,0 +1,29 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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 + + def test_ref_append + hash = YAML.load(<<-eoyml) +--- +foo: &foo + hello: world +bar: + <<: *foo +eoyml + assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash) + end + end +end diff --git a/test/syck/test_null.rb b/test/syck/test_null.rb new file mode 100644 index 0000000000..b38bf50fba --- /dev/null +++ b/test/syck/test_null.rb @@ -0,0 +1,20 @@ +require 'test/unit' +require 'yaml' + +module Syck + ### + # Test null from YAML spec: + # http://yaml.org/type/null.html + class TestNull < Test::Unit::TestCase + def test_null_list + assert_equal [nil] * 5, YAML.load(<<-eoyml) +--- +- ~ +- null +- +- Null +- NULL + eoyml + end + end +end diff --git a/test/syck/test_omap.rb b/test/syck/test_omap.rb new file mode 100644 index 0000000000..8a2d7075b6 --- /dev/null +++ b/test/syck/test_omap.rb @@ -0,0 +1,56 @@ +require 'test/unit' +require 'yaml' + +module Syck + class TestOmap < Test::Unit::TestCase + def test_keys + map = YAML::Omap.new + map['foo'] = 'bar' + assert_equal 'bar', map['foo'] + end + + def test_order + map = YAML::Omap.new + map['a'] = 'b' + map['b'] = 'c' + assert_equal [%w{a b}, %w{b c}], map.to_a + end + + def test_square + list = [["a", "b"], ["b", "c"]] + map = YAML::Omap[*list.flatten] + assert_equal list, map.to_a + assert_equal 'b', map['a'] + assert_equal 'c', map['b'] + end + + def test_to_yaml + map = YAML::Omap['a', 'b', 'c', 'd'] + yaml = map.to_yaml + assert_match('!omap', yaml) + assert_match('- a: b', yaml) + assert_match('- c: d', yaml) + end + + def test_round_trip + list = [["a", "b"], ["b", "c"]] + map = YAML::Omap[*list.flatten] + loaded = YAML.load(YAML.dump(map)) + + assert_equal map, loaded + assert_equal list, loaded.to_a + end + + ### + # FIXME: Syck should also support !!omap as shorthand + def test_load + list = [["a", "b"], ["c", "d"]] + map = YAML.load(<<-eoyml) +--- !omap +- a: b +- c: d + eoyml + assert_equal list, map.to_a + end + end +end diff --git a/test/syck/test_set.rb b/test/syck/test_set.rb new file mode 100644 index 0000000000..d58f92e53f --- /dev/null +++ b/test/syck/test_set.rb @@ -0,0 +1,31 @@ +require 'test/unit' +require 'yaml' + +module Syck + class TestSet < Test::Unit::TestCase + def setup + @set = YAML::Set.new + @set['foo'] = 'bar' + @set['bar'] = 'baz' + end + + def test_to_yaml + assert_match(/!set/, @set.to_yaml) + end + + def test_roundtrip + assert_equal(@set, YAML.load(YAML.dump(@set))) + end + + ### + # FIXME: Syck should also support !!set as shorthand + def test_load_from_yaml + loaded = YAML.load(<<-eoyml) +--- !set +foo: bar +bar: baz + eoyml + assert_equal(@set, loaded) + end + end +end diff --git a/test/syck/test_string.rb b/test/syck/test_string.rb new file mode 100644 index 0000000000..3bac75964f --- /dev/null +++ b/test/syck/test_string.rb @@ -0,0 +1,45 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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 diff --git a/test/syck/test_struct.rb b/test/syck/test_struct.rb new file mode 100644 index 0000000000..cdd4814fd4 --- /dev/null +++ b/test/syck/test_struct.rb @@ -0,0 +1,33 @@ +require 'test/unit' +require 'yaml' + +class StructWithIvar < Struct.new(:foo) + attr_reader :bar + def initialize *args + super + @bar = 'hello' + end +end + +module Syck + class TestStruct < MiniTest::Unit::TestCase + def test_roundtrip + thing = StructWithIvar.new('bar') + struct = YAML.load(YAML.dump(thing)) + + assert_equal 'hello', struct.bar + assert_equal 'bar', struct.foo + end + + def test_load + obj = YAML.load(<<-eoyml) +--- !ruby/struct:StructWithIvar +foo: bar +@bar: hello + eoyml + + assert_equal 'hello', obj.bar + assert_equal 'bar', obj.foo + end + end +end diff --git a/test/syck/test_symbol.rb b/test/syck/test_symbol.rb new file mode 100644 index 0000000000..39ffa8bb03 --- /dev/null +++ b/test/syck/test_symbol.rb @@ -0,0 +1,22 @@ +require 'test/unit' +require 'yaml' + +module Syck + 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/syck/test_yaml.rb b/test/syck/test_yaml.rb new file mode 100644 index 0000000000..ece1b768e3 --- /dev/null +++ b/test/syck/test_yaml.rb @@ -0,0 +1,1329 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- +# vim:sw=4:ts=4 +# $Id$ +# +require 'test/unit' +require 'yaml' +require 'syck/ypath' + +# [ruby-core:01946] +module YAML_Tests + StructTest = Struct::new( :c ) +end + +module Syck +class YAML_Unit_Tests < Test::Unit::TestCase + # + # Convert between YAML and the object to verify correct parsing and + # emitting + # + def assert_to_yaml( obj, yaml ) + assert_equal( obj, YAML::load( yaml ) ) + assert_equal( obj, YAML::parse( yaml ).transform ) + assert_equal( obj, YAML::load( obj.to_yaml ) ) + assert_equal( obj, YAML::parse( obj.to_yaml ).transform ) + assert_equal( obj, YAML::load( + obj.to_yaml( :UseVersion => true, :UseHeader => true, :SortKeys => true ) + ) ) + end + + # + # Test parser only + # + def assert_parse_only( obj, yaml ) + assert_equal( obj, YAML::load( yaml ) ) + assert_equal( obj, YAML::parse( yaml ).transform ) + end + + def assert_cycle( obj ) + assert_equal( obj, YAML::load( obj.to_yaml ) ) + end + + def assert_path_segments( path, segments ) + YAML::YPath.each_path( path ) { |choice| + assert_equal( choice.segments, segments.shift ) + } + assert_equal( segments.length, 0, "Some segments leftover: #{ segments.inspect }" ) + end + + # + # Make a time with the time zone + # + def mktime( year, mon, day, hour, min, sec, usec, zone = "Z" ) + usec = Rational(usec.to_s) * 1000000 + val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec ) + if zone != "Z" + hour = zone[0,3].to_i * 3600 + min = zone[3,2].to_i * 60 + ofs = (hour + min) + val = Time.at( val.tv_sec - ofs, val.tv_nsec / 1000.0 ) + end + return val + end + + # + # Tests modified from 00basic.t in YAML.pm + # + def test_basic_map + # Simple map + assert_parse_only( + { 'one' => 'foo', 'three' => 'baz', 'two' => 'bar' }, < 'simple string', 2 => 42, 3 => '1 Single Quoted String', + 4 => 'YAML\'s Double "Quoted" String', 5 => "A block\n with several\n lines.\n", + 6 => "A \"chomped\" block", 7 => "A folded\n string\n", 8 => ": started string" }, + < + A + folded + string +8: ": started string" +EOY + ) + end + + # + # Test the specification examples + # - Many examples have been changes because of whitespace problems that + # caused the two to be inequivalent, or keys to be sorted wrong + # + + def test_spec_simple_implicit_sequence + # Simple implicit sequence + assert_to_yaml( + [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ], < 65, 'avg' => 0.278, 'rbi' => 147 }, < + [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ], + 'national' => + [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] }, < 'Mark McGwire', 'hr' => 65, 'avg' => 0.278}, + {'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288} + ], < + { 'hr' => 65, 'avg' => 0.278 }, + 'Sammy Sosa' => + { 'hr' => 63, 'avg' => 0.288 } + }, < [ 'Mark McGwire', 'Sammy Sosa' ], + 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] }, < + [ 'Mark McGwire', 'Sammy Sosa' ], + 'rbi' => + [ 'Sammy Sosa', 'Ken Griffey' ] }, <"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}], <["fareref", "currency", "departure", "arrival"], "FARES"=>[{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}]}, < [ Date.new( 2001, 7, 23 ) ], + [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] }, < + [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), + Date.new( 2001, 8, 14 ) ], + [ 'Detroit Tigers', 'Chicago Cubs' ] => + [ Date.new( 2001, 7, 23 ) ] + }, < 34843, 'date' => Date.new( 2001, 1, 23 ), + 'bill-to' => 'Chris Dumars', 'product' => + [ { 'item' => 'Super Hoop', 'quantity' => 1 }, + { 'item' => 'Basketball', 'quantity' => 4 }, + { 'item' => 'Big Shoes', 'quantity' => 1 } ] }, < nil }, + [ { 'five' => [ 'six' ] } ], + [ 'seven' ] + ], + [ 'eight', 'nine' ] +], < + Mark McGwire\'s + year was crippled + by a knee injury. +EOY + ) + end + + def test_spec_preserve_indent + # Preserve indented spaces + assert_parse_only( + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n", < + Sammy Sosa completed another + fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! +EOY + ) + end + + def test_spec_indentation_determines_scope + assert_parse_only( + { 'name' => 'Mark McGwire', 'accomplishment' => "Mark set a major league home run record in 1998.\n", + 'stats' => "65 Home Runs\n0.278 Batting Average\n" }, < + Mark set a major league + home run record in 1998. +stats: | + 65 Home Runs + 0.278 Batting Average +EOY + ) + end + + def test_spec_multiline_scalars + # Multiline flow scalars + assert_parse_only( + { 'plain' => 'This unquoted scalar spans many lines.', + 'quoted' => "So does this quoted scalar.\n" }, < 12345, 'decimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex }, < 685230, 'decimal' => 685230, 'octal' => 02472256, 'hexadecimal' => 0x0A74AE, 'sexagesimal' => 685230 }, < 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15, + 'negative infinity' => -1.0/0.0 }, < nil, true => true, false => false, 'string' => '12345' }, < 'Chris', 'family' => 'Dumars', 'address' => + { 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', + 'state' => 'MI', 'postal' => 48046 } } + assert_parse_only( + { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), + 'bill-to' => id001, 'ship-to' => id001, 'product' => + [ { 'sku' => 'BL394D', 'quantity' => 4, + 'description' => 'Basketball', 'price' => 450.00 }, + { 'sku' => 'BL4438H', 'quantity' => 1, + 'description' => 'Super Hoop', 'price' => 2392.00 } ], + 'tax' => 251.42, 'total' => 4443.52, + 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" }, < + Late afternoon is best. + Backup contact is Nancy + Billsmer @ 338-4338. +EOY + ) + end + + def test_spec_log_file + doc_ct = 0 + YAML::load_documents( < + This is an error message + for the log file +--- +Time: 2001-11-23 15:02:31 -05:00 +User: ed +Warning: > + A slightly different error + message. +--- +Date: 2001-11-23 15:03:17 -05:00 +User: ed +Fatal: > + Unknown variable "bar" +Stack: + - file: TopClass.py + line: 23 + code: | + x = MoreObject("345\\n") + - file: MoreClass.py + line: 58 + code: |- + foo = bar +EOY + ) { |doc| + case doc_ct + when 0 + assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } ) + when 1 + assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } ) + when 2 + assert_equal( doc, { 'Date' => mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ), + 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n", + 'Stack' => [ + { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" }, + { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } ) + end + doc_ct += 1 + } + assert_equal( doc_ct, 3 ) + end + + def test_spec_root_fold + y = YAML::load( < +This YAML stream contains a single text value. +The next stream is a log file - a sequence of +log entries. Adding an entry to the log is a +simple matter of appending it at the end. +EOY + ) + assert_equal( y, "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" ) + end + + def test_spec_root_mapping + y = YAML::load( < 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } ) + end + + def test_spec_oneline_docs + doc_ct = 0 + YAML::load_documents( < { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }, <"contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"}, < 12, 'also int' => 12, 'string' => '12' }, < 8, 'color' => 'black' } ) + when 1 + assert_equal( doc['bearing'].type_id, 'x-private:ball' ) + assert_equal( doc['bearing'].transform.value, { 'material' => 'steel' } ) + end + doc_ct += 1 + } + assert_equal( doc_ct, 2 ) + end + + def test_spec_url_escaping + YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val| + "ONE: #{val}" + } + YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val| + "TWO: #{val}" + } + assert_parse_only( + { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value' ] }, < 'This scalar has an anchor.', 'override' => a001, 'alias' => a001 }, < + The alias node below is a + repeated use of this value. +alias : *A001 +EOY + ) + end + + def test_spec_explicit_families + YAML.add_domain_type( "somewhere.com,2002", 'type' ) { |type, val| + "SOMEWHERE: #{val}" + } + assert_parse_only( + { 'not-date' => '2002-04-28', 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", 'hmm' => "SOMEWHERE: family above is short for\nhttp://somewhere.com/type\n" }, <7, "center"=>{"x"=>73, "y"=>129}, "TYPE"=>"Shape: graph/circle"}, {"finish"=>{"x"=>89, "y"=>102}, "TYPE"=>"Shape: graph/line", "start"=>{"x"=>73, "y"=>129}}, {"TYPE"=>"Shape: graph/text", "value"=>"Pretty vector drawing.", "start"=>{"x"=>73, "y"=>129}, "color"=>16772795}, "Shape Container"]], < [], 'in-line' => [ 'one', 'two', 'three', 'four', 'five' ], + 'nested' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ], + "A multi-line sequence entry\n", 'Sixth item in top sequence' ] }, < + A multi-line + sequence entry + - Sixth item in top sequence +EOY + ) + end + + def test_spec_builtin_map + # Assortment of mappings + assert_parse_only( + { 'empty' => {}, 'in-line' => { 'one' => 1, 'two' => 2 }, + 'spanning' => { 'one' => 1, 'two' => 2 }, + 'nested' => { 'first' => 'First entry', 'second' => + { 'key' => 'Subordinate mapping' }, 'third' => + [ 'Subordinate sequence', {}, 'Previous mapping is empty.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' }, + 'The previous entry is equal to the following one.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ], + 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.', + "\a" => 'This key had to be escaped.', + "This is a multi-line folded key\n" => "Whose value is also multi-line.\n", + [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }, < + ? + : This key had to be protected. + "\\a" : This key had to be escaped. + ? > + This is a + multi-line + folded key + : > + Whose value is + also multi-line. + ? + - This key + - is a sequence + : + - With a sequence value. +# The following parses correctly, +# but Ruby 1.6.* fails the comparison! +# ? +# This: key +# is a: mapping +# : +# with a: mapping value. +EOY + ) + end + + def test_spec_builtin_literal_blocks + # Assortment of literal scalar blocks + assert_parse_only( + {"both are equal to"=>" This has no newline.", "is equal to"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n", "also written as"=>" This has no newline.", "indented and chomped"=>" This has no newline.", "empty"=>"", "literal"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n"}, < str1, 'same as "clipped" above' => str1, + 'stripped' => str2, 'same as "stripped" above' => str2, + 'kept' => str3, 'same as "kept" above' => str3 }, <"a single quote ' must be escaped.", "second"=>"! : \\ etc. can be used freely.", "is same as"=>"this contains six spaces\nand one line break", "empty"=>"", "span"=>"this contains six spaces\nand one line break"}, <"this contains four spaces", "third"=>"a \" or a \\ must be escaped.", "second"=>"! : etc. can be used freely.", "empty"=>"", "fourth"=>"this value ends with an LF.\n", "span"=>"this contains four spaces"}, < mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ), + "canonical" => mktime( 2001, 12, 15, 2, 59, 43, ".10" ), + "date (noon UTC)" => Date.new( 2002, 12, 14), + "valid iso8601" => mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ) }, < arrow_gif, 'base64' => arrow_gif, + 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" }, < /George McFly/i }, < 2, :UseVersion => 0 ) + y.add( + { 'hi' => 'hello', 'map' => + { 'good' => 'two' }, + 'time' => Time.now, + 'try' => /^po(.*)$/, + 'bye' => 'goodbye' + } + ) + y.add( { 'po' => 'nil', 'oper' => 90 } ) + y.add( { 'hi' => 'wow!', 'bye' => 'wow!' } ) + y.add( { [ 'Red Socks', 'Boston' ] => [ 'One', 'Two', 'Three' ] } ) + y.add( [ true, false, false ] ) + end + + # + # Test YPath choices parsing + # + def test_ypath_parsing + assert_path_segments( "/*/((one|three)/name|place)|//place", + [ ["*", "one", "name"], + ["*", "three", "name"], + ["*", "place"], + ["/", "place"] ] + ) + end + + # + # Tests from Tanaka Akira on [ruby-core] + # + def test_akira + + # Commas in plain scalars [ruby-core:1066] + assert_to_yaml( + {"A"=>"A,","B"=>"B"}, <2, "2"=>3}, <"b"}] * 2, <"b", "c"=>"d"} } + # YAML::load( a.to_yaml ) + + end + + # + # Test Time.now cycle + # + def test_time_now_cycle + # + # From Minero Aoki [ruby-core:2305] + # + require 'yaml' + t = Time.now + t = Time.at(t.tv_sec, t.tv_usec) + 5.times do + assert_cycle(t) + end + end + + # + # Test Range cycle + # + def test_range_cycle + # + # From Minero Aoki [ruby-core:02306] + # + assert_cycle("a".."z") + + # + # From Nobu Nakada [ruby-core:02311] + # + assert_cycle(0..1) + assert_cycle(1.0e20 .. 2.0e20) + assert_cycle("0".."1") + assert_cycle(".."..."...") + assert_cycle(".rb"..".pl") + assert_cycle(".rb"...".pl") + assert_cycle('"'...".") + assert_cycle("'"...".") + end + + # + # Circular references + # + def test_circular_references + a = []; a[0] = a; a[1] = a + inspect_str = "[[...], [...]]" + assert_equal( inspect_str, YAML::load( a.to_yaml ).inspect ) + end + + # + # Test Symbol cycle + # + def test_symbol_cycle + # + # From Aaron Schrab [ruby-Bugs:2535] + # + assert_cycle(:"^foo") + end + + # + # Test Numeric cycle + # + class NumericTest < Numeric + def initialize(value) + @value = value + end + def ==(other) + @value == other.instance_eval{ @value } + end + end + def test_numeric_cycle + assert_cycle(1) # Fixnum + assert_cycle(111111111111111111111111111111111) # Bignum + assert_cycle(NumericTest.new(3)) # Subclass of Numeric + end + + # + # Test empty map/seq in map cycle + # + def test_empty_map_key + # + # empty seq as key + # + o = YAML.load({[]=>""}.to_yaml) + assert_equal(Hash, o.class) + assert_equal([[]], o.keys) + + # + # empty map as key + # + o = YAML.load({{}=>""}.to_yaml) + assert_equal(Hash, o.class) + assert_equal([{}], o.keys) + end + + # + # contributed by riley lynch [ruby-Bugs-8548] + # + def test_object_id_collision + omap = YAML::Omap.new + 1000.times { |i| omap["key_#{i}"] = { "value" => i } } + raise "id collision in ordered map" if omap.to_yaml =~ /id\d+/ + end + + def test_date_out_of_range + assert_nothing_raised{YAML::load('1900-01-01T00:00:00+00:00')} + end + + def test_normal_exit + YAML.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n") + # '[ruby-core:13735]' + end +end +end + +if $0 == __FILE__ + suite = Test::Unit::TestSuite.new('YAML') + ObjectSpace.each_object(Class) do |klass| + suite << klass.suite if (Test::Unit::TestCase > klass) + end + require 'test/unit/ui/console/testrunner' + Test::Unit::UI::Console::TestRunner.run(suite).passed? +end diff --git a/test/syck/test_yaml_properties.rb b/test/syck/test_yaml_properties.rb new file mode 100644 index 0000000000..2df2e1cf76 --- /dev/null +++ b/test/syck/test_yaml_properties.rb @@ -0,0 +1,64 @@ +require 'test/unit' +require 'yaml' + +module Syck + class TestYamlProperties < Test::Unit::TestCase + class Foo + attr_reader :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 = YAML.load(YAML.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 = YAML.load(YAML.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 = YAML.load YAML.dump string + assert_equal 'delicious', v.instance_variable_get(:@tastes) + end + + def test_string_load + str = YAML.load("--- !str \nstr: okonomiyaki\n:@tastes: delicious\n") + assert_equal 'okonomiyaki', str + assert_equal 'delicious', str.instance_variable_get(:@tastes) + end + end +end diff --git a/test/syck/test_yamlstore.rb b/test/syck/test_yamlstore.rb new file mode 100644 index 0000000000..e78a7e4ecb --- /dev/null +++ b/test/syck/test_yamlstore.rb @@ -0,0 +1,76 @@ +require 'test/unit' +require 'syck/store' + +module Syck + class YAMLStoreTest < Test::Unit::TestCase + def setup + @yamlstore_file = "yamlstore.tmp.#{Process.pid}" + @yamlstore = YAML::Store.new(@yamlstore_file) + end + + def teardown + File.unlink(@yamlstore_file) rescue nil + end + + def test_opening_new_file_in_readonly_mode_should_result_in_empty_values + @yamlstore.transaction(true) do + assert_nil @yamlstore[:foo] + assert_nil @yamlstore[:bar] + end + end + + def test_opening_new_file_in_readwrite_mode_should_result_in_empty_values + @yamlstore.transaction do + assert_nil @yamlstore[:foo] + assert_nil @yamlstore[:bar] + end + end + + def test_data_should_be_loaded_correctly_when_in_readonly_mode + @yamlstore.transaction do + @yamlstore[:foo] = "bar" + end + @yamlstore.transaction(true) do + assert_equal "bar", @yamlstore[:foo] + end + end + + def test_data_should_be_loaded_correctly_when_in_readwrite_mode + @yamlstore.transaction do + @yamlstore[:foo] = "bar" + end + @yamlstore.transaction do + assert_equal "bar", @yamlstore[:foo] + end + end + + def test_changes_after_commit_are_discarded + @yamlstore.transaction do + @yamlstore[:foo] = "bar" + @yamlstore.commit + @yamlstore[:foo] = "baz" + end + @yamlstore.transaction(true) do + assert_equal "bar", @yamlstore[:foo] + end + end + + def test_changes_are_not_written_on_abort + @yamlstore.transaction do + @yamlstore[:foo] = "bar" + @yamlstore.abort + end + @yamlstore.transaction(true) do + assert_nil @yamlstore[:foo] + end + end + + def test_writing_inside_readonly_transaction_raises_error + assert_raise(PStore::Error) do + @yamlstore.transaction(true) do + @yamlstore[:foo] = "bar" + end + end + end + end +end -- cgit v1.2.3