Skip to content

Commit

Permalink
Add new Performance/BigDecimalWithNumericArgument cop
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed Jun 8, 2020
1 parent bda0a63 commit 5709be6
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### New features

* [#129](https://github.com/rubocop-hq/rubocop-performance/pull/129): Add new `Performance/BigDecimalWithNumericArgument` cop. ([@fatkodima][])
* [#130](https://github.com/rubocop-hq/rubocop-performance/pull/130): Add new `Performance/SortReverse` cop. ([@fatkodima][])
* [#81](https://github.com/rubocop-hq/rubocop-performance/issues/81): Add new `Performance/StringInclude` cop. ([@fatkodima][])
* [#123](https://github.com/rubocop-hq/rubocop-performance/pull/123): Add new `Performance/AncestorsInclude` cop. ([@fatkodima][])
Expand Down
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Performance/AncestorsInclude:
Enabled: true
VersionAdded: '1.7'

Performance/BigDecimalWithNumericArgument:
Description: 'Convert numeric argument to string before passing to BigDecimal.'
Enabled: true
VersionAdded: '1.7'

Performance/BindCall:
Description: 'Use `bind_call(obj, args, ...)` instead of `bind(obj).call(args, ...)`.'
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
= Department xref:cops_performance.adoc[Performance]

* xref:cops_performance.adoc#performanceancestorsinclude[Performance/AncestorsInclude]
* xref:cops_performance.adoc#performancebigdecimalwithnumericargument[Performance/BigDecimalWithNumericArgument]
* xref:cops_performance.adoc#performancebindcall[Performance/BindCall]
* xref:cops_performance.adoc#performancecaller[Performance/Caller]
* xref:cops_performance.adoc#performancecasewhensplat[Performance/CaseWhenSplat]
Expand Down
30 changes: 30 additions & 0 deletions docs/modules/ROOT/pages/cops_performance.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,36 @@ A <= B

* https://github.com/JuanitoFatas/fast-ruby#ancestorsinclude-vs--code

== Performance/BigDecimalWithNumericArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 1.7
| -
|===

This cop identifies places where numeric argument to BigDecimal should be
converted to string. Initializing from String is faster
than from Numeric for BigDecimal.

BigDecimal(1, 2)
BigDecimal(1.2, 3, exception: true)

# good
BigDecimal('1', 2)
BigDecimal('1.2', 3, exception: true)

=== Examples

[source,ruby]
----
# bad
----

== Performance/BindCall

NOTE: Required Ruby version: 2.7
Expand Down
43 changes: 43 additions & 0 deletions lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Performance
# This cop identifies places where numeric argument to BigDecimal should be
# converted to string. Initializing from String is faster
# than from Numeric for BigDecimal.
#
# @example
#
# # bad
# BigDecimal(1, 2)
# BigDecimal(1.2, 3, exception: true)
#
# # good
# BigDecimal('1', 2)
# BigDecimal('1.2', 3, exception: true)
#
class BigDecimalWithNumericArgument < Cop
MSG = 'Convert numeric argument to string before passing to `BigDecimal`.'

def_node_matcher :big_decimal_with_numeric_argument?, <<~PATTERN
(send nil? :BigDecimal $numeric_type? ...)
PATTERN

def on_send(node)
big_decimal_with_numeric_argument?(node) do |numeric|
add_offense(node, location: numeric.source_range)
end
end

def autocorrect(node)
big_decimal_with_numeric_argument?(node) do |numeric|
lambda do |corrector|
corrector.wrap(numeric, "'", "'")
end
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/performance_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative 'mixin/regexp_metacharacter'

require_relative 'performance/ancestors_include'
require_relative 'performance/big_decimal_with_numeric_argument'
require_relative 'performance/bind_call'
require_relative 'performance/caller'
require_relative 'performance/case_when_splat'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Performance::BigDecimalWithNumericArgument do
subject(:cop) { described_class.new }

it 'registers an offense and corrects when using `BigDecimal` with integer' do
expect_offense(<<~RUBY)
BigDecimal(1)
^ Convert numeric argument to string before passing to `BigDecimal`.
RUBY

expect_correction(<<~RUBY)
BigDecimal('1')
RUBY
end

it 'registers an offense and corrects when using `BigDecimal` with float' do
expect_offense(<<~RUBY)
BigDecimal(1.5, 2, exception: true)
^^^ Convert numeric argument to string before passing to `BigDecimal`.
RUBY

expect_correction(<<~RUBY)
BigDecimal('1.5', 2, exception: true)
RUBY
end

it 'does not register an offense when using `BigDecimal` with string' do
expect_no_offenses(<<~RUBY)
BigDecimal('1')
RUBY
end
end

0 comments on commit 5709be6

Please sign in to comment.