Skip to content

Commit

Permalink
Merge pull request #1682 from graygilmore/spree-money/comparable
Browse files Browse the repository at this point in the history
Add Comparable to Spree::Money
  • Loading branch information
jhawthorn authored Jan 16, 2017
2 parents 8ae8ec4 + 943b2c5 commit 2dcc0ed
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
## Solidus 2.2.0 (master, unreleased)

* Promotion and Shipping calculators can be created or have their type
changed without saving and reloading the page. [#1618](https://github.com/solidusio/solidus/pull/1618)
changed without saving and reloading the page.
[#1618](https://github.com/solidusio/solidus/pull/1618)

* Product slugs no longer have a minimum length validation to match the Product name validation.
* Product slugs no longer have a minimum length validation to match the
Product name validation.
[#1616](https://github.com/solidusio/solidus/pull/1616)

* Changed the promotion field in the admin order search to only find orders
which used the specified promotion code, instead of any code on an applied
promotion. [#1662](https://github.com/solidusio/solidus/pull/1662)

* `Spree::Money` now includes `Comparable` and the `<=>` operator for
comparisons. A comparison will fail if the two objects do not use the same
currency. [#1682](https://github.com/solidusio/solidus/pull/1682)

## Solidus 2.1.0 (unreleased)

* The OrderUpdater (as used by `order.update!`) now fully updates taxes.
Expand Down Expand Up @@ -83,7 +89,7 @@
For now `PromotionAction` provides a default remove_from method, with a
deprecation warning that subclasses should define their own remove_from
method.

[#1451](https://github.com/solidusio/solidus/pull/1451)

* Remove `is_default` boolean from `Spree::Price` model
Expand Down
18 changes: 18 additions & 0 deletions core/lib/spree/money.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module Spree
# Spree::Money is a relatively thin wrapper around Monetize which handles
# formatting via Spree::Config.
class Money
include Comparable
DifferentCurrencyError = Class.new(StandardError)
RUBY_NUMERIC_STRING = /\A-?\d+(\.\d+)?\z/

class <<self
Expand Down Expand Up @@ -92,6 +94,22 @@ def as_json(*)
to_s
end

def <=>(other)
if !other.respond_to?(:money)
raise TypeError, "Can't compare #{other.class} to Spree::Money"
end
if self.currency != other.currency
# By default, ::Money will try to run a conversion on `other.money` and
# try a comparison on that. We do not want any currency conversion to
# take place so we'll catch this here and raise an error.
raise(
DifferentCurrencyError,
"Can't compare #{self.currency} with #{other.currency}"
)
end
@money <=> other.money
end

# Delegates comparison to the internal ruby money instance.
#
# @see http://www.rubydoc.info/gems/money/Money/Arithmetic#%3D%3D-instance_method
Expand Down
32 changes: 32 additions & 0 deletions core/spec/lib/spree/money_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,36 @@
end
end
end

it "includes Comparable" do
expect(described_class).to include(Comparable)
end

describe "<=>" do
let(:usd_10) { Spree::Money.new(10, currency: "USD") }
let(:usd_20) { Spree::Money.new(20, currency: "USD") }
let(:usd_30) { Spree::Money.new(30, currency: "USD") }

it "compares the two amounts" do
expect(usd_20 <=> usd_20).to eq 0
expect(usd_20 <=> usd_10).to be > 0
expect(usd_20 <=> usd_30).to be < 0
end

context "with a non Spree::Money object" do
it "raises an error" do
expect { usd_10 <=> 20 }.to raise_error(TypeError)
end
end

context "with differing currencies" do
let(:cad) { Spree::Money.new(10, currency: "CAD") }

it "raises an error" do
expect { usd_10 <=> cad }.to raise_error(
Spree::Money::DifferentCurrencyError
)
end
end
end
end

0 comments on commit 2dcc0ed

Please sign in to comment.