as_deprecation_tracker 1.0.0 → 1.1.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: b25a9c470b3310b7a3112d290e0655811ea93c3d
4
- data.tar.gz: 78857eba82e956ad61ad8e6276128fe4a73d6056
3
+ metadata.gz: 3c3db75579f6e32b233ab757406affac74f42210
4
+ data.tar.gz: 22c98db26c0c16b71993f038804b9b6e23ad7ea4
5
5
  SHA512:
6
- metadata.gz: 83efcef8a382e9c9cace6a2e942f7d96032d587b76b1ab36707cf3f7c37c82a1e6a8a241c1bdd8da5de298fe6e5ec2b2f705414f8c47208d3581059087629e0e
7
- data.tar.gz: c6558bacefd24acba76e6aa3e6bb23beff1e26cf1ec502cc010f6172f7cdd07f86affaf919509eef9b58015fb2ab7d3e761b129b16800765684a422b9aa7b94d
6
+ metadata.gz: 7d3a4345c389c3a37436cab4aaac86c981264f237e8e14d0366b9b3a85b53e24f6d567ecb3029daac26f6f438b4adf634ae1d8073a1d9edd3d175f6b727a8812
7
+ data.tar.gz: a4609be92a9373db4acba7a048f0ee320a51f027d5295a6c2c3c3cad4d608ab8ad3872cdd5eca617313337554b932d5b810fa0f76e3bbc75230a092d481582de
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016 Dominic Cleal
1
+ Copyright (c) 2016-2017 Dominic Cleal
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -50,7 +50,10 @@ specific instances of deprecated calls which can be committed. Subsequent `rake
50
50
  test` runs will then automatically raise errors for new occurrences.
51
51
 
52
52
  Re-run tests with `AS_DEPRECATION_RECORD=yes` to append new instances to the
53
- existing configuration file, if you wish to whitelist rather than fix them.
53
+ existing whitelist file, if you wish to permit rather than fix them.
54
+
55
+ Use `AS_DEPRECATION_WHITELIST=~/rails_engine` to set a different root directory
56
+ or whitelist file to update, e.g. for a Rails engine.
54
57
 
55
58
  ### Whitelist configuration
56
59
 
@@ -71,9 +74,12 @@ array of hashes:
71
74
  callstack: "app/models/foo.rb:23:in `example_method'"
