inch 0.2.3 → 0.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +7 -0
  3. data/TODOS.md +0 -5
  4. data/config/defaults.rb +26 -1
  5. data/inch.gemspec +1 -0
  6. data/lib/inch.rb +2 -1
  7. data/lib/inch/api.rb +34 -0
  8. data/lib/inch/api/filter.rb +17 -0
  9. data/lib/inch/api/get.rb +30 -0
  10. data/lib/inch/api/list.rb +10 -0
  11. data/lib/inch/api/options/base.rb +45 -0
  12. data/lib/inch/api/options/filter.rb +25 -0
  13. data/lib/inch/api/options/suggest.rb +36 -0
  14. data/lib/inch/api/stats.rb +7 -0
  15. data/lib/inch/api/suggest.rb +110 -0
  16. data/lib/inch/cli.rb +4 -1
  17. data/lib/inch/cli/command/base.rb +1 -17
  18. data/lib/inch/cli/command/base_list.rb +3 -63
  19. data/lib/inch/cli/command/base_object.rb +6 -28
  20. data/lib/inch/cli/command/list.rb +3 -2
  21. data/lib/inch/cli/command/options/base.rb +1 -1
  22. data/lib/inch/cli/command/options/base_list.rb +4 -2
  23. data/lib/inch/cli/command/options/suggest.rb +9 -8
  24. data/lib/inch/cli/command/output/base.rb +9 -11
  25. data/lib/inch/cli/command/output/list.rb +2 -2
  26. data/lib/inch/cli/command/output/show.rb +2 -10
  27. data/lib/inch/cli/command/output/stats.rb +4 -3
  28. data/lib/inch/cli/command/output/suggest.rb +5 -5
  29. data/lib/inch/cli/command/stats.rb +4 -3
  30. data/lib/inch/cli/command/suggest.rb +4 -94
  31. data/lib/inch/code_object.rb +2 -2
  32. data/lib/inch/code_object/converter.rb +89 -0
  33. data/lib/inch/code_object/provider.rb +36 -0
  34. data/lib/inch/code_object/provider/yard.rb +19 -0
  35. data/lib/inch/code_object/provider/yard/docstring.rb +106 -0
  36. data/lib/inch/code_object/provider/yard/nodoc_helper.rb +93 -0
  37. data/lib/inch/code_object/provider/yard/object.rb +55 -0
  38. data/lib/inch/code_object/provider/yard/object/base.rb +262 -0
  39. data/lib/inch/code_object/provider/yard/object/class_object.rb +12 -0
  40. data/lib/inch/code_object/provider/yard/object/constant_object.rb +12 -0
  41. data/lib/inch/code_object/provider/yard/object/method_object.rb +126 -0
  42. data/lib/inch/code_object/provider/yard/object/method_parameter_object.rb +88 -0
  43. data/lib/inch/code_object/provider/yard/object/module_object.rb +12 -0
  44. data/lib/inch/code_object/provider/yard/object/namespace_object.rb +47 -0
  45. data/lib/inch/code_object/provider/yard/parser.rb +54 -0
  46. data/lib/inch/code_object/proxy.rb +5 -3
  47. data/lib/inch/code_object/proxy/base.rb +103 -110
  48. data/lib/inch/code_object/proxy/class_object.rb +0 -1
  49. data/lib/inch/code_object/proxy/method_object.rb +20 -99
  50. data/lib/inch/code_object/proxy/method_parameter_object.rb +15 -39
  51. data/lib/inch/code_object/proxy/namespace_object.rb +7 -18
  52. data/lib/inch/codebase.rb +19 -0
  53. data/lib/inch/codebase/objects.rb +73 -0
  54. data/lib/inch/codebase/objects_filter.rb +61 -0
  55. data/lib/inch/codebase/proxy.rb +22 -0
  56. data/lib/inch/config.rb +8 -1
  57. data/lib/inch/evaluation.rb +5 -7
  58. data/lib/inch/evaluation/file.rb +1 -1
  59. data/lib/inch/evaluation/grade.rb +1 -1
  60. data/lib/inch/evaluation/object_schema.rb +3 -1
  61. data/lib/inch/evaluation/priority_range.rb +44 -0
  62. data/lib/inch/evaluation/proxy.rb +25 -0
  63. data/lib/inch/evaluation/proxy/base.rb +146 -0
  64. data/lib/inch/evaluation/proxy/class_object.rb +8 -0
  65. data/lib/inch/evaluation/proxy/constant_object.rb +19 -0
  66. data/lib/inch/evaluation/proxy/method_object.rb +65 -0
  67. data/lib/inch/evaluation/proxy/module_object.rb +8 -0
  68. data/lib/inch/evaluation/proxy/namespace_object.rb +27 -0
  69. data/lib/inch/evaluation/role/base.rb +19 -0
  70. data/lib/inch/evaluation/role/constant.rb +16 -0
  71. data/lib/inch/evaluation/role/method.rb +22 -0
  72. data/lib/inch/evaluation/role/method_parameter.rb +31 -1
  73. data/lib/inch/evaluation/role/namespace.rb +15 -0
  74. data/lib/inch/evaluation/role/object.rb +24 -0
  75. data/lib/inch/rake/suggest.rb +1 -0
  76. data/lib/inch/utils/read_write_methods.rb +44 -0
  77. data/lib/inch/{cli → utils}/weighted_list.rb +1 -1
  78. data/lib/inch/version.rb +1 -1
  79. data/test/fixtures/simple/lib/broken.rb +8 -0
  80. data/test/inch/api/filter_test.rb +51 -0
  81. data/test/inch/api/get_test.rb +22 -0
  82. data/test/inch/api/list_test.rb +15 -0
  83. data/test/inch/api/options/base_test.rb +30 -0
  84. data/test/inch/api/stats_test.rb +15 -0
  85. data/test/inch/api/suggest_test.rb +26 -0
  86. data/test/inch/cli/command/list_test.rb +2 -1
  87. data/test/inch/code_object/converter_test.rb +29 -0
  88. data/test/inch/code_object/{docstring_test.rb → provider/yard/docstring_test.rb} +13 -13
  89. data/test/inch/code_object/{nodoc_helper_test.rb → provider/yard/nodoc_helper_test.rb} +6 -6
  90. data/test/inch/code_object/provider/yard_test.rb +11 -0
  91. data/test/inch/code_object/provider_test.rb +9 -0
  92. data/test/inch/code_object/proxy/method_object_test.rb +22 -22
  93. data/test/inch/code_object/proxy_test.rb +10 -10
  94. data/test/inch/codebase/objects_test.rb +28 -0
  95. data/test/inch/codebase/proxy_test.rb +17 -0
  96. data/test/inch/evaluation/role/base_test.rb +71 -0
  97. data/test/inch/{cli → utils}/weighted_list_test.rb +2 -2
  98. data/test/shared/base_list.rb +73 -0
  99. data/test/test_helper.rb +0 -95
  100. metadata +89 -24
  101. data/lib/inch/code_object/docstring.rb +0 -102
  102. data/lib/inch/code_object/nodoc_helper.rb +0 -107
  103. data/lib/inch/evaluation/base.rb +0 -157
  104. data/lib/inch/evaluation/class_object.rb +0 -6
  105. data/lib/inch/evaluation/constant_object.rb +0 -33
  106. data/lib/inch/evaluation/method_object.rb +0 -105
  107. data/lib/inch/evaluation/module_object.rb +0 -6
  108. data/lib/inch/evaluation/namespace_object.rb +0 -52
  109. data/lib/inch/evaluation/read_write_methods.rb +0 -21
  110. data/lib/inch/source_parser.rb +0 -62
  111. data/test/inch/source_parser_test.rb +0 -23
