[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / test / psych / test_hash.rb
blob31eba8580bb96febdd239c18b86bca97c36dd1ef
1 # frozen_string_literal: true
2 require_relative 'helper'
4 module Psych
5   class TestHash < TestCase
6     class X < Hash
7     end
9     class HashWithIvar < Hash
10       def initialize
11         @keys = []
12         super
13       end
15       def []=(k, v)
16         @keys << k
17         super(k, v)
18       end
19     end
21     class HashWithCustomInit < Hash
22       attr_reader :obj
23       def initialize(obj)
24         @obj = obj
25       end
26     end
28     class HashWithCustomInitNoIvar < Hash
29       def initialize(obj)
30         # *shrug*
31       end
32     end
34     def setup
35       super
36       @hash = { :a => 'b' }
37     end
39     def test_hash_with_ivar
40       t1 = HashWithIvar.new
41       t1[:foo] = :bar
42       t2 = Psych.unsafe_load(Psych.dump(t1))
43       assert_equal t1, t2
44       assert_cycle t1
45     end
47     def test_referenced_hash_with_ivar
48       a = [1,2,3,4,5]
49       t1 = [HashWithCustomInit.new(a)]
50       t1 << t1.first
51       assert_cycle t1
52     end
54     def test_custom_initialized
55       a = [1,2,3,4,5]
56       t1 = HashWithCustomInit.new(a)
57       t2 = Psych.unsafe_load(Psych.dump(t1))
58       assert_equal t1, t2
59       assert_cycle t1
60     end
62     def test_custom_initialize_no_ivar
63       t1 = HashWithCustomInitNoIvar.new(nil)
64       t2 = Psych.unsafe_load(Psych.dump(t1))
65       assert_equal t1, t2
66       assert_cycle t1
67     end
69     def test_hash_subclass_with_ivars
70       x = X.new
71       x[:a] = 'b'
72       x.instance_variable_set :@foo, 'bar'
73       dup = Psych.unsafe_load Psych.dump x
74       assert_cycle x
75       assert_equal 'bar', dup.instance_variable_get(:@foo)
76       assert_equal X, dup.class
77     end
79     def test_load_with_class_syck_compatibility
80       hash = Psych.unsafe_load "--- !ruby/object:Hash\n:user_id: 7\n:username: Lucas\n"
81       assert_equal({ user_id: 7, username: 'Lucas'}, hash)
82     end
84     def test_empty_subclass
85       assert_match "!ruby/hash:#{X}", Psych.dump(X.new)
86       x = Psych.unsafe_load Psych.dump X.new
87       assert_equal X, x.class
88     end
90     def test_map
91       x = Psych.unsafe_load "--- !map:#{X} { }\n"
92       assert_equal X, x.class
93     end
95     def test_self_referential
96       @hash['self'] = @hash
97       assert_cycle(@hash)
98     end
100     def test_cycles
101       assert_cycle(@hash)
102     end
104     def test_ref_append
105       hash = Psych.unsafe_load(<<~eoyml)
106         ---
107         foo: &foo
108           hello: world
109         bar:
110           <<: *foo
111       eoyml
112       assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
113     end
115     def test_anchor_reuse
116       hash = Psych.unsafe_load(<<~eoyml)
117         ---
118         foo: &foo
119           hello: world
120         bar: *foo
121       eoyml
122       assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
123       assert_same(hash.fetch("foo"), hash.fetch("bar"))
124     end
126     def test_raises_if_anchor_not_defined
127       assert_raise(Psych::AnchorNotDefined) do
128         Psych.unsafe_load(<<~eoyml)
129           ---
130           foo: &foo
131             hello: world
132           bar: *not_foo
133         eoyml
134       end
135     end
137     def test_recursive_hash
138       h = { }
139       h["recursive_reference"] = h
141       loaded = Psych.load(Psych.dump(h), aliases: true)
143       assert_same loaded, loaded.fetch("recursive_reference")
144     end
146     def test_recursive_hash_uses_alias
147       h = { }
148       h["recursive_reference"] = h
150       assert_raise(AliasesNotEnabled) do
151         Psych.load(Psych.dump(h), aliases: false)
152       end
153     end
155     def test_key_deduplication
156       unless String.method_defined?(:-@) && (-("a" * 20)).equal?((-("a" * 20)))
157         pend "This Ruby implementation doesn't support string deduplication"
158       end
160       hashes = Psych.load(<<~eoyml)
161         ---
162         - unique_identifier: 1
163         - unique_identifier: 2
164       eoyml
166       assert_same hashes[0].keys.first, hashes[1].keys.first
167     end
168   end