inch 0.2.2 → 0.2.3

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +170 -56
  3. data/TODOS.md +0 -6
  4. data/config/defaults.rb +82 -0
  5. data/lib/inch/cli/command/base.rb +9 -0
  6. data/lib/inch/cli/command/base_list.rb +8 -8
  7. data/lib/inch/cli/command/base_object.rb +1 -1
  8. data/lib/inch/cli/command/list.rb +6 -1
  9. data/lib/inch/cli/command/options/base.rb +1 -1
  10. data/lib/inch/cli/command/options/suggest.rb +3 -1
  11. data/lib/inch/cli/command/output/list.rb +6 -6
  12. data/lib/inch/cli/command/output/show.rb +3 -3
  13. data/lib/inch/cli/command/output/stats.rb +52 -33
  14. data/lib/inch/cli/command/output/suggest.rb +7 -7
  15. data/lib/inch/cli/command/show.rb +5 -0
  16. data/lib/inch/cli/command/stats.rb +6 -1
  17. data/lib/inch/cli/command/suggest.rb +31 -12
  18. data/lib/inch/cli/command.rb +7 -14
  19. data/lib/inch/cli/command_parser.rb +2 -9
  20. data/lib/inch/cli/sparkline_helper.rb +13 -13
  21. data/lib/inch/cli/weighted_list.rb +85 -0
  22. data/lib/inch/cli.rb +2 -1
  23. data/lib/inch/code_object/nodoc_helper.rb +2 -0
  24. data/lib/inch/code_object/proxy/base.rb +36 -13
  25. data/lib/inch/code_object/proxy/method_object.rb +29 -0
  26. data/lib/inch/code_object/proxy/namespace_object.rb +6 -0
  27. data/lib/inch/config.rb +30 -37
  28. data/lib/inch/evaluation/base.rb +53 -1
  29. data/lib/inch/evaluation/constant_object.rb +8 -11
  30. data/lib/inch/evaluation/file.rb +1 -1
  31. data/lib/inch/evaluation/grade.rb +41 -0
  32. data/lib/inch/evaluation/grade_list.rb +32 -0
  33. data/lib/inch/evaluation/method_object.rb +10 -51
  34. data/lib/inch/evaluation/namespace_object.rb +8 -49
  35. data/lib/inch/evaluation/{criteria.rb → object_schema.rb} +12 -22
  36. data/lib/inch/evaluation/read_write_methods.rb +21 -0
  37. data/lib/inch/evaluation/role/method.rb +8 -0
  38. data/lib/inch/evaluation.rb +5 -2
  39. data/lib/inch/version.rb +1 -1
  40. data/lib/inch.rb +3 -1
  41. data/test/fixtures/simple/lib/broken.rb +15 -0
  42. data/test/fixtures/simple/lib/role_methods.rb +15 -0
  43. data/test/inch/cli/weighted_list_test.rb +55 -0
  44. data/test/inch/code_object/proxy/method_object_test.rb +42 -0
  45. data/test/integration/stats_options_test.rb +1 -1
  46. metadata +11 -5
  47. data/lib/inch/evaluation/score_range.rb +0 -38
data/lib/inch/config.rb CHANGED
@@ -1,53 +1,46 @@
1
1
  module Inch
2
- module Evaluation
3
-
4
- ConstantObject.criteria do
5
- docstring 1.0
6
-
7
- # optional:
8
- unconsidered_tag 0.2
2
+ class Config
3
+ class << self
4
+ attr_accessor :instance
5
+
6
+ def run(&block)
7
+ self.instance ||= new
8
+ instance.update(&block)
9
+ instance
10
+ end
9
11
  end
10
12
 
11
- ClassObject.criteria do
12
- docstring 1.0
13
-
14
- # optional:
15
- code_example_single 0.1
16
- code_example_multi 0.2
17
- unconsidered_tag 0.2
13
+ def update(&block)
14
+ instance_eval(&block)
18
15
  end
19
16
 
20
- ModuleObject.criteria do
21
- docstring 1.0
17
+ def development?
18
+ @development
19
+ end
22
20
 
23
- # optional:
24
- code_example_single 0.1
25
- code_example_multi 0.2
26
- unconsidered_tag 0.2
21
+ def development!
22
+ @development = true
27
23
  end
