DEV Community

milica golocorbin
milica golocorbin

Posted on

 

CastingVote - App built with Phoenix(1.6) - PART 01

This will be a fairly simple and straightforward app, but I will try to touch on as many Phoenix concepts as possible. Hope you will like it and learn something new. Lets start today with what we need to install in order to be able to create a new Phoenix project. Than we will add a couple of tools, that will help us with testing. Install TailwindCSS, change default font. We will end with clearing the boilerplate code, our first test and committing everything to Github.

Code is available at milica-golocorbin/casting_vote.

Installation

Phoenix is a web development framework written in Elixir. And is based on the server-side Model View Controller (MVC) pattern. To build a Phoenix application, we will need a few dependencies:

  • Erlang VM and the Elixir programming language

  • PostgreSQL database

  • Hex package manager (Hex is used for installation of dependencies we might need in our project.)

  mix local.hex
Enter fullscreen mode Exit fullscreen mode

Once we have Elixir and Erlang, PostgreSQL and Hex installed, we can install the Phoenix application generator:

mix archive.install hex phx_new
Enter fullscreen mode Exit fullscreen mode

At the moment of writing this blog, Phoenix 1.7 is available. Since I already started writing this project with 1.6, I will continue with it. But along the way I will see to migrate the project to 1.7.

Project creation

If you are not sure about which command to use you can always use mix help to see all available commands. To shorten the list and find command necessary for bootstrapping new Phoenix app use:

mix help | grep phx
Enter fullscreen mode Exit fullscreen mode
mix help phx.new

mix phx.new casting_vote --binary-id
Enter fullscreen mode Exit fullscreen mode

We'll use binary_id for primary key type in Ecto schemas.

Phoenix assumes that the database has a user account with name: postgres and with the password postgres. If that is not the case, changes can be made in the config/dev.exs file.

Adding Credo, Mix test.watch, ExCoveralls

We will use credo for static code analyses and code consistency. It is a great tool for following the standards and best practices of elixir.

Mix test.watch is great for automatically running our tests. So we don't have to constantly call mix.test, whenever we test something.

We will use ExCoveralls as a test coverage tool. It will show us how many percent of our code is covered by tests.

mix.exs

# Add to dependencies list:

defp deps do
  [
    ...
    {:credo, "~> 1.6", only: [:dev, :test], runtime: false},
    {:mix_test_watch, "~> 1.0", only: [:dev, :test], runtime:
     false},
    {:excoveralls, "~> 0.10", only: :test}
  ]
end

# Add the following parameters into project:

def project do
  [
    ...
    test_coverage: [tool: ExCoveralls],
    preferred_cli_env: [
    "test.watch": :test,
    coveralls: :test,
    "coveralls.detail": :test,
    "coveralls.post": :test,
    "coveralls.html": :test
    ]
  ]
end
Enter fullscreen mode Exit fullscreen mode
# Fetch dependencies:
  mix deps.get
Enter fullscreen mode Exit fullscreen mode

credo

# Run task:
  mix credo -a --strict
Enter fullscreen mode Exit fullscreen mode
  • Modules should have a @moduledoc tag.

Either go into each module and add documentation or add at the top: @moduledoc false

  • Nested modules could be aliased at the top of the invoking module.

test/support/data_case.ex

Inside the file add alias Ecto.Adapters.SQL.Sandbox on the top. So we can remove nested modules from the function that was the issue.

mix test.watch

# Run task:
mix test.watch
Enter fullscreen mode Exit fullscreen mode

At the moment all the tests that were created when we bootstrapped our project are passing, because we haven't made any changes yet.

coveralls

# Run task:
  MIX_ENV=test mix coveralls

# Run task to generate html:
  mix coveralls.html
Enter fullscreen mode Exit fullscreen mode

First command prints test coverage percent in the console. And the second one will give us a graphical representation.

We can also add files, to be skipped during code coverage calculation. We can add files autogenerated by Phoenix that we are not planning to change. In case we decide to do something with them, we can simply remove them from coveralls.json. This file needs to be created at the root.

coveralls.json

{
  "skip_files": [
   "lib/casting_vote_web.ex",
   "lib/casting_vote.ex",
   "lib/casting_vote/application.ex",
   "lib/casting_vote/mailer.ex",
   "lib/casting_vote/repo.ex",
   "lib/casting_vote_web/telemetry.ex",
   "lib/casting_vote_web/gettext.ex",
   "lib/casting_vote_web/views/error_helpers.ex",
   "test/support/conn_case.ex",
   "test/support/data_case.ex"
 ]
}
Enter fullscreen mode Exit fullscreen mode

router.ex

At the moment in the MISSED column next to routes, we have 2. To solve that, we can use comments # coveralls-ignore-start and # coveralls-ignore-stop in the router file to ignore LiveDashboard and Swoosh mailbox preview from code coverage calculation. Just add the start comment before this block of code and after.

At the moment I will also put pipeline api in the comment. Later, if I decide to use it, we can remove the comment.

Installing Tailwind CSS

Follow instructions from Install Tailwind CSS with Phoenix.

Adding fonts

layout/root.html.heex

In the head tag add:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=League+Spartan:wght@400;600;700&display=swap" rel="stylesheet">
Enter fullscreen mode Exit fullscreen mode

tailwind.config.js

We need to tell Tailwind to use "League Spartan font". At the top of the file add defaultTheme constant.

const defaultTheme = require("tailwindcss/defaultTheme");

theme: {
  extend: {
    fontFamily: {
      sans: ["League Spartan", ...defaultTheme.fontFamily.sans],
    },
  },
},
Enter fullscreen mode Exit fullscreen mode

Clean up generated boilerplate code. Fix the failing test.

layout/root.html.heex

<header>
  <section>
    <div>
     <%= link "home", to: Routes.page_path(@conn, :index) %>
    </div>
  </section>
</header>
Enter fullscreen mode Exit fullscreen mode

page/index.html.heex

<section>
  <h1 class="text-4xl font-bold">Casting Vote App</h1>
</section>
Enter fullscreen mode Exit fullscreen mode

If we run mix test.watch now we will see our first failing test, because we changed our h1 tag in the page/index.html.heex.

test/casting_vote_web/controllers/page_controller_test.exs

assert html_response(conn, 200) =~ "Casting Vote App"
Enter fullscreen mode Exit fullscreen mode

Commit to github

git init

git add .

git commit -m "Added credo, excoveralls, mix_test_watch, tailwind and different font. Cleaned up boilerplate."
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Regex for lazy developers

regex for lazy devs

You know who you are. Sorry for the callout 😆