string_stubber 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/string_stubber/base.rb +19 -6
- data/lib/string_stubber/core_ext.rb +51 -16
- data/lib/string_stubber/version.rb +1 -1
- data/spec/string_stubber/base_spec.rb +67 -7
- data/spec/string_stubber/core_ext_spec.rb +107 -0
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/lib/string_stubber/base.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module StringStubber
|
2
2
|
module Base
|
3
|
-
WORD = /
|
3
|
+
WORD = /(\w+[[:punct:]]*)+/
|
4
4
|
SNIP = /\s+$/
|
5
5
|
|
6
6
|
# Stubs a given text string, up to a given number of words
|
@@ -23,22 +23,35 @@ module StringStubber
|
|
23
23
|
return scan_text(scanner, max_text)
|
24
24
|
end
|
25
25
|
|
26
|
+
# Scans ahead one word position, and returns it
|
27
|
+
# @param [StringScanner] scanner
|
28
|
+
# @return [String]
|
26
29
|
def scan_word(scanner)
|
27
30
|
scanner.scan_until(WORD)
|
28
31
|
end
|
29
32
|
|
33
|
+
# Scans a given number of words from a scanner
|
34
|
+
# @param [StringScanner]
|
35
|
+
# @param [Fixnum]
|
36
|
+
# @return [String]
|
30
37
|
def scan_words(scanner, max_words)
|
31
|
-
max_words.times.map {
|
32
|
-
|
33
|
-
|
38
|
+
words = max_words.times.map {
|
39
|
+
scan_word(scanner)
|
40
|
+
}
|
41
|
+
words.compact!
|
42
|
+
words.join
|
34
43
|
end
|
35
44
|
|
45
|
+
# Scans a given number of words, up to a given character position (but not beyond)
|
46
|
+
# @param [StringScanner]
|
47
|
+
# @param [Fixnum]
|
48
|
+
# @return [String]
|
36
49
|
def scan_text(scanner, max_text)
|
37
50
|
start = scanner.pos
|
38
51
|
|
39
|
-
until scanner.pos >= max_text || scanner
|
52
|
+
until scanner.pos >= max_text || scan_word(scanner).nil?; end
|
40
53
|
|
41
|
-
(
|
54
|
+
(scanner.pre_match || scanner.string[start, max_text]).to_s.gsub(SNIP, '')
|
42
55
|
end
|
43
56
|
end # module Base
|
44
57
|
end # module StringStubber
|
@@ -2,10 +2,14 @@ module StringStubber
|
|
2
2
|
module CoreExt
|
3
3
|
include StringStubber::Base
|
4
4
|
|
5
|
+
# @return [StringScanner]
|
5
6
|
def scanner
|
6
7
|
@scanner ||= StringScanner.new(self)
|
7
8
|
end
|
8
9
|
|
10
|
+
# @param [Fixnum]
|
11
|
+
# @param [true, false]
|
12
|
+
# @return [String]
|
9
13
|
def stub_words(max_words, save_pos=false)
|
10
14
|
scanner.reset unless save_pos
|
11
15
|
|
@@ -18,53 +22,84 @@ module StringStubber
|
|
18
22
|
alias :stub :stub_words
|
19
23
|
alias :words :stub_words
|
20
24
|
|
21
|
-
|
25
|
+
# @param [Fixnum]
|
26
|
+
# @param [true, false]
|
27
|
+
# @return [String]
|
28
|
+
def stub_at_most(max_chars, save_pos=false)
|
22
29
|
scanner.reset unless save_pos
|
23
30
|
|
24
|
-
if max_chars < 0
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
str = if max_chars < 0
|
32
|
+
rev_stub_at_most(max_chars.abs, save_pos)
|
33
|
+
else
|
34
|
+
scan_text(scanner, max_chars)
|
35
|
+
end
|
36
|
+
|
37
|
+
scanner.unscan if str.empty? && scanner.pos > max_chars
|
38
|
+
|
39
|
+
return str
|
29
40
|
end
|
30
41
|
alias :stub_text :stub_at_most
|
31
42
|
alias :stub_chars :stub_at_most
|
32
43
|
alias :stub_pos :stub_at_most
|
33
44
|
alias :stub_to :stub_at_most
|
34
45
|
|
35
|
-
|
46
|
+
# @param [Fixnum]
|
47
|
+
# @param [true, false]
|
48
|
+
# @return [String]
|
49
|
+
def stub_at_least(min_chars, save_pos=false)
|
36
50
|
scanner.reset unless save_pos
|
37
51
|
|
38
52
|
if min_chars < 0
|
39
|
-
rev_stub_at_least(min_chars.abs, save_pos)
|
40
|
-
else
|
41
|
-
scan_text(scanner, min_chars) << scan_word(scanner).to_s
|
53
|
+
return rev_stub_at_least(min_chars.abs, save_pos)
|
42
54
|
end
|
55
|
+
|
56
|
+
start = scanner.pos
|
57
|
+
str = scan_text(scanner, min_chars)
|
58
|
+
|
59
|
+
if((scanner.pos - start) < min_chars)
|
60
|
+
str << scan_word(scanner).to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
str
|
43
64
|
end
|
44
65
|
alias :stub_thru :stub_at_least
|
45
66
|
alias :stub_through :stub_at_least
|
46
67
|
|
47
|
-
|
48
68
|
private
|
69
|
+
# @param [Fixnum]
|
70
|
+
# @param [true, false]
|
71
|
+
# @return [String]
|
49
72
|
def rev_stub_words(max_words, save_pos=false)
|
50
73
|
str = self.reverse
|
51
74
|
str.scanner.pos = 0 - scanner.pos if save_pos
|
52
75
|
|
53
|
-
|
76
|
+
stub = str.stub_words(max_words, save_pos).reverse!
|
77
|
+
scanner.pos = 0 - str.scanner.pos
|
78
|
+
return stub
|
54
79
|
end
|
55
80
|
|
56
|
-
|
81
|
+
# @param [Fixnum]
|
82
|
+
# @param [true, false]
|
83
|
+
# @return [String]
|
84
|
+
def rev_stub_at_most(max_chars, save_pos=false)
|
57
85
|
str = self.reverse
|
58
86
|
str.scanner.pos = 0 - scanner.pos if save_pos
|
59
87
|
|
60
|
-
|
88
|
+
stub = str.stub_at_most(max_chars, save_pos).reverse!
|
89
|
+
scanner.pos = 0 - str.scanner.pos
|
90
|
+
return stub
|
61
91
|
end
|
62
92
|
|
63
|
-
|
93
|
+
# @param [Fixnum]
|
94
|
+
# @param [true, false]
|
95
|
+
# @return [String]
|
96
|
+
def rev_stub_at_least(min_chars, save_pos=false)
|
64
97
|
str = self.reverse
|
65
98
|
str.scanner.pos = 0 - scanner.pos if save_pos
|
66
99
|
|
67
|
-
|
100
|
+
stub = str.stub_at_least(min_chars, save_pos).reverse!
|
101
|
+
scanner.pos = 0 - str.scanner.pos
|
102
|
+
return stub
|
68
103
|
end
|
69
104
|
end
|
70
105
|
end
|
@@ -17,7 +17,7 @@ describe StringStubber::Base do
|
|
17
17
|
end
|
18
18
|
end # Should be a Mix-In
|
19
19
|
|
20
|
-
describe 'The stubbing methods should behave as
|
20
|
+
describe 'The stubbing methods should behave as documented' do
|
21
21
|
before :each do
|
22
22
|
@text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat. "
|
23
23
|
@text << "Aliquam sit amet felis. Etiam congue. Donec risus risus, pretium ac, tincidunt eu, tempor eu, quam. Morbi "
|
@@ -29,7 +29,7 @@ describe StringStubber::Base do
|
|
29
29
|
@count = @text.split(/\W+/).count
|
30
30
|
end
|
31
31
|
|
32
|
-
describe '
|
32
|
+
describe 'Methods: stub_words, scan_words' do
|
33
33
|
it 'should return the expected number of words' do
|
34
34
|
StringStubber.stub_words(@text, 10).split(/\W+/).count.should be(10)
|
35
35
|
end
|
@@ -72,17 +72,77 @@ describe StringStubber::Base do
|
|
72
72
|
#
|
73
73
|
end # describe 'Method: stub_words'
|
74
74
|
|
75
|
-
describe '
|
76
|
-
it 'should return
|
75
|
+
describe 'Methods: stub_text, scan_text' do
|
76
|
+
it 'should return fewer chars than specified, if the offset is in the middle of a word' do
|
77
77
|
StringStubber.stub_text(@text, 33).size.should be(27)
|
78
78
|
end
|
79
79
|
|
80
|
-
it 'should return
|
81
|
-
StringStubber.stub_text(@text,
|
80
|
+
it 'should return the same number of chars specified, if the offset lands on a punctuation character' do
|
81
|
+
StringStubber.stub_text(@text, 27).size.should be(21)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should return fewer chars than specified, if the position lands in white-space' do
|
85
|
+
(StringStubber.stub_text(@text, 28).size < 28).should be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should return the whole string, if the ammt of text exceeds the amount of actual text' do
|
89
|
+
StringStubber.stub_text(@text, 2000).casecmp(@text).should be(0)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should return a copy of the whole string, if the ammt of text exceeds the amount of actual text' do
|
93
|
+
(StringStubber.stub_text(@text, 2000).object_id != @text.object_id).should be_true
|
82
94
|
end
|
83
95
|
|
84
|
-
it 'should return
|
96
|
+
it 'should always return a string' do
|
97
|
+
stubs = [
|
98
|
+
StringStubber.stub_text(@text, -2000),
|
99
|
+
StringStubber.stub_text(@text, -1),
|
100
|
+
StringStubber.stub_text(@text, 0),
|
101
|
+
StringStubber.stub_text(@text, 10),
|
102
|
+
StringStubber.stub_text(@text, 2000)
|
103
|
+
]
|
104
|
+
|
105
|
+
stubs.each {|stub|
|
106
|
+
stub.is_a?(String).should be_true
|
107
|
+
}
|
85
108
|
end
|
86
109
|
end # describe 'Method: stub_text'
|
110
|
+
|
111
|
+
describe 'Methods: scan_word' do
|
112
|
+
before :each do
|
113
|
+
# #1 #2 #3 #4 #5 #6 #7 #8
|
114
|
+
@words = %w[Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ]
|
115
|
+
@wjoin = @words.join(' ')
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should scan ahead exactly one word' do
|
119
|
+
ss = StringScanner.new(@wjoin)
|
120
|
+
|
121
|
+
x = 0
|
122
|
+
until StringStubber.scan_word(ss).nil?
|
123
|
+
x += 1
|
124
|
+
end
|
125
|
+
|
126
|
+
x.should be(@words.count)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return the correct word' do
|
130
|
+
ss = StringScanner.new(@wjoin)
|
131
|
+
@words.each do |word|
|
132
|
+
StringStubber.scan_word(ss).strip.should eql(word)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'scan_word should return a string, unless there is no more to scan' do
|
137
|
+
ss = StringScanner.new(@wjoin)
|
138
|
+
x = 0
|
139
|
+
|
140
|
+
until (word = StringStubber.scan_word(ss)).nil?
|
141
|
+
word.should be_instance_of(String)
|
142
|
+
end
|
143
|
+
|
144
|
+
word.should be_nil
|
145
|
+
end
|
146
|
+
end
|
87
147
|
end
|
88
148
|
end
|
@@ -1,2 +1,109 @@
|
|
1
1
|
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
2
|
|
3
|
+
describe StringStubber::CoreExt do
|
4
|
+
describe 'The CoreExt module should be mixed into String (via string_stubber.rb)' do
|
5
|
+
before :each do
|
6
|
+
@methods = [ :scanner, :stub_words, :stub_at_most, :stub_at_least ]
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should have class methods available' do
|
10
|
+
text = "it 'should have class methods available' <-- OMG META"
|
11
|
+
|
12
|
+
@methods.each do |method|
|
13
|
+
text.respond_to?(method).should be_true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end # Should be mixed into String
|
17
|
+
|
18
|
+
describe 'The stubbing methods should behave as documented' do
|
19
|
+
before :each do
|
20
|
+
@text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat. "
|
21
|
+
@count = @text.split(/\W+/).count
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should return a StringScanner instance, when calling String#scanner' do
|
25
|
+
@text.scanner.should be_instance_of(StringScanner)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should act upon the String instance, itself' do
|
29
|
+
@text.scanner.string.should be(@text)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'Method: stub_words' do
|
33
|
+
it 'should retain its position' do
|
34
|
+
@text.stub_words(1)
|
35
|
+
@text.scanner.pos.should be(5)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should always return a string' do
|
39
|
+
@text.stub_words( -100).should be_instance_of(String)
|
40
|
+
@text.stub_words( -10).should be_instance_of(String)
|
41
|
+
@text.stub_words( 0).should be_instance_of(String)
|
42
|
+
@text.stub_words( 10).should be_instance_of(String)
|
43
|
+
@text.stub_words( 100).should be_instance_of(String)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should correctly act on negative offsets' do
|
47
|
+
@text.stub_words( -1).should eql("placerat. ")
|
48
|
+
@text.stub_words( -10).should eql("consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat. ")
|
49
|
+
# @text.stub_words( -1, true).should eql("amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat. ")
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should never have trailing spaces'
|
53
|
+
it 'should return the expected number of words'
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'Method: stub_at_most' do
|
57
|
+
it 'should retain its position, relative to what was returned' do
|
58
|
+
@text.stub_at_most(3)
|
59
|
+
@text.scanner.pos.should be(0)
|
60
|
+
|
61
|
+
@text.stub_at_most(5)
|
62
|
+
@text.scanner.pos.should be(5)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should always return a string' do
|
66
|
+
@text.stub_at_most( -100).should be_instance_of(String)
|
67
|
+
@text.stub_at_most( -10).should be_instance_of(String)
|
68
|
+
@text.stub_at_most( 0).should be_instance_of(String)
|
69
|
+
@text.stub_at_most( 10).should be_instance_of(String)
|
70
|
+
@text.stub_at_most( 100).should be_instance_of(String)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should correctly act on negative offsets' do
|
74
|
+
end
|
75
|
+
it 'should never have trailing spaces'
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'Method: stub_at_least' do
|
79
|
+
it 'should retain its position' do
|
80
|
+
@text.stub_at_least(3)
|
81
|
+
@text.scanner.pos.should be(5)
|
82
|
+
|
83
|
+
@text.stub_at_least(5)
|
84
|
+
@text.scanner.pos.should be(5)
|
85
|
+
|
86
|
+
@text.stub_at_least(6)
|
87
|
+
@text.scanner.pos.should be(11)
|
88
|
+
|
89
|
+
@text.stub_at_least(3)
|
90
|
+
@text.scanner.pos.should be(5)
|
91
|
+
|
92
|
+
@text.stub_at_least(4, true)
|
93
|
+
@text.scanner.pos.should be(11)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should always return a string' do
|
97
|
+
@text.stub_at_least( -100).should be_instance_of(String)
|
98
|
+
@text.stub_at_least( -10).should be_instance_of(String)
|
99
|
+
@text.stub_at_least( 0).should be_instance_of(String)
|
100
|
+
@text.stub_at_least( 10).should be_instance_of(String)
|
101
|
+
@text.stub_at_least( 100).should be_instance_of(String)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should correctly act on negative offsets' do
|
105
|
+
end
|
106
|
+
it 'should never have trailing spaces'
|
107
|
+
end
|
108
|
+
end # Docs check
|
109
|
+
end
|