Docs tests & a refactor

This commit is contained in:
Max Veytsman
2021-03-06 16:53:46 -05:00
parent 143b0d78c9
commit 682e9d04f3
5 changed files with 73 additions and 28 deletions

View File

@ -8,42 +8,51 @@ defmodule Heroicons do
@doc false
defmacro __before_compile__(%Macro.Env{module: module}) do
unless Module.has_attribute?(module, :icon_path) do
raise CompileError, description: "@icon_path attrubute is required"
unless Module.has_attribute?(module, :icon_dir) do
raise CompileError, description: "@icon_dir attrubute is required"
end
icon_dir = Module.get_attribute(module, :icon_dir)
icon_paths =
Module.get_attribute(module, :icon_path)
Path.absname(icon_dir, :code.priv_dir(:heroicons))
|> Path.join("*.svg")
|> Path.wildcard()
for path <- icon_paths do
name =
Path.basename(path, ".svg")
|> String.replace("-", "_")
|> String.to_atom()
generate_function(path)
end
end
quote do
@doc """
![](#{unquote(path)}) {: width=24px}
@doc false
def generate_function(path) do
name =
Path.basename(path, ".svg")
|> String.replace("-", "_")
|> String.to_atom()
## Examples
iex> #{unquote(name)}()
iex> #{unquote(name)}(class: "h-6 w-6 text-gray-500")
"""
@spec unquote(name)(keyword(binary)) :: binary
def unquote(name)(opts \\ []) do
icon = File.read!(unquote(path))
{i, _} = :binary.match(icon, ">")
doc = """
![](assets/#{Path.relative_to(path, :code.priv_dir(:heroicons))}) {: width=24px}
{head, tail} = String.split_at(icon, i)
## Examples
iex> #{name}()
iex> #{name}(class: "h-6 w-6 text-gray-500")
"""
attrs =
opts
|> Enum.map_join(fn {k, v} -> ~s( #{k}="#{v}") end)
quote do
@doc unquote(doc)
@spec unquote(name)(keyword(binary)) :: binary
def unquote(name)(opts \\ []) do
icon = File.read!(unquote(path))
{i, _} = :binary.match(icon, ">")
head <> attrs <> tail
end
{head, tail} = String.split_at(icon, i)
attrs =
opts
|> Enum.map_join(fn {k, v} -> ~s( #{k}="#{v}") end)
head <> attrs <> tail
end
end
end

View File

@ -4,6 +4,6 @@ defmodule Heroicons.Outline do
For primary navigation and marketing sections, designed to be rendered at 24x24.
"""
@icon_path "#{:code.priv_dir(:heroicons)}/outline/"
@icon_dir "outline/"
@before_compile Heroicons
end

View File

@ -5,6 +5,6 @@ defmodule Heroicons.Solid do
For buttons, form elements, and to support text, designed to be rendered at 20x20.
"""
@icon_path "#{:code.priv_dir(:heroicons)}/solid/"
@icon_dir "solid/"
@before_compile Heroicons
end

14
mix.exs
View File

@ -7,7 +7,13 @@ defmodule HeroiconsElixir.MixProject do
version: "0.1.0",
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps()
deps: deps(),
# Docs
name: "Heroicons Elixir",
source_url: "https://github.com/mveytsman/heroicons_elixir",
description: "Include Heroicons as SVG-strings in your Elixir/Phoenix project!",
docs: docs()
]
end
@ -26,4 +32,10 @@ defmodule HeroiconsElixir.MixProject do
{:ex_doc, "~> 0.23", only: :dev, runtime: false}
]
end
defp docs do
[
assets: "priv/"
]
end
end

View File

@ -1,4 +1,28 @@
defmodule HeroiconsTest do
use ExUnit.Case, async: true
doctest Heroicons.Solid
@icon """
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z"/>
</svg>
"""
@tag :tmp_dir
test "generated function", %{tmp_dir: tmp_dir} do
Path.join(tmp_dir, "academic_cap.svg")
|> File.write(@icon)
quote do
defmodule TestIcons do
@icon_dir unquote(Path.absname(tmp_dir))
@before_compile Heroicons
end
end
|> Code.compile_quoted()
assert TestIcons.academic_cap() == @icon
assert TestIcons.academic_cap(class: "h-6 w-6 text-gray-500") =~
~s(class="h-6 w-6 text-gray-500")
end
end