@@ -10,78 +10,18 @@ module Inch
10
10
  #
11
11
  # @abstract
12
12
  class BaseList < Base
13
- attr_writer :objects
14
-
15
- def initialize
16
- super
17
- @grade_lists = Evaluation.new_grade_lists
18
- end
13
+ attr_accessor :objects
19
14
 
20
15
  # Prepares the list of objects and grade_lists, parsing arguments and
21
16
  # running the source parser.
22
17
  #
23
18
  # @param *args [Array<String>] the list of arguments.
24
19
  # @return [void]
25
- def prepare_list(*args)
20
+ def prepare_codebase(*args)
26
21
  @options.parse(args)
27
22
  @options.verify
28
- run_source_parser(@options.paths, @options.excluded)
29
- filter_objects
30
- assign_objects_to_grade_lists
31
- end
32
-
33
- private
34
-
35
- # Assigns the objects returned by {#objects} to the grade_lists
36
- # based on their score
37
- #
38
- def assign_objects_to_grade_lists
39
- @grade_lists.each do |range|
40
- list = objects.select { |o| range.scores.include?(o.score) }
41
- range.objects = sort_by_priority(list)
42
- end
43
- end
44
-
45
- # Filters the +@objects+ based on the settings in +@options+
46
- #
47
- # @return [void]
48
- def filter_objects
49
- if @options.namespaces == :only
50
- self.objects = objects.select(&:namespace?)
51
- end
52
- if @options.namespaces == :none
53
- self.objects = objects.reject(&:namespace?)
54
- end
55
- if @options.undocumented == :only
56
- self.objects = objects.select(&:undocumented?)
57
- end
58
- if @options.undocumented == :none
59
- self.objects = objects.reject(&:undocumented?)
60
- end
61
- if @options.depth
62
- self.objects = objects.select { |o| o.depth <= @options.depth }
63
- end
64
- self.objects = objects.select do |o|
65
- @options.visibility.include?(o.visibility)
66
- end
67
- if !@options.visibility.include?(:private)
68
- self.objects = objects.reject do |o|
69
- o.private_tag?
70
- end
71
- end
72
- end
73
-
74
- # @return [Array<CodeObject::Proxy::Base>]
75
- def objects
76
- @objects ||= sort_by_priority(source_parser.all_objects)
77
- end
78
23
 