72
75
  ```
73
76
 
74
- Accepted keys are `message`, matching the exact deprecation message and
75
- `callstack`, a string or an array forming the backtrace of the deprecation.
76
- If an array is given for the callstack, all entries must match the caller.
77
+ Accepted keys are:
78
+
79
+ * `message`, matching the exact deprecation message
80
+ * `callstack`, a string or an array forming the backtrace of the deprecation.
81
+ If an array is given for the callstack, all entries must match the caller.
82
+ * `engine`, a Rails `engine_name` string, matching any call within the engine
77
83
 
78
84
  The callstack will match on as much data as is provided - if only a file is
79
85
  given, any matching deprecation within the file will be whitelisted. The line
@@ -82,6 +88,13 @@ number may vary by up to ten lines from the recorded number by default (see
82
88
  `line_tolerance` to tune). Usually the filename and method name are sufficient
83
89
  to match the caller without needing line numbers.
84
90
 
91
+ Additional whitelist files may be placed below the root of each Rails engine
92
+ and will be loaded at startup in addition to the main Rails root config file.
93
+
94
+ Entries can be added programmatically by calling
95
+ `ASDeprecationTracker.whitelist.add(message: ...)` with any of the supported
96
+ keys above supplied as keyword arguments.
97
+
85
98
  ### Configuration
86
99
 
87
100
  Use an initializer to change ASDT's behaviour at startup:
@@ -101,8 +114,8 @@ Supported options:
101
114
  to ASDeprecationTracker::Receiver at startup, may be disabled to use multiple
102
115
  behaviors (defaults to true)
103
116
  * `whitelist_file` to customise the location of the whitelist YAML file
104
- (defaults to `config/as_deprecation_whitelist.yaml` beneath the Rails root)
117
+ (defaults to `config/as_deprecation_whitelist.yaml`)
105
118
 
106
119
  ## License
107
120
 
108
- Copyright (c) 2016 Dominic Cleal. Distributed under the MIT license.
121
+ Copyright (c) 2016-2017 Dominic Cleal. Distributed under the MIT license.
@@ -9,7 +9,7 @@ module ASDeprecationTracker
9
9
  @envs = %w(test)
10
10
  @line_tolerance = 10
11
11
  @register_behavior = true
12
- @whitelist_file = File.join(Rails.root, 'config', 'as_deprecation_whitelist.yaml')
12
+ @whitelist_file = File.join('config', 'as_deprecation_whitelist.yaml')
13
13
  end
14
14
  end
15
15
  end
@@ -9,7 +9,16 @@ module ASDeprecationTracker
9
9
  ActiveSupport::Deprecation.behavior = :notify if ASDeprecationTracker.config.register_behavior?
10
10
 
11
11
  whitelist = ASDeprecationTracker.config.whitelist_file
12
- ASDeprecationTracker.whitelist.load_file(whitelist) if File.exist?(whitelist)
12
+ ([Rails.root] + engine_roots).each do |root|
13
+ engine_whitelist = File.join(root, whitelist)
14
+ ASDeprecationTracker.whitelist.load_file(engine_whitelist) if File.exist?(engine_whitelist)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def engine_roots
21
+ ::Rails::Engine.descendants.map { |engine| engine.root rescue nil }.compact.uniq # rubocop:disable Style/RescueModifier
13
22
  end
14
23
  end
15
24
  end
@@ -20,11 +20,25 @@ module ASDeprecationTracker
20
20
  private
21
21
 
22
22
  def write_deprecation(message, callstack)
23
- writer = ASDeprecationTracker::Writer.new(ASDeprecationTracker.config.whitelist_file)
23
+ writer = ASDeprecationTracker::Writer.new(whitelist_file)
24
24
  writer.add(message, callstack)
25
25
  writer.write_file
26
26
  end
27
27
 
28
+ def whitelist_file
29
+ root = if ENV['AS_DEPRECATION_WHITELIST'].present?
30
+ File.expand_path(ENV['AS_DEPRECATION_WHITELIST'])
31
+ else
32
+ Rails.root
33
+ end
34
+
35
+ if File.directory?(root)
36
+ File.join(root, ASDeprecationTracker.config.whitelist_file)
37
+ else
38
+ root
39
+ end
40
+ end
41
+
28
42
  def raise_deprecation(message, callstack)
29
43
  e = ActiveSupport::DeprecationException.new(message)
30
44
  e.set_backtrace(callstack)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ASDeprecationTracker
3
- VERSION = '1.0.0'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
@@ -11,9 +11,10 @@ module ASDeprecationTracker
11
11
  @list = []
12
12
  end
13
13
 
14
- def add_to_list(entries)
15
- entries.each { |entry| @list << WhitelistEntry.new(entry) }
14
+ def add_to_list(*entries)
15
+ entries.flatten.each { |entry| @list << WhitelistEntry.new(entry.symbolize_keys) }
16
16
  end
17
+ alias_method :add, :add_to_list
17
18
 
18
19
  def clear
19
20
  @list.clear
@@ -3,21 +3,24 @@ module ASDeprecationTracker
3
3
  # Configuration of a whitelisted (known) deprecation warning matched by data
4
4
  # such as a message and/or callstack
5
5
  class WhitelistEntry
6
+ KNOWN_KEYS = %w(callstack engine message).freeze
6
7
  MESSAGE_CLEANUP_RE = Regexp.new('\ADEPRECATION WARNING: (.+) \(called from.*')
7
8
  CALLSTACK_FILE_RE = Regexp.new('\A(.*?)(?::(\d+))?(?::in `(.+)\')?\z')
8
9
 
9
- def initialize(entry)
10
- entry = entry.with_indifferent_access
11
- raise('Missing `message` or `callstack` from whitelist entry') unless entry.key?(:message) || entry.key?(:callstack)
12
- @message = entry[:message]
13
- @callstack = callstack_to_files_lines(Array.wrap(entry[:callstack]))
10
+ def initialize(callstack: [], engine: nil, message: nil)
11
+ @callstack = callstack_to_files_lines(Array.wrap(callstack))
12
+ @engine_root = engine.present? ? engine_root(engine) : nil
13
+ @message = message
14
14
  end
