rubysl-strscan 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|