diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c09e69..7332b6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,15 @@ -# Changelog for Money v3.1.1 +# Changelog for Money v3.2.0 -This is the changelog for Money v3.1.0 released on January ____, 2019. For older changelogs please consult the release tag on [GitHub](https://github.com/kipcole9/money/tags) +This is the changelog for Money v3.1.0 released on February 1st, 2019. For older changelogs please consult the release tag on [GitHub](https://github.com/kipcole9/money/tags) ### Bug Fixes * Correctly generate `migrations_path/1` function based upon whether `Ecto` is configured and which version +### Enhancements + +* Adds `Money.parse/2` which will parse a string comprising a currency code and an amount. It will return a `Money.t` or an error. This function may be helpful in supporting money input in HTML forms. + # Changelog for Money v3.1.0 This is the changelog for Money v3.1.0 released on December 30th, 2018. For older changelogs please consult the release tag on [GitHub](https://github.com/kipcole9/money/tags) diff --git a/README.md b/README.md index b68720b..66e45ce 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,12 @@ end iex> Money.new("1.000,99", :EUR, locale: "de") #Money<:EUR, 1000.99> + iex> Money.parse("USD 100") + #Money<:USD, 100> + + iex> Money.parse("USD 100,00", locale: "de") + #Money<:USD, 100.00> + The canonical representation of a currency code is an `atom` that is a valid [ISO4217](http://www.currency-iso.org/en/home/tables/table-a1.html) currency code. The amount of a `%Money{}` is represented by a `Decimal`. diff --git a/config/dev.exs b/config/dev.exs index 58d4c12..31cdaec 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -11,4 +11,4 @@ config :ex_money, log_success: :info, json_library: Jason, exchange_rates_cache: Money.ExchangeRates.Cache.Dets, - default_cldr_backend: Test.Cldr + default_cldr_backend: Money.Cldr diff --git a/lib/money.ex b/lib/money.ex index 3cea04c..298e572 100644 --- a/lib/money.ex +++ b/lib/money.ex @@ -234,7 +234,7 @@ defmodule Money do Returns a %Money{} struct from a currency code and a currency amount. Raises an exception if the current code is invalid. - ## Options + ## Arguments * `currency_code` is an ISO4217 three-character upcased binary or atom @@ -287,7 +287,7 @@ defmodule Money do introduced upstream. This function therefore should be used with great care and its use should be considered potentially harmful. - ## Options + ## Arguments * `currency_code` is an ISO4217 three-character upcased binary or atom @@ -340,7 +340,7 @@ defmodule Money do introduced upstream. This function therefore should be used with great care and its use should be considered potentially harmful. - ## Options + ## Arguments * `currency_code` is an ISO4217 three-character upcased binary or atom @@ -366,6 +366,80 @@ defmodule Money do end end + @doc """ + Parse a string and return a `Money.t` or an error. + + The string to be parsed is required to have a currency + code and an amount. The currency code may be placed + before the amount or after, but not both. + + Parsing is strict. Additional text surrounding the + currency code and amount will cause the parse to + fail. + + ## Arguments + + * `string` is a string to be parsed + + * `options` is a keyword list of options that is + passed to `Money.new/3` + + ## Examples + + iex> Money.parse("USD 100") + #Money<:USD, 100> + + iex> Money.parse "USD 100,00", locale: "de" + #Money<:USD, 100.00> + + iex> Money.parse("100 USD") + #Money<:USD, 100> + + iex> Money.parse("100") + {:error, + {Money.Invalid, + "A currency code must be specified but was not found in \\"100\\""}} + + iex> Money.parse("USD 100 with trailing text") + {:error, {Money.Invalid, "Could not parse \\"USD 100 with trailing text\\"."}} + + """ + # @doc since: "2.1.0" + @regex Regex.compile!("^(?[a-zA-Z]{3})?(?[^a-zA-Z]*)(?[a-zA-Z]{3})?$") + def parse(string, options \\ []) do + @regex + |> Regex.named_captures(String.trim(string)) + |> do_parse(string, options) + end + + defp do_parse(%{"currency_before" => "", "currency_after" => ""}, string, _options) do + {:error, {Money.Invalid, + "A currency code must be specified but was not found in #{inspect string}"}} + end + + defp do_parse(%{"amount" => ""}, string, _options) do + {:error, {Money.Invalid, + "An amount must be specified but was not found in #{inspect string}"}} + end + + defp do_parse(%{"currency_before" => "", "currency_after" => currency, "amount" => amount}, _, options) do + Money.new(currency, String.trim(amount), options) + end + + defp do_parse(%{"currency_before" => currency, "currency_after" => "", "amount" => amount}, _, options) do + Money.new(currency, String.trim(amount), options) + end + + defp do_parse(%{"currency_before" => currency_before, "currency_after" => currency_after}, _, _options) do + {:error, {Money.Invalid, + "A currency code can only be specified once. Found both #{inspect currency_before} and #{inspect currency_after}."}} + end + + defp do_parse(_captures, string, _options) do + {:error, {Money.Invalid, + "Could not parse #{inspect string}."}} + end + @doc """ Returns a formatted string representation of a `Money{}`. diff --git a/mix.exs b/mix.exs index 3456e3c..53698d2 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Money.Mixfile do use Mix.Project - @version "3.1.1" + @version "3.2.0" def project do [ diff --git a/mix.lock b/mix.lock index 5c6c2e3..3b39b85 100644 --- a/mix.lock +++ b/mix.lock @@ -1,42 +1,42 @@ %{ "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "cldr_utils": {:hex, :cldr_utils, "2.0.4", "d32156b5209aa03b5665fa0edec959c347400308cf74f9fd58635ebfc4406574", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, + "cldr_utils": {:hex, :cldr_utils, "2.0.5", "eba0f4cc86861b74f2c1180fe7f6fa25f9e9a3b06365fa7468213c9ec3fd392c", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, - "db_connection": {:hex, :db_connection, "2.0.3", "b4e8aa43c100e16f122ccd6798cd51c48c79fd391c39d411f42b3cd765daccb0", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "2.0.4", "d6b8d2199c7df7d9e42b53cbac8c32291ca66376ee653db7eb68c8050e1d3892", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, "decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"}, - "ecto": {:hex, :ecto, "3.0.5", "bf9329b56f781a67fdb19e92e6d9ed79c5c8b31d41653b79dafb7ceddfbe87e0", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, - "ecto_sql": {:hex, :ecto_sql, "3.0.3", "dd17f2401a69bb2ec91d5564bd259ad0bc63ee32c2cb2e616d04f1559801dba6", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.4", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.2.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, + "ecto": {:hex, :ecto, "3.0.6", "d33ab5b3f7553a41507d4b0ad5bf192d533119c4ad08f3a5d63d85aa12117dc9", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, + "ecto_sql": {:hex, :ecto_sql, "3.0.4", "e7a0feb0b2484b90981c56d5cd03c52122c1c31ded0b95ed213b7c5c07ae6737", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.6", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "elixir_xml_to_map": {:hex, :elixir_xml_to_map, "0.1.2", "e3d1bd2f6562711117ae209657f385a1c1c34c8c720c748eeba2e22815797071", [:mix], [{:erlsom, "~>1.4", [hex: :erlsom, repo: "hexpm", optional: false]}], "hexpm"}, - "erlsom": {:hex, :erlsom, "1.4.2", "5cddb82fb512f406f61162e511ae86582f824f0dccda788378b18a00d89c1b3f", [:rebar3], [], "hexpm"}, - "ex_cldr": {:hex, :ex_cldr, "2.2.0", "983c4e6983f111f55ab219bf0e0772e37a53cef4012b278dfd3c2309ceb74337", [:mix], [{:cldr_utils, "~> 2.0", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"}, + "erlsom": {:hex, :erlsom, "1.5.0", "c5a5cdd0ee0e8dca62bcc4b13ff08da24fdefc16ccd8b25282a2fda2ba1be24a", [:rebar3], [], "hexpm"}, + "ex_cldr": {:hex, :ex_cldr, "2.2.1", "aa5bc7209db7ff85d0e2ad89f4d013592769c36d2f7136755c3eff7fbbbc9425", [:mix], [{:cldr_utils, "~> 2.0", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"}, "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.0.0", "e91ee2cf81144cb308b2bf025c2877f38fc713475931efcd55885e149c2ae36f", [:mix], [{:ex_cldr, "~> 2.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.1.0", "ae7364223bea04e56d7f93b444e02b82c74c0d4230ab269b9688e3c0a5765ff1", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.1", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.0", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.19.2", "6f4081ccd9ed081b6dc0bd5af97a41e87f5554de469e7d76025fba535180565f", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"}, "gringotts": {:hex, :gringotts, "1.1.0", "2139543a33b131fac1b0bd94e6c2ff2190178b9f5b58cf71a8577f785b7fcbaf", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:elixir_xml_to_map, "~> 0.1", [hex: :elixir_xml_to_map, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.13", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.1.0", [hex: :poison, repo: "hexpm", optional: false]}, {:timex, "~> 3.2", [hex: :timex, repo: "hexpm", optional: false]}, {:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.15.0", "287a5d2304d516f63e56c469511c42b016423bcb167e61b611f6bad47e3ca60e", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "makeup": {:hex, :makeup, "0.6.0", "e0fd985525e8d42352782bd76253105fbab0a783ac298708ca9020636c9568af", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.11.0", "aa3446f67356afa5801618867587a8863f176f9c632fb62b20f49bd1ea335e8a", [:mix], [{:makeup, "~> 0.6", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, - "phoenix_html": {:hex, :phoenix_html, "2.13.0", "3bad10de5efb6c590f7aa5b316ad0d3faa054715414c9b562c410de4ffb885c5", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "phoenix_html": {:hex, :phoenix_html, "2.13.1", "fa8f034b5328e2dfa0e4131b5569379003f34bc1fafdaa84985b0b9d2f12e68b", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug": {:hex, :plug, "1.7.1", "8516d565fb84a6a8b2ca722e74e2cd25ca0fc9d64f364ec9dbec09d33eb78ccd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "stream_data": {:hex, :stream_data, "0.4.2", "fa86b78c88ec4eaa482c0891350fcc23f19a79059a687760ddcf8680aac2799b", [:mix], [], "hexpm"}, - "telemetry": {:hex, :telemetry, "0.2.0", "5b40caa3efe4deb30fb12d7cd8ed4f556f6d6bd15c374c2366772161311ce377", [:mix], [], "hexpm"}, - "timex": {:hex, :timex, "3.4.2", "d74649c93ad0e12ce5b17cf5e11fbd1fb1b24a3d114643e86dba194b64439547", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, + "telemetry": {:hex, :telemetry, "0.3.0", "099a7f3ce31e4780f971b4630a3c22ec66d22208bc090fe33a2a3a6a67754a73", [:rebar3], [], "hexpm"}, + "timex": {:hex, :timex, "3.5.0", "b0a23167da02d0fe4f1a4e104d1f929a00d348502b52432c05de875d0b9cffa5", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, "xml_builder": {:hex, :xml_builder, "2.1.1", "2d6d665f09cf1319e3e1c46035755271b414d99ad8615d0bd6f337623e0c885b", [:mix], [], "hexpm"}, diff --git a/mix/test.cldr.ex b/mix/test.cldr.ex index 015446b..a3e4b3d 100644 --- a/mix/test.cldr.ex +++ b/mix/test.cldr.ex @@ -3,6 +3,6 @@ defmodule Money.Cldr do use Cldr, locales: ["en", "de", "it", "es"], - providers: [Cldr, Cldr.Numbers] + providers: [Cldr, Cldr.Number] end \ No newline at end of file diff --git a/test/money_parse_test.exs b/test/money_parse_test.exs new file mode 100644 index 0000000..9f2939a --- /dev/null +++ b/test/money_parse_test.exs @@ -0,0 +1,43 @@ +defmodule MoneyTest.Parse do + use ExUnit.Case + + describe "Money.parse/2 " do + test "parses with currency code in front" do + assert Money.parse("USD 100") == Money.new(:USD, 100) + assert Money.parse("USD100") == Money.new(:USD, 100) + assert Money.parse("USD 100 ") == Money.new(:USD, 100) + assert Money.parse("USD100 ") == Money.new(:USD, 100) + assert Money.parse("USD 100.00") == Money.new(:USD, "100.00") + end + + test "parses with currency code out back" do + assert Money.parse("100 USD") == Money.new(:USD, 100) + assert Money.parse("100USD") == Money.new(:USD, 100) + assert Money.parse("100 USD ") == Money.new(:USD, 100) + assert Money.parse("100USD ") == Money.new(:USD, 100) + assert Money.parse("100.00USD") == Money.new(:USD, "100.00") + end + + test "parses with locale specific separators" do + assert Money.parse("100,00USD", locale: "de") == Money.new(:USD, "100.00") + end + + test "parsing fails" do + assert Money.parse("100") == {:error, + {Money.Invalid, + "A currency code must be specified but was not found in \"100\""}} + + assert Money.parse("EUR") == {:error, + {Money.Invalid, "An amount must be specified but was not found in \"EUR\""}} + + assert Money.parse("EUR 100 USD") == + {:error, {Money.Invalid, "A currency code can only be specified once. Found both \"EUR\" and \"USD\"."}} + + string = "EUR 100 And some bogus extra stuff" + assert {:error, {Money.Invalid, "Could not parse \"" <> string <> "\"."}} == Money.parse(string) + + string = "100 EUR And some bogus extra stuff" + assert {:error, {Money.Invalid, "Could not parse \"" <> string <> "\"."}} == Money.parse(string) + end + end +end \ No newline at end of file