string_stubber 0.0.3 → 0.0.5
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.
- 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
|