diff --git a/.github/workflows/salad_ui.yml b/.github/workflows/salad_ui.yml new file mode 100644 index 0000000..950247e --- /dev/null +++ b/.github/workflows/salad_ui.yml @@ -0,0 +1,87 @@ +name: Elixir CI + +# Define workflow that runs when changes are pushed to the +# `main` branch or pushed to a PR branch that targets the `main` +# branch. Change the branch name if your project uses a +# different name for the main branch like "master" or "production". +on: + push: + branches: [ "master", "main", "staging", "dev", "setup-dev", "setting-up-tests"] # adapt branch for project + pull_request: + branches: [ "master", "main", "staging", "dev", "setup-dev", "setting-up-tests"] # adapt branch for project + +# Sets the ENV `MIX_ENV` to `test` for running tests +env: + MIX_ENV: test + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + name: Test on OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}} + strategy: + # Specify the OTP and Elixir versions to use when building + # and running the workflow steps. + matrix: + otp: ['26'] # Define the OTP version [required] + elixir: ['1.16.2'] # Define the elixir version [required] + steps: + # Step: Setup Elixir + Erlang image as the base. + - name: Set up Elixir + uses: erlef/setup-beam@v1 + with: + otp-version: ${{matrix.otp}} + elixir-version: ${{matrix.elixir}} + + # Step: Check out the code. + - name: Checkout code + uses: actions/checkout@v3 + + # Step: Define how to cache deps. Restores existing cache if present. + - name: Cache deps + id: cache-deps + uses: actions/cache@v3 + env: + cache-name: cache-elixir-deps + with: + path: deps + key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-mix-${{ env.cache-name }}- + + # Step: Define how to cache the `_build` directory. After the first run, + # this speeds up tests runs a lot. This includes not re-compiling our + # project's downloaded deps every run. + - name: Cache compiled build + id: cache-build + uses: actions/cache@v3 + env: + cache-name: cache-compiled-build + with: + path: _build + key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-mix-${{ env.cache-name }}- + ${{ runner.os }}-mix- + + # Step: Download project dependencies. If unchanged, uses + # the cached version. + - name: Install dependencies + run: mix deps.get + + # Step: Compile the project treating any warnings as errors. + # Customize this step if a different behavior is desired. + - name: Compiles without warnings + run: mix compile --warnings-as-errors + + # Step: Check that the checked in code has already been formatted. + # This step fails if something was found unformatted. + # Customize this step as desired. + - name: Check Formatting + run: mix format --check-formatted + + # Step: Execute the tests. + - name: Run tests + run: mix test \ No newline at end of file diff --git a/.gitignore b/.gitignore index e52f7ad..c74b622 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,6 @@ salad_ui-*.tar .DS_Store -node_modules/ \ No newline at end of file +node_modules/ + +/.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index abc675e..9ee9535 100644 --- a/README.md +++ b/README.md @@ -106,11 +106,21 @@ Here is how to start develop SaladUI on local machine. 1. Clone this repo 2. Clone `https://github.com/bluzky/salad_storybook` in the same directory with `SaladUI` 3. Start storybook -``` +```ex cd salad_storybook mix phx.server ``` +## Unit Testing + +In your project folder make sure the dependencies are installed by running `mix deps.get`, then once completed you can run: + +- `mix test` to run tests once or, +- `mix test.watch` to watch file and run tests on file changes. + +To run the failing tests only, just run `mix test.watch --stale`. + + It's also important to note that you must format your code with `mix format` before sending a pull request, otherwise the build in github will fail. ## List of components diff --git a/lib/salad_ui/dialog.ex b/lib/salad_ui/dialog.ex index 18bb9ee..2c35172 100644 --- a/lib/salad_ui/dialog.ex +++ b/lib/salad_ui/dialog.ex @@ -37,11 +37,11 @@ defmodule SaladUI.Dialog do """ - attr :id, :string, required: true - attr :show, :boolean, default: false - attr :on_cancel, JS, default: %JS{} - attr :class, :string, default: nil - slot :inner_block, required: true + attr(:id, :string, required: true) + attr(:show, :boolean, default: false) + attr(:on_cancel, JS, default: %JS{}) + attr(:class, :string, default: nil) + slot(:inner_block, required: true) def dialog(assigns) do ~H""" @@ -107,8 +107,8 @@ defmodule SaladUI.Dialog do """ end - attr :class, :string, default: nil - slot :inner_block, required: true + attr(:class, :string, default: nil) + slot(:inner_block, required: true) def dialog_header(assigns) do ~H""" @@ -118,8 +118,8 @@ defmodule SaladUI.Dialog do """ end - attr :class, :string, default: nil - slot :inner_block, required: true + attr(:class, :string, default: nil) + slot(:inner_block, required: true) def dialog_title(assigns) do ~H""" @@ -129,8 +129,8 @@ defmodule SaladUI.Dialog do """ end - attr :class, :string, default: nil - slot :inner_block, required: true + attr(:class, :string, default: nil) + slot(:inner_block, required: true) def dialog_description(assigns) do ~H""" @@ -140,8 +140,8 @@ defmodule SaladUI.Dialog do """ end - attr :class, :string, default: nil - slot :inner_block, required: true + attr(:class, :string, default: nil) + slot(:inner_block, required: true) def dialog_footer(assigns) do ~H""" diff --git a/lib/salad_ui/dropdown_menu.ex b/lib/salad_ui/dropdown_menu.ex index 4893322..910f617 100644 --- a/lib/salad_ui/dropdown_menu.ex +++ b/lib/salad_ui/dropdown_menu.ex @@ -35,9 +35,9 @@ defmodule SaladUI.DropdownMenu do """ - attr :class, :string, default: nil - slot :inner_block, required: true - attr :rest, :global + attr(:class, :string, default: nil) + slot(:inner_block, required: true) + attr(:rest, :global) def dropdown_menu(assigns) do ~H""" @@ -47,9 +47,9 @@ defmodule SaladUI.DropdownMenu do """ end - attr :class, :string, default: nil - slot :inner_block, required: true - attr :rest, :global + attr(:class, :string, default: nil) + slot(:inner_block, required: true) + attr(:rest, :global) def dropdown_menu_trigger(assigns) do ~H""" @@ -65,11 +65,11 @@ defmodule SaladUI.DropdownMenu do """ end - attr :class, :string, default: nil - attr :side, :string, values: ["top", "right", "bottom", "left"], default: "bottom" - attr :align, :string, values: ["start", "center", "end"], default: "start" - slot :inner_block, required: true - attr :rest, :global + attr(:class, :string, default: nil) + attr(:side, :string, values: ["top", "right", "bottom", "left"], default: "bottom") + attr(:align, :string, values: ["start", "center", "end"], default: "start") + slot(:inner_block, required: true) + attr(:rest, :global) def dropdown_menu_content(assigns) do ~H""" diff --git a/lib/salad_ui/separator.ex b/lib/salad_ui/separator.ex index 39ddc06..59927a2 100644 --- a/lib/salad_ui/separator.ex +++ b/lib/salad_ui/separator.ex @@ -10,7 +10,7 @@ defmodule SaladUI.Separator do <.separator orientation="horizontal" /> """ - attr :orientation, :string, values: ~w(vertical horizontal), default: "horizontal" + attr(:orientation, :string, values: ~w(vertical horizontal), default: "horizontal") attr(:class, :string, default: nil) attr(:rest, :global, include: ~w(disabled form name value)) diff --git a/lib/salad_ui/sheet.ex b/lib/salad_ui/sheet.ex index e256b97..598c31a 100644 --- a/lib/salad_ui/sheet.ex +++ b/lib/salad_ui/sheet.ex @@ -212,27 +212,6 @@ defmodule SaladUI.Sheet do """ end - @variants %{ - side: %{ - "top" => "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-to", - "bottom" => - "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", - "left" => - "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", - "right" => "text-foreground" - } - } - - @default_variants %{ - side: "default" - } - - defp variant(props) do - variants = Map.merge(@default_variants, props) - - Enum.map_join(variants, " ", fn {key, value} -> @variants[key][value] end) - end - defp show_sheet(js \\ %JS{}, id, side) when is_binary(id) do transition = case side do diff --git a/lib/salad_ui/table.ex b/lib/salad_ui/table.ex index 8fd1503..f4d9b47 100644 --- a/lib/salad_ui/table.ex +++ b/lib/salad_ui/table.ex @@ -44,9 +44,9 @@ defmodule SaladUI.Table do """ - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table(assigns) do ~H""" @@ -56,9 +56,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_header(assigns) do ~H""" @@ -68,9 +68,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_row(assigns) do ~H""" @@ -88,9 +88,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_head(assigns) do ~H""" @@ -108,9 +108,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_body(assigns) do ~H""" @@ -120,9 +120,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_cell(assigns) do ~H""" @@ -155,9 +155,9 @@ defmodule SaladUI.Table do """ end - attr :class, :string, default: nil - attr :rest, :global - slot :inner_block, required: true + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) def table_caption(assigns) do ~H""" diff --git a/mix.exs b/mix.exs index 0266ba7..c37ad2d 100644 --- a/mix.exs +++ b/mix.exs @@ -6,16 +6,29 @@ defmodule SaladUI.MixProject do app: :salad_ui, version: "0.4.2", elixir: "~> 1.14", + elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, deps: deps(), name: "SaladUI", description: description(), source_url: "https://github.com/bluzky/salad_ui", docs: docs(), - package: package() + package: package(), + aliases: aliases(), + test_coverage: [tool: ExCoveralls], + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test + ] ] end + # Specifies which paths to compile per environment. + defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(_), do: ["lib"] + # Run "mix help compile.app" to learn about applications. def application do [ @@ -46,14 +59,29 @@ defmodule SaladUI.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:phoenix_live_view, "~> 0.20.1"}, {:tails, "~> 0.1.5"}, + {:phoenix, "~> 1.7"}, + {:phoenix_html, "~> 4.0"}, + {:mix_test_watch, "~> 1.2"}, + {:phoenix_live_view, "~> 0.20.1"}, + {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:styler, "~> 0.7", only: [:dev, :test], runtime: false}, - {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, + {:ex_doc, "~> 0.24", only: [:dev, :test], runtime: false}, + {:excoveralls, "~> 0.10", only: [:dev, :test], runtime: false}, {:tailwind, "~> 0.2", only: [:dev, :test], runtime: Mix.env() == :dev} + ] + end - # {:dep_from_hexpm, "~> 0.3.0"}, - # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} + # Aliases are shortcuts or tasks specific to the current project. + # For example, to install project dependencies and perform other setup tasks, run: + # + # $ mix setup + # + # See the documentation for `Mix` for more info on aliases. + defp aliases do + [ + test: ["test --color"], + audit: ["format", "credo", "coveralls"] ] end end diff --git a/mix.lock b/mix.lock index 3783ea5..77cafc2 100644 --- a/mix.lock +++ b/mix.lock @@ -1,12 +1,17 @@ %{ + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, + "credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"}, "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "ex_doc": {:hex, :ex_doc, "0.34.0", "ab95e0775db3df71d30cf8d78728dd9261c355c81382bcd4cefdc74610bef13e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "60734fb4c1353f270c3286df4a0d51e65a2c1d9fba66af3940847cc65a8066d7"}, + "excoveralls": {:hex, :excoveralls, "0.18.1", "a6f547570c6b24ec13f122a5634833a063aec49218f6fff27de9df693a15588c", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d65f79db146bb20399f23046015974de0079668b9abb2f5aac074d078da60b8d"}, + "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "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.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "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, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, + "mix_test_watch": {:hex, :mix_test_watch, "1.2.0", "1f9acd9e1104f62f280e30fc2243ae5e6d8ddc2f7f4dc9bceb454b9a41c82b42", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "278dc955c20b3fb9a3168b5c2493c2e5cffad133548d307e0a50c7f2cfbf34f6"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "phoenix": {:hex, :phoenix, "1.7.12", "1cc589e0eab99f593a8aa38ec45f15d25297dd6187ee801c8de8947090b5a9d3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "d646192fbade9f485b01bc9920c139bfdd19d0f8df3d73fd8eaf2dfbe0d2837c"}, "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"}, @@ -17,7 +22,7 @@ "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "styler": {:hex, :styler, "0.11.9", "2595393b94e660cd6e8b582876337cc50ff047d184ccbed42fdad2bfd5d78af5", [:mix], [], "hexpm", "8b7806ba1fdc94d0a75127c56875f91db89b75117fcc67572661010c13e1f259"}, "tails": {:hex, :tails, "0.1.11", "112a62ff06046805c052c3cf6aba6f64fd41e8f82fe8cc1705fb446d04400607", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "a908c1e3191610d606f1518eb108b7abe3e91fcc2ebda16b321e917d0d8987dd"}, - "tailwind": {:hex, :tailwind, "0.2.2", "9e27288b568ede1d88517e8c61259bc214a12d7eed271e102db4c93fcca9b2cd", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "ccfb5025179ea307f7f899d1bb3905cd0ac9f687ed77feebc8f67bdca78565c4"}, + "tailwind": {:hex, :tailwind, "0.2.3", "277f08145d407de49650d0a4685dc062174bdd1ae7731c5f1da86163a24dfcdb", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "8e45e7a34a676a7747d04f7913a96c770c85e6be810a1d7f91e713d3a3655b5d"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"}, diff --git a/test/salad_ui/alert_test.exs b/test/salad_ui/alert_test.exs new file mode 100644 index 0000000..70ea79c --- /dev/null +++ b/test/salad_ui/alert_test.exs @@ -0,0 +1,83 @@ +defmodule SaladUI.AlertTest do + use ComponentCase + + import SaladUI.Alert + + describe "Test Alerting" do + test "it renders default alert correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.alert> + <.alert_title>Heads up! + + <.alert_description>Alert Descriptions + + """) + + assert html =~ "
" + assert html =~ "Heads up!" + assert html =~ "Alert Descriptions" + + for class <- ~w(relative w-full rounded-lg border p-4 absolute left-4 top-4) do + assert html =~ class + end + end + + test "It renders destructive alert correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.alert variant="destructive"> + <.alert_title>Heads up! + + <.alert_description> + You can add components to your app using the cli + + + """) + + for class <- ~w(relative p-4 rounded-lg border-destructive/50 text-destructive w-full dark:border-destructive) do + assert html =~ class + end + + assert html =~ "Heads up!" + assert html =~ "You can add components to your app using the cli" + end + + test "It renders alert title correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.alert_title>Alert title + """) + + for class <- ~w(mb-1 font-medium leading-none tracking-tight) do + assert html =~ class + end + + assert html =~ "
" + end + + test "it renders alert description correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.alert_description>Alert description + """) + + assert html =~ "Alert description" + assert html =~ "
" + + for class <- ~w(text-sm leading-relaxed) do + assert html =~ class + end + end + end +end diff --git a/test/salad_ui/avatar_test.exs b/test/salad_ui/avatar_test.exs new file mode 100644 index 0000000..5a4b67d --- /dev/null +++ b/test/salad_ui/avatar_test.exs @@ -0,0 +1,46 @@ +defmodule SaladUI.AvatarTest do + use ComponentCase + + import SaladUI.Avatar + + describe "Test Avatar" do + test "It renders avatar image correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.avatar_image src="https://github.com/shadcn.png" /> + """) + + assert html =~ "CN + """) + + assert html =~ "" + assert html =~ "CN" + end + + test "It renders avatar correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.avatar> + <.avatar_image src="https://github.com/shadcn.png" /> + <.avatar_fallback class="bg-primary text-white">CN + + """) + + assert html =~ "" + assert html =~ "CN" + end + end +end diff --git a/test/salad_ui/badge_test.exs b/test/salad_ui/badge_test.exs new file mode 100644 index 0000000..0320805 --- /dev/null +++ b/test/salad_ui/badge_test.exs @@ -0,0 +1,67 @@ +defmodule SaladUI.BadgeTest do + use ComponentCase + + import SaladUI.Badge + + describe "Test Badge" do + test "It renders a badge default variant" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.badge>Badge + """) + + for class <- + ~w(inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-primary text-primary-foreground hover:bg-primary/80) do + assert html =~ class + end + + assert html =~ "
Secondary + """) + + for class <- ~w(border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80) do + assert html =~ class + end + end + + test "It renders a badge with the destructive variant" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.badge variant="destructive">Destructive + """) + + for class <- ~w(border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80) do + assert html =~ class + end + + assert html =~ "Destructive" + end + + test "it renders a badge with the outlined variant" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.badge variant="outline">Outline + """) + + for class <- ~w(text-foreground) do + assert html =~ class + end + + assert html =~ "Outline" + end + end +end diff --git a/test/salad_ui/breadcrumb_test.exs b/test/salad_ui/breadcrumb_test.exs new file mode 100644 index 0000000..ea5341e --- /dev/null +++ b/test/salad_ui/breadcrumb_test.exs @@ -0,0 +1,41 @@ +defmodule SaladUI.BreadcrumbTest do + use ComponentCase + + import SaladUI.Breadcrumb + + describe "Test breadcrumb" do + test "It renders breadcrumb correctly" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.breadcrumb> + <.breadcrumb_list> + <.breadcrumb_item> + <.breadcrumb_link href="/">Home + + <.breadcrumb_separator /> + <.breadcrumb_item> + <.breadcrumb_link href="">Components + + <.breadcrumb_separator /> + <.breadcrumb_item> + <.breadcrumb_page>Breadcrumb + + + + """) + + # Confirm all CSS classes are available + for class <- + ~w(flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5 inline-flex items-center gap-1.5 transition-colors hover:text-foreground font-normal text-foreground) do + assert html =~ class + end + + assert html =~ "Home" + assert html =~ "