rails_best_practices 1.15.1 → 1.15.2

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: aad6be6297629a1706250552dd2dc67a88d088f4
4
- data.tar.gz: 7416b40f8860088f0ef6734f44fb7dc68531a226
3
+ metadata.gz: 16424767a639f93e65221ccb0a759de20b7ce9fa
4
+ data.tar.gz: ce5f1080da4406d14d893246af12360ada46308f
5
5
  SHA512:
6
- metadata.gz: d3ccfe6ee0f2164b49c2d00db11505d858b0750c9167d39e7e9e3da251d3d7e4a122e7601dc158efc462bcc5a422c94c65e6e02ccce95fa68ac2a787fd30eaad
7
- data.tar.gz: 1be5179a45ca10b0b5ebb3436bf56af16fcca01a35ff93d8846365eb8390bda417750945ea2c21eec659b68cbde1cfd17e67dbdbecbddb1ad2f2d4c5a337d93d
6
+ metadata.gz: 998a80e8e4399e80a8cb555ac596a2758c8beea6bd2f7e8fe13017b4a8931baa40efd2f892a899733dd94803418bdadde63069e21cd351e5dee9db49a2ce8adc
7
+ data.tar.gz: fb113c8116c5b0e575d2b6fed6e500b83bad9d96fbace45bdbfbb1eca6f5ebf77648ba1af5e16a09327e7a6eb1dc90e9a29e4b1268e9b4cfd2c8b57fe03caaaf
@@ -347,13 +347,7 @@ module RailsBestPractices
347
347
  # check if the method is in the except methods list.
348
348
  def excepted?(method)
349
349
  is_ignored?(method.file) ||
350
- except_methods.any? do |except_method|
351
- class_name, method_name = except_method.split('#')
352
- (class_name == '*' && method_name == method.method_name) ||
353
- (method_name == '*' && class_name == method.class_name) ||
354
- (method_name == '*' && class_name == Prepares.klasses.find { |klass| klass.class_name == method.class_name }.try(:extend_class_name)) ||
355
- (class_name == method.class_name && method_name == method.method_name)
356
- end
350
+ except_methods.any? { |except_method| Exceptable.matches method, except_method }
357
351
  end
358
352
 
359
353
  def internal_except_methods
@@ -361,6 +355,29 @@ module RailsBestPractices
361
355
  end
362
356
  end
363
357
  end
358
+
359
+ def self.matches method, except_method
360
+ class_name, method_name = except_method.split('#')
361
+
362
+ method_name = ".*" if method_name == "*"
363
+ method_expression = Regexp.new method_name
364
+ matched = method.method_name =~ method_expression
365
+
366
+ if matched
367
+ class_name = ".*" if class_name == "*"
368
+ class_expression = Regexp.new class_name
369
+
370
+ class_names = Prepares.klasses
371
+ .select { |klass| klass.class_name == method.class_name }
372
+ .map(&:extend_class_name)
373
+ .compact
374
+
375
+ class_names.unshift method.class_name
376
+ matched = class_names.any? { |name| name =~ class_expression }
377
+ end
378
+
379
+ !!matched
380
+ end
364
381
  end
365
382
 
366
383
  # Helper to parse the access control.
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module RailsBestPractices
3
+ module Core
4
+ class ChecksLoader
5
+ def initialize(config)
6
+ @config = config
7
+ end
8
+
9
+ # load all lexical checks.
10
+ def load_lexicals
11
+ load_checks_from_config { |check_name| RailsBestPractices::Lexicals.const_get(check_name) }
12
+ end
13
+
14
+ # load all reviews according to configuration.
15
+ def load_reviews
16
+ load_checks_from_config { |check_name| RailsBestPractices::Reviews.const_get(check_name.gsub(/Check$/, 'Review')) }
17
+ end
18
+
19
+ private
20
+ # read the checks from yaml config.
21
+ def checks_from_config
22
+ @checks ||= YAML.load_file @config
23
+ end
24
+
25
+ # load all checks from the configuration
26
+ def load_checks_from_config(&block)
27
+ checks_from_config.inject([]) do |active_checks, check|
28
+ check_instance = instantiate_check(block, *check)
29
+ active_checks << check_instance unless check_instance.nil?
30
+ active_checks
31
+ end
32
+ end
33
+
34
+ # instantiates a check
35
+ def instantiate_check(block, check_name, options)
36
+ check_class = load_check_class(check_name, &block)
37
+ check_class.new(options || {}) unless check_class.nil?
38
+ end
39
+
40
+ # loads the class for a check by calling the given block
41
+ def load_check_class(check_name, &block)
42
+ block.call(check_name)
43
+ rescue NameError
44
+ # nothing to do, the check does not exist
45
+ end
46
+ end
47
+ end
48
+ end
@@ -43,9 +43,11 @@ module RailsBestPractices
43
43
  lexicals = Array(options[:lexicals])
