motion-strscan 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +63 -0
- data/lib/motion-strscan/string.rb +20 -0
- data/lib/motion-strscan/strscan.rb +676 -0
- data/lib/motion-strscan/version.rb +3 -0
- data/lib/motion-strscan.rb +8 -0
- data/spec/helpers/it_behaves_like.rb +27 -0
- data/spec/string_spec/_shared/slice.rb +244 -0
- data/spec/string_spec/byteslice_spec.rb +21 -0
- data/spec/strscan_spec/_shared/bol.rb +25 -0
- data/spec/strscan_spec/_shared/concat.rb +31 -0
- data/spec/strscan_spec/_shared/eos.rb +17 -0
- data/spec/strscan_spec/_shared/extract_range.rb +22 -0
- data/spec/strscan_spec/_shared/extract_range_matched.rb +22 -0
- data/spec/strscan_spec/_shared/get_byte.rb +28 -0
- data/spec/strscan_spec/_shared/matched_size.rb +21 -0
- data/spec/strscan_spec/_shared/peek.rb +44 -0
- data/spec/strscan_spec/_shared/pos.rb +83 -0
- data/spec/strscan_spec/_shared/rest_size.rb +18 -0
- data/spec/strscan_spec/_shared/terminate.rb +17 -0
- data/spec/strscan_spec/append_spec.rb +7 -0
- data/spec/strscan_spec/beginning_of_line_spec.rb +3 -0
- data/spec/strscan_spec/bol_spec.rb +3 -0
- data/spec/strscan_spec/check_spec.rb +13 -0
- data/spec/strscan_spec/check_until_spec.rb +14 -0
- data/spec/strscan_spec/clear_spec.rb +21 -0
- data/spec/strscan_spec/concat_spec.rb +7 -0
- data/spec/strscan_spec/dup_spec.rb +36 -0
- data/spec/strscan_spec/element_reference_spec.rb +46 -0
- data/spec/strscan_spec/empty_spec.rb +21 -0
- data/spec/strscan_spec/eos_spec.rb +3 -0
- data/spec/strscan_spec/exist_spec.rb +21 -0
- data/spec/strscan_spec/get_byte_spec.rb +3 -0
- data/spec/strscan_spec/getbyte_spec.rb +23 -0
- data/spec/strscan_spec/getch_spec.rb +41 -0
- data/spec/strscan_spec/initialize_spec.rb +25 -0
- data/spec/strscan_spec/inspect_spec.rb +17 -0
- data/spec/strscan_spec/match_spec.rb +25 -0
- data/spec/strscan_spec/matched_size_spec.rb +3 -0
- data/spec/strscan_spec/matched_spec.rb +37 -0
- data/spec/strscan_spec/matchedsize_spec.rb +23 -0
- data/spec/strscan_spec/must_C_version_spec.rb +5 -0
- data/spec/strscan_spec/peek_spec.rb +4 -0
- data/spec/strscan_spec/peep_spec.rb +21 -0
- data/spec/strscan_spec/pointer_spec.rb +7 -0
- data/spec/strscan_spec/pos_spec.rb +7 -0
- data/spec/strscan_spec/post_match_spec.rb +24 -0
- data/spec/strscan_spec/pre_match_spec.rb +37 -0
- data/spec/strscan_spec/reset_spec.rb +12 -0
- data/spec/strscan_spec/rest_size_spec.rb +3 -0
- data/spec/strscan_spec/rest_spec.rb +44 -0
- data/spec/strscan_spec/restsize_spec.rb +21 -0
- data/spec/strscan_spec/scan_full_spec.rb +27 -0
- data/spec/strscan_spec/scan_spec.rb +50 -0
- data/spec/strscan_spec/scan_until_spec.rb +20 -0
- data/spec/strscan_spec/search_full_spec.rb +27 -0
- data/spec/strscan_spec/skip_spec.rb +15 -0
- data/spec/strscan_spec/skip_until_spec.rb +15 -0
- data/spec/strscan_spec/string_spec.rb +37 -0
- data/spec/strscan_spec/terminate_spec.rb +3 -0
- data/spec/strscan_spec/unscan_spec.rb +26 -0
- metadata +172 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
describe "StringScanner#dup" do
|
2
|
+
before do
|
3
|
+
@string = "this is a test"
|
4
|
+
@orig_s = StringScanner.new(@string)
|
5
|
+
end
|
6
|
+
|
7
|
+
it "copies the passed StringScanner's content to self" do
|
8
|
+
s = @orig_s.dup
|
9
|
+
s.string.should == @string
|
10
|
+
end
|
11
|
+
|
12
|
+
it "copies the passed StringSCanner's position to self" do
|
13
|
+
@orig_s.pos = 5
|
14
|
+
s = @orig_s.dup
|
15
|
+
s.pos.should.equal(5)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "copies previous match state" do
|
19
|
+
@orig_s.scan(/\w+/)
|
20
|
+
@orig_s.scan(/\s/)
|
21
|
+
|
22
|
+
@orig_s.pre_match.should == "this"
|
23
|
+
|
24
|
+
s = @orig_s.dup
|
25
|
+
s.pre_match.should == "this"
|
26
|
+
|
27
|
+
s.unscan
|
28
|
+
s.scan(/\s/).should == " "
|
29
|
+
end
|
30
|
+
|
31
|
+
it "copies the passed StringScanner scan pointer to self" do
|
32
|
+
@orig_s.terminate
|
33
|
+
s = @orig_s.dup
|
34
|
+
s.eos?.should.be_true
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe "StringScanner#[]" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("Fri Jun 13 2008 22:43")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns nil if there is no current match" do
|
7
|
+
@s[0].should == nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns the n-th subgroup in the most recent match" do
|
11
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
12
|
+
@s[0].should == "Fri Jun 13 "
|
13
|
+
@s[1].should == "Fri"
|
14
|
+
@s[2].should == "Jun"
|
15
|
+
@s[3].should == "13"
|
16
|
+
@s[-3].should == "Fri"
|
17
|
+
@s[-2].should == "Jun"
|
18
|
+
@s[-1].should == "13"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns nil if index is outside of self" do
|
22
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
23
|
+
@s[5].should == nil
|
24
|
+
@s[-5].should == nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "calls to_int on the given index" do
|
28
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
29
|
+
@s[0.5].should == "Fri Jun 13 "
|
30
|
+
end
|
31
|
+
|
32
|
+
it "raises a TypeError if the given index is nil" do
|
33
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
34
|
+
lambda { @s[nil]}.should.raise(TypeError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises a TypeError when a String is as argument" do
|
38
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
39
|
+
lambda { @s["Fri"]}.should.raise(TypeError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises a TypeError when a Range is as argument" do
|
43
|
+
@s.scan(/(\w+) (\w+) (\d+) /)
|
44
|
+
lambda { @s[0..2]}.should.raise(TypeError)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe "StringScanner#empty?" do
|
2
|
+
it_behaves_like(:strscan_eos, :empty?)
|
3
|
+
|
4
|
+
# it "warns in verbose mode that the method is obsolete" do
|
5
|
+
# s = StringScanner.new("abc")
|
6
|
+
# begin
|
7
|
+
# old = $VERBOSE
|
8
|
+
# lambda {
|
9
|
+
# $VERBOSE = true
|
10
|
+
# s.empty?
|
11
|
+
# }.should complain(/empty?.*obsolete.*eos?/)
|
12
|
+
#
|
13
|
+
# lambda {
|
14
|
+
# $VERBOSE = false
|
15
|
+
# s.empty?
|
16
|
+
# }.should_not complain
|
17
|
+
# ensure
|
18
|
+
# $VERBOSE = old
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe "StringScanner#exist?" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the index of the first occurrence of the given pattern" do
|
7
|
+
@s.exist?(/s/).should == 4
|
8
|
+
@s.scan(/This is/)
|
9
|
+
@s.exist?(/s/).should == 6
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns 0 if the pattern is empty" do
|
13
|
+
@s.exist?(//).should == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns nil if the pattern isn't found in the string" do
|
17
|
+
@s.exist?(/S/).should == nil
|
18
|
+
@s.scan(/This is/)
|
19
|
+
@s.exist?(/i/).should == nil
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe "StringScanner#getbyte" do
|
2
|
+
it_behaves_like :strscan_get_byte, :getbyte
|
3
|
+
|
4
|
+
# it "warns in verbose mode that the method is obsolete" do
|
5
|
+
# s = StringScanner.new("abc")
|
6
|
+
# begin
|
7
|
+
# old = $VERBOSE
|
8
|
+
# lambda {
|
9
|
+
# $VERBOSE = true
|
10
|
+
# s.getbyte
|
11
|
+
# }.should complain(/getbyte.*obsolete.*get_byte/)
|
12
|
+
#
|
13
|
+
# lambda {
|
14
|
+
# $VERBOSE = false
|
15
|
+
# s.getbyte
|
16
|
+
# }.should_not complain
|
17
|
+
# ensure
|
18
|
+
# $VERBOSE = old
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
|
22
|
+
it_behaves_like :extract_range, :getbyte
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
describe "StringScanner#getch" do
|
2
|
+
before do
|
3
|
+
@kcode = $KCODE
|
4
|
+
end
|
5
|
+
|
6
|
+
after do
|
7
|
+
$KCODE = @kcode
|
8
|
+
end
|
9
|
+
|
10
|
+
it "scans one character and returns it" do
|
11
|
+
s = StringScanner.new('abc')
|
12
|
+
s.getch.should == "a"
|
13
|
+
s.getch.should == "b"
|
14
|
+
s.getch.should == "c"
|
15
|
+
end
|
16
|
+
|
17
|
+
# it "is multi-byte character sensitive" do
|
18
|
+
# $KCODE = 'EUC'
|
19
|
+
#
|
20
|
+
# # Japanese hiragana "A" in EUC-JP
|
21
|
+
# # src = "\244\242".encode("euc-jp")
|
22
|
+
# src = "\244\242".force_encoding("euc-jp")
|
23
|
+
#
|
24
|
+
# s = StringScanner.new(src)
|
25
|
+
# s.getch.should == src
|
26
|
+
# end
|
27
|
+
|
28
|
+
it "returns nil at the end of the string" do
|
29
|
+
# empty string case
|
30
|
+
s = StringScanner.new('')
|
31
|
+
s.getch.should == nil
|
32
|
+
s.getch.should == nil
|
33
|
+
|
34
|
+
# non-empty string case
|
35
|
+
s = StringScanner.new('a')
|
36
|
+
s.getch # skip one
|
37
|
+
s.getch.should == nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it_behaves_like :extract_range, :getch
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe "StringScanner#initialize" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
# it "is a private method" do
|
7
|
+
# StringScanner.should.be.a.private_instance_method(:initialize)
|
8
|
+
# end
|
9
|
+
|
10
|
+
it "returns an instance of StringScanner" do
|
11
|
+
@s.should.be.kind_of(StringScanner)
|
12
|
+
@s.tainted?.should.be_false
|
13
|
+
@s.eos?.should.be_false
|
14
|
+
end
|
15
|
+
|
16
|
+
# it "converts the argument into a string using #to_str" do
|
17
|
+
# m = mock(:str)
|
18
|
+
#
|
19
|
+
# s = "test"
|
20
|
+
# m.should_receive(:to_str).and_return(s)
|
21
|
+
#
|
22
|
+
# scan = StringScanner.new(m)
|
23
|
+
# scan.string.should == s
|
24
|
+
# end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe "StringScanner#inspect" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns a String object" do
|
7
|
+
@s.inspect.should.be.kind_of(String)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns a string that represents the StringScanner object" do
|
11
|
+
@s.inspect.should == "#<StringScanner 0/14 @ \"This ...\">"
|
12
|
+
@s.scan_until /is/
|
13
|
+
@s.inspect.should == "#<StringScanner 4/14 \"This\" @ \" is a...\">"
|
14
|
+
@s.terminate
|
15
|
+
@s.inspect.should == "#<StringScanner fin>"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe "StringScanner#match?" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the length of the match and the scan pointer is not advanced" do
|
7
|
+
@s.match?(/\w+/).should == 4
|
8
|
+
@s.match?(/\w+/).should == 4
|
9
|
+
@s.pos.should == 0
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns nil if there's no match" do
|
13
|
+
@s.match?(/\d+/).should == nil
|
14
|
+
@s.match?(/\s+/).should == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "effects pre_match" do
|
18
|
+
@s.scan(/\w+/)
|
19
|
+
@s.scan(/\s/)
|
20
|
+
|
21
|
+
@s.pre_match.should == "This"
|
22
|
+
@s.match?(/\w+/)
|
23
|
+
@s.pre_match.should == "This "
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe "StringScanner#matched" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the last matched string" do
|
7
|
+
@s.match?(/\w+/)
|
8
|
+
@s.matched.should == "This"
|
9
|
+
@s.getch
|
10
|
+
@s.matched.should == "T"
|
11
|
+
@s.get_byte
|
12
|
+
@s.matched.should == "h"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns nil if there's no match" do
|
16
|
+
@s.match?(/\d+/)
|
17
|
+
@s.matched.should == nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it_behaves_like :extract_range_matched, :matched
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "StringScanner#matched?" do
|
24
|
+
before do
|
25
|
+
@s = StringScanner.new("This is a test")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns true if the last match was successful" do
|
29
|
+
@s.match?(/\w+/)
|
30
|
+
@s.matched?.should.be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns false if there's no match" do
|
34
|
+
@s.match?(/\d+/)
|
35
|
+
@s.matched?.should.be_false
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# ruby_version_is "" ... "1.9" do
|
2
|
+
describe "StringScanner#matchedsize" do
|
3
|
+
it_behaves_like(:strscan_matched_size, :matchedsize)
|
4
|
+
|
5
|
+
# it "warns in verbose mode that the method is obsolete" do
|
6
|
+
# s = StringScanner.new("abc")
|
7
|
+
# begin
|
8
|
+
# old = $VERBOSE
|
9
|
+
# lambda {
|
10
|
+
# $VERBOSE = true
|
11
|
+
# s.matchedsize
|
12
|
+
# }.should complain(/matchedsize.*obsolete.*matched_size/)
|
13
|
+
#
|
14
|
+
# lambda {
|
15
|
+
# $VERBOSE = false
|
16
|
+
# s.matchedsize
|
17
|
+
# }.should_not complain
|
18
|
+
# ensure
|
19
|
+
# $VERBOSE = old
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
end
|
23
|
+
# end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe "StringScanner#peep" do
|
2
|
+
it_behaves_like(:strscan_peek, :peep)
|
3
|
+
|
4
|
+
# it "warns in verbose mode that the method is obsolete" do
|
5
|
+
# s = StringScanner.new("abc")
|
6
|
+
# begin
|
7
|
+
# old = $VERBOSE
|
8
|
+
# lambda {
|
9
|
+
# $VERBOSE = true
|
10
|
+
# s.peep(1)
|
11
|
+
# }.should complain(/peep.*obsolete.*peek/)
|
12
|
+
#
|
13
|
+
# lambda {
|
14
|
+
# $VERBOSE = false
|
15
|
+
# s.peep(1)
|
16
|
+
# }.should_not complain
|
17
|
+
# ensure
|
18
|
+
# $VERBOSE = old
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
describe "StringScanner#post_match" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the post-match (in the regular expression sense) of the last scan" do
|
7
|
+
@s.post_match.should == nil
|
8
|
+
@s.scan(/\w+\s/)
|
9
|
+
@s.post_match.should == "is a test"
|
10
|
+
@s.getch
|
11
|
+
@s.post_match.should == "s a test"
|
12
|
+
@s.get_byte
|
13
|
+
@s.post_match.should == " a test"
|
14
|
+
@s.get_byte
|
15
|
+
@s.post_match.should == "a test"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns nil if there's no match" do
|
19
|
+
@s.scan(/\s+/)
|
20
|
+
@s.post_match.should == nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it_behaves_like :extract_range_matched, :post_match
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe "StringScanner#pre_match" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the pre-match (in the regular expression sense) of the last scan" do
|
7
|
+
@s.pre_match.should == nil
|
8
|
+
@s.scan(/\w+\s/)
|
9
|
+
@s.pre_match.should == ""
|
10
|
+
@s.getch
|
11
|
+
@s.pre_match.should == "This "
|
12
|
+
@s.get_byte
|
13
|
+
@s.pre_match.should == "This i"
|
14
|
+
@s.get_byte
|
15
|
+
@s.pre_match.should == "This is"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns nil if there's no match" do
|
19
|
+
@s.scan(/\s+/)
|
20
|
+
@s.pre_match.should == nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is more than just the data from the last match" do
|
24
|
+
@s.scan(/\w+/)
|
25
|
+
@s.scan_until(/a te/)
|
26
|
+
@s.pre_match.should == "This is "
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is not changed when the scanner's position changes" do
|
30
|
+
@s.scan_until(/\s+/)
|
31
|
+
@s.pre_match.should == "This"
|
32
|
+
@s.pos -= 1
|
33
|
+
@s.pre_match.should == "This"
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like :extract_range_matched, :pre_match
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe "StringScanner#rest" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the rest of the string" do
|
7
|
+
@s.scan(/This\s+/)
|
8
|
+
@s.rest.should == "is a test"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns self in the reset position" do
|
12
|
+
@s.reset
|
13
|
+
@s.rest.should == @s.string
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns an empty string in the terminate position" do
|
17
|
+
@s.terminate
|
18
|
+
@s.rest.should == ""
|
19
|
+
end
|
20
|
+
|
21
|
+
it_behaves_like :extract_range_matched, :rest
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "StringScanner#rest?" do
|
26
|
+
before do
|
27
|
+
@s = StringScanner.new("This is a test")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true if there is more data in the string" do
|
31
|
+
@s.rest?.should.be_true
|
32
|
+
@s.scan(/This/)
|
33
|
+
@s.rest?.should.be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns false if there is no more data in the string" do
|
37
|
+
@s.terminate
|
38
|
+
@s.rest?.should.be_false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is the opposite of eos?" do
|
42
|
+
@s.rest?.should.not == @s.eos?
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe "StringScanner#restsize" do
|
2
|
+
it_behaves_like(:strscan_rest_size, :restsize)
|
3
|
+
|
4
|
+
# it "warns in verbose mode that the method is obsolete" do
|
5
|
+
# s = StringScanner.new("abc")
|
6
|
+
# begin
|
7
|
+
# old = $VERBOSE
|
8
|
+
# lambda {
|
9
|
+
# $VERBOSE = true
|
10
|
+
# s.restsize
|
11
|
+
# }.should complain(/restsize.*obsolete.*rest_size/)
|
12
|
+
#
|
13
|
+
# lambda {
|
14
|
+
# $VERBOSE = false
|
15
|
+
# s.restsize
|
16
|
+
# }.should_not complain
|
17
|
+
# ensure
|
18
|
+
# $VERBOSE = old
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "StringScanner#scan_full" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the number of bytes advanced" do
|
7
|
+
orig_pos = @s.pos
|
8
|
+
@s.scan_full(/This/, false, false).should == 4
|
9
|
+
@s.pos.should == orig_pos
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the number of bytes advanced and advances the scan pointer if the second argument is true" do
|
13
|
+
@s.scan_full(/This/, true, false).should == 4
|
14
|
+
@s.pos.should == 4
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the matched string if the third argument is true" do
|
18
|
+
orig_pos = @s.pos
|
19
|
+
@s.scan_full(/This/, false, true).should == "This"
|
20
|
+
@s.pos.should == orig_pos
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the matched string if the third argument is true and advances the scan pointer if the second argument is true" do
|
24
|
+
@s.scan_full(/This/, true, true).should == "This"
|
25
|
+
@s.pos.should == 4
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
describe "StringScanner#scan" do
|
4
|
+
before do
|
5
|
+
@s = StringScanner.new("This is a test")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns the matched string" do
|
9
|
+
@s.scan(/\w+/).should == "This"
|
10
|
+
@s.scan(/.../).should == " is"
|
11
|
+
@s.scan(//).should == ""
|
12
|
+
@s.scan(/\s+/).should == " "
|
13
|
+
end
|
14
|
+
|
15
|
+
# ruby_version_is "1.9" do
|
16
|
+
it "returns the matched string for a multi byte string" do
|
17
|
+
m = StringScanner.new("Привет!")
|
18
|
+
m.scan(/[А-Яа-я]+/).should == "Привет"
|
19
|
+
m.rest.should == "!"
|
20
|
+
end
|
21
|
+
# end
|
22
|
+
|
23
|
+
it "treats ^ as matching from the beginning of the current position" do
|
24
|
+
@s.scan(/\w+/).should == "This"
|
25
|
+
@s.scan(/^\d/).should == nil
|
26
|
+
@s.scan(/^\s/).should == " "
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns nil if there's no match" do
|
30
|
+
@s.scan(/\d/).should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns nil when there is no more to scan" do
|
34
|
+
@s.scan(/[\w\s]+/).should == "This is a test"
|
35
|
+
@s.scan(/\w+/).should == nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns an empty string when the pattern matches empty" do
|
39
|
+
@s.scan(/.*/).should == "This is a test"
|
40
|
+
@s.scan(/.*/).should == ""
|
41
|
+
@s.scan(/./).should == nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises a TypeError if pattern isn't a Regexp" do
|
45
|
+
lambda { @s.scan("aoeu") }.should.raise(TypeError)
|
46
|
+
lambda { @s.scan(5) }.should.raise(TypeError)
|
47
|
+
lambda { @s.scan(:test) }.should.raise(TypeError)
|
48
|
+
# lambda { @s.scan(mock('x')) }.should.raise(TypeError)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe "StringScanner#scan_until" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the substring up to and including the end of the match" do
|
7
|
+
@s.scan_until(/a/).should == "This is a"
|
8
|
+
@s.pre_match.should == "This is "
|
9
|
+
@s.post_match.should == " test"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns nil if there's no match" do
|
13
|
+
@s.scan_until(/\d/).should == nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can match anchors properly" do
|
17
|
+
@s.scan(/T/)
|
18
|
+
@s.scan_until(/^h/).should == "h"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "StringScanner#search_full" do
|
2
|
+
before do
|
3
|
+
@s = StringScanner.new("This is a test")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "returns the number of bytes advanced" do
|
7
|
+
orig_pos = @s.pos
|
8
|
+
@s.search_full(/This/, false, false).should == 4
|
9
|
+
@s.pos.should == orig_pos
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the number of bytes advanced and advances the scan pointer if the second argument is true" do
|
13
|
+
@s.search_full(/This/, true, false).should == 4
|
14
|
+
@s.pos.should == 4
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the matched string if the third argument is true" do
|
18
|
+
orig_pos = @s.pos
|
19
|
+
@s.search_full(/This/, false, true).should == "This"
|
20
|
+
@s.pos.should == orig_pos
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the matched string if the third argument is true and advances the scan pointer if the second argument is true" do
|
24
|
+
@s.search_full(/This/, true, true).should == "This"
|
25
|
+
@s.pos.should == 4
|
26
|
+
end
|
27
|
+
end
|