Skip to content

Commit

Permalink
Don't autocorrect BigDecimal with float when precision is specified
Browse files Browse the repository at this point in the history
The precision argument to `BigDecimal()` is ignored unless the value is
a float or rational. Converting the value from a float to a string when
a precision is specified changes the result.

    $ ruby -rbigdecimal -e "puts BigDecimal(3.14, 1)"
    0.3e1

    $ ruby -rbigdecimal -e "puts BigDecimal('3.14', 1)"
    0.314e1
  • Loading branch information
eugeneius committed Jul 10, 2020
1 parent 809fae5 commit 22478ee
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bug fixes

* [#150](https://github.com/rubocop-hq/rubocop-performance/pull/150): Fix an incorrect autocorrect for `Performance/BigDecimalWithNumericArgument` when a precision is specified. ([@eugeneius][])

## 1.7.0 (2020-07-07)

### New features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class BigDecimalWithNumericArgument < Cop

def on_send(node)
big_decimal_with_numeric_argument?(node) do |numeric|
next if numeric.float_type? && specifies_precision?(node)

add_offense(node, location: numeric.source_range)
end
end
Expand All @@ -36,6 +38,12 @@ def autocorrect(node)
end
end
end

private

def specifies_precision?(node)
node.arguments.size > 1 && !node.arguments[1].hash_type?
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,31 @@

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

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

it 'does not register an offense when using `BigDecimal` with float and precision' do
expect_no_offenses(<<~RUBY)
BigDecimal(3.14, 1)
RUBY
end

it 'does not register an offense when using `BigDecimal` with float and non-literal precision' do
expect_no_offenses(<<~RUBY)
precision = 1
BigDecimal(3.14, precision)
RUBY
end

it 'does not register an offense when using `BigDecimal` with float, precision, and a keyword argument' do
expect_no_offenses(<<~RUBY)
BigDecimal(3.14, 1, exception: true)
RUBY
end

Expand Down

0 comments on commit 22478ee

Please sign in to comment.