diff options
Diffstat (limited to 'spec/ruby/core/data/deconstruct_keys_spec.rb')
| -rw-r--r-- | spec/ruby/core/data/deconstruct_keys_spec.rb | 135 |
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 |
