Skip to content

Preserve and utilize Warning categories #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## main (unreleased)

* [#86](https://github.com/Shopify/deprecation_toolkit/pull/86): Preserve and utilize `Warning` categories

## 2.0.3 (2023-02-10)

* [#80](https://github.com/Shopify/deprecation_toolkit/pull/80): Filter out stack trace from Gem::Deprecate deprecation messages
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ This setting accepts an array of regular expressions. To match on all warnings,
DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [//]
```

### 🔨 `#DeprecationToolkit::Configuration#warning_deprecated_category`

[Ruby silences its deprecation warnings by setting the `Warning[:deprecated]` category to `false`
unless otherwise specified.](https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/a84ad24386d27269b90794146c2a351c1d79471b)
This configuration option enables that category by default.

| Value of `DeprecationToolkit::Configuration#warning_deprecated_category` | Value of `Warning[:deprecated]` |
|--------------------------------------------------------------------------|---------------------------------|
| `true` (default) | `true` |
| `false` | `false` |
| `nil` | Unchanged |

## RSpec

By default Deprecation Toolkit uses Minitest as its test runner. To use Deprecation Toolkit with RSpec you'll have to configure it.
Expand Down
15 changes: 15 additions & 0 deletions lib/deprecation_toolkit/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,26 @@ module DeprecationToolkit
class Configuration
include ActiveSupport::Configurable

PREVIOUS_WARNING_DEPRECATED_CATEGORY = ::Warning[:deprecated]

config_accessor(:allowed_deprecations) { [] }
config_accessor(:attach_to) { [:rails] }
config_accessor(:behavior) { Behaviors::Raise }
config_accessor(:deprecation_path) { "test/deprecations" }
config_accessor(:test_runner) { :minitest }
config_accessor(:warnings_treated_as_deprecation) { [] }
config_accessor(:warning_deprecated_category)

def self.warning_deprecated_category=(value)
::Warning[:deprecated] =
if value.nil?
PREVIOUS_WARNING_DEPRECATED_CATEGORY
else
value
end
config.warning_deprecated_category = value
end

self.warning_deprecated_category = true
end
end
9 changes: 5 additions & 4 deletions lib/deprecation_toolkit/warning.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,20 @@ def handle_multipart(str)
str
end

def deprecation_triggered?(str)
DeprecationToolkit::Configuration.warnings_treated_as_deprecation.any? { |warning| warning =~ str }
def deprecation_triggered?(str, category: nil)
(category == :deprecated && ::Warning[:deprecated]) ||
DeprecationToolkit::Configuration.warnings_treated_as_deprecation.any? { |warning| warning =~ str }
end
end
end

module DeprecationToolkit
module WarningPatch
def warn(str)
def warn(str, category: nil)
str = DeprecationToolkit::Warning.handle_multipart(str)
return unless str

if DeprecationToolkit::Warning.deprecation_triggered?(str)
if DeprecationToolkit::Warning.deprecation_triggered?(str, category: category)
ActiveSupport::Deprecation.warn(str)
else
super
Expand Down
73 changes: 73 additions & 0 deletions test/deprecation_toolkit/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

module DeprecationToolkit
class ConfigurationTest < ActiveSupport::TestCase
setup do
@previous_warning_deprecated = ::Warning[:deprecated]
@previous_warning_deprecated_category = Configuration.warning_deprecated_category
end

teardown do
Configuration.warning_deprecated_category = @previous_warning_deprecated_category
::Warning[:deprecated] = @previous_warning_deprecated
end

test ".behavior is by default set to Raise" do
assert_equal Behaviors::Raise, Configuration.behavior
end
Expand All @@ -23,5 +33,68 @@ class ConfigurationTest < ActiveSupport::TestCase
test ".test_runner is by default set to `minitest`" do
assert_equal :minitest, Configuration.test_runner
end

test ".warning_deprecated_category is by default set to `true`" do
with_each_warning_deprecated_value do
assert_equal true, Configuration.warning_deprecated_category
end
end

test ".warning_deprecated_category= sets `Warning[:deprecated]` when passed boolean" do
with_each_warning_deprecated_value do
Configuration.warning_deprecated_category = true
assert_equal true, ::Warning[:deprecated]

Configuration.warning_deprecated_category = false
assert_equal false, ::Warning[:deprecated]
end
end

test ".warning_deprecated_category= leaves `Warning[:deprecated]` unchanged when passed nil" do
with_warning_deprecated false do
Configuration.warning_deprecated_category = nil
assert_equal false, ::Warning[:deprecated]

Configuration.warning_deprecated_category = true
assert_equal true, ::Warning[:deprecated]

Configuration.warning_deprecated_category = nil
assert_equal false, ::Warning[:deprecated]
end

with_warning_deprecated true do
Configuration.warning_deprecated_category = nil
assert_equal true, ::Warning[:deprecated]

Configuration.warning_deprecated_category = false
assert_equal false, ::Warning[:deprecated]

Configuration.warning_deprecated_category = nil
assert_equal true, ::Warning[:deprecated]
end
end

private

def with_warning_deprecated(value)
previous_value = ::Warning[:deprecated]

::Warning[:deprecated] = value

Configuration.send(:remove_const, :PREVIOUS_WARNING_DEPRECATED_CATEGORY)
Configuration.const_set(:PREVIOUS_WARNING_DEPRECATED_CATEGORY, ::Warning[:deprecated])

yield
ensure
::Warning[:deprecated] = previous_value

Configuration.send(:remove_const, :PREVIOUS_WARNING_DEPRECATED_CATEGORY)
Configuration.const_set(:PREVIOUS_WARNING_DEPRECATED_CATEGORY, ::Warning[:deprecated])
end

def with_each_warning_deprecated_value(&block)
with_warning_deprecated(false, &block)
with_warning_deprecated(true, &block)
end
end
end
36 changes: 36 additions & 0 deletions test/deprecation_toolkit/warning_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ module DeprecationToolkit
class WarningTest < ActiveSupport::TestCase
setup do
@previous_warnings_treated_as_deprecation = Configuration.warnings_treated_as_deprecation
@previous_warnings_deprecated_category = Configuration.warning_deprecated_category
@previous_warning_experimental = ::Warning[:experimental]
end

teardown do
::Warning[:experimental] = @previous_warning_experimental
Configuration.warning_deprecated_category = @previous_warnings_deprecated_category
Configuration.warnings_treated_as_deprecation = @previous_warnings_treated_as_deprecation
end

Expand Down Expand Up @@ -78,5 +82,37 @@ class WarningTest < ActiveSupport::TestCase
assert_match(/Using the last argument as keyword parameters/, error.message)
assert_match(/The called method/, error.message)
end

test "warn preserves category" do
::Warning[:experimental] = true
assert_output(nil, /#example is experimental/) do
warn "#example is experimental", category: :experimental

trigger_deprecation_toolkit_behavior
end

::Warning[:experimental] = false
assert_silent do
warn "#example is experimental", category: :experimental

trigger_deprecation_toolkit_behavior
end
end

test "treats `category: :deprecated` as deprecations, if flag is set" do
Configuration.warning_deprecated_category = true
assert_raises Behaviors::DeprecationIntroduced do
warn "#example is deprecated", category: :deprecated

trigger_deprecation_toolkit_behavior
end

Configuration.warning_deprecated_category = false
assert_nothing_raised do
warn "#example is deprecated", category: :deprecated

trigger_deprecation_toolkit_behavior
end
end
end
end