inch 0.2.3 → 0.3.0.rc1

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 (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
@@ -0,0 +1,22 @@
1
+ module Inch
2
+ module Codebase
3
+ class Proxy
4
+ attr_reader :objects
5
+
6
+ def initialize(dir = Dir.pwd, paths = nil, excluded = nil)
7
+ @base_dir = dir
8
+ provider = CodeObject::Provider.parse(dir, paths, excluded)
9
+ @objects = Codebase::Objects.new(provider.objects)
10
+ end
11
+
12
+ def grade_lists
13
+ lists = Evaluation.new_grade_lists
14
+ lists.each do |range|
15
+ list = objects.select { |o| range.scores.include?(o.score) }
16
+ range.objects = Objects.sort_by_priority(list)
17
+ end
18
+ lists
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,7 @@
1
1
  module Inch
2
+ # Stores the configuration for Inch
3
+ #
4
+ # @see config/defaults.rb
2
5
  class Config
3
6
  class << self
4
7
  attr_accessor :instance
@@ -37,8 +40,12 @@ module Inch
37
40
  ::Inch::Evaluation::Grade.grade(symbol, &block)
38
41
  end
39
42
 
43
+ def priority(symbol, &block)
44
+ ::Inch::Evaluation::PriorityRange.priority_range(symbol, &block)
45
+ end
46
+
40
47
  def schema(constant_name, &block)
41
- constant = eval("::Inch::Evaluation::#{constant_name}")
48
+ constant = eval("::Inch::Evaluation::Proxy::#{constant_name}")
42
49
  constant.criteria(&block)
43
50
  end
44
51
  end
@@ -1,4 +1,6 @@
1
1
  module Inch
2
+ # The Evaluation module concerns itself with the evaluation of code objects
3
+ # with regard to their inline code documentation
2
4
  module Evaluation
3
5
  def self.for(code_object)
4
6
  class_for(code_object).new(code_object)
@@ -13,12 +15,13 @@ module Inch
13
15
  end
14
16
  end
15
17
 
16
- require_relative 'evaluation/read_write_methods'
18
+ require_relative 'utils/read_write_methods'
17
19
 
18
20
  require_relative 'evaluation/file'
19
21
  require_relative 'evaluation/grade'
20
22
  require_relative 'evaluation/grade_list'
21
23
  require_relative 'evaluation/object_schema'
24
+ require_relative 'evaluation/priority_range'
22
25
 
23
26
  require_relative 'evaluation/role/base'
24
27
  require_relative 'evaluation/role/missing'
@@ -28,9 +31,4 @@ require_relative 'evaluation/role/method_parameter'
28
31
  require_relative 'evaluation/role/namespace'
29
32
  require_relative 'evaluation/role/constant'
30
33
 
31
- require_relative 'evaluation/base'
32
- require_relative 'evaluation/namespace_object'
33
- require_relative 'evaluation/class_object'
34
- require_relative 'evaluation/constant_object'
35
- require_relative 'evaluation/method_object'
36
- require_relative 'evaluation/module_object'
34
+ require_relative 'evaluation/proxy'
@@ -11,7 +11,7 @@ module Inch
11
11
  end
12
12
 
13
13
  # @note added to be compatible with code objects
14
- def path
14
+ def fullname
15
15
  filename
16
16
  end
17
17
 
@@ -1,7 +1,7 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  class Grade
4
- extend Evaluation::ReadWriteMethods
4
+ extend Utils::ReadWriteMethods
5
5
 
6
6
  rw_methods %w(scores label color bg_color)
7
7
 
@@ -1,7 +1,9 @@
1
1
  module Inch
2
2
  module Evaluation
3
+ # An ObjectSchema describes how important certain parts of the docs are
4
+ # for the associated Object
3
5
  class ObjectSchema
4
- extend Evaluation::ReadWriteMethods
6
+ extend Utils::ReadWriteMethods
5
7
 
6
8
  rw_methods %w(
7
9
  docstring
@@ -0,0 +1,44 @@
1
+ module Inch
2
+ module Evaluation
3
+ class PriorityRange
4
+ extend Utils::ReadWriteMethods
5
+ extend Forwardable
6
+
7
+ rw_methods %w(priorities arrow)
8
+
9
+ def_delegators :priorities, :include?, :min, :max
10
+
11
+ def initialize(symbol)
12
+ @symbol = symbol
13
+ end
14
+
15
+ def update(&block)
16
+ instance_eval(&block)
17
+ end
18
+
19
+ def to_sym
20
+ @symbol
21
+ end
22
+
23
+ def to_s
24
+ arrow
25
+ end
26
+
27
+ class << self
28
+ attr_reader :priority_map
29
+
30
+ def all
31
+ @priority_map ||= {}
32
+ @priority_map.values
33
+ end
34
+
35
+ def priority_range(symbol, &block)
36
+ @priority_map ||= {}
37
+ @priority_map[symbol] ||= PriorityRange.new(symbol)
38
+ @priority_map[symbol].update(&block) if block
39
+ @priority_map[symbol]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ module Inch
2
+ # The Evaluation module concerns itself with the evaluation of code objects
3
+ # with regard to their inline code documentation
4
+ module Evaluation
5
+ module Proxy
6
+ def self.for(code_object)
7
+ class_for(code_object).new(code_object)
8
+ end
9
+
10
+ private
11
+
12
+ def self.class_for(code_object)
13
+ class_name = code_object.class.to_s.split('::').last
14
+ eval(class_name)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ require_relative 'proxy/base'
21
+ require_relative 'proxy/namespace_object'
22
+ require_relative 'proxy/class_object'
23
+ require_relative 'proxy/constant_object'
24
+ require_relative 'proxy/method_object'
25
+ require_relative 'proxy/module_object'
@@ -0,0 +1,146 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ # @abstract
5
+ class Base
6
+ extend Forwardable
7
+
8
+ MIN_SCORE = 0
9
+ MAX_SCORE = 100
10
+
11
+ TAGGED_SCORE = 20 # assigned per unconsidered tag
12
+
13
+ # @return [CodeObject::Proxy::Base]
14
+ attr_accessor :object
15
+
16
+ attr_reader :min_score, :max_score
17
+
18
+ class << self
19
+ attr_reader :criteria_map
20
+
21
+ # Defines the weights during evaluation for different criteria
22
+ #
23
+ # MethodObject.criteria do
24
+ # docstring 0.5
25
+ # parameters 0.4
26
+ # return_type 0.1
27
+ #
28
+ # if object.constructor?
29
+ # parameters 0.5
30
+ # return_type 0.0
31
+ # end
32
+ # end
33
+ #
34
+ # @return [void]
35
+ def criteria(&block)
36
+ @criteria_map ||= {}
37
+ @criteria_map[to_s] ||= ObjectSchema.new(&block)
38
+ end
39
+ end
40
+
41
+ # @param object [CodeObject::Proxy::Base]
42
+ def initialize(object)
43
+ self.object = object
44
+ @roles = []
45
+ evaluate
46
+ end
47
+
48
+ # Evaluates the objects and assigns roles
49
+ def evaluate
50
+ __evaluate(object, relevant_roles)
51
+ end
52
+
53
+ def __evaluate(object, role_classes)
54
+ role_classes.each do |role_class, score|
55
+ if role_class.applicable?(object)
56
+ add_role role_class.new(object, score)
57
+ end
58
+ end
59
+ end
60
+
61
+ # @return [Float]
62
+ def max_score
63
+ arr = @roles.map(&:max_score).compact
64
+ [MAX_SCORE].concat(arr).min
65
+ end
66
+
67
+ # @return [Float]
68
+ def min_score
69
+ arr = @roles.map(&:min_score).compact
70
+ [MIN_SCORE].concat(arr).max
71
+ end
72
+
73
+ # @return [Float]
74
+ def score
75
+ value = @roles.inject(0) { |sum,r| sum + r.score.to_f }
76
+ if value < min_score
77
+ min_score
78
+ elsif value > max_score
79
+ max_score
80
+ else
81
+ value
82
+ end
83
+ end
84
+
85
+ # @return [Fixnum]
86
+ def priority
87
+ @roles.inject(0) { |sum,r| sum + r.priority.to_i }
88
+ end
89
+
90
+ # @return [Array<Evaluation::Role::Base>]
91
+ def roles
92
+ @roles
93
+ end
94
+
95
+ protected
96
+
97
+ def add_role(role)
98
+ @roles << role
99
+ end
100
+
101
+ def criteria
102
+ @criteria ||= begin
103
+ c = self.class.criteria_map[self.class.to_s]
104
+ c.evaluate(object)
105
+ c
106
+ end
107
+ end
108
+
109
+ def relevant_base_roles
110
+ {
111
+ Role::Object::InRoot => nil,
112
+ Role::Object::Public => nil,
113
+ Role::Object::Protected => nil,
114
+ Role::Object::Private => nil,
115
+ Role::Object::TaggedAsNodoc => nil,
116
+ Role::Object::WithDoc => score_for(:docstring),
117
+ Role::Object::WithoutDoc => score_for(:docstring),
118
+ Role::Object::WithCodeExample => score_for(:code_example_single),
119
+ Role::Object::WithMultipleCodeExamples => score_for(:code_example_multi),
120
+ Role::Object::WithoutCodeExample => score_for(:code_example_single),
121
+ Role::Object::Tagged => score_for_unconsidered_tags,
122
+ Role::Object::TaggedAsAPI => nil,
123
+ Role::Object::TaggedAsPrivateAPI => nil,
124
+ }
125
+ end
126
+
127
+ def score_for_unconsidered_tags
128
+ count = object.unconsidered_tag_count
129
+ score_for(:unconsidered_tag) * count
130
+ end
131
+
132
+ # Returns a key-value pair of Role classes and potential scores for
133
+ # each role (can be nil)
134
+ #
135
+ # @return [Hash]
136
+ def relevant_roles
137
+ {}
138
+ end
139
+
140
+ def score_for(criteria_name)
141
+ criteria.send(criteria_name) * MAX_SCORE
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,8 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ class ClassObject < NamespaceObject
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ class ConstantObject < Base
5
+ protected
6
+
7
+ def relevant_roles
8
+ {
9
+ Role::Constant::WithDoc => score_for(:docstring),
10
+ Role::Constant::WithoutDoc => score_for(:docstring),
11
+ Role::Constant::TaggedAsNodoc => nil,
12
+ Role::Constant::Public => nil,
13
+ Role::Constant::Private => nil,
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,65 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ class MethodObject < Base
5
+ def evaluate
6
+ super
7
+ evaluate_parameters
8
+ end
9
+
10
+ protected
11
+
12
+ def relevant_roles
13
+ relevant_base_roles.merge(relevant_method_roles)
14
+ end
15
+
16
+ private
17
+
18
+ def evaluate_parameters
19
+ params = object.parameters
20
+ per_param = score_for_single_parameter
21
+ params.each do |param|
22
+ role_classes = relevant_parameter_roles(param, per_param)
23
+ __evaluate(param, role_classes)
24
+ end
25
+ end
26
+
27
+ def relevant_method_roles
28
+ {
29
+ Role::Method::Constructor => nil,
30
+ Role::Method::Getter => nil,
31
+ Role::Method::Setter => nil,
32
+ Role::Method::Overridden => object.overridden? ? object.overridden_method.score : nil,
33
+ Role::Method::WithManyLines => nil,
34
+ Role::Method::WithBangName => nil,
35
+ Role::Method::WithQuestioningName => nil,
36
+ Role::Method::HasAlias => nil,
37
+ Role::Method::WithReturnType => score_for(:return_type),
38
+ Role::Method::WithoutReturnType => score_for(:return_type),
39
+ Role::Method::WithReturnDescription => score_for(:return_description),
40
+ Role::Method::WithoutReturnDescription => score_for(:return_description),
41
+ Role::Method::WithoutParameters => score_for(:parameters),
42
+ Role::Method::WithManyParameters => nil,
43
+ }
44
+ end
45
+
46
+ def relevant_parameter_roles(param, per_param)
47
+ {
48
+ Role::MethodParameter::WithWrongMention => -score_for(:parameters),
49
+ Role::MethodParameter::WithMention => per_param * 0.5,
50
+ Role::MethodParameter::WithoutMention => per_param * 0.5,
51
+ Role::MethodParameter::WithType => per_param * 0.5,
52
+ Role::MethodParameter::WithoutType => per_param * 0.5,
53
+ Role::MethodParameter::WithBadName => nil,
54
+ Role::MethodParameter::Block => nil,
55
+ Role::MethodParameter::Splat => nil,
56
+ }
57
+ end
58
+
59
+ def score_for_single_parameter
60
+ @param_score ||= score_for(:parameters) / object.parameters.size
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ class ModuleObject < NamespaceObject
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Proxy
4
+ # a namespace object can have methods and other namespace objects
5
+ # inside itself (e.g. classes and modules)
6
+ class NamespaceObject < Base
7
+ protected
8
+
9
+ def relevant_roles
10
+ relevant_base_roles.merge(relevant_namespace_roles)
11
+ end
12
+
13
+ def relevant_namespace_roles
14
+ {
15
+ Role::Namespace::Core => nil,
16
+ Role::Namespace::WithManyAttributes => nil,
17
+ Role::Namespace::WithoutChildren => nil,
18
+ Role::Namespace::WithChildren => nil,
19
+ Role::Namespace::WithManyChildren => nil,
20
+ Role::Namespace::WithoutMethods => nil,
21
+ Role::Namespace::Pure => nil,
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end