summaryrefslogtreecommitdiff
path: root/spec/ruby/core/matchdata/begin_spec.rb
blob: 54b4e0a33fe47ba6c06e23f633d8d29512c71bf7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# -*- encoding: utf-8 -*-

require_relative '../../spec_helper'

describe "MatchData#begin" do
  context "when passed an integer argument" do
    it "returns the character offset of the start of the nth element" do
      match_data = /(.)(.)(\d+)(\d)/.match("THX1138.")
      match_data.begin(0).should == 1
      match_data.begin(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.begin(1).should be_nil
    end

    it "returns the character offset for multi-byte strings" do
      match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.")
      match_data.begin(0).should == 1
      match_data.begin(2).should == 2
    end

    not_supported_on :opal do
      it "returns the character offset for multi-byte strings with unicode regexp" do
        match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.")
        match_data.begin(0).should == 1
        match_data.begin(2).should == 2
      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.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
    it "return the character offset of the start of the named capture" do
      match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.")
      match_data.begin("a").should == 1
      match_data.begin("b").should == 3
    end

    it "returns the character offset for multi byte strings" do
      match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.")
      match_data.begin("a").should == 1
      match_data.begin("b").should == 3
    end

    not_supported_on :opal do
      it "returns the character offset for multi byte strings with unicode regexp" do
        match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.")
        match_data.begin("a").should == 1
        match_data.begin("b").should == 3
      end
    end

    it "returns the character offset for the farthest match when multiple named captures use the same name" do
      match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.")
      match_data.begin("a").should == 3
    end

    it "returns the character offset for multi-byte names" 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
    it "return the character offset of the start of the named capture" do
      match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("THX1138.")
      match_data.begin(:a).should == 1
      match_data.begin(:b).should == 3
    end

    it "returns the character offset for multi byte strings" do
      match_data = /(?<a>.)(.)(?<b>\d+)(\d)/.match("TñX1138.")
      match_data.begin(:a).should == 1
      match_data.begin(:b).should == 3
    end

    not_supported_on :opal do
      it "returns the character offset for multi byte strings with unicode regexp" do
        match_data = /(?<a>.)(.)(?<b>\d+)(\d)/u.match("TñX1138.")
        match_data.begin(:a).should == 1
        match_data.begin(:b).should == 3
      end
    end

    it "returns the character offset for the farthest match when multiple named captures use the same name" do
      match_data = /(?<a>.)(.)(?<a>\d+)(\d)/.match("THX1138.")
      match_data.begin(:a).should == 3
    end

    it "returns the character offset for multi-byte names" 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