HashPipe

HashPipe is a minimalist testing and code documentation tool for Elixir.

Installation

Add hashpipe to your list of dependencies in mix.exs:

def deps do
  [{:hashpipe, "~> 0.1.0"}]
end

Ensure hashpipe is started before your application:

def application do
  [applications: [:hashpipe]]
end

Update your dependencies:

$ mix deps.get

Usage

Let's use HashPipe and write some HashPipe tests, which are just consecutive lines starting with #|:

defmodule MyApp.MyModule do

  use HashPipe

  #| 1 + 1 > 1

  defp sum(a, b), do: a + b

  #| # test a private function defined above this test
  #| sum(1, 2) == 3

  #| # test a public function defined somewhere in this module
  #| a = 1
  #| b = 2
  #| average(a, b) == 1.5

  def average(a, b), do: sum(a, b) / 2

  #| is_atom(Elixir) and 42 in 1..100

  def my_div(_a, 0), do: raise "Devision by zero!"
  def my_div(a, b), do: a / b

  #| # test devision by zero
  #| result = try do
  #|   my_div(1, 0)
  #| rescue
  #|   e -> e
  #| end
  #| result == %RuntimeError{message: "Devision by zero!"}

end

Now compile your project and HashPipe tests will be automatically executed:

Screenshot

Let's make two errors in the first and last tests:

defmodule MyApp.MyModule do

  use HashPipe

  #| 1 + 1 > 2

  defp sum(a, b), do: a + b

  #| # test a private function defined above this test
  #| sum(1, 2) == 3

  #| # test a public function defined somewhere in this module
  #| a = 1
  #| b = 2
  #| average(a, b) == 1.5

  def average(a, b), do: sum(a, b) / 2

  #| is_atom(Elixir) and 42 in 1..100

  def my_div(_a, 0), do: raise "Devision by zero!"
  def my_div(a, b), do: a / b

  #| # test devision by zero
  #| result = try do
  #|   my_div(1, 0)
  #| rescue
  #|   e -> e
  #| end
  #| result

end

Compile the project again and check the output:

Screenshot

Note that a HashPipe test succeeds if it returns true and fails otherwise. If it fails, its return value is printed after the test.

You can also use HashPipe to check return values of private functions or (almost) any Elixir expressions:

defmodule MyApp.MyModule do

  use HashPipe

  #| emphasize("elixir")

  defp emphasize(word) do
    word
    |> String.upcase
    |> String.graphemes
    |> Enum.intersperse(" ")
    |> Enum.join
  end

  #| highlight("Chuck Norris can access private methods.", "private")

  defp highlight(text, word) do
    String.replace(text, word, emphasize(word))
  end

  #| 1..9
  #| |> Enum.map(&String.duplicate("|", 5 - abs(&1 - 5)))
  #| |> Enum.join("  ")

end

Compile it and you will get something like this:

Screenshot

Limitations