inch 0.0.1 → 0.1.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 (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