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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/rubysl/strscan.rb +2 -0
  9. data/lib/rubysl/strscan/strscan.rb +286 -0
  10. data/lib/rubysl/strscan/version.rb +5 -0
  11. data/lib/strscan.rb +1 -0
  12. data/rubysl-strscan.gemspec +22 -0
  13. data/spec/append_spec.rb +10 -0
  14. data/spec/beginning_of_line_spec.rb +6 -0
  15. data/spec/bol_spec.rb +6 -0
  16. data/spec/check_spec.rb +15 -0
  17. data/spec/check_until_spec.rb +14 -0
  18. data/spec/clear_spec.rb +24 -0
  19. data/spec/concat_spec.rb +10 -0
  20. data/spec/dup_spec.rb +38 -0
  21. data/spec/element_reference_spec.rb +48 -0
  22. data/spec/empty_spec.rb +24 -0
  23. data/spec/eos_spec.rb +6 -0
  24. data/spec/exist_spec.rb +23 -0
  25. data/spec/get_byte_spec.rb +6 -0
  26. data/spec/getbyte_spec.rb +27 -0
  27. data/spec/getch_spec.rb +43 -0
  28. data/spec/initialize_spec.rb +27 -0
  29. data/spec/inspect_spec.rb +19 -0
  30. data/spec/match_spec.rb +27 -0
  31. data/spec/matched_size_spec.rb +6 -0
  32. data/spec/matched_spec.rb +40 -0
  33. data/spec/matchedsize_spec.rb +26 -0
  34. data/spec/must_C_version_spec.rb +7 -0
  35. data/spec/peek_spec.rb +7 -0
  36. data/spec/peep_spec.rb +24 -0
  37. data/spec/pointer_spec.rb +10 -0
  38. data/spec/pos_spec.rb +10 -0
  39. data/spec/post_match_spec.rb +27 -0
  40. data/spec/pre_match_spec.rb +40 -0
  41. data/spec/reset_spec.rb +14 -0
  42. data/spec/rest_size_spec.rb +6 -0
  43. data/spec/rest_spec.rb +47 -0
  44. data/spec/restsize_spec.rb +24 -0
  45. data/spec/scan_full_spec.rb +29 -0
  46. data/spec/scan_spec.rb +81 -0
  47. data/spec/scan_until_spec.rb +22 -0
  48. data/spec/search_full_spec.rb +29 -0
  49. data/spec/shared/bol.rb +25 -0
  50. data/spec/shared/concat.rb +30 -0
  51. data/spec/shared/eos.rb +17 -0
  52. data/spec/shared/extract_range.rb +22 -0
  53. data/spec/shared/extract_range_matched.rb +22 -0
  54. data/spec/shared/get_byte.rb +28 -0
  55. data/spec/shared/matched_size.rb +21 -0
  56. data/spec/shared/peek.rb +44 -0
  57. data/spec/shared/pos.rb +83 -0
  58. data/spec/shared/rest_size.rb +18 -0
  59. data/spec/shared/terminate.rb +17 -0
  60. data/spec/skip_spec.rb +17 -0
  61. data/spec/skip_until_spec.rb +17 -0
  62. data/spec/string_spec.rb +39 -0
  63. data/spec/terminate_spec.rb +6 -0
  64. data/spec/unscan_spec.rb +28 -0
  65. metadata +201 -0
@@ -0,0 +1,7 @@
1
+ require 'strscan'
2
+
3
+ describe "StringScanner.must_C_version" do
4
+ it "returns self" do
5
+ StringScanner.must_C_version.should == StringScanner
6
+ end
7
+ end
data/spec/peek_spec.rb ADDED
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared/peek.rb', __FILE__)
2
+ require 'strscan'
3
+
4
+ describe "StringScanner#peek" do
5
+ it_behaves_like(:strscan_peek, :peek)
6
+ end
7
+
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
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../shared/pos.rb', __FILE__)
2
+ require 'strscan'
3
+
4
+ describe "StringScanner#pointer" do
5
+ it_behaves_like(:strscan_pos, :pointer)
6
+ end
7
+
8
+ describe "StringScanner#pointer=" do
9
+ it_behaves_like(:strscan_pos_set, :pointer=)
10
+ end
data/spec/pos_spec.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../shared/pos.rb', __FILE__)
2
+ require 'strscan'
3
+
4
+ describe "StringScanner#pos" do
5
+ it_behaves_like(:strscan_pos, :pos)
6
+ end
7
+
8
+ describe "StringScanner#pos=" do
9
+ it_behaves_like(:strscan_pos_set, :pos=)
10
+ end
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../shared/rest_size.rb', __FILE__)
2
+ require 'strscan'
3
+
4
+ describe "StringScanner#rest_size" do
5
+ it_behaves_like(:strscan_rest_size, :rest_size)
6
+ 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
@@ -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