hashie 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +213 -187
  3. data/CONTRIBUTING.md +13 -6
  4. data/README.md +33 -9
  5. data/UPGRADING.md +5 -5
  6. data/hashie.gemspec +11 -6
  7. data/lib/hashie.rb +1 -0
  8. data/lib/hashie/extensions/dash/property_translation.rb +1 -1
  9. data/lib/hashie/extensions/deep_merge.rb +18 -1
  10. data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
  11. data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +19 -2
  12. data/lib/hashie/extensions/ruby_version_check.rb +5 -1
  13. data/lib/hashie/mash.rb +31 -26
  14. data/lib/hashie/utils.rb +28 -0
  15. data/lib/hashie/version.rb +1 -1
  16. metadata +16 -131
  17. data/spec/hashie/array_spec.rb +0 -29
  18. data/spec/hashie/clash_spec.rb +0 -70
  19. data/spec/hashie/dash_spec.rb +0 -608
  20. data/spec/hashie/extensions/autoload_spec.rb +0 -24
  21. data/spec/hashie/extensions/coercion_spec.rb +0 -648
  22. data/spec/hashie/extensions/dash/coercion_spec.rb +0 -13
  23. data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
  24. data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
  25. data/spec/hashie/extensions/deep_find_spec.rb +0 -144
  26. data/spec/hashie/extensions/deep_locate_spec.rb +0 -138
  27. data/spec/hashie/extensions/deep_merge_spec.rb +0 -74
  28. data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -48
  29. data/spec/hashie/extensions/indifferent_access_spec.rb +0 -295
  30. data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
  31. data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
  32. data/spec/hashie/extensions/mash/define_accessors_spec.rb +0 -90
  33. data/spec/hashie/extensions/mash/keep_original_keys_spec.rb +0 -46
  34. data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -50
  35. data/spec/hashie/extensions/mash/symbolize_keys_spec.rb +0 -39
  36. data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
  37. data/spec/hashie/extensions/method_access_spec.rb +0 -233
  38. data/spec/hashie/extensions/strict_key_access_spec.rb +0 -109
  39. data/spec/hashie/extensions/stringify_keys_spec.rb +0 -124
  40. data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -131
  41. data/spec/hashie/hash_spec.rb +0 -123
  42. data/spec/hashie/mash_spec.rb +0 -1077
  43. data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -46
  44. data/spec/hashie/rash_spec.rb +0 -83
  45. data/spec/hashie/trash_spec.rb +0 -334
  46. data/spec/hashie/utils_spec.rb +0 -25
  47. data/spec/hashie/version_spec.rb +0 -7
  48. data/spec/hashie_spec.rb +0 -13
  49. data/spec/integration/elasticsearch/integration_spec.rb +0 -41
  50. data/spec/integration/omniauth-oauth2/app.rb +0 -52
  51. data/spec/integration/omniauth-oauth2/integration_spec.rb +0 -26
  52. data/spec/integration/omniauth-oauth2/some_site.rb +0 -38
  53. data/spec/integration/omniauth/app.rb +0 -11
  54. data/spec/integration/omniauth/integration_spec.rb +0 -38
  55. data/spec/integration/rails-without-dependency/integration_spec.rb +0 -15
  56. data/spec/integration/rails/app.rb +0 -40
  57. data/spec/integration/rails/integration_spec.rb +0 -47
  58. data/spec/spec_helper.rb +0 -23
  59. data/spec/support/integration_specs.rb +0 -36
  60. data/spec/support/logger.rb +0 -24
  61. data/spec/support/module_context.rb +0 -11
  62. data/spec/support/ruby_version_check.rb +0 -6