79
- # @param objects [Array<CodeObject::Proxy::Base>]
80
- # @return [Array<CodeObject::Proxy::Base>]
81
- def sort_by_priority(objects)
82
- objects.sort_by do |o|
83
- [o.priority, o.score, o.path.size]
84
- end.reverse
24
+ @codebase = ::Inch::Codebase.parse(Dir.pwd, @options.paths, @options.excluded)
85
25
  end
86
26
  end
87
27
  end
@@ -10,13 +10,8 @@ module Inch
10
10
  # $ inch COMMAND [paths] OBJECT_NAME [, OBJECT_NAME2, ...] [options]
11
11
  #
12
12
  # @abstract
13
- class BaseObject < Base
14
- attr_accessor :object, :objects
15
-
16
- def initialize
17
- super
18
- @grade_lists = Evaluation.new_grade_lists
19
- end
13
+ class BaseObject < BaseList
14
+ attr_accessor :object
20
15
 
21
16
  # Prepares the given objects, parsing arguments and
22
17
  # running the source parser.
@@ -24,28 +19,11 @@ module Inch
24
19
  # @param *args [Array<String>] the list of arguments
25
20
  # @return [void]
26
21
  def prepare_objects(*args)
27
- @options.parse(args)
28
- @options.verify
29
- run_source_parser(@options.paths, @options.excluded)
30
-
31
- self.objects = find_objects_with_names(@options.object_names)
32
- self.object = @objects.first
33
- end
34
-
35
- private
22
+ prepare_codebase(*args)
36
23
 
37
- # Returns all objects matching the given +object_names+
38
- #
39
- # @param object_names [Array<String>]
40
- # @return [Array<CodeObject::Proxy::Base>]
41
- def find_objects_with_names(object_names)
42
- object_names.map do |object_name|
43
- if object = source_parser.find_object(object_name)
44
- object
45
- else
46
- source_parser.find_objects(object_name)
47
- end
48
- end.flatten
24
+ context = API::Get.new(codebase, @options.object_names)
25
+ self.objects = context.objects
26
+ self.object = context.object
49
27
  end
50
28
  end
51
29
  end
