summaryrefslogtreecommitdiff
path: root/spec/ruby/core/data/deconstruct_keys_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/data/deconstruct_keys_spec.rb')
-rw-r--r--spec/ruby/core/data/deconstruct_keys_spec.rb135
1 files changed, 69 insertions, 66 deletions
diff --git a/spec/ruby/core/data/deconstruct_keys_spec.rb b/spec/ruby/core/data/deconstruct_keys_spec.rb
index 07af87771d..7e81f966ea 100644
--- a/spec/ruby/core/data/deconstruct_keys_spec.rb
+++ b/spec/ruby/core/data/deconstruct_keys_spec.rb
@@ -1,107 +1,110 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-ruby_version_is "3.2" do
- describe "Data#deconstruct" do
- it "returns a hash of attributes" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
- d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
- end
+describe "Data#deconstruct_keys" do
+ it "returns a hash of attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- it "requires one argument" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
+ end
- -> {
- d.deconstruct_keys
- }.should raise_error(ArgumentError, /wrong number of arguments \(given 0, expected 1\)/)
- end
+ it "requires one argument" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- it "returns only specified keys" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ -> {
+ d.deconstruct_keys
+ }.should.raise(ArgumentError, /wrong number of arguments \(given 0, expected 1\)/)
+ end
- d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
- d.deconstruct_keys([:x] ).should == {x: 1}
- d.deconstruct_keys([] ).should == {}
- end
+ it "returns only specified keys" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- it "accepts string attribute names" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
- d.deconstruct_keys(['x', 'y']).should == {'x' => 1, 'y' => 2}
- end
+ d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
+ d.deconstruct_keys([:x] ).should == {x: 1}
+ d.deconstruct_keys([] ).should == {}
+ end
- it "accepts argument position number as well but returns them as keys" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ it "accepts string attribute names" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- d.deconstruct_keys([0, 1]).should == {0 => 1, 1 => 2}
- d.deconstruct_keys([0] ).should == {0 => 1}
- d.deconstruct_keys([-1] ).should == {-1 => 2}
- end
+ d.deconstruct_keys(['x', 'y']).should == {'x' => 1, 'y' => 2}
+ end
- it "ignores incorrect position numbers" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ it "returns an empty hash when there are more keys than attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- d.deconstruct_keys([0, 3]).should == {0 => 1}
- end
+ d.deconstruct_keys([:x, :y, :x]).should == {}
+ end
- it "support mixing attribute names and argument position numbers" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ it "returns at first not existing attribute name" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- d.deconstruct_keys([0, :x]).should == {0 => 1, :x => 1}
- end
+ d.deconstruct_keys([:a, :x]).should == {}
+ d.deconstruct_keys([:x, :a]).should == {x: 1}
+ end
- it "returns an empty hash when there are more keys than attributes" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
- d.deconstruct_keys([:x, :y, :x]).should == {}
- end
+ it "accepts nil argument and return all the attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- it "returns at first not existing attribute name" do
+ d.deconstruct_keys(nil).should == {x: 1, y: 2}
+ end
+
+ ruby_version_is "4.0" do # https://bugs.ruby-lang.org/issues/21844
+ it "tries to convert a key with #to_str if index is not a String nor a Symbol, but responds to #to_str" do
klass = Data.define(:x, :y)
d = klass.new(1, 2)
- d.deconstruct_keys([:a, :x]).should == {}
- d.deconstruct_keys([:x, :a]).should == {x: 1}
+ key = mock("to_str")
+ key.should_receive(:to_str).and_return("y")
+
+ d.deconstruct_keys([key]).should == { "y" => 2 }
end
- it "returns at first not existing argument position number" do
+ it "raise an error on argument position number" do
klass = Data.define(:x, :y)
d = klass.new(1, 2)
- d.deconstruct_keys([3, 0]).should == {}
- d.deconstruct_keys([0, 3]).should == {0 => 1}
+ -> {
+ d.deconstruct_keys([0, 1])
+ }.should.raise(TypeError, "0 is not a symbol nor a string")
end
- it "accepts nil argument and return all the attributes" do
+ it "raises a TypeError if the conversion with #to_str does not return a String" do
klass = Data.define(:x, :y)
d = klass.new(1, 2)
- d.deconstruct_keys(nil).should == {x: 1, y: 2}
+ key = mock("to_str")
+ key.should_receive(:to_str).and_return(0)
+
+ -> {
+ d.deconstruct_keys([key])
+ }.should raise_consistent_error(TypeError, /can't convert MockObject into String/)
end
- it "raises TypeError if index is not a String, a Symbol and not convertible to Integer " do
+ it "raises TypeError if index is not a Symbol and not convertible to String" do
klass = Data.define(:x, :y)
d = klass.new(1, 2)
-> {
d.deconstruct_keys([0, []])
- }.should raise_error(TypeError, "no implicit conversion of Array into Integer")
+ }.should.raise(TypeError, "0 is not a symbol nor a string")
end
+ end
- it "raise TypeError if passed anything except nil or array" do
- klass = Data.define(:x, :y)
- d = klass.new(1, 2)
+ it "raise TypeError if passed anything except nil or array" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
- -> { d.deconstruct_keys('x') }.should raise_error(TypeError, /expected Array or nil/)
- -> { d.deconstruct_keys(1) }.should raise_error(TypeError, /expected Array or nil/)
- -> { d.deconstruct_keys(:x) }.should raise_error(TypeError, /expected Array or nil/)
- -> { d.deconstruct_keys({}) }.should raise_error(TypeError, /expected Array or nil/)
- end
+ -> { d.deconstruct_keys('x') }.should.raise(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys(1) }.should.raise(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys(:x) }.should.raise(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys({}) }.should.raise(TypeError, /expected Array or nil/)
end
end