28
24
 
29
- MethodObject.criteria do
30
- docstring 0.5
31
- parameters 0.4
32
- return_type 0.1
33
- return_description 0.3
25
+ def evaluation(&block)
26
+ @evaluation ||= Evaluation.new
27
+ @evaluation.update(&block) if block
28
+ @evaluation
29
+ end
34
30
 
35
- if object.constructor? || object.questioning_name?
36
- parameters parameters + return_type
37
- return_type 0.0
31
+ class Evaluation
32
+ def update(&block)
33
+ instance_eval(&block)
38
34
  end
39
35
 
40
- unless object.has_parameters?
41
- return_description docstring + parameters
42
- docstring docstring + parameters
43
- parameters 0.0
36
+ def grade(symbol, &block)
37
+ ::Inch::Evaluation::Grade.grade(symbol, &block)
44
38
  end
45
39
 
46
- # optional:
47
- code_example_single 0.1
48
- code_example_multi 0.25
49
- unconsidered_tag 0.2
40
+ def schema(constant_name, &block)
41
+ constant = eval("::Inch::Evaluation::#{constant_name}")
42
+ constant.criteria(&block)
43
+ end
50
44
  end
51
-
52
45
  end
53
46
  end
@@ -79,7 +79,7 @@ module Inch
79
79
  # @return [void]
80
80
  def criteria(&block)
81
81
  @criteria_map ||= {}
82
- @criteria_map[to_s] ||= Criteria.new(&block)
82
+ @criteria_map[to_s] ||= ObjectSchema.new(&block)
83
83
  end
84
84
  end
85
85
 
@@ -97,6 +97,58 @@ module Inch
97
97
  end
98
98
  end
99
99
 
100
+ def eval_visibility
101
+ if object.in_root?
102
+ add_role Role::Object::InRoot.new(object)
103
+ end
104
+ if object.public?
105
+ add_role Role::Object::Public.new(object)
106
+ end
107
+ if object.protected?
108
+ add_role Role::Object::Protected.new(object)
109
+ end
110
+ if object.private?
111
+ add_role Role::Object::Private.new(object)
112
+ end
113
+ end
114
+
115
+ def eval_doc
116
+ if object.has_doc?
117
+ add_role Role::Object::WithDoc.new(object, score_for(:docstring))
118
+ else
119
+ add_role Role::Object::WithoutDoc.new(object, score_for(:docstring))
120
+ end
121
+ if object.nodoc?
122
+ add_role Role::Object::TaggedAsNodoc.new(object)
123
+ end
124
+ end
125
+
126
+ def eval_code_example
127
+ if object.has_code_example?
128
+ if object.has_multiple_code_examples?
129
+ add_role Role::Object::WithMultipleCodeExamples.new(object, score_for(:code_example_multi))
130
+ else
131
+ add_role Role::Object::WithCodeExample.new(object, score_for(:code_example_single))
132
+ end
133
+ else
134
+ add_role Role::Object::WithoutCodeExample.new(object, score_for(:code_example_single))
135
+ end
136
+ end
137
+
138
+ def eval_tags
139
+ if object.api_tag?
140
+ if object.private_api_tag?
141
+ add_role Role::Object::TaggedAsPrivateAPI.new(object)
142
+ else
143
+ add_role Role::Object::TaggedAsAPI.new(object)
144
+ end
145
+ end
146
+ if object.has_unconsidered_tags?
147
+ count = object.unconsidered_tags.size
148
+ add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
149
+ end
150
+ end
151
+
100
152
  def score_for(criteria_name)
101
153
  criteria.send(criteria_name) * MAX_SCORE
102
154
  end
@@ -2,6 +2,11 @@ module Inch
2
2
  module Evaluation
3
3
  class ConstantObject < Base
4
4
  def evaluate
5
+ eval_doc
6
+ eval_visibility
7
+ end
8
+
9
+ def eval_doc
5
10
  if object.has_doc?
6
11
  add_role Role::Constant::WithDoc.new(object, score_for(:docstring))
7
12
  else
@@ -10,17 +15,9 @@ module Inch
10
15
  if object.nodoc?
11
16
  add_role Role::Constant::TaggedAsNodoc.new(object)
12
17
  end
