README.md

# HashPipe

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

## Installation

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

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

Ensure `hashpipe` is started before your application:

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

Update your dependencies:

```sh-session
$ mix deps.get
```

## Usage

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

```elixir
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](https://cloud.githubusercontent.com/assets/19773293/19279018/cfe07a8c-8fdf-11e6-9509-1fc9786ad111.png)

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

```elixir
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](https://cloud.githubusercontent.com/assets/19773293/19279025/d87cabf2-8fdf-11e6-843c-1def5d16a7f3.png)

**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:

```elixir
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](https://cloud.githubusercontent.com/assets/19773293/19325639/5b9e1966-90c7-11e6-9c39-94d8d614ed51.png)

## Limitations

* `HashPipe` tests can't see each other's bounded variables
* `HashPipe` tests don't capture IO
* If you got multiple modules in a file, you can `use HashPipe` in just one of them (currently)