@@ -21,8 +21,9 @@ module Inch
21
21
  # @param [Array<String>] args the list of arguments.
22
22
  # @return [void]
23
23
  def run(*args)
24
- prepare_list(*args)
25
- Output::List.new(@options, objects, @grade_lists)
24
+ prepare_codebase(*args)
25
+ context = API::List.new(codebase, @options)
26
+ Output::List.new(@options, context.objects, context.grade_lists)
26
27
  end
27
28
  end
28
29
  end
@@ -91,7 +91,7 @@ module Inch
91
91
  #
92
92
  # @return [String]
93
93
  def description_hint_arrows
94
- arrows = Output::Base::PRIORITY_ARROWS.join(' ')
94
+ arrows = Evaluation::PriorityRange.all.map(&:arrow).join(' ')
95
95
  "Arrows (#{arrows}) hint at the importance of the object " +
96
96
  "being documented."
97
97
  end
@@ -6,12 +6,14 @@ module Inch
6
6
  #
7
7
  # @abstract Subclass and override #set_options
8
8
  class BaseList < Base
9
- attribute :show_all, false
10
- attribute :visibility, [:public, :protected]
9
+ include API::Options::Filter::DefaultAttributeValues
10
+
11
+ attribute :visibility, DEFAULT_VISIBILITY
11
12
  attribute :namespaces
12
13
  attribute :undocumented
13
14
  attribute :depth
14
15
 
16
+ attribute :show_all, false
15
17
  alias :show_all? :show_all
16
18
 
17
19
  def parse(args)
@@ -3,14 +3,15 @@ module Inch
3
3
  module Command
4
4
  module Options
5
5
  class Suggest < BaseList
6
- attribute :object_count, 20
7
- attribute :file_count, 5
8
-
9
- attribute :proper_grades, [:A, :B]
10
- attribute :grades_to_display, [:B, :C, :U]
11
- attribute :grade_weights, [0.2, 0.4, 0.4]
12
- attribute :object_min_priority, 0
13
- attribute :object_max_score, ::Inch::Evaluation::Base::MAX_SCORE
6
+ include API::Options::Suggest::DefaultAttributeValues
7
+
8
+ attribute :object_count, DEFAULT_OBJECT_COUNT
9
+ attribute :file_count, DEFAULT_FILE_COUNT
10
+ attribute :proper_grades, DEFAULT_PROPER_GRADES
11
+ attribute :grades_to_display, DEFAULT_GRADES_TO_DISPLAY
12
+ attribute :grade_weights, DEFAULT_GRADE_WEIGHTS
13
+ attribute :object_min_priority, DEFAULT_OBJECT_MIN_PRIORITY
14
+ attribute :object_max_score, DEFAULT_OBJECT_MAX_SCORE
14
15
 
15
16
  attribute :pedantic, false
16
17
 
@@ -18,22 +18,20 @@ module Inch
18
18
  class Base
19
19
  include TraceHelper
20
20
 
21
- PRIORITY_MAP = {
22
- (4..99) => "\u2191", # north
23
- (2...4) => "\u2197", # north-east
24
- (0..1) => "\u2192", # east
25
- (-2..-1) => "\u2198", # south-east
26
- (-99..-3) => "\u2193", # south-east
27
- }
28
- PRIORITY_ARROWS = PRIORITY_MAP.values
29
-
30
21
  def priority_arrow(priority, color = :white)
31
- PRIORITY_MAP.each do |range, str|
22
+ Evaluation::PriorityRange.all.each do |range|
32
23
  if range.include?(priority)
33
- return str.color(color).dark
24
+ return range.arrow.color(color).dark
34
25
  end
35
26
  end
36
27
  end
28
+
29
+ def print_file_info(o, _color)
30
+ o.files.each do |f|
31
+ echo "-> #{f[0]}:#{f[1]}".color(_color)
32
+ end
33
+ echo separator
34
+ end
37
35
  end
38
36
  end
39
37
  end
@@ -70,14 +70,14 @@ module Inch
70
70
  grade = object.grade.to_s
71
71
  grade = grade.ljust(2).color(color)
