inch 0.2.2 → 0.2.3

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