diff options
Diffstat (limited to 'spec/ruby/core/kernel/shared/sprintf.rb')
| -rw-r--r-- | spec/ruby/core/kernel/shared/sprintf.rb | 209 |
1 files changed, 161 insertions, 48 deletions
diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb index 8defbfd665..fe77b5f45b 100644 --- a/spec/ruby/core/kernel/shared/sprintf.rb +++ b/spec/ruby/core/kernel/shared/sprintf.rb @@ -22,12 +22,13 @@ describe :kernel_sprintf, shared: true do @method.call("%d", "112").should == "112" @method.call("%d", "0127").should == "87" @method.call("%d", "0xc4").should == "196" + @method.call("%d", "0").should == "0" end it "raises TypeError exception if cannot convert to Integer" do -> { @method.call("%b", Object.new) - }.should raise_error(TypeError) + }.should.raise(TypeError) end ["b", "B"].each do |f| @@ -57,6 +58,11 @@ describe :kernel_sprintf, shared: true do it "works well with large numbers" do @method.call("%#{f}", 1234567890987654321).should == "1234567890987654321" end + + it "converts to the empty string if precision is 0 and value is 0" do + @method.call("%.#{f}", 0).should == "" + @method.call("%.0#{f}", 0).should == "" + end end end @@ -116,7 +122,7 @@ describe :kernel_sprintf, shared: true do it "raises TypeError exception if cannot convert to Float" do -> { @method.call("%f", Object.new) - }.should raise_error(TypeError) + }.should.raise(TypeError) end {"e" => "e", "E" => "E"}.each_pair do |f, exp| @@ -289,21 +295,64 @@ describe :kernel_sprintf, shared: true do @method.call("%c", "a").should == "a" end - it "raises ArgumentError if argument is a string of several characters" do + it "displays only the first character if argument is a string of several characters" do + @method.call("%c", "abc").should == "a" + end + + it "displays no characters if argument is an empty string" do + @method.call("%c", "").should == "" + end + + it "raises TypeError if argument is not String or Integer and cannot be converted to them" do -> { - @method.call("%c", "abc") - }.should raise_error(ArgumentError) + @method.call("%c", []) + }.should raise_consistent_error(TypeError, /no implicit conversion of Array into Integer/) + end + + it "raises TypeError if argument is nil" do + -> { + @method.call("%c", nil) + }.should raise_consistent_error(TypeError, /no implicit conversion of nil into Integer/) + end + + it "tries to convert argument to String with to_str" do + obj = BasicObject.new + def obj.to_str + "a" + end + + @method.call("%c", obj).should == "a" + end + + it "tries to convert argument to Integer with to_int" do + obj = BasicObject.new + def obj.to_int + 90 + end + + @method.call("%c", obj).should == "Z" end - it "raises ArgumentError if argument is an empty string" do + it "raises TypeError if converting to String with to_str returns non-String" do + obj = BasicObject.new + def obj.to_str + :foo + end + -> { - @method.call("%c", "") - }.should raise_error(ArgumentError) + @method.call("%c", obj) + }.should raise_consistent_error(TypeError, /can't convert BasicObject into String/) end - it "supports Unicode characters" do - @method.call("%c", 1286).should == "Ԇ" - @method.call("%c", "ش").should == "ش" + it "raises TypeError if converting to Integer with to_int returns non-Integer" do + obj = BasicObject.new + def obj.to_int + :foo + end + + -> { + @method.call("%c", obj) + }.should raise_consistent_error(TypeError, /can't convert BasicObject into Integer/) end end @@ -313,6 +362,10 @@ describe :kernel_sprintf, shared: true do obj.should_receive(:inspect).and_return("<inspect-result>") @method.call("%p", obj).should == "<inspect-result>" end + + it "substitutes 'nil' for nil" do + @method.call("%p", nil).should == "nil" + end end describe "s" do @@ -320,6 +373,10 @@ describe :kernel_sprintf, shared: true do @method.call("%s", "abc").should == "abc" end + it "substitutes '' for nil" do + @method.call("%s", nil).should == "" + end + it "converts argument to string with to_s" do obj = mock("string") obj.should_receive(:to_s).and_return("abc") @@ -334,28 +391,65 @@ describe :kernel_sprintf, shared: true do -> { @method.call("%s", obj) - }.should raise_error(NoMethodError) + }.should.raise(NoMethodError) end - end - describe "%" do - ruby_version_is ""..."2.5" do - it "alone displays the percent sign" do - @method.call("%").should == "%" - end + it "formats a partial substring without including omitted characters" do + long_string = "aabbccddhelloddccbbaa" + sub_string = long_string[8, 5] + sprintf("%.#{1 * 3}s", sub_string).should == "hel" end - ruby_version_is "2.5" do - it "alone raises an ArgumentError" do - -> { - @method.call("%") - }.should raise_error(ArgumentError) - end + it "formats string with precision" do + Kernel.format("%.3s", "hello").should == "hel" + Kernel.format("%-3.3s", "hello").should == "hel" + end + + it "formats string with width" do + @method.call("%6s", "abc").should == " abc" + @method.call("%6s", "abcdefg").should == "abcdefg" + end + + it "formats string with width and precision" do + @method.call("%4.6s", "abc").should == " abc" + @method.call("%4.6s", "abcdefg").should == "abcdef" + end + + it "formats nil with width" do + @method.call("%6s", nil).should == " " + end + + it "formats nil with precision" do + @method.call("%.6s", nil).should == "" + end + + it "formats nil with width and precision" do + @method.call("%4.6s", nil).should == " " + end + + it "formats multibyte string with precision" do + Kernel.format("%.2s", "été").should == "ét" + end + + it "preserves encoding of the format string" do + str = format('%s'.encode(Encoding::UTF_8), 'foobar') + str.encoding.should == Encoding::UTF_8 + + str = format('%s'.encode(Encoding::US_ASCII), 'foobar') + str.encoding.should == Encoding::US_ASCII + end + end + + describe "%" do + it "alone raises an ArgumentError" do + -> { + @method.call("%") + }.should.raise(ArgumentError) end it "is escaped by %" do @method.call("%%").should == "%" - @method.call("%%d", 10).should == "%d" + @method.call("%%d").should == "%d" end end end @@ -457,7 +551,7 @@ describe :kernel_sprintf, shared: true do it "raises exception if argument number is bigger than actual arguments list" do -> { @method.call("%4$d", 1, 2, 3) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "ignores '-' sign" do @@ -468,7 +562,7 @@ describe :kernel_sprintf, shared: true do it "raises ArgumentError exception when absolute and relative argument numbers are mixed" do -> { @method.call("%1$d %d", 1, 2) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -718,7 +812,7 @@ describe :kernel_sprintf, shared: true do it "raises ArgumentError when is mixed with width" do -> { @method.call("%*10d", 10, 112) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end end @@ -817,7 +911,7 @@ describe :kernel_sprintf, shared: true do it "cannot be mixed with unnamed style" do -> { @method.call("%d %<foo>d", 1, foo: "123") - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -837,13 +931,30 @@ describe :kernel_sprintf, shared: true do it "cannot be mixed with unnamed style" do -> { @method.call("%d %{foo}", 1, foo: "123") - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end - it "raises KeyError when there is no matching key" do + it "respects Hash#default when there is no set key" do + @method.call("%{foo}", Hash.new(123)).should == "123" + @method.call("%{foo}", Hash.new { 123 }).should == "123" + end + + it "raises KeyError when Hash#default returns nil" do -> { @method.call("%{foo}", {}) - }.should raise_error(KeyError) + }.should.raise(KeyError, 'key{foo} not found') + + -> { + @method.call("%{foo}", Hash.new(nil)) + }.should.raise(KeyError, 'key{foo} not found') + + -> { + @method.call("%{foo}", Hash.new { nil }) + }.should.raise(KeyError, 'key{foo} not found') + end + + it "accepts a nil value for an existing key" do + @method.call("%{foo}", { foo: nil }).should == "" end it "converts value to String with to_s" do @@ -867,25 +978,27 @@ describe :kernel_sprintf, shared: true do it "raises a KeyError" do -> { @method.call("%<foo>s", @object) - }.should raise_error(KeyError) + }.should.raise(KeyError) end - ruby_version_is "2.5" do - it "sets the Hash as the receiver of KeyError" do - -> { - @method.call("%<foo>s", @object) - }.should raise_error(KeyError) { |err| - err.receiver.should equal(@object) - } - end + it "sets the Hash as the receiver of KeyError" do + -> { + @method.call("%<foo>s", @object) + }.should.raise(KeyError) { |err| + err.receiver.should.equal?(@object) + } + end - it "sets the unmatched key as the key of KeyError" do - -> { - @method.call("%<foo>s", @object) - }.should raise_error(KeyError) { |err| - err.key.to_s.should == 'foo' - } - end + it "sets the unmatched key as the key of KeyError" do + -> { + @method.call("%<foo>s", @object) + }.should.raise(KeyError) { |err| + err.key.to_s.should == 'foo' + } end end + + it "does not raise error when passed more arguments than needed" do + sprintf("%s %d %c", "string", 2, "c", []).should == "string 2 c" + end end |
