Skip to content

Commit

Permalink
Add tests for Cldr.HTML.Unit and update changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
kipcole9 committed Feb 7, 2021
1 parent 40b302c commit c5fb870
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 20 deletions.
Empty file added .dialyzer_ignore_warnings
Empty file.
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Changelog for Cldr_HTML v1.0.0
# Changelog for Cldr_HTML v0.2.0

This is the changelog for Cldr HTML v1.0.0 released on November 1st, 2020. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_numbers/tags)
This is the changelog for Cldr HTML v1.1.0 released on February 7th, 2021. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_html/tags)

### Enhancements

* Add `Cldr.HTML.Unit.unit_select/3`

* Use `Cldr.get_locale/0` not `Cldr.default_locale/0` as default parameter

# Changelog for Cldr_HTML v0.1.0

This is the changelog for Cldr HTML v0.1.0 released on November 1st, 2020. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_html/tags)

### Enhancements

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ HTML helper functions for CLDR.

* [Implemented] Select currencies - by default the currencies of the locales configured in the default backend

* [Implemented] Select units - by default the units returned by `Cldr.Unit.known_units/0`

* [Not Implemented] Select territories

* [Not Implemented] Select languages
Expand All @@ -27,7 +29,7 @@ HTML helper functions for CLDR.
```elixir
def deps do
[
{:ex_cldr_html, "~> 0.1"}
{:ex_cldr_html, "~> 1.0"}
]
end
```
Expand Down
3 changes: 2 additions & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use Mix.Config

config :ex_cldr,
default_locale: "en-001"
default_locale: "en-001",
default_backend: MyApp.Cldr
5 changes: 5 additions & 0 deletions lib/cldr_html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ defmodule Cldr.HTML do
if Cldr.Code.ensure_compiled?(Cldr.Currency) do
defdelegate currency_select(form, field, options), to: Cldr.HTML.Currency, as: :select
end

if Cldr.Code.ensure_compiled?(Cldr.Unit) do
defdelegate unit_select(form, field, options), to: Cldr.HTML.Unit, as: :select
end

end
6 changes: 3 additions & 3 deletions lib/cldr_html_currencies.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if Cldr.Code.ensure_compiled?(Cldr.Currency) do