44
44
  prepares = Array(options[:prepares])
45
45
  reviews = Array(options[:reviews])
46
- @lexicals = lexicals.empty? ? load_lexicals : lexicals
46
+
47
+ checks_loader = ChecksLoader.new(@config)
48
+ @lexicals = lexicals.empty? ? checks_loader.load_lexicals : lexicals
47
49
  @prepares = prepares.empty? ? load_prepares : prepares
48
- @reviews = reviews.empty? ? load_reviews : reviews
50
+ @reviews = reviews.empty? ? checks_loader.load_reviews : reviews
49
51
  load_plugin_reviews if reviews.empty?
50
52
 
51
53
  @lexical_checker ||= CodeAnalyzer::CheckingVisitor::Plain.new(checkers: @lexicals)
@@ -66,7 +68,7 @@ module RailsBestPractices
66
68
  @lexical_checker.after_check
67
69
  end
68
70
 
69
- # parepare the file.
71
+ # prepare the file.
70
72
  #
71
73
  # @param [String] filename of the file
72
74
  # @param [String] content of the file
@@ -101,7 +103,7 @@ module RailsBestPractices
101
103
  end
102
104
 
103
105
  private
104
- # parse html tempalte code, erb, haml and slim.
106
+ # parse html template code, erb, haml and slim.
105
107
  #
106
108
  # @param [String] filename is the filename of the erb, haml or slim code.
107
109
  # @param [String] content is the source code of erb, haml or slim file.
@@ -132,41 +134,11 @@ module RailsBestPractices
132
134
  content
133
135
  end
134
136
 
135
- # load all lexical checks.
136
- def load_lexicals
137
- checks_from_config.inject([]) { |active_checks, check|
138
- begin
139
- check_name, options = *check
140
- klass = RailsBestPractices::Lexicals.const_get(check_name)
141
- options = Hash(options)
142
- active_checks << (options.empty? ? klass.new : klass.new(options))
143
- rescue
144
- # the check does not exist in the Lexicals namepace.
145
- end
146
- active_checks
147
- }
148
- end
149
-
150
137
  # load all prepares.
151
138
  def load_prepares
152
139
  Prepares.constants.map { |prepare| Prepares.const_get(prepare).new }
153
140
  end
154
141
 
155
- # load all reviews according to configuration.
156
- def load_reviews
157
- checks_from_config.inject([]) { |active_checks, check|
158
- begin
159
- check_name, options = *check
160
- klass = RailsBestPractices::Reviews.const_get(check_name.gsub(/Check$/, 'Review'))
161
- options = Hash(options)
162
- active_checks << (options.empty? ? klass.new : klass.new(options))
163
- rescue
164
- # the check does not exist in the Reviews namepace.
165
- end
166
- active_checks
167
- }
168
- end
169
-
170
142
  # load all plugin reviews.
171
143
  def load_plugin_reviews
172
144
  begin
@@ -183,19 +155,6 @@ module RailsBestPractices
183
155
  end
184
156
  end
185
157
  end
186
-
187
- # read the checks from yaml config.
188
- def checks_from_config
189
- @checks ||= YAML.load_file @config
190
- end
191
-
192
- # read the file content.
193
- #
194
- # @param [String] filename
195
- # @return [String] file conent
196
- def read_file(filename)
197
- File.open(filename, "r:UTF-8") { |f| f.read }
198
- end
199
158
  end
200
159
  end
201
160
  end
@@ -105,7 +105,7 @@ module RailsBestPractices
105
105
  end
106
106
 
107
107
  def internal_except_methods
108
- %w(rescue_action).map { |method_name| "*\##{method_name}" } +
108
+ %w(rescue_action default_url_options).map { |method_name| "*\##{method_name}" } +
109
109
  %w(Devise::OmniauthCallbacksController).map { |controller_name| "#{controller_name}#*" }
110
110
  end
111
111
 
@@ -29,6 +29,9 @@ module RailsBestPractices
29
29
  # check if the generated routes have the corresponding actions in controller for rails routes.
30
30
  add_callback :start_command, :start_command_call do |node|
31
31
  if "resources" == node.message.to_s
32
+ if (mod = module_option(node))
33
+ @namespaces << mod
34
+ end
32
35
  check_resources(node)
33
36
  @resource_controllers << node.arguments.all.first.to_s
34
37
  elsif "resource" == node.message.to_s
@@ -40,6 +43,7 @@ module RailsBestPractices
40
43
  add_callback :end_command do |node|
41
44
  if "resources" == node.message.to_s
42
45
  @resource_controllers.pop
