From 265e5ff18817da2a8aa0f4a6a2ef2e08b51c00c6 Mon Sep 17 00:00:00 2001 From: Amanda Sposito Date: Mon, 30 Jul 2018 17:54:58 -0300 Subject: [PATCH 1/3] Move formatted_token_amount to currency_helpers and rename it --- .../address_transaction/_transaction.html.eex | 2 +- .../views/address_transaction_view.ex | 23 ------------- .../explorer_web/views/currency_helpers.ex | 30 +++++++++++++++++ .../views/address_transaction_view_test.exs | 32 ------------------- .../views/currency_helpers_test.exs | 30 +++++++++++++++++ 5 files changed, 61 insertions(+), 56 deletions(-) diff --git a/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex b/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex index 07cecea1a4..3b3bd61d52 100644 --- a/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex +++ b/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex @@ -77,7 +77,7 @@ - <%= formatted_token_amount(token_transfer.amount, token_transfer.token.decimals) %> <%= token_transfer.token.symbol %> + <%= format_according_to_decimals(token_transfer.amount, token_transfer.token.decimals) %> <%= token_transfer.token.symbol %>
diff --git a/apps/explorer_web/lib/explorer_web/views/address_transaction_view.ex b/apps/explorer_web/lib/explorer_web/views/address_transaction_view.ex index 3a61821a32..2b45e869ed 100644 --- a/apps/explorer_web/lib/explorer_web/views/address_transaction_view.ex +++ b/apps/explorer_web/lib/explorer_web/views/address_transaction_view.ex @@ -14,29 +14,6 @@ defmodule ExplorerWeb.AddressTransactionView do end end - @doc """ - Formats the given amount according to given decimals. - - ## Examples - - iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(20500000), 5) - "205" - - iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(20500000), 7) - "2.05" - - iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(205000), 12) - "0.000000205" - - """ - @spec formatted_token_amount(Decimal.t(), non_neg_integer()) :: String.t() - def formatted_token_amount(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do - sign - |> Decimal.new(coef, exp - decimals) - |> Decimal.reduce() - |> Decimal.to_string(:normal) - end - def from_or_to_address?(%{from_address_hash: from_hash, to_address_hash: to_hash}, %Address{hash: hash}) do from_hash == hash || to_hash == hash end diff --git a/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex b/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex index 859ae1bc81..364b2b4d0f 100644 --- a/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex +++ b/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex @@ -33,4 +33,34 @@ defmodule ExplorerWeb.CurrencyHelpers do _ -> nil end end + + @spec format_integer_to_currency(non_neg_integer()) :: String.t() + def format_integer_to_currency(value) do + {:ok, formatted} = Cldr.Number.to_string(value, format: "#,##0") + + formatted + end + + @doc """ + Formats the given amount according to given decimals. + + ## Examples + + iex> format_according_to_decimals(Decimal.new(20500000), 5) + "205" + + iex> format_according_to_decimals(Decimal.new(20500000), 7) + "2.05" + + iex> format_according_to_decimals(Decimal.new(205000), 12) + "0.000000205" + + """ + @spec format_according_to_decimals(Decimal.t(), non_neg_integer()) :: String.t() + def format_according_to_decimals(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do + sign + |> Decimal.new(coef, exp - decimals) + |> Decimal.reduce() + |> Decimal.to_string(:normal) + end end diff --git a/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs b/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs index f62ed1f935..21cbcb7aeb 100644 --- a/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs +++ b/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs @@ -1,37 +1,5 @@ defmodule ExplorerWeb.AddresstransactionViewTest do use ExplorerWeb.ConnCase, async: true - alias ExplorerWeb.AddressTransactionView - doctest ExplorerWeb.AddressTransactionView - - describe "formatted_token_amount/1" do - test "formats the amount as value considering the given decimals" do - amount = Decimal.new(205_000_000_000_000) - decimals = 12 - - assert AddressTransactionView.formatted_token_amount(amount, decimals) == "205" - end - - test "considers the decimal places according to the given decimals" do - amount = Decimal.new(205_000) - decimals = 12 - - assert AddressTransactionView.formatted_token_amount(amount, decimals) == "0.000000205" - end - - test "does not consider right zeros in decimal places" do - amount = Decimal.new(90_000_000) - decimals = 6 - - assert AddressTransactionView.formatted_token_amount(amount, decimals) == "90" - end - - test "returns the full number when there is no right zeros in decimal places" do - amount = Decimal.new(9_324_876) - decimals = 6 - - assert AddressTransactionView.formatted_token_amount(amount, decimals) == "9.324876" - end - end end diff --git a/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs b/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs index 25d513b6ed..16e662173e 100644 --- a/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs +++ b/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs @@ -13,4 +13,34 @@ defmodule ExplorerWeb.CurrencyHelpersTest do test "with USD.null() it returns nil" do assert nil == CurrencyHelpers.format_usd_value(USD.null()) end + + describe "format_according_to_decimals/1" do + test "formats the amount as value considering the given decimals" do + amount = Decimal.new(205_000_000_000_000) + decimals = 12 + + assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "205" + end + + test "considers the decimal places according to the given decimals" do + amount = Decimal.new(205_000) + decimals = 12 + + assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "0.000000205" + end + + test "does not consider right zeros in decimal places" do + amount = Decimal.new(90_000_000) + decimals = 6 + + assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "90" + end + + test "returns the full number when there is no right zeros in decimal places" do + amount = Decimal.new(9_324_876) + decimals = 6 + + assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "9.324876" + end + end end From 4f07176e08226f443542640660ee329b05671a82 Mon Sep 17 00:00:00 2001 From: Felipe Renan Date: Wed, 1 Aug 2018 16:13:11 -0300 Subject: [PATCH 2/3] Render token transfers info according to the token's type --- apps/explorer_web/lib/explorer_web.ex | 9 ++- .../address_transaction/_transaction.html.eex | 2 +- .../lib/explorer_web/views/token_helpers.ex | 60 ++++++++++++++++++ .../views/address_transaction_view_test.exs | 5 -- .../explorer_web/views/token_helpers_test.exs | 62 +++++++++++++++++++ 5 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 apps/explorer_web/lib/explorer_web/views/token_helpers.ex delete mode 100644 apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs create mode 100644 apps/explorer_web/test/explorer_web/views/token_helpers_test.exs diff --git a/apps/explorer_web/lib/explorer_web.ex b/apps/explorer_web/lib/explorer_web.ex index fae629b9a9..0423ba5b7b 100644 --- a/apps/explorer_web/lib/explorer_web.ex +++ b/apps/explorer_web/lib/explorer_web.ex @@ -41,7 +41,14 @@ defmodule ExplorerWeb do # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML - import ExplorerWeb.{CurrencyHelpers, ErrorHelpers, Gettext, Router.Helpers, WeiHelpers} + import ExplorerWeb.{ + CurrencyHelpers, + ErrorHelpers, + Gettext, + Router.Helpers, + TokenHelpers, + WeiHelpers + } end end diff --git a/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex b/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex index 3b3bd61d52..d41e79feb4 100644 --- a/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex +++ b/apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex @@ -77,7 +77,7 @@ - <%= format_according_to_decimals(token_transfer.amount, token_transfer.token.decimals) %> <%= token_transfer.token.symbol %> + <%= token_transfer_amount(token_transfer) %> <%= token_symbol(token_transfer.token) %>
diff --git a/apps/explorer_web/lib/explorer_web/views/token_helpers.ex b/apps/explorer_web/lib/explorer_web/views/token_helpers.ex new file mode 100644 index 0000000000..52cc4d5cde --- /dev/null +++ b/apps/explorer_web/lib/explorer_web/views/token_helpers.ex @@ -0,0 +1,60 @@ +defmodule ExplorerWeb.TokenHelpers do + @moduledoc """ + Helper functions for intereacting with `t:ExplorerWeb.Chain.Token` attributes. + """ + + alias Explorer.Chain.{Token, TokenTransfer} + alias ExplorerWeb.{CurrencyHelpers} + + @doc """ + Returns the token transfers' amount according to the token's type and decimails. + + When the token's type is ERC-20, then we are going to format the amount according to the token's + decimals considering 0 when the decimals is nil. Case the amount is nil, this function will + return the symbol `--`. + + When the token's type is ERC-721, the function will return a string with the token_id that + represents the ERC-721 token since this kind of token doesn't have amount and decimals. + """ + def token_transfer_amount(%TokenTransfer{token: token, amount: amount, token_id: token_id}) do + do_token_transfer_amount(token, amount, token_id) + end + + defp do_token_transfer_amount(%Token{type: "ERC-20"}, nil, _token_id) do + "--" + end + + defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: nil}, amount, _token_id) do + CurrencyHelpers.format_according_to_decimals(amount, 0) + end + + defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: decimals}, amount, _token_id) do + CurrencyHelpers.format_according_to_decimals(amount, decimals) + end + + defp do_token_transfer_amount(%Token{type: "ERC-721"}, _amount, token_id) do + "TokenID [#{token_id}]" + end + + defp do_token_transfer_amount(_token, _amount, _token_id) do + nil + end + + @doc """ + Returns the token's symbol. + + When the token's symbol is nil, the function will return the contract address hash. + """ + def token_symbol(%Token{symbol: nil, contract_address_hash: address_hash}) do + address_hash = + address_hash + |> to_string() + |> String.slice(0..6) + + "#{address_hash}..." + end + + def token_symbol(%Token{symbol: symbol}) do + symbol + end +end diff --git a/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs b/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs deleted file mode 100644 index 21cbcb7aeb..0000000000 --- a/apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -defmodule ExplorerWeb.AddresstransactionViewTest do - use ExplorerWeb.ConnCase, async: true - - doctest ExplorerWeb.AddressTransactionView -end diff --git a/apps/explorer_web/test/explorer_web/views/token_helpers_test.exs b/apps/explorer_web/test/explorer_web/views/token_helpers_test.exs new file mode 100644 index 0000000000..a0425118bd --- /dev/null +++ b/apps/explorer_web/test/explorer_web/views/token_helpers_test.exs @@ -0,0 +1,62 @@ +defmodule ExplorerWeb.TokenHelpersTest do + use ExplorerWeb.ConnCase, async: true + + alias ExplorerWeb.{TokenHelpers} + + describe "token_transfer_amount/1" do + test "returns the symbol -- with ERC-20 token and amount nil" do + token = build(:token, type: "ERC-20") + token_transfer = build(:token_transfer, token: token, amount: nil) + + assert TokenHelpers.token_transfer_amount(token_transfer) == "--" + end + + test "returns the formatted amount according to token decimals with ERC-20 token" do + token = build(:token, type: "ERC-20", decimals: 6) + token_transfer = build(:token_transfer, token: token, amount: Decimal.new(1_000_000)) + + assert TokenHelpers.token_transfer_amount(token_transfer) == "1" + end + + test "returns the formatted amount when the decimals is nil with ERC-20 token" do + token = build(:token, type: "ERC-20", decimals: nil) + token_transfer = build(:token_transfer, token: token, amount: Decimal.new(1_000_000)) + + assert TokenHelpers.token_transfer_amount(token_transfer) == "1,000,000" + end + + test "returns a string with the token_id with ERC-721 token" do + token = build(:token, type: "ERC-721", decimals: nil) + token_transfer = build(:token_transfer, token: token, amount: nil, token_id: 1) + + assert TokenHelpers.token_transfer_amount(token_transfer) == "TokenID [1]" + end + + test "returns nothing for unknow token's type" do + token = build(:token, type: "unknow") + token_transfer = build(:token_transfer, token: token) + + assert TokenHelpers.token_transfer_amount(token_transfer) == nil + end + end + + describe "token_symbol/1" do + test "returns the token symbol" do + token = build(:token, symbol: "BAT") + + assert TokenHelpers.token_symbol(token) == "BAT" + end + + test "returns the token contract address hash when the symbol is nil" do + address = build(:address) + token = build(:token, symbol: nil, contract_address_hash: address.hash) + + address_hash = + address.hash + |> Explorer.Chain.Hash.to_string() + |> String.slice(0..6) + + assert TokenHelpers.token_symbol(token) == "#{address_hash}..." + end + end +end From d8baa94de8fe2f5fada48410234a5c38da06aaa4 Mon Sep 17 00:00:00 2001 From: Felipe Renan Date: Wed, 1 Aug 2018 16:49:41 -0300 Subject: [PATCH 3/3] Fix format_according_to_decimals to considers thousands separator --- .../lib/explorer_web/views/currency_helpers.ex | 12 +++++++++++- .../explorer_web/views/currency_helpers_test.exs | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex b/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex index 364b2b4d0f..0762095d57 100644 --- a/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex +++ b/apps/explorer_web/lib/explorer_web/views/currency_helpers.ex @@ -55,12 +55,22 @@ defmodule ExplorerWeb.CurrencyHelpers do iex> format_according_to_decimals(Decimal.new(205000), 12) "0.000000205" + iex> format_according_to_decimals(Decimal.new(205000), 2) + "2,050" """ @spec format_according_to_decimals(Decimal.t(), non_neg_integer()) :: String.t() def format_according_to_decimals(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do sign |> Decimal.new(coef, exp - decimals) |> Decimal.reduce() - |> Decimal.to_string(:normal) + |> thousands_separator() + end + + defp thousands_separator(value) do + if Decimal.to_float(value) > 999 do + Cldr.Number.to_string!(value) + else + Decimal.to_string(value, :normal) + end end end diff --git a/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs b/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs index 16e662173e..758b057835 100644 --- a/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs +++ b/apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs @@ -42,5 +42,12 @@ defmodule ExplorerWeb.CurrencyHelpersTest do assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "9.324876" end + + test "formats the value considering thousands separators" do + amount = Decimal.new(1_000_450) + decimals = 2 + + assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "10,004.5" + end end end