mentor 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d61b738e627b884222d11ae5e7e01b717a4b473
4
- data.tar.gz: 30b3b83534080ed8a0da9eb9d32ba11dde4c6b01
3
+ metadata.gz: 5a40f1afb1c3314adb1e36dcbee0fc5c2f77a40f
4
+ data.tar.gz: e4e66cb1e08473200b9d56cff9dab28b2b60fe83
5
5
  SHA512:
6
- metadata.gz: 974dea0e3cf08d028480c1e4925df058fee38583c7a115d7a83d39bc8b09e6467f8371d47110913f5ed9c5c8655ba8666b84561b86ecabd86625b7756f9fa2a0
7
- data.tar.gz: 8b8e7aa5f94c8c3b186c05d5bcc7f5013623b16dd2d6754e059d340197e4134861501729e9b0c5a197aacbffd5342bc6e0d6afc812209488c2252ed685c5ba88
6
+ metadata.gz: 861f06ddef0003bc3daa96b8da8fc8736eb74a79779c03c34b5d3f31339a5220998fb288d4d951ad9599e87d10caad965278a43f0333f7d30c800e73b8e55df6
7
+ data.tar.gz: fcba8b0493d472f9556b6f977b24409fe5a6054da1aeff62434e8de832faeb8e6363b38f611cb9f7fe6ce00ba2bfb20a8da1d04eba9339e72bb611c50cacc699
@@ -0,0 +1,7 @@
1
+ require 'warning'
2
+ Warning.ignore(/gems\/rouge/)
3
+ Warning.ignore(/gems\/awesome_print/)
4
+ Warning.ignore(/instance variable @lines_from_file not initialized/)
5
+ Warning.ignore(/previous definition of output_value was here/)
6
+ Warning.ignore(/irb\/ext\/save-history/)
7
+ Warning.ignore(/irb\/extend-command/)
@@ -20,10 +20,10 @@ module Mentor
20
20
  end
21
21
  end
22
22
 
23
- private_class_method
24
-
25
23
  def self.error_classes
