inch 0.1.4 → 0.2.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/TODOS.md +5 -3
  3. data/bin/inch +9 -4
  4. data/inch.gemspec +9 -4
  5. data/lib/inch.rb +1 -0
  6. data/lib/inch/cli.rb +6 -0
  7. data/lib/inch/cli/command.rb +0 -6
  8. data/lib/inch/cli/command_parser.rb +0 -2
  9. data/lib/inch/code_object/nodoc_helper.rb +1 -1
  10. data/lib/inch/code_object/proxy/base.rb +18 -3
  11. data/lib/inch/code_object/proxy/method_object.rb +5 -0
  12. data/lib/inch/config.rb +53 -0
  13. data/lib/inch/evaluation.rb +1 -1
  14. data/lib/inch/evaluation/base.rb +45 -1
  15. data/lib/inch/evaluation/constant_object.rb +10 -5
  16. data/lib/inch/evaluation/criteria.rb +38 -0
  17. data/lib/inch/evaluation/method_object.rb +50 -42
  18. data/lib/inch/evaluation/namespace_object.rb +38 -33
  19. data/lib/inch/evaluation/role/constant.rb +1 -0
  20. data/lib/inch/evaluation/role/method.rb +41 -10
  21. data/lib/inch/evaluation/role/method_parameter.rb +16 -1
  22. data/lib/inch/evaluation/role/namespace.rb +17 -5
  23. data/lib/inch/evaluation/role/object.rb +35 -0
  24. data/lib/inch/version.rb +1 -1
  25. data/test/fixtures/simple/lib/foo.rb +0 -37
  26. data/test/fixtures/simple/lib/nodoc.rb +45 -0
  27. data/test/fixtures/simple/lib/role_methods.rb +4 -0
  28. data/test/inch/code_object/nodoc_helper_test.rb +3 -1
  29. data/test/inch/code_object/proxy/method_object_test.rb +9 -0
  30. metadata +26 -32
  31. data/lib/inch/cli/command/console.rb +0 -22
  32. data/lib/inch/cli/command/inspect.rb +0 -20
  33. data/lib/inch/cli/command/options/console.rb +0 -26
  34. data/lib/inch/cli/command/options/inspect.rb +0 -25
  35. data/lib/inch/cli/command/output/console.rb +0 -49
  36. data/lib/inch/cli/command/output/inspect.rb +0 -129
  37. data/test/inch/cli/command/console_test.rb +0 -59
  38. data/test/inch/cli/command/inspect_test.rb +0 -68
@@ -1,18 +1,41 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  class MethodObject < Base
4
- DOC_SCORE = 50
5
- EXAMPLE_SCORE = 10
6
- MULTIPLE_EXAMPLES_SCORE = 25
7
- PARAM_SCORE = 40
8
- RETURN_SCORE = 10
9
-
10
4
  def evaluate
11
5
  eval_doc
12
6
  eval_parameters
13
7
  eval_return_type
14
8
  eval_code_example
9
+ eval_method
10
+ eval_misc
11
+ end
12
+
13
+ private
14
+
15
+ def eval_doc
16
+ if object.has_doc?
17
+ add_role Role::Object::WithDoc.new(object, score_for(:docstring))
18
+ else
19
+ add_role Role::Object::WithoutDoc.new(object, score_for(:docstring))
20
+ end
21
+ end
15
22
 
23
+ def eval_code_example
24
+ if object.has_code_example?
25
+ if object.has_multiple_code_examples?
26
+ add_role Role::Object::WithMultipleCodeExamples.new(object, score_for(:code_example_multi))
27
+ else
28
+ add_role Role::Object::WithCodeExample.new(object, score_for(:code_example_single))
29
+ end
30
+ else
31
+ add_role Role::Object::WithoutCodeExample.new(object, score_for(:code_example_single))
32
+ end
33
+ end
34
+
35
+ def eval_method
36
+ if object.constructor?
37
+ add_role Role::Method::Constructor.new(object)
38
+ end
16
39
  if object.overridden?
17
40
  add_role Role::Method::Overridden.new(object, object.overridden_method.score)
18
41
  end
@@ -28,12 +51,22 @@ module Inch
28
51
  if object.has_alias?
29
52
  add_role Role::Method::HasAlias.new(object)
30
53
  end
54
+ end
55
+
56
+ def eval_misc
31
57
  if object.nodoc?
32
58
  add_role Role::Object::TaggedAsNodoc.new(object)
33
59
  end
60
+ if object.api_tag?
61
+ if object.private_api_tag?
62
+ add_role Role::Object::TaggedAsPrivateAPI.new(object)
63
+ else
64
+ add_role Role::Object::TaggedAsAPI.new(object)
65
+ end
66
+ end
34
67
  if object.has_unconsidered_tags?
35
68
  count = object.unconsidered_tags.size
36
- add_role Role::Object::Tagged.new(object, TAGGED_SCORE * count)
69
+ add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
37
70
  end
38
71
  if object.in_root?
39
72
  add_role Role::Object::InRoot.new(object)
@@ -49,28 +82,6 @@ module Inch
49
82
  end
50
83
  end
51
84
 
52
- private
53
-
54
- def eval_doc
55
- if object.has_doc?
56
- add_role Role::Object::WithDoc.new(object, DOC_SCORE)
57
- else
58
- add_role Role::Object::WithoutDoc.new(object, DOC_SCORE)
59
- end
60
- end
61
-
62
- def eval_code_example
63
- if object.has_code_example?
64
- if object.has_multiple_code_examples?
65
- add_role Role::Object::WithMultipleCodeExamples.new(object, MULTIPLE_EXAMPLES_SCORE)
66
- else
67
- add_role Role::Object::WithCodeExample.new(object, EXAMPLE_SCORE)
68
- end
69
- else
70
- add_role Role::Object::WithoutCodeExample.new(object, EXAMPLE_SCORE)
71
- end
72
- end
73
-
74
85
  def eval_parameters
75
86
  if object.has_parameters?
76
87
  eval_all_parameters
@@ -81,17 +92,17 @@ module Inch
81
92
 
82
93
  def eval_no_parameters
83
94
  if score > min_score
84
- add_role Role::Method::WithoutParameters.new(object, PARAM_SCORE)
95
+ add_role Role::Method::WithoutParameters.new(object, score_for(:parameters))
85
96
  end
86
97
  end
87
98
 
88
99
  def eval_all_parameters
89
100
  params = object.parameters
90
- per_param = PARAM_SCORE.to_f / params.size
101
+ per_param = score_for(:parameters) / params.size
91
102
  params.each do |param|
92
103
  if param.mentioned?
93
104
  if param.wrongly_mentioned?
94
- add_role Role::MethodParameter::WithWrongMention.new(param, -PARAM_SCORE)
105
+ add_role Role::MethodParameter::WithWrongMention.new(param, -score_for(:parameters))
95
106
  else
96
107
  add_role Role::MethodParameter::WithMention.new(param, per_param * 0.5)
97
108
  end
@@ -120,17 +131,14 @@ module Inch
120
131
 
121
132
  def eval_return_type
122
133
  if object.return_mentioned?
123
- if object.questioning_name? && !object.return_described?
124
- # annotating a question mark method with the return type boolean
125
- # does not give any points
126
- # also, this could to be one of those cases where YARD
127
- # automatically assigns a @return tag to methods ending in a
128
- # question mark
129
- else
130
- add_role Role::Method::WithReturnType.new(object, RETURN_SCORE)
131
- end
134
+ add_role Role::Method::WithReturnType.new(object, score_for(:return_type))
135
+ else
136
+ add_role Role::Method::WithoutReturnType.new(object, score_for(:return_type))
137
+ end
138
+ if object.return_described?
139
+ add_role Role::Method::WithReturnDescription.new(object, score_for(:return_description))
132
140
  else
133
- add_role Role::Method::WithoutReturnType.new(object, RETURN_SCORE)
141
+ add_role Role::Method::WithoutReturnDescription.new(object, score_for(:return_description))
134
142
  end
135
143
  end
136
144
  end
@@ -3,10 +3,6 @@ module Inch
3
3
  # a namespace object can have methods and other namespace objects
4
4
  # inside itself (e.g. classes and modules)
5
5
  class NamespaceObject < Base
6
- DOC_SCORE = MAX_SCORE
7
- EXAMPLE_SCORE = 10
8
- MULTIPLE_EXAMPLES_SCORE = 20
9
-
10
6
  RUBY_CORE = %w(Array Bignum BasicObject Object Module Class Complex NilClass Numeric String Float Fiber FiberError Continuation Dir File Encoding Enumerator StopIteration Enumerator::Generator Enumerator::Yielder Exception SystemExit SignalException Interrupt StandardError TypeError ArgumentError IndexError KeyError RangeError ScriptError SyntaxError LoadError NotImplementedError NameError NoMethodError RuntimeError SecurityError NoMemoryError EncodingError SystemCallError Encoding::CompatibilityError File::Stat IO Hash ENV IOError EOFError ARGF RubyVM RubyVM::InstructionSequence Math::DomainError ZeroDivisionError FloatDomainError Integer Fixnum Data TrueClass FalseClass Mutex Thread Proc LocalJumpError SystemStackError Method UnboundMethod Binding Process::Status Random Range Rational RegexpError Regexp MatchData Symbol Struct ThreadGroup ThreadError Time Encoding::UndefinedConversionError Encoding::InvalidByteSequenceError Encoding::ConverterNotFoundError Encoding::Converter RubyVM::Env) +
11
7
  %w(Comparable Kernel File::Constants Enumerable Errno FileTest GC ObjectSpace GC::Profiler IO::WaitReadable IO::WaitWritable Marshal Math Process Process::UID Process::GID Process::Sys Signal)
12
8
 
@@ -14,24 +10,7 @@ module Inch
14
10
  eval_doc
15
11
  eval_children
16
12
  eval_code_example
17
-
18
- if object.has_many_attributes?
19
- add_role Role::Namespace::WithManyAttributes.new(object)
20
- end
21
- if object.nodoc?
22
- add_role Role::Object::TaggedAsNodoc.new(object)
23
- end
24
- if object.has_unconsidered_tags?
25
- count = object.unconsidered_tags.size
26
- add_role Role::Object::Tagged.new(object, TAGGED_SCORE * count)
27
- end
28
- if object.in_root?
29
- add_role Role::Object::InRoot.new(object)
30
- end
31
- if object.public? # this is always true for classes and modules
32
- add_role Role::Object::Public.new(object)
33
- end
34
-
13
+ eval_misc
35
14
  eval_core
36
15
  end
37
16
 
@@ -43,23 +22,23 @@ module Inch
43
22
  end
44
23
  end
45
24
 
46
- def eval_doc
47
- if object.has_doc?
48
- add_role Role::Object::WithDoc.new(object, DOC_SCORE)
49
- else
50
- add_role Role::Object::WithoutDoc.new(object, DOC_SCORE)
51
- end
52
- end
53
-
54
25
  def eval_code_example
55
26
  if object.has_code_example?
56
27
  if object.has_multiple_code_examples?
57
- add_role Role::Object::WithMultipleCodeExamples.new(object, MULTIPLE_EXAMPLES_SCORE)
28
+ add_role Role::Object::WithMultipleCodeExamples.new(object, score_for(:code_example_multi))
58
29
  else
59
- add_role Role::Object::WithCodeExample.new(object, EXAMPLE_SCORE)
30
+ add_role Role::Object::WithCodeExample.new(object, score_for(:code_example_single))
60
31
  end
61
32
  else
62
- add_role Role::Object::WithoutCodeExample.new(object, EXAMPLE_SCORE)
33
+ add_role Role::Object::WithoutCodeExample.new(object, score_for(:code_example_single))
34
+ end
35
+ end
36
+
37
+ def eval_doc
38
+ if object.has_doc?
39
+ add_role Role::Object::WithDoc.new(object, score_for(:docstring))
40
+ else
41
+ add_role Role::Object::WithoutDoc.new(object, score_for(:docstring))
63
42
  end