13
- if object.api_tag?
14
- if object.private_api_tag?
15
- add_role Role::Object::TaggedAsPrivateAPI.new(object)
16
- else
17
- add_role Role::Object::TaggedAsAPI.new(object)
18
- end
19
- end
20
- if object.has_unconsidered_tags?
21
- count = object.unconsidered_tags.size
22
- add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
23
- end
18
+ end
19
+
20
+ def eval_visibility
24
21
  if object.in_root?
25
22
  add_role Role::Constant::InRoot.new(object)
26
23
  end
@@ -21,7 +21,7 @@ module Inch
21
21
  #
22
22
 
23
23
  def grade
24
- median(grades.sort)
24
+ median(grades.sort_by(&:to_sym))
25
25
  end
26
26
 
27
27
  def priority
@@ -0,0 +1,41 @@
1
+ module Inch
2
+ module Evaluation
3
+ class Grade
4
+ extend Evaluation::ReadWriteMethods
5
+
6
+ rw_methods %w(scores label color bg_color)
7
+
8
+ def initialize(symbol)
9
+ @symbol = symbol
10
+ end
11
+
12
+ def update(&block)
13
+ instance_eval(&block)
14
+ end
15
+
16
+ def to_sym
17
+ @symbol
18
+ end
19
+
20
+ def to_s
21
+ @symbol.to_s
22
+ end
23
+
24
+ class << self
25
+ attr_reader :grade_map
26
+
27
+ def all
28
+ @grade_map ||= {}
29
+ @grade_map.values
30
+ end
31
+
32
+ def grade(symbol, &block)
33
+ @grade_map ||= {}
34
+ @grade_map[symbol] ||= Grade.new(symbol)
35
+ @grade_map[symbol].update(&block) if block
36
+ @grade_map[symbol]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,32 @@
1
+ module Inch
2
+ module Evaluation
3
+ # These objects associate a grade with a group of objects
4
+ #
5
+ # @see .new_grade_lists
6
+ class GradeList < Struct.new(:grade)
7
+ extend Forwardable
8
+
9
+ def_delegators :grade, :scores, :label, :color, :bg_color,
10
+ :to_s, :to_sym
11
+
12
+ # Returns code_objects that received a score with the defined +scores+
13
+ attr_reader :objects
14
+
15
+ # Assigns code_objects that received a score with the defined +scores+
16
+ #
17
+ # @param arr [Array<CodeObject::Proxy::Base>]
18
+ # @return [Array<CodeObject::Proxy::Base>]
19
+ def objects=(arr)
20
+ arr.each { |o| o.grade = grade }
21
+ @objects = arr
22
+ end
23
+ end
24
+
25
+ # Returns newly instanciated grade range objects
26
+ #
27
+ # @return [Array<GradeList>]
28
+ def self.new_grade_lists
29
+ Evaluation::Grade.all.map { |g| GradeList.new(g) }
30
+ end
31
+ end
32
+ end
@@ -3,39 +3,27 @@ module Inch
3
3
  class MethodObject < Base
4
4
  def evaluate
5
5
  eval_doc
6
+ eval_code_example
7
+ eval_visibility
8
+ eval_tags
9
+
6
10
  eval_parameters
7
11
  eval_return_type
8
- eval_code_example
9
12
  eval_method
10
- eval_misc
11
13
  end
12
14
 
13
15
  private
14
16
 
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
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
17
  def eval_method
36
18
  if object.constructor?
37
19
  add_role Role::Method::Constructor.new(object)
38
20
  end
21
+ if object.getter?
22
+ add_role Role::Method::Getter.new(object)
23
+ end
24
+ if object.setter?
25
+ add_role Role::Method::Setter.new(object)
26
+ end
39
27
  if object.overridden?
40
28
  add_role Role::Method::Overridden.new(object, object.overridden_method.score)
41
29
  end
@@ -53,35 +41,6 @@ module Inch
53
41
  end
54
42
  end
55
43
 