26
24
  [
25
+ NoMethodDidYouMeanStringLiteralError,
26
+ NoMethodDidYouMeanNumericLiteralError,
27
27
  NoMethodDidYouMeanSuggestionError,
28
28
  NoMethodForNilClassForCommonClassError,
29
29
  NoMethodForNilClassError,
@@ -0,0 +1,38 @@
1
+ module Mentor
2
+
3
+ class NoMethodDidYouMeanNumericLiteralError < MentorNoMethodError
4
+
5
+ def self.can_handle?
6
+ super &&
7
+ Mentor.tp.raised_exception.respond_to?(:corrections) &&
8
+ Mentor.tp.raised_exception.corrections.any? &&
9
+ var_for_method.empty? &&
10
+ [Integer, Float].include?(Mentor.tp.raised_exception.receiver.class)
11
+ end
12
+
13
+ def sections
14
+ [
15
+ Header.new,
16
+ RubyErrorComplete.new,
17
+ RelativePath.new,
18
+ LinesOfCode.new,
19
+ ErrorClassSpecificHelp.new(error_class_specific_help),
20
+ Suggestion.new("Try changing the method #{method_name} to #{did_you_mean_word} on your #{literal_class}.")
21
+ ]
22
+ end
23
+
24
+ private
25
+
26
+ def error_class_specific_help
27
+ [
28
+ "#{literal_for_method} is #{a_an(literal_class)} #{literal_class}.",
29
+ '',
30
+ "#{pluralize(literal_class)} do not have the method #{method_name}.",
31
+ '',
32
+ 'You may have made a typo.'
33
+ ]
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,38 @@
1
+ module Mentor
2
+
3
+ class NoMethodDidYouMeanStringLiteralError < MentorNoMethodError
4
+
5
+ def self.can_handle?
6
+ super &&
7
+ Mentor.tp.raised_exception.respond_to?(:corrections) &&
8
+ Mentor.tp.raised_exception.corrections.any? &&
9
+ var_for_method.empty? &&
10
+ Mentor.tp.raised_exception.receiver.is_a?(String)
11
+ end
12
+
13
+ def sections
14
+ [
15
+ Header.new,
16
+ RubyErrorComplete.new,
17
+ RelativePath.new,
18
+ LinesOfCode.new,
19
+ ErrorClassSpecificHelp.new(error_class_specific_help),
20
+ Suggestion.new("Try changing the method #{method_name} to #{did_you_mean_word} on your #{literal_class}.")
21
+ ]
22
+ end
23
+
24
+ private
25
+
26
+ def error_class_specific_help
27
+ [
28
+ "#{quoted_literal_for_method} is #{a_an(literal_class)} #{literal_class}.",
29
+ '',
30
+ "#{pluralize(literal_class)} do not have the method #{method_name}.",
31
+ '',
32
+ 'You may have made a typo.'
33
+ ]
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -47,7 +47,6 @@ module Mentor
47
47
  end
48
48
  end
49
49
 
50
- private_class_method
51
50
 
52
51
  @@string_methods = String.new.methods
53
52
  @@integer_methods = 1.methods
@@ -69,6 +68,8 @@ module Mentor
69
68
  common_classes.map { |klass, attrs| attrs[:methods] }.flatten - Object.methods
70
69
  end
71
70
 
71
+ private_class_method :common_methods
72
+
72
73
  end
73
74
 
74
75
  end
@@ -31,24 +31,32 @@ module Mentor
31
31
 
32
32
  def output_types
33
33
  %i[
34
- did_you_mean_text did_you_mean_word
35
- message horizontal_line ruby_error_text
36
- calling_method method_name var_for_method
37
- absolute_base_dir relative_base_dir app_dir file_name
34
+ did_you_mean_text did_you_mean_word
35
+ message horizontal_line ruby_error_text
36
+ calling_method method_name var_for_method
37
+ absolute_base_dir relative_base_dir app_dir file_name
38
38
  ]
39
39
  end
40
40
 
41
41
  def apply_colors(line)
42
+ line = apply_literal_for_method(line) if did_you_mean_with_literal_error?
42
43
  line = apply_pattern_colors(line)
43
44
  line = apply_output_colors(line)
44
45
  line = apply_nil_colors(line)
45
46
  line = apply_common_classes_colors(line)
46
47
  end
47
48
 
49
+ def apply_literal_for_method(line)
50
+ line = TextToColor.new(line, literal_for_method, :literal_for_method, "#{literal_for_method} is a").color_pattern
51
+ line = TextToColor.new(line, literal_for_method, :literal_for_method, "for #{literal_for_method}:").color_pattern
52
+ line = TextToColor.new(line, literal_for_method, :literal_for_method, %Q{"#{literal_for_method}"}).color_pattern
53
+ line = TextToColor.new(line, literal_for_method, :literal_for_method, "'#{literal_for_method}'").color_pattern
54
+ end
55
+
48
56
  def apply_pattern_colors(line)
49
- line = TextToColor.new(line, error_lineno, :error_lineno, "#{file_name}:#{error_lineno}").color_pattern
50
- line = TextToColor.new(line, ruby_error_class, :ruby_error_class, "(#{ruby_error_class})").color_pattern
51
- line = TextToColor.new(line, ruby_error_class, :ruby_error_class, " #{ruby_error_class} ").color_pattern
57
+ line = TextToColor.new(line, error_lineno, :error_lineno, "#{file_name}:#{error_lineno}").color_pattern
58
+ line = TextToColor.new(line, ruby_error_class, :ruby_error_class, "(#{ruby_error_class})").color_pattern
59
+ line = TextToColor.new(line, ruby_error_class, :ruby_error_class, " #{ruby_error_class} ").color_pattern
52
60
  end
53
61
 
54
62
  def apply_output_colors(line)
@@ -76,9 +84,13 @@ module Mentor
76
84
  end
77
85
 
78
86
  def color_code(code)
79
- formatter = Rouge::Formatters::Terminal256.new
80
- lexer = Rouge::Lexers::Ruby.new
81
- formatter.format(lexer.lex(code))
87
+ if did_you_mean_with_literal_error?
88
+ TextToColor.new(code, literal_for_method, :literal_for_method).colored
89
+ else
90
+ formatter = Rouge::Formatters::Terminal256.new
91
+ lexer = Rouge::Lexers::Ruby.new
92
+ formatter.format(lexer.lex(code))
93
+ end
82
94
  end
83
95
 
84
96
  def color_padded_lineno(padded_lineno)
@@ -99,6 +111,12 @@ module Mentor
99
111
  Rainbow(str).color(colors[output_type])
100
112
  end
101
113
 
114
+ def did_you_mean_with_literal_error?
115
+ Mentor.tp.raised_exception.respond_to?(:corrections) &&
116
+ Mentor.tp.raised_exception.corrections.any? &&
117
+ [String, Integer, Float].include?(Mentor.tp.raised_exception.receiver.class)
118
+ end
119
+
102
120
  def colors
103
121
  error = :tomato
104
122
  error_lineno = :gold
@@ -106,32 +124,35 @@ module Mentor
106
124
  subtle = :olive
107
125
  very_subtle = :dimgray
108
126
  nil_text = :orange
127
+ literal = :mediumpurple
109
128
 
110
129
  {
111
- app_dir: subtle,
112
- backtrace_line: very_subtle,
113
- absolute_base_dir: subtle,
114
- relative_base_dir: subtle,
115
- calling_method: :green,
116
- common_class: :wheat,
117
- did_you_mean_text: :royalblue,
118
- did_you_mean_word: method_name,
119
- error_lineno: error_lineno,
120
- error_lineno_padded: error_lineno,
121
- file_name: :greenyellow,
122
- horizontal_line: :red,
123
- lineno_subtle_padded: subtle,
124
- message: error,
125
- method_class: :mediumpurple,
126
- method_name: method_name,
127
- nil_text: nil_text,
128
- other_class_or_module: :darksalmon,
129
- prominent: :ivory,
130
- ruby_error_class: :orangered,
131
- ruby_error_text: error,
132
- subtle: subtle,
133
- suggestion: :lightgreen,
134
- var_for_method: :palevioletred
130
+ app_dir: subtle,
131
+ backtrace_line: very_subtle,
132
+ absolute_base_dir: subtle,
133
+ relative_base_dir: subtle,
134
+ calling_method: :green,
135
+ common_class: :cornflower,
136
+ did_you_mean_text: :royalblue,
137
+ did_you_mean_word: method_name,
138
+ error_lineno: error_lineno,
139
+ error_lineno_padded: error_lineno,
140
+ file_name: :greenyellow,
141
+ horizontal_line: :red,
142
+ lineno_subtle_padded: subtle,
143
+ message: error,
144
+ method_class: :mediumpurple,
145
+ method_name: method_name,
146
+ nil_text: nil_text,
147
+ other_class_or_module: :darksalmon,
148
+ prominent: :ivory,
149
+ ruby_error_class: :orangered,
150
+ literal_for_method: literal,
151
+ quoted_literal_for_method: literal,
152
+ ruby_error_text: error,
153
+ subtle: subtle,
154
+ suggestion: :lightgreen,
155
+ var_for_method: :palevioletred
135
156
  }
136
157
  end
137
158
 
@@ -6,8 +6,12 @@ module Mentor
6
6
  %w(A E I O U).include?(word[0]) ? 'an' : 'a'
7
7
  end
8
8
 
9
+ def culprit_line
10
+ lines_from_file[tp.lineno]
11
+ end
12
+
9
13
  def pluralize(word)
10
- word.to_s + (word.to_s == 'Hash' ? 'es' :'s')
14
+ word.to_s + (word.to_s == 'Hash' ? 'es' : 's')
11
15
  end
12
16
 
13
17
  def pluralize_words(words)
@@ -83,6 +83,19 @@ module Mentor
83
83
  @lineno.to_s.rjust(width)
84
84
  end
85
85
 
86
+ def literal_class
87
+ tp.raised_exception.receiver.class.to_s
88
+ end
89
+
90
+ def literal_for_method
91
+ tp.raised_exception.receiver.to_s
92
+ end
93
+
94
+ def quoted_literal_for_method
95
+ quote = culprit_line[culprit_line.index(tp.raised_exception.receiver) - 1]
96
+ quote + tp.raised_exception.receiver + quote
97
+ end
98
+
86
99
  def message
87
100
  if raised_exception.respond_to? :original_message
88
101
  raised_exception.original_message
@@ -112,7 +125,6 @@ module Mentor
112
125
  end
113
126
 
114
127
  def var_for_method
115
- culprit_line = lines_from_file[tp.lineno]
116
128
  var = culprit_line[/#{valid_var_name}\.#{method_name}/].to_s.chomp(".#{method_name}")
117
129
  if var.empty?
118
130
  culprit_line[/#{valid_var_name} method_name/].to_s.chomp(".#{method_name}")
@@ -1,5 +1,7 @@
1
1
  module Mentor
2
2
 
3
+ require_relative '../development' if ENV['MENTOR'] == 'development'
4
+
3
5
  dir = __dir__ + '/../..'
4
6
 
5
7
  gems = %w[pry rainbow rouge]
@@ -1,3 +1,3 @@
1
1
  module Mentor
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/mentor.rb CHANGED
@@ -9,8 +9,6 @@ module Mentor
9
9
  Mentor.enable
10
10
  end
11
11
 
12
- private_class_method
13
-
14
12
  def self.setup_trace_point
15
13
 
16
14
  TracePoint.trace(:raise) do |tp|
@@ -28,6 +26,8 @@ module Mentor
28
26
 
29
27
  end
30
28
 
29
+ private_class_method :setup_trace_point
30
+
31
31
  end
32
32
 
33
33
  end
data/mentor.gemspec CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.executables << 'mentor'
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'pry', '~> 0.10'
22
- spec.add_dependency 'rainbow', '~> 2.2'
23
- spec.add_dependency 'rouge', '~> 2.0'
21
+ spec.add_dependency 'pry', '~> 0.10'
22
+ spec.add_dependency 'rainbow', '~> 2.2'
23
+ spec.add_dependency 'rouge', '~> 2.0'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.13'
26
26
  spec.add_development_dependency 'did_you_mean', '~> 1.1'
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'guard-minitest', '~> 2.4'
29
29
  spec.add_development_dependency 'minitest', '~> 5.0'
30
30
  spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'warning', '~> 0.10'
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mentor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Lerner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-26 00:00:00.000000000 Z
11
+ date: 2017-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '10.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: warning
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.10'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.10'
139
153
  description:
140
154
  email:
141
155
  - sean@smallcity.ca
@@ -151,8 +165,11 @@ files:
151
165
  - README.md
152
166
  - Rakefile
153
167
  - bin/mentor
168
+ - lib/development.rb
154
169
  - lib/errors/mentor_error.rb
155
170
  - lib/errors/mentor_no_method_error.rb
171
+ - lib/errors/no_method_did_you_mean_numeric_literal.rb
172
+ - lib/errors/no_method_did_you_mean_string_literal.rb
156
173
  - lib/errors/no_method_did_you_mean_suggestion_error.rb
157
174
  - lib/errors/no_method_for_nil_class_error.rb
158
175
  - lib/errors/no_method_for_nil_class_for_common_class_error.rb