hashie 2.1.2 → 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +524 -59
- data/CONTRIBUTING.md +24 -7
- data/README.md +781 -90
- data/Rakefile +19 -2
- data/UPGRADING.md +245 -0
- data/hashie.gemspec +21 -13
- data/lib/hashie.rb +60 -21
- data/lib/hashie/array.rb +21 -0
- data/lib/hashie/clash.rb +24 -12
- data/lib/hashie/dash.rb +96 -33
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
- data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
- data/lib/hashie/extensions/coercion.rb +124 -18
- data/lib/hashie/extensions/dash/coercion.rb +25 -0
- data/lib/hashie/extensions/dash/indifferent_access.rb +56 -0
- data/lib/hashie/extensions/dash/property_translation.rb +191 -0
- data/lib/hashie/extensions/deep_fetch.rb +7 -5
- data/lib/hashie/extensions/deep_find.rb +69 -0
- data/lib/hashie/extensions/deep_locate.rb +113 -0
- data/lib/hashie/extensions/deep_merge.rb +35 -12
- data/lib/hashie/extensions/ignore_undeclared.rb +11 -5
- data/lib/hashie/extensions/indifferent_access.rb +28 -16
- data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
- data/lib/hashie/extensions/key_conversion.rb +0 -82
- data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
- data/lib/hashie/extensions/mash/keep_original_keys.rb +53 -0
- data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
- data/lib/hashie/extensions/mash/safe_assignment.rb +18 -0
- data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
- data/lib/hashie/extensions/method_access.rb +154 -11
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +48 -0
- data/lib/hashie/extensions/pretty_inspect.rb +19 -0
- data/lib/hashie/extensions/ruby_version.rb +60 -0
- data/lib/hashie/extensions/ruby_version_check.rb +21 -0
- data/lib/hashie/extensions/strict_key_access.rb +77 -0
- data/lib/hashie/extensions/stringify_keys.rb +71 -0
- data/lib/hashie/extensions/symbolize_keys.rb +71 -0
- data/lib/hashie/hash.rb +27 -8
- data/lib/hashie/logger.rb +18 -0
- data/lib/hashie/mash.rb +235 -57
- data/lib/hashie/railtie.rb +21 -0
- data/lib/hashie/rash.rb +40 -16
- data/lib/hashie/trash.rb +2 -88
- data/lib/hashie/utils.rb +44 -0
- data/lib/hashie/version.rb +1 -1
- metadata +42 -81
- data/.gitignore +0 -9
- data/.rspec +0 -2
- data/.rubocop.yml +0 -36
- data/.travis.yml +0 -15
- data/Gemfile +0 -11
- data/Guardfile +0 -5
- data/lib/hashie/hash_extensions.rb +0 -47
- data/spec/hashie/clash_spec.rb +0 -48
- data/spec/hashie/dash_spec.rb +0 -338
- data/spec/hashie/extensions/coercion_spec.rb +0 -156
- data/spec/hashie/extensions/deep_fetch_spec.rb +0 -70
- data/spec/hashie/extensions/deep_merge_spec.rb +0 -22
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -23
- data/spec/hashie/extensions/indifferent_access_spec.rb +0 -152
- data/spec/hashie/extensions/key_conversion_spec.rb +0 -103
- data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
- data/spec/hashie/extensions/method_access_spec.rb +0 -121
- data/spec/hashie/hash_spec.rb +0 -66
- data/spec/hashie/mash_spec.rb +0 -467
- data/spec/hashie/rash_spec.rb +0 -44
- data/spec/hashie/trash_spec.rb +0 -193
- data/spec/hashie/version_spec.rb +0 -7
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +0 -8
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
AllCops:
|
2
|
-
Exclude:
|
3
|
-
- vendor/**
|
4
|
-
- bin/**
|
5
|
-
- .bundle/**
|
6
|
-
|
7
|
-
LineLength:
|
8
|
-
Enabled: false
|
9
|
-
|
10
|
-
MethodLength:
|
11
|
-
Enabled: false
|
12
|
-
|
13
|
-
ClassLength:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
Documentation:
|
17
|
-
# don't require classes to be documented
|
18
|
-
Enabled: false
|
19
|
-
|
20
|
-
Encoding:
|
21
|
-
# no need to always specify encoding
|
22
|
-
Enabled: false
|
23
|
-
|
24
|
-
Lambda:
|
25
|
-
# TODO: replace all lambda with -> or Proc
|
26
|
-
Enabled: false
|
27
|
-
|
28
|
-
CyclomaticComplexity:
|
29
|
-
Enabled: false
|
30
|
-
|
31
|
-
DoubleNegation:
|
32
|
-
Enabled: false
|
33
|
-
|
34
|
-
CaseEquality:
|
35
|
-
Enabled: false
|
36
|
-
|
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Guardfile
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Hashie
|
2
|
-
module HashExtensions
|
3
|
-
def self.included(base)
|
4
|
-
# Don't tread on existing extensions of Hash by
|
5
|
-
# adding methods that are likely to exist.
|
6
|
-
%w(stringify_keys stringify_keys!).each do |hashie_method|
|
7
|
-
base.send :alias_method, hashie_method, "hashie_#{hashie_method}" unless base.instance_methods.include?(hashie_method)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
# Destructively convert all of the keys of a Hash
|
12
|
-
# to their string representations.
|
13
|
-
def hashie_stringify_keys!
|
14
|
-
keys.each do |k|
|
15
|
-
self[k.to_s] = delete(k) unless String === k
|
16
|
-
end
|
17
|
-
self
|
18
|
-
end
|
19
|
-
|
20
|
-
# Convert all of the keys of a Hash
|
21
|
-
# to their string representations.
|
22
|
-
def hashie_stringify_keys
|
23
|
-
dup.stringify_keys!
|
24
|
-
end
|
25
|
-
|
26
|
-
# Convert this hash into a Mash
|
27
|
-
def to_mash
|
28
|
-
::Hashie::Mash.new(self)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module PrettyInspect
|
33
|
-
def self.included(base)
|
34
|
-
base.send :alias_method, :hash_inspect, :inspect
|
35
|
-
base.send :alias_method, :inspect, :hashie_inspect
|
36
|
-
end
|
37
|
-
|
38
|
-
def hashie_inspect
|
39
|
-
ret = "#<#{self.class}"
|
40
|
-
stringify_keys.keys.sort.each do |key|
|
41
|
-
ret << " #{key}=#{self[key].inspect}"
|
42
|
-
end
|
43
|
-
ret << '>'
|
44
|
-
ret
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/spec/hashie/clash_spec.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Hashie::Clash do
|
4
|
-
subject { Hashie::Clash.new }
|
5
|
-
|
6
|
-
it 'is able to set an attribute via method_missing' do
|
7
|
-
subject.foo('bar')
|
8
|
-
expect(subject[:foo]).to eq 'bar'
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'is able to set multiple attributes' do
|
12
|
-
subject.foo('bar').baz('wok')
|
13
|
-
expect(subject).to eq(foo: 'bar', baz: 'wok')
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'converts multiple arguments into an array' do
|
17
|
-
subject.foo(1, 2, 3)
|
18
|
-
expect(subject[:foo]).to eq [1, 2, 3]
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'is able to use bang notation to create a new Clash on a key' do
|
22
|
-
subject.foo!
|
23
|
-
expect(subject[:foo]).to be_kind_of(Hashie::Clash)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'is able to chain onto the new Clash when using bang notation' do
|
27
|
-
subject.foo!.bar('abc').baz(123)
|
28
|
-
expect(subject).to eq(foo: { bar: 'abc', baz: 123 })
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'is able to jump back up to the parent in the chain with #_end!' do
|
32
|
-
subject.foo!.bar('abc')._end!.baz(123)
|
33
|
-
expect(subject).to eq(foo: { bar: 'abc' }, baz: 123)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'merges rather than replaces existing keys' do
|
37
|
-
subject.where(abc: 'def').where(hgi: 123)
|
38
|
-
expect(subject).to eq(where: { abc: 'def', hgi: 123 })
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'is able to replace all of its own keys with #replace' do
|
42
|
-
subject.foo(:bar).hello(:world)
|
43
|
-
expect(subject.replace(baz: 123, hgi: 123)).to eq(baz: 123, hgi: 123)
|
44
|
-
expect(subject).to eq(baz: 123, hgi: 123)
|
45
|
-
expect(subject[:foo]).to be_nil
|
46
|
-
expect(subject[:hello]).to be_nil
|
47
|
-
end
|
48
|
-
end
|
data/spec/hashie/dash_spec.rb
DELETED
@@ -1,338 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
Hashie::Hash.class_eval do
|
4
|
-
def self.inherited(klass)
|
5
|
-
klass.instance_variable_set('@inheritance_test', true)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class DashTest < Hashie::Dash
|
10
|
-
property :first_name, required: true
|
11
|
-
property :email
|
12
|
-
property :count, default: 0
|
13
|
-
end
|
14
|
-
|
15
|
-
class DashNoRequiredTest < Hashie::Dash
|
16
|
-
property :first_name
|
17
|
-
property :email
|
18
|
-
property :count, default: 0
|
19
|
-
end
|
20
|
-
|
21
|
-
class PropertyBangTest < Hashie::Dash
|
22
|
-
property :important!
|
23
|
-
end
|
24
|
-
|
25
|
-
class Subclassed < DashTest
|
26
|
-
property :last_name, required: true
|
27
|
-
end
|
28
|
-
|
29
|
-
class DashDefaultTest < Hashie::Dash
|
30
|
-
property :aliases, default: ['Snake']
|
31
|
-
end
|
32
|
-
|
33
|
-
class DeferredTest < Hashie::Dash
|
34
|
-
property :created_at, default: proc { Time.now }
|
35
|
-
end
|
36
|
-
|
37
|
-
describe DashTest do
|
38
|
-
|
39
|
-
subject { DashTest.new(first_name: 'Bob', email: 'bob@example.com') }
|
40
|
-
|
41
|
-
it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
|
42
|
-
|
43
|
-
describe '#to_s' do
|
44
|
-
subject { super().to_s }
|
45
|
-
it { should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">' }
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'lists all set properties in inspect' do
|
49
|
-
subject.first_name = 'Bob'
|
50
|
-
subject.email = 'bob@example.com'
|
51
|
-
expect(subject.inspect).to eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">'
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '#count' do
|
55
|
-
subject { super().count }
|
56
|
-
it { should be_zero }
|
57
|
-
end
|
58
|
-
|
59
|
-
it { should respond_to(:first_name) }
|
60
|
-
it { should respond_to(:first_name=) }
|
61
|
-
it { should_not respond_to(:nonexistent) }
|
62
|
-
|
63
|
-
it 'errors out for a non-existent property' do
|
64
|
-
expect { subject['nonexistent'] }.to raise_error(NoMethodError)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'errors out when attempting to set a required property to nil' do
|
68
|
-
expect { subject.first_name = nil }.to raise_error(ArgumentError)
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'writing to properties' do
|
72
|
-
it 'fails writing a required property to nil' do
|
73
|
-
expect { subject.first_name = nil }.to raise_error(ArgumentError)
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'fails writing a required property to nil using []=' do
|
77
|
-
expect { subject['first_name'] = nil }.to raise_error(ArgumentError)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'fails writing to a non-existent property using []=' do
|
81
|
-
expect { subject['nonexistent'] = 123 }.to raise_error(NoMethodError)
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'works for an existing property using []=' do
|
85
|
-
subject['first_name'] = 'Bob'
|
86
|
-
expect(subject['first_name']).to eq 'Bob'
|
87
|
-
expect(subject[:first_name]).to eq 'Bob'
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'works for an existing property using a method call' do
|
91
|
-
subject.first_name = 'Franklin'
|
92
|
-
expect(subject.first_name).to eq 'Franklin'
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context 'reading from properties' do
|
97
|
-
it 'fails reading from a non-existent property using []' do
|
98
|
-
expect { subject['nonexistent'] }.to raise_error(NoMethodError)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'is able to retrieve properties through blocks' do
|
102
|
-
subject['first_name'] = 'Aiden'
|
103
|
-
value = nil
|
104
|
-
subject.[]('first_name') { |v| value = v }
|
105
|
-
expect(value).to eq 'Aiden'
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'is able to retrieve properties through blocks with method calls' do
|
109
|
-
subject['first_name'] = 'Frodo'
|
110
|
-
value = nil
|
111
|
-
subject.first_name { |v| value = v }
|
112
|
-
expect(value).to eq 'Frodo'
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
context 'reading from deferred properties' do
|
117
|
-
it 'evaluates proc after initial read' do
|
118
|
-
expect(DeferredTest.new['created_at']).to be_instance_of(Time)
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'does not evalute proc after subsequent reads' do
|
122
|
-
deferred = DeferredTest.new
|
123
|
-
expect(deferred['created_at'].object_id).to eq deferred['created_at'].object_id
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe '#new' do
|
128
|
-
it 'fails with non-existent properties' do
|
129
|
-
expect { described_class.new(bork: '') }.to raise_error(NoMethodError)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'sets properties that it is able to' do
|
133
|
-
obj = described_class.new first_name: 'Michael'
|
134
|
-
expect(obj.first_name).to eq 'Michael'
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'accepts nil' do
|
138
|
-
expect { DashNoRequiredTest.new(nil) }.not_to raise_error
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'accepts block to define a global default' do
|
142
|
-
obj = described_class.new { |hash, key| key.to_s.upcase }
|
143
|
-
expect(obj.first_name).to eq 'FIRST_NAME'
|
144
|
-
expect(obj.count).to be_zero
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'fails when required values are missing' do
|
148
|
-
expect { DashTest.new }.to raise_error(ArgumentError)
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'does not overwrite default values' do
|
152
|
-
obj1 = DashDefaultTest.new
|
153
|
-
obj1.aliases << 'El Rey'
|
154
|
-
obj2 = DashDefaultTest.new
|
155
|
-
expect(obj2.aliases).not_to include 'El Rey'
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe '#merge' do
|
160
|
-
it 'creates a new instance of the Dash' do
|
161
|
-
new_dash = subject.merge(first_name: 'Robert')
|
162
|
-
expect(subject.object_id).not_to eq new_dash.object_id
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'merges the given hash' do
|
166
|
-
new_dash = subject.merge(first_name: 'Robert', email: 'robert@example.com')
|
167
|
-
expect(new_dash.first_name).to eq 'Robert'
|
168
|
-
expect(new_dash.email).to eq 'robert@example.com'
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'fails with non-existent properties' do
|
172
|
-
expect { subject.merge(middle_name: 'James') }.to raise_error(NoMethodError)
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'errors out when attempting to set a required property to nil' do
|
176
|
-
expect { subject.merge(first_name: nil) }.to raise_error(ArgumentError)
|
177
|
-
end
|
178
|
-
|
179
|
-
context 'given a block' do
|
180
|
-
it "sets merged key's values to the block's return value" do
|
181
|
-
expect(subject.merge(first_name: 'Jim') do |key, oldval, newval|
|
182
|
-
"#{key}: #{newval} #{oldval}"
|
183
|
-
end.first_name).to eq 'first_name: Jim Bob'
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
describe '#merge!' do
|
189
|
-
it 'modifies the existing instance of the Dash' do
|
190
|
-
original_dash = subject.merge!(first_name: 'Robert')
|
191
|
-
expect(subject.object_id).to eq original_dash.object_id
|
192
|
-
end
|
193
|
-
|
194
|
-
it 'merges the given hash' do
|
195
|
-
subject.merge!(first_name: 'Robert', email: 'robert@example.com')
|
196
|
-
expect(subject.first_name).to eq 'Robert'
|
197
|
-
expect(subject.email).to eq 'robert@example.com'
|
198
|
-
end
|
199
|
-
|
200
|
-
it 'fails with non-existent properties' do
|
201
|
-
expect { subject.merge!(middle_name: 'James') }.to raise_error(NoMethodError)
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'errors out when attempting to set a required property to nil' do
|
205
|
-
expect { subject.merge!(first_name: nil) }.to raise_error(ArgumentError)
|
206
|
-
end
|
207
|
-
|
208
|
-
context 'given a block' do
|
209
|
-
it "sets merged key's values to the block's return value" do
|
210
|
-
expect(subject.merge!(first_name: 'Jim') do |key, oldval, newval|
|
211
|
-
"#{key}: #{newval} #{oldval}"
|
212
|
-
end.first_name).to eq 'first_name: Jim Bob'
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
describe 'properties' do
|
218
|
-
it 'lists defined properties' do
|
219
|
-
expect(described_class.properties).to eq Set.new([:first_name, :email, :count])
|
220
|
-
end
|
221
|
-
|
222
|
-
it 'checks if a property exists' do
|
223
|
-
expect(described_class.property?('first_name')).to be true
|
224
|
-
expect(described_class.property?(:first_name)).to be true
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'checks if a property is required' do
|
228
|
-
expect(described_class.required?('first_name')).to be true
|
229
|
-
expect(described_class.required?(:first_name)).to be true
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'doesnt include property from subclass' do
|
233
|
-
expect(described_class.property?(:last_name)).to be false
|
234
|
-
end
|
235
|
-
|
236
|
-
it 'lists declared defaults' do
|
237
|
-
expect(described_class.defaults).to eq(count: 0)
|
238
|
-
end
|
239
|
-
|
240
|
-
it 'allows properties that end in bang' do
|
241
|
-
expect(PropertyBangTest.property?(:important!)).to be true
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
describe '#replace' do
|
246
|
-
before { subject.replace(first_name: 'Cain') }
|
247
|
-
|
248
|
-
it 'return self' do
|
249
|
-
expect(subject.replace(email: 'bar').to_hash).to eq('email' => 'bar', 'count' => 0)
|
250
|
-
end
|
251
|
-
|
252
|
-
it 'sets all specified keys to their corresponding values' do
|
253
|
-
expect(subject.first_name).to eq 'Cain'
|
254
|
-
end
|
255
|
-
|
256
|
-
it 'leaves only specified keys and keys with default values' do
|
257
|
-
expect(subject.keys.sort).to eq %w(count first_name)
|
258
|
-
expect(subject.email).to be_nil
|
259
|
-
expect(subject.count).to eq 0
|
260
|
-
end
|
261
|
-
|
262
|
-
context 'when replacing keys with default values' do
|
263
|
-
before { subject.replace(count: 3) }
|
264
|
-
|
265
|
-
it 'sets all specified keys to their corresponding values' do
|
266
|
-
expect(subject.count).to eq 3
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
describe Hashie::Dash, 'inheritance' do
|
273
|
-
before do
|
274
|
-
@top = Class.new(Hashie::Dash)
|
275
|
-
@middle = Class.new(@top)
|
276
|
-
@bottom = Class.new(@middle)
|
277
|
-
end
|
278
|
-
|
279
|
-
it 'reports empty properties when nothing defined' do
|
280
|
-
expect(@top.properties).to be_empty
|
281
|
-
expect(@top.defaults).to be_empty
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'inherits properties downwards' do
|
285
|
-
@top.property :echo
|
286
|
-
expect(@middle.properties).to include(:echo)
|
287
|
-
expect(@bottom.properties).to include(:echo)
|
288
|
-
end
|
289
|
-
|
290
|
-
it 'doesnt inherit properties upwards' do
|
291
|
-
@middle.property :echo
|
292
|
-
expect(@top.properties).not_to include(:echo)
|
293
|
-
expect(@bottom.properties).to include(:echo)
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'allows overriding a default on an existing property' do
|
297
|
-
@top.property :echo
|
298
|
-
@middle.property :echo, default: 123
|
299
|
-
expect(@bottom.properties.to_a).to eq [:echo]
|
300
|
-
expect(@bottom.new.echo).to eq 123
|
301
|
-
end
|
302
|
-
|
303
|
-
it 'allows clearing an existing default' do
|
304
|
-
@top.property :echo
|
305
|
-
@middle.property :echo, default: 123
|
306
|
-
@bottom.property :echo
|
307
|
-
expect(@bottom.properties.to_a).to eq [:echo]
|
308
|
-
expect(@bottom.new.echo).to be_nil
|
309
|
-
end
|
310
|
-
|
311
|
-
it 'allows nil defaults' do
|
312
|
-
@bottom.property :echo, default: nil
|
313
|
-
expect(@bottom.new).to have_key('echo')
|
314
|
-
end
|
315
|
-
|
316
|
-
end
|
317
|
-
|
318
|
-
describe Subclassed do
|
319
|
-
subject { Subclassed.new(first_name: 'Bob', last_name: 'McNob', email: 'bob@example.com') }
|
320
|
-
|
321
|
-
describe '#count' do
|
322
|
-
subject { super().count }
|
323
|
-
it { should be_zero }
|
324
|
-
end
|
325
|
-
|
326
|
-
it { should respond_to(:first_name) }
|
327
|
-
it { should respond_to(:first_name=) }
|
328
|
-
it { should respond_to(:last_name) }
|
329
|
-
it { should respond_to(:last_name=) }
|
330
|
-
|
331
|
-
it 'has one additional property' do
|
332
|
-
expect(described_class.property?(:last_name)).to be true
|
333
|
-
end
|
334
|
-
|
335
|
-
it "didn't override superclass inheritance logic" do
|
336
|
-
expect(described_class.instance_variable_get('@inheritance_test')).to be true
|
337
|
-
end
|
338
|
-
end
|