From 2025502c6a525ade0bd50d28877609eb2e020d30 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 11 Jan 2013 16:01:03 -0800 Subject: * ext/psych/lib/psych/visitors/to_ruby.rb: merge key values that contain something besides a hash should be left in tact. * test/psych/test_merge_keys.rb: test for change fixes #114 --- CHANGELOG.rdoc | 7 ++++++ lib/psych/visitors/to_ruby.rb | 26 +++++++++++++++++----- test/psych/test_merge_keys.rb | 51 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 98e3524..ec12e87 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,10 @@ +Sat Jan 12 08:58:47 2013 Aaron Patterson + + * ext/psych/lib/psych/visitors/to_ruby.rb: merge key values that + contain something besides a hash should be left in tact. + + * test/psych/test_merge_keys.rb: test for change + Thu Jan 10 04:23:07 2013 Aaron Patterson * ext/psych/lib/psych/scalar_scanner.rb: strip trailing dots from diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index 725f1f9..9ccf420 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -263,28 +263,42 @@ module Psych def revive_hash hash, o @st[o.anchor] = hash if o.anchor - o.children.each_slice(2) { |k,v| + o.children.each_slice(2) { |k,v| key = accept(k) + val = accept(v) if key == '<<' case v when Nodes::Alias - hash.merge! accept(v) + begin + hash.merge! val + rescue TypeError + hash[key] = val + end when Nodes::Sequence - accept(v).reverse_each do |value| - hash.merge! value + begin + h = {} + val.reverse_each do |value| + h.merge! value + end + hash.merge! h + rescue TypeError + hash[key] = val end else - hash[key] = accept(v) + hash[key] = val end else - hash[key] = accept(v) + hash[key] = val end } hash end + def merge_key hash, key, val + end + def revive klass, node s = klass.allocate @st[node.anchor] = s if node.anchor diff --git a/test/psych/test_merge_keys.rb b/test/psych/test_merge_keys.rb index bf5968f..c31f9b8 100644 --- a/test/psych/test_merge_keys.rb +++ b/test/psych/test_merge_keys.rb @@ -2,6 +2,57 @@ require 'psych/helper' module Psych class TestMergeKeys < TestCase + def test_merge_nil + yaml = <<-eoyml +defaults: &defaults +development: + <<: *defaults + eoyml + assert_equal({'<<' => nil }, Psych.load(yaml)['development']) + end + + def test_merge_array + yaml = <<-eoyml +foo: &hello +- 1 +baz: + <<: *hello + eoyml + assert_equal({'<<' => [1]}, Psych.load(yaml)['baz']) + end + + def test_merge_is_not_partial + yaml = <<-eoyml +default: &default + hello: world +foo: &hello +- 1 +baz: + <<: [*hello, *default] + eoyml + doc = Psych.load yaml + refute doc['baz'].key? 'hello' + assert_equal({'<<' => [[1], {"hello"=>"world"}]}, Psych.load(yaml)['baz']) + end + + def test_merge_seq_nil + yaml = <<-eoyml +foo: &hello +baz: + <<: [*hello] + eoyml + assert_equal({'<<' => [nil]}, Psych.load(yaml)['baz']) + end + + def test_bad_seq_merge + yaml = <<-eoyml +defaults: &defaults [1, 2, 3] +development: + <<: *defaults + eoyml + assert_equal({'<<' => [1,2,3]}, Psych.load(yaml)['development']) + end + def test_missing_merge_key yaml = <<-eoyml bar: -- cgit v1.2.3