inch 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
- data/README.md +170 -56
- data/TODOS.md +0 -6
- data/config/defaults.rb +82 -0
- data/lib/inch/cli/command/base.rb +9 -0
- data/lib/inch/cli/command/base_list.rb +8 -8
- data/lib/inch/cli/command/base_object.rb +1 -1
- data/lib/inch/cli/command/list.rb +6 -1
- data/lib/inch/cli/command/options/base.rb +1 -1
- data/lib/inch/cli/command/options/suggest.rb +3 -1
- data/lib/inch/cli/command/output/list.rb +6 -6
- data/lib/inch/cli/command/output/show.rb +3 -3
- data/lib/inch/cli/command/output/stats.rb +52 -33
- data/lib/inch/cli/command/output/suggest.rb +7 -7
- data/lib/inch/cli/command/show.rb +5 -0
- data/lib/inch/cli/command/stats.rb +6 -1
- data/lib/inch/cli/command/suggest.rb +31 -12
- data/lib/inch/cli/command.rb +7 -14
- data/lib/inch/cli/command_parser.rb +2 -9
- data/lib/inch/cli/sparkline_helper.rb +13 -13
- data/lib/inch/cli/weighted_list.rb +85 -0
- data/lib/inch/cli.rb +2 -1
- data/lib/inch/code_object/nodoc_helper.rb +2 -0
- data/lib/inch/code_object/proxy/base.rb +36 -13
- data/lib/inch/code_object/proxy/method_object.rb +29 -0
- data/lib/inch/code_object/proxy/namespace_object.rb +6 -0
- data/lib/inch/config.rb +30 -37
- data/lib/inch/evaluation/base.rb +53 -1
- data/lib/inch/evaluation/constant_object.rb +8 -11
- data/lib/inch/evaluation/file.rb +1 -1
- data/lib/inch/evaluation/grade.rb +41 -0
- data/lib/inch/evaluation/grade_list.rb +32 -0
- data/lib/inch/evaluation/method_object.rb +10 -51
- data/lib/inch/evaluation/namespace_object.rb +8 -49
- data/lib/inch/evaluation/{criteria.rb → object_schema.rb} +12 -22
- data/lib/inch/evaluation/read_write_methods.rb +21 -0
- data/lib/inch/evaluation/role/method.rb +8 -0
- data/lib/inch/evaluation.rb +5 -2
- data/lib/inch/version.rb +1 -1
- data/lib/inch.rb +3 -1
- data/test/fixtures/simple/lib/broken.rb +15 -0
- data/test/fixtures/simple/lib/role_methods.rb +15 -0
- data/test/inch/cli/weighted_list_test.rb +55 -0
- data/test/inch/code_object/proxy/method_object_test.rb +42 -0
- data/test/integration/stats_options_test.rb +1 -1
- metadata +11 -5
- data/lib/inch/evaluation/score_range.rb +0 -38
@@ -16,10 +16,10 @@ module Inch
|
|
16
16
|
[203, 203, 204, 204, 205, 206, 207]
|
17
17
|
].flatten.map { |s| :"color#{s}" }
|
18
18
|
|
19
|
-
def initialize(options, objects,
|
19
|
+
def initialize(options, objects, grade_lists)
|
20
20
|
@options = options
|
21
21
|
@objects = objects
|
22
|
-
@
|
22
|
+
@grade_lists = grade_lists
|
23
23
|
|
24
24
|
method("display_#{@options.format}").call
|
25
25
|
end
|
@@ -27,19 +27,23 @@ module Inch
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def display_text
|
30
|
-
|
31
|
-
|
30
|
+
print_grades
|
31
|
+
print_grades_by_priority
|
32
|
+
print_priorities
|
32
33
|
puts
|
33
34
|
puts 'Try `--format json|yaml` for raw numbers.'.dark
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
-
sparkline =
|
37
|
+
def print_grades
|
38
|
+
sparkline = grade_lists_sparkline(@grade_lists).to_s(' ')
|
38
39
|
puts
|
39
40
|
puts 'Grade distribution: (undocumented, C, B, A)'
|
40
41
|
puts
|
41
42
|
puts " Overall: #{sparkline} #{objects.size.to_s.rjust(5)} objects"
|
42
43
|
puts
|
44
|
+
end
|
45
|
+
|
46
|
+
def print_grades_by_priority
|
43
47
|
puts 'Grade distribution by priority:'
|
44
48
|
puts
|
45
49
|
PRIORITY_MAP.each do |priority_range, arrow|
|
@@ -51,25 +55,29 @@ module Inch
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
def
|
58
|
+
def print_grade_list(grade_list)
|
59
|
+
list = grade_list.objects.map(&:priority)
|
60
|
+
|
61
|
+
priorities = {}
|
62
|
+
(-7..7).each do |key|
|
63
|
+
priorities[key.to_s] = list.select { |p| p == key }.size
|
64
|
+
end
|
65
|
+
|
66
|
+
sparkline = Sparkr::Sparkline.new(priorities.values)
|
67
|
+
sparkline.format do |tick, count, index|
|
68
|
+
tick.color( PRIORITY_COLORS[index] )
|
69
|
+
end
|
70
|
+
puts " #{grade_list.grade}: " + sparkline.to_s(' ') +
|
71
|
+
" #{grade_list.objects.size.to_s.rjust(5)} objects"
|
72
|
+
puts
|
73
|
+
end
|
74
|
+
|
75
|
+
def print_priorities
|
55
76
|
puts "Priority distribution in grades: (low to high)"
|
56
77
|
puts
|
57
78
|
puts " #{PRIORITY_MAP.values.reverse.join(' ')}"
|
58
|
-
@
|
59
|
-
|
60
|
-
|
61
|
-
priorities = {}
|
62
|
-
(-7..7).each do |key|
|
63
|
-
priorities[key.to_s] = list.select { |p| p == key }.size
|
64
|
-
end
|
65
|
-
|
66
|
-
sparkline = Sparkr::Sparkline.new(priorities.values)
|
67
|
-
sparkline.format do |tick, count, index|
|
68
|
-
tick.color( PRIORITY_COLORS[index] )
|
69
|
-
end
|
70
|
-
puts " #{range.grade}: " + sparkline.to_s(' ') +
|
71
|
-
" #{range.objects.size.to_s.rjust(5)} objects"
|
72
|
-
puts
|
79
|
+
@grade_lists.reverse.each do |grade_list|
|
80
|
+
print_grade_list(grade_list)
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|
@@ -82,25 +90,36 @@ module Inch
|
|
82
90
|
end
|
83
91
|
|
84
92
|
def stats_hash
|
85
|
-
|
93
|
+
{
|
94
|
+
'grade_lists' => __grade_lists,
|
95
|
+
'scores' => __scores,
|
96
|
+
'priorities' => __priorities
|
97
|
+
}
|
98
|
+
end
|
86
99
|
|
87
|
-
|
88
|
-
|
89
|
-
|
100
|
+
def __grade_lists
|
101
|
+
hash = {}
|
102
|
+
@grade_lists.each do |r|
|
103
|
+
hash[r.grade.to_s] = r.objects.size
|
90
104
|
end
|
105
|
+
hash
|
106
|
+
end
|
91
107
|
|
92
|
-
|
108
|
+
def __scores
|
109
|
+
hash = {}
|
93
110
|
@objects.sort_by(&:score).each do |o|
|
94
|
-
hash[
|
95
|
-
hash[
|
111
|
+
hash[o.score.to_i] ||= 0
|
112
|
+
hash[o.score.to_i] += 1
|
96
113
|
end
|
114
|
+
hash
|
115
|
+
end
|
97
116
|
|
98
|
-
|
117
|
+
def __priorities
|
118
|
+
hash = {}
|
99
119
|
@objects.sort_by(&:priority).each do |o|
|
100
|
-
hash[
|
101
|
-
hash[
|
120
|
+
hash[o.priority.to_i] ||= 0
|
121
|
+
hash[o.priority.to_i] += 1
|
102
122
|
end
|
103
|
-
|
104
123
|
hash
|
105
124
|
end
|
106
125
|
|
@@ -20,13 +20,13 @@ module Inch
|
|
20
20
|
# @param options [Command::Options::Suggest]
|
21
21
|
# @param objects_to_display [Array<CodeObject::Proxy::Base>]
|
22
22
|
# @param relevant_objects [Array<CodeObject::Proxy::Base>] the objects meeting the criteria defined in +options+
|
23
|
-
# @param
|
23
|
+
# @param grade_lists [Array<Evaluation::GradeList>]
|
24
24
|
# @param files [Array<Evaluation::File>]
|
25
|
-
def initialize(options, objects_to_display, relevant_objects,
|
25
|
+
def initialize(options, objects_to_display, relevant_objects, grade_lists, files)
|
26
26
|
@options = options
|
27
27
|
@objects = objects_to_display
|
28
28
|
@relevant_objects = relevant_objects
|
29
|
-
@
|
29
|
+
@grade_lists = grade_lists
|
30
30
|
@files = files
|
31
31
|
|
32
32
|
if objects.empty?
|
@@ -70,11 +70,11 @@ module Inch
|
|
70
70
|
|
71
71
|
def display_list
|
72
72
|
@options.grades_to_display.map do |grade|
|
73
|
-
r =
|
73
|
+
r = grade_list(grade)
|
74
74
|
grade_objects = objects.select { |o| o.grade == r.grade }
|
75
75
|
unless grade_objects.empty?
|
76
76
|
trace
|
77
|
-
trace_header(RANGE_LABELS[r.grade], r.color, r.bg_color)
|
77
|
+
trace_header(RANGE_LABELS[r.grade.to_sym], r.color, r.bg_color)
|
78
78
|
grade_objects.each do |o|
|
79
79
|
grade = o.grade.to_s.ljust(2).color(r.color)
|
80
80
|
priority = o.priority
|
@@ -94,8 +94,8 @@ module Inch
|
|
94
94
|
end.compact
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
98
|
-
@
|
97
|
+
def grade_list(grade_symbol)
|
98
|
+
@grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
require_relative 'options/stats'
|
2
|
+
require_relative 'output/stats'
|
3
|
+
|
1
4
|
module Inch
|
2
5
|
module CLI
|
3
6
|
module Command
|
4
7
|
class Stats < List
|
8
|
+
register_command_as :stats
|
9
|
+
|
5
10
|
def description
|
6
11
|
'Lists all objects with their results'
|
7
12
|
end
|
@@ -12,7 +17,7 @@ module Inch
|
|
12
17
|
|
13
18
|
def run(*args)
|
14
19
|
prepare_list(*args)
|
15
|
-
Output::Stats.new(@options, objects, @
|
20
|
+
Output::Stats.new(@options, objects, @grade_lists)
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
require_relative 'options/suggest'
|
2
|
+
require_relative 'output/suggest'
|
3
|
+
|
1
4
|
module Inch
|
2
5
|
module CLI
|
3
6
|
module Command
|
4
7
|
class Suggest < List
|
8
|
+
register_command_as :suggest, true
|
9
|
+
|
5
10
|
def description
|
6
11
|
'Suggests some objects to be doucmented (better)'
|
7
12
|
end
|
@@ -17,29 +22,43 @@ module Inch
|
|
17
22
|
# @return [void]
|
18
23
|
def run(*args)
|
19
24
|
prepare_list(*args)
|
20
|
-
Output::Suggest.new(@options, objects_to_display, relevant_objects, @
|
25
|
+
Output::Suggest.new(@options, objects_to_display, relevant_objects, @grade_lists, files)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# @return [Fixnum] how many objects should be displayed in the output
|
31
|
+
def object_count
|
32
|
+
@options.object_count
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Array<Fixnum>]
|
36
|
+
# how many objects of each grade should be displayed in the output
|
37
|
+
def object_list_counts
|
38
|
+
@options.grade_weights.map { |w| w * object_count }
|
21
39
|
end
|
22
40
|
|
41
|
+
# @return [Array] the objects that should be displayed in the output
|
23
42
|
def objects_to_display
|
24
43
|
@objects_to_display ||= filter_objects_to_display
|
25
44
|
end
|
26
45
|
|
46
|
+
# @return [Array] the objects that should be displayed in the output
|
27
47
|
def filter_objects_to_display
|
28
|
-
|
48
|
+
grade_list = []
|
29
49
|
@options.grades_to_display.map do |grade|
|
30
|
-
r =
|
50
|
+
r = grade_list(grade)
|
31
51
|
arr = select_by_priority(r.objects, @options.object_min_priority)
|
32
52
|
arr = arr.select { |o| o.score <= @options.object_max_score }
|
33
|
-
|
53
|
+
grade_list << arr
|
34
54
|
end
|
35
55
|
|
36
|
-
|
56
|
+
weighted_list = WeightedList.new(grade_list, object_list_counts)
|
57
|
+
|
58
|
+
list = sort_by_priority(weighted_list.to_a.flatten)
|
37
59
|
|
38
|
-
if list.size >
|
39
|
-
list = list[0
|
40
|
-
elsif list.size < @options.object_count
|
41
|
-
# should we add objects with lower priority to fill out the
|
42
|
-
# requested count?
|
60
|
+
if list.size > object_count
|
61
|
+
list = list[0...object_count]
|
43
62
|
end
|
44
63
|
list
|
45
64
|
end
|
@@ -78,8 +97,8 @@ module Inch
|
|
78
97
|
objects.map(&:grade).uniq
|
79
98
|
end
|
80
99
|
|
81
|
-
def
|
82
|
-
@
|
100
|
+
def grade_list(grade_symbol)
|
101
|
+
@grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
|
83
102
|
end
|
84
103
|
|
85
104
|
def relevant_objects
|
data/lib/inch/cli/command.rb
CHANGED
@@ -2,22 +2,15 @@ require_relative 'command/base'
|
|
2
2
|
require_relative 'command/base_list'
|
3
3
|
require_relative 'command/base_object'
|
4
4
|
|
5
|
-
require_relative 'command/list'
|
6
|
-
require_relative 'command/show'
|
7
|
-
require_relative 'command/stats'
|
8
|
-
require_relative 'command/suggest'
|
9
|
-
|
10
5
|
require_relative 'command/options/base'
|
11
6
|
require_relative 'command/options/base_list'
|
12
7
|
require_relative 'command/options/base_object'
|
13
8
|
|
14
|
-
require_relative 'command/options/list'
|
15
|
-
require_relative 'command/options/show'
|
16
|
-
require_relative 'command/options/stats'
|
17
|
-
require_relative 'command/options/suggest'
|
18
|
-
|
19
9
|
require_relative 'command/output/base'
|
20
|
-
|
21
|
-
require_relative '
|
22
|
-
|
23
|
-
require_relative 'command/
|
10
|
+
|
11
|
+
require_relative 'command_parser'
|
12
|
+
|
13
|
+
require_relative 'command/list'
|
14
|
+
require_relative 'command/show'
|
15
|
+
require_relative 'command/stats'
|
16
|
+
require_relative 'command/suggest'
|
@@ -43,15 +43,8 @@ module Inch
|
|
43
43
|
attr_accessor :default_command
|
44
44
|
end
|
45
45
|
|
46
|
-
self.commands = {
|
47
|
-
|
48
|
-
:show => Command::Show,
|
49
|
-
:stats => Command::Stats,
|
50
|
-
:suggest => Command::Suggest,
|
51
|
-
}
|
52
|
-
|
53
|
-
self.default_command = :suggest
|
54
|
-
|
46
|
+
self.commands = {}
|
47
|
+
|
55
48
|
# Convenience method to create a new CommandParser and call {#run}
|
56
49
|
# @return (see #run)
|
57
50
|
def self.run(*args)
|
@@ -1,28 +1,28 @@
|
|
1
1
|
module Inch
|
2
2
|
module CLI
|
3
3
|
module SparklineHelper
|
4
|
-
def
|
5
|
-
|
6
|
-
list =
|
7
|
-
|
8
|
-
sparkline.format do |tick, count, index|
|
9
|
-
t = tick.color(ranges[index].color)
|
10
|
-
index == 0 ? t + ' ' : t
|
11
|
-
end
|
4
|
+
def grade_lists_sparkline(_grade_lists)
|
5
|
+
grade_lists = _grade_lists.reverse
|
6
|
+
list = grade_lists.map { |r| r.objects.size }
|
7
|
+
__sparkline(list, grade_lists)
|
12
8
|
end
|
13
9
|
|
14
10
|
def grades_sparkline(objects)
|
15
11
|
grades = {}
|
16
12
|
objects.each do |o|
|
17
|
-
grades[o.grade] ||= 0
|
18
|
-
grades[o.grade] += 1
|
13
|
+
grades[o.grade.to_sym] ||= 0
|
14
|
+
grades[o.grade.to_sym] += 1
|
19
15
|
end
|
20
|
-
|
21
|
-
order =
|
16
|
+
grade_lists = Evaluation.new_grade_lists.reverse
|
17
|
+
order = grade_lists.map(&:to_sym)
|
22
18
|
list = order.map { |g| grades[g] }
|
19
|
+
__sparkline(list, grade_lists)
|
20
|
+
end
|
21
|
+
|
22
|
+
def __sparkline(list, grade_lists)
|
23
23
|
sparkline = Sparkr::Sparkline.new(list)
|
24
24
|
sparkline.format do |tick, count, index|
|
25
|
-
t = tick.color(
|
25
|
+
t = tick.color(grade_lists[index].color)
|
26
26
|
index == 0 ? t + ' ' : t
|
27
27
|
end
|
28
28
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Inch
|
2
|
+
module CLI
|
3
|
+
class WeightedList
|
4
|
+
# Trims down a list of object lists to given sizes.
|
5
|
+
# If there are not enough objects in any particular tier,
|
6
|
+
# they are filled up from the tier below/above.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# list = [
|
11
|
+
# [:B1, :B2],
|
12
|
+
# [:C1, :C2, :C3, :C4, :C5, :C6, :C7, :C8, :C9, :C10],
|
13
|
+
# [:U1, :U2, :U3, :U4, :U5, :U6, :U7, :U8, :U9, :U10]
|
14
|
+
# ]
|
15
|
+
# counts = [4, 8, 8]
|
16
|
+
#
|
17
|
+
# This means there should be 4 +:B+s, 8 +:C+s, and 8 +:U+s in the
|
18
|
+
# resulting list. But we only have 2 +:B+s, so the result is filled up
|
19
|
+
# with +:U+s:
|
20
|
+
#
|
21
|
+
# WeightedList.new(list, counts).to_a
|
22
|
+
# # => [
|
23
|
+
# [:B1, :B2],
|
24
|
+
# [:C1, :C2, :C3, :C4, :C5, :C6, :C7, :C8],
|
25
|
+
# [:U1, :U2, :U3, :U4, :U5, :U6, :U7, :U8, :U9, :U10]
|
26
|
+
# ]
|
27
|
+
#
|
28
|
+
# @param list_of_lists [Array<Array>]
|
29
|
+
# @param counts [Array<Fixnum>]
|
30
|
+
def initialize(list_of_lists, counts)
|
31
|
+
@original = list_of_lists
|
32
|
+
@max_counts = counts
|
33
|
+
compute_list
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array]
|
37
|
+
def to_a
|
38
|
+
@list
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def compute_list
|
44
|
+
@list = init_empty_list(@original.size)
|
45
|
+
still_missing = fill_list_with_predefined_sizes
|
46
|
+
|
47
|
+
# all sublists are now filled up to their max capacity but we might
|
48
|
+
# have missed some objects (+still_missing+), because there weren't
|
49
|
+
# enough
|
50
|
+
|
51
|
+
@original.reverse_each.with_index do |sublist, rear_index|
|
52
|
+
if still_missing > 0
|
53
|
+
index = @original.size - rear_index - 1
|
54
|
+
present_count = @max_counts[index]
|
55
|
+
not_yet_in_list = sublist[present_count..-1]
|
56
|
+
if not_yet_in_list
|
57
|
+
put_in_list = not_yet_in_list[0...still_missing]
|
58
|
+
@list[index].concat put_in_list
|
59
|
+
still_missing -= put_in_list.size
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def init_empty_list(sublist_count)
|
66
|
+
list = []
|
67
|
+
sublist_count.times { list << [] }
|
68
|
+
list
|
69
|
+
end
|
70
|
+
|
71
|
+
def fill_list_with_predefined_sizes
|
72
|
+
missing = 0
|
73
|
+
@original.each_with_index do |sublist, index|
|
74
|
+
target_count = @max_counts[index]
|
75
|
+
@list[index].concat sublist[0...target_count]
|
76
|
+
|
77
|
+
if sublist.size < target_count
|
78
|
+
missing += target_count - sublist.size
|
79
|
+
end
|
80
|
+
end
|
81
|
+
missing
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/inch/cli.rb
CHANGED
@@ -17,11 +17,12 @@ module Inch
|
|
17
17
|
end
|
18
18
|
|
19
19
|
require_relative 'cli/arguments'
|
20
|
+
require_relative 'cli/weighted_list'
|
20
21
|
require_relative 'cli/sparkline_helper'
|
21
22
|
require_relative 'cli/trace_helper'
|
22
23
|
require_relative 'cli/yardopts_helper'
|
24
|
+
|
23
25
|
require_relative 'cli/command'
|
24
|
-
require_relative 'cli/command_parser'
|
25
26
|
|
26
27
|
console_rb = File.join(File.dirname(__FILE__), 'cli', 'command', 'console.rb')
|
27
28
|
if File.exists?(console_rb)
|
@@ -9,10 +9,10 @@ module Inch
|
|
9
9
|
include NodocHelper
|
10
10
|
|
11
11
|
# @return [YARD::CodeObjects::Base] the actual (YARD) code object
|
12
|
-
|
12
|
+
attr_reader :object
|
13
13
|
|
14
14
|
# @return [Symbol]
|
15
|
-
# when objects are assigned to
|
15
|
+
# when objects are assigned to GradeLists, this grade is set to
|
16
16
|
# enable easier querying for objects of a certain grade
|
17
17
|
attr_writer :grade
|
18
18
|
|
@@ -27,7 +27,7 @@ module Inch
|
|
27
27
|
|
28
28
|
# @param object [YARD::CodeObjects::Base] the actual (YARD) code object
|
29
29
|
def initialize(object)
|
30
|
-
|
30
|
+
@object = object
|
31
31
|
end
|
32
32
|
|
33
33
|
def api_tag?
|
@@ -35,7 +35,14 @@ module Inch
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def api_tag
|
38
|
-
|
38
|
+
tag(:api) || (parent && parent.api_tag)
|
39
|
+
end
|
40
|
+
|
41
|
+
# To be overridden
|
42
|
+
# @see Proxy::NamespaceObject
|
43
|
+
# @return [CodeObject::Proxy::Base,nil] the child inside the current object or +nil+
|
44
|
+
def child(name)
|
45
|
+
nil
|
39
46
|
end
|
40
47
|
|
41
48
|
# To be overridden
|
@@ -65,8 +72,8 @@ module Inch
|
|
65
72
|
|
66
73
|
# @return [Symbol]
|
67
74
|
def grade
|
68
|
-
@grade ||= Evaluation.
|
69
|
-
range.
|
75
|
+
@grade ||= Evaluation.new_grade_lists.detect { |range|
|
76
|
+
range.scores.include?(score)
|
70
77
|
}.grade
|
71
78
|
end
|
72
79
|
|
@@ -75,7 +82,7 @@ module Inch
|
|
75
82
|
end
|
76
83
|
|
77
84
|
def has_code_example?
|
78
|
-
!
|
85
|
+
!tags(:example).empty? ||
|
79
86
|
docstring.contains_code_example?
|
80
87
|
end
|
81
88
|
|
@@ -84,10 +91,10 @@ module Inch
|
|
84
91
|
end
|
85
92
|
|
86
93
|
def has_multiple_code_examples?
|
87
|
-
if
|
94
|
+
if tags(:example).size > 1 || docstring.code_examples.size > 1
|
88
95
|
true
|
89
96
|
else
|
90
|
-
if tag =
|
97
|
+
if tag = tag(:example)
|
91
98
|
multi_code_examples?(tag.text)
|
92
99
|
elsif text = docstring.code_examples.first
|
93
100
|
multi_code_examples?(text)
|
@@ -148,7 +155,11 @@ module Inch
|
|
148
155
|
# @return [Boolean]
|
149
156
|
# +true+ if the object or its parent is tagged as @private
|
150
157
|
def private_tag?
|
151
|
-
!
|
158
|
+
!private_tag.nil?
|
159
|
+
end
|
160
|
+
|
161
|
+
def private_tag
|
162
|
+
tag(:private) || (parent && parent.private_tag)
|
152
163
|
end
|
153
164
|
|
154
165
|
def private_api_tag?
|
@@ -165,13 +176,13 @@ module Inch
|
|
165
176
|
|
166
177
|
# @return [Boolean] +true+ if the object has no documentation at all
|
167
178
|
def undocumented?
|
168
|
-
docstring.empty? &&
|
179
|
+
docstring.empty? && tags.empty?
|
169
180
|
end
|
170
181
|
|
171
182
|
# @return [Array]
|
172
183
|
# YARD tags that are not already covered by other wrapper methods
|
173
184
|
def unconsidered_tags
|
174
|
-
@unconsidered_tags ||=
|
185
|
+
@unconsidered_tags ||= tags.reject do |tag|
|
175
186
|
CONSIDERED_YARD_TAGS.include?(tag.tag_name)
|
176
187
|
end
|
177
188
|
end
|
@@ -180,11 +191,23 @@ module Inch
|
|
180
191
|
"#<#{self.class.to_s}: #{path}>"
|
181
192
|
end
|
182
193
|
|
183
|
-
|
194
|
+
protected
|
184
195
|
|
185
196
|
def multi_code_examples?(text)
|
186
197
|
text.scan(/\b(#{Regexp.escape(name)})[^_0-9\!\?]/m).size > 1
|
187
198
|
end
|
199
|
+
|
200
|
+
def tag(name)
|
201
|
+
tags(name).first
|
202
|
+
end
|
203
|
+
|
204
|
+
def tags(name = nil)
|
205
|
+
object.tags(name)
|
206
|
+
rescue YARD::CodeObjects::ProxyMethodError
|
207
|
+
# this error is raised by YARD
|
208
|
+
# see broken.rb in test fixtures
|
209
|
+
[]
|
210
|
+
end
|
188
211
|
end
|
189
212
|
end
|
190
213
|
end
|
@@ -16,6 +16,20 @@ module Inch
|
|
16
16
|
name =~ /\!$/
|
17
17
|
end
|
18
18
|
|
19
|
+
def getter?
|
20
|
+
attr_info = object.attr_info || {}
|
21
|
+
read_info = attr_info[:read]
|
22
|
+
if read_info
|
23
|
+
read_info.path == path
|
24
|
+
else
|
25
|
+
parent.child(:"#{name}=")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_doc?
|
30
|
+
super && !implicit_docstring?
|
31
|
+
end
|
32
|
+
|
19
33
|
def has_parameters?
|
20
34
|
!parameters.empty?
|
21
35
|
end
|
@@ -68,6 +82,10 @@ module Inch
|
|
68
82
|
(return_tag && !return_tag.text.empty?) || docstring.describes_return?
|
69
83
|
end
|
70
84
|
|
85
|
+
def setter?
|
86
|
+
name =~ /\=$/ && parameters.size == 1
|
87
|
+
end
|
88
|
+
|
71
89
|
def questioning_name?
|
72
90
|
name =~ /\?$/
|
73
91
|
end
|
@@ -109,6 +127,17 @@ module Inch
|
|
109
127
|
lines.reverse
|
110
128
|
end
|
111
129
|
|
130
|
+
def implicit_docstring?
|
131
|
+
if getter?
|
132
|
+
docstring == "Returns the value of attribute #{name}"
|
133
|
+
elsif setter?
|
134
|
+
basename = name.to_s.gsub(/(\=)$/, '')
|
135
|
+
docstring == "Sets the attribute #{basename}"
|
136
|
+
else
|
137
|
+
false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
112
141
|
def signature_parameter_names
|
113
142
|
object.parameters.map(&:first)
|
114
143
|
end
|
@@ -4,6 +4,12 @@ module Inch
|
|
4
4
|
# a namespace object can have methods and other namespace objects
|
5
5
|
# inside itself (e.g. classes and modules)
|
6
6
|
class NamespaceObject < Base
|
7
|
+
def child(name)
|
8
|
+
if children
|
9
|
+
children.detect { |child| child.name == name }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
def children
|
8
14
|
object.children.map do |o|
|
9
15
|
Proxy.for(o)
|