Skip to content
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

Introduce Money.from_amount for compatibility with RubyMoney #44

Merged
merged 3 commits into from
Mar 20, 2017

Conversation

bdewater
Copy link
Contributor

@bdewater bdewater commented Mar 7, 2017

Introduce Money.from_amount for compatibility with RubyMoney and by extension offsite_payments.

We use this gem in Shopify instead of money on Rubygems. The API's were similar enough until activemerchant/offsite_payments#217 introduced a change which broke upgrading offsite_payments in Shopify. This PR aims to restore compatibility between ShopifyMoney and RubyMoney to unblock ourselves until a better solution is found.

ShopifyMoney.new calls #value_to_decimal to either cast a Numeric object to BigDecimal, or have BigDecimal parse the input value. RubyMoney does something similar for .from_amount.

@bdewater bdewater requested review from elfassy and pi3r March 7, 2017 18:53
it "raises ArgumentError with unsupported argument" do
expect { Money.from_amount(Object.new) }.to raise_error(ArgumentError)
end
end
Copy link
Contributor

@elfassy elfassy Mar 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rubymoney money tests (for reference)

@@ -6,6 +6,10 @@ class Money

attr_reader :value, :cents

def self.from_amount(value)
new(value)
end
Copy link
Contributor

@elfassy elfassy Mar 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@bdewater bdewater Mar 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. That'll work for Money.new though because offiste_payment has this line just for us: https://github.com/activemerchant/offsite_payments/blob/e90298b1801552070ca9cee83f649363567cb8a9/lib/offsite_payments/notification.rb#L37

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Might as well

class << self
  alias_method :new, :from_amount
end

@Krystosterone
Copy link

Mind linking to the big write-up you guys did on what's the problem we're encountering and how it solves it?

@@ -485,4 +485,16 @@
end

end

describe "from_amount quacks like RubyMoney" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 😢

@bdewater
Copy link
Contributor Author

bdewater commented Mar 8, 2017

Fixed all the things, ready for re-review!

alias_method :from_amount, :new
end

def initialize(value = 0, _currency = nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://i.faketrumptweet.com/ensxgrymba_1ljuxxi.png

@@ -266,8 +270,10 @@ def all_rational?(splits)
def value_to_decimal(num)
if num.respond_to?(:to_d)
num.is_a?(Rational) ? num.to_d(16) : num.to_d
else
elsif num.is_a?(Money) || num.is_a?(Numeric) || num.is_a?(String)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did the need for this come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for the "raises ArgumentError with unsupported argument" spec from RubyMoney to pass we can't just call num#to_s and pass it to BigDecimal like we did. I couldn't think of a way to duck(type) myself out of this one 🤔

Copy link
Contributor

@elfassy elfassy Mar 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When would we have num.is_a?(Numeric) || num.is_a?(String)? Both respond to the .to_d in theory, so would do the first if

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Derp, you're right!

Copy link

@Krystosterone Krystosterone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with the changes, but they make me sad. Mind just adding a bit more of a clearer PR description so that anyone looking into the PR knows why this was done?

Copy link
Contributor

@elfassy elfassy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one nit, otherwise LGTM

Bart de Water added 2 commits March 20, 2017 11:06
…ney, fix `value_to_decimal` to match RubyMoney behaviour

This is an interim solution to unbblock ourselves from upgrading offsite_payments. See https://github.com/Shopify/shopify/issues/95949 for a write-up.
…cation:0x000000029b82d0>` from `bundle exec rake` that is run by CI by upgrading RSpec and fixing some spec warnings along the way
@bdewater bdewater merged commit 02ef66b into master Mar 20, 2017
@elfassy elfassy deleted the from_amount branch March 20, 2017 15:10
@elfassy elfassy mentioned this pull request Mar 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants