inch 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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