@@ -1,109 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hashie::Extensions::StrictKeyAccess do
4
- class StrictKeyAccessHash < Hash
5
- include Hashie::Extensions::StrictKeyAccess
6
- end
7
-
8
- shared_examples_for 'StrictKeyAccess with valid key' do |options = {}|
9
- before { pending_for(options[:pending]) } if options[:pending]
10
- context 'set' do
11
- let(:new_value) { 42 }
12
- it('returns value') do
13
- expect(instance.send(:[]=, valid_key, new_value)).to eq new_value
14
- end
15
- end
16
- context 'access' do
17
- it('returns value') do
18
- expect(instance[valid_key]).to eq valid_value
19
- end
20
- end
21
- context 'lookup' do
22
- it('returns key') do
23
- expect(instance.key(valid_value)).to eq valid_key
24
- end
25
- end
26
- end
27
- shared_examples_for 'StrictKeyAccess with invalid key' do |options = {}|
28
- before { pending_for(options[:pending]) } if options[:pending]
29
- context 'access' do
30
- it('raises an error') do
31
- # Formatting of the error message varies on Rubinius and ruby-head
32
- expect { instance[invalid_key] }.to raise_error KeyError
33
- end
34
- end
35
- context 'lookup' do
36
- it('raises an error') do
37
- # Formatting of the error message does not vary here because raised by StrictKeyAccess
38
- expect { instance.key(invalid_value) }.to raise_error KeyError
39
- end
40
- end
41
- end
42
- shared_examples_for 'StrictKeyAccess raises KeyError instead of allowing defaults' do
43
- context '#default' do
44
- it 'raises an error' do
45
- expect { instance.default(invalid_key) }
46
- .to raise_error Hashie::Extensions::StrictKeyAccess::DefaultError
47
- end
48
- end
49
- context '#default=' do
50
- it 'raises an error' do
51
- expect { instance.default = invalid_key }
52
- .to raise_error Hashie::Extensions::StrictKeyAccess::DefaultError
53
- end
54
- end
55
- context '#default_proc' do
56
- it 'raises an error' do
57
- expect { instance.default_proc }
58
- .to raise_error Hashie::Extensions::StrictKeyAccess::DefaultError
59
- end
60
- end
61
- context '#default_proc=' do
62
- it 'raises an error' do
63
- expect { instance.default_proc = proc {} }
64
- .to raise_error Hashie::Extensions::StrictKeyAccess::DefaultError
65
- end
66
- end
67
- end
68
-
69
- let(:klass) { StrictKeyAccessHash }
70
- let(:instance) { StrictKeyAccessHash.new(*initialization_args) }
71
- let(:initialization_args) do
72
- [
73
- { valid_key => valid_value }
74
- ]
75
- end
76
- let(:valid_key) { :abc }
77
- let(:valid_value) { 'def' }
78
- let(:invalid_key) { :mega }
79
- let(:invalid_value) { 'death' }
80
-
81
- context '.new' do
82
- context 'no defaults at initialization' do
83
- let(:initialization_args) { [] }
84
- before do
85
- instance.merge!(valid_key => valid_value)
86
- end
87
- it_behaves_like 'StrictKeyAccess with valid key'
88
- it_behaves_like 'StrictKeyAccess with invalid key'
89
- it_behaves_like 'StrictKeyAccess raises KeyError instead of allowing defaults'
90
- end
91
- context 'with defaults at initialization' do
92
- before do
93
- instance.merge!(valid_key => valid_value)
94
- end
95
- it_behaves_like 'StrictKeyAccess with valid key'
96
- it_behaves_like 'StrictKeyAccess with invalid key'
97
- it_behaves_like 'StrictKeyAccess raises KeyError instead of allowing defaults'
98
- end
99
- it_behaves_like 'StrictKeyAccess with invalid key'
100
- it_behaves_like 'StrictKeyAccess raises KeyError instead of allowing defaults'
101
- end
102
-
103
- context '.[]' do
104
- let(:instance) { StrictKeyAccessHash[*initialization_args] }
105
- it_behaves_like 'StrictKeyAccess with valid key', pending: { engine: 'rbx' }
106
- it_behaves_like 'StrictKeyAccess with invalid key', pending: { engine: 'rbx' }
107
- it_behaves_like 'StrictKeyAccess raises KeyError instead of allowing defaults'
108
- end
109
- end
@@ -1,124 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/module_context'
3
-
4
- def invoke(method)
5
- if subject == object
6
- subject.public_send(method)
7
- else
8
- subject.public_send(method, object)
9
- end
10
- end
11
-
12
- shared_examples 'stringify_keys!' do
13
- it 'converts keys to strings' do
14
- object[:abc] = 'abc'
15
- object[123] = '123'
16
- invoke :stringify_keys!
17
- expect((object.keys & %w[abc 123]).size).to eq 2
18
- end
19
-
20
- it 'converts nested instances of the same class' do
21
- object[:ab] = dummy_class.new
22
- object[:ab][:cd] = dummy_class.new
23
- object[:ab][:cd][:ef] = 'abcdef'
24
- invoke :stringify_keys!
25
- expect(object).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
26
- end
27
-
28
- it 'converts nested hashes' do
29
- object[:ab] = { cd: { ef: 'abcdef' } }
30
- invoke :stringify_keys!
31
- expect(object).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
32
- end
33
-
34
- it 'converts nested arrays' do
35
- object[:ab] = []
36
- object[:ab] << dummy_class.new
37
- object[:ab] << dummy_class.new
38
- object[:ab][0][:cd] = 'abcd'
39
- object[:ab][1][:ef] = 'abef'
40
- invoke :stringify_keys!
41
- expect(object).to eq('ab' => [{ 'cd' => 'abcd' }, { 'ef' => 'abef' }])
42
- end
43
- end
44
-
45
- shared_examples 'stringify_keys' do
46
- it 'converts keys to strings' do
47
- object[:abc] = 'def'
48
- copy = invoke :stringify_keys
49
- expect(copy['abc']).to eq 'def'
50
- end
51
-
52
- it 'does not alter the original' do
53
- object[:abc] = 'def'
54
- copy = invoke :stringify_keys
55
- expect(object.keys).to eq [:abc]
56
- expect(copy.keys).to eq %w[abc]
57
- end
58
- end
59
-
60
- describe Hashie::Extensions::StringifyKeys do
61
- include_context 'included hash module'
62
- let(:object) { subject }
63
-
64
- describe '#stringify_keys!' do
65
- include_examples 'stringify_keys!'
66
-
67
- it 'returns itself' do
68
- expect(subject.stringify_keys!).to eq subject
69
- end
70
- end
71
-
72
- context 'class methods' do
73
- subject { described_class }
74
- let(:object) { {} }
75
-
76
- describe '.stringify_keys' do
77
- include_examples 'stringify_keys'
78
- end
79
- describe '.stringify_keys!' do
80
- include_examples 'stringify_keys!'
81
- end
82
- end
83
-
84
- context 'singleton methods' do
85
- subject { Hash }
86
- let(:object) { subject.new.merge(a: 1, b: { c: 2 }).extend(Hashie::Extensions::StringifyKeys) }
87
- let(:expected_hash) { { 'a' => 1, 'b' => { 'c' => 2 } } }
88
-
89
- describe '.stringify_keys' do
90
- it 'does not raise error' do
91
- expect { object.stringify_keys } .not_to raise_error
92
- end
93
- it 'produces expected stringified hash' do
94
- expect(object.stringify_keys).to eq(expected_hash)
95
- end
96
- end
97
- describe '.stringify_keys!' do
98
- it 'does not raise error' do
99
- expect { object.stringify_keys! } .not_to raise_error
100
- end
101
- it 'produces expected stringified hash' do
102
- expect(object.stringify_keys!).to eq(expected_hash)
103
- end
104
- end
105
- end
106
- end
107
-
108
- describe Hashie do
109
- let!(:dummy_class) do
110
- klass = Class.new(::Hash)
111
- klass.send :include, Hashie::Extensions::StringifyKeys
112
- klass
113
- end
114
-
115
- subject { described_class }
116
- let(:object) { {} }
117
-
118
- describe '.stringify_keys' do
119
- include_examples 'stringify_keys'
120
- end
121
- describe '.stringify_keys!' do
122
- include_examples 'stringify_keys!'
123
- end
124
- end
@@ -1,131 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/module_context'
3
-
4
- def invoke(method)
5
- if subject == object
6
- subject.public_send(method)
7
- else
8
- subject.public_send(method, object)
9
- end
10
- end
11
-
12
- shared_examples 'symbolize_keys!' do
13
- it 'converts keys to symbols' do
14
- object['abc'] = 'abc'
15
- object['def'] = 'def'
16
- invoke :symbolize_keys!
17
- expect((object.keys & %i[abc def]).size).to eq 2
18
- end
19
-
20
- it 'converts nested instances of the same class' do
21
- object['ab'] = dummy_class.new
22
- object['ab']['cd'] = dummy_class.new
23
- object['ab']['cd']['ef'] = 'abcdef'
24
- invoke :symbolize_keys!
25
- expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
26
- end
27
-
28
- it 'converts nested hashes' do
29
- object['ab'] = { 'cd' => { 'ef' => 'abcdef' } }
30
- invoke :symbolize_keys!
31
- expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
32
- end
33
-
34
- it 'performs deep conversion within nested arrays' do
35
- object['ab'] = []
36
- object['ab'] << dummy_class.new
37
- object['ab'] << dummy_class.new
38
- object['ab'][0]['cd'] = 'abcd'
39
- object['ab'][1]['ef'] = 'abef'
40
- new_object = invoke :symbolize_keys
41
- expect(new_object).to eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
42
- end
43
- end
44
-
45
- shared_examples 'symbolize_keys' do
46
- it 'converts keys to symbols' do
47
- object['abc'] = 'def'
48
- copy = invoke :symbolize_keys
49
- expect(copy[:abc]).to eq 'def'
50
- end
51
-
52
- it 'does not alter the original' do
53
- object['abc'] = 'def'
54
- copy = invoke :symbolize_keys
55
- expect(object.keys).to eq ['abc']
56
- expect(copy.keys).to eq [:abc]
57
- end
58
- end
59
-
60
- describe Hashie::Extensions::SymbolizeKeys do
61
- include_context 'included hash module'
62
- let(:object) { subject }
63
-
64
- describe '#symbolize_keys!' do
65
- include_examples 'symbolize_keys!'
66
- let(:object) { subject }
67
-
68
- it 'returns itself' do
69
- expect(subject.symbolize_keys!).to eq subject
70
- end
71
- end
72
-
73
- describe '#symbolize_keys' do
74
- include_examples 'symbolize_keys'
75
- end
76
-
77
- context 'class methods' do
78
- subject { described_class }
79
- let(:object) { {} }
80
-
81
- describe '.symbolize_keys' do
82
- include_examples 'symbolize_keys'
83
- end
84
- describe '.symbolize_keys!' do
85
- include_examples 'symbolize_keys!'
86
- end
87
- end
88
-
89
- context 'singleton methods' do
90
- subject { Hash }
91
- let(:object) do
92
- subject.new.merge('a' => 1, 'b' => { 'c' => 2 }).extend(Hashie::Extensions::SymbolizeKeys)
93
- end
94
- let(:expected_hash) { { a: 1, b: { c: 2 } } }
95
-
96
- describe '.symbolize_keys' do
97
- it 'does not raise error' do
98
- expect { object.symbolize_keys }.not_to raise_error
99
- end
100
- it 'produces expected symbolized hash' do
101
- expect(object.symbolize_keys).to eq(expected_hash)
102
- end
103
- end
104
- describe '.symbolize_keys!' do
105
- it 'does not raise error' do
106
- expect { object.symbolize_keys! }.not_to raise_error
107
- end
108
- it 'produces expected symbolized hash' do
109
- expect(object.symbolize_keys!).to eq(expected_hash)
110
- end
111
- end
112
- end
113
- end
114
-
115
- describe Hashie do
116
- let!(:dummy_class) do
117
- klass = Class.new(::Hash)
118
- klass.send :include, Hashie::Extensions::StringifyKeys
119
- klass
120
- end
121
-
122
- subject { described_class }
123
- let(:object) { {} }
124
-
125
- describe '.symbolize_keys' do
126
- include_examples 'symbolize_keys'
127
- end
128
- describe '.symbolize_keys!' do
129
- include_examples 'symbolize_keys!'
130
- end
131
- end
@@ -1,123 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hash do
4
- it 'is convertible to a Hashie::Mash' do
5
- mash = Hashie::Hash[some: 'hash'].to_mash
6
- expect(mash.is_a?(Hashie::Mash)).to be_truthy
7
- expect(mash.some).to eq 'hash'
8
- end
9
-
10
- it '#stringify_keys! turns all keys into strings' do
11
- hash = Hashie::Hash[a: 'hey', 123 => 'bob']
12
- hash.stringify_keys!
13
- expect(hash).to eq Hashie::Hash['a' => 'hey', '123' => 'bob']
14
- end
15
-
16
- it '#stringify_keys! turns all keys into strings recursively' do
17
- hash = Hashie::Hash[a: 'hey', 123 => { 345 => 'hey' }]
18
- hash.stringify_keys!
19
- expect(hash).to eq Hashie::Hash['a' => 'hey', '123' => { '345' => 'hey' }]
20
- end
21
-
22
- it '#stringify_keys returns a hash with stringified keys' do
23
- hash = Hashie::Hash[a: 'hey', 123 => 'bob']
24
- stringified_hash = hash.stringify_keys
25
- expect(hash).to eq Hashie::Hash[a: 'hey', 123 => 'bob']
26
- expect(stringified_hash).to eq Hashie::Hash['a' => 'hey', '123' => 'bob']
27
- end
28
-
29
- it '#to_hash returns a hash with same keys' do
30
- hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
31
- stringified_hash = hash.to_hash
32
- expect(stringified_hash).to eq('a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3])
33
- end
34
-
35
- it '#to_hash with stringify_keys set to true returns a hash with stringified_keys' do
36
- hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
37
- symbolized_hash = hash.to_hash(stringify_keys: true)
38
- expect(symbolized_hash).to eq('a' => 'hey', '123' => 'bob', 'array' => [1, 2, 3])
39
- end
40
-
41
- it '#to_hash with symbolize_keys set to true returns a hash with symbolized keys' do
42
- hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
43
- symbolized_hash = hash.to_hash(symbolize_keys: true)
44
- expect(symbolized_hash).to eq(a: 'hey', :"123" => 'bob', array: [1, 2, 3])
45
- end
46
-
47
- it "#to_hash should not blow up when #to_hash doesn't accept arguments" do
48
- class BareCustomMash < Hashie::Mash
49
- def to_hash
50
- {}
51
- end
52
- end
53
-
54
- h = Hashie::Hash.new
55
- h[:key] = BareCustomMash.new
56
- expect { h.to_hash }.not_to raise_error
57
- end
58
-
59
- describe 'when the value is an object that respond_to to_hash' do
60
- class ClassRespondsToHash
61
- def to_hash(options = {})
62
- Hashie::Hash['a' => 'hey', b: 'bar', 123 => 'bob', 'array' => [1, 2, 3]].to_hash(options)
63
- end
64
- end
65
-
66
- it '#to_hash returns a hash with same keys' do
67
- hash = Hashie::Hash[
68
- 'a' => 'hey',
69
- 123 => 'bob',
70
- 'array' => [1, 2, 3],
71
- subhash: ClassRespondsToHash.new
72
- ]
73
- stringified_hash = hash.to_hash
74
-
75
- expected = {
76
- 'a' => 'hey',
77
- 123 => 'bob',
78
- 'array' => [1, 2, 3],
79
- subhash: { 'a' => 'hey', b: 'bar', 123 => 'bob', 'array' => [1, 2, 3] }
80
- }
81
-
82
- expect(stringified_hash).to eq(expected)
83
- end
84
-
85
- it '#to_hash with stringify_keys set to true returns a hash with stringified_keys' do
86
- hash = Hashie::Hash[
87
- 'a' => 'hey',
88
- 123 => 'bob',
89
- 'array' => [1, 2, 3],
90
- subhash: ClassRespondsToHash.new
91
- ]
92
- symbolized_hash = hash.to_hash(stringify_keys: true)
93
-
94
- expected = {
95
- 'a' => 'hey',
96
- '123' => 'bob',
97
- 'array' => [1, 2, 3],
98
- 'subhash' => { 'a' => 'hey', 'b' => 'bar', '123' => 'bob', 'array' => [1, 2, 3] }
99
- }
100
-
101
- expect(symbolized_hash).to eq(expected)
102
- end
103
-
104
- it '#to_hash with symbolize_keys set to true returns a hash with symbolized keys' do
105
- hash = Hashie::Hash[
106
- 'a' => 'hey',
107
- 123 => 'bob',
108
- 'array' => [1, 2, 3],
109
- subhash: ClassRespondsToHash.new
110
- ]
111
- symbolized_hash = hash.to_hash(symbolize_keys: true)
112
-
113
- expected = {
114
- a: 'hey',
115
- :"123" => 'bob',
116
- array: [1, 2, 3],
117
- subhash: { a: 'hey', b: 'bar', :'123' => 'bob', array: [1, 2, 3] }
118
- }
119
-
120
- expect(symbolized_hash).to eq(expected)
121
- end
122
- end
123
- end