56
- def eval_misc
57
- if object.nodoc?
58
- add_role Role::Object::TaggedAsNodoc.new(object)
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
67
- if object.has_unconsidered_tags?
68
- count = object.unconsidered_tags.size
69
- add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
70
- end
71
- if object.in_root?
72
- add_role Role::Object::InRoot.new(object)
73
- end
74
- if object.public?
75
- add_role Role::Object::Public.new(object)
76
- end
77
- if object.protected?
78
- add_role Role::Object::Protected.new(object)
79
- end
80
- if object.private?
81
- add_role Role::Object::Private.new(object)
82
- end
83
- end
84
-
85
44
  def eval_parameters
86
45
  if object.has_parameters?
87
46
  eval_all_parameters
@@ -8,37 +8,22 @@ module Inch
8
8
 
9
9
  def evaluate
10
10
  eval_doc
11
- eval_children
12
11
  eval_code_example
13
- eval_misc
14
- eval_core
12
+ eval_visibility
13
+ eval_tags
14
+
15
+ eval_children
16
+ eval_namespace
15
17
  end
16
18
 
17
19
  private
18
20
 
19
- def eval_core
21
+ def eval_namespace
20
22
  if RUBY_CORE.include?(object.path)
21
23
  add_role Role::Namespace::Core.new(object)
22
24
  end
23
- end
24
-
25
- def eval_code_example
26
- if object.has_code_example?
27
- if object.has_multiple_code_examples?
28
- add_role Role::Object::WithMultipleCodeExamples.new(object, score_for(:code_example_multi))
29
- else
30
- add_role Role::Object::WithCodeExample.new(object, score_for(:code_example_single))
31
- end
32
- else
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))
25
+ if object.has_many_attributes?
26
+ add_role Role::Namespace::WithManyAttributes.new(object)
42
27
  end
43
28
  end
44
29
 
@@ -59,32 +44,6 @@ module Inch
59
44
  end
60
45
  end
61
46
 
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
-
88
47
  def children
89
48
  @children ||= object.children.map(&:evaluation)
90
49
  end
@@ -1,18 +1,9 @@
1
1
  module Inch
2
2
  module Evaluation
3
- class Criteria
4
- attr_reader :object
5
-
6
- def initialize(&block)
7
- @block = block
8
- end
9
-
10
- def evaluate(object)
11
- @object = object
12
- instance_eval(&@block)
13
- end
3
+ class ObjectSchema
4
+ extend Evaluation::ReadWriteMethods
14
5
 