15
15
 
16
+ # rubocop:disable Metrics/CyclomaticComplexity
16
17
  def matches?(deprecation)
17
18
  return false if @message.present? && !message_matches?(deprecation[:message])
18
19
  return false if @callstack.present? && !callstack_matches?(deprecation[:callstack])
20
+ return false if @engine_root.present? && !engine_root_matches?(deprecation[:callstack])
19
21
  true
20
22
  end
23
+ # rubocop:enable Metrics/CyclomaticComplexity
21
24
 
22
25
  private
23
26
 
@@ -35,6 +38,7 @@ module ASDeprecationTracker
35
38
  end
36
39
 
37
40
  def callstack_matches?(callstack)
41
+ callstack = Rails::BacktraceCleaner.new.clean(callstack, :silent)
38
42
  callstack = callstack_to_files_lines(callstack)
39
43
 
40
44
  @callstack.all? do |whitelist_entry|
@@ -59,5 +63,20 @@ module ASDeprecationTracker
59
63
  return true if method1.nil? || method2.nil?
60
64
  method1 == method2
61
65
  end
66
+
67
+ def engine_root_matches?(callstack)
68
+ callstack.any? { |callstack_entry| callstack_entry.start_with?(@engine_root) }
69
+ end
70
+
71
+ def engine_root(engine_name)
72
+ ::Rails::Engine.descendants.each do |engine|
73
+ begin
74
+ return engine.root.to_s if engine_name == engine.engine_name
75
+ rescue NoMethodError, RuntimeError # rubocop:disable Lint/HandleExceptions
76
+ # Ignore failures with singleton engine subclasses etc.
77
+ end
78
+ end
79
+ raise("Unknown configured engine name #{engine_name}")
80
+ end
62
81
  end
63
82
  end
@@ -36,7 +36,7 @@ class ConfigurationTest < ASDeprecationTracker::TestCase
36
36
 
37
37
  def test_whitelist_file
38
38
  assert_kind_of String, @config.whitelist_file
39
- assert File.exist?(@config.whitelist_file)
39
+ assert File.exist?(File.join(Rails.root, @config.whitelist_file))
40
40
  end
41
41
 
42
42
  def test_whitelist_file=
@@ -40,6 +40,31 @@ class ReceiverTest < ASDeprecationTracker::TestCase
40
40
  ActiveSupport::Notifications.instrument('deprecation.rails', message: 'test')
41
41
  end
42
42
 
43
+ def test_whitelist_file_root
44
+ assert_equal File.join(Rails.root, 'config', 'as_deprecation_whitelist.yaml'), ASDeprecationTracker::Receiver.new.send(:whitelist_file)
45
+ end
46
+
47
+ def test_whitelist_file_env_directory
48
+ ENV['AS_DEPRECATION_WHITELIST'] = '/'
49
+ assert_equal File.join('/', 'config', 'as_deprecation_whitelist.yaml'), ASDeprecationTracker::Receiver.new.send(:whitelist_file)
50
+ ensure
51
+ ENV.delete('AS_DEPRECATION_WHITELIST')
52
+ end
53
+
54
+ def test_whitelist_file_env_file
55
+ ENV['AS_DEPRECATION_WHITELIST'] = '/as_deprecation_whitelist.yaml'
56
+ assert_equal '/as_deprecation_whitelist.yaml', ASDeprecationTracker::Receiver.new.send(:whitelist_file)
57
+ ensure
58
+ ENV.delete('AS_DEPRECATION_WHITELIST')
59
+ end
60
+
61
+ def test_whitelist_file_env_expand
62
+ ENV['AS_DEPRECATION_WHITELIST'] = File.join(Rails.root, '..', 'as_deprecation_whitelist.yaml')
63
+ assert_equal File.expand_path('../as_deprecation_whitelist.yaml', Rails.root), ASDeprecationTracker::Receiver.new.send(:whitelist_file)
64
+ ensure
65
+ ENV.delete('AS_DEPRECATION_WHITELIST')
66
+ end
67
+
43
68
  private