64
43
  end
65
44
 
@@ -80,6 +59,32 @@ module Inch
80
59
  end
81
60
  end
82
61
 
62
+ def eval_misc
63
+ if object.has_many_attributes?
64
+ add_role Role::Namespace::WithManyAttributes.new(object)
65
+ end
66
+ if object.nodoc?
67
+ add_role Role::Object::TaggedAsNodoc.new(object)
68
+ end
69
+ if object.api_tag?
70
+ if object.private_api_tag?
71
+ add_role Role::Object::TaggedAsPrivateAPI.new(object)
72
+ else
73
+ add_role Role::Object::TaggedAsAPI.new(object)
74
+ end
75
+ end
76
+ if object.has_unconsidered_tags?
77
+ count = object.unconsidered_tags.size
78
+ add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
79
+ end
80
+ if object.in_root?
81
+ add_role Role::Object::InRoot.new(object)
82
+ end
83
+ if object.public? # this is always true for classes and modules
84
+ add_role Role::Object::Public.new(object)
85
+ end
86
+ end
87
+
83
88
  def children
84
89
  @children ||= object.children.map(&:evaluation)
85
90
  end
@@ -1,6 +1,7 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  module Role
4
+ # Roles assigned to constants
4
5
  module Constant
5
6
  class WithDoc < Object::WithDoc
6
7
  end
@@ -2,46 +2,77 @@ module Inch
2
2
  module Evaluation
3
3
  module Role
4
4
  module Method
5
+ # Role assigned to methods without parameters
5
6
  class WithoutParameters < Base
6
7
  end
8
+
9
+ # Role assigned to methods with many parameters
10
+ #
11
+ # @see CodeObject::Proxy::MethodObject#has_many_parameters?
7
12
  class WithManyParameters < Base
8
- # +priority
9
13
  def priority
10
14
  +2
11
15
  end
12
16
  end
17
+
18
+ # Role assigned to methods where the return value is typed in the docs
19
+ class WithReturnType < Base
20
+ end
21
+
22
+ # Role assigned to methods where the return value is not typed
23
+ class WithoutReturnType < Missing
24
+ def suggestion
25
+ "Describe what '#{object.name}' returns"
26
+ end
27
+ end
28
+
29
+ # Role assigned to methods where the return value is decribed in the docs
30
+ class WithReturnDescription < Base
31
+ end
32
+
33
+ # Role assigned to methods where the return value is not decribed
34
+ class WithoutReturnDescription < Missing
35
+ def suggestion
36
+ "Describe what '#{object.name}' returns"
37
+ end
38
+ end
39
+
40
+
41
+ # Role assigned to methods with many lines
42
+ #
43
+ # @see CodeObject::Proxy::MethodObject#has_many_lines?
13
44
  class WithManyLines < Base
14
- # +priority
15
45
  def priority
16
46
  +2
17
47
  end
18
48
  end
49
+
50
+ # Role assigned to methods whose name end in a '!'
19
51
  class WithBangName < Base
20
- # +priority
21
52
  def priority
22
53
  +3
23
54
  end
24
55
  end
56
+
57
+ # Role assigned to methods whose name end in a '?'
25
58
  class WithQuestioningName < Base
26
59
  def priority
27
60
  -4
28
61
  end
29
62
  end
63
+
64
+ # Role assigned to methods which are aliased
30
65
  class HasAlias < Base
31
- # +priority
32
66
  def priority
33
67
  +2
34
68
  end
35
69
  end
36
70
 
37
- class WithReturnType < Base
38
- end
39
- class WithoutReturnType < Missing
40
- def suggestion
41
- "Describe what '#{object.name}' returns"
42
- end
71
+ # Role assigned to methods that are constructors
72
+ class Constructor < Base
43
73
  end
44
74
 
