rubysl-strscan 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rubysl/strscan.rb +2 -0
- data/lib/rubysl/strscan/strscan.rb +286 -0
- data/lib/rubysl/strscan/version.rb +5 -0
- data/lib/strscan.rb +1 -0
- data/rubysl-strscan.gemspec +22 -0
- data/spec/append_spec.rb +10 -0
- data/spec/beginning_of_line_spec.rb +6 -0
- data/spec/bol_spec.rb +6 -0
- data/spec/check_spec.rb +15 -0
- data/spec/check_until_spec.rb +14 -0
- data/spec/clear_spec.rb +24 -0
- data/spec/concat_spec.rb +10 -0
- data/spec/dup_spec.rb +38 -0
- data/spec/element_reference_spec.rb +48 -0
- data/spec/empty_spec.rb +24 -0
- data/spec/eos_spec.rb +6 -0
- data/spec/exist_spec.rb +23 -0
- data/spec/get_byte_spec.rb +6 -0
- data/spec/getbyte_spec.rb +27 -0
- data/spec/getch_spec.rb +43 -0
- data/spec/initialize_spec.rb +27 -0
- data/spec/inspect_spec.rb +19 -0
- data/spec/match_spec.rb +27 -0
- data/spec/matched_size_spec.rb +6 -0
- data/spec/matched_spec.rb +40 -0
- data/spec/matchedsize_spec.rb +26 -0
- data/spec/must_C_version_spec.rb +7 -0
- data/spec/peek_spec.rb +7 -0
- data/spec/peep_spec.rb +24 -0
- data/spec/pointer_spec.rb +10 -0
- data/spec/pos_spec.rb +10 -0
- data/spec/post_match_spec.rb +27 -0
- data/spec/pre_match_spec.rb +40 -0
- data/spec/reset_spec.rb +14 -0
- data/spec/rest_size_spec.rb +6 -0
- data/spec/rest_spec.rb +47 -0
- data/spec/restsize_spec.rb +24 -0
- data/spec/scan_full_spec.rb +29 -0
- data/spec/scan_spec.rb +81 -0
- data/spec/scan_until_spec.rb +22 -0
- data/spec/search_full_spec.rb +29 -0
- data/spec/shared/bol.rb +25 -0
- data/spec/shared/concat.rb +30 -0
- data/spec/shared/eos.rb +17 -0
- data/spec/shared/extract_range.rb +22 -0
- data/spec/shared/extract_range_matched.rb +22 -0
- data/spec/shared/get_byte.rb +28 -0
- data/spec/shared/matched_size.rb +21 -0
- data/spec/shared/peek.rb +44 -0
- data/spec/shared/pos.rb +83 -0
- data/spec/shared/rest_size.rb +18 -0
- data/spec/shared/terminate.rb +17 -0
- data/spec/skip_spec.rb +17 -0
- data/spec/skip_until_spec.rb +17 -0
- data/spec/string_spec.rb +39 -0
- data/spec/terminate_spec.rb +6 -0
- data/spec/unscan_spec.rb +28 -0
- metadata +201 -0
data/spec/peek_spec.rb
ADDED
data/spec/peep_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('../shared/peek.rb', __FILE__)
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
describe "StringScanner#peep" do
|
5
|
+
it_behaves_like(:strscan_peek, :peep)
|
6
|
+
|
7
|
+
it "warns in verbose mode that the method is obsolete" do
|
8
|
+
s = StringScanner.new("abc")
|
9
|
+
begin
|
10
|
+
old = $VERBOSE
|
11
|
+
lambda {
|
12
|
+
$VERBOSE = true
|
13
|
+
s.peep(1)
|
14
|
+
}.should complain(/peep.*obsolete.*peek/)
|
15
|
+
|
16
|
+
lambda {
|
17
|
+
$VERBOSE = false
|
18
|
+
s.peep(1)
|
19
|
+
}.should_not complain
|
20
|
+
ensure
|
21
|
+
$VERBOSE = old
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/pos_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../shared/extract_range_matched', __FILE__)
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
describe "StringScanner#post_match" do
|
5
|
+
before :each do
|
6
|
+
@s = StringScanner.new("This is a test")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the post-match (in the regular expression sense) of the last scan" do
|
10
|
+
@s.post_match.should == nil
|
11
|
+
@s.scan(/\w+\s/)
|
12
|
+
@s.post_match.should == "is a test"
|
13
|
+
@s.getch
|
14
|
+
@s.post_match.should == "s a test"
|
15
|
+
@s.get_byte
|
16
|
+
@s.post_match.should == " a test"
|
17
|
+
@s.get_byte
|
18
|
+
@s.post_match.should == "a test"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns nil if there's no match" do
|
22
|
+
@s.scan(/\s+/)
|
23
|
+
@s.post_match.should == nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it_behaves_like :extract_range_matched, :post_match
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path('../shared/extract_range_matched', __FILE__)
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
describe "StringScanner#pre_match" do
|
5
|
+
before :each do
|
6
|
+
@s = StringScanner.new("This is a test")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the pre-match (in the regular expression sense) of the last scan" do
|
10
|
+
@s.pre_match.should == nil
|
11
|
+
@s.scan(/\w+\s/)
|
12
|
+
@s.pre_match.should == ""
|
13
|
+
@s.getch
|
14
|
+
@s.pre_match.should == "This "
|
15
|
+
@s.get_byte
|
16
|
+
@s.pre_match.should == "This i"
|
17
|
+
@s.get_byte
|
18
|
+
@s.pre_match.should == "This is"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns nil if there's no match" do
|
22
|
+
@s.scan(/\s+/)
|
23
|
+
@s.pre_match.should == nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is more than just the data from the last match" do
|
27
|
+
@s.scan(/\w+/)
|
28
|
+
@s.scan_until(/a te/)
|
29
|
+
@s.pre_match.should == "This is "
|
30
|
+
end
|
31
|
+
|
32
|
+
it "is not changed when the scanner's position changes" do
|
33
|
+
@s.scan_until(/\s+/)
|
34
|
+
@s.pre_match.should == "This"
|
35
|
+
@s.pos -= 1
|
36
|
+
@s.pre_match.should == "This"
|
37
|
+
end
|
38
|
+
|
39
|
+
it_behaves_like :extract_range_matched, :pre_match
|
40
|
+
end
|
data/spec/reset_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
describe "StringScanner#reset" do
|
4
|
+
before :each do
|
5
|
+
@s = StringScanner.new("This is a test")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "reset the scan pointer and clear matching data" do
|
9
|
+
@s.scan(/This/)
|
10
|
+
@s.reset
|
11
|
+
@s.pos.should == 0
|
12
|
+
@s.matched.should == nil
|
13
|
+
end
|
14
|
+
end
|
data/spec/rest_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path('../shared/extract_range_matched', __FILE__)
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
describe "StringScanner#rest" do
|
5
|
+
before :each do
|
6
|
+
@s = StringScanner.new("This is a test")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the rest of the string" do
|
10
|
+
@s.scan(/This\s+/)
|
11
|
+
@s.rest.should == "is a test"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns self in the reset position" do
|
15
|
+
@s.reset
|
16
|
+
@s.rest.should == @s.string
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns an empty string in the terminate position" do
|
20
|
+
@s.terminate
|
21
|
+
@s.rest.should == ""
|
22
|
+
end
|
23
|
+
|
24
|
+
it_behaves_like :extract_range_matched, :rest
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "StringScanner#rest?" do
|
29
|
+
before :each do
|
30
|
+
@s = StringScanner.new("This is a test")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns true if there is more data in the string" do
|
34
|
+
@s.rest?.should be_true
|
35
|
+
@s.scan(/This/)
|
36
|
+
@s.rest?.should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns false if there is no more data in the string" do
|
40
|
+
@s.terminate
|
41
|
+
@s.rest?.should be_false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "is the opposite of eos?" do
|
45
|
+
@s.rest?.should_not == @s.eos?
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('../shared/rest_size.rb', __FILE__)
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
describe "StringScanner#restsize" do
|
5
|
+
it_behaves_like(:strscan_rest_size, :restsize)
|
6
|
+
|
7
|
+
it "warns in verbose mode that the method is obsolete" do
|
8
|
+
s = StringScanner.new("abc")
|
9
|
+
begin
|
10
|
+
old = $VERBOSE
|
11
|
+
lambda {
|
12
|
+
$VERBOSE = true
|
13
|
+
s.restsize
|
14
|
+
}.should complain(/restsize.*obsolete.*rest_size/)
|
15
|
+
|
16
|
+
lambda {
|
17
|
+
$VERBOSE = false
|
18
|
+
s.restsize
|
19
|
+
}.should_not complain
|
20
|
+
ensure
|
21
|
+
$VERBOSE = old
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
describe "StringScanner#scan_full" do
|
4
|
+
before :each do
|
5
|
+
@s = StringScanner.new("This is a test")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns the number of bytes advanced" do
|
9
|
+
orig_pos = @s.pos
|
10
|
+
@s.scan_full(/This/, false, false).should == 4
|
11
|
+
@s.pos.should == orig_pos
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns the number of bytes advanced and advances the scan pointer if the second argument is true" do
|
15
|
+
@s.scan_full(/This/, true, false).should == 4
|
16
|
+
@s.pos.should == 4
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns the matched string if the third argument is true" do
|
20
|
+
orig_pos = @s.pos
|
21
|
+
@s.scan_full(/This/, false, true).should == "This"
|
22
|
+
@s.pos.should == orig_pos
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns the matched string if the third argument is true and advances the scan pointer if the second argument is true" do
|
26
|
+
@s.scan_full(/This/, true, true).should == "This"
|
27
|
+
@s.pos.should == 4
|
28
|
+
end
|
29
|
+
end
|
data/spec/scan_spec.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
4
|
+
require 'strscan'
|
5
|
+
|
6
|
+
describe "StringScanner#scan" do
|
7
|
+
before :each do
|
8
|
+
@s = StringScanner.new("This is a test")
|
9
|
+
@kcode = $KCODE
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
$KCODE = @kcode
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns the matched string" do
|
17
|
+
@s.scan(/\w+/).should == "This"
|
18
|
+
@s.scan(/.../).should == " is"
|
19
|
+
@s.scan(//).should == ""
|
20
|
+
@s.scan(/\s+/).should == " "
|
21
|
+
end
|
22
|
+
|
23
|
+
ruby_version_is ""..."1.9" do
|
24
|
+
it "returns the first character for a multi byte string with no KCODE" do
|
25
|
+
$KCODE = 'NONE'
|
26
|
+
m = StringScanner.new("Привет!")
|
27
|
+
m.scan(/[А-Яа-я]+/).should == "\320\237\321"
|
28
|
+
m.rest.should == "\200\320\270\320\262\320\265\321\202!"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns the matched string for a multi byte string with KCODE" do
|
32
|
+
$KCODE = 'UTF-8'
|
33
|
+
m = StringScanner.new("Привет!")
|
34
|
+
m.scan(/[А-Яа-я]+/).should == "Привет"
|
35
|
+
m.rest.should == "!"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns the matched string for a multi byte string with unicode regexp" do
|
39
|
+
$KCODE = 'NONE'
|
40
|
+
m = StringScanner.new("Привет!")
|
41
|
+
m.scan(/[А-Яа-я]+/u).should == "Привет"
|
42
|
+
m.rest.should == "!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
ruby_version_is "1.9" do
|
47
|
+
it "returns the matched string for a multi byte string" do
|
48
|
+
m = StringScanner.new("Привет!")
|
49
|
+
m.scan(/[А-Яа-я]+/).should == "Привет"
|
50
|
+
m.rest.should == "!"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "treats ^ as matching from the beginning of the current position" do
|
55
|
+
@s.scan(/\w+/).should == "This"
|
56
|
+
@s.scan(/^\d/).should be_nil
|
57
|
+
@s.scan(/^\s/).should == " "
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns nil if there's no match" do
|
61
|
+
@s.scan(/\d/).should == nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns nil when there is no more to scan" do
|
65
|
+
@s.scan(/[\w\s]+/).should == "This is a test"
|
66
|
+
@s.scan(/\w+/).should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns an empty string when the pattern matches empty" do
|
70
|
+
@s.scan(/.*/).should == "This is a test"
|
71
|
+
@s.scan(/.*/).should == ""
|
72
|
+
@s.scan(/./).should be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
it "raises a TypeError if pattern isn't a Regexp" do
|
76
|
+
lambda { @s.scan("aoeu") }.should raise_error(TypeError)
|
77
|
+
lambda { @s.scan(5) }.should raise_error(TypeError)
|
78
|
+
lambda { @s.scan(:test) }.should raise_error(TypeError)
|
79
|
+
lambda { @s.scan(mock('x')) }.should raise_error(TypeError)
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
describe "StringScanner#scan_until" do
|
4
|
+
before :each do
|
5
|
+
@s = StringScanner.new("This is a test")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns the substring up to and including the end of the match" do
|
9
|
+
@s.scan_until(/a/).should == "This is a"
|
10
|
+
@s.pre_match.should == "This is "
|
11
|
+
@s.post_match.should == " test"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns nil if there's no match" do
|
15
|
+
@s.scan_until(/\d/).should == nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can match anchors properly" do
|
19
|
+
@s.scan(/T/)
|
20
|
+
@s.scan_until(/^h/).should == "h"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
describe "StringScanner#search_full" do
|
4
|
+
before :each do
|
5
|
+
@s = StringScanner.new("This is a test")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns the number of bytes advanced" do
|
9
|
+
orig_pos = @s.pos
|
10
|
+
@s.search_full(/This/, false, false).should == 4
|
11
|
+
@s.pos.should == orig_pos
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns the number of bytes advanced and advances the scan pointer if the second argument is true" do
|
15
|
+
@s.search_full(/This/, true, false).should == 4
|
16
|
+
@s.pos.should == 4
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns the matched string if the third argument is true" do
|
20
|
+
orig_pos = @s.pos
|
21
|
+
@s.search_full(/This/, false, true).should == "This"
|
22
|
+
@s.pos.should == orig_pos
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns the matched string if the third argument is true and advances the scan pointer if the second argument is true" do
|
26
|
+
@s.search_full(/This/, true, true).should == "This"
|
27
|
+
@s.pos.should == 4
|
28
|
+
end
|
29
|
+
end
|
data/spec/shared/bol.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
describe :strscan_bol, :shared => true do
|
2
|
+
it "returns true if the scan pointer is at the beginning of the line, false otherwise" do
|
3
|
+
s = StringScanner.new("This is a test")
|
4
|
+
s.send(@method).should be_true
|
5
|
+
s.scan(/This/)
|
6
|
+
s.send(@method).should be_false
|
7
|
+
s.terminate
|
8
|
+
s.send(@method).should be_false
|
9
|
+
|
10
|
+
s = StringScanner.new("hello\nworld")
|
11
|
+
s.bol?.should be_true
|
12
|
+
s.scan(/\w+/)
|
13
|
+
s.bol?.should be_false
|
14
|
+
s.scan(/\n/)
|
15
|
+
s.bol?.should be_true
|
16
|
+
s.unscan
|
17
|
+
s.bol?.should be_false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns true if the scan pointer is at the end of the line of an empty string." do
|
21
|
+
s = StringScanner.new('')
|
22
|
+
s.terminate
|
23
|
+
s.send(@method).should be_true
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe :strscan_concat, :shared => true do
|
2
|
+
it "concatenates the given argument to self and returns self" do
|
3
|
+
s = StringScanner.new("hello ")
|
4
|
+
s.send(@method, 'world').should == s
|
5
|
+
s.string.should == "hello world"
|
6
|
+
s.eos?.should be_false
|
7
|
+
end
|
8
|
+
|
9
|
+
it "raises a TypeError if the given argument can't be converted to a String" do
|
10
|
+
lambda { a = StringScanner.new('hello').send(@method, :world) }.should raise_error(TypeError)
|
11
|
+
lambda { a = StringScanner.new('hello').send(@method, mock('x')) }.should raise_error(TypeError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe :strscan_concat_fixnum, :shared => true do
|
16
|
+
it "raises a TypeError" do
|
17
|
+
a = StringScanner.new("hello world")
|
18
|
+
lambda { a.send(@method, 333) }.should raise_error(TypeError)
|
19
|
+
b = StringScanner.new("")
|
20
|
+
lambda { b.send(@method, (256 * 3 + 64)) }.should raise_error(TypeError)
|
21
|
+
lambda { b.send(@method, -200) }.should raise_error(TypeError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "doesn't call to_int on the argument" do
|
25
|
+
x = mock('x')
|
26
|
+
x.should_not_receive(:to_int)
|
27
|
+
|
28
|
+
lambda { "".send(@method, x) }.should raise_error(TypeError)
|
29
|
+
end
|
30
|
+
end
|