diff options
Diffstat (limited to 'spec/ruby/core/matchdata')
23 files changed, 523 insertions, 170 deletions
diff --git a/spec/ruby/core/matchdata/allocate_spec.rb b/spec/ruby/core/matchdata/allocate_spec.rb index 142ce639c2..f41e2d5481 100644 --- a/spec/ruby/core/matchdata/allocate_spec.rb +++ b/spec/ruby/core/matchdata/allocate_spec.rb @@ -3,6 +3,6 @@ require_relative '../../spec_helper' describe "MatchData.allocate" do it "is undefined" do # https://bugs.ruby-lang.org/issues/16294 - -> { MatchData.allocate }.should raise_error(NoMethodError) + -> { MatchData.allocate }.should.raise(NoMethodError) end end diff --git a/spec/ruby/core/matchdata/begin_spec.rb b/spec/ruby/core/matchdata/begin_spec.rb index 54b4e0a33f..b4be077ae4 100644 --- a/spec/ruby/core/matchdata/begin_spec.rb +++ b/spec/ruby/core/matchdata/begin_spec.rb @@ -12,7 +12,7 @@ describe "MatchData#begin" do it "returns nil when the nth match isn't found" do match_data = /something is( not)? (right)/.match("something is right") - match_data.begin(1).should be_nil + match_data.begin(1).should == nil end it "returns the character offset for multi-byte strings" do @@ -42,11 +42,11 @@ describe "MatchData#begin" do -> { match_data.begin(-1) - }.should raise_error(IndexError, "index -1 out of matches") + }.should.raise(IndexError, "index -1 out of matches") -> { match_data.begin(3) - }.should raise_error(IndexError, "index 3 out of matches") + }.should.raise(IndexError, "index 3 out of matches") end end @@ -86,7 +86,7 @@ describe "MatchData#begin" do -> { match_data.begin("y") - }.should raise_error(IndexError, "undefined group name reference: y") + }.should.raise(IndexError, "undefined group name reference: y") end end @@ -126,7 +126,7 @@ describe "MatchData#begin" do -> { match_data.begin(:y) - }.should raise_error(IndexError, "undefined group name reference: y") + }.should.raise(IndexError, "undefined group name reference: y") end end end diff --git a/spec/ruby/core/matchdata/bytebegin_spec.rb b/spec/ruby/core/matchdata/bytebegin_spec.rb new file mode 100644 index 0000000000..fa44ec3b41 --- /dev/null +++ b/spec/ruby/core/matchdata/bytebegin_spec.rb @@ -0,0 +1,132 @@ +require_relative '../../spec_helper' + +ruby_version_is "3.4" do + describe "MatchData#bytebegin" do + context "when passed an integer argument" do + it "returns the byte-based offset of the start of the nth element" do + match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") + match_data.bytebegin(0).should == 1 + match_data.bytebegin(2).should == 2 + end + + it "returns nil when the nth match isn't found" do + match_data = /something is( not)? (right)/.match("something is right") + match_data.bytebegin(1).should == nil + end + + it "returns the byte-based offset for multi-byte strings" do + match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.") + match_data.bytebegin(0).should == 1 + match_data.bytebegin(2).should == 3 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi-byte strings with unicode regexp" do + match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.") + match_data.bytebegin(0).should == 1 + match_data.bytebegin(2).should == 3 + end + end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(2) + + match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") + match_data.bytebegin(obj).should == 2 + end + + it "raises IndexError if index is out of bounds" do + match_data = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + match_data.bytebegin(-1) + }.should.raise(IndexError, "index -1 out of matches") + + -> { + match_data.bytebegin(3) + }.should.raise(IndexError, "index 3 out of matches") + end + end + + context "when passed a String argument" do + it "return the byte-based offset of the start of the named capture" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.bytebegin("a").should == 1 + match_data.bytebegin("b").should == 3 + end + + it "returns the byte-based offset for multi byte strings" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.") + match_data.bytebegin("a").should == 1 + match_data.bytebegin("b").should == 4 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi byte strings with unicode regexp" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.") + match_data.bytebegin("a").should == 1 + match_data.bytebegin("b").should == 4 + end + end + + it "returns the byte-based offset for the farthest match when multiple named captures use the same name" do + match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.") + match_data.bytebegin("a").should == 3 + end + + it "returns the byte-based offset for multi-byte names" do + match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.bytebegin("æ").should == 1 + end + + it "raises IndexError if there is no group with the provided name" do + match_data = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + match_data.bytebegin("y") + }.should.raise(IndexError, "undefined group name reference: y") + end + end + + context "when passed a Symbol argument" do + it "return the byte-based offset of the start of the named capture" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.bytebegin(:a).should == 1 + match_data.bytebegin(:b).should == 3 + end + + it "returns the byte-based offset for multi byte strings" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.") + match_data.bytebegin(:a).should == 1 + match_data.bytebegin(:b).should == 4 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi byte strings with unicode regexp" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.") + match_data.bytebegin(:a).should == 1 + match_data.bytebegin(:b).should == 4 + end + end + + it "returns the byte-based offset for the farthest match when multiple named captures use the same name" do + match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.") + match_data.bytebegin(:a).should == 3 + end + + it "returns the byte-based offset for multi-byte names" do + match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.bytebegin(:æ).should == 1 + end + + it "raises IndexError if there is no group with the provided name" do + match_data = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + match_data.bytebegin(:y) + }.should.raise(IndexError, "undefined group name reference: y") + end + end + end +end diff --git a/spec/ruby/core/matchdata/byteend_spec.rb b/spec/ruby/core/matchdata/byteend_spec.rb new file mode 100644 index 0000000000..e77cbf8b0d --- /dev/null +++ b/spec/ruby/core/matchdata/byteend_spec.rb @@ -0,0 +1,104 @@ +require_relative '../../spec_helper' + +ruby_version_is "3.4" do + describe "MatchData#byteend" do + context "when passed an integer argument" do + it "returns the byte-based offset of the end of the nth element" do + match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") + match_data.byteend(0).should == 7 + match_data.byteend(2).should == 3 + end + + it "returns nil when the nth match isn't found" do + match_data = /something is( not)? (right)/.match("something is right") + match_data.byteend(1).should == nil + end + + it "returns the byte-based offset for multi-byte strings" do + match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.") + match_data.byteend(0).should == 8 + match_data.byteend(2).should == 4 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi-byte strings with unicode regexp" do + match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.") + match_data.byteend(0).should == 8 + match_data.byteend(2).should == 4 + end + end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(2) + + match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") + match_data.byteend(obj).should == 3 + end + end + + context "when passed a String argument" do + it "return the byte-based offset of the start of the named capture" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.byteend("a").should == 2 + match_data.byteend("b").should == 6 + end + + it "returns the byte-based offset for multi byte strings" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.") + match_data.byteend("a").should == 3 + match_data.byteend("b").should == 7 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi byte strings with unicode regexp" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.") + match_data.byteend("a").should == 3 + match_data.byteend("b").should == 7 + end + end + + it "returns the byte-based offset for the farthest match when multiple named captures use the same name" do + match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.") + match_data.byteend("a").should == 6 + end + + it "returns the byte-based offset for multi-byte names" do + match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.byteend("æ").should == 2 + end + end + + context "when passed a Symbol argument" do + it "return the byte-based offset of the start of the named capture" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.byteend(:a).should == 2 + match_data.byteend(:b).should == 6 + end + + it "returns the byte-based offset for multi byte strings" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.") + match_data.byteend(:a).should == 3 + match_data.byteend(:b).should == 7 + end + + not_supported_on :opal do + it "returns the byte-based offset for multi byte strings with unicode regexp" do + match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.") + match_data.byteend(:a).should == 3 + match_data.byteend(:b).should == 7 + end + end + + it "returns the byte-based offset for the farthest match when multiple named captures use the same name" do + match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.") + match_data.byteend(:a).should == 6 + end + + it "returns the byte-based offset for multi-byte names" do + match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") + match_data.byteend(:æ).should == 2 + end + end + end +end diff --git a/spec/ruby/core/matchdata/byteoffset_spec.rb b/spec/ruby/core/matchdata/byteoffset_spec.rb index b27267fd0e..062e84027c 100644 --- a/spec/ruby/core/matchdata/byteoffset_spec.rb +++ b/spec/ruby/core/matchdata/byteoffset_spec.rb @@ -1,95 +1,93 @@ require_relative '../../spec_helper' describe "MatchData#byteoffset" do - ruby_version_is "3.2" do - it "returns beginning and ending byte-based offset of whole matched substring for 0 element" do - m = /(.)(.)(\d+)(\d)/.match("THX1138.") - m.byteoffset(0).should == [1, 7] - end + it "returns beginning and ending byte-based offset of whole matched substring for 0 element" do + m = /(.)(.)(\d+)(\d)/.match("THX1138.") + m.byteoffset(0).should == [1, 7] + end - it "returns beginning and ending byte-based offset of n-th match, all the subsequent elements are capturing groups" do - m = /(.)(.)(\d+)(\d)/.match("THX1138.") + it "returns beginning and ending byte-based offset of n-th match, all the subsequent elements are capturing groups" do + m = /(.)(.)(\d+)(\d)/.match("THX1138.") - m.byteoffset(2).should == [2, 3] - m.byteoffset(3).should == [3, 6] - m.byteoffset(4).should == [6, 7] - end + m.byteoffset(2).should == [2, 3] + m.byteoffset(3).should == [3, 6] + m.byteoffset(4).should == [6, 7] + end - it "accepts String as a reference to a named capture" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "accepts String as a reference to a named capture" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - m.byteoffset("f").should == [0, 3] - m.byteoffset("b").should == [3, 6] - end + m.byteoffset("f").should == [0, 3] + m.byteoffset("b").should == [3, 6] + end - it "accepts Symbol as a reference to a named capture" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "accepts Symbol as a reference to a named capture" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - m.byteoffset(:f).should == [0, 3] - m.byteoffset(:b).should == [3, 6] - end + m.byteoffset(:f).should == [0, 3] + m.byteoffset(:b).should == [3, 6] + end - it "returns [nil, nil] if a capturing group is optional and doesn't match" do - m = /(?<x>q..)?/.match("foobarbaz") + it "returns [nil, nil] if a capturing group is optional and doesn't match" do + m = /(?<x>q..)?/.match("foobarbaz") - m.byteoffset("x").should == [nil, nil] - m.byteoffset(1).should == [nil, nil] - end + m.byteoffset("x").should == [nil, nil] + m.byteoffset(1).should == [nil, nil] + end - it "returns correct beginning and ending byte-based offset for multi-byte strings" do - m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") + it "returns correct beginning and ending byte-based offset for multi-byte strings" do + m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") - m.byteoffset(1).should == [3, 6] - m.byteoffset(3).should == [6, 9] - end + m.byteoffset(1).should == [3, 6] + m.byteoffset(3).should == [6, 9] + end - it "returns [nil, nil] if a capturing group is optional and doesn't match for multi-byte string" do - m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") + it "returns [nil, nil] if a capturing group is optional and doesn't match for multi-byte string" do + m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") - m.byteoffset(2).should == [nil, nil] - end + m.byteoffset(2).should == [nil, nil] + end - it "converts argument into integer if is not String nor Symbol" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "converts argument into integer if is not String nor Symbol" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - obj = Object.new - def obj.to_int; 2; end + obj = Object.new + def obj.to_int; 2; end - m.byteoffset(1r).should == [0, 3] - m.byteoffset(1.1).should == [0, 3] - m.byteoffset(obj).should == [3, 6] - end + m.byteoffset(1r).should == [0, 3] + m.byteoffset(1.1).should == [0, 3] + m.byteoffset(obj).should == [3, 6] + end - it "raises IndexError if there is no group with the provided name" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "raises IndexError if there is no group with the provided name" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - -> { - m.byteoffset("y") - }.should raise_error(IndexError, "undefined group name reference: y") + -> { + m.byteoffset("y") + }.should.raise(IndexError, "undefined group name reference: y") - -> { - m.byteoffset(:y) - }.should raise_error(IndexError, "undefined group name reference: y") - end + -> { + m.byteoffset(:y) + }.should.raise(IndexError, "undefined group name reference: y") + end - it "raises IndexError if index is out of bounds" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "raises IndexError if index is out of bounds" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - -> { - m.byteoffset(-1) - }.should raise_error(IndexError, "index -1 out of matches") + -> { + m.byteoffset(-1) + }.should.raise(IndexError, "index -1 out of matches") - -> { - m.byteoffset(3) - }.should raise_error(IndexError, "index 3 out of matches") - end + -> { + m.byteoffset(3) + }.should.raise(IndexError, "index 3 out of matches") + end - it "raises TypeError if can't convert argument into Integer" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "raises TypeError if can't convert argument into Integer" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - -> { - m.byteoffset([]) - }.should raise_error(TypeError, "no implicit conversion of Array into Integer") - end + -> { + m.byteoffset([]) + }.should.raise(TypeError, "no implicit conversion of Array into Integer") end end diff --git a/spec/ruby/core/matchdata/deconstruct_keys_spec.rb b/spec/ruby/core/matchdata/deconstruct_keys_spec.rb index 5b68f886c7..9126d20394 100644 --- a/spec/ruby/core/matchdata/deconstruct_keys_spec.rb +++ b/spec/ruby/core/matchdata/deconstruct_keys_spec.rb @@ -1,65 +1,78 @@ require_relative '../../spec_helper' describe "MatchData#deconstruct_keys" do - ruby_version_is "3.2" do - it "returns whole hash for nil as an argument" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + it "returns whole hash for nil as an argument" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - m.deconstruct_keys(nil).should == { f: "foo", b: "bar" } - end + m.deconstruct_keys(nil).should == { f: "foo", b: "bar" } + end + + it "returns only specified keys" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - it "returns only specified keys" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + m.deconstruct_keys([:f]).should == { f: "foo" } + end - m.deconstruct_keys([:f]).should == { f: "foo" } - end + it "requires one argument" do + m = /l/.match("l") - it "requires one argument" do - m = /l/.match("l") + -> { + m.deconstruct_keys + }.should.raise(ArgumentError, "wrong number of arguments (given 0, expected 1)") + end + + it "it raises error when argument is neither nil nor array" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { m.deconstruct_keys(1) }.should.raise(TypeError, "wrong argument type Integer (expected Array)") + -> { m.deconstruct_keys("asd") }.should.raise(TypeError, "wrong argument type String (expected Array)") + -> { m.deconstruct_keys(:x) }.should.raise(TypeError, "wrong argument type Symbol (expected Array)") + -> { m.deconstruct_keys({}) }.should.raise(TypeError, "wrong argument type Hash (expected Array)") + end - -> { - m.deconstruct_keys - }.should raise_error(ArgumentError, "wrong number of arguments (given 0, expected 1)") - end + it "returns {} when passed []" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - it "it raises error when argument is neither nil nor array" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + m.deconstruct_keys([]).should == {} + end - -> { m.deconstruct_keys(1) }.should raise_error(TypeError, "wrong argument type Integer (expected Array)") - -> { m.deconstruct_keys("asd") }.should raise_error(TypeError, "wrong argument type String (expected Array)") - -> { m.deconstruct_keys(:x) }.should raise_error(TypeError, "wrong argument type Symbol (expected Array)") - -> { m.deconstruct_keys({}) }.should raise_error(TypeError, "wrong argument type Hash (expected Array)") - end + it "does not accept non-Symbol keys" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") - it "returns {} when passed []" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + -> { + m.deconstruct_keys(['year', :foo]) + }.should.raise(TypeError, "wrong argument type String (expected Symbol)") + end - m.deconstruct_keys([]).should == {} - end + it "process keys till the first non-existing one" do + m = /(?<f>foo)(?<b>bar)(?<c>baz)/.match("foobarbaz") - it "does not accept non-Symbol keys" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") + m.deconstruct_keys([:f, :a, :b]).should == { f: "foo" } + end - -> { - m.deconstruct_keys(['year', :foo]) - }.should raise_error(TypeError, "wrong argument type String (expected Symbol)") - end + it "returns {} when there are no named captured groups at all" do + m = /foo.+/.match("foobar") - it "process keys till the first non-existing one" do - m = /(?<f>foo)(?<b>bar)(?<c>baz)/.match("foobarbaz") + m.deconstruct_keys(nil).should == {} + end - m.deconstruct_keys([:f, :a, :b]).should == { f: "foo" } - end + it "returns {} when passed more keys than named captured groups" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + m.deconstruct_keys([:f, :b, :c]).should == {} + end - it "returns {} when there are no named captured groups at all" do - m = /foo.+/.match("foobar") + it "includes non-participating captures as nil for nil argument" do + m = "hello".match(/(?<a>hello)(?<b>world)?/) + m.deconstruct_keys(nil).should == { a: "hello", b: nil } + end - m.deconstruct_keys(nil).should == {} - end + it "includes non-participating captures as nil for explicit keys" do + m = "hello".match(/(?<a>hello)(?<b>world)?/) + m.deconstruct_keys([:a, :b]).should == { a: "hello", b: nil } + end - it "returns {} when passed more keys than named captured groups" do - m = /(?<f>foo)(?<b>bar)/.match("foobar") - m.deconstruct_keys([:f, :b, :c]).should == {} - end + it "does not stop iterating at a non-participating capture" do + m = "hello!".match(/(?<a>hello)(?<b>world)?(?<c>!)/) + m.deconstruct_keys([:b, :c, :a]).should == { b: nil, c: "!", a: "hello" } end end diff --git a/spec/ruby/core/matchdata/deconstruct_spec.rb b/spec/ruby/core/matchdata/deconstruct_spec.rb index 6af55113b6..c55095665d 100644 --- a/spec/ruby/core/matchdata/deconstruct_spec.rb +++ b/spec/ruby/core/matchdata/deconstruct_spec.rb @@ -2,7 +2,5 @@ require_relative '../../spec_helper' require_relative 'shared/captures' describe "MatchData#deconstruct" do - ruby_version_is "3.2" do - it_behaves_like :matchdata_captures, :deconstruct - end + it_behaves_like :matchdata_captures, :deconstruct end diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb index 0924be0aae..5509371cd2 100644 --- a/spec/ruby/core/matchdata/element_reference_spec.rb +++ b/spec/ruby/core/matchdata/element_reference_spec.rb @@ -55,7 +55,7 @@ describe "MatchData#[]" do it "returns instances of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138.") - /(.)(.)(\d+)(\d)/.match(str)[0..-1].each { |m| m.should be_an_instance_of(String) } + /(.)(.)(\d+)(\d)/.match(str)[0..-1].each { |m| m.should.instance_of?(String) } end end @@ -108,12 +108,12 @@ describe "MatchData#[Symbol]" do it "raises an IndexError if there is no named match corresponding to the Symbol" do md = 'haystack'.match(/(?<t>t(?<a>ack))/) - -> { md[:baz] }.should raise_error(IndexError, /baz/) + -> { md[:baz] }.should.raise(IndexError, /baz/) end it "raises an IndexError if there is no named match corresponding to the String" do md = 'haystack'.match(/(?<t>t(?<a>ack))/) - -> { md['baz'] }.should raise_error(IndexError, /baz/) + -> { md['baz'] }.should.raise(IndexError, /baz/) end it "returns matches in the String's encoding" do diff --git a/spec/ruby/core/matchdata/end_spec.rb b/spec/ruby/core/matchdata/end_spec.rb index d01b0a8b30..4fee24a763 100644 --- a/spec/ruby/core/matchdata/end_spec.rb +++ b/spec/ruby/core/matchdata/end_spec.rb @@ -12,7 +12,7 @@ describe "MatchData#end" do it "returns nil when the nth match isn't found" do match_data = /something is( not)? (right)/.match("something is right") - match_data.end(1).should be_nil + match_data.end(1).should == nil end it "returns the character offset for multi-byte strings" do diff --git a/spec/ruby/core/matchdata/inspect_spec.rb b/spec/ruby/core/matchdata/inspect_spec.rb index 5315257677..cacbe10c5d 100644 --- a/spec/ruby/core/matchdata/inspect_spec.rb +++ b/spec/ruby/core/matchdata/inspect_spec.rb @@ -6,7 +6,7 @@ describe "MatchData#inspect" do end it "returns a String" do - @match_data.inspect.should be_kind_of(String) + @match_data.inspect.should.is_a?(String) end it "returns a human readable representation that contains entire matched string and the captures" do diff --git a/spec/ruby/core/matchdata/integer_at_spec.rb b/spec/ruby/core/matchdata/integer_at_spec.rb new file mode 100644 index 0000000000..65f73a7bee --- /dev/null +++ b/spec/ruby/core/matchdata/integer_at_spec.rb @@ -0,0 +1,38 @@ +# -*- encoding: utf-8 -*- + +require_relative '../../spec_helper' + +ruby_version_is "4.1" do + describe "MatchData#integer_at" do + it "converts the corresponding match to an Integer and returns it when given an Integer" do + md = /(\d{4})(\d{2})(\d{2})/.match("20260308") + md.integer_at(0).should == 20260308 + md.integer_at(1).should == 2026 + md.integer_at(2).should == 3 + end + + it "returns nil on non-matching index matches" do + md = /\b(\d)?\b/.match("THX1138.") + md.integer_at(1).should == nil + end + + it "returns nil on non-integer matches" do + md = /(\w)?/.match("THX1138.") + md.integer_at(1).should == nil + end + + it "converts the match to an Integer in the given base" do + md = /\w+/.match("0c") + md.integer_at(0).should == 0 + md.integer_at(0, 16).should == 12 + end + + it "converts the match to an Integer in the prefix when given base is zero" do + /\w+/.match("010").integer_at(0, 0).should == 010 + /\w+/.match("0x10").integer_at(0, 0).should == 0x10 + /\w+/.match("0d10").integer_at(0, 0).should == 0d10 + /\w+/.match("0o10").integer_at(0, 0).should == 0o10 + /\w+/.match("0b10").integer_at(0, 0).should == 0b10 + end + end +end diff --git a/spec/ruby/core/matchdata/named_captures_spec.rb b/spec/ruby/core/matchdata/named_captures_spec.rb index 5e4693d62d..10b1f884d6 100644 --- a/spec/ruby/core/matchdata/named_captures_spec.rb +++ b/spec/ruby/core/matchdata/named_captures_spec.rb @@ -13,15 +13,13 @@ describe 'MatchData#named_captures' do /\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)?\z/.match('012').named_captures.should == { 'a' => '0', 'b' => '2' } end - ruby_version_is "3.3" do - it 'returns a Hash with Symbol keys when symbolize_names is provided a true value' do - /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: true).should == { a: '0', b: nil } - /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: "truly").should == { a: '0', b: nil } - end + it 'returns a Hash with Symbol keys when symbolize_names is provided a true value' do + /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: true).should == { a: '0', b: nil } + /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: "truly").should == { a: '0', b: nil } + end - it 'returns a Hash with String keys when symbolize_names is provided a false value' do - /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: false).should == { 'a' => '0', 'b' => '2' } - /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: nil).should == { 'a' => '0', 'b' => '2' } - end + it 'returns a Hash with String keys when symbolize_names is provided a false value' do + /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: false).should == { 'a' => '0', 'b' => '2' } + /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: nil).should == { 'a' => '0', 'b' => '2' } end end diff --git a/spec/ruby/core/matchdata/names_spec.rb b/spec/ruby/core/matchdata/names_spec.rb index 25ca06ced9..dca15985b0 100644 --- a/spec/ruby/core/matchdata/names_spec.rb +++ b/spec/ruby/core/matchdata/names_spec.rb @@ -3,12 +3,12 @@ require_relative '../../spec_helper' describe "MatchData#names" do it "returns an Array" do md = 'haystack'.match(/(?<yellow>hay)/) - md.names.should be_an_instance_of(Array) + md.names.should.instance_of?(Array) end it "sets each element to a String" do 'haystack'.match(/(?<yellow>hay)/).names.all? do |e| - e.should be_an_instance_of(String) + e.should.instance_of?(String) end end diff --git a/spec/ruby/core/matchdata/offset_spec.rb b/spec/ruby/core/matchdata/offset_spec.rb index 1ccb54b7a7..5a923d6ce0 100644 --- a/spec/ruby/core/matchdata/offset_spec.rb +++ b/spec/ruby/core/matchdata/offset_spec.rb @@ -1,30 +1,102 @@ -# -*- encoding: utf-8 -*- - require_relative '../../spec_helper' describe "MatchData#offset" do - it "returns a two element array with the begin and end of the nth match" do - match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") - match_data.offset(0).should == [1, 7] - match_data.offset(4).should == [6, 7] + it "returns beginning and ending character offset of whole matched substring for 0 element" do + m = /(.)(.)(\d+)(\d)/.match("THX1138.") + m.offset(0).should == [1, 7] + end + + it "returns beginning and ending character offset of n-th match, all the subsequent elements are capturing groups" do + m = /(.)(.)(\d+)(\d)/.match("THX1138.") + + m.offset(2).should == [2, 3] + m.offset(3).should == [3, 6] + m.offset(4).should == [6, 7] + end + + it "accepts String as a reference to a named capture" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + m.offset("f").should == [0, 3] + m.offset("b").should == [3, 6] + end + + it "accepts Symbol as a reference to a named capture" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + m.offset(:f).should == [0, 3] + m.offset(:b).should == [3, 6] end - it "returns [nil, nil] when the nth match isn't found" do - match_data = /something is( not)? (right)/.match("something is right") - match_data.offset(1).should == [nil, nil] + it "returns [nil, nil] if a capturing group is optional and doesn't match" do + m = /(?<x>q..)?/.match("foobarbaz") + + m.offset("x").should == [nil, nil] + m.offset(1).should == [nil, nil] end - it "returns the offset for multi byte strings" do - match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.") - match_data.offset(0).should == [1, 7] - match_data.offset(4).should == [6, 7] + it "returns correct beginning and ending character offset for multi-byte strings" do + m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") + + m.offset(1).should == [1, 2] + m.offset(3).should == [2, 3] end not_supported_on :opal do - it "returns the offset for multi byte strings with unicode regexp" do - match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.") - match_data.offset(0).should == [1, 7] - match_data.offset(4).should == [6, 7] + it "returns correct character offset for multi-byte strings with unicode regexp" do + m = /\A\u3042(.)(.)?(.)\z/u.match("\u3042\u3043\u3044") + + m.offset(1).should == [1, 2] + m.offset(3).should == [2, 3] end end + + it "returns [nil, nil] if a capturing group is optional and doesn't match for multi-byte string" do + m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") + + m.offset(2).should == [nil, nil] + end + + it "converts argument into integer if is not String nor Symbol" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + obj = Object.new + def obj.to_int; 2; end + + m.offset(1r).should == [0, 3] + m.offset(1.1).should == [0, 3] + m.offset(obj).should == [3, 6] + end + + it "raises IndexError if there is no group with the provided name" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + m.offset("y") + }.should.raise(IndexError, "undefined group name reference: y") + + -> { + m.offset(:y) + }.should.raise(IndexError, "undefined group name reference: y") + end + + it "raises IndexError if index is out of bounds" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + m.offset(-1) + }.should.raise(IndexError, "index -1 out of matches") + + -> { + m.offset(3) + }.should.raise(IndexError, "index 3 out of matches") + end + + it "raises TypeError if can't convert argument into Integer" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + m.offset([]) + }.should.raise(TypeError, "no implicit conversion of Array into Integer") + end end diff --git a/spec/ruby/core/matchdata/post_match_spec.rb b/spec/ruby/core/matchdata/post_match_spec.rb index 7bfe6df119..b50d637124 100644 --- a/spec/ruby/core/matchdata/post_match_spec.rb +++ b/spec/ruby/core/matchdata/post_match_spec.rb @@ -9,16 +9,16 @@ describe "MatchData#post_match" do it "sets the encoding to the encoding of the source String" do str = "abc".dup.force_encoding Encoding::EUC_JP - str.match(/b/).post_match.encoding.should equal(Encoding::EUC_JP) + str.match(/b/).post_match.encoding.should.equal?(Encoding::EUC_JP) end it "sets an empty result to the encoding of the source String" do str = "abc".dup.force_encoding Encoding::ISO_8859_1 - str.match(/c/).post_match.encoding.should equal(Encoding::ISO_8859_1) + str.match(/c/).post_match.encoding.should.equal?(Encoding::ISO_8859_1) end it "returns an instance of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138: The Movie") - /(.)(.)(\d+)(\d)/.match(str).post_match.should be_an_instance_of(String) + /(.)(.)(\d+)(\d)/.match(str).post_match.should.instance_of?(String) end end diff --git a/spec/ruby/core/matchdata/pre_match_spec.rb b/spec/ruby/core/matchdata/pre_match_spec.rb index 2f1ba9b8f6..106612a4f7 100644 --- a/spec/ruby/core/matchdata/pre_match_spec.rb +++ b/spec/ruby/core/matchdata/pre_match_spec.rb @@ -9,16 +9,16 @@ describe "MatchData#pre_match" do it "sets the encoding to the encoding of the source String" do str = "abc".dup.force_encoding Encoding::EUC_JP - str.match(/b/).pre_match.encoding.should equal(Encoding::EUC_JP) + str.match(/b/).pre_match.encoding.should.equal?(Encoding::EUC_JP) end it "sets an empty result to the encoding of the source String" do str = "abc".dup.force_encoding Encoding::ISO_8859_1 - str.match(/a/).pre_match.encoding.should equal(Encoding::ISO_8859_1) + str.match(/a/).pre_match.encoding.should.equal?(Encoding::ISO_8859_1) end it "returns an instance of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138: The Movie") - /(.)(.)(\d+)(\d)/.match(str).pre_match.should be_an_instance_of(String) + /(.)(.)(\d+)(\d)/.match(str).pre_match.should.instance_of?(String) end end diff --git a/spec/ruby/core/matchdata/regexp_spec.rb b/spec/ruby/core/matchdata/regexp_spec.rb index 099b59c559..7dcb0e62db 100644 --- a/spec/ruby/core/matchdata/regexp_spec.rb +++ b/spec/ruby/core/matchdata/regexp_spec.rb @@ -3,7 +3,7 @@ require_relative '../../spec_helper' describe "MatchData#regexp" do it "returns a Regexp object" do m = 'haystack'.match(/hay/) - m.regexp.should be_an_instance_of(Regexp) + m.regexp.should.instance_of?(Regexp) end it "returns the pattern used in the match" do diff --git a/spec/ruby/core/matchdata/shared/captures.rb b/spec/ruby/core/matchdata/shared/captures.rb index 33f834561a..de5870f543 100644 --- a/spec/ruby/core/matchdata/shared/captures.rb +++ b/spec/ruby/core/matchdata/shared/captures.rb @@ -8,6 +8,6 @@ describe :matchdata_captures, shared: true do it "returns instances of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138: The Movie") - /(.)(.)(\d+)(\d)/.match(str).send(@method).each { |c| c.should be_an_instance_of(String) } + /(.)(.)(\d+)(\d)/.match(str).send(@method).each { |c| c.should.instance_of?(String) } end end diff --git a/spec/ruby/core/matchdata/shared/eql.rb b/spec/ruby/core/matchdata/shared/eql.rb index e021baa178..e4bb8797b7 100644 --- a/spec/ruby/core/matchdata/shared/eql.rb +++ b/spec/ruby/core/matchdata/shared/eql.rb @@ -4,23 +4,23 @@ describe :matchdata_eql, shared: true do it "returns true if both operands have equal target strings, patterns, and match positions" do a = 'haystack'.match(/hay/) b = 'haystack'.match(/hay/) - a.send(@method, b).should be_true + a.send(@method, b).should == true end it "returns false if the operands have different target strings" do a = 'hay'.match(/hay/) b = 'haystack'.match(/hay/) - a.send(@method, b).should be_false + a.send(@method, b).should == false end it "returns false if the operands have different patterns" do a = 'haystack'.match(/h.y/) b = 'haystack'.match(/hay/) - a.send(@method, b).should be_false + a.send(@method, b).should == false end it "returns false if the argument is not a MatchData object" do a = 'haystack'.match(/hay/) - a.send(@method, Object.new).should be_false + a.send(@method, Object.new).should == false end end diff --git a/spec/ruby/core/matchdata/string_spec.rb b/spec/ruby/core/matchdata/string_spec.rb index 952e953318..50bbb5a64f 100644 --- a/spec/ruby/core/matchdata/string_spec.rb +++ b/spec/ruby/core/matchdata/string_spec.rb @@ -14,7 +14,7 @@ describe "MatchData#string" do it "returns the same frozen string for every call" do md = /(.)(.)(\d+)(\d)/.match("THX1138.") - md.string.should equal(md.string) + md.string.should.equal?(md.string) end it "returns a frozen copy of the matched string for gsub!(String)" do diff --git a/spec/ruby/core/matchdata/to_a_spec.rb b/spec/ruby/core/matchdata/to_a_spec.rb index 4fa11ff604..c77fc4ab37 100644 --- a/spec/ruby/core/matchdata/to_a_spec.rb +++ b/spec/ruby/core/matchdata/to_a_spec.rb @@ -8,6 +8,6 @@ describe "MatchData#to_a" do it "returns instances of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138.") - /(.)(.)(\d+)(\d)/.match(str)[0..-1].to_a.each { |m| m.should be_an_instance_of(String) } + /(.)(.)(\d+)(\d)/.match(str)[0..-1].to_a.each { |m| m.should.instance_of?(String) } end end diff --git a/spec/ruby/core/matchdata/to_s_spec.rb b/spec/ruby/core/matchdata/to_s_spec.rb index cd1c4dbca2..cbcc5e8a21 100644 --- a/spec/ruby/core/matchdata/to_s_spec.rb +++ b/spec/ruby/core/matchdata/to_s_spec.rb @@ -8,6 +8,6 @@ describe "MatchData#to_s" do it "returns an instance of String when given a String subclass" do str = MatchDataSpecs::MyString.new("THX1138.") - /(.)(.)(\d+)(\d)/.match(str).to_s.should be_an_instance_of(String) + /(.)(.)(\d+)(\d)/.match(str).to_s.should.instance_of?(String) end end diff --git a/spec/ruby/core/matchdata/values_at_spec.rb b/spec/ruby/core/matchdata/values_at_spec.rb index 535719a2ee..ba5b0e662c 100644 --- a/spec/ruby/core/matchdata/values_at_spec.rb +++ b/spec/ruby/core/matchdata/values_at_spec.rb @@ -26,7 +26,7 @@ describe "MatchData#values_at" do end it "raises RangeError if any element of the range is negative and out of range" do - -> { /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(-6..3) }.should raise_error(RangeError, "-6..3 out of range") + -> { /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(-6..3) }.should.raise(RangeError, "-6..3 out of range") end it "supports endless Range" do @@ -71,6 +71,6 @@ describe "MatchData#values_at" do it "fails when passed arguments of unsupported types" do -> { /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(Object.new) - }.should raise_error(TypeError, "no implicit conversion of Object into Integer") + }.should.raise(TypeError, "no implicit conversion of Object into Integer") end end |
