uncruft 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fdb195d4b08809aa2c07c8496fcc908f11fcc990
4
+ data.tar.gz: 5790bc811ae97d8d3de5a851c26cd707b452b530
5
+ SHA512:
6
+ metadata.gz: 766cefcb5c8b903953292269ad4ae8e451c4f1dd5f6f2b01d2c3f3283aefead950614b7354f9f28022ede6749aacfc042751c6cd9e9145b79b92bf5bb04d3df5
7
+ data.tar.gz: ace1be673782194643ffb5fe4b931fb7e7f947083084cb6c1c1af62deec03ef76ba44fb36c41384de516f97aaf2386b4957431f57d0c0f803bad8598bec4c243
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Betterment
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,53 @@
1
+ Uncruft
2
+ ========
3
+
4
+ A library to assist with clearing out Rails deprecation warnings and upgrading Rails versions.
5
+
6
+ ## Getting Started
7
+
8
+ Uncruft is designed to work with Rails 4.2 and higher.
9
+
10
+ ### Installation
11
+
12
+ You can add Uncruft to your Gemfile with:
13
+
14
+ ```
15
+ gem 'uncruft'
16
+ ```
17
+
18
+ Then run `bundle install`.
19
+
20
+ ### Deprecation Warnings
21
+
22
+ By default, deprecation warnings will cause your application to raise exceptions in `test` and `development` modes.
23
+
24
+ The exception message will include the original deprecation warning, plus a link to [our troubleshooting guide](https://github.com/Betterment/uncruft/blob/master/GUIDE.md), to assist with resolving deprecations as they are encountered.
25
+
26
+ ## Whitelisting Deprecations
27
+
28
+ When testing on a new Rails version for the first time, you will undoubtedly encounter many new warnings. As such, you can quickly whitelist all existing deprecation warnings encountered during your test suite like so:
29
+
30
+ ```bash
31
+ WHITELIST_DEPRECATIONS=1 rake
32
+ ```
33
+
34
+ You can also incrementally add new warnings to the whitelist as you encounter them:
35
+
36
+ ```bash
37
+ WHITELIST_DEPRECATIONS=1 rspec path/to/my/failing/spec.rb
38
+ ```
39
+
40
+ This will generate (or add to) a whitelist of warnings at `config/deprecations.ignore`. Any warning in that file will be ignored when next encountered.
41
+
42
+ ## How to Contribute
43
+
44
+ We would love for you to contribute! Anything that benefits the majority of users—from a documentation fix to an entirely new feature—is encouraged.
45
+
46
+ Before diving in, [check our issue tracker](//github.com/Betterment/uncruft/issues) and consider creating a new issue to get early feedback on your proposed change.
47
+
48
+ ### Suggested Workflow
49
+
50
+ * Fork the project and create a new branch for your contribution.
51
+ * Write your contribution (and any applicable test coverage).
52
+ * Make sure all tests pass (`bundle exec rake`).
53
+ * Submit a pull request.
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ task(:default).clear
10
+
11
+ require 'rubocop/rake_task'
12
+ RuboCop::RakeTask.new
13
+
14
+ require 'rspec/core'
15
+ require 'rspec/core/rake_task'
16
+ RSpec::Core::RakeTask.new(:spec)
17
+
18
+ if ENV['APPRAISAL_INITIALIZED'] || ENV['TRAVIS']
19
+ task default: %i(rubocop spec)
20
+ else
21
+ require 'appraisal'
22
+ Appraisal::Task.new
23
+ task default: :appraisal
24
+ end
@@ -0,0 +1,19 @@
1
+ require 'uncruft/version'
2
+ require 'uncruft/railtie'
3
+ require 'uncruft/deprecation_handler'
4
+ require 'uncruft/warning'
5
+
6
+ module Uncruft
7
+ class << self
8
+ # http://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
9
+ FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"].to_set
10
+
11
+ def whitelist_deprecations?
12
+ ENV['WHITELIST_DEPRECATIONS'].presence && !FALSE_VALUES.include?(ENV['WHITELIST_DEPRECATIONS'])
13
+ end
14
+
15
+ def ignorefile_path
16
+ ENV['UNCRUFT_IGNOREFILE_PATH'] || Rails.root.join('config', 'deprecations.ignore')
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,122 @@
1
+ require 'set'
2
+
3
+ module Uncruft
4
+ class DeprecationHandler
5
+ def call(message, _callstack)
6
+ line_number = line_number(message)
7
+ message = normalize_message(message)
8
+ handle_unknown_deprecation!(message, line_number) unless known_deprecations.include?(message)
9
+ end
10
+
11
+ def arity
12
+ 2
13
+ end
14
+
15
+ private
16
+
17
+ def handle_unknown_deprecation!(message, line_number)
18
+ if Uncruft.whitelist_deprecations?
19
+ known_deprecations << message
20
+ write_deprecations_file!
21
+ else
22
+ raise error_message(message, line_number)
23
+ end
24
+ end
25
+
26
+ def write_deprecations_file!
27
+ file = File.open(Uncruft.ignorefile_path, 'w')
28
+ file.puts(file_content(known_deprecations))
29
+ file.close
30
+ end
31
+
32
+ def line_number(message)
33
+ message.match(/called from( .+ at)? .+:(\d+)/)&.[](2)
34
+ end
35
+
36
+ # Rails deprecation message formats found here:
37
+ # https://github.com/rails/rails/blob/5-0-stable/activesupport/lib/active_support/deprecation/reporting.rb#L75
38
+ def normalize_message(message)
39
+ remove_line_number(normalize_caller(normalize_callstack_path(message)))
40
+ end
41
+
42
+ def normalize_callstack_path(message)
43
+ if (gem_home = gem_home(message)).present?
44
+ message.gsub(gem_home, '$GEM_PATH')
45
+ elsif (absolute_path = absolute_path(message)).present?
46
+ message.gsub(absolute_path, relative_path(absolute_path))
47
+ end
48
+ end
49
+
50
+ def normalize_caller(message)
51
+ normalize_require_callers(remove_view_callers(message))
52
+ end
53
+
54
+ def normalize_require_callers(message)
55
+ message.gsub(/ <(top \(required\)|main)> at /, ' <global scope> at ')
56
+ end
57
+
58
+ def remove_view_callers(message)
59
+ message.gsub(/ _\w+__+\d+_\d+ at /, ' ')
60
+ end
61
+
62
+ def remove_line_number(message)
63
+ message.sub(/(called from( .+ at)? .+):\d+/, '\1')
64
+ end
65
+
66
+ def gem_home(message)
67
+ message.match(%r{called from( .+ at)? (#{ENV['GEM_HOME']}/(.+/)*gems)})&.[](2)
68
+ end
69
+
70
+ def absolute_path(message)
71
+ message.match(/called from( .+ at)? (.+):\d/)&.[](2)
72
+ end
73
+
74
+ def relative_path(absolute_path)
75
+ Pathname.new(absolute_path)
76
+ .relative_path_from(Rails.root).to_s
77
+ .gsub(%r{\A(../)*vendor/cache}, '$GEM_PATH')
78
+ rescue ArgumentError # When `relative_path_from` cannot find a relative path.
79
+ absolute_path
80
+ end
81
+
82
+ def error_message(message, line_number)
83
+ <<~ERROR.strip
84
+ #{message}:#{line_number}
85
+
86
+ To resolve this error, adjust your code according to the instructions above.
87
+ If you did not introduce this error or are unsure why you are seeing it,
88
+ you will find additional guidance at the URL below:
89
+ https://github.com/Betterment/uncruft/blob/master/GUIDE.md
90
+ ERROR
91
+ end
92
+
93
+ def known_deprecations_file_exists?
94
+ File.file?(Uncruft.ignorefile_path)
95
+ end
96
+
97
+ def known_deprecations
98
+ @known_deprecations ||= begin
99
+ if known_deprecations_file_exists?
100
+ file = File.read(Uncruft.ignorefile_path)
101
+ JSON.parse(file)['ignored_warnings'].to_set
102
+ else
103
+ Set.new
104
+ end
105
+ end
106
+ end
107
+
108
+ def file_content(deprecations)
109
+ JSON.pretty_generate ignored_warnings: deprecations.sort,
110
+ updated: now,
111
+ rails_version: Rails::VERSION::STRING
112
+ end
113
+
114
+ def now
115
+ if defined?(Timecop)
116
+ Timecop.return { Time.zone.now }
117
+ else
118
+ Time.zone.now
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails'
2
+
3
+ module Uncruft
4
+ class Railtie < ::Rails::Railtie
5
+ if Rails.env.test? || Rails.env.development?
6
+ initializer 'uncruft.deprecation_handler', before: 'active_support.deprecation_behavior' do
7
+ strategies = [config.active_support.deprecation].flatten(1).compact
8
+ strategies.reject! { |s| s == :stderr }
9
+ strategies.unshift(DeprecationHandler.new)
10
+ config.active_support.deprecation = strategies
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Uncruft
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,32 @@
1
+ module Uncruft
2
+ module Warning
3
+ DEPRECATION_PATTERN = /(deprecation|deprecated)/i
4
+
5
+ def warn(str)
6
+ if str =~ DEPRECATION_PATTERN # rubocop:disable Performance/RegexpMatch
7
+ message = strip_caller_info(str, caller_locations(1..1).first).strip
8
+ ActiveSupport::Deprecation.warn(message)
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def strip_caller_info(str, cloc)
17
+ str.sub(cloc.to_s, '') # try full caller information first
18
+ .gsub(/#{cloc.path}(:#{cloc.lineno})?:?\s*/, '') # try path with optional line
19
+ end
20
+ end
21
+ end
22
+
23
+ if Rails.env.development? || Rails.env.test?
24
+ if defined?(Warning)
25
+ Warning.prepend(Uncruft::Warning)
26
+ Warning.singleton_class.prepend(Uncruft::Warning)
27
+ end
28
+ Kernel.prepend(Uncruft::Warning)
29
+ Kernel.singleton_class.prepend(Uncruft::Warning)
30
+ Object.prepend(Uncruft::Warning)
31
+ Object.singleton_class.prepend(Uncruft::Warning)
32
+ end
@@ -0,0 +1,8 @@
1
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
2
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
3
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
4
+
5
+ module Dummy
6
+ class Application < Rails::Application
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ {
2
+ "ignored_warnings": [
3
+ "Warning: BAD called from chicken/nuggets.rb"
4
+ ],
5
+ "updated": "2018-06-05 15:20:12 -0400",
6
+ "rails_version": "5.1.6"
7
+ }
File without changes
@@ -0,0 +1,24 @@
1
+ example_id | status | run_time |
2
+ ------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:1] | passed | 0.00321 seconds |
4
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:2:1] | passed | 0.01779 seconds |
5
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:2:2:1] | passed | 0.00596 seconds |
6
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:3:1] | passed | 0.00079 seconds |
7
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:4:1] | passed | 0.00071 seconds |
8
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:5:1] | passed | 0.00247 seconds |
9
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:6:1] | passed | 0.0026 seconds |
10
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:6:2:1] | passed | 0.0029 seconds |
11
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:6:3:1] | passed | 0.00142 seconds |
12
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:6:3:2:1] | passed | 0.00168 seconds |
13
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:7:1] | passed | 0.00052 seconds |
14
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:8:1] | passed | 0.00211 seconds |
15
+ ./spec/uncruft/deprecation_handler_spec.rb[1:1:8:2:1] | passed | 0.00335 seconds |
16
+ ./spec/uncruft/railtie_spec.rb[1:1] | passed | 0.06556 seconds |
17
+ ./spec/uncruft/railtie_spec.rb[1:2:1] | passed | 0.00156 seconds |
18
+ ./spec/uncruft/railtie_spec.rb[1:3:1] | passed | 0.00133 seconds |
19
+ ./spec/uncruft/warning_spec.rb[1:1] | passed | 0.00076 seconds |
20
+ ./spec/uncruft/warning_spec.rb[1:2:1] | passed | 0.00158 seconds |
21
+ ./spec/uncruft/warning_spec.rb[1:2:2:1] | passed | 0.00142 seconds |
22
+ ./spec/uncruft_spec.rb[1:1:1] | passed | 0.00533 seconds |
23
+ ./spec/uncruft_spec.rb[1:2:1] | passed | 0.00091 seconds |
24
+ ./spec/uncruft_spec.rb[1:2:2:1] | passed | 0.00151 seconds |
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler.require :default, :development
3
+
4
+ ENV["RAILS_ENV"] ||= 'test'
5
+ require File.expand_path('dummy/config/application', __dir__)
6
+ require 'support/rails_root'
7
+
8
+ Time.zone = ActiveSupport::TimeZone.all.first
9
+
10
+ RSpec.configure do |config|
11
+ config.run_all_when_everything_filtered = true
12
+ config.example_status_persistence_file_path = 'spec/examples.txt'
13
+ end
@@ -0,0 +1,7 @@
1
+ module ::Rails
2
+ class << self
3
+ def root
4
+ @root ||= Pathname.new(Dir.pwd).realpath.join('spec', 'dummy')
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,172 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Uncruft::DeprecationHandler do
4
+ let(:ignorefile_path) { Rails.root.join('config', 'deprecations.ignore') }
5
+
6
+ before do
7
+ File.delete(ignorefile_path) if File.exist?(ignorefile_path)
8
+ end
9
+
10
+ subject { described_class.new }
11
+
12
+ describe '#call' do
13
+ let(:absolute_path) { Rails.root.join('chicken', 'nuggets.rb') }
14
+ let(:line_number) { 123 }
15
+ let(:caller_label) { '<something>' }
16
+ let(:message) { "Warning: BAD called from #{caller_label} at #{absolute_path}:#{line_number}" }
17
+ let(:expected_whitelist_entry) { 'Warning: BAD called from <something> at chicken/nuggets.rb' }
18
+ let(:expected_error) { "#{expected_whitelist_entry}:123" }
19
+ let(:expected_error_message) do
20
+ <<~ERROR.strip
21
+ #{expected_error}
22
+
23
+ To resolve this error, adjust your code according to the instructions above.
24
+ If you did not introduce this error or are unsure why you are seeing it,
25
+ you will find additional guidance at the URL below:
26
+ https://github.com/Betterment/uncruft/blob/master/GUIDE.md
27
+ ERROR
28
+ end
29
+
30
+ it 'sanitizes the message and raises an error' do
31
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
32
+ end
33
+
34
+ context 'when whitelisting new deprecations' do
35
+ before do
36
+ allow(Uncruft).to receive(:whitelist_deprecations?).and_return(true)
37
+ end
38
+
39
+ it 'sanitizes the message and writes it to the file' do
40
+ expect { subject.call(message, '') }.to change { File.exist?(ignorefile_path) }.from(false).to(true)
41
+ expect(File.read(ignorefile_path)).to include(expected_whitelist_entry)
42
+ end
43
+
44
+ context 'when timecop is enabled' do
45
+ let(:test_started) { Time.zone.now }
46
+
47
+ it 'ignores time travel and writes the current time' do
48
+ Timecop.travel(test_started - 100.years) do
49
+ subject.call(message, '')
50
+
51
+ file_updated = Time.zone.parse(JSON.parse(File.read(ignorefile_path))['updated'])
52
+ expect(file_updated).to be_within(1.second).of(test_started)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'when caller is an erb file' do
59
+ let(:caller_label) { '_app_views_bananas_show__1234_567890' }
60
+ let(:expected_whitelist_entry) { 'Warning: BAD called from chicken/nuggets.rb' }
61
+
62
+ it 'sanitizes the message and raises an error' do
63
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
64
+ end
65
+ end
66
+
67
+ context 'when caller is "top (required)"' do
68
+ let(:caller_label) { '<top (required)>' }
69
+ let(:expected_whitelist_entry) { 'Warning: BAD called from <global scope> at chicken/nuggets.rb' }
70
+
71
+ it 'sanitizes the caller and raises an error' do
72
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
73
+ end
74
+ end
75
+
76
+ context 'when caller is "main"' do
77
+ let(:caller_label) { '<main>' }
78
+ let(:expected_whitelist_entry) { 'Warning: BAD called from <global scope> at chicken/nuggets.rb' }
79
+
80
+ it 'sanitizes the caller and raises an error' do
81
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
82
+ end
83
+ end
84
+
85
+ context 'when message includes custom gem path' do
86
+ let(:absolute_path) { Pathname.new('/banana/banana/banana/gems/chicken/nuggets.rb') }
87
+ let(:expected_whitelist_entry) { "Warning: BAD called from <something> at $GEM_PATH/chicken/nuggets.rb" }
88
+
89
+ before do
90
+ allow(ENV).to receive(:[]).and_call_original
91
+ allow(ENV).to receive(:[]).with('GEM_HOME').and_return('/banana/banana/banana')
92
+ end
93
+
94
+ it 'sanitizes the message and raises an error' do
95
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
96
+ end
97
+
98
+ context 'when gem home is nested' do
99
+ let(:absolute_path) { Pathname.new('/banana/banana/banana/arbitrary/gem/path/gems/chicken/nuggets.rb') }
100
+
101
+ it 'sanitizes the message and raises an error' do
102
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
103
+ end
104
+ end
105
+
106
+ context 'when gem is vendored' do
107
+ let(:absolute_path) { Rails.root.join('vendor', 'cache', 'chicken', 'nuggets.rb') }
108
+
109
+ it 'sanitizes the message and raises an error' do
110
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
111
+ end
112
+
113
+ context 'when gem is vendored elsewhere' do
114
+ let(:absolute_path) { Rails.root.join('..', '..', 'vendor', 'cache', 'chicken', 'nuggets.rb') }
115
+
116
+ it 'sanitizes the message and raises an error' do
117
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'when caller is not a filepath' do
124
+ let(:absolute_path) { '(pry)' }
125
+ let(:expected_whitelist_entry) { 'Warning: BAD called from <something> at (pry)' }
126
+
127
+ it 'sanitizes the message and raises an error' do
128
+ expect { subject.call(message, '') }.to raise_error(RuntimeError, expected_error_message)
129
+ end
130
+ end
131
+
132
+ context 'when whitelist exists' do
133
+ let(:message) { "Warning: BAD called from #{absolute_path}:#{line_number}" }
134
+ let(:file_content) do
135
+ <<~IGNOREFILE
136
+ {
137
+ "ignored_warnings": [
138
+ "Warning: BAD called from chicken/nuggets.rb"
139
+ ],
140
+ "updated": "2018-06-05 15:20:12 -0400",
141
+ "rails_version": "5.1.6"
142
+ }
143
+ IGNOREFILE
144
+ end
145
+
146
+ before do
147
+ File.open(ignorefile_path, 'w') do |f|
148
+ f.write file_content
149
+ end
150
+ end
151
+
152
+ it 'does not raise an error and leaves the file intact' do
153
+ expect(File.read(ignorefile_path)).to eq(file_content)
154
+ expect { subject.call(message, '') }.not_to change { File.read(ignorefile_path) }
155
+ end
156
+
157
+ context 'when whitelisting new deprecations' do
158
+ let(:line_number) { '456' }
159
+
160
+ before do
161
+ allow(Uncruft).to receive(:whitelist_deprecations?).and_return(true)
162
+ end
163
+
164
+ it 'does not raise an error and leaves the file intact' do
165
+ expect(File.read(ignorefile_path)).to eq(file_content)
166
+ expect { subject.call(message, '') }.not_to raise_error
167
+ expect(File.read(ignorefile_path)).to include('Warning: BAD called from chicken/nuggets.rb')
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Uncruft::Railtie do
4
+ let(:app) { Rails.application }
5
+ let(:initializers) { app.initializers.tsort_each.select { |i| i.name.to_s.include?('deprecation') } }
6
+
7
+ it 'injects the default deprecation handler' do
8
+ expect { initializers.map { |i| i.run(app) } }.to change { Rails.application.config.active_support.deprecation }
9
+ .from(nil).to(a_collection_containing_exactly(an_instance_of(Uncruft::DeprecationHandler)))
10
+ end
11
+
12
+ context 'when the configured behavior is :stderr' do
13
+ before do
14
+ Rails.application.config.active_support.deprecation = :stderr
15
+ end
16
+
17
+ it 'injects the default deprecation handler' do
18
+ expect { initializers.map { |i| i.run(app) } }.to change { Rails.application.config.active_support.deprecation }
19
+ .from(:stderr).to(a_collection_containing_exactly(an_instance_of(Uncruft::DeprecationHandler)))
20
+ end
21
+ end
22
+
23
+ context 'when a custom deprecation behavior is already configured' do
24
+ before do
25
+ Rails.application.config.active_support.deprecation = :notify
26
+ end
27
+
28
+ it 'injects the default deprecation handler' do
29
+ expect { initializers.map { |i| i.run(app) } }.to change { Rails.application.config.active_support.deprecation }
30
+ .from(:notify).to(a_collection_containing_exactly(:notify, an_instance_of(Uncruft::DeprecationHandler)))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Uncruft::Warning do
4
+ before do
5
+ stub_const('Warning', Kernel) unless defined?(Warning)
6
+ end
7
+
8
+ it "doesn't block generic warnings" do
9
+ expect(ActiveSupport::Deprecation).not_to receive(:warn)
10
+ warn('oh no, you should worry')
11
+ Kernel.warn('oh no, you should worry')
12
+ Warning.warn('oh no, you should worry')
13
+ end
14
+
15
+ context 'when warning includes the word "deprecation" or "deprecated"' do
16
+ it 'treats it as a deprecation warning' do
17
+ expect(ActiveSupport::Deprecation).to receive(:warn).and_return('banana').exactly(6).times
18
+ expect(warn('[dEpReCaTiOn] oh no, you should worry')).to eq 'banana'
19
+ expect(Kernel.warn('[dEpReCaTiOn] oh no, you should worry')).to eq 'banana'
20
+ expect(Warning.warn('[dEpReCaTiOn] oh no, you should worry')).to eq 'banana'
21
+ expect(warn('oh no, this is DePrEcAtEd, so you should worry')).to eq 'banana'
22
+ expect(Kernel.warn('oh no, this is DePrEcAtEd, so you should worry')).to eq 'banana'
23
+ expect(Warning.warn('oh no, this is DePrEcAtEd, so you should worry')).to eq 'banana'
24
+ end
25
+
26
+ context 'and when warning includes caller info' do
27
+ it 'strips out the path so that ActiveSupport::Deprecation can append a new one' do
28
+ path = caller_locations(0..0).first.path
29
+
30
+ expect(ActiveSupport::Deprecation).to receive(:warn).with('foo is deprecated!').and_return('hurray')
31
+ expect(warn("#{path}: foo is deprecated!")).to eq('hurray')
32
+
33
+ expect(ActiveSupport::Deprecation).to receive(:warn).with('[DEPRECATION] bar is no more.').and_return('huzzah')
34
+ expect(Kernel.warn("[DEPRECATION] bar is no more. #{path}:#{caller_locations(0..0).first.lineno}")).to eq('huzzah')
35
+
36
+ expect(ActiveSupport::Deprecation).to receive(:warn).with('Deprecation detected: banana --').and_return('we do our best...')
37
+ expect(Warning.warn("Deprecation detected: banana -- #{caller(0..0).first}")).to eq('we do our best...')
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Uncruft do
4
+ describe '.whitelist_deprecations?' do
5
+ it 'handles common truthy and falsy values' do
6
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('1')
7
+ expect(described_class.whitelist_deprecations?).to eq true
8
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('t')
9
+ expect(described_class.whitelist_deprecations?).to eq true
10
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('T')
11
+ expect(described_class.whitelist_deprecations?).to eq true
12
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('true')
13
+ expect(described_class.whitelist_deprecations?).to eq true
14
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('TRUE')
15
+ expect(described_class.whitelist_deprecations?).to eq true
16
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('0')
17
+ expect(described_class.whitelist_deprecations?).to eq false
18
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('f')
19
+ expect(described_class.whitelist_deprecations?).to eq false
20
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('F')
21
+ expect(described_class.whitelist_deprecations?).to eq false
22
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('false')
23
+ expect(described_class.whitelist_deprecations?).to eq false
24
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('FALSE')
25
+ expect(described_class.whitelist_deprecations?).to eq false
26
+ allow(ENV).to receive(:[]).with('WHITELIST_DEPRECATIONS').and_return('')
27
+ expect(described_class.whitelist_deprecations?).to be_nil
28
+ end
29
+ end
30
+
31
+ describe '.ignorefile_path' do
32
+ it 'uses rails root' do
33
+ expect(described_class.ignorefile_path).to eq(Rails.root.join('config', 'deprecations.ignore'))
34
+ end
35
+
36
+ context 'when env var is set' do
37
+ before do
38
+ allow(ENV).to receive(:[]).with('UNCRUFT_IGNOREFILE_PATH').and_return('/path/to/file.txt')
39
+ end
40
+
41
+ it 'uses env var' do
42
+ expect(described_class.ignorefile_path).to eq('/path/to/file.txt')
43
+ end
44
+ end
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uncruft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Griffith
8
+ - Chris Zega
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-04-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: railties
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 4.2.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 4.2.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: appraisal
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 2.2.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 2.2.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 3.7.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 3.7.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop-betterment
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 1.1.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 1.1.1
84
+ - !ruby/object:Gem::Dependency
85
+ name: timecop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.9.1
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.9.1
98
+ description: A library to assist with clearing out Rails deprecation warnings and
99
+ upgrading Rails versions
100
+ email:
101
+ - nathan@betterment.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - LICENSE
107
+ - README.md
108
+ - Rakefile
109
+ - lib/uncruft.rb
110
+ - lib/uncruft/deprecation_handler.rb
111
+ - lib/uncruft/railtie.rb
112
+ - lib/uncruft/version.rb
113
+ - lib/uncruft/warning.rb
114
+ - spec/dummy/config/application.rb
115
+ - spec/dummy/config/deprecations.ignore
116
+ - spec/dummy/log/test.log
117
+ - spec/examples.txt
118
+ - spec/spec_helper.rb
119
+ - spec/support/rails_root.rb
120
+ - spec/uncruft/deprecation_handler_spec.rb
121
+ - spec/uncruft/railtie_spec.rb
122
+ - spec/uncruft/warning_spec.rb
123
+ - spec/uncruft_spec.rb
124
+ homepage: https://github.com/Betterment/uncruft
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.6.13
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: A library to assist with Rails upgrades
148
+ test_files:
149
+ - spec/spec_helper.rb
150
+ - spec/dummy/config/deprecations.ignore
151
+ - spec/dummy/config/application.rb
152
+ - spec/dummy/log/test.log
153
+ - spec/examples.txt
154
+ - spec/uncruft/railtie_spec.rb
155
+ - spec/uncruft/warning_spec.rb
156
+ - spec/uncruft/deprecation_handler_spec.rb
157
+ - spec/support/rails_root.rb
158
+ - spec/uncruft_spec.rb