@type select_options :: [
{:currencies, [atom() | binary(), ...]}
| {:locale, binary() | Cldr.LanguageTag.t()}
| {:locale, Cldr.Locale.locale_name() | Cldr.LanguageTag.t()}
| {:mapper, function()}
| {:backend, module()}
| {:selected, atom() | binary()}
Expand Down Expand Up @@ -39,7 +39,7 @@ if Cldr.Code.ensure_compiled?(Cldr.Currency) do
* `:locale` defines the locale to be used to localise the
description of the currencies. The default is the locale
returned by `Cldr.default_locale/1`
returned by `Cldr.get_locale/1`
* `:backend` is any backend module. The default is
`Cldr.default_backend!/0`
Expand Down Expand Up @@ -114,7 +114,7 @@ if Cldr.Code.ensure_compiled?(Cldr.Currency) do
defp default_options do
Map.new(
currencies: default_currency_list(),
locale: Cldr.default_locale(),
locale: Cldr.get_locale(),
backend: Cldr.default_backend!(),
mapper: &{&1.code <> " - " <> &1.name, &1.code},
selected: nil
Expand Down
179 changes: 179 additions & 0 deletions lib/cldr_html_units.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
if Cldr.Code.ensure_compiled?(Cldr.Unit) do
defmodule Cldr.HTML.Unit do
@moduledoc """
Implements `Phoenix.HTML.Form.select/4` specifically for
localised unit display.
"""

@type select_options :: [
{:units, [atom() | binary(), ...]}
| {:locale, Cldr.Locale.locale_name() | Cldr.LanguageTag.t()}
| {:mapper, function()}
| {:backend, module()}
| {:selected, atom() | binary()}
]

@doc """
Generate an HTML select tag for a unit list
that can be used with a `Phoenix.HTML.Form.t`.
## Arguments
* A `t:Phoenix.HTML.Form` form
* A `t:Phoenix.HTML.Form.field` field
* A `t:Keyword` list of options
## Options
For select options see `Phoenix.HTML.Form.select/4`
* `:units` is a list of units to be displayed in the
select. See `Cldr.Unit.known_units/0` and
`Cldr.Unit.known_units_for_category/1`
* `:locale` defines the locale to be used to localise the
description of the units. The default is the locale
returned by `Cldr.get_locale/0`
* `:backend` is any backend module. The default is
`Cldr.default_backend!/0`
* `:mapper` is a function that creates the text to be
displayed in the select tag for each unit. It is
passed the unit name. The default function
is `&({Cldr.Unit.display_name(&1), &1})`
* `:selected` identifies the unit that is to be selected
by default in the `select` tag. The default is `nil`. This
is passed unmodified to `Phoenix.HTML.Form.select/4`
* `:prompt` is a prompt displayed at the top of the select
box. This is passed unmodified to `Phoenix.HTML.Form.select/4`
# Examples
=> Cldr.HTML.Unit.select(:my_form, :unit, selected: :foot)
=> Cldr.HTML.Unit.select(:my_form, :unit,
units: [:foot, :inch], mapper: &{Cldr.Unit.display_name(&1, &2), &1})
"""
@spec select(
form :: Phoenix.HTML.Form.t(),
field :: Phoenix.HTML.Form.field(),
select_options
) ::
Phoenix.HTML.safe()
| {:error, {Cldr.UnknownUnitError, binary()}}
| {:error, {Cldr.UnknownLocaleError, binary()}}

def select(form, field, options \\ [])

def select(form, field, options) when is_list(options) do
select(form, field, validate_options(options), options[:selected])
end

# Invalid options
defp select(_form, _field, {:error, reason}, _selected) do
{:error, reason}
end

# Selected currency
defp select(form, field, options, _selected) do
select_options =
options
|> Map.take([:selected, :prompt])
|> Map.to_list

options =
options
|> maybe_include_selected_unit
|> unit_options

Phoenix.HTML.Form.select(form, field, options, select_options)
end

defp validate_options(options) do
with options <- Map.merge(default_options(), Map.new(options)),
{:ok, options} <- validate_selected(options),
{:ok, options} <- validate_units(options),
{:ok, options} <- validate_locale(options) do
options
end
end

defp default_options do
Map.new(
units: default_unit_list(),
backend: Cldr.default_backend!(),
locale: Cldr.get_locale(),
mapper: &{Cldr.Unit.display_name(&1, &2), &1},
selected: nil
)
end

defp validate_selected(%{selected: nil} = options) do
{:ok, options}
end

defp validate_selected(%{selected: selected} = options) do
with {:ok, unit, _conversion} <- Cldr.Unit.validate_unit(selected) do
{:ok, Map.put(options, :selected, unit)}
end
end

# Return a list of validated units or an error
defp validate_units(%{units: units} = options) do
validate_units(units, options)
end

defp validate_units(units) when is_list(units) do
Enum.reduce_while(units, [], fn unit, acc ->
case Cldr.Unit.validate_unit(unit) do
{:ok, unit, _conversion} -> {:cont, [unit | acc]}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
end

defp validate_units(units, options) do
case validate_units(units) do
{:error, reason} -> {:error, reason}
units -> {:ok, Map.put(options, :units, Enum.reverse(units))}
end
end

defp validate_locale(%{locale: locale} = options) do
with {:ok, locale} <- Cldr.validate_locale(locale) do
{:ok, Map.put(options, :locale, locale)}
end
end

defp maybe_include_selected_unit(%{selected: nil} = options) do
options
end

defp maybe_include_selected_unit(%{units: units, selected: selected} = options) do
if Enum.any?(units, &(&1 == selected)) do
options
else
Map.put(options, :units, [selected | units])
end
end

defp unit_options(options) do
options = Map.to_list(options)

options[:units]
|> Enum.map(fn unit -> options[:mapper].(unit, options) end)
|> Enum.sort()
end

defp default_unit_list() do
Cldr.Unit.known_units()
end

end
end
12 changes: 9 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Cldr.Html.MixProject do
use Mix.Project

@version "0.1.0"
@version "0.2.0"

def project do
[
Expand All @@ -18,7 +18,11 @@ defmodule Cldr.Html.MixProject do
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
package: package()
package: package(),
dialyzer: [
ignore_warnings: ".dialyzer_ignore_warnings",
plt_add_apps: ~w(ex_money)a
],
]
end

Expand Down Expand Up @@ -73,13 +77,15 @@ defmodule Cldr.Html.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:ex_cldr, "~> 2.18"},
{:ex_cldr, "~> 2.19"},
{:phoenix_html, "~> 1.2 or ~> 2.0"},
{:ex_cldr_currencies, "~> 2.8", optional: true},
{:ex_money, "~> 5.0", optional: true},
{:ex_cldr_units, path: "../cldr_units"},
{:jason, "~> 1.0", optional: true},
{:poison, "~> 2.1 or ~> 3.0 or ~> 4.0", optional: true},
{:ex_doc, "~> 0.18", runtime: false},
{:dialyxir, "~> 1.0", only: [:dev], runtime: false}
]
end

Expand Down
Loading

0 comments on commit c5fb870

Please sign in to comment.