Skip to content

Commit

Permalink
Merge pull request #326 from Shopify/pb-from-json
Browse files Browse the repository at this point in the history
Introduce from_json as the inverse of to_json
  • Loading branch information
pedropb authored Sep 6, 2024
2 parents ca8e590 + 9b98ee8 commit 7a9de52
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/money/money.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
require 'forwardable'
require 'json'

class Money
include Comparable
Expand Down Expand Up @@ -74,6 +75,16 @@ def from_subunits(subunits, currency_iso, format: :iso4217)
new(value, currency)
end

def from_json(string)
hash = JSON.parse(string, symbolize_names: true)
Money.new(hash.fetch(:value), hash.fetch(:currency))
end

def from_hash(hash)
hash = hash.transform_keys(&:to_sym)
Money.new(hash.fetch(:value), hash.fetch(:currency))
end

def rational(money1, money2)
money1.send(:arithmetic, money2) do
factor = money1.currency.subunit_to_unit * money2.currency.subunit_to_unit
Expand Down Expand Up @@ -278,6 +289,7 @@ def as_json(options = nil)
{ value: to_s(:amount), currency: currency.to_s }
end
end
alias_method :to_h, :as_json

def abs
abs = value.abs
Expand Down
30 changes: 30 additions & 0 deletions spec/money_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,36 @@
expect(JSON.dump(Money.new(1.00, "CAD"))).to eq('{"value":"1.00","currency":"CAD"}')
end

describe ".from_hash" do
it "is the inverse operation of #to_h" do
one_cad = Money.new(1, "CAD")
expect(Money.from_hash(one_cad.to_h)).to eq(one_cad)
end

it "creates Money object from hash with expected keys" do
expect(Money.from_hash({ value: 1.01, currency: "CAD" })).to eq(Money.new(1.01, "CAD"))
end

it "raises if Hash does not have the expected keys" do
expect { Money.from_hash({ "val": 1.0 }) }.to raise_error(KeyError)
end
end

describe ".from_json" do
it "is the inverse operation of #to_json" do
one_cad = Money.new(1, "CAD")
expect(Money.from_json(one_cad.to_json)).to eq(one_cad)
end

it "creates Money object from JSON-encoded string" do
expect(Money.from_json('{ "value": 1.01, "currency": "CAD" }')).to eq(Money.new(1.01, "CAD"))
end

it "raises if JSON string is malformed" do
expect { Money.from_json('{ "val": 1.0 }') }.to raise_error(KeyError)
end
end

it "supports absolute value" do
expect(Money.new(-1.00).abs).to eq(Money.new(1.00))
end
Expand Down

0 comments on commit 7a9de52

Please sign in to comment.