dkubb-yardstick 0.0.1 → 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.
@@ -2,57 +2,62 @@ module Yardstick
2
2
  module Method
3
3
  include Measurable
4
4
 
5
- measurement 'The method summary should be specified' do
5
+ rule 'The method summary should be specified' do
6
6
  skip if has_tag?('see')
7
- summary != ''
7
+ summary_text != ''
8
8
  end
9
9
 
10
- measurement 'The method summary should be less than 80 characters in length' do
11
- summary.length <= 78
10
+ rule 'The method summary should be less than 80 characters in length' do
11
+ summary_text.split(//).length <= 80
12
12
  end
13
13
 
14
- measurement 'The method summary should be a single line' do
15
- !summary.include?("\n")
14
+ rule 'The method summary should not end in a period' do
15
+ summary_text[-1, 1] != '.'
16
16
  end
17
17
 
18
- measurement 'The method summary should not end in a period' do
19
- summary[0, -1] != '.'
18
+ rule 'The method summary should be a single line' do
19
+ !summary_text.include?("\n")
20
20
  end
21
21
 
22
- measurement 'The public/semipublic method should have an example specified' do
23
- skip unless api?(%w[ public semipublic ]) && tag_types('return') != %w[ undefined ]
22
+ rule 'The public/semipublic method should have an example specified' do
23
+ skip if api?(%w[ private ]) || tag_types('return') == %w[ undefined ]
24
24
  has_tag?('example')
25
25
  end
26
26
 
27
- measurement 'The @api tag should be specified' do
27
+ rule 'The @api tag should be specified' do
28
28
  has_tag?('api')
29
29
  end
30
30
 
31
- measurement 'The @api tag must be either public, semipublic or private' do
31
+ rule 'The @api tag must be either public, semipublic or private' do
32
32
  %w[ public semipublic private ].include?(tag_text('api'))
33
33
  end
34
34
 
35
- measurement 'A method with public visibility must have an @api tag of public, semipublic or private' do
36
- skip unless visibility == :public
37
- api?(%w[ public semipublic private ])
38
- end
39
-
40
- measurement 'A method with protected visibility must have an @api tag of semipublic or private' do
35
+ rule 'A method with protected visibility must have an @api tag of semipublic or private' do
41
36
  skip unless visibility == :protected
42
37
  api?(%w[ semipublic private ])
43
38
  end
44
39
 
45
- measurement 'A method with private visibility must have an @api tag of private' do
40
+ rule 'A method with private visibility must have an @api tag of private' do
46
41
  skip unless visibility == :private
47
42
  api?(%w[ private ])
48
43
  end
49
44
 
50
- measurement 'The @return tag should be specified' do
45
+ rule 'The @return tag should be specified' do
51
46
  has_tag?('return')
52
47
  end
53
48
 
54
49
  private
55
50
 
51
+ # The raw text for the summary
52
+ #
53
+ # @return [String]
54
+ # the summary text
55
+ #
56
+ # @api private
57
+ def summary_text
58
+ split(/\r?\n\r?\n/).first || ''
59
+ end
60
+
56
61
  # The text for a specified tag
57
62
  #
58
63
  # @param [String] tag_name
@@ -0,0 +1,112 @@
1
+ module Yardstick
2
+ class OrderedSet
3
+ include Enumerable
4
+
5
+ # Returns the OrderedSet instance
6
+ #
7
+ # @param [Array] entries
8
+ # optional entries
9
+ #
10
+ # @return [OrderedSet]
11
+ # the ordered set instance
12
+ #
13
+ # @api private
14
+ def initialize(entries = nil)
15
+ @entries = []
16
+ @index = {}
17
+ merge(entries) if entries
18
+ end
19
+
20
+ # Append to the OrderedSet
21
+ #
22
+ # @param [Object] entry
23
+ # the object to append
24
+ #
25
+ # @return [OrderedSet]
26
+ # returns self
27
+ #
28
+ # @api private
29
+ def <<(entry)
30
+ unless include?(entry)
31
+ @index[entry] = @entries.length
32
+ @entries << entry
33
+ end
34
+ self
35
+ end
36
+
37
+ # Merge in another OrderedSet
38
+ #
39
+ # @param [#each] other
40
+ # the other ordered set
41
+ #
42
+ # @return [OrderedSet]
43
+ # returns self
44
+ #
45
+ # @api private
46
+ def merge(other)
47
+ other.each { |entry| self << entry }
48
+ self
49
+ end
50
+
51
+ # Iterate over each entry
52
+ #
53
+ # @yield [entry]
54
+ # yield to the entry
55
+ #
56
+ # @yieldparam [Object] entry
57
+ # an entry in the ordered set
58
+ #
59
+ # @return [OrderedSet]
60
+ # returns self
61
+ #
62
+ # @api private
63
+ def each(&block)
64
+ @entries.each(&block)
65
+ self
66
+ end
67
+
68
+ # Check if there are any entries
69
+ #
70
+ # @return [Boolean]
71
+ # true if there are no entries, false if there are
72
+ #
73
+ # @api private
74
+ def empty?
75
+ @entries.empty?
76
+ end
77
+
78
+ # The number of entries
79
+ #
80
+ # @return [Integer]
81
+ # number of entries
82
+ #
83
+ # @api private
84
+ def length
85
+ @entries.length
86
+ end
87
+
88
+ # Check if the entry exists in the set
89
+ #
90
+ # @return [Boolean]
91
+ # true if the entry exists in the set, false if not
92
+ #
93
+ # @api private
94
+ def include?(entry)
95
+ @index.key?(entry)
96
+ end
97
+
98
+ # Return the index for the entry in the set
99
+ #
100
+ # @param [Object] entry
101
+ # the entry to check the set for
102
+ #
103
+ # @return [Integer, nil]
104
+ # the index for the entry, or nil if it does not exist
105
+ #
106
+ # @api private
107
+ def index(entry)
108
+ @index[entry]
109
+ end
110
+
111
+ end # class OrderedSet
112
+ end # module Yardstick
@@ -3,16 +3,16 @@ module Yardstick
3
3
 
4
4
  # Measure files provided
5
5
  #
6
- # @param [Array<#to_str>] files
6
+ # @param [Array<#to_s>, #to_s] path
7
7
  # the files to measure
8
8
  #
9
- # @return [Array<Measurement>]
9
+ # @return [MeasurementSet]
10
10
  # a collection of measurements
11
11
  #
12
12
  # @api private
13
- def self.process_files(files)
14
- YARD.parse(Pathname.glob(files).map { |file| file.to_str })
15
- measure_method_objects(method_objects)
13
+ def self.process_path(path)
14
+ YARD.parse(Array(path).map { |file| file.to_s })
15
+ measurements
16
16
  end
17
17
 
18
18
  # Measure string provided
@@ -20,13 +20,27 @@ module Yardstick
20
20
  # @param [#to_str] string
21
21
  # the string to measure
22
22
  #
23
- # @return [Array<Measurement>]
23
+ # @return [MeasurementSet]
24
24
  # a collection of measurements
25
25
  #
26
26
  # @api private
27
27
  def self.process_string(string)
28
28
  YARD.parse_string(string.to_str)
29
- measure_method_objects(method_objects)
29
+ measurements
30
+ end
31
+
32
+ # Measure method objects in YARD registry
33
+ #
34
+ # @return [MeasurementSet]
35
+ # a collection of measurements
36
+ #
37
+ # @api private
38
+ def self.measurements
39
+ measurements = MeasurementSet.new
40
+ method_objects.each do |method_object|
41
+ measurements.merge(method_object.docstring.measure)
42
+ end
43
+ measurements
30
44
  end
31
45
 
32
46
  # Return method objects in YARD registry
@@ -43,24 +57,8 @@ module Yardstick
43
57
  YARD::Registry.clear
44
58
  end
45
59
 
46
- # Measure the method objects provided
47
- #
48
- # @param [Array<YARD::CodeObjects::MethodObject>] method_objects
49
- # a collection of method objects
50
- #
51
- # @return [Array<Measurement>]
52
- # a collection of measurements
53
- #
54
- # @api private
55
- def self.measure_method_objects(method_objects)
56
- method_objects.map do |method_object|
57
- method_object.docstring.measure
58
- end.flatten
59
- end
60
-
61
60
  class << self
62
- private :method_objects
63
- private :measure_method_objects
61
+ private :measurements, :method_objects
64
62
  end
65
63
 
66
64
  end # class Processor
@@ -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,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} 0.0.1\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_stderr { 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_stderr { 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_stderr { 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_stderr { 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