1 # frozen_string_literal: true
3 require_relative 'helper'
6 require_relative '../lib/rack/headers'
9 class RackHeadersTest < Minitest::Spec
11 @h = Rack::Headers.new
12 @fh = Rack::Headers['AB'=>'1', 'cd'=>'2', '3'=>'4']
15 def test_public_interface
16 headers_methods = Rack::Headers.public_instance_methods.sort
17 hash_methods = Hash.public_instance_methods.sort
18 assert_empty(headers_methods - hash_methods)
19 assert_empty(hash_methods - headers_methods)
23 assert_equal Hash[], Rack::Headers[]
24 assert_equal Hash['a'=>'2'], Rack::Headers['A'=>'2']
25 assert_equal Hash['a'=>'2', 'b'=>'4'], Rack::Headers['A'=>'2', 'B'=>'4']
26 assert_equal Hash['a','2','b','4'], Rack::Headers['A','2','B','4']
27 assert_raises(ArgumentError){Rack::Headers['A']}
28 assert_raises(ArgumentError){Rack::Headers['A',2,'B']}
31 def test_default_values
32 h, ch = Hash.new, Rack::Headers.new
34 h, ch = Hash.new('1'), Rack::Headers.new('1')
36 assert_equal h['3'], ch['3']
37 h['a'], ch['A'] = ['2', '2']
38 assert_equal h['a'], ch['a']
39 h, ch = Hash.new{|h,k| k*2}, Rack::Headers.new{|h,k| k*2}
40 assert_equal h['3'], ch['3']
41 h['c'], ch['C'] = ['2', '2']
42 assert_equal h['c'], ch['c']
43 assert_raises(ArgumentError){Rack::Headers.new('1'){|hash,k| key}}
45 assert_nil @fh.default
46 assert_nil @fh.default_proc
48 assert_equal '3', Rack::Headers.new('3').default
49 assert_nil Rack::Headers.new('3').default_proc
50 assert_equal '3', Rack::Headers.new('3')['1']
53 assert_equal '4', @fh.default
54 assert_nil @fh.default_proc
55 assert_equal '4', @fh['55']
57 h = Rack::Headers.new('5')
58 assert_equal '5', h.default
59 assert_nil h.default_proc
60 assert_equal '5', h['55']
62 h = Rack::Headers.new{|hash, key| '1234'}
64 refute_equal nil, h.default_proc
65 assert_equal '1234', h['55']
67 h = Rack::Headers.new{|hash, key| hash[key] = '1234'; nil}
69 refute_equal nil, h.default_proc
71 assert_equal '1234', h['aC']
74 def test_store_and_retrieve
77 assert_equal '2', @h['a']
78 assert_equal '2', @h['A']
80 assert_equal '3', @h['a']
81 assert_equal '3', @h['A']
83 assert_equal '5', @h['ab']
84 assert_equal '5', @h['AB']
85 assert_equal '5', @h['aB']
86 assert_equal '5', @h['Ab']
88 assert_equal '8', @h['c']
89 assert_equal '8', @h['C']
93 assert_equal 3, @fh.length
95 assert_equal Hash[], @fh
96 assert_equal 0, @fh.length
100 assert_equal 3, @fh.length
101 assert_equal '1', @fh.delete('aB')
102 assert_equal 2, @fh.length
103 assert_nil @fh.delete('Ab')
104 assert_equal 2, @fh.length
107 def test_delete_if_and_reject
108 assert_equal 3, @fh.length
109 hash = @fh.reject{|key, value| key == 'ab' || key == 'cd'}
110 assert_equal 1, hash.length
111 assert_equal Hash['3'=>'4'], hash
112 assert_equal 3, @fh.length
113 hash = @fh.delete_if{|key, value| key == 'ab' || key == 'cd'}
114 assert_equal 1, hash.length
115 assert_equal Hash['3'=>'4'], hash
116 assert_equal 1, @fh.length
117 assert_equal Hash['3'=>'4'], @fh
118 assert_nil @fh.reject!{|key, value| key == 'ab' || key == 'cd'}
119 hash = @fh.reject!{|key, value| key == '3'}
120 assert_equal 0, hash.length
121 assert_equal Hash[], hash
122 assert_equal 0, @fh.length
123 assert_equal Hash[], @fh
126 def test_dup_and_clone
132 assert_equal Rack::Headers[], @h
133 assert_raises NoMethodError do h2.foo end
134 assert_equal 1, h3.foo
135 assert_equal '2', h2['a']
136 assert_equal '3', h3['b']
143 items = [['ab','1'], ['cd','2'], ['3','4']]
145 assert items.include?([k,v])
148 assert_equal [], items
155 keys = ['ab', 'cd', '3']
157 assert keys.include?(k)
161 assert_equal [], keys
168 values = ['1', '2', '4']
169 @fh.each_value do |v|
170 assert values.include?(v)
173 assert_equal [], values
182 assert_raises(ArgumentError){@h.fetch(1,2,3)}
183 assert_raises(ArgumentError){@h.fetch(1,2,3){4}}
184 assert_raises(IndexError){@h.fetch(1)}
186 assert_raises(IndexError){@h.fetch(1)}
188 assert_equal '8', @h.fetch('1')
189 assert_equal '3', @h.fetch(2, '3')
190 assert_equal '222', @h.fetch('2'){|k| k*3}
191 assert_equal '1', @fh.fetch('Ab')
192 assert_equal '2', @fh.fetch('cD', '3')
193 assert_equal '4', @fh.fetch("3", 3)
194 assert_equal '4', @fh.fetch("3"){|k| k*3}
195 assert_raises(IndexError){Rack::Headers.new{34}.fetch(1)}
199 %i'include? has_key? key? member?'.each do |meth|
200 assert !@h.send(meth,1)
201 assert @fh.send(meth,'Ab')
202 assert @fh.send(meth,'cD')
203 assert @fh.send(meth,'3')
204 assert @fh.send(meth,'ab')
205 assert @fh.send(meth,'CD')
206 assert @fh.send(meth,'3')
207 assert !@fh.send(meth,1)
212 %i'value? has_value?'.each do |meth|
213 assert !@h.send(meth,'1')
214 assert @fh.send(meth,'1')
215 assert @fh.send(meth,'2')
216 assert @fh.send(meth,'4')
217 assert !@fh.send(meth,'3')
222 %i'inspect to_s'.each do |meth|
223 assert_equal({}.inspect, @h.send(meth))
224 assert_equal({"ab"=>"1", "cd"=>"2", "3"=>"4"}.inspect, @fh.send(meth))
229 assert_kind_of(Rack::Headers, @h.invert)
230 assert_equal({}, @h.invert)
231 assert_equal({"1"=>"ab", "2"=>"cd", "4"=>"3"}, @fh.invert)
232 assert_equal({'cd'=>'ab'}, Rack::Headers['AB'=>'CD'].invert)
233 assert_equal({'cd'=>'xy'}, Rack::Headers['AB'=>'Cd', 'xY'=>'cD'].invert)
237 assert_equal [], @h.keys
238 assert_equal %w'ab cd 3', @fh.keys
242 %i'length size'.each do |meth|
243 assert_equal 0, @h.send(meth)
244 assert_equal 3, @fh.send(meth)
248 def test_merge_and_update
249 assert_equal @h, @h.merge({})
250 assert_equal @fh, @fh.merge({})
251 assert_equal Rack::Headers['ab'=>'55'], @h.merge({'ab'=>'55'})
252 assert_equal Rack::Headers[], @h
253 assert_equal Rack::Headers['ab'=>'55'], @h.update({'ab'=>'55'})
254 assert_equal Rack::Headers['ab'=>'55'], @h
255 assert_equal Rack::Headers['ab'=>'55', 'cd'=>'2', '3'=>'4'], @fh.merge({'ab'=>'55'})
256 assert_equal Rack::Headers['ab'=>'1', 'cd'=>'2', '3'=>'4'], @fh
257 assert_equal Rack::Headers['ab'=>'55', 'cd'=>'2', '3'=>'4'], @fh.merge!({'ab'=>'55'})
258 assert_equal Rack::Headers['ab'=>'55', 'cd'=>'2', '3'=>'4'], @fh
259 assert_equal Rack::Headers['ab'=>'abss55', 'cd'=>'2', '3'=>'4'], @fh.merge({'ab'=>'ss'}){|k,ov,nv| [k,nv,ov].join}
260 assert_equal Rack::Headers['ab'=>'55', 'cd'=>'2', '3'=>'4'], @fh
261 assert_equal Rack::Headers['ab'=>'abss55', 'cd'=>'2', '3'=>'4'], @fh.update({'ab'=>'ss'}){|k,ov,nv| [k,nv,ov].join}
262 assert_equal Rack::Headers['ab'=>'abss55', 'cd'=>'2', '3'=>'4'], @fh
263 assert_equal Rack::Headers['ab'=>'abssabss55', 'cd'=>'2', '3'=>'4'], @fh.merge!({'ab'=>'ss'}){|k,ov,nv| [k,nv,ov].join}
264 assert_equal Rack::Headers['ab'=>'abssabss55', 'cd'=>'2', '3'=>'4'], @fh
278 assert_equal @h, fh.replace({})
279 assert_equal @fh, h.replace('AB'=>'1', 'cd'=>'2', '3'=>'4')
283 assert_equal({}, @h.select{true})
284 assert_equal({}, @h.select{false})
285 assert_equal({'3' => '4', "ab" => '1', 'cd' => '2'}, @fh.select{true})
286 assert_equal({}, @fh.select{false})
287 assert_equal({'cd' => '2'}, @fh.select{|k,v| k.start_with?('c')})
288 assert_equal({'3' => '4'}, @fh.select{|k,v| v == '4'})
299 assert_equal [], array
303 assert array.include?(kv)
307 assert_equal [], array
312 assert_equal [], @h.sort
313 assert_equal [], @h.sort{|a,b| a.to_s<=>b.to_s}
314 assert_equal [['ab', '1'], ['cd', '4'], ['ef', '2']], Rack::Headers['CD','4','AB','1','EF','2'].sort
315 assert_equal [['3', '4'], ['ab', '1'], ['cd', '2']], @fh.sort{|(ak,av),(bk,bv)| ak.to_s<=>bk.to_s}
319 assert_equal [], @h.to_a
320 assert_equal [['ab', '1'], ['cd', '2'], ['3', '4']], @fh.to_a
324 assert_equal Hash[], @h.to_hash
325 assert_equal Hash['3','4','ab','1','cd','2'], @fh.to_hash
329 assert_equal [], @h.values
330 assert_equal ['f', 'c'], Rack::Headers['aB','f','1','c'].values
334 assert_equal [], @h.values_at()
335 assert_equal [nil], @h.values_at(1)
336 assert_equal [nil, nil], @h.values_at(1, 1)
337 assert_equal [], @fh.values_at()
338 assert_equal ['1'], @fh.values_at('AB')
339 assert_equal ['2', '1'], @fh.values_at('CD', 'Ab')
340 assert_equal ['2', nil, '1'], @fh.values_at('CD', 32, 'aB')
341 assert_equal ['4', '2', nil, '1'], @fh.values_at('3', 'CD', 32, 'ab')
345 assert_nil @h.assoc(1)
346 assert_equal ['ab', '1'], @fh.assoc('Ab')
347 assert_equal ['cd', '2'], @fh.assoc('CD')
348 assert_nil @fh.assoc('4')
349 assert_equal ['3', '4'], @fh.assoc('3')
352 def test_default_proc=
353 @h.default_proc = proc{|h, k| k * 2}
354 assert_equal 'aa', @h['A']
356 assert_equal '2', @h['aB']
360 assert_equal [], @h.flatten
361 assert_equal ['ab', '1', 'cd', '2', '3', '4'], @fh.flatten
363 assert_equal ['ab', '1', 'cd', '2', '3', '4', 'x', '56'], @fh.flatten
364 assert_equal ['ab', '1', 'cd', '2', '3', '4', 'x', '56'], @fh.flatten(2)
368 assert_equal @h, @h.keep_if{|k, v| true}
369 assert_equal @fh, @fh.keep_if{|k, v| true}
370 assert_equal @h, @fh.dup.keep_if{|k, v| false}
371 assert_equal Rack::Headers["AB"=>'1'], @fh.keep_if{|k, v| k == "ab"}
375 assert_nil @h.key('1')
376 assert_nil @fh.key(1)
377 assert_equal 'ab', @fh.key('1')
378 assert_equal 'cd', @fh.key('2')
379 assert_nil @fh.key('3')
380 assert_equal '3', @fh.key('4')
384 assert_nil @h.rassoc('1')
385 assert_equal ['ab', '1'], @fh.rassoc('1')
386 assert_equal ['cd', '2'], @fh.rassoc('2')
387 assert_nil @fh.rassoc('3')
388 assert_equal ['3', '4'], @fh.rassoc('4')
392 assert_nil @h.select!{|k, v| true}
393 assert_nil @fh.select!{|k, v| true}
394 assert_equal @h, @fh.dup.select!{|k, v| false}
395 assert_equal Rack::Headers["AB"=>'1'], @fh.select!{|k, v| k == "ab"}
398 def test_compare_by_identity
399 assert_raises(TypeError){@fh.compare_by_identity}
402 def test_compare_by_identity?
403 assert_equal(false, @fh.compare_by_identity?)
407 assert_equal Hash[], @h.to_h
408 assert_equal Hash['3','4','ab','1','cd','2'], @fh.to_h
412 assert_equal('1', @fh.dig('AB'))
413 assert_equal('2', @fh.dig('Cd'))
414 assert_equal('4', @fh.dig('3'))
415 assert_nil(@fh.dig('4'))
417 assert_raises(TypeError){@fh.dig('AB', 1)}
418 assert_raises(TypeError){@fh.dig('cd', 2)}
419 assert_raises(TypeError){@fh.dig('3', 3)}
420 assert_nil(@fh.dig('4', 5))
423 def test_fetch_values
424 assert_equal(['1'], @fh.fetch_values('AB'))
425 assert_equal(['1', '2', '4'], @fh.fetch_values('AB', 'Cd', '3'))
426 assert_raises(KeyError){@fh.fetch_values('AB', 'cD', '4')}
431 assert_equal('1', pr['AB'])
432 assert_equal('2', pr['cD'])
433 assert_equal('4', pr['3'])
438 assert_equal(false, @fh.compact.equal?(@fh))
439 assert_equal(@fh, @fh.compact)
440 assert_equal(Rack::Headers['Ab'=>1], Rack::Headers['aB'=>1, 'cd'=>nil].compact)
445 assert_nil(@fh.compact!)
446 assert_equal(fh, @fh)
448 h = Rack::Headers['Ab'=>1, 'cd'=>nil]
449 assert_equal(Rack::Headers['aB'=>1], h.compact!)
450 assert_equal(Rack::Headers['AB'=>1], h)
453 def test_transform_values
454 fh = @fh.transform_values{|v| v.to_s*2}
455 assert_equal('1', @fh['aB'])
456 assert_equal(Rack::Headers['AB'=>'11', 'cD'=>'22', '3'=>'44'], fh)
457 assert_equal('11', fh['Ab'])
460 def test_transform_values!
461 @fh.transform_values!{|v| v.to_s*2}
462 assert_equal('11', @fh['AB'])
463 assert_equal(Rack::Headers['Ab'=>'11', 'CD'=>'22', '3'=>'44'], @fh)
464 assert_equal('11', @fh['aB'])
467 if RUBY_VERSION >= '2.5'
469 assert_equal(Rack::Headers['Ab'=>'1', 'cD'=>'2', '3'=>'4'], @fh.slice('aB', 'Cd', '3'))
470 assert_equal(Rack::Headers['AB'=>'1', 'CD'=>'2'], @fh.slice('Ab', 'CD'))
471 assert_equal(Rack::Headers[], @fh.slice('ad'))
472 assert_equal('1', @fh.slice('AB', 'cd')['Ab'])
475 def test_transform_keys
476 map = {'ab'=>'Xy', 'cd'=>'dC', '3'=>'5'}
478 fh = @fh.transform_keys{|k| map[k]}
479 assert_equal(dh, @fh)
480 assert_equal('1', fh['xY'])
481 assert_equal('2', fh['Dc'])
482 assert_equal('4', fh['5'])
485 def test_transform_keys!
486 map = {'ab'=>'Xy', 'cd'=>'dC', '3'=>'5'}
488 @fh.transform_keys!{|k| map[k]}
489 assert_equal(false, dh == @fh)
490 assert_equal('1', @fh['xY'])
491 assert_equal('2', @fh['DC'])
492 assert_equal('4', @fh['5'])
496 if RUBY_VERSION >= '2.6'
498 assert_nil @h.filter!{|k, v| true}
499 assert_nil @fh.filter!{|k, v| true}
500 assert_equal @h, @fh.dup.filter!{|k, v| false}
501 assert_equal Rack::Headers["AB"=>'1'], @fh.filter!{|k, v| k == "ab"}
505 if RUBY_VERSION >= '2.7'
506 def test_deconstruct_keys
507 assert_equal(@fh.to_hash, @fh.deconstruct_keys([]))
508 assert_equal(Rack::Headers, @fh.deconstruct_keys([]).class)
512 if RUBY_VERSION >= '3.0'
514 @fh = Rack::Headers['AB'=>'1', 'Cd'=>'2', '3'=>'4']
515 assert_equal(@fh, @fh.except)
516 assert_equal(Rack::Headers['cD'=>'2', '3'=>'4'], @fh.except('AB', 5))
517 assert_equal(Rack::Headers['AB'=>'1'], @fh.except('cD', '3'))