15
- NAMES = %w(
6
+ rw_methods %w(
16
7
  docstring
17
8
  parameters
18
9
  return_type
@@ -22,16 +13,15 @@ module Inch
22
13
  unconsidered_tag
23
14
  )
24
15
 
25
- NAMES.each do |name|
26
- class_eval """
27
- def #{name}(value = nil)
28
- if value.nil?
29
- @#{name}.to_f
30
- else
31
- @#{name} = value
32
- end
33
- end
34
- """
16
+ attr_reader :object
17
+
18
+ def initialize(&block)
19
+ @block = block
20
+ end
21
+
22
+ def evaluate(object)
23
+ @object = object
24
+ instance_eval(&@block)
35
25
  end
36
26
  end
37
27
  end
@@ -0,0 +1,21 @@
1
+ module Inch
2
+ module Evaluation
3
+ module ReadWriteMethods
4
+ def rw_method(name)
5
+ class_eval """
6
+ def #{name}(value = nil)
7
+ if value.nil?
8
+ @#{name}
9
+ else
10
+ @#{name} = value
11
+ end
12
+ end
13
+ """
14
+ end
15
+
16
+ def rw_methods(*names)
17
+ [names].flatten.each { |name| rw_method(name) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -72,6 +72,14 @@ module Inch
72
72
  class Constructor < Base
73
73
  end
74
74
 
75
+ # Role assigned to methods that are getters
76
+ class Getter < Base
77
+ end
78
+
79
+ # Role assigned to methods that are setters
80
+ class Setter < Base
81
+ end
82
+
75
83
  # Role assigned to methods that are overriding another method
76
84
  class Overridden < Base
77
85
  # It seems more important to document the overridden method,
@@ -13,9 +13,12 @@ module Inch
13
13
  end
14
14
  end
15
15
 
16
- require_relative 'evaluation/criteria'
16
+ require_relative 'evaluation/read_write_methods'
17
+
17
18
  require_relative 'evaluation/file'
18
- require_relative 'evaluation/score_range'
19
+ require_relative 'evaluation/grade'
20
+ require_relative 'evaluation/grade_list'
21
+ require_relative 'evaluation/object_schema'
19
22
 
20
23
  require_relative 'evaluation/role/base'
21
24
  require_relative 'evaluation/role/missing'
data/lib/inch/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Inch
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
data/lib/inch.rb CHANGED
@@ -7,5 +7,7 @@ require_relative 'inch/core_ext'
7
7
  require_relative 'inch/source_parser'
8
8
  require_relative 'inch/code_object'
9
9
  require_relative 'inch/evaluation'
10
- require_relative 'inch/config'
11
10
  require_relative 'inch/cli'
11
+
12
+ require_relative 'inch/config'
13
+ require File.join(File.dirname(__FILE__), '..', 'config', 'defaults.rb')
@@ -8,3 +8,18 @@ module Foo
8
8
 
9
9
  end
10
10
  end
11
+
12
+ module YardError
13
+ if defined? ::Deprecate
14
+ Deprecate = ::Deprecate
15
+ elsif defined? Gem::Deprecate
16
+ Deprecate = Gem::Deprecate
17
+ else
18
+ class Deprecate; end
19
+ end
20
+
21
+ unless Deprecate.respond_to?(:skip_during)
22
+ def Deprecate.skip_during; yield; end
23
+ end
24
+
25
+ end
@@ -2,6 +2,21 @@ def root_method
2
2
  end
3
3
 
4
4
  module InchTest
5
+ attr_accessor :attr_getset
6
+
7
+ def manual_getset
8
+ end
9
+
10
+ def manual_getset=(val)
11
+ end
12
+
13
+ attr_reader :getter
14
+
15
+ def manual_setter=(val)
16
+ end
17
+
18
+ attr_writer :attr_setter
19
+
5
20
  def bang_method!
6
21
  end
7
22
 
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ describe ::Inch::CLI::WeightedList do
4
+ before do
5
+ @counts = [4, 8, 8]
6
+ end
7
+
8
+ def assert_weighted_list(list, counts, expected)
9
+ weighted_list = ::Inch::CLI::WeightedList.new(list, counts)
10
+ # assert_equal expected.map(&:size).inject(:+), weighted_list.to_a.map(&:size).inject(:+)
11
+ assert_equal expected, weighted_list.to_a, "should be #{expected.map(&:size)}, was #{weighted_list.to_a.map(&:size)}"
12
+ end
13
+
14
+ def list_and_expected(counts, expected_counts)
15
+ elements = [:B, :C, :U]
16
+ list = counts.map.with_index do |num, index|
17
+ (1..num).map { |i| :"#{elements[index]}#{i}" }
18
+ end
19
+ expected = expected_counts.map.with_index do |num, index|
20
+ (1..num).map { |i| :"#{elements[index]}#{i}" }
21
+ end
22
+ return list, expected
23
+ end
24
+
25
+ it "should work if elements are exact" do
26
+ @list, @expected = list_and_expected([4, 8, 8], [4, 8, 8])
27
+ assert_weighted_list(@list, @counts, @expected)
28
+ end
29
+
30
+ it "should work if more than enough elements are present" do
31
+ @list, @expected = list_and_expected([10, 10, 10], [4, 8, 8])
32
+ assert_weighted_list(@list, @counts, @expected)
33
+ end
34
+
35
+ it "should work if not enough Bs are present" do
36
+ @list, @expected = list_and_expected([2, 12, 15], [2, 8, 10])
37
+ assert_weighted_list(@list, @counts, @expected)
38
+ end
39
+
40
+ it "should work if not enough Cs are present" do
41
+ @list, @expected = list_and_expected([15, 4, 15], [4, 4, 12])
42
+ assert_weighted_list(@list, @counts, @expected)
43
+ end
44
+
45
+ it "should work if not enough Us are present" do
46
+ @list, @expected = list_and_expected([15, 15, 4], [4, 12, 4])
47
+ assert_weighted_list(@list, @counts, @expected)
48
+ end
49
+
50
+ it "should work if not enough Bs AND Cs and Us are present" do
51
+ @list, @expected = list_and_expected([2, 2, 15], [2, 2, 15])
52
+ assert_weighted_list(@list, @counts, @expected)
53
+ end
54
+
55
+ end