yardstick 0.1.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.
- data/.document +5 -0
- data/.gitignore +10 -0
- data/LICENSE +20 -0
- data/README.markdown +117 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/bin/yardstick +7 -0
- data/deps.rip +1 -0
- data/lib/yardstick/autoload.rb +16 -0
- data/lib/yardstick/cli.rb +76 -0
- data/lib/yardstick/core_ext/object.rb +13 -0
- data/lib/yardstick/measurable.rb +78 -0
- data/lib/yardstick/measurement.rb +217 -0
- data/lib/yardstick/measurement_set.rb +130 -0
- data/lib/yardstick/method.rb +111 -0
- data/lib/yardstick/ordered_set.rb +115 -0
- data/lib/yardstick/processor.rb +65 -0
- data/lib/yardstick/rake/measurement.rb +101 -0
- data/lib/yardstick/rake/verify.rb +179 -0
- data/lib/yardstick/rule.rb +61 -0
- data/lib/yardstick/rule_set.rb +18 -0
- data/lib/yardstick/yard_ext.rb +20 -0
- data/lib/yardstick.rb +52 -0
- data/spec/public/yardstick/cli_spec.rb +108 -0
- data/spec/public/yardstick/measurement_set_spec.rb +265 -0
- data/spec/public/yardstick/measurement_spec.rb +256 -0
- data/spec/public/yardstick/method_spec.rb +356 -0
- data/spec/public/yardstick/rake/measurement_spec.rb +173 -0
- data/spec/public/yardstick/rake/verify_spec.rb +229 -0
- data/spec/public/yardstick_spec.rb +70 -0
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/yardstick/rule_spec.rb +28 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +45 -0
- data/tasks/ci.rake +1 -0
- data/tasks/heckle.rake +52 -0
- data/tasks/metrics.rake +5 -0
- data/tasks/rdoc.rake +15 -0
- data/tasks/spec.rake +22 -0
- data/tasks/yardstick.rake +9 -0
- data/yardstick.gemspec +90 -0
- metadata +113 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
module Yardstick
|
2
|
+
class Rule
|
3
|
+
|
4
|
+
# Return a Rule instance
|
5
|
+
#
|
6
|
+
# @param [#to_str] description
|
7
|
+
# the description of the Rule
|
8
|
+
#
|
9
|
+
# @yield []
|
10
|
+
# the measurement for the rule
|
11
|
+
#
|
12
|
+
# @return [Rule]
|
13
|
+
# the rule instance
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
def initialize(description, &block)
|
17
|
+
@description = description.to_str
|
18
|
+
@block = block
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return a Measurement for a docstring
|
22
|
+
#
|
23
|
+
# @param [YARD::Docstring] docstring
|
24
|
+
# the docstring to measure
|
25
|
+
#
|
26
|
+
# @return [Measurement]
|
27
|
+
# the measurement
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
def measure(docstring)
|
31
|
+
Measurement.new(@description, docstring, &@block)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Test if Rule is equal to another rule
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# rule == equal_rule # => true
|
38
|
+
#
|
39
|
+
# @param [Rule] other
|
40
|
+
# the other Rule
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
# true if the Rule is equal to the other, false if not
|
44
|
+
#
|
45
|
+
# @api semipublic
|
46
|
+
def eql?(other)
|
47
|
+
@description.eql?(other.instance_variable_get(:@description))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Return hash identifier for the Rule
|
51
|
+
#
|
52
|
+
# @return [Integer]
|
53
|
+
# the hash identifier
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
def hash
|
57
|
+
@description.hash
|
58
|
+
end
|
59
|
+
|
60
|
+
end # class Rule
|
61
|
+
end # module Yardstick
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Yardstick
|
2
|
+
class RuleSet < OrderedSet
|
3
|
+
|
4
|
+
# Measure a docstring with all Rules
|
5
|
+
#
|
6
|
+
# @param [YARD::Docstring] docstring
|
7
|
+
# the docstring to measure
|
8
|
+
#
|
9
|
+
# @return [MeasurementSet]
|
10
|
+
# a collection of measurements
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
def measure(docstring)
|
14
|
+
MeasurementSet.new(map { |rule| rule.measure(docstring) })
|
15
|
+
end
|
16
|
+
|
17
|
+
end # class RuleSet
|
18
|
+
end # module Yardstick
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module YARD #:nodoc: all
|
2
|
+
module CodeObjects
|
3
|
+
class MethodObject
|
4
|
+
|
5
|
+
# Return the docstring associated with the method
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# method_object.docstring # => YARD::Docstring instance
|
9
|
+
#
|
10
|
+
# @return [YARD::Docstring]
|
11
|
+
# the docstring for this method
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
def docstring
|
15
|
+
super.extend(Yardstick::Method)
|
16
|
+
end
|
17
|
+
|
18
|
+
end # class MethodObject
|
19
|
+
end # module CodeObjects
|
20
|
+
end # module YARD
|
data/lib/yardstick.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yard'
|
3
|
+
|
4
|
+
module Yardstick
|
5
|
+
VERSION = '0.1.0'.freeze
|
6
|
+
ROOT = Pathname(__FILE__).dirname.parent.expand_path.freeze
|
7
|
+
|
8
|
+
# Measure a list of files
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# Yardstick.measure('article.rb') # => [ Measurement ]
|
12
|
+
#
|
13
|
+
# @param [Array<#to_s>, #to_s] path
|
14
|
+
# optional list of paths to measure
|
15
|
+
# @param [Hash] options
|
16
|
+
# optional configuration
|
17
|
+
#
|
18
|
+
# @return [MeasurementSet]
|
19
|
+
# the measurements for each file
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def self.measure(path = 'lib/**/*.rb', options = {})
|
23
|
+
Yardstick::Processor.process_path(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Measure a string of code and YARD documentation
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# string = "def my_method; end"
|
30
|
+
#
|
31
|
+
# Yardstick.measure_string(string) # => [ Measurement ]
|
32
|
+
#
|
33
|
+
# @param [#to_str] string
|
34
|
+
# the string to measure
|
35
|
+
# @param [Hash] options
|
36
|
+
# optional configuration
|
37
|
+
#
|
38
|
+
# @return [MeasurementSet]
|
39
|
+
# the measurements for the string
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def self.measure_string(string, options = {})
|
43
|
+
Yardstick::Processor.process_string(string)
|
44
|
+
end
|
45
|
+
|
46
|
+
end # module Yardstick
|
47
|
+
|
48
|
+
$LOAD_PATH.unshift(Yardstick::ROOT + 'lib')
|
49
|
+
|
50
|
+
require 'yardstick/core_ext/object'
|
51
|
+
require 'yardstick/yard_ext'
|
52
|
+
require 'yardstick/autoload'
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname.expand_path.join('..', '..', 'spec_helper')
|
3
|
+
|
4
|
+
shared_examples_for 'displays help' do
|
5
|
+
it 'should display the help message' do
|
6
|
+
@output.should == <<-OUTPUT.gsub(/^\s{6}/, '')
|
7
|
+
Usage: #{OptionParser.new.program_name} [options]
|
8
|
+
-v, --version print version information and exit
|
9
|
+
-h, --help display this help and exit
|
10
|
+
OUTPUT
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
shared_examples_for 'displays version' do
|
15
|
+
it 'should display the program and version' do
|
16
|
+
@output.should == "#{OptionParser.new.program_name} #{Yardstick::VERSION}\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples_for 'displays coverage summary' do
|
21
|
+
it 'should output the coverage summary' do
|
22
|
+
@output.should == "\nCoverage: 100.0% Success: 20 Failed: 0 Total: 20\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Yardstick::CLI do
|
27
|
+
def capture_display(&block)
|
28
|
+
capture_stdout do
|
29
|
+
block.should raise_error(SystemExit)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.run' do
|
34
|
+
describe 'with no arguments' do
|
35
|
+
before do
|
36
|
+
capture_display { Yardstick::CLI.run }
|
37
|
+
end
|
38
|
+
|
39
|
+
it_should_behave_like 'displays help'
|
40
|
+
end
|
41
|
+
|
42
|
+
%w[ -h --help ].each do |help_option|
|
43
|
+
describe "with #{help_option} option" do
|
44
|
+
before do
|
45
|
+
capture_display { Yardstick::CLI.run(help_option) }
|
46
|
+
end
|
47
|
+
|
48
|
+
it_should_behave_like 'displays help'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
%w[ -v --version ].each do |version_option|
|
53
|
+
describe "with #{version_option} option" do
|
54
|
+
before do
|
55
|
+
capture_display { Yardstick::CLI.run(version_option) }
|
56
|
+
end
|
57
|
+
|
58
|
+
it_should_behave_like 'displays version'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'with a String path' do
|
63
|
+
before :all do
|
64
|
+
@measurements = capture_stdout { Yardstick::CLI.run(Yardstick::ROOT.join('lib', 'yardstick.rb').to_s) }
|
65
|
+
end
|
66
|
+
|
67
|
+
it_should_behave_like 'measured itself'
|
68
|
+
it_should_behave_like 'displays coverage summary'
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'with a Pathname' do
|
72
|
+
before :all do
|
73
|
+
@measurements = capture_stdout { Yardstick::CLI.run(Yardstick::ROOT.join('lib', 'yardstick.rb')) }
|
74
|
+
end
|
75
|
+
|
76
|
+
it_should_behave_like 'measured itself'
|
77
|
+
it_should_behave_like 'displays coverage summary'
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'with an Array of String objects' do
|
81
|
+
before :all do
|
82
|
+
@measurements = capture_stdout { Yardstick::CLI.run(*[ Yardstick::ROOT.join('lib', 'yardstick.rb').to_s ]) }
|
83
|
+
end
|
84
|
+
|
85
|
+
it_should_behave_like 'measured itself'
|
86
|
+
it_should_behave_like 'displays coverage summary'
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'with an Array of Pathname objects' do
|
90
|
+
before :all do
|
91
|
+
@measurements = capture_stdout { Yardstick::CLI.run(*[ Yardstick::ROOT.join('lib', 'yardstick.rb') ]) }
|
92
|
+
end
|
93
|
+
|
94
|
+
it_should_behave_like 'measured itself'
|
95
|
+
it_should_behave_like 'displays coverage summary'
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'with invalid option' do
|
99
|
+
before do
|
100
|
+
capture_display { Yardstick::CLI.run('--invalid') }
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should display the invalid option message' do
|
104
|
+
@output.should == "invalid option: --invalid\n"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname.expand_path.join('..', '..', 'spec_helper')
|
3
|
+
|
4
|
+
describe Yardstick::MeasurementSet do
|
5
|
+
before do
|
6
|
+
YARD.parse_string('def test; end')
|
7
|
+
|
8
|
+
@description = 'test measurement'
|
9
|
+
@docstring = YARD::Registry.all(:method).first.docstring
|
10
|
+
|
11
|
+
@measurement = Yardstick::Measurement.new(@description, @docstring) { true }
|
12
|
+
@measurements = Yardstick::MeasurementSet.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should be Enumerable' do
|
16
|
+
Yardstick::MeasurementSet.new.should be_kind_of(Enumerable)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.new' do
|
20
|
+
describe 'with no arguments' do
|
21
|
+
before do
|
22
|
+
@measurements = Yardstick::MeasurementSet.new
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return a MeasurementSet' do
|
26
|
+
@measurements.should be_kind_of(Yardstick::MeasurementSet)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should be empty' do
|
30
|
+
@measurements.should be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'with Measurements' do
|
35
|
+
before do
|
36
|
+
@measurements = Yardstick::MeasurementSet.new([ @measurement ])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should return a MeasurementSet' do
|
40
|
+
@measurements.should be_kind_of(Yardstick::MeasurementSet)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should include the Measurements' do
|
44
|
+
@measurements.should include(@measurement)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#<<' do
|
50
|
+
describe 'with a new Measurement' do
|
51
|
+
before do
|
52
|
+
@response = @measurements << @measurement
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return self' do
|
56
|
+
@response.should be_equal(@measurements)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should append the Measurement' do
|
60
|
+
@measurements.to_a.last.should equal(@measurement)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'with an equivalent Measurement' do
|
65
|
+
before do
|
66
|
+
@measurements << @measurement
|
67
|
+
@measurements.to_a.should == [ @measurement ]
|
68
|
+
|
69
|
+
@response = @measurements << Yardstick::Measurement.new(@description, @docstring) { true }
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should return self' do
|
73
|
+
@response.should be_equal(@measurements)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should not append the Measurement again' do
|
77
|
+
@measurements.to_a.should == [ @measurement ]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#merge' do
|
83
|
+
before do
|
84
|
+
@other = Yardstick::MeasurementSet.new
|
85
|
+
@other << @measurement
|
86
|
+
|
87
|
+
@response = @measurements.merge(@other)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should return self' do
|
91
|
+
@response.should be_equal(@measurements)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should merge the other Measurements' do
|
95
|
+
@measurements.should include(*@other)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#each' do
|
100
|
+
before do
|
101
|
+
@measurements << @measurement
|
102
|
+
|
103
|
+
@yield = []
|
104
|
+
|
105
|
+
@response = @measurements.each { |*args| @yield << args }
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should return self' do
|
109
|
+
@response.should be_equal(@measurements)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should yield measurements' do
|
113
|
+
@yield.should eql([ [ @measurement ] ])
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#empty?' do
|
118
|
+
describe 'when there are no measurements' do
|
119
|
+
it 'should return true' do
|
120
|
+
@measurements.empty?.should be_true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'when there are measurements' do
|
125
|
+
before do
|
126
|
+
@measurements << @measurement
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return false' do
|
130
|
+
@measurements.empty?.should be_false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#include?' do
|
136
|
+
describe 'when provided an included measurement' do
|
137
|
+
before do
|
138
|
+
@measurements << @measurement
|
139
|
+
|
140
|
+
@response = @measurements.include?(@measurement)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should return true' do
|
144
|
+
@response.should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'when provided an excluded measurement' do
|
149
|
+
before do
|
150
|
+
@response = @measurements.include?(@measurement)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should return false' do
|
154
|
+
@response.should be_false
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#index' do
|
160
|
+
describe 'when provided an included measurement' do
|
161
|
+
before do
|
162
|
+
@measurements << @measurement
|
163
|
+
|
164
|
+
@response = @measurements.index(@measurement)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should return the index' do
|
168
|
+
@response.should eql(0)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'when provided an excluded measurement' do
|
173
|
+
before do
|
174
|
+
@response = @measurements.index(@measurement)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should return nil' do
|
178
|
+
@response.should == nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '#total' do
|
184
|
+
before do
|
185
|
+
@measurements << @measurement
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should return the number of total measurements' do
|
189
|
+
@measurements.total.should eql(1)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe '#successful' do
|
194
|
+
before do
|
195
|
+
@measurements << @measurement
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should return the number of successful measurements' do
|
199
|
+
@measurements.successful.should eql(1)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#failed' do
|
204
|
+
before do
|
205
|
+
@measurements << @measurement
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should return the number of failed measurements' do
|
209
|
+
@measurements.failed.should eql(0)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#coverage' do
|
214
|
+
describe 'when there are no measurements' do
|
215
|
+
it 'should return 0' do
|
216
|
+
@measurements.coverage.should eql(0)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe 'when there are measurements' do
|
221
|
+
before do
|
222
|
+
@response = @measurements << @measurement
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should return a Rational' do
|
226
|
+
@measurements.coverage.should be_kind_of(Rational)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should return the expected value' do
|
230
|
+
@measurements.coverage.should == 1
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '#puts' do
|
236
|
+
before do
|
237
|
+
@measurements << Yardstick::Measurement.new(@description, @docstring) { false }
|
238
|
+
end
|
239
|
+
|
240
|
+
describe 'with no arguments' do
|
241
|
+
before do
|
242
|
+
capture_stdout { @measurements.puts }
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should output the summary' do
|
246
|
+
@output.should == "(stdin):1: #test: test measurement\n" \
|
247
|
+
"\nCoverage: 0.0% Success: 0 Failed: 1 Total: 1\n"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe 'with an object implementing #puts' do
|
252
|
+
before do
|
253
|
+
io = StringIO.new
|
254
|
+
@measurements.puts(io)
|
255
|
+
io.rewind
|
256
|
+
@output = io.read
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should output the summary' do
|
260
|
+
@output.should == "(stdin):1: #test: test measurement\n" \
|
261
|
+
"\nCoverage: 0.0% Success: 0 Failed: 1 Total: 1\n"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|