75
+ # Role assigned to methods that are overriding another method
45
76
  class Overridden < Base
46
77
  # It seems more important to document the overridden method,
47
78
  # than the overriding one
@@ -1,31 +1,43 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  module Role
4
+ # Roles assigned to method parameters
4
5
  module MethodParameter
6
+ # Role assigned to parameters that are mentioned in the docs
5
7
  class WithMention < Base
6
8
  end
9
+
10
+ # Role assigned to parameters that are not mentioned in the docs
7
11
  class WithoutMention < Missing
8
12
  def suggestion
9
13
  "Describe the parameter '#{object.name}'"
10
14
  end
11
15
  end
12
16
 
17
+ # Role assigned to parameters that are typed in the docs
13
18
  class WithType < Base
14
19
  end
20
+
21
+ # Role assigned to parameters that are not typed in the docs
15
22
  class WithoutType < Missing
16
23
  end
17
24
 
25
+ # Role assigned to parameters that are spalts, e.g. +*args+
18
26
  class Splat < Base
19
27
  def priority
20
28
  +1
21
29
  end
22
30
  end
31
+
32
+ # Role assigned to parameters that are blocks, e.g. +&block+
23
33
  class Block < Base
24
34
  def priority
25
35
  +1
26
36
  end
27
37
  end
28
38
 
39
+ # Role assigned to parameters that are documented, but not part of
40
+ # the method signature
29
41
  class WithWrongMention < Missing
30
42
  def suggestion
31
43
  "The parameter '#{object.name}' seems not to be part of the signature."
@@ -34,8 +46,11 @@ module Inch
34
46
  +1
35
47
  end
36
48
  end
49
+
50
+ # Role assigned to parameters that have a 'bad' name
51
+ #
52
+ # @see CodeObject::Proxy::MethodParameterObject#bad_name?
37
53
  class WithBadName < Base
38
- # +priority
39
54
  def priority
40
55
  +1
41
56
  end
@@ -1,7 +1,9 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  module Role
4
+ # Roles assigned to namespaces (classes and modules)
4
5
  module Namespace
6
+ # Role assigned to namespaces with children
5
7
  class WithChildren < Base
6
8
  # This role doesnot assign a score.
7
9
  def score
@@ -13,12 +15,20 @@ module Inch
13
15
  # @value.to_f
14
16
  end
15
17
  end
18
+
19
+ # Role assigned to namespaces with many children
20
+ #
21
+ # @see CodeObject::Proxy::NamespaceObject#has_many_children?
16
22
  class WithManyChildren < Base
17
23
  # +priority
18
24
  def priority
19
25
  +1
20
26
  end
21
27
  end
28
+
29
+ # Role assigned to namespaces with many attributes
30
+ #
31
+ # @see CodeObject::Proxy::NamespaceObject#has_many_attributes?
22
32
  class WithManyAttributes < Base
23
33
  # +priority
24
34
  def priority
@@ -26,28 +36,30 @@ module Inch
26
36
  end
27
37
  end
28
38
 
39
+ # Role assigned to namespaces without any children
29
40
  class WithoutChildren < Base
30
41
  end
42
+
43
+ # Role assigned to namespaces without any methods
31
44
  class WithoutMethods < Base
32
- # --priority
33
45
  def priority
34
46
  -2
35
47
  end
36
48
  end
49
+
37
50
  # A 'pure' namespace has only namespaces as children
38
51
  class Pure < Base
39
- # --priority
40
52
  def priority
41
53
  -2
42
54
  end
43
55
  end
56
+
44
57
  # A 'core' namespace is a class or module that is part of the Ruby
45
58
  # core. It might appear in the object tree when monkey-patching
46
59
  # functionality.
47
- # But just because we patch Hash does not mean we need to document
48
- # the Hash class itself.
60
+ # (the reasoning here is: just because we patch Hash does not mean
61
+ # we need to document the Hash class itself)
49
62
  class Core < Base
50
- # --priority
51
63
  def priority
52
64
  -7
53
65
  end