summaryrefslogtreecommitdiff
path: root/spec/ruby/core/string/modulo_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/string/modulo_spec.rb')
-rw-r--r--spec/ruby/core/string/modulo_spec.rb144
1 files changed, 67 insertions, 77 deletions
diff --git a/spec/ruby/core/string/modulo_spec.rb b/spec/ruby/core/string/modulo_spec.rb
index 0ac0963403..46e0aa0f36 100644
--- a/spec/ruby/core/string/modulo_spec.rb
+++ b/spec/ruby/core/string/modulo_spec.rb
@@ -1,8 +1,22 @@
require_relative '../../spec_helper'
+require_relative '../kernel/shared/sprintf'
+require_relative '../kernel/shared/sprintf_encoding'
require_relative 'fixtures/classes'
require_relative '../../shared/hash/key_error'
describe "String#%" do
+ it_behaves_like :kernel_sprintf, -> format, *args {
+ format % args
+ }
+
+ it_behaves_like :kernel_sprintf_encoding, -> format, *args {
+ format % args
+ }
+end
+
+# TODO: these specs are mostly redundant with kernel/shared/sprintf.rb specs.
+# These specs should be moved there and deduplicated.
+describe "String#%" do
context "when key is missing from passed-in hash" do
it_behaves_like :key_error, -> obj, key { "%{#{key}}" % obj }, { a: 5 }
end
@@ -36,47 +50,53 @@ describe "String#%" do
end
end
- ruby_version_is ""..."2.5" do
- it "formats single % character at the end as literal %" do
- ("%" % []).should == "%"
- ("foo%" % []).should == "foo%"
- end
+ it "raises an error if single % appears at the end" do
+ -> { ("%" % []) }.should raise_error(ArgumentError)
+ -> { ("foo%" % [])}.should raise_error(ArgumentError)
end
- ruby_version_is "2.5" do
- it "raises an error if single % appears at the end" do
- -> { ("%" % []) }.should raise_error(ArgumentError)
- -> { ("foo%" % [])}.should raise_error(ArgumentError)
+ ruby_version_is ""..."3.4" do
+ it "formats single % character before a newline as literal %" do
+ ("%\n" % []).should == "%\n"
+ ("foo%\n" % []).should == "foo%\n"
+ ("%\n.3f" % 1.2).should == "%\n.3f"
end
- end
- it "formats single % character before a newline as literal %" do
- ("%\n" % []).should == "%\n"
- ("foo%\n" % []).should == "foo%\n"
- ("%\n.3f" % 1.2).should == "%\n.3f"
- end
+ it "formats single % character before a NUL as literal %" do
+ ("%\0" % []).should == "%\0"
+ ("foo%\0" % []).should == "foo%\0"
+ ("%\0.3f" % 1.2).should == "%\0.3f"
+ end
- it "formats single % character before a NUL as literal %" do
- ("%\0" % []).should == "%\0"
- ("foo%\0" % []).should == "foo%\0"
- ("%\0.3f" % 1.2).should == "%\0.3f"
- end
+ it "raises an error if single % appears anywhere else" do
+ -> { (" % " % []) }.should raise_error(ArgumentError)
+ -> { ("foo%quux" % []) }.should raise_error(ArgumentError)
+ end
- it "raises an error if single % appears anywhere else" do
- -> { (" % " % []) }.should raise_error(ArgumentError)
- -> { ("foo%quux" % []) }.should raise_error(ArgumentError)
- end
+ it "raises an error if NULL or \\n appear anywhere else in the format string" do
+ begin
+ old_debug, $DEBUG = $DEBUG, false
- it "raises an error if NULL or \\n appear anywhere else in the format string" do
- begin
- old_debug, $DEBUG = $DEBUG, false
+ -> { "%.\n3f" % 1.2 }.should raise_error(ArgumentError)
+ -> { "%.3\nf" % 1.2 }.should raise_error(ArgumentError)
+ -> { "%.\03f" % 1.2 }.should raise_error(ArgumentError)
+ -> { "%.3\0f" % 1.2 }.should raise_error(ArgumentError)
+ ensure
+ $DEBUG = old_debug
+ end
+ end
+ end
+ ruby_version_is "3.4" do
+ it "raises an ArgumentError if % is not followed by a conversion specifier" do
+ -> { "%" % [] }.should raise_error(ArgumentError)
+ -> { "%\n" % [] }.should raise_error(ArgumentError)
+ -> { "%\0" % [] }.should raise_error(ArgumentError)
+ -> { " % " % [] }.should raise_error(ArgumentError)
-> { "%.\n3f" % 1.2 }.should raise_error(ArgumentError)
-> { "%.3\nf" % 1.2 }.should raise_error(ArgumentError)
-> { "%.\03f" % 1.2 }.should raise_error(ArgumentError)
-> { "%.3\0f" % 1.2 }.should raise_error(ArgumentError)
- ensure
- $DEBUG = old_debug
end
end
@@ -120,8 +140,16 @@ describe "String#%" do
end
end
- it "replaces trailing absolute argument specifier without type with percent sign" do
- ("hello %1$" % "foo").should == "hello %"
+ ruby_version_is ""..."3.4" do
+ it "replaces trailing absolute argument specifier without type with percent sign" do
+ ("hello %1$" % "foo").should == "hello %"
+ end
+ end
+
+ ruby_version_is "3.4" do
+ it "raises an ArgumentError if absolute argument specifier is followed by a conversion specifier" do
+ -> { "hello %1$" % "foo" }.should raise_error(ArgumentError)
+ end
end
it "raises an ArgumentError when given invalid argument specifiers" do
@@ -297,27 +325,6 @@ describe "String#%" do
end
end
- it "always taints the result when the format string is tainted" do
- universal = mock('0')
- def universal.to_int() 0 end
- def universal.to_str() "0" end
- def universal.to_f() 0.0 end
-
- [
- "", "foo",
- "%b", "%B", "%c", "%d", "%e", "%E",
- "%f", "%g", "%G", "%i", "%o", "%p",
- "%s", "%u", "%x", "%X"
- ].each do |format|
- subcls_format = StringSpecs::MyString.new(format)
- subcls_format.taint
- format.taint
-
- (format % universal).tainted?.should == true
- (subcls_format % universal).tainted?.should == true
- end
- end
-
it "supports binary formats using %b for positive numbers" do
("%b" % 10).should == "1010"
("% b" % 10).should == " 1010"
@@ -384,8 +391,8 @@ describe "String#%" do
("%c" % 'A').should == "A"
end
- it "raises an exception for multiple character strings as argument for %c" do
- -> { "%c" % 'AA' }.should raise_error(ArgumentError)
+ it "supports only the first character as argument for %c" do
+ ("%c" % 'AA').should == "A"
end
it "calls to_str on argument for %c formats" do
@@ -555,7 +562,7 @@ describe "String#%" do
("%1$p" % [10, 5]).should == "10"
("%-22p" % 10).should == "10 "
("%*p" % [10, 10]).should == " 10"
- ("%p" % {capture: 1}).should == "{:capture=>1}"
+ ("%p" % {capture: 1}).should == {capture: 1}.inspect
("%p" % "str").should == "\"str\""
end
@@ -571,18 +578,6 @@ describe "String#%" do
# ("%p" % obj).should == "obj"
end
- it "taints result for %p when argument.inspect is tainted" do
- obj = mock('x')
- def obj.inspect() "x".taint end
-
- ("%p" % obj).tainted?.should == true
-
- obj = mock('x'); obj.taint
- def obj.inspect() "x" end
-
- ("%p" % obj).tainted?.should == false
- end
-
it "supports string formats using %s" do
("%s" % "hello").should == "hello"
("%s" % "").should == ""
@@ -611,11 +606,6 @@ describe "String#%" do
# ("%s" % obj).should == "obj"
end
- it "taints result for %s when argument is tainted" do
- ("%s" % "x".taint).tainted?.should == true
- ("%s" % mock('x').taint).tainted?.should == true
- end
-
# MRI crashes on this one.
# See http://groups.google.com/group/ruby-core-google/t/c285c18cd94c216d
it "raises an ArgumentError for huge precisions for %s" do
@@ -751,6 +741,11 @@ describe "String#%" do
(format % "-10.4e-20").should == (format % -10.4e-20)
(format % ".5").should == (format % 0.5)
(format % "-.5").should == (format % -0.5)
+
+ ruby_version_is "3.4" do
+ (format % "10.").should == (format % 10)
+ end
+
# Something's strange with this spec:
# it works just fine in individual mode, but not when run as part of a group
(format % "10_1_0.5_5_5").should == (format % 1010.555)
@@ -760,7 +755,6 @@ describe "String#%" do
-> { format % "" }.should raise_error(ArgumentError)
-> { format % "x" }.should raise_error(ArgumentError)
-> { format % "." }.should raise_error(ArgumentError)
- -> { format % "10." }.should raise_error(ArgumentError)
-> { format % "5x" }.should raise_error(ArgumentError)
-> { format % "0b1" }.should raise_error(ArgumentError)
-> { format % "10e10.5" }.should raise_error(ArgumentError)
@@ -775,10 +769,6 @@ describe "String#%" do
it "behaves as if calling Kernel#Float for #{format} arguments, when the passed argument is hexadecimal string" do
(format % "0xA").should == (format % 0xA)
end
-
- it "doesn't taint the result for #{format} when argument is tainted" do
- (format % "5".taint).tainted?.should == false
- end
end
describe "when format string contains %{} sections" do