72
72
  priority = object.priority
73
- " #{grade} #{priority_arrow(priority, color)} #{object.path}"
73
+ " #{grade} #{priority_arrow(priority, color)} #{object.fullname}"
74
74
  end
75
75
 
76
76
  def result_numbers(object, color)
77
77
  score = object.score.to_i.to_s
78
78
  score = score.rjust(3).color(color)
79
79
  priority = object.priority
80
- "#{score} #{priority} #{object.path}"
80
+ "#{score} #{priority} #{object.fullname}"
81
81
  end
82
82
 
83
83
  end
@@ -26,19 +26,11 @@ module Inch
26
26
 
27
27
  def print_object(o)
28
28
  trace
29
- trace_header(o.path, COLOR, BG_COLOR)
29
+ trace_header(o.fullname, COLOR, BG_COLOR)
30
30
 
31
- print_file_info(o)
31
+ print_file_info(o, COLOR)
32
32
  print_grade_info(o)
33
33
  print_roles_info(o)
34
-
35
- end
36
-
37
- def print_file_info(o)
38
- o.files.each do |f|
39
- echo "-> #{f[0]}:#{f[1]}".color(COLOR)
40
- end
41
- echo separator
42
34
  end
43
35
 
44
36
  def print_grade_info(o)
@@ -46,10 +46,10 @@ module Inch
46
46
  def print_grades_by_priority
47
47
  puts 'Grade distribution by priority:'
48
48
  puts
49
- PRIORITY_MAP.each do |priority_range, arrow|
49
+ Evaluation::PriorityRange.all.each do |priority_range|
50
50
  list = objects.select { |o| priority_range.include?(o.priority) }
51
51
  sparkline = grades_sparkline(list).to_s(' ')
52
- puts " #{arrow} #{sparkline} " +
52
+ puts " #{priority_range.arrow} #{sparkline} " +
53
53
  "#{list.size.to_s.rjust(5)} objects"
54
54
  puts
55
55
  end
@@ -73,9 +73,10 @@ module Inch
73
73
  end
74
74
 
75
75
  def print_priorities
76
+ arrows = Evaluation::PriorityRange.all.map(&:arrow)
76
77
  puts "Priority distribution in grades: (low to high)"
77
78
  puts
78
- puts " #{PRIORITY_MAP.values.reverse.join(' ')}"
79
+ puts " #{arrows.reverse.join(' ')}"
79
80
  @grade_lists.reverse.each do |grade_list|
80
81
  print_grade_list(grade_list)
81
82
  end
@@ -18,11 +18,11 @@ module Inch
18
18
  }
19
19
 
20
20
  # @param options [Command::Options::Suggest]
21
- # @param objects_to_display [Array<CodeObject::Proxy::Base>]
22
21
  # @param relevant_objects [Array<CodeObject::Proxy::Base>] the objects meeting the criteria defined in +options+
22
+ # @param objects_to_display [Array<CodeObject::Proxy::Base>]
23
23
  # @param grade_lists [Array<Evaluation::GradeList>]
24
24
  # @param files [Array<Evaluation::File>]
25
- def initialize(options, objects_to_display, relevant_objects, grade_lists, files)
25
+ def initialize(options, relevant_objects, objects_to_display, grade_lists, files)
26
26
  @options = options
27
27
  @objects = objects_to_display
28
28
  @relevant_objects = relevant_objects
@@ -63,7 +63,7 @@ module Inch
63
63
  trace
64
64
 
65
65
  files.each do |f|
66
- trace edged(FILE_COLOR, f.path.color(FILE_COLOR))
66
+ trace edged(FILE_COLOR, f.fullname.color(FILE_COLOR))
67
67
  end
68
68
  trace
69
69
  end
@@ -78,7 +78,7 @@ module Inch
78
78
  grade_objects.each do |o|
79
79
  grade = o.grade.to_s.ljust(2).color(r.color)
80
80
  priority = o.priority
81
- trace edged(r.color, " #{grade} #{priority_arrow(priority, r.color)} #{o.path}")
81
+ trace edged(r.color, " #{grade} #{priority_arrow(priority, r.color)} #{o.fullname}")
82
82
  end
