diff --git a/CHANGELOG.md b/CHANGELOG.md index 221271e..9e0295c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,34 @@ # Changelog +## Cldr Numbers v2.33.0 + +This is the changelog for Cldr v2.33.0 released on April 21st, 2024. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_numbers/tags) + +### Enhancements + +* Update to [CLDR 45.0](https://cldr.unicode.org/index/downloads/cldr-45) data. + +* Support currency formatting when the given currency in a given locale uses a specific symbol that replaces the decimal separator. The only known example is the [Cape Verde escudo](https://en.wikipedia.org/wiki/Cape_Verdean_escudo). A formatted example formatting 20 CVE is `20$00`. + ## Cldr Numbers v2.32.4 This is the changelog for Cldr v2.32.4 released on January 18th, 2023. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_numbers/tags) ### Bug Fixes +<<<<<<< HEAD * Fix formatting a number when a currency is specified but the format has no currency symbol. Closes [ex_money 162](https://github.com/kipcole9/money/issues/162). ## Cldr Numbers v2.32.3 This is the changelog for Cldr v2.32.3 released on November 2nd, 2023. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_numbers/tags) +======= +* Fix formatting a number when a currency is specified but the format has no currency symbol. Closes [ex_money 162](https://github.com/kipcole9/money/issues/162). + +## Cldr Numbers v2.32.3 + +This is the changelog for Cldr v2.32.0 released on November 2nd, 2023. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_numbers/tags) +>>>>>>> cldr45 ### Bug Fixes @@ -48,7 +66,7 @@ This is the changelog for Cldr v2.32.0 released on September 4th, 2023. For old ### Deprecations -* `Cldr.Number.System.systems_with_digits/0` is deprecated in favour of `Cldr.Number.System.numeric_systems/0`. +* `Cldr.Number.System.systems_with_digits/0` is deprecated in favour of `Cldr.Number.System.numeric_systems/0`. ### Enhancements diff --git a/lib/cldr/number/backend/format.ex b/lib/cldr/number/backend/format.ex index 4f8192c..504e48b 100644 --- a/lib/cldr/number/backend/format.ex +++ b/lib/cldr/number/backend/format.ex @@ -154,8 +154,8 @@ defmodule Cldr.Number.Backend.Format do * `{:error, {exception, message}}` """ - @spec all_formats_for(LanguageTag.t() | Cldr.Locale.locale_name()) :: - {:ok, map()} | {:error, {module(), String.t()}} + @spec all_formats_for(Cldr.Locale.locale_reference()) :: + {:ok, %{System.system_name() => map()}} | {:error, {module(), String.t()}} def all_formats_for(locale \\ unquote(backend).get_locale()) @@ -182,7 +182,7 @@ defmodule Cldr.Number.Backend.Format do {:ok, 1} """ - @spec minimum_grouping_digits_for(LanguageTag.t() | Cldr.Locale.locale_name()) :: + @spec minimum_grouping_digits_for(Cldr.Locale.locale_reference()) :: {:ok, non_neg_integer} | {:error, {module(), String.t()}} def minimum_grouping_digits_for(locale \\ unquote(backend).get_locale()) @@ -210,7 +210,7 @@ defmodule Cldr.Number.Backend.Format do {:ok, %{fraction: %{first: 0, rest: 0}, integer: %{first: 3, rest: 3}}} """ - @spec default_grouping_for(LanguageTag.t() | Cldr.Locale.locale_name()) :: + @spec default_grouping_for(Cldr.Locale.locale_reference()) :: {:ok, map()} | {:error, {module(), String.t()}} def default_grouping_for(locale \\ unquote(backend).get_locale()) @@ -244,7 +244,9 @@ defmodule Cldr.Number.Backend.Format do locale_data |> get_in([:number_systems, :default]) - standard_format = number_formats[default_number_system].standard || @default_standard_format + standard_format = + number_formats[default_number_system].standard || @default_standard_format + {:ok, meta} = Cldr.Number.Format.Compiler.format_to_metadata(standard_format) def default_grouping_for(%LanguageTag{cldr_locale_name: unquote(locale_name)}) do @@ -286,7 +288,7 @@ defmodule Cldr.Number.Backend.Format do * `minumum_digits` or - * raises an exception + * raises an exception. ## Examples @@ -294,8 +296,9 @@ defmodule Cldr.Number.Backend.Format do 1 """ - @spec minimum_grouping_digits_for!(LanguageTag.t() | Cldr.Locale.locale_name()) :: - non_neg_integer | no_return() + @dialyzer {:no_underspecs, minimum_grouping_digits_for!: 1} + @spec minimum_grouping_digits_for!(Cldr.Locale.locale_reference()) :: + non_neg_integer() | no_return() def minimum_grouping_digits_for!(locale) do case minimum_grouping_digits_for(locale) do @@ -320,7 +323,7 @@ defmodule Cldr.Number.Backend.Format do * `grouping` as a map or - * raises an exception + * raises an exception. ## Examples @@ -328,8 +331,12 @@ defmodule Cldr.Number.Backend.Format do %{fraction: %{first: 0, rest: 0}, integer: %{first: 3, rest: 3}} """ - @spec default_grouping_for!(LanguageTag.t() | Cldr.Locale.locale_name()) :: - map() | no_return() + @spec default_grouping_for!(Cldr.Locale.locale_reference()) :: + %{ + fraction: %{first: non_neg_integer(), rest: non_neg_integer()}, + integer: %{first: non_neg_integer(), rest: non_neg_integer()} + } + | no_return() def default_grouping_for!(locale) do case default_grouping_for(locale) do @@ -370,13 +377,13 @@ defmodule Cldr.Number.Backend.Format do * `{:ok, map}` where map is a map of decimal formats keyed by number system or - * raises an exception + * raises an exception. See `#{inspect(__MODULE__)}.Number.Format.all_formats_for/1` for further information. """ - @spec all_formats_for!(LanguageTag.t() | Cldr.Locale.locale_name()) :: - map() | no_return() + @spec all_formats_for(Cldr.Locale.locale_reference()) :: + %{System.system_name() => map()} | no_return() def all_formats_for!(locale \\ unquote(backend).get_locale()) do case all_formats_for(locale) do diff --git a/lib/cldr/number/backend/number.ex b/lib/cldr/number/backend/number.ex index 5c39c8c..92df3be 100644 --- a/lib/cldr/number/backend/number.ex +++ b/lib/cldr/number/backend/number.ex @@ -419,7 +419,7 @@ defmodule Cldr.Number.Backend.Number do number | Decimal.t() | String.t(), Keyword.t() | map() ) :: - String.t() | no_return() + String.t() | no_return() def to_string!(number, options \\ default_options()) do Cldr.Number.to_string!(number, unquote(backend), options) end diff --git a/lib/cldr/number/backend/system.ex b/lib/cldr/number/backend/system.ex index 98cadc2..fe0ba5f 100644 --- a/lib/cldr/number/backend/system.ex +++ b/lib/cldr/number/backend/system.ex @@ -351,8 +351,8 @@ defmodule Cldr.Number.Backend.System do """ @spec system_name_from( Cldr.Number.System.system_name(), - Cldr.Locale.locale_name() | LanguageTag.t() - ) :: {:ok, atom} | {:error, {module(), String.t()}} + Cldr.Locale.locale_reference() + ) :: {:ok, Cldr.Number.System.system_name()} | {:error, {module(), String.t()}} def system_name_from(system_name, locale) do Cldr.Number.System.system_name_from(system_name, locale, unquote(backend)) @@ -362,7 +362,7 @@ defmodule Cldr.Number.Backend.System do Cldr.Locale.locale_reference(), Cldr.Number.System.system_name() ) :: - {:ok, list()} | {:error, tuple} + {:ok, list()} | {:error, {module(), String.t()}} def number_systems_like(locale, number_system) do Cldr.Number.System.number_systems_like(locale, number_system, unquote(backend)) diff --git a/lib/cldr/number/format/compiler.ex b/lib/cldr/number/format/compiler.ex index 1e5a54a..8f682e9 100644 --- a/lib/cldr/number/format/compiler.ex +++ b/lib/cldr/number/format/compiler.ex @@ -400,7 +400,7 @@ defmodule Cldr.Number.Format.Compiler do defp currency_location(parts) do location = Enum.reduce_while(parts, 0, fn - {:currency, count}, offset -> {:halt, %{location: offset, symbol_count: count}} + {:currency, count}, offset -> {:halt, %{location: offset, symbol_count: count}} _other, offset -> {:cont, offset + 1} end) diff --git a/lib/cldr/number/format/meta.ex b/lib/cldr/number/format/meta.ex index dcd5b79..153dcb2 100644 --- a/lib/cldr/number/format/meta.ex +++ b/lib/cldr/number/format/meta.ex @@ -123,12 +123,30 @@ defmodule Cldr.Number.Format.Meta do currency: nil, format: [ positive: [format: "#"], - negative: [minus: '-', format: :same_as_positive] + negative: [minus: ~c"-", format: :same_as_positive] ], number: 0 @typedoc "Metadata type that drives how to format a number" - @type t :: %__MODULE__{} + @type t :: %__MODULE__{ + :currency => nil | Cldr.Currency.t(), + :exponent_digits => non_neg_integer(), + :exponent_sign => boolean(), + :format => [{:negative, [any(), ...]} | {:positive, [any(), ...]}, ...], + :fractional_digits => %{:max => non_neg_integer(), :min => non_neg_integer()}, + :grouping => %{ + :fraction => %{:first => non_neg_integer(), :rest => non_neg_integer()}, + :integer => %{:first => non_neg_integer(), :rest => non_neg_integer()} + }, + :integer_digits => %{:max => non_neg_integer(), :min => non_neg_integer()}, + :multiplier => non_neg_integer(), + :number => non_neg_integer(), + :padding_char => String.t(), + :padding_length => non_neg_integer(), + :round_nearest => non_neg_integer(), + :scientific_rounding => non_neg_integer(), + :significant_digits => %{:max => non_neg_integer(), :min => non_neg_integer()} + } @doc """ Returns a new number formatting metadata @@ -333,6 +351,6 @@ defmodule Cldr.Number.Format.Meta do @spec put_format(t(), Keyword.t()) :: t() def put_format(%__MODULE__{} = meta, positive_format) do - put_format(meta, positive_format, minus: '-', format: :same_as_positive) + put_format(meta, positive_format, minus: ~c"-", format: :same_as_positive) end end diff --git a/lib/cldr/number/format/options.ex b/lib/cldr/number/format/options.ex index 09dca3f..f2fec1d 100644 --- a/lib/cldr/number/format/options.ex +++ b/lib/cldr/number/format/options.ex @@ -82,10 +82,10 @@ defmodule Cldr.Number.Format.Options do :symbol ] - @type fixed_formats :: :standard | :currency | :accounting | :short | :long - @type format :: binary() | fixed_formats() + @type fixed_format :: :standard | :currency | :accounting | :short | :long + @type format :: binary() | fixed_format() @type currency_symbol :: :standard | :iso - @type short_format_styles :: + @type short_format_style :: :currency_short | :currency_long | :currency_long_with_symbol @@ -173,7 +173,8 @@ defmodule Cldr.Number.Format.Options do # :narrow, the format to :currency @doc false - defp maybe_adjust_currency_format(options, currency, :narrow, backend) when not is_nil(currency) do + defp maybe_adjust_currency_format(options, currency, :narrow, backend) + when not is_nil(currency) do currency_format = derive_currency_format(options) options @@ -197,34 +198,43 @@ defmodule Cldr.Number.Format.Options do options end - defp set_default_fractional_digits(%{fractional_digits: nil, currency_digits: :accounting} = options, backend) do + defp set_default_fractional_digits( + %{fractional_digits: nil, currency_digits: :accounting} = options, + backend + ) do case Cldr.Currency.currency_for_code(options.currency, backend, locale: options.locale) do {:ok, currency} -> Map.put(options, :fractional_digits, currency.digits) _other -> options - end + end end - defp set_default_fractional_digits(%{fractional_digits: nil, currency_digits: :cash} = options, backend) do + defp set_default_fractional_digits( + %{fractional_digits: nil, currency_digits: :cash} = options, + backend + ) do case Cldr.Currency.currency_for_code(options.currency, backend, locale: options.locale) do {:ok, currency} -> Map.put(options, :fractional_digits, currency.cash_digits) _other -> options - end + end end - defp set_default_fractional_digits(%{fractional_digits: nil, currency_digits: :iso} = options, backend) do + defp set_default_fractional_digits( + %{fractional_digits: nil, currency_digits: :iso} = options, + backend + ) do case Cldr.Currency.currency_for_code(options.currency, backend, locale: options.locale) do {:ok, currency} -> Map.put(options, :fractional_digits, currency.iso_digits) _other -> options - end + end end defp set_default_fractional_digits(options, _backend) do @@ -247,7 +257,8 @@ defmodule Cldr.Number.Format.Options do %{locale: locale, number_system: number_system} = options with {:ok, formats} <- Format.formats_for(locale, number_system, backend), - {:ok, resolved_format} <- standard_format(formats, format, locale, number_system, backend) do + {:ok, resolved_format} <- + standard_format(formats, format, locale, number_system, backend) do Map.put(options, :format, resolved_format) end end @@ -538,7 +549,6 @@ defmodule Cldr.Number.Format.Options do end end - defp validate_option(:format, _options, _backend, format) do {:ok, format} end @@ -727,7 +737,7 @@ defmodule Cldr.Number.Format.Options do end @doc false - @spec short_format_styles() :: list(atom()) + @spec short_format_styles() :: [short_format_style(), ...] def short_format_styles do @short_formats end @@ -771,7 +781,14 @@ defmodule Cldr.Number.Format.Options do case metadata.currency do %{symbol_count: symbol_count} -> symbol = - currency_symbol(currency, options.currency_symbol, number, symbol_count, options.locale, backend) + currency_symbol( + currency, + options.currency_symbol, + number, + symbol_count, + options.locale, + backend + ) Map.put(options, :currency_symbol, symbol) diff --git a/lib/cldr/number/formatter/decimal_formatter.ex b/lib/cldr/number/formatter/decimal_formatter.ex index 8e19b36..7f52c62 100644 --- a/lib/cldr/number/formatter/decimal_formatter.ex +++ b/lib/cldr/number/formatter/decimal_formatter.ex @@ -539,16 +539,17 @@ defmodule Cldr.Number.Formatter.Decimal do {_sign, integer, fraction, exponent_sign, exponent}, meta, _backend, - _options + options ) do - integer = if integer == [], do: ['0'], else: integer - fraction = if fraction == [], do: fraction, else: [@decimal_separator, fraction] + decimal_separator = decimal_separator(options, @decimal_separator) + integer = if integer == [], do: [~c"0"], else: integer + fraction = if fraction == [], do: fraction, else: [decimal_separator, fraction] exponent_sign = cond do exponent_sign < 0 -> @minus_placeholder meta.exponent_sign -> @exponent_sign - true -> '' + true -> ~c"" end exponent = @@ -563,7 +564,8 @@ defmodule Cldr.Number.Formatter.Decimal do [] end - :erlang.iolist_to_binary([integer, fraction, exponent]) + [integer, fraction, exponent] + |> :erlang.iolist_to_binary() end # Now we can assemble the final format. Based upon @@ -576,8 +578,12 @@ defmodule Cldr.Number.Formatter.Decimal do format = meta.format[options.pattern] number = meta.number - assemble_parts(format, number_string, number, backend, meta, options) - |> :erlang.iolist_to_binary() + formatted = + assemble_parts(format, number_string, number, backend, meta, options) + |> :erlang.iolist_to_binary() + |> String.trim_trailing() + + formatted end defp assemble_parts( @@ -646,12 +652,17 @@ defmodule Cldr.Number.Formatter.Decimal do [] end + @nbsp "\u200b" + defp assemble_parts([{:currency, _type} | rest], number_string, number, backend, meta, options) do %{currency_symbol: symbol, wrapper: wrapper} = options - symbol = maybe_wrap(symbol, :currency_symbol, wrapper) - - [symbol | assemble_parts(rest, number_string, number, backend, meta, options)] + if symbol == @nbsp do + assemble_parts(rest, number_string, number, backend, meta, options) + else + symbol = maybe_wrap(symbol, :currency_symbol, wrapper) + [symbol | assemble_parts(rest, number_string, number, backend, meta, options)] + end end defp assemble_parts( @@ -805,7 +816,8 @@ defmodule Cldr.Number.Formatter.Decimal do end @doc false - def transliterate(number_string, _meta, backend, %{locale: locale, number_system: number_system}) do + def transliterate(number_string, _meta, backend, options) do + %{locale: locale, number_system: number_system} = options Cldr.Number.Transliterate.transliterate(number_string, locale, number_system, backend) end @@ -1024,4 +1036,16 @@ defmodule Cldr.Number.Formatter.Decimal do String.match?(number_string, Regex.compile!("^" <> spacing[:surrounding_match], "u")) && String.match?(symbol, Regex.compile!(spacing[:currency_match] <> "$", "u")) end + + defp decimal_separator(%{currency: %{decimal_separator: nil}}, default_decimal_separator) do + default_decimal_separator + end + + defp decimal_separator(%{currency: %{decimal_separator: separator}}, _default_decimal_separator) do + separator + end + + defp decimal_separator(_options, default_decimal_separator) do + default_decimal_separator + end end diff --git a/lib/cldr/number/rbnf.ex b/lib/cldr/number/rbnf.ex index 9d60a37..741b439 100644 --- a/lib/cldr/number/rbnf.ex +++ b/lib/cldr/number/rbnf.ex @@ -225,7 +225,7 @@ defmodule Cldr.Rbnf do |> Cldr.Map.merge_map_list() end - def rbnf_locale_error(%LanguageTag{} = locale) do + def rbnf_locale_error(%LanguageTag{} = locale) do {Cldr.Rbnf.NotAvailable, "RBNF is not available for locale #{inspect(locale)}"} end @@ -246,8 +246,9 @@ defmodule Cldr.Rbnf do function = to_string(rule_group) case function do - <> when digit in ?0..?9 -> + <> when digit in ?0..?9 -> "r" <> function + _other -> function end diff --git a/lib/cldr/number/system.ex b/lib/cldr/number/system.ex index b65d871..94f8d7e 100644 --- a/lib/cldr/number/system.ex +++ b/lib/cldr/number/system.ex @@ -113,7 +113,7 @@ defmodule Cldr.Number.System do @doc """ Return the default number system type name. - The default number system type is `#{inspect @default_number_system_type}`. + The default number system type is `#{inspect(@default_number_system_type)}`. Note that this is not the number system itself but the type of the number system. @@ -137,7 +137,7 @@ defmodule Cldr.Number.System do 88 """ - @spec number_systems :: map() + @spec number_systems :: unquote(Cldr.Type.number_systems()) @number_systems Cldr.Config.number_systems() def number_systems do @@ -145,9 +145,9 @@ defmodule Cldr.Number.System do end @numeric_systems Enum.reject(@number_systems, fn {_name, system} -> - is_nil(system[:digits]) - end) - |> Map.new() + is_nil(system[:digits]) + end) + |> Map.new() @doc """ Returns a map of the number systems that have @@ -301,7 +301,7 @@ defmodule Cldr.Number.System do """ @spec number_system_from_locale(Locale.locale_reference(), Cldr.backend()) :: - system_name | {:error, {module(), String.t()}} + system_name | {:error, {module(), String.t()}} def number_system_from_locale(%LanguageTag{locale: %{numbers: nil}} = locale, backend) do locale @@ -352,7 +352,7 @@ defmodule Cldr.Number.System do """ @spec number_system_from_locale(Locale.locale_reference()) :: - system_name | {:error, {module(), String.t()}} + system_name | {:error, {module(), String.t()}} def number_system_from_locale(%LanguageTag{locale: %{numbers: nil}} = locale) do number_system_from_locale(locale.cldr_locale_name, locale.backend) @@ -1098,11 +1098,11 @@ defmodule Cldr.Number.System do nil -> unknown_number_system_error(system_name) - _system -> - { - Cldr.UnknownNumberSystemError, - "The number system #{inspect(system_name)} does not have digits" - } + _system -> + { + Cldr.UnknownNumberSystemError, + "The number system #{inspect(system_name)} does not have digits" + } end end @@ -1112,11 +1112,11 @@ defmodule Cldr.Number.System do nil -> unknown_number_system_error(system_name) - _system -> - { - Cldr.UnknownNumberSystemError, - "The number system #{inspect(system_name)} is not algorithmic" - } + _system -> + { + Cldr.UnknownNumberSystemError, + "The number system #{inspect(system_name)} is not algorithmic" + } end end diff --git a/mix.exs b/mix.exs index 64ad1ce..1dba380 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule Cldr.Numbers.Mixfile do use Mix.Project - @version "2.32.4" + @version "2.33.0" def project do [ @@ -22,7 +22,8 @@ defmodule Cldr.Numbers.Mixfile do compilers: [:leex, :yecc] ++ Mix.compilers(), dialyzer: [ ignore_warnings: ".dialyzer_ignore_warnings", - plt_add_apps: ~w(inets jason mix)a + plt_add_apps: ~w(inets jason mix)a, + flags: [:underspecs] ] ] end @@ -42,9 +43,12 @@ defmodule Cldr.Numbers.Mixfile do defp deps do [ - {:ex_cldr, "~> 2.37"}, + # {:ex_cldr, path: "../cldr", override: true}, + {:ex_cldr, "~> 2.38"}, + + # {:ex_cldr_currencies, path: "../cldr_currencies"}, + {:ex_cldr_currencies, "~> 2.16"}, - {:ex_cldr_currencies, ">= 2.14.2"}, {:digital_token, "~> 0.3 or ~> 1.0"}, {:decimal, "~> 1.6 or ~> 2.0"}, {:jason, "~> 1.0", optional: true}, diff --git a/mix.lock b/mix.lock index 4274d3f..7123f90 100644 --- a/mix.lock +++ b/mix.lock @@ -1,21 +1,21 @@ %{ "benchee": {:hex, :benchee, "1.3.0", "f64e3b64ad3563fa9838146ddefb2d2f94cf5b473bdfd63f5ca4d0657bf96694", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "34f4294068c11b2bd2ebf2c59aac9c7da26ffa0068afdf3419f1b176e16c5f81"}, - "cldr_utils": {:hex, :cldr_utils, "2.24.2", "364fa30be55d328e704629568d431eb74cd2f085752b27f8025520b566352859", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "3362b838836a9f0fa309de09a7127e36e67310e797d556db92f71b548832c7cf"}, + "cldr_utils": {:hex, :cldr_utils, "2.25.0", "3cc2ab6e9e4f855ba78a3f3fc4963ccf7b68b731f4e91de3d9b310adddb96b62", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "9041660356ffa1129e0d87d110e188f5da0e0bba94fb915e11275e04ace066e1"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, "digital_token": {:hex, :digital_token, "0.6.0", "13e6de581f0b1f6c686f7c7d12ab11a84a7b22fa79adeb4b50eec1a2d278d258", [:mix], [{:cldr_utils, "~> 2.17", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "2455d626e7c61a128b02a4a8caddb092548c3eb613ac6f6a85e4cbb6caddc4d1"}, "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_cldr": {:hex, :ex_cldr, "2.37.5", "9da6d97334035b961d2c2de167dc6af8cd3e09859301a5b8f49f90bd8b034593", [:mix], [{:cldr_utils, "~> 2.21", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "74ad5ddff791112ce4156382e171a5f5d3766af9d5c4675e0571f081fe136479"}, - "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.15.0", "aadd34e91cfac7ef6b03fe8f47f8c6fa8c5daf3f89b5d9fee64ec545ded839cf", [:mix], [{:ex_cldr, "~> 2.34", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "0521316396c66877a2d636219767560bb2397c583341fcb154ecf9f3000e6ff8"}, - "ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"}, + "ex_cldr": {:hex, :ex_cldr, "2.38.0", "80399ccbfd996ea02f245394db83d7ce6113ed88e1e50e4695238cd9a0c258d5", [:mix], [{:cldr_utils, "~> 2.25", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "8758000c97bdf4b2583c3fedd7cfa35896567a7f8351248b2faa33ba73841cc7"}, + "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.16.0", "fb62b5ed735427989a2b1c0f7089ed08d8387666cc59b8257f2376d1a39e5a2d", [:mix], [{:ex_cldr, "~> 2.38", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "7b1cc81605fa7023d896430d2ead36adb6abe13d09573500cba130824e10baf0"}, + "ex_doc": {:hex, :ex_doc, "0.32.1", "21e40f939515373bcdc9cffe65f3b3543f05015ac6c3d01d991874129d173420", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5142c9db521f106d61ff33250f779807ed2a88620e472ac95dc7d59c380113da"}, "exprintf": {:hex, :exprintf, "0.2.1", "b7e895dfb00520cfb7fc1671303b63b37dc3897c59be7cbf1ae62f766a8a0314", [:mix], [], "hexpm", "20a0e8c880be90e56a77fcc82533c5d60c643915c7ce0cc8aa1e06ed6001da28"}, "exprof": {:hex, :exprof, "0.2.4", "13ddc0575a6d24b52e7c6809d2a46e9ad63a4dd179628698cdbb6c1f6e497c98", [:mix], [{:exprintf, "~> 0.2", [hex: :exprintf, repo: "hexpm", optional: false]}], "hexpm", "0884bcb66afc421c75d749156acbb99034cc7db6d3b116c32e36f32551106957"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "phoenix_html": {:hex, :phoenix_html, "3.3.3", "380b8fb45912b5638d2f1d925a3771b4516b9a78587249cabe394e0a5d579dc9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "923ebe6fec6e2e3b3e569dfbdc6560de932cd54b000ada0208b5f45024bdd76c"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, diff --git a/mix/test_backend.ex b/mix/test_backend.ex index d37a4ef..f6c5359 100644 --- a/mix/test_backend.ex +++ b/mix/test_backend.ex @@ -25,7 +25,9 @@ defmodule MyApp.Cldr do "fr-CH", "fr-BE", "ta", - "he" + "he", + "pt-CV", + "ar-EG" ], precompile_transliterations: [{:latn, :arab}, {:arab, :thai}, {:arab, :latn}], providers: [Cldr.Number], diff --git a/test/meta_test.exs b/test/meta_test.exs index 1c7f9c8..098fd6b 100644 --- a/test/meta_test.exs +++ b/test/meta_test.exs @@ -8,7 +8,7 @@ defmodule Cldr.Number.Format.Meta.Test do exponent_sign: false, format: [ positive: [format: "#"], - negative: [minus: '-', format: :same_as_positive] + negative: [minus: ~c"-", format: :same_as_positive] ], fractional_digits: %{max: 0, min: 0}, grouping: %{fraction: %{first: 0, rest: 0}, integer: %{first: 0, rest: 0}}, diff --git a/test/number/currency_test.exs b/test/number/currency_test.exs index 38a17a4..f14e965 100644 --- a/test/number/currency_test.exs +++ b/test/number/currency_test.exs @@ -2,8 +2,16 @@ defmodule Cldr.Number.CurrencyTest do use ExUnit.Case, async: true test "That the currency is derived from the locale" do - assert {:ok, "AU$๑๒๓.๐๐"} == MyApp.Cldr.Number.to_string(123, locale: "th-u-cu-aud-nu-thai", currency: :from_locale) - assert {:ok, "฿๑๒๓.๐๐"} == MyApp.Cldr.Number.to_string(123, locale: "th-u-nu-thai", currency: :from_locale) - assert {:ok, "฿123.00"} == MyApp.Cldr.Number.to_string(123, locale: "th", currency: :from_locale) + assert {:ok, "AU$๑๒๓.๐๐"} == + MyApp.Cldr.Number.to_string(123, + locale: "th-u-cu-aud-nu-thai", + currency: :from_locale + ) + + assert {:ok, "฿๑๒๓.๐๐"} == + MyApp.Cldr.Number.to_string(123, locale: "th-u-nu-thai", currency: :from_locale) + + assert {:ok, "฿123.00"} == + MyApp.Cldr.Number.to_string(123, locale: "th", currency: :from_locale) end -end \ No newline at end of file +end diff --git a/test/number/number_format_test.exs b/test/number/number_format_test.exs index b6967f7..8156d10 100644 --- a/test/number/number_format_test.exs +++ b/test/number/number_format_test.exs @@ -62,13 +62,13 @@ defmodule Number.Format.Test do test "that an rbnf format request fails if the locale doesn't define the ruleset" do assert TestBackend.Cldr.Number.to_string(123, format: :spellout_ordinal_verbose, locale: "zh") == - { - :error, - { - Cldr.Rbnf.NoRule, - "RBNF rule :spellout_ordinal_verbose is unknown to locale #Cldr.LanguageTag" - } - } + { + :error, + { + Cldr.Rbnf.NoRule, + "RBNF rule :spellout_ordinal_verbose is unknown to locale TestBackend.Cldr.Locale.new!(\"zh-Hans-CN\")" + } + } end test "that we get default formats_for" do @@ -195,18 +195,25 @@ defmodule Number.Format.Test do end test "A free form currency format where the currency symbol is not first or last" do - assert {:ok, "US$1,234"} = MyApp.Cldr.Number.to_string(1234, currency: "USD", format: "US¤#,###") + assert {:ok, "US$1,234"} = + MyApp.Cldr.Number.to_string(1234, currency: "USD", format: "US¤#,###") end test "Digital tokens with overriden symbols" do assert {:ok, "₿ 1,234,545,656.456789"} = - Cldr.Number.to_string(1_234_545_656.456789, currency: "BTC", currency_symbol: :narrow) + Cldr.Number.to_string(1_234_545_656.456789, + currency: "BTC", + currency_symbol: :narrow + ) assert {:ok, "BTC 1,234,545,656.456789"} = Cldr.Number.to_string(1_234_545_656.456789, currency: "BTC", currency_symbol: :iso) assert {:ok, "₿ 1,234,545,656.456789"} = - Cldr.Number.to_string(1_234_545_656.456789, currency: "BTC", currency_symbol: :symbol) + Cldr.Number.to_string(1_234_545_656.456789, + currency: "BTC", + currency_symbol: :symbol + ) assert {:ok, "₿ 1,234,545,656.456789"} = Cldr.Number.to_string(1_234_545_656.456789, @@ -219,7 +226,8 @@ defmodule Number.Format.Test do end test "Formatting a number with standard format in a locale with no RBNF" do - for {_locale, language_tag} <- Cldr.Config.all_language_tags(), is_nil(language_tag.rbnf_locale_name) do + for {_locale, language_tag} <- Cldr.Config.all_language_tags(), + is_nil(language_tag.rbnf_locale_name) do assert {:ok, _formatted_number} = Cldr.Number.to_string(1234, locale: language_tag) end end @@ -228,13 +236,23 @@ defmodule Number.Format.Test do for locale <- TestBackend.Cldr.known_locale_names() do {:ok, systems} = TestBackend.Cldr.Number.System.number_systems_for(locale) number_systems = Enum.uniq(Map.keys(systems) ++ Map.values(systems)) + for number_system <- number_systems do - assert {:ok, _} = TestBackend.Cldr.Number.to_string(123, locale: locale, number_system: number_system) + assert {:ok, _} = + TestBackend.Cldr.Number.to_string(123, + locale: locale, + number_system: number_system + ) end end end test "Formatting when a currency is specified but the format has no currency symbol" do - assert {:ok, _} = Cldr.Number.to_string(1234, curency: :CAD, format: "#,##0.###;-#,##0.###", locale: :en) + assert {:ok, _} = + Cldr.Number.to_string(1234, + curency: :CAD, + format: "#,##0.###;-#,##0.###", + locale: :en + ) end end diff --git a/test/number/rbnf_test.exs b/test/number/rbnf_test.exs index ea9509c..29fc409 100644 --- a/test/number/rbnf_test.exs +++ b/test/number/rbnf_test.exs @@ -143,11 +143,17 @@ defmodule Rbnf.Test do end test "RBNF Spellout for spanish" do - assert TestBackend.Cldr.Number.to_string(123.456, format: :spellout_cardinal_masculine, locale: :es) == - {:ok, "ciento veintitrés punto cuatro cinco seis"} - - assert TestBackend.Cldr.Number.to_string(123.456, format: :spellout_cardinal_feminine, locale: :es) == - {:ok, "ciento veintitrés punto cuatro cinco seis"} + assert TestBackend.Cldr.Number.to_string(123.456, + format: :spellout_cardinal_masculine, + locale: :es + ) == + {:ok, "ciento veintitrés punto cuatro cinco seis"} + + assert TestBackend.Cldr.Number.to_string(123.456, + format: :spellout_cardinal_feminine, + locale: :es + ) == + {:ok, "ciento veintitrés punto cuatro cinco seis"} end Elixir.Cldr.Rbnf.TestSupport.rbnf_tests(fn name, tests, module, function, locale -> diff --git a/test/support/number_format_test_data.exs b/test/support/number_format_test_data.exs index 0b9dd8f..f857b46 100644 --- a/test/support/number_format_test_data.exs +++ b/test/support/number_format_test_data.exs @@ -56,6 +56,9 @@ defmodule Cldr.Test.Number.Format do {1234, "COP 1,234.00", [currency: :COP, currency_digits: :iso]}, {1234, "COP 1,234.00", [currency: :COP]}, + # Currency where the symbol replaces the decimal separator + {1234, "1234$00", [currency: :CVE, locale: "pt-CV"]}, + # Currency default fractional digits {1234, "¥1,234", [currency: :JPY]}, {1234, "TND 1,234.000", [currency: :TND]}, diff --git a/test/support/rbnf/id/rbnf_test.json b/test/support/rbnf/id/rbnf_test.json index 2cd00a8..83cf511 100644 --- a/test/support/rbnf/id/rbnf_test.json +++ b/test/support/rbnf/id/rbnf_test.json @@ -8,8 +8,8 @@ "-75": "negatif ketujuh puluh lima", "-50": "negatif kelima puluh", "-24": "negatif kedua puluh empat", - "0": "kekosong", - "1": "kesatu", + "0": "kenol", + "1": "pertama", "2": "kedua", "3": "ketiga", "4": "keempat", @@ -126,7 +126,7 @@ "-75": "negatif tujuh puluh lima", "-50": "negatif lima puluh", "-24": "negatif dua puluh empat", - "0": "kosong", + "0": "nol", "1": "satu", "2": "dua", "3": "tiga", @@ -244,7 +244,7 @@ "-75": "negatif tujuh puluh lima", "-50": "negatif lima puluh", "-24": "negatif dua puluh empat", - "0": "kosong", + "0": "nol", "1": "satu", "2": "dua", "3": "tiga", @@ -362,7 +362,7 @@ "-75": "negatif tujuh puluh lima", "-50": "negatif lima puluh", "-24": "negatif dua puluh empat", - "0": "kosong", + "0": "nol", "1": "satu", "2": "dua", "3": "tiga",