parent
309a5bc5cb
commit
3befa706ec
@ -0,0 +1,36 @@ |
||||
defmodule ExplorerWeb.ExchangeRates.USD do |
||||
@moduledoc """ |
||||
Struct and associated conversion functions for USD currency |
||||
""" |
||||
|
||||
@typedoc """ |
||||
Represents USD currency |
||||
|
||||
* `:value` - value in USD |
||||
""" |
||||
@type t :: %__MODULE__{ |
||||
value: Decimal.t() | nil |
||||
} |
||||
|
||||
defstruct ~w(value)a |
||||
|
||||
alias Explorer.Chain.Wei |
||||
alias Explorer.ExchangeRates.Token |
||||
|
||||
def from(nil, _), do: null() |
||||
|
||||
def from(_, nil), do: null() |
||||
|
||||
def from(%Wei{value: nil}, _), do: null() |
||||
|
||||
def from(_, %Token{usd_value: nil}), do: null() |
||||
|
||||
def from(%Wei{} = wei, %Token{usd_value: exchange_rate}) do |
||||
ether = Wei.to(wei, :ether) |
||||
%__MODULE__{value: Decimal.mult(ether, exchange_rate)} |
||||
end |
||||
|
||||
def null do |
||||
%__MODULE__{value: nil} |
||||
end |
||||
end |
@ -0,0 +1,36 @@ |
||||
defmodule ExplorerWeb.CurrencyHelpers do |
||||
@moduledoc """ |
||||
Helper functions for interacting with `t:ExplorerWeb.ExchangeRates.USD.t/0` values. |
||||
""" |
||||
|
||||
import ExplorerWeb.Gettext |
||||
|
||||
alias ExplorerWeb.ExchangeRates.USD |
||||
alias Cldr.Number |
||||
|
||||
@doc """ |
||||
Formats a `ExplorerWeb.ExchangeRates.USD` value into USD and applies a unit label. |
||||
|
||||
## Examples |
||||
|
||||
iex> format_usd_value(%USD{value: Decimal.new(5)}) |
||||
"$5 USD" |
||||
|
||||
iex> format_usd_value(%USD{value: Decimal.new(5000)}) |
||||
"$5,000 USD" |
||||
|
||||
iex> format_usd_value(%USD{value: Decimal.new(0.000005)}) |
||||
"$0.000005 USD" |
||||
""" |
||||
@spec format_usd_value(USD.t() | nil) :: binary() | nil |
||||
def format_usd_value(nil), do: nil |
||||
|
||||
def format_usd_value(%USD{value: nil}), do: nil |
||||
|
||||
def format_usd_value(%USD{value: value}) do |
||||
case Number.to_string(value, format: "#,##0.##################") do |
||||
{:ok, formatted} -> "$#{formatted} " <> gettext("USD") |
||||
_ -> nil |
||||
end |
||||
end |
||||
end |
@ -1,8 +1,4 @@ |
||||
defmodule ExplorerWeb.TransactionLogView do |
||||
use ExplorerWeb, :view |
||||
@dialyzer :no_match |
||||
|
||||
alias ExplorerWeb.TransactionView |
||||
|
||||
defdelegate format_usd(txn, token), to: TransactionView |
||||
end |
||||
|
@ -0,0 +1,42 @@ |
||||
defmodule ExplorerWeb.ExchangeRates.USDTest do |
||||
use ExUnit.Case, async: true |
||||
|
||||
alias ExplorerWeb.ExchangeRates.USD |
||||
alias Explorer.ExchangeRates.Token |
||||
alias Explorer.Chain.Wei |
||||
|
||||
describe "from/2" do |
||||
test "with nil wei returns null object" do |
||||
token = %Token{usd_value: Decimal.new(0.5)} |
||||
|
||||
assert USD.null() == USD.from(nil, token) |
||||
end |
||||
|
||||
test "with nil token returns nil" do |
||||
wei = %Wei{value: Decimal.new(10_000_000_000_000)} |
||||
|
||||
assert USD.null() == USD.from(wei, nil) |
||||
end |
||||
|
||||
test "without a wei value returns nil" do |
||||
wei = %Wei{value: nil} |
||||
token = %Token{usd_value: Decimal.new(0.5)} |
||||
|
||||
assert USD.null() == USD.from(wei, token) |
||||
end |
||||
|
||||
test "without an exchange rate returns nil" do |
||||
wei = %Wei{value: Decimal.new(10_000_000_000_000)} |
||||
token = %Token{usd_value: nil} |
||||
|
||||
assert USD.null() == USD.from(wei, token) |
||||
end |
||||
|
||||
test "returns formatted usd value" do |
||||
wei = %Wei{value: Decimal.new(10_000_000_000_000)} |
||||
token = %Token{usd_value: Decimal.new(0.5)} |
||||
|
||||
assert %USD{value: Decimal.new(0.000005)} == USD.from(wei, token) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,26 @@ |
||||
defmodule ExplorerWeb.AddressViewTest do |
||||
use ExplorerWeb.ConnCase, async: true |
||||
|
||||
alias ExplorerWeb.AddressView |
||||
alias Explorer.ExchangeRates.Token |
||||
|
||||
describe "formatted_usd/2" do |
||||
test "without a fetched_balance returns nil" do |
||||
address = build(:address, fetched_balance: nil) |
||||
token = %Token{usd_value: Decimal.new(0.5)} |
||||
assert nil == AddressView.formatted_usd(address, token) |
||||
end |
||||
|
||||
test "without a usd_value returns nil" do |
||||
address = build(:address) |
||||
token = %Token{usd_value: nil} |
||||
assert nil == AddressView.formatted_usd(address, token) |
||||
end |
||||
|
||||
test "returns formatted usd value" do |
||||
address = build(:address, fetched_balance: 10_000_000_000_000) |
||||
token = %Token{usd_value: Decimal.new(0.5)} |
||||
assert "$0.000005 USD" == AddressView.formatted_usd(address, token) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,16 @@ |
||||
defmodule ExplorerWeb.CurrencyHelpersTest do |
||||
use ExUnit.Case |
||||
|
||||
alias ExplorerWeb.CurrencyHelpers |
||||
alias ExplorerWeb.ExchangeRates.USD |
||||
|
||||
doctest ExplorerWeb.CurrencyHelpers, import: true |
||||
|
||||
test "with nil it returns nil" do |
||||
assert nil == CurrencyHelpers.format_usd_value(nil) |
||||
end |
||||
|
||||
test "with USD.null() it returns nil" do |
||||
assert nil == CurrencyHelpers.format_usd_value(USD.null()) |
||||
end |
||||
end |
Loading…
Reference in new issue