summaryrefslogtreecommitdiff
path: root/spec/hashie/dash_spec.rb
diff options
context:
space:
mode:
authorMichael Herold <opensource@michaeljherold.com>2020-10-22 21:07:14 -0500
committerMichael Herold <opensource@michaeljherold.com>2020-10-22 21:07:14 -0500
commit98df995e2f0433d3d1abe46efd732bc8e20e31cc (patch)
tree0e6471bf261fcd79dd641867ad1c50ff7b687ee8 /spec/hashie/dash_spec.rb
parentb9a93916f538bfab57815a1d48740c826715ca5d (diff)
downloadhashie-98df995e2f0433d3d1abe46efd732bc8e20e31cc.tar.gz
Ensure all properties are set on exported Dash
When exporting a Dash via `#to_h` or `#to_hash`, we expect all properties to be exported whether or not they are set. However, in the change that allows codependent properties to be nilified, we regressed the behavior of exporting all properties. There is a gotcha here, which I note in the tests for the specs. For posterity, MRI does not send the `#to_hash` method to anything that subclasses `Hash` when you double-splat it. Thus, we cannot override the behavior within MRI. For more information, see [this comment][1] where I detail the behavior of double-splat within MRI. Currently, JRuby also follows this behavior, but it's not guaranteed that other Rubies will. [1]: https://github.com/hashie/hashie/issues/353#issuecomment-363294886
Diffstat (limited to 'spec/hashie/dash_spec.rb')
-rw-r--r--spec/hashie/dash_spec.rb76
1 files changed, 76 insertions, 0 deletions
diff --git a/spec/hashie/dash_spec.rb b/spec/hashie/dash_spec.rb
index c64e400..e75ad1a 100644
--- a/spec/hashie/dash_spec.rb
+++ b/spec/hashie/dash_spec.rb
@@ -416,6 +416,7 @@ describe DashTest do
Class.new(Hashie::Dash) do
property :a, required: -> { b.nil? }, message: 'is required if b is not set.'
property :b, required: -> { a.nil? }, message: 'is required if a is not set.'
+ property :c, default: -> { 'c' }
end
end
@@ -434,6 +435,44 @@ describe DashTest do
it 'raises an error when neither property is set' do
expect { codependent.new(a: nil, b: nil) }.to raise_error(ArgumentError)
end
+
+ context 'exporting nil values' do
+ describe '#to_h' do
+ it 'does not prune nil values' do
+ expect(codependent.new(a: 'hi', b: nil).to_h).to eq(a: 'hi', b: nil, c: 'c')
+ expect(codependent.new(a: 'hi', b: nil, c: nil).to_hash).to eq(a: 'hi', b: nil, c: 'c')
+ expect(codependent.new(a: 'hi', b: nil).merge(c: nil).to_h).to(
+ eq(a: 'hi', b: nil, c: nil)
+ )
+ end
+ end
+
+ describe '#to_hash' do
+ it 'does not prune nil values' do
+ expect(codependent.new(a: 'hi', b: nil).to_hash).to eq(a: 'hi', b: nil, c: 'c')
+ expect(codependent.new(a: 'hi', b: nil, c: nil).to_hash).to eq(a: 'hi', b: nil, c: 'c')
+ expect(codependent.new(a: 'hi', b: nil).merge(c: nil).to_hash).to(
+ eq(a: 'hi', b: nil, c: nil)
+ )
+ end
+ end
+
+ describe '**' do
+ # Note: This test is an implementation detail of MRI and may not hold for
+ # other Ruby interpreters. But it's important to note in the test suite
+ # because it can be surprising for people unfamiliar with the semantics of
+ # double-splatting.
+ #
+ # For more information, see [this link][1]:
+ #
+ # [1]: https://github.com/hashie/hashie/issues/353#issuecomment-363294886
+ it 'prunes nil values because they are not set in the dash' do
+ dash = codependent.new(a: 'hi', b: nil)
+
+ expect(**dash).to eq(a: 'hi', c: 'c')
+ end
+ end
+ end
end
end
end
@@ -482,6 +521,43 @@ describe Hashie::Dash, 'inheritance' do
expect(@bottom.new).to have_key(:echo)
expect(@bottom.new).to_not have_key('echo')
end
+
+ context 'exporting nil values' do
+ let(:test) do
+ Class.new(Hashie::Dash) do
+ property :foo
+ property :bar
+ end
+ end
+
+ describe '#to_h' do
+ it 'does not prune nil values' do
+ expect(test.new(foo: 'hi', bar: nil).to_h).to eq(foo: 'hi', bar: nil)
+ end
+ end
+
+ describe '#to_hash' do
+ it 'does not prune nil values' do
+ expect(test.new(foo: 'hi', bar: nil).to_hash).to eq(foo: 'hi', bar: nil)
+ end
+ end
+
+ describe '**' do
+ # Note: This test is an implementation detail of MRI and may not hold for
+ # other Ruby interpreters. But it's important to note in the test suite
+ # because it can be surprising for people unfamiliar with the semantics of
+ # double-splatting.
+ #
+ # For more information, see [this link][1]:
+ #
+ # [1]: https://github.com/hashie/hashie/issues/353#issuecomment-363294886
+ it 'prunes nil values because they are not set in the dash' do
+ dash = test.new(foo: 'hi', bar: nil)
+
+ expect(**dash).to eq(foo: 'hi')
+ end
+ end
+ end
end
describe SubclassedTest do