inch 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +335 -3
  4. data/Rakefile +8 -0
  5. data/TODOS.md +12 -0
  6. data/bin/inch +17 -0
  7. data/inch.gemspec +7 -2
  8. data/lib/inch.rb +6 -1
  9. data/lib/inch/cli.rb +24 -0
  10. data/lib/inch/cli/arguments.rb +45 -0
  11. data/lib/inch/cli/command.rb +29 -0
  12. data/lib/inch/cli/command/base.rb +62 -0
  13. data/lib/inch/cli/command/base_list.rb +75 -0
  14. data/lib/inch/cli/command/base_object.rb +40 -0
  15. data/lib/inch/cli/command/console.rb +22 -0
  16. data/lib/inch/cli/command/inspect.rb +20 -0
  17. data/lib/inch/cli/command/list.rb +25 -0
  18. data/lib/inch/cli/command/options/base.rb +137 -0
  19. data/lib/inch/cli/command/options/base_list.rb +84 -0
  20. data/lib/inch/cli/command/options/base_object.rb +47 -0
  21. data/lib/inch/cli/command/options/console.rb +26 -0
  22. data/lib/inch/cli/command/options/inspect.rb +25 -0
  23. data/lib/inch/cli/command/options/list.rb +30 -0
  24. data/lib/inch/cli/command/options/show.rb +27 -0
  25. data/lib/inch/cli/command/options/stats.rb +20 -0
  26. data/lib/inch/cli/command/options/suggest.rb +61 -0
  27. data/lib/inch/cli/command/output/base.rb +32 -0
  28. data/lib/inch/cli/command/output/console.rb +45 -0
  29. data/lib/inch/cli/command/output/inspect.rb +129 -0
  30. data/lib/inch/cli/command/output/list.rb +87 -0
  31. data/lib/inch/cli/command/output/show.rb +79 -0
  32. data/lib/inch/cli/command/output/stats.rb +111 -0
  33. data/lib/inch/cli/command/output/suggest.rb +104 -0
  34. data/lib/inch/cli/command/show.rb +20 -0
  35. data/lib/inch/cli/command/stats.rb +20 -0
  36. data/lib/inch/cli/command/suggest.rb +104 -0
  37. data/lib/inch/cli/command_parser.rb +82 -0
  38. data/lib/inch/cli/sparkline_helper.rb +31 -0
  39. data/lib/inch/cli/trace_helper.rb +42 -0
  40. data/lib/inch/cli/yardopts_helper.rb +49 -0
  41. data/lib/inch/code_object.rb +8 -0
  42. data/lib/inch/code_object/docstring.rb +97 -0
  43. data/lib/inch/code_object/nodoc_helper.rb +84 -0
  44. data/lib/inch/code_object/proxy.rb +37 -0
  45. data/lib/inch/code_object/proxy/base.rb +194 -0
  46. data/lib/inch/code_object/proxy/class_object.rb +9 -0
  47. data/lib/inch/code_object/proxy/constant_object.rb +8 -0
  48. data/lib/inch/code_object/proxy/method_object.rb +118 -0
  49. data/lib/inch/code_object/proxy/method_parameter_object.rb +81 -0
  50. data/lib/inch/code_object/proxy/module_object.rb +8 -0
  51. data/lib/inch/code_object/proxy/namespace_object.rb +38 -0
  52. data/lib/inch/core_ext.rb +2 -0
  53. data/lib/inch/core_ext/string.rb +3 -0
  54. data/lib/inch/core_ext/yard.rb +4 -0
  55. data/lib/inch/evaluation.rb +35 -0
  56. data/lib/inch/evaluation/base.rb +60 -0
  57. data/lib/inch/evaluation/class_object.rb +6 -0
  58. data/lib/inch/evaluation/constant_object.rb +34 -0
  59. data/lib/inch/evaluation/file.rb +66 -0
  60. data/lib/inch/evaluation/method_object.rb +127 -0
  61. data/lib/inch/evaluation/module_object.rb +6 -0
  62. data/lib/inch/evaluation/namespace_object.rb +94 -0
  63. data/lib/inch/evaluation/role/base.rb +49 -0
  64. data/lib/inch/evaluation/role/constant.rb +43 -0
  65. data/lib/inch/evaluation/role/method.rb +60 -0
  66. data/lib/inch/evaluation/role/method_parameter.rb +46 -0
  67. data/lib/inch/evaluation/role/missing.rb +20 -0
  68. data/lib/inch/evaluation/role/namespace.rb +58 -0
  69. data/lib/inch/evaluation/role/object.rb +64 -0
  70. data/lib/inch/evaluation/score_range.rb +26 -0
  71. data/lib/inch/rake.rb +1 -0
  72. data/lib/inch/rake/suggest.rb +26 -0
  73. data/lib/inch/source_parser.rb +36 -0
  74. data/lib/inch/version.rb +1 -1
  75. data/test/fixtures/code_examples/lib/foo.rb +87 -0
  76. data/test/fixtures/readme/lib/foo.rb +17 -0
  77. data/test/fixtures/simple/README +25 -0
  78. data/test/fixtures/simple/lib/broken.rb +10 -0
  79. data/test/fixtures/simple/lib/foo.rb +214 -0
  80. data/test/fixtures/simple/lib/role_methods.rb +78 -0
  81. data/test/fixtures/simple/lib/role_namespaces.rb +68 -0
  82. data/test/fixtures/visibility/lib/foo.rb +18 -0
  83. data/test/fixtures/yardopts/.yardopts +1 -0
  84. data/test/fixtures/yardopts/foo/bar.rb +6 -0
  85. data/test/inch/cli/arguments_test.rb +70 -0
  86. data/test/inch/cli/command/console_test.rb +59 -0
  87. data/test/inch/cli/command/inspect_test.rb +59 -0
  88. data/test/inch/cli/command/list_test.rb +61 -0
  89. data/test/inch/cli/command/show_test.rb +59 -0
  90. data/test/inch/cli/command/stats_test.rb +57 -0
  91. data/test/inch/cli/command/suggest_test.rb +57 -0
  92. data/test/inch/cli/command_parser_test.rb +33 -0
  93. data/test/inch/cli/yardopts_helper_test.rb +84 -0
  94. data/test/inch/code_object/docstring_test.rb +204 -0
  95. data/test/inch/code_object/nodoc_helper_test.rb +38 -0
  96. data/test/inch/code_object/proxy_test.rb +188 -0
  97. data/test/inch/source_parser_test.rb +23 -0
  98. data/test/integration/stats_options_test.rb +34 -0
  99. data/test/integration/visibility_options_test.rb +79 -0
  100. data/test/test_helper.rb +21 -0
  101. metadata +184 -7
@@ -0,0 +1,127 @@
1
+ module Inch
2
+ module Evaluation
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
+ def evaluate
11
+ eval_doc
12
+ eval_parameters
13
+ eval_return_type
14
+ eval_code_example
15
+
16
+ if object.overridden?
17
+ add_role Role::Method::Overridden.new(object, object.overridden_method.score)
18
+ end
19
+ if object.has_many_lines?
20
+ add_role Role::Method::WithManyLines.new(object)
21
+ end
22
+ if object.bang_name?
23
+ add_role Role::Method::WithBangName.new(object)
24
+ end
25
+ if object.has_alias?
26
+ add_role Role::Method::HasAlias.new(object)
27
+ end
28
+ if object.nodoc?
29
+ add_role Role::Object::TaggedAsNodoc.new(object)
30
+ end
31
+ if object.has_unconsidered_tags?
32
+ count = object.unconsidered_tags.size
33
+ add_role Role::Object::Tagged.new(object, TAGGED_SCORE * count)
34
+ end
35
+ if object.in_root?
36
+ add_role Role::Object::InRoot.new(object)
37
+ end
38
+ if object.public?
39
+ add_role Role::Object::Public.new(object)
40
+ end
41
+ if object.protected?
42
+ add_role Role::Object::Protected.new(object)
43
+ end
44
+ if object.private?
45
+ add_role Role::Object::Private.new(object)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def eval_doc
52
+ if object.has_doc?
53
+ add_role Role::Object::WithDoc.new(object, DOC_SCORE)
54
+ else
55
+ add_role Role::Object::WithoutDoc.new(object, DOC_SCORE)
56
+ end
57
+ end
58
+
59
+ def eval_code_example
60
+ if object.has_code_example?
61
+ if object.has_multiple_code_examples?
62
+ add_role Role::Object::WithMultipleCodeExamples.new(object, MULTIPLE_EXAMPLES_SCORE)
63
+ else
64
+ add_role Role::Object::WithCodeExample.new(object, EXAMPLE_SCORE)
65
+ end
66
+ else
67
+ add_role Role::Object::WithoutCodeExample.new(object, EXAMPLE_SCORE)
68
+ end
69
+ end
70
+
71
+ def eval_parameters
72
+ if object.has_parameters?
73
+ eval_all_parameters
74
+ else
75
+ eval_no_parameters
76
+ end
77
+ end
78
+
79
+ def eval_no_parameters
80
+ if score > min_score
81
+ add_role Role::Method::WithoutParameters.new(object, PARAM_SCORE)
82
+ end
83
+ end
84
+
85
+ def eval_all_parameters
86
+ params = object.parameters
87
+ per_param = PARAM_SCORE.to_f / params.size
88
+ params.each do |param|
89
+ if param.mentioned?
90
+ if param.wrongly_mentioned?
91
+ add_role Role::MethodParameter::WithWrongMention.new(param, -PARAM_SCORE)
92
+ else
93
+ add_role Role::MethodParameter::WithMention.new(param, per_param * 0.5)
94
+ end
95
+ else
96
+ add_role Role::MethodParameter::WithoutMention.new(param, per_param * 0.5)
97
+ end
98
+ if param.typed?
99
+ add_role Role::MethodParameter::WithType.new(param, per_param * 0.5)
100
+ else
101
+ add_role Role::MethodParameter::WithoutType.new(param, per_param * 0.5)
102
+ end
103
+ if param.bad_name?
104
+ add_role Role::MethodParameter::WithBadName.new(param)
105
+ end
106
+ if param.block?
107
+ add_role Role::MethodParameter::Block.new(param)
108
+ end
109
+ if param.splat?
110
+ add_role Role::MethodParameter::Splat.new(param)
111
+ end
112
+ end
113
+ if object.has_many_parameters?
114
+ add_role Role::Method::WithManyParameters.new(object)
115
+ end
116
+ end
117
+
118
+ def eval_return_type
119
+ if object.return_mentioned?
120
+ add_role Role::Method::WithReturnType.new(object, RETURN_SCORE)
121
+ else
122
+ add_role Role::Method::WithoutReturnType.new(object, RETURN_SCORE)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,6 @@
1
+ module Inch
2
+ module Evaluation
3
+ class ModuleObject < NamespaceObject
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,94 @@
1
+ module Inch
2
+ module Evaluation
3
+ # a namespace object can have methods and other namespace objects
4
+ # inside itself (e.g. classes and modules)
5
+ class NamespaceObject < Base
6
+ DOC_SCORE = MAX_SCORE
7
+ EXAMPLE_SCORE = 10
8
+ MULTIPLE_EXAMPLES_SCORE = 20
9
+
10
+ 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
+ %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
+
13
+ def evaluate
14
+ eval_doc
15
+ eval_children
16
+ 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?
32
+ add_role Role::Object::Public.new(object)
33
+ end
34
+ if object.protected?
35
+ add_role Role::Object::Protected.new(object)
36
+ end
37
+ if object.private?
38
+ add_role Role::Object::Private.new(object)
39
+ end
40
+
41
+ eval_core
42
+ end
43
+
44
+ private
45
+
46
+ def eval_core
47
+ if RUBY_CORE.include?(object.path)
48
+ add_role Role::Namespace::Core.new(object)
49
+ end
50
+ end
51
+
52
+ def eval_doc
53
+ if object.has_doc?
54
+ add_role Role::Object::WithDoc.new(object, DOC_SCORE)
55
+ else
56
+ add_role Role::Object::WithoutDoc.new(object, DOC_SCORE)
57
+ end
58
+ end
59
+
60
+ def eval_code_example
61
+ if object.has_code_example?
62
+ if object.has_multiple_code_examples?
63
+ add_role Role::Object::WithMultipleCodeExamples.new(object, MULTIPLE_EXAMPLES_SCORE)
64
+ else
65
+ add_role Role::Object::WithCodeExample.new(object, EXAMPLE_SCORE)
66
+ end
67
+ else
68
+ add_role Role::Object::WithoutCodeExample.new(object, EXAMPLE_SCORE)
69
+ end
70
+ end
71
+
72
+ def eval_children
73
+ if children.empty?
74
+ add_role Role::Namespace::WithoutChildren.new(object)
75
+ else
76
+ add_role Role::Namespace::WithChildren.new(object, children.map(&:score).min)
77
+ if object.pure_namespace?
78
+ add_role Role::Namespace::Pure.new(object)
79
+ end
80
+ if object.no_methods?
81
+ add_role Role::Namespace::WithoutMethods.new(object)
82
+ end
83
+ if object.has_many_children?
84
+ add_role Role::Namespace::WithManyChildren.new(object)
85
+ end
86
+ end
87
+ end
88
+
89
+ def children
90
+ @children ||= object.children.map(&:evaluation)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,49 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ class Base
5
+ attr_reader :object
6
+
7
+ def initialize(object, value = nil)
8
+ @object = object
9
+ @value = value
10
+ end
11
+
12
+ # Override this method to that a max_score for the evaluation.
13
+ def max_score
14
+ end
15
+
16
+ # Override this method to that a min_score for the evaluation.
17
+ def min_score
18
+ end
19
+
20
+ # Returns a score that will be added to the associated object's
21
+ # overall score.
22
+ #
23
+ # Override this method to that a score for the role.
24
+ def score
25
+ @value.to_f
26
+ end
27
+
28
+ # @return [Float]
29
+ # a score that can be achieved by adding the missing thing mentioned
30
+ # by the role
31
+ def potential_score
32
+ nil
33
+ end
34
+
35
+ def priority
36
+ 0
37
+ end
38
+
39
+ def suggestion
40
+ nil
41
+ end
42
+
43
+ def object_type
44
+ object.class.to_s.split('::').last.gsub(/Object$/, '').downcase
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ module Constant
5
+ class WithDoc < Object::WithDoc
6
+ end
7
+ class WithoutDoc < Object::WithoutDoc
8
+ end
9
+
10
+ class TaggedAsNodoc < Object::TaggedAsNodoc
11
+ end
12
+ class InRoot < Object::InRoot
13
+ end
14
+
15
+ class Public < Object::Public
16
+ def priority
17
+ -1
18
+ end
19
+ end
20
+ class Protected < Object::Protected
21
+ def priority
22
+ -2
23
+ end
24
+ end
25
+ class Private < Object::Private
26
+ def priority
27
+ -3
28
+ end
29
+ end
30
+
31
+ class WithCodeExample < Object::WithCodeExample
32
+ end
33
+ class WithMultipleCodeExamples < Object::WithMultipleCodeExamples
34
+ end
35
+ class WithoutCodeExample < Object::WithoutCodeExample
36
+ def suggestion
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,60 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ module Method
5
+ class WithoutParameters < Base
6
+ end
7
+ class WithManyParameters < Base
8
+ # +priority
9
+ def priority
10
+ +2
11
+ end
12
+ end
13
+ class WithManyLines < Base
14
+ # +priority
15
+ def priority
16
+ +2
17
+ end
18
+ end
19
+ class WithBangName < Base
20
+ # +priority
21
+ def priority
22
+ +3
23
+ end
24
+ end
25
+ class HasAlias < Base
26
+ # +priority
27
+ def priority
28
+ +2
29
+ end
30
+ end
31
+
32
+ class WithReturnType < Base
33
+ end
34
+ class WithoutReturnType < Missing
35
+ def suggestion
36
+ "Describe the return type of '#{object.name}'"
37
+ end
38
+ end
39
+
40
+ class Overridden < Base
41
+ # It seems more important to document the overridden method,
42
+ # than the overriding one
43
+ def priority
44
+ -2
45
+ end
46
+
47
+ # This role doesnot assign a score.
48
+ def score
49
+ nil
50
+ end
51
+
52
+ # This role sets a min_score.
53
+ def min_score
54
+ @value.to_f
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ module MethodParameter
5
+ class WithMention < Base
6
+ end
7
+ class WithoutMention < Missing
8
+ def suggestion
9
+ "Describe the parameter '#{object.name}'"
10
+ end
11
+ end
12
+
13
+ class WithType < Base
14
+ end
15
+ class WithoutType < Missing
16
+ end
17
+
18
+ class Splat < Base
19
+ def priority
20
+ +1
21
+ end
22
+ end
23
+ class Block < Base
24
+ def priority
25
+ +1
26
+ end
27
+ end
28
+
29
+ class WithWrongMention < Missing
30
+ def suggestion
31
+ "The parameter '#{object.name}' seems not to be part of the signature."
32
+ end
33
+ def priority
34
+ +1
35
+ end
36
+ end
37
+ class WithBadName < Base
38
+ # +priority
39
+ def priority
40
+ +1
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ # Missing is the base class for things that can be improved in the doc
5
+ #
6
+ class Missing < Base
7
+ def score
8
+ nil
9
+ end
10
+
11
+ # @return [Float]
12
+ # a score that can be achieved by adding the missing thing mentioned
13
+ # by the role
14
+ def potential_score
15
+ @value.to_f
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end