46
+ @namespaces.pop if module_option(node)
43
47
  elsif "resource" == node.message.to_s
44
48
  @resource_controllers.pop
45
49
  end
@@ -52,6 +56,10 @@ module RailsBestPractices
52
56
  @namespaces << node.arguments.all.first.to_s if check_method_add_block?(node)
53
57
  when "resources", "resource"
54
58
  @resource_controllers << node.arguments.all.first.to_s if check_method_add_block?(node)
59
+ when 'scope'
60
+ if check_method_add_block?(node) && (mod = module_option(node))
61
+ @namespaces << mod
62
+ end
55
63
  else
56
64
  end
57
65
  end
@@ -64,6 +72,10 @@ module RailsBestPractices
64
72
  @namespaces.pop
65
73
  when "resources", "resource"
66
74
  @resource_controllers.pop
75
+ when 'scope'
76
+ if check_method_add_block?(node) && module_option(node)
77
+ @namespaces.pop
78
+ end
67
79
  end
68
80
  end
69
81
  end
@@ -143,6 +155,13 @@ module RailsBestPractices
143
155
  end
144
156
  end
145
157
 
158
+ def module_option(node)
159
+ option_node = node.arguments[1].last
160
+ if option_node && option_node.sexp_type == :bare_assoc_hash && hash_key_exist?(option_node, 'module')
161
+ option_node.hash_value('module').to_s
162
+ end
163
+ end
164
+
146
165
  def option_with_hash(node)
147
166
  node.arguments.all.size > 1 && :bare_assoc_hash == node.arguments.all[1].sexp_type
148
167
  end
@@ -22,7 +22,7 @@ module RailsBestPractices
22
22
  interesting_files MODEL_FILES
23
23
  url "http://rails-bestpractices.com/posts/19-use-observer"
24
24
 
25
- def initialize
25
+ def initialize(options = {})
26
26
  super
27
27
  @callbacks = []
28
28
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module RailsBestPractices
3
- VERSION = "1.15.1"
3
+ VERSION = "1.15.2"
4
4
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module RailsBestPractices::Core
4
+ describe ChecksLoader do
5
+ let(:checks_loader) { ChecksLoader.new(RailsBestPractices::Analyzer::DEFAULT_CONFIG) }
6
+
7
+ describe "load_lexicals" do
8
+ it "should load lexical checks from the default configuration" do
9
+ lexicals = checks_loader.load_lexicals
10
+ expect(lexicals.map(&:class)).to include(RailsBestPractices::Lexicals::RemoveTrailingWhitespaceCheck)
11
+ end
12
+ end
13
+
14
+ describe "load_reviews" do
15
+ it "should load the reviews from the default the configuration" do
16
+ reviews = checks_loader.load_reviews
17
+ expect(reviews.map(&:class)).to include(RailsBestPractices::Reviews::AlwaysAddDbIndexReview)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ module RailsBestPractices::Core
4
+ describe Check::Exceptable do
5
+ let(:method) { Method.new "BlogPost", "approve", "public", {} }
6
+
7
+ context "wildcard class and method" do
8
+ let(:except_method) { '*#*' }
9
+
10
+ it "matches" do
11
+ expect(Check::Exceptable.matches(method, except_method)).to eql true
12
+ end
13
+ end
14
+
15
+ context "wildcard class and matching explicit method" do
16
+ let(:except_method) { '*#approve' }
17
+
18
+ it "matches" do
19
+ expect(Check::Exceptable.matches(method, except_method)).to eql true
20
+ end
21
+ end
22
+
23
+ context "wildcard class and non-matching explicit method" do
24
+ let(:except_method) { '*#disapprove' }
25
+
26
+ it "matches" do
27
+ expect(Check::Exceptable.matches(method, except_method)).to eql false
28
+ end
29
+ end
30
+
31
+ context "matching class and wildcard method" do
32
+ let(:except_method) { 'BlogPost#*' }
33
+
34
+ it "matches" do
35
+ expect(Check::Exceptable.matches(method, except_method)).to eql true
36
+ end
37
+ end
38
+
39
+ context "non-matching class and wildcard method" do
40
+ let(:except_method) { 'User#*' }
41
+
42
+ it "matches" do
43
+ expect(Check::Exceptable.matches(method, except_method)).to eql false
44
+ end
45
+ end
46
+
47
+ context "matching class and matching method" do
48
+ let(:except_method) { 'BlogPost#approve' }
49
+
50
+ it "matches" do
51
+ expect(Check::Exceptable.matches(method, except_method)).to eql true
52
+ end
53
+ end
54
+
55
+ context "non-matching class and non-matching method" do
56
+ let(:except_method) { 'User#disapprove' }
57
+
58
+ it "matches" do
59
+ expect(Check::Exceptable.matches(method, except_method)).to eql false
60
+ end
61
+ end
62
+ end
63
+ end
@@ -186,7 +186,7 @@ module RailsBestPractices
186
186
  end
