stubber 0.1.1
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/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/README.md +53 -0
- data/Rakefile +22 -0
- data/lib/stubber.rb +11 -0
- data/lib/stubber/base.rb +60 -0
- data/lib/stubber/core_ext.rb +111 -0
- data/lib/stubber/version.rb +3 -0
- data/spec/quality_spec.rb +11 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/string_stubber/base_spec.rb +150 -0
- data/spec/string_stubber/core_ext_spec.rb +109 -0
- data/spec/string_stubber/readme_spec.rb +26 -0
- data/spec/support/custom_matchers.rb +44 -0
- data/string_stubber.gemspec +23 -0
- metadata +98 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Stubber
|
2
|
+
|
3
|
+
Stubber is a simple gem that lets you stub strings, using "words" as the unit of measure. For example:
|
4
|
+
|
5
|
+
require 'stubber'
|
6
|
+
require 'lorem' # Or just add your own text
|
7
|
+
|
8
|
+
str = Lorem::Base.new('paragraphs', 1).output
|
9
|
+
# => "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat."
|
10
|
+
|
11
|
+
# Get the first 5 words
|
12
|
+
str.stub_words(5)
|
13
|
+
# => "Lorem ipsum dolor sit amet"
|
14
|
+
|
15
|
+
# Get the NEXT 5 words
|
16
|
+
str.stub_words(5, true)
|
17
|
+
# => ", consectetuer adipiscing elit. Vivamus vitae"
|
18
|
+
|
19
|
+
# Grab the _complete_ words, appearing _up to_ position 20
|
20
|
+
str.stub_to(70)
|
21
|
+
# => "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus "
|
22
|
+
|
23
|
+
str.stub_to(70).size
|
24
|
+
# => 66
|
25
|
+
|
26
|
+
# Grab the _complete_ words, appearing _through_ position 20
|
27
|
+
str.stub_thru(70)
|
28
|
+
# => "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae"
|
29
|
+
|
30
|
+
str.stub_thru(70).size
|
31
|
+
# => 71
|
32
|
+
|
33
|
+
Now the other direction!
|
34
|
+
|
35
|
+
str.stub_words(-5)
|
36
|
+
# => "risus vitae lorem iaculis placerat."
|
37
|
+
|
38
|
+
str.stub_words(-5, true)
|
39
|
+
# => "consectetuer adipiscing elit. Vivamus vitae "
|
40
|
+
|
41
|
+
str.stub_to(-45)
|
42
|
+
# => " vitae risus vitae lorem iaculis placerat."
|
43
|
+
|
44
|
+
str.stub_to(-45).size
|
45
|
+
# => 42
|
46
|
+
|
47
|
+
So far, so good! Suggestions are welcome.
|
48
|
+
|
49
|
+
# TODO
|
50
|
+
|
51
|
+
* stubbing from the right direction is simple to do and will be the next addition.
|
52
|
+
* *^* done, needs specs
|
53
|
+
* left and right indexes
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
task :release => :spec
|
9
|
+
|
10
|
+
desc "Run Specs"
|
11
|
+
Rspec::Core::RakeTask.new(:spec) do |spec|
|
12
|
+
spec.pattern = "spec/**/*_spec.rb"
|
13
|
+
spec.verbose = true
|
14
|
+
spec.rspec_opts = ['--color']
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'yard'
|
18
|
+
|
19
|
+
desc "Generate YARD docs"
|
20
|
+
YARD::Rake::YardocTask.new(:yard) do |t|
|
21
|
+
t.files += ['lib/**/*.rb']
|
22
|
+
end
|
data/lib/stubber.rb
ADDED
data/lib/stubber/base.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'stubber/version'
|
2
|
+
|
3
|
+
module Stubber
|
4
|
+
autoload :CoreExt, 'stubber/core_ext'
|
5
|
+
|
6
|
+
module Base
|
7
|
+
WORD = /\w+[\!\.\?]*[^\s,]/
|
8
|
+
|
9
|
+
# Stubs a given text string, up to a given number of words
|
10
|
+
# @param [String] text Any piece of text
|
11
|
+
# @param [Fixnum] max_words The desired number of words
|
12
|
+
# @return [String] The text, stubbed at max_words number of words
|
13
|
+
def stub_words(text, max_words)
|
14
|
+
scanner = StringScanner.new(text.to_s)
|
15
|
+
|
16
|
+
return scan_words(scanner, max_words)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Stubs the given text string a number of whole-words, not to go beyond the given text position
|
20
|
+
# @param [String] text Any piece of text
|
21
|
+
# @param [Fixnum] max_text Text position that delimits the desired number of whole words
|
22
|
+
# @return [String] The text, stubbed at the max_text position
|
23
|
+
def stub_text(text, max_text)
|
24
|
+
scanner = StringScanner.new(text.to_s)
|
25
|
+
|
26
|
+
return scan_text(scanner, max_text)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Scans ahead one word position, and returns it
|
30
|
+
# @param [StringScanner] scanner
|
31
|
+
# @return [String]
|
32
|
+
def scan_word(scanner)
|
33
|
+
scanner.scan_until(WORD)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Scans a given number of words from a scanner
|
37
|
+
# @param [StringScanner]
|
38
|
+
# @param [Fixnum]
|
39
|
+
# @return [String]
|
40
|
+
def scan_words(scanner, max_words)
|
41
|
+
words = max_words.times.map {
|
42
|
+
scan_word(scanner)
|
43
|
+
}
|
44
|
+
words.compact!
|
45
|
+
words.join
|
46
|
+
end
|
47
|
+
|
48
|
+
# Scans a given number of words, up to a given character position (but not beyond)
|
49
|
+
# @param [StringScanner]
|
50
|
+
# @param [Fixnum]
|
51
|
+
# @return [String]
|
52
|
+
def scan_text(scanner, max_text)
|
53
|
+
start = scanner.pos
|
54
|
+
|
55
|
+
until scanner.pos >= (max_text + start) || scan_word(scanner).nil?; end
|
56
|
+
|
57
|
+
(scanner.pre_match || scanner.string[start, max_text]).to_s
|
58
|
+
end
|
59
|
+
end # module Base
|
60
|
+
end # module Stubber
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'stubber/base'
|
2
|
+
|
3
|
+
module Stubber
|
4
|
+
module CoreExt
|
5
|
+
include Stubber::Base
|
6
|
+
|
7
|
+
# @return [StringScanner]
|
8
|
+
def scanner
|
9
|
+
@scanner ||= StringScanner.new(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [Fixnum]
|
13
|
+
# @param [true, false]
|
14
|
+
# @return [String]
|
15
|
+
def stub_words(max_words, save_pos=false)
|
16
|
+
scanner.reset unless save_pos
|
17
|
+
|
18
|
+
if max_words < 0
|
19
|
+
rev_stub_words(max_words.abs, save_pos)
|
20
|
+
else
|
21
|
+
scan_words(scanner, max_words)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias :stub :stub_words
|
25
|
+
alias :words :stub_words
|
26
|
+
|
27
|
+
# @param [Fixnum]
|
28
|
+
# @param [true, false]
|
29
|
+
# @return [String]
|
30
|
+
def stub_at_most(max_chars, save_pos=false)
|
31
|
+
scanner.reset unless save_pos
|
32
|
+
|
33
|
+
str = if max_chars < 0
|
34
|
+
rev_stub_at_most(max_chars.abs, save_pos)
|
35
|
+
else
|
36
|
+
scan_text(scanner, max_chars)
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
scanner.unscan if str.empty? && scanner.pos > max_chars && !scanner.pre_match.nil?
|
41
|
+
rescue StringScanner::Error => e
|
42
|
+
# Do nothing
|
43
|
+
end
|
44
|
+
|
45
|
+
return str
|
46
|
+
end
|
47
|
+
alias :stub_text :stub_at_most
|
48
|
+
alias :stub_chars :stub_at_most
|
49
|
+
alias :stub_pos :stub_at_most
|
50
|
+
alias :stub_to :stub_at_most
|
51
|
+
|
52
|
+
# @param [Fixnum]
|
53
|
+
# @param [true, false]
|
54
|
+
# @return [String]
|
55
|
+
def stub_at_least(min_chars, save_pos=false)
|
56
|
+
scanner.reset unless save_pos
|
57
|
+
|
58
|
+
if min_chars < 0
|
59
|
+
return rev_stub_at_least(min_chars.abs, save_pos)
|
60
|
+
end
|
61
|
+
|
62
|
+
start = scanner.pos
|
63
|
+
str = scan_text(scanner, min_chars)
|
64
|
+
|
65
|
+
if(str.size < (min_chars + start))
|
66
|
+
str << scanner.matched.to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
str
|
70
|
+
end
|
71
|
+
alias :stub_thru :stub_at_least
|
72
|
+
alias :stub_through :stub_at_least
|
73
|
+
|
74
|
+
private
|
75
|
+
# @param [Fixnum]
|
76
|
+
# @param [true, false]
|
77
|
+
# @return [String]
|
78
|
+
def rev_stub_words(max_words, save_pos=false)
|
79
|
+
str = self.reverse
|
80
|
+
str.scanner.pos = 0 - scanner.pos if save_pos
|
81
|
+
|
82
|
+
stub = str.stub_words(max_words, save_pos).reverse!
|
83
|
+
scanner.pos = 0 - str.scanner.pos
|
84
|
+
return stub
|
85
|
+
end
|
86
|
+
|
87
|
+
# @param [Fixnum]
|
88
|
+
# @param [true, false]
|
89
|
+
# @return [String]
|
90
|
+
def rev_stub_at_most(max_chars, save_pos=false)
|
91
|
+
str = self.reverse
|
92
|
+
str.scanner.pos = 0 - scanner.pos if save_pos
|
93
|
+
|
94
|
+
stub = str.stub_at_most(max_chars, save_pos).reverse!
|
95
|
+
scanner.pos = 0 - str.scanner.pos
|
96
|
+
return stub
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param [Fixnum]
|
100
|
+
# @param [true, false]
|
101
|
+
# @return [String]
|
102
|
+
def rev_stub_at_least(min_chars, save_pos=false)
|
103
|
+
str = self.reverse
|
104
|
+
str.scanner.pos = 0 - scanner.pos if save_pos
|
105
|
+
|
106
|
+
stub = str.stub_at_least(min_chars, save_pos).reverse!
|
107
|
+
scanner.pos = 0 - str.scanner.pos
|
108
|
+
return stub
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
IGNORE = /\.(gitmodules|png$|tar$|gz$|rbc$|gem$|pdf$)/
|
4
|
+
|
5
|
+
describe "The application itself" do
|
6
|
+
it "has no malformed whitespace" do
|
7
|
+
files = `git ls-files`.split("\n").select {|fn| fn !~ IGNORE}
|
8
|
+
|
9
|
+
files.should be_well_formed
|
10
|
+
end
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe Stubber::Base do
|
4
|
+
describe 'The Base module should behave like a proper mix-in ;)' do
|
5
|
+
before :each do
|
6
|
+
@methods = [ :stub_words, :stub_text, :scan_word, :scan_words, :scan_text ]
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should have class methods available' do
|
10
|
+
class TestMixin
|
11
|
+
extend Stubber::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
@methods.each {|method|
|
15
|
+
TestMixin.respond_to?(method).should be_true
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end # Should be a Mix-In
|
19
|
+
|
20
|
+
describe 'The stubbing methods should behave as documented' do
|
21
|
+
before :each do
|
22
|
+
@text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat. "
|
23
|
+
@text << "Aliquam sit amet felis. Etiam congue. Donec risus risus, pretium ac, tincidunt eu, tempor eu, quam. Morbi "
|
24
|
+
@text << "blandit mollis magna. Suspendisse eu tortor. Donec vitae felis nec ligula blandit rhoncus. Ut a pede ac neque "
|
25
|
+
@text << "mattis facilisis. Nulla nunc ipsum, sodales vitae, hendrerit non, imperdiet ac, ante. Morbi sit amet mi. Ut "
|
26
|
+
@text << "magna. Curabitur id est. Nulla velit. Sed consectetuer sodales justo. Aliquam dictum gravida libero. Sed eu "
|
27
|
+
@text << "turpis. Nunc id lorem. Aenean consequat tempor mi. Phasellus in neque. Nunc fermentum convallis ligula."
|
28
|
+
|
29
|
+
@count = @text.split(/\W+/).count
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'Methods: stub_words, scan_words' do
|
33
|
+
it 'should return the expected number of words' do
|
34
|
+
Stubber.stub_words(@text, 10).split(/\W+/).count.should be(10)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should always return a string' do
|
38
|
+
stubs = [
|
39
|
+
Stubber.stub_words(@text, -100),
|
40
|
+
Stubber.stub_words(@text, -1),
|
41
|
+
Stubber.stub_words(@text, 0),
|
42
|
+
Stubber.stub_words(@text, 10),
|
43
|
+
Stubber.stub_words(@text, 100)
|
44
|
+
]
|
45
|
+
|
46
|
+
stubs.each {|stub|
|
47
|
+
stub.is_a?(String).should be_true
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should never have trailing spaces' do
|
52
|
+
@count.times {|x|
|
53
|
+
(Stubber.stub_words(@text, x) !~ /\s+[\s\W]+$/).should be_true
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'Should only have trailing non-words if they immediately follow words' do
|
58
|
+
# regex = /[^\w\s]/
|
59
|
+
# scanner = StringScanner.new(@text)
|
60
|
+
# count = @text.split(/[^\w\s]/).count
|
61
|
+
# puncts = Hash[ count.times.map {
|
62
|
+
# scanner.scan_until(regex)
|
63
|
+
# [scanner.pre_match.split.count, scanner.pos - 1]
|
64
|
+
# }
|
65
|
+
# ]
|
66
|
+
#
|
67
|
+
# @count.times {|x|
|
68
|
+
# (Stubber.stub_words(@text, x) !~ /\s+$/).should be_true
|
69
|
+
# }
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
end # describe 'Method: stub_words'
|
74
|
+
|
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
|
+
Stubber.stub_text(@text, 33).size.should be(28)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should return the same number of chars specified, if the offset lands on a punctuation character' do
|
81
|
+
# This is a tough nut to crack. Eesh.
|
82
|
+
Stubber.stub_text(@text, 27).should == "Lorem ipsum dolor sit amet, "
|
83
|
+
Stubber.stub_text(@text, 27).size.should be(28)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should return fewer chars than specified, if the position lands in white-space' do
|
87
|
+
(Stubber.stub_text(@text, 28).size == 28).should be_true
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should return the whole string, if the ammt of text exceeds the amount of actual text' do
|
91
|
+
Stubber.stub_text(@text, 2000).casecmp(@text).should be(0)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return a copy of the whole string, if the ammt of text exceeds the amount of actual text' do
|
95
|
+
(Stubber.stub_text(@text, 2000).object_id != @text.object_id).should be_true
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should always return a string' do
|
99
|
+
stubs = [
|
100
|
+
Stubber.stub_text(@text, -2000),
|
101
|
+
Stubber.stub_text(@text, -1),
|
102
|
+
Stubber.stub_text(@text, 0),
|
103
|
+
Stubber.stub_text(@text, 10),
|
104
|
+
Stubber.stub_text(@text, 2000)
|
105
|
+
]
|
106
|
+
|
107
|
+
stubs.each {|stub|
|
108
|
+
stub.is_a?(String).should be_true
|
109
|
+
}
|
110
|
+
end
|
111
|
+
end # describe 'Method: stub_text'
|
112
|
+
|
113
|
+
describe 'Methods: scan_word' do
|
114
|
+
before :each do
|
115
|
+
# #1 #2 #3 #4 #5 #6 #7 #8
|
116
|
+
@words = %w[Lorem ipsum dolor sit amet consectetuer adipiscing elit.]
|
117
|
+
@wjoin = @words.join(' ')
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should scan ahead exactly one word' do
|
121
|
+
ss = StringScanner.new(@wjoin)
|
122
|
+
|
123
|
+
x = 0
|
124
|
+
until Stubber.scan_word(ss).nil?
|
125
|
+
x += 1
|
126
|
+
end
|
127
|
+
|
128
|
+
x.should be(@words.count)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should return the correct word' do
|
132
|
+
ss = StringScanner.new(@wjoin)
|
133
|
+
@words.each do |word|
|
134
|
+
Stubber.scan_word(ss).strip.should == word
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'scan_word should return a string, unless there is no more to scan' do
|
139
|
+
ss = StringScanner.new(@wjoin)
|
140
|
+
x = 0
|
141
|
+
|
142
|
+
until (word = Stubber.scan_word(ss)).nil?
|
143
|
+
word.should be_instance_of(String)
|
144
|
+
end
|
145
|
+
|
146
|
+
word.should be_nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe Stubber::CoreExt do
|
4
|
+
describe 'The CoreExt module should be mixed into String (via 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, ")
|
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
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
# This Spec is to validate the stuff I put in the README
|
4
|
+
#
|
5
|
+
describe 'Stubber::Readme' do
|
6
|
+
it "shouldn't make me look bad" do
|
7
|
+
#
|
8
|
+
# str = Lorem::Base.new('paragraphs', 1).output
|
9
|
+
#
|
10
|
+
str = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae risus vitae lorem iaculis placerat."
|
11
|
+
|
12
|
+
str.stub_words(5).should == "Lorem ipsum dolor sit amet"
|
13
|
+
str.stub_words(5, true).should == ", consectetuer adipiscing elit. Vivamus vitae"
|
14
|
+
str.stub_to(70).should == "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus "
|
15
|
+
str.stub_to(70).size.should be(66)
|
16
|
+
str.stub_thru(70).should == "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus vitae"
|
17
|
+
str.stub_thru(70).size.should be(71)
|
18
|
+
|
19
|
+
# Now the negatives!
|
20
|
+
str.stub_words(-5).should == "risus vitae lorem iaculis placerat."
|
21
|
+
str.stub_words(-5, true).should == "consectetuer adipiscing elit. Vivamus vitae "
|
22
|
+
str.stub_to(-45).should == " vitae risus vitae lorem iaculis placerat."
|
23
|
+
str.stub_to(-45).size.should be(42)
|
24
|
+
# str.stub_thru(-50)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CustomMatchers
|
2
|
+
class BeWellFormed
|
3
|
+
def matches?(files)
|
4
|
+
@errors = files.map {|filename|
|
5
|
+
[
|
6
|
+
check_for_tabs(filename),
|
7
|
+
excessive_spacing(filename),
|
8
|
+
newline_precedes_eof(filename)
|
9
|
+
]
|
10
|
+
}.flatten.compact
|
11
|
+
|
12
|
+
@errors.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def failure_message_for_should
|
16
|
+
@errors.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def check_for_tabs(filename)
|
21
|
+
bad_lines = File.readlines(filename).each_with_index.map do |line, line_no|
|
22
|
+
line_no + 1 if line["\t"] and line !~ /^\s+#.*\s+\n$/
|
23
|
+
end.flatten.compact
|
24
|
+
|
25
|
+
"#{filename} has tab characters on lines #{bad_lines.join(', ')}" if bad_lines.any?
|
26
|
+
end
|
27
|
+
|
28
|
+
def excessive_spacing(filename)
|
29
|
+
bad_lines = File.readlines(filename).each_with_index.map do |line, line_no|
|
30
|
+
line_no + 1 if line =~ /\s+\n$/ and line !~ /^\s+#.*\s+\n$/
|
31
|
+
end.flatten.compact
|
32
|
+
|
33
|
+
"#{filename} has spaces on the EOL on lines #{bad_lines.join(', ')}" if bad_lines.any?
|
34
|
+
end
|
35
|
+
|
36
|
+
def newline_precedes_eof(filename)
|
37
|
+
"#{filename} does not have a newline (\\n) before EOF" if File.read(filename) !~ /\n$/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def be_well_formed
|
42
|
+
BeWellFormed.new
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "stubber/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "stubber"
|
7
|
+
s.version = Stubber::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Scott Gonyea"]
|
10
|
+
s.email = ["me@sgonyea.com"]
|
11
|
+
s.homepage = "http://github.com/sgonyea/string_stubber"
|
12
|
+
s.summary = %q{Allows you to truncate Strings, while preserving whole-words.}
|
13
|
+
s.description = %q{Stubber allows you to truncate Strings, while preserving whole-words.}
|
14
|
+
|
15
|
+
s.add_dependency 'yard', '~>0.6'
|
16
|
+
|
17
|
+
s.add_development_dependency 'rspec', '~>2.4'
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stubber
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Scott Gonyea
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-03-01 00:00:00 -08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: yard
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0.6"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "2.4"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
description: Stubber allows you to truncate Strings, while preserving whole-words.
|
39
|
+
email:
|
40
|
+
- me@sgonyea.com
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- .rspec
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/stubber.rb
|
54
|
+
- lib/stubber/base.rb
|
55
|
+
- lib/stubber/core_ext.rb
|
56
|
+
- lib/stubber/version.rb
|
57
|
+
- spec/quality_spec.rb
|
58
|
+
- spec/spec_helper.rb
|
59
|
+
- spec/string_stubber/base_spec.rb
|
60
|
+
- spec/string_stubber/core_ext_spec.rb
|
61
|
+
- spec/string_stubber/readme_spec.rb
|
62
|
+
- spec/support/custom_matchers.rb
|
63
|
+
- string_stubber.gemspec
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/sgonyea/string_stubber
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 1.6.0
|
89
|
+
signing_key:
|
90
|
+
specification_version: 3
|
91
|
+
summary: Allows you to truncate Strings, while preserving whole-words.
|
92
|
+
test_files:
|
93
|
+
- spec/quality_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
- spec/string_stubber/base_spec.rb
|
96
|
+
- spec/string_stubber/core_ext_spec.rb
|
97
|
+
- spec/string_stubber/readme_spec.rb
|
98
|
+
- spec/support/custom_matchers.rb
|