44
69
 
45
70
  def event(payload)
@@ -2,11 +2,7 @@
2
2
  require 'test_helper'
3
3
 
4
4
  class WhitelistEntryTest < ASDeprecationTracker::TestCase
5
- def test_initialize_with_strings
6
- ASDeprecationTracker::WhitelistEntry.new('message' => 'test')
7
- end
8
-
9
- def test_initialize_with_symbols
5
+ def test_initialize
10
6
  ASDeprecationTracker::WhitelistEntry.new(message: 'test')
11
7
  end
12
8
 
@@ -27,54 +23,54 @@ class WhitelistEntryTest < ASDeprecationTracker::TestCase
27
23
  end
28
24
 
29
25
  def test_matches_partial_callstack_top
30
- assert entry(callstack: ['/home/user/app/models/foo.rb:23']).matches?(deprecation)
26
+ assert entry(callstack: ['app/models/foo.rb:23']).matches?(deprecation)
31
27
  end
32
28
 
33
29
  def test_matches_partial_callstack_bottom
34
- assert entry(callstack: ['/home/user/app/controllers/foos_controller.rb:42']).matches?(deprecation)
30
+ assert entry(callstack: ['app/controllers/foos_controller.rb:42']).matches?(deprecation)
35
31
  end
36
32
 
37
33
  def test_matches_partial_callstack_multiple
38
34
  assert entry(callstack: [
39
- '/home/user/app/models/foo.rb:23',
40
- '/home/user/app/controllers/foos_controller.rb:42'
35
+ 'app/models/foo.rb:23',
36
+ 'app/controllers/foos_controller.rb:42'
41
37
  ]).matches?(deprecation)
42
38
  end
43
39
 
44
40
  def test_matches_partial_callstack_within_tolerance
45
- assert entry(callstack: ['/home/user/app/models/foo.rb:25']).matches?(deprecation)
41
+ assert entry(callstack: ['app/models/foo.rb:25']).matches?(deprecation)
46
42
  end
47
43
 
48
44
  def test_matches_partial_callstack_outside_tolerance
49
- refute entry(callstack: ['/home/user/app/models/foo.rb:34']).matches?(deprecation)
45
+ refute entry(callstack: ['app/models/foo.rb:34']).matches?(deprecation)
50
46
  end
51
47
 
52
48
  def test_matches_partial_callstack_same_method
53
- assert entry(callstack: ['/home/user/app/models/foo.rb:in `example_method\'']).matches?(deprecation)
49
+ assert entry(callstack: ['app/models/foo.rb:in `example_method\'']).matches?(deprecation)
54
50
  end
55
51
 
56
52
  def test_matches_partial_callstack_different_method
57
- refute entry(callstack: ['/home/user/app/models/foo.rb:23:in `another_method\'']).matches?(deprecation)
53
+ refute entry(callstack: ['app/models/foo.rb:23:in `another_method\'']).matches?(deprecation)
58
54
  end
59
55
 
60
56
  def test_matches_partial_callstack_different_method_no_line
61
- refute entry(callstack: ['/home/user/app/models/foo.rb:in `another_method\'']).matches?(deprecation)
57
+ refute entry(callstack: ['app/models/foo.rb:in `another_method\'']).matches?(deprecation)
62
58
  end
63
59
 
64
60
  def test_matches_partial_callstack_within_tolerance_same_method
65
- assert entry(callstack: ['/home/user/app/models/foo.rb:25:in `example_method\'']).matches?(deprecation)
61
+ assert entry(callstack: ['app/models/foo.rb:25:in `example_method\'']).matches?(deprecation)
66
62
  end
67
63
 
68
64
  def test_matches_partial_callstack_outside_tolerance_same_method
69
- refute entry(callstack: ['/home/user/app/models/foo.rb:34:in `example_method\'']).matches?(deprecation)
65
+ refute entry(callstack: ['app/models/foo.rb:34:in `example_method\'']).matches?(deprecation)
70
66
  end
71
67
 
72
68
  def test_matches_partial_callstack_string
