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.
Files changed (42) hide show
  1. data/.document +5 -0
  2. data/.gitignore +10 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +117 -0
  5. data/Rakefile +24 -0
  6. data/VERSION +1 -0
  7. data/bin/yardstick +7 -0
  8. data/deps.rip +1 -0
  9. data/lib/yardstick/autoload.rb +16 -0
  10. data/lib/yardstick/cli.rb +76 -0
  11. data/lib/yardstick/core_ext/object.rb +13 -0
  12. data/lib/yardstick/measurable.rb +78 -0
  13. data/lib/yardstick/measurement.rb +217 -0
  14. data/lib/yardstick/measurement_set.rb +130 -0
  15. data/lib/yardstick/method.rb +111 -0
  16. data/lib/yardstick/ordered_set.rb +115 -0
  17. data/lib/yardstick/processor.rb +65 -0
  18. data/lib/yardstick/rake/measurement.rb +101 -0
  19. data/lib/yardstick/rake/verify.rb +179 -0
  20. data/lib/yardstick/rule.rb +61 -0
  21. data/lib/yardstick/rule_set.rb +18 -0
  22. data/lib/yardstick/yard_ext.rb +20 -0
  23. data/lib/yardstick.rb +52 -0
  24. data/spec/public/yardstick/cli_spec.rb +108 -0
  25. data/spec/public/yardstick/measurement_set_spec.rb +265 -0
  26. data/spec/public/yardstick/measurement_spec.rb +256 -0
  27. data/spec/public/yardstick/method_spec.rb +356 -0
  28. data/spec/public/yardstick/rake/measurement_spec.rb +173 -0
  29. data/spec/public/yardstick/rake/verify_spec.rb +229 -0
  30. data/spec/public/yardstick_spec.rb +70 -0
  31. data/spec/rcov.opts +6 -0
  32. data/spec/semipublic/yardstick/rule_spec.rb +28 -0
  33. data/spec/spec.opts +4 -0
  34. data/spec/spec_helper.rb +45 -0
  35. data/tasks/ci.rake +1 -0
  36. data/tasks/heckle.rake +52 -0
  37. data/tasks/metrics.rake +5 -0
  38. data/tasks/rdoc.rake +15 -0
  39. data/tasks/spec.rake +22 -0
  40. data/tasks/yardstick.rake +9 -0
  41. data/yardstick.gemspec +90 -0
  42. 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