diff options
Diffstat (limited to 'spec/ruby/core/matchdata')
-rw-r--r-- | spec/ruby/core/matchdata/allocate_spec.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/begin_spec.rb | 28 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/byteoffset_spec.rb | 95 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/captures_spec.rb | 5 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/deconstruct_keys_spec.rb | 65 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/deconstruct_spec.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/element_reference_spec.rb | 34 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/fixtures/classes.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/named_captures_spec.rb | 12 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/post_match_spec.rb | 28 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/pre_match_spec.rb | 28 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/shared/captures.rb | 13 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/string_spec.rb | 5 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/to_a_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/to_s_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/matchdata/values_at_spec.rb | 71 |
16 files changed, 356 insertions, 59 deletions
diff --git a/spec/ruby/core/matchdata/allocate_spec.rb b/spec/ruby/core/matchdata/allocate_spec.rb index 9f3ada4018..142ce639c2 100644 --- a/spec/ruby/core/matchdata/allocate_spec.rb +++ b/spec/ruby/core/matchdata/allocate_spec.rb @@ -1,10 +1,8 @@ require_relative '../../spec_helper' describe "MatchData.allocate" do - ruby_version_is "2.7" do - it "is undefined" do - # https://bugs.ruby-lang.org/issues/16294 - -> { MatchData.allocate }.should raise_error(NoMethodError) - end + it "is undefined" do + # https://bugs.ruby-lang.org/issues/16294 + -> { MatchData.allocate }.should raise_error(NoMethodError) end end diff --git a/spec/ruby/core/matchdata/begin_spec.rb b/spec/ruby/core/matchdata/begin_spec.rb index 85c454da56..54b4e0a33f 100644 --- a/spec/ruby/core/matchdata/begin_spec.rb +++ b/spec/ruby/core/matchdata/begin_spec.rb @@ -36,6 +36,18 @@ describe "MatchData#begin" do match_data = /(.)(.)(\d+)(\d)/.match("THX1138.") match_data.begin(obj).should == 2 end + + it "raises IndexError if index is out of bounds" do + match_data = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + match_data.begin(-1) + }.should raise_error(IndexError, "index -1 out of matches") + + -> { + match_data.begin(3) + }.should raise_error(IndexError, "index 3 out of matches") + end end context "when passed a String argument" do @@ -68,6 +80,14 @@ describe "MatchData#begin" do match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") match_data.begin("æ").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.begin("y") + }.should raise_error(IndexError, "undefined group name reference: y") + end end context "when passed a Symbol argument" do @@ -100,5 +120,13 @@ describe "MatchData#begin" do match_data = /(?<æ>.)(.)(?<b>\d+)(\d)/.match("THX1138.") match_data.begin(:æ).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.begin(:y) + }.should raise_error(IndexError, "undefined group name reference: y") + end end end diff --git a/spec/ruby/core/matchdata/byteoffset_spec.rb b/spec/ruby/core/matchdata/byteoffset_spec.rb new file mode 100644 index 0000000000..b27267fd0e --- /dev/null +++ b/spec/ruby/core/matchdata/byteoffset_spec.rb @@ -0,0 +1,95 @@ +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 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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.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") + + -> { + m.byteoffset("y") + }.should raise_error(IndexError, "undefined group name reference: y") + + -> { + m.byteoffset(:y) + }.should raise_error(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.byteoffset(-1) + }.should raise_error(IndexError, "index -1 out of matches") + + -> { + m.byteoffset(3) + }.should raise_error(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.byteoffset([]) + }.should raise_error(TypeError, "no implicit conversion of Array into Integer") + end + end +end diff --git a/spec/ruby/core/matchdata/captures_spec.rb b/spec/ruby/core/matchdata/captures_spec.rb index 8c0d2978b7..f829a25481 100644 --- a/spec/ruby/core/matchdata/captures_spec.rb +++ b/spec/ruby/core/matchdata/captures_spec.rb @@ -1,7 +1,6 @@ require_relative '../../spec_helper' +require_relative 'shared/captures' describe "MatchData#captures" do - it "returns an array of the match captures" do - /(.)(.)(\d+)(\d)/.match("THX1138.").captures.should == ["H","X","113","8"] - end + it_behaves_like :matchdata_captures, :captures end diff --git a/spec/ruby/core/matchdata/deconstruct_keys_spec.rb b/spec/ruby/core/matchdata/deconstruct_keys_spec.rb new file mode 100644 index 0000000000..5b68f886c7 --- /dev/null +++ b/spec/ruby/core/matchdata/deconstruct_keys_spec.rb @@ -0,0 +1,65 @@ +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") + + m.deconstruct_keys(nil).should == { f: "foo", b: "bar" } + end + + it "returns only specified keys" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + m.deconstruct_keys([:f]).should == { f: "foo" } + end + + it "requires one argument" do + m = /l/.match("l") + + -> { + m.deconstruct_keys + }.should raise_error(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_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 "returns {} when passed []" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + m.deconstruct_keys([]).should == {} + end + + it "does not accept non-Symbol keys" do + m = /(?<f>foo)(?<b>bar)/.match("foobar") + + -> { + m.deconstruct_keys(['year', :foo]) + }.should raise_error(TypeError, "wrong argument type String (expected Symbol)") + end + + it "process keys till the first non-existing one" do + m = /(?<f>foo)(?<b>bar)(?<c>baz)/.match("foobarbaz") + + m.deconstruct_keys([:f, :a, :b]).should == { f: "foo" } + end + + it "returns {} when there are no named captured groups at all" do + m = /foo.+/.match("foobar") + + m.deconstruct_keys(nil).should == {} + 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 + end +end diff --git a/spec/ruby/core/matchdata/deconstruct_spec.rb b/spec/ruby/core/matchdata/deconstruct_spec.rb new file mode 100644 index 0000000000..6af55113b6 --- /dev/null +++ b/spec/ruby/core/matchdata/deconstruct_spec.rb @@ -0,0 +1,8 @@ +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 +end diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb index 26550ac94d..806db2d7b5 100644 --- a/spec/ruby/core/matchdata/element_reference_spec.rb +++ b/spec/ruby/core/matchdata/element_reference_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "MatchData#[]" do it "acts as normal array indexing [index]" do @@ -15,10 +16,41 @@ describe "MatchData#[]" do it "supports accessors [start, length]" do /(.)(.)(\d+)(\d)/.match("THX1138.")[1, 2].should == %w|H X| /(.)(.)(\d+)(\d)/.match("THX1138.")[-3, 2].should == %w|X 113| + + # negative index is larger than the number of match values + /(.)(.)(\d+)(\d)/.match("THX1138.")[-30, 2].should == nil + + # length argument larger than number of match values is capped to match value length + /(.)(.)(\d+)(\d)/.match("THX1138.")[3, 10].should == %w|113 8| + + /(.)(.)(\d+)(\d)/.match("THX1138.")[3, 0].should == [] + + /(.)(.)(\d+)(\d)/.match("THX1138.")[3, -1].should == nil + /(.)(.)(\d+)(\d)/.match("THX1138.")[3, -30].should == nil end it "supports ranges [start..end]" do /(.)(.)(\d+)(\d)/.match("THX1138.")[1..3].should == %w|H X 113| + /(.)(.)(\d+)(\d)/.match("THX1138.")[3..10].should == %w|113 8| + /(.)(.)(\d+)(\d)/.match("THX1138.")[-30..2].should == nil + /(.)(.)(\d+)(\d)/.match("THX1138.")[3..1].should == [] + end + + it "supports endless ranges [start..]" do + /(.)(.)(\d+)(\d)/.match("THX1138.")[3..].should == %w|113 8| + end + + it "supports beginningless ranges [..end]" do + /(.)(.)(\d+)(\d)/.match("THX1138.")[..1].should == %w|HX1138 H| + end + + it "supports beginningless endless ranges [nil..nil]" do + /(.)(.)(\d+)(\d)/.match("THX1138.")[nil..nil].should == %w|HX1138 H X 113 8| + end + + 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) } end end @@ -81,7 +113,7 @@ describe "MatchData#[Symbol]" do it "returns matches in the String's encoding" do rex = /(?<t>t(?<a>ack))/u - md = 'haystack'.force_encoding('euc-jp').match(rex) + md = 'haystack'.dup.force_encoding('euc-jp').match(rex) md[:t].encoding.should == Encoding::EUC_JP end end diff --git a/spec/ruby/core/matchdata/fixtures/classes.rb b/spec/ruby/core/matchdata/fixtures/classes.rb new file mode 100644 index 0000000000..54795636e5 --- /dev/null +++ b/spec/ruby/core/matchdata/fixtures/classes.rb @@ -0,0 +1,3 @@ +module MatchDataSpecs + class MyString < String; end +end diff --git a/spec/ruby/core/matchdata/named_captures_spec.rb b/spec/ruby/core/matchdata/named_captures_spec.rb index 9b1e324a24..5e4693d62d 100644 --- a/spec/ruby/core/matchdata/named_captures_spec.rb +++ b/spec/ruby/core/matchdata/named_captures_spec.rb @@ -12,4 +12,16 @@ describe 'MatchData#named_captures' do it 'returns the latest matched capture, even if a later one that does not match exists' 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 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 end diff --git a/spec/ruby/core/matchdata/post_match_spec.rb b/spec/ruby/core/matchdata/post_match_spec.rb index 4ae51f107e..7bfe6df119 100644 --- a/spec/ruby/core/matchdata/post_match_spec.rb +++ b/spec/ruby/core/matchdata/post_match_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "MatchData#post_match" do it "returns the string after the match equiv. special var $'" do @@ -6,31 +7,18 @@ describe "MatchData#post_match" do $'.should == ': The Movie' end - ruby_version_is ''...'2.7' do - it "keeps taint status from the source string" do - str = "THX1138: The Movie" - str.taint - res = /(.)(.)(\d+)(\d)/.match(str).post_match - res.tainted?.should be_true - $'.tainted?.should be_true - end - - it "keeps untrusted status from the source string" do - str = "THX1138: The Movie" - str.untrust - res = /(.)(.)(\d+)(\d)/.match(str).post_match - res.untrusted?.should be_true - $'.untrusted?.should be_true - end - end - it "sets the encoding to the encoding of the source String" do - str = "abc".force_encoding Encoding::EUC_JP + str = "abc".dup.force_encoding 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".force_encoding Encoding::ISO_8859_1 + str = "abc".dup.force_encoding 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) + end end diff --git a/spec/ruby/core/matchdata/pre_match_spec.rb b/spec/ruby/core/matchdata/pre_match_spec.rb index 824612c84c..2f1ba9b8f6 100644 --- a/spec/ruby/core/matchdata/pre_match_spec.rb +++ b/spec/ruby/core/matchdata/pre_match_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "MatchData#pre_match" do it "returns the string before the match, equiv. special var $`" do @@ -6,31 +7,18 @@ describe "MatchData#pre_match" do $`.should == 'T' end - ruby_version_is ''...'2.7' do - it "keeps taint status from the source string" do - str = "THX1138: The Movie" - str.taint - res = /(.)(.)(\d+)(\d)/.match(str).pre_match - res.tainted?.should be_true - $`.tainted?.should be_true - end - - it "keeps untrusted status from the source string" do - str = "THX1138: The Movie" - str.untrust - res = /(.)(.)(\d+)(\d)/.match(str).pre_match - res.untrusted?.should be_true - $`.untrusted?.should be_true - end - end - it "sets the encoding to the encoding of the source String" do - str = "abc".force_encoding Encoding::EUC_JP + str = "abc".dup.force_encoding 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".force_encoding Encoding::ISO_8859_1 + str = "abc".dup.force_encoding 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) + end end diff --git a/spec/ruby/core/matchdata/shared/captures.rb b/spec/ruby/core/matchdata/shared/captures.rb new file mode 100644 index 0000000000..33f834561a --- /dev/null +++ b/spec/ruby/core/matchdata/shared/captures.rb @@ -0,0 +1,13 @@ +require_relative '../../../spec_helper' +require_relative '../fixtures/classes' + +describe :matchdata_captures, shared: true do + it "returns an array of the match captures" do + /(.)(.)(\d+)(\d)/.match("THX1138.").send(@method).should == ["H","X","113","8"] + end + + 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) } + end +end diff --git a/spec/ruby/core/matchdata/string_spec.rb b/spec/ruby/core/matchdata/string_spec.rb index 420233e1f3..952e953318 100644 --- a/spec/ruby/core/matchdata/string_spec.rb +++ b/spec/ruby/core/matchdata/string_spec.rb @@ -17,8 +17,9 @@ describe "MatchData#string" do md.string.should equal(md.string) end - it "returns a frozen copy of the matched string for gsub(String)" do - 'he[[o'.gsub!('[', ']') + it "returns a frozen copy of the matched string for gsub!(String)" do + s = +'he[[o' + s.gsub!('[', ']') $~.string.should == 'he[[o' $~.string.should.frozen? end diff --git a/spec/ruby/core/matchdata/to_a_spec.rb b/spec/ruby/core/matchdata/to_a_spec.rb index 6231d096fb..4fa11ff604 100644 --- a/spec/ruby/core/matchdata/to_a_spec.rb +++ b/spec/ruby/core/matchdata/to_a_spec.rb @@ -1,7 +1,13 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "MatchData#to_a" do it "returns an array of matches" do /(.)(.)(\d+)(\d)/.match("THX1138.").to_a.should == ["HX1138", "H", "X", "113", "8"] end + + 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) } + end end diff --git a/spec/ruby/core/matchdata/to_s_spec.rb b/spec/ruby/core/matchdata/to_s_spec.rb index 9e213bb342..cd1c4dbca2 100644 --- a/spec/ruby/core/matchdata/to_s_spec.rb +++ b/spec/ruby/core/matchdata/to_s_spec.rb @@ -1,7 +1,13 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "MatchData#to_s" do it "returns the entire matched string" do /(.)(.)(\d+)(\d)/.match("THX1138.").to_s.should == "HX1138" end + + 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) + end end diff --git a/spec/ruby/core/matchdata/values_at_spec.rb b/spec/ruby/core/matchdata/values_at_spec.rb index 8f7fdf557c..535719a2ee 100644 --- a/spec/ruby/core/matchdata/values_at_spec.rb +++ b/spec/ruby/core/matchdata/values_at_spec.rb @@ -1,21 +1,76 @@ require_relative '../../spec_helper' describe "MatchData#values_at" do - it "returns an array of the matching value" do - /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0, 2, -2).should == ["HX1138", "X", "113"] + # Should be synchronized with core/array/values_at_spec.rb and core/struct/values_at_spec.rb + # + # /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").to_a # => ["HX1138", "H", "X", "113", "8"] + + context "when passed a list of Integers" do + it "returns an array containing each value given by one of integers" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0, 2, -2).should == ["HX1138", "X", "113"] + end + + it "returns nil value for any integer that is out of range" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(5).should == [nil] + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(-6).should == [nil] + end end - describe "when passed a Range" do - it "returns an array of the matching value" do - /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(2..4, 0..1).should == ["X", "113", "8", "HX1138", "H"] + context "when passed an integer Range" do + it "returns an array containing each value given by the elements of the range" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0..2).should == ["HX1138", "H", "X"] + end + + it "fills with nil values for range elements larger than the captured values number" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0..5).should == ["HX1138", "H", "X", "113", "8", nil] + 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") + end + + it "supports endless Range" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0..).should == ["HX1138", "H", "X", "113", "8"] + end + + it "supports beginningless Range" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(..2).should == ["HX1138", "H", "X"] + end + + it "returns an empty Array when Range is empty" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(2..0).should == [] + end + end + + context "when passed names" do + it 'slices captures with the given names' do + /(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at(:c, :a).should == ['2', '0'] + end + + it 'slices captures with the given String names' do + /(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at('c', 'a').should == ['2', '0'] end end - it 'slices captures with the given names' do - /(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at(:c, :a).should == ['2', '0'] + it "supports multiple integer Ranges" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(1..2, 2..3).should == ["H", "X", "X", "113"] end - it 'takes names and indices' do + it "supports mixing integer Ranges and Integers" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(1..2, 4).should == ["H", "X", "8"] + end + + it 'supports mixing of names and indices' do /\A(?<a>.)(?<b>.)\z/.match('01').values_at(0, 1, 2, :a, :b).should == ['01', '0', '1', '0', '1'] end + + it "returns a new empty Array if no arguments given" do + /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at().should == [] + end + + 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") + end end |