187
187
 
188
188
  describe "namespace" do
189
- it "should restrict auto-generated routes" do
189
+ before do
190
190
  content =<<-EOF
191
191
  class Admin::CommentsController < ApplicationController
192
192
  def show; end
@@ -198,7 +198,9 @@ module RailsBestPractices
198
198
  end
199
199
  EOF
200
200
  runner.prepare('app/controllers/admin/comments_controller.rb', content)
201
+ end
201
202
 
203
+ it "should restrict auto-generated routes" do
202
204
  content =<<-EOF
203
205
  RailsBestPracticesCom::Application.routes.draw do
204
206
  namespace :admin do
@@ -210,6 +212,30 @@ module RailsBestPractices
210
212
  expect(runner.errors.size).to eq(1)
211
213
  expect(runner.errors[0].to_s).to eq("config/routes.rb:3 - restrict auto-generated routes admin/comments (except: [:index])")
212
214
  end
215
+
216
+ it "should restrict auto-generated routes with scope :module" do
217
+ content =<<-EOF
218
+ RailsBestPracticesCom::Application.routes.draw do
219
+ scope module: :admin do
220
+ resources :comments
221
+ end
222
+ end
223
+ EOF
224
+ runner.review('config/routes.rb', content)
225
+ expect(runner.errors.size).to eq(1)
226
+ expect(runner.errors[0].to_s).to eq("config/routes.rb:3 - restrict auto-generated routes admin/comments (except: [:index])")
227
+ end
228
+
229
+ it "should restrict auto-generated routes with resources :module" do
230
+ content =<<-EOF
231
+ RailsBestPracticesCom::Application.routes.draw do
232
+ resources :comments, module: :admin
233
+ end
234
+ EOF
235
+ runner.review('config/routes.rb', content)
236
+ expect(runner.errors.size).to eq(1)
237
+ expect(runner.errors[0].to_s).to eq("config/routes.rb:2 - restrict auto-generated routes admin/comments (except: [:index])")
238
+ end
213
239
  end
214
240
 
215
241
  describe "nested routes" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_best_practices
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-05 00:00:00.000000000 Z
11
+ date: 2014-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -200,7 +200,6 @@ executables:
200
200
  extensions: []
201
201
  extra_rdoc_files: []
202
202
  files:
203
- - ".gemtest"
204
203
  - ".gitignore"
205
204
  - ".rspec"
206
205
  - ".ruby-version"
@@ -218,6 +217,7 @@ files:
218
217
  - lib/rails_best_practices/command.rb
219
218
  - lib/rails_best_practices/core.rb
220
219
  - lib/rails_best_practices/core/check.rb
220
+ - lib/rails_best_practices/core/checks_loader.rb
221
221
  - lib/rails_best_practices/core/configs.rb
222
222
  - lib/rails_best_practices/core/controllers.rb
223
223
  - lib/rails_best_practices/core/error.rb
@@ -294,9 +294,11 @@ files:
294
294
  - spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb
295
295
  - spec/rails_best_practices/analyzer_spec.rb
296
296
  - spec/rails_best_practices/core/check_spec.rb
297
+ - spec/rails_best_practices/core/checks_loader_spec.rb
297
298
  - spec/rails_best_practices/core/configs_spec.rb
298
299
  - spec/rails_best_practices/core/controllers_spec.rb
299
300
  - spec/rails_best_practices/core/error_spec.rb
301
+ - spec/rails_best_practices/core/except_methods_spec.rb
300
302
  - spec/rails_best_practices/core/gems_spec.rb
301
303
  - spec/rails_best_practices/core/helpers_spec.rb
302
304
  - spec/rails_best_practices/core/klasses_spec.rb
@@ -406,9 +408,11 @@ test_files:
406
408
  - spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb
407
409
  - spec/rails_best_practices/analyzer_spec.rb
408
410
  - spec/rails_best_practices/core/check_spec.rb
411
+ - spec/rails_best_practices/core/checks_loader_spec.rb
409
412
  - spec/rails_best_practices/core/configs_spec.rb
410
413
  - spec/rails_best_practices/core/controllers_spec.rb
411
414
  - spec/rails_best_practices/core/error_spec.rb
415
+ - spec/rails_best_practices/core/except_methods_spec.rb
412
416
  - spec/rails_best_practices/core/gems_spec.rb
413
417
  - spec/rails_best_practices/core/helpers_spec.rb
414
418
  - spec/rails_best_practices/core/klasses_spec.rb
data/.gemtest DELETED
File without changes