stubber 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|