83
83
  end
84
84
  end
@@ -89,7 +89,7 @@ module Inch
89
89
  end
90
90
 
91
91
  def priority_arrows_gte(min_priority)
92
- PRIORITY_MAP.map do |range, str|
92
+ Evaluation::PriorityRange.all.map do |range, str|
93
93
  str if range.min >= min_priority
94
94
  end.compact
95
95
  end
@@ -8,7 +8,7 @@ module Inch
8
8
  register_command_as :stats
9
9
 
10
10
  def description
11
- 'Lists all objects with their results'
11
+ 'Show statistics'
12
12
  end
13
13
 
14
14
  def usage
@@ -16,8 +16,9 @@ module Inch
16
16
  end
17
17
 
18
18
  def run(*args)
19
- prepare_list(*args)
20
- Output::Stats.new(@options, objects, @grade_lists)
19
+ prepare_codebase(*args)
20
+ context = API::Stats.new(codebase, @options)
21
+ Output::Stats.new(@options, context.objects, context.grade_lists)
21
22
  end
22
23
  end
23
24
  end
@@ -21,100 +21,10 @@ module Inch
21
21
  # @param [Array<String>] args the list of arguments.
22
22
  # @return [void]
23
23
  def run(*args)
24
- prepare_list(*args)
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 }
39
- end
40
-
41
- # @return [Array] the objects that should be displayed in the output
42
- def objects_to_display
43
- @objects_to_display ||= filter_objects_to_display
44
- end
45
-
46
- # @return [Array] the objects that should be displayed in the output
47
- def filter_objects_to_display
48
- grade_list = []
49
- @options.grades_to_display.map do |grade|
50
- r = grade_list(grade)
51
- arr = select_by_priority(r.objects, @options.object_min_priority)
52
- arr = arr.select { |o| o.score <= @options.object_max_score }
53
- grade_list << arr
54
- end
55
-
56
- weighted_list = WeightedList.new(grade_list, object_list_counts)
57
-
58
- list = sort_by_priority(weighted_list.to_a.flatten)
59
-
60
- if list.size > object_count
61
- list = list[0...object_count]
62
- end
63
- list
64
- end
65
-
66
- def files
67
- list = files_sorted_by_importance
68
- how_many = @options.file_count || list.size
69
- list[0...how_many]
70
- end
71
-
72
- def files_sorted_by_importance
73
- list = all_filenames(relevant_objects).uniq.map do |filename|
74
- f = Evaluation::File.for(filename, relevant_objects)
75
- end
76
-
77
- priority_list = list.select do |f|
78
- relevant_grades.include?(f.grade) &&
79
- relevant_priorities.include?(f.priority)
80
- end
81
-
82
- sort_by_priority(priority_list.empty? ? list : priority_list)
83
- end
84
-
85
- def all_filenames(objects)
86
- objects.map do |o|
87
- o.files.map(&:first)
88
- end.flatten
89
- end
90
-
91
- # Returns the unique grades assigned to objects
92
- #
93
- # grades # => [:A, :B, :C, :U]
94
- #
95
- # @return [Array<Symbol>]
96
- def grades
97
- objects.map(&:grade).uniq
98
- end
99
-
100
- def grade_list(grade_symbol)
101
- @grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
102
- end
103
-
104
- def relevant_objects
105
- select_by_priority(objects, @options.object_min_priority)
106
- end
107
-
108
- def relevant_grades
109
- grades.size >= 2 ? grades[-2..-1] : [grades.last].compact
110
- end
111
-
112
- def relevant_priorities
113
- (@options.object_min_priority..99)
114
- end
115
-
116
- def select_by_priority(list, min_priority)
117
- list.select { |o| o.priority >= min_priority }
24
+ prepare_codebase(*args)
25
+ context = API::Suggest.new(codebase, @options)
26
+ Output::Suggest.new(@options, context.all_objects,
27
+ context.objects, context.grade_lists, context.files)
118
28
  end
119
29
  end
120
30
  end