73
- assert entry(callstack: '/home/user/app/models/foo.rb:23').matches?(deprecation)
69
+ assert entry(callstack: 'app/models/foo.rb:23').matches?(deprecation)
74
70
  end
75
71
 
76
72
  def test_matches_partial_callstack_file
77
- assert entry(callstack: ['/home/user/app/models/foo.rb']).matches?(deprecation)
73
+ assert entry(callstack: ['app/models/foo.rb']).matches?(deprecation)
78
74
  end
79
75
 
80
76
  def test_matches_different_message_same_callstack
@@ -89,20 +85,44 @@ class WhitelistEntryTest < ASDeprecationTracker::TestCase
89
85
  refute entry.matches?(deprecation(message: 'a different method is deprecated', callstack: caller))
90
86
  end
91
87
 
88
+ def test_matches_only_engine
89
+ assert entry(engine: 'example').matches?(deprecation(called_in_engine: 'example'))
90
+ end
91
+
92
+ def test_matches_different_engine
93
+ refute entry(engine: 'another').matches?(deprecation(called_in_engine: 'example'))
94
+ end
95
+
96
+ def test_matches_outside_engine
97
+ refute entry(engine: 'another').matches?(deprecation(called_in_engine: 'example'))
98
+ end
99
+
92
100
  private
93
101
 
94
- def deprecation(overrides = {})
102
+ def default_deprecation
95
103
  {
96
104
  message: 'uniq is deprecated and will be removed',
97
105
  callstack: [
98
- '/home/user/app/models/foo.rb:23:in `example_method\'',
99
- '/home/user/app/controllers/foos_controller.rb:42:in `update\'',
100
- '/home/user/test/controllers/foos_controller_test.rb:18:in `block in <class:FoosControllerTest>\''
106
+ "#{Rails.root}/app/models/foo.rb:23:in `example_method'",
107
+ "#{Rails.root}/app/controllers/foos_controller.rb:42:in `update'",
108
+ "#{Rails.root}/test/controllers/foos_controller_test.rb:18:in `block in <class:FoosControllerTest>'"
101
109
  ]
102
- }.merge(overrides).compact
110
+ }
111
+ end
112
+
113
+ def deprecation(overrides = {})
114
+ deprecation = default_deprecation
115
+ if (engine = overrides.delete(:called_in_engine))
116
+ deprecation[:callstack] << "/home/user/engines/#{engine}/app/middleware/foo.rb:12:in `call'"
117
+ end
118
+ deprecation.merge(overrides).compact
103
119
  end
104
120
 
105
121
  def entry(overrides = {})
106
- ASDeprecationTracker::WhitelistEntry.new(deprecation(overrides))
122
+ entry_hash = default_deprecation.merge(overrides).compact
123
+ entry_hash[:callstack].map! { |line| line.sub(Rails.root.to_s + '/', '') } if entry_hash[:callstack].is_a?(Array)
124
+
125
+ ASDeprecationTracker::WhitelistEntry.any_instance.expects(:engine_root).with(overrides[:engine]).returns("/home/user/engines/#{overrides[:engine]}") if overrides.key?(:engine)
126
+ ASDeprecationTracker::WhitelistEntry.new(entry_hash)
107
127
  end
108
128
  end
@@ -7,11 +7,21 @@ class WhitelistTest < ASDeprecationTracker::TestCase
7
7
  super
8
8
  end
9
9
 
10
+ def test_add
11
+ @whitelist.add(entry)
12
+ assert_equal 1, @whitelist.list.count
13
+ end
14
+
10
15
  def test_add_to_list
11
16
  @whitelist.add_to_list([entry])
12
17
  assert_equal 1, @whitelist.list.count
13
18
  end
14
19
 
20
+ def test_add_to_list_string_keys
21
+ @whitelist.add_to_list([entry.stringify_keys])
22
+ assert_equal 1, @whitelist.list.count
23
+ end
24
+
15
25
  def test_clear
16
26
  @whitelist.add_to_list([entry])
17
27
  @whitelist.clear
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: as_deprecation_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominic Cleal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-02 00:00:00.000000000 Z
11
+ date: 2017-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport