Modernise Elixir usage and replace espec with exunit.
This commit is contained in:
parent
7ad923335f
commit
7ca833dd84
19 changed files with 237 additions and 254 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@
|
||||||
erl_crash.dump
|
erl_crash.dump
|
||||||
*.ez
|
*.ez
|
||||||
/doc
|
/doc
|
||||||
|
/docs
|
||||||
|
|
12
.travis.yml
12
.travis.yml
|
@ -1,8 +1,14 @@
|
||||||
language: elixir
|
language: elixir
|
||||||
elixir:
|
elixir:
|
||||||
- 1.2.2
|
- 1.5.1
|
||||||
otp_release:
|
otp_release:
|
||||||
- 18.2.1
|
- 20.0
|
||||||
script: mix espec
|
script:
|
||||||
|
- mix test
|
||||||
|
- mix credo --strict
|
||||||
|
- MIX_ENV=docs mix inch
|
||||||
|
after_script:
|
||||||
|
- mix deps.get --only docs
|
||||||
|
- MIX_ENV=docs mix inch.report
|
||||||
env:
|
env:
|
||||||
- MIX_ENV=test
|
- MIX_ENV=test
|
||||||
|
|
|
@ -20,7 +20,7 @@ If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||||
1. Add heap to your list of dependencies in `mix.exs`:
|
1. Add heap to your list of dependencies in `mix.exs`:
|
||||||
|
|
||||||
def deps do
|
def deps do
|
||||||
[{:heap, "~> 1.0.1"}]
|
[{:heap, "~> 1.1.0"}]
|
||||||
end
|
end
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
134
lib/heap.ex
134
lib/heap.ex
|
@ -12,36 +12,92 @@ defmodule Heap do
|
||||||
Create an empty min heap.
|
Create an empty min heap.
|
||||||
|
|
||||||
A min heap is a heap tree which always has the smallest value at the root.
|
A min heap is a heap tree which always has the smallest value at the root.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.min())
|
||||||
|
...> |> Heap.root()
|
||||||
|
1
|
||||||
"""
|
"""
|
||||||
@spec min() :: Heap.t
|
@spec min() :: t
|
||||||
def min(), do: Heap.new(:>)
|
def min, do: Heap.new(:>)
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Create an empty max heap.
|
Create an empty max heap.
|
||||||
|
|
||||||
A max heap is a heap tree which always has the largest value at the root.
|
A max heap is a heap tree which always has the largest value at the root.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.max())
|
||||||
|
...> |> Heap.root()
|
||||||
|
10
|
||||||
"""
|
"""
|
||||||
@spec max() :: Heap.t
|
@spec max() :: t
|
||||||
def max(), do: Heap.new(:<)
|
def max, do: Heap.new(:<)
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Create an empty heap.
|
Create an empty heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Create an empty heap with the default direction.
|
||||||
|
|
||||||
|
iex> Heap.new()
|
||||||
|
...> |> Heap.comparator()
|
||||||
|
:>
|
||||||
|
|
||||||
|
Create an empty heap with a specific direction.
|
||||||
|
|
||||||
|
iex> Heap.new(:<)
|
||||||
|
...> |> Heap.comparator()
|
||||||
|
:<
|
||||||
"""
|
"""
|
||||||
@spec new() :: Heap.t
|
@spec new() :: t
|
||||||
@spec new(:> | :<) :: Heap.t
|
@spec new(:> | :<) :: t
|
||||||
def new(direction \\ :>), do: %Heap{d: direction}
|
def new(direction \\ :>), do: %Heap{d: direction}
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Test if the heap is empty.
|
Test if the heap is empty.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Heap.new()
|
||||||
|
...> |> Heap.empty?()
|
||||||
|
true
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.empty?()
|
||||||
|
false
|
||||||
"""
|
"""
|
||||||
@spec empty?(Heap.t) :: boolean()
|
@spec empty?(t) :: boolean()
|
||||||
def empty?(%Heap{h: nil, n: 0}), do: true
|
def empty?(%Heap{h: nil, n: 0}), do: true
|
||||||
def empty?(%Heap{}), do: false
|
def empty?(%Heap{}), do: false
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Test if the heap contains the element <elem>
|
Test if the heap contains the element <elem>
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.member?(11)
|
||||||
|
false
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.member?(7)
|
||||||
|
true
|
||||||
"""
|
"""
|
||||||
@spec member?(Heap.t, any()) :: boolean()
|
@spec member?(t, any()) :: boolean()
|
||||||
def member?(%Heap{} = heap, value) do
|
def member?(%Heap{} = heap, value) do
|
||||||
root = Heap.root heap
|
root = Heap.root heap
|
||||||
heap = Heap.pop heap
|
heap = Heap.pop heap
|
||||||
|
@ -50,40 +106,77 @@ defmodule Heap do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Push a new element into the heap.
|
Push a new element into the heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Heap.new()
|
||||||
|
...> |> Heap.push(13)
|
||||||
|
...> |> Heap.root()
|
||||||
|
13
|
||||||
"""
|
"""
|
||||||
@spec push(Heap.t, any()) :: Heap.t
|
@spec push(t, any()) :: t
|
||||||
def push(%Heap{h: h, n: n, d: d}, v), do: %Heap{h: meld(h, {v, []}, d), n: n + 1, d: d}
|
def push(%Heap{h: h, n: n, d: d}, v), do: %Heap{h: meld(h, {v, []}, d), n: n + 1, d: d}
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Pop the root element off the heap and discard it.
|
Pop the root element off the heap and discard it.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.pop()
|
||||||
|
...> |> Heap.root()
|
||||||
|
2
|
||||||
"""
|
"""
|
||||||
@spec pop(Heap.t) :: Heap.t
|
@spec pop(t) :: t
|
||||||
def pop(%Heap{h: nil, n: 0}), do: nil
|
def pop(%Heap{h: nil, n: 0}), do: nil
|
||||||
def pop(%Heap{h: {_, q}, n: n, d: d}), do: %Heap{h: pair(q, d), n: n - 1, d: d}
|
def pop(%Heap{h: {_, q}, n: n, d: d}), do: %Heap{h: pair(q, d), n: n - 1, d: d}
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Return the element at the root of the heap.
|
Return the element at the root of the heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Heap.new()
|
||||||
|
...> |> Heap.root()
|
||||||
|
nil
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.root()
|
||||||
|
1
|
||||||
"""
|
"""
|
||||||
@spec root(Heap.t) :: any()
|
@spec root(t) :: any()
|
||||||
def root(%Heap{h: {v, _}}), do: v
|
def root(%Heap{h: {v, _}}), do: v
|
||||||
def root(%Heap{h: nil, n: 0}), do: nil
|
def root(%Heap{h: nil, n: 0}), do: nil
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Return the number of elements in the heap.
|
Return the number of elements in the heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..10
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.size()
|
||||||
|
10
|
||||||
"""
|
"""
|
||||||
@spec size(Heap.t) :: non_neg_integer()
|
@spec size(t) :: non_neg_integer()
|
||||||
def size(%Heap{n: n}), do: n
|
def size(%Heap{n: n}), do: n
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Quickly sort an enumerable with a heap.
|
Return the comparator of the heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Heap.new(:<)
|
||||||
|
...> |> Heap.comparator()
|
||||||
|
:<
|
||||||
"""
|
"""
|
||||||
@spec sort(Enum.t) :: List.t
|
@spec comparator(t) :: :< | :>
|
||||||
@spec sort(Enum.t, :< | :>) :: List.t
|
def comparator(%Heap{d: d}), do: d
|
||||||
def sort(enum, direction \\ :>) do
|
|
||||||
enum
|
|
||||||
|> Enum.into(Heap.new(direction))
|
|
||||||
|> Enum.to_list
|
|
||||||
end
|
|
||||||
|
|
||||||
defp meld(nil, queue, _), do: queue
|
defp meld(nil, queue, _), do: queue
|
||||||
defp meld(queue, nil, _), do: queue
|
defp meld(queue, nil, _), do: queue
|
||||||
|
@ -94,7 +187,6 @@ defmodule Heap do
|
||||||
defp meld({k0, l0}, {k1, _} = r, :<) when k0 > k1, do: {k0, [r | l0]}
|
defp meld({k0, l0}, {k1, _} = r, :<) when k0 > k1, do: {k0, [r | l0]}
|
||||||
defp meld({_, _} = l, {k1, r0}, :<), do: {k1, [l | r0]}
|
defp meld({_, _} = l, {k1, r0}, :<), do: {k1, [l | r0]}
|
||||||
|
|
||||||
|
|
||||||
defp pair([], _), do: nil
|
defp pair([], _), do: nil
|
||||||
defp pair([q], _), do: q
|
defp pair([q], _), do: q
|
||||||
defp pair([q0, q1 | q], d) do
|
defp pair([q0, q1 | q], d) do
|
||||||
|
|
|
@ -1,8 +1,20 @@
|
||||||
defimpl Collectable, for: Heap do
|
defimpl Collectable, for: Heap do
|
||||||
|
|
||||||
def into heap do
|
@doc """
|
||||||
|
Collect an enumerable into a heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..500
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Heap.root
|
||||||
|
1
|
||||||
|
"""
|
||||||
|
@spec into(Heap.t) :: {list, function}
|
||||||
|
def into(heap) do
|
||||||
{heap, fn
|
{heap, fn
|
||||||
(h, {:cont, v}) -> Heap.push h, v
|
(h, {:cont, v}) -> Heap.push(h, v)
|
||||||
(h, :done) -> h
|
(h, :done) -> h
|
||||||
(_, :halt) -> :ok
|
(_, :halt) -> :ok
|
||||||
end}
|
end}
|
||||||
|
|
|
@ -1,21 +1,61 @@
|
||||||
defimpl Enumerable, for: Heap do
|
defimpl Enumerable, for: Heap do
|
||||||
|
|
||||||
def count heap do
|
@doc """
|
||||||
|
Returns the number of elements in a heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..500
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Enum.count()
|
||||||
|
500
|
||||||
|
"""
|
||||||
|
@spec count(Heap.t) :: non_neg_integer
|
||||||
|
def count(heap) do
|
||||||
{:ok, Heap.size heap}
|
{:ok, Heap.size heap}
|
||||||
end
|
end
|
||||||
|
|
||||||
def member? heap, v do
|
@doc """
|
||||||
{:ok, Heap.member?(heap, v)}
|
Returns true if value is a contained in the heap.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..500
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Enum.member?(250)
|
||||||
|
true
|
||||||
|
|
||||||
|
iex> 1..500
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Enum.member?(750)
|
||||||
|
false
|
||||||
|
"""
|
||||||
|
@spec member?(Heap.t, term) :: boolean
|
||||||
|
def member?(heap, value) do
|
||||||
|
{:ok, Heap.member?(heap, value)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Allows reduction to be applied to Heaps.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> 1..500
|
||||||
|
...> |> Enum.shuffle()
|
||||||
|
...> |> Enum.into(Heap.new())
|
||||||
|
...> |> Enum.filter(&(Integer.mod(&1, 2) == 0))
|
||||||
|
...> |> Enum.count()
|
||||||
|
250
|
||||||
|
"""
|
||||||
|
@spec reduce(Heap.t, Enumerable.acc, Enumerable.reducer) :: Enumerable.result
|
||||||
def reduce(_, {:halt, acc}, _fun), do: {:halted, acc}
|
def reduce(_, {:halt, acc}, _fun), do: {:halted, acc}
|
||||||
def reduce(heap, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(heap, &1, fun)}
|
def reduce(heap, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(heap, &1, fun)}
|
||||||
def reduce(heap, {:cont, acc}, fun) do
|
def reduce(heap, {:cont, acc}, fun) do
|
||||||
case Heap.root heap do
|
case Heap.root(heap) do
|
||||||
nil ->
|
nil ->
|
||||||
{:done, acc}
|
{:done, acc}
|
||||||
root ->
|
root ->
|
||||||
heap = Heap.pop heap
|
heap = Heap.pop(heap)
|
||||||
reduce(heap, fun.(root, acc), fun)
|
reduce(heap, fun.(root, acc), fun)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
defimpl Inspect, for: Heap do
|
defimpl Inspect, for: Heap do
|
||||||
import Inspect.Algebra
|
import Inspect.Algebra
|
||||||
|
|
||||||
def inspect heap, opts do
|
@doc """
|
||||||
concat [
|
Format the heap nicely for inspection.
|
||||||
"#Heap<",
|
|
||||||
to_doc(Enum.to_list(heap), opts),
|
## Examples
|
||||||
">"
|
|
||||||
]
|
iex> 1..10
|
||||||
|
...> |> Enum.into(Heap.max())
|
||||||
|
...> |> inspect
|
||||||
|
"#Heap<[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]>"
|
||||||
|
"""
|
||||||
|
@spec inspect(Heap.t, Inspect.Opts.t) :: Inspect.Algebra.t
|
||||||
|
def inspect(heap, opts) do
|
||||||
|
concat(["#Heap<", to_doc(Enum.to_list(heap), opts), ">"])
|
||||||
end
|
end
|
||||||
end
|
end
|
26
mix.exs
26
mix.exs
|
@ -3,14 +3,13 @@ defmodule Heap.Mixfile do
|
||||||
|
|
||||||
def project do
|
def project do
|
||||||
[app: :heap,
|
[app: :heap,
|
||||||
version: "1.0.1",
|
version: "1.1.0",
|
||||||
description: description,
|
description: description(),
|
||||||
elixir: "~> 1.2",
|
elixir: "~> 1.5",
|
||||||
build_embedded: Mix.env == :prod,
|
build_embedded: Mix.env == :prod,
|
||||||
start_permanent: Mix.env == :prod,
|
start_permanent: Mix.env == :prod,
|
||||||
preferred_cli_env: [espec: :test],
|
package: package(),
|
||||||
package: package,
|
deps: deps()]
|
||||||
deps: deps]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Configuration for the OTP application
|
# Configuration for the OTP application
|
||||||
|
@ -21,18 +20,12 @@ defmodule Heap.Mixfile do
|
||||||
end
|
end
|
||||||
|
|
||||||
def description do
|
def description do
|
||||||
"""
|
"Small composable Heap implementation. Heaps sort elements at insert time."
|
||||||
Small composable Heap implementation. Heaps sort elements at insert time.
|
|
||||||
They're good for:
|
|
||||||
* Scientific computing
|
|
||||||
* Statistics
|
|
||||||
* Priority queues
|
|
||||||
"""
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def package do
|
def package do
|
||||||
[
|
[
|
||||||
maintainers: [ "James Harton <james@messagerocket.co>" ],
|
maintainers: [ "James Harton <james@automat.nz>" ],
|
||||||
licenses: [ "MIT" ],
|
licenses: [ "MIT" ],
|
||||||
links: %{
|
links: %{
|
||||||
"GitHub" => "https://github.com/jamesotron/heap",
|
"GitHub" => "https://github.com/jamesotron/heap",
|
||||||
|
@ -52,8 +45,9 @@ defmodule Heap.Mixfile do
|
||||||
# Type "mix help deps" for more examples and options
|
# Type "mix help deps" for more examples and options
|
||||||
defp deps do
|
defp deps do
|
||||||
[
|
[
|
||||||
{:espec, "~> 0.8.11", only: :test},
|
{:ex_doc, ">= 0.0.0", only: :dev},
|
||||||
{:ex_doc, "~> 0.11.4", only: :dev}
|
{:credo, "~> 0.6", only: ~w(dev test)a},
|
||||||
|
{:inch_ex, "~> 0.5", only: :docs}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
10
mix.lock
10
mix.lock
|
@ -1,3 +1,7 @@
|
||||||
%{"espec": {:hex, :espec, "0.8.15", "a3427bc1e7984caa5f23dc25316e869260b10c2336bf5bb2b928638ad224c7a8", [:mix], [{:meck, "~> 0.8.4", [hex: :meck, optional: false]}]},
|
%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
|
||||||
"ex_doc": {:hex, :ex_doc, "0.11.4", "a064bdb720594c3745b94709b17ffb834fd858b4e0c1f48f37c0d92700759e02", [:mix], [{:earmark, "~> 0.1.17 or ~> 0.2", [hex: :earmark, optional: true]}]},
|
"credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
|
||||||
"meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:rebar, :make], []}}
|
"espec": {:hex, :espec, "0.8.28", "f002710673d215876c4ca6fc74cbf5e330954badea7389d2284d2050940f1779", [:mix], [{:meck, "~> 0.8.4", [hex: :meck, optional: false]}]},
|
||||||
|
"ex_doc": {:hex, :ex_doc, "0.11.5", "0dc51cb84f8312162a2313d6c71573a9afa332333d8a332bb12540861b9834db", [:mix], [{:earmark, "~> 0.1.17 or ~> 0.2", [hex: :earmark, optional: true]}]},
|
||||||
|
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]},
|
||||||
|
"meck": {:hex, :meck, "0.8.8", "eeb3efe811d4346e1a7f65b2738abc2ad73cbe1a2c91b5dd909bac2ea0414fa6", [:rebar3], []},
|
||||||
|
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
defmodule HeapCollectableSpec do
|
|
||||||
use ESpec
|
|
||||||
|
|
||||||
describe "into" do
|
|
||||||
let :source, do: 1..500
|
|
||||||
subject do: source |> Enum.into(Heap.new)
|
|
||||||
|
|
||||||
it "inserts into the heap" do
|
|
||||||
expect(Heap.size subject) |> to(eq 500)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,34 +0,0 @@
|
||||||
defmodule HeapEnumerableSpec do
|
|
||||||
use ESpec
|
|
||||||
|
|
||||||
describe "count" do
|
|
||||||
let :heap, do: Enum.into(1..500, Heap.new)
|
|
||||||
subject do: Enum.count heap
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq 500)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "member?" do
|
|
||||||
let :heap, do: Heap.new
|
|
||||||
subject do: Enum.member? heap, 13
|
|
||||||
|
|
||||||
context "When the value is in the heap" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13)
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "When the value is not in the heap" do
|
|
||||||
it do: is_expected |> to(be_false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "reduce" do
|
|
||||||
let :heap, do: Enum.into(1..500, Heap.new)
|
|
||||||
subject do: Enum.filter heap, fn(i) -> rem(i, 2) == 0 end
|
|
||||||
|
|
||||||
it do: is_expected |> to(have_min 2)
|
|
||||||
it do: is_expected |> to(have_max 500)
|
|
||||||
it do: is_expected |> to(have_count 250)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,10 +0,0 @@
|
||||||
defmodule HeapInspectSpec do
|
|
||||||
use ESpec
|
|
||||||
|
|
||||||
describe "inspect" do
|
|
||||||
let :heap, do: Enum.into(1..5, Heap.new)
|
|
||||||
subject do: inspect heap
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq "#Heap<[1, 2, 3, 4, 5]>")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,123 +0,0 @@
|
||||||
defmodule HeapSpec do
|
|
||||||
use ESpec
|
|
||||||
|
|
||||||
describe "new" do
|
|
||||||
subject do: Heap.new
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_struct Heap)
|
|
||||||
|
|
||||||
it "is empty" do
|
|
||||||
expect(Heap.empty? subject) |> to(be_true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "min" do
|
|
||||||
subject do: Heap.min
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_struct Heap)
|
|
||||||
|
|
||||||
it "is empty" do
|
|
||||||
expect(Heap.empty? subject) |> to(be_true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "has the correct sort direction" do
|
|
||||||
expect(subject.d) |> to(eq :>)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "max" do
|
|
||||||
subject do: Heap.max
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_struct Heap)
|
|
||||||
|
|
||||||
it "is empty" do
|
|
||||||
expect(Heap.empty? subject) |> to(be_true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "has the correct sort direction" do
|
|
||||||
expect(subject.d) |> to(eq :<)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "empty?" do
|
|
||||||
subject do: Heap.empty? heap
|
|
||||||
|
|
||||||
context "When the heap is empty" do
|
|
||||||
let :heap, do: Heap.new
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "When the heap contains elements" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13)
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "member?" do
|
|
||||||
subject do: heap |> Heap.member?(13)
|
|
||||||
|
|
||||||
context "When the heap contains the element" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13)
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "When the heap does not contain the element" do
|
|
||||||
let :heap, do: Heap.new
|
|
||||||
|
|
||||||
it do: is_expected |> to(be_false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "push" do
|
|
||||||
let :heap, do: Heap.new
|
|
||||||
subject do: heap |> Heap.push(13)
|
|
||||||
|
|
||||||
it "adds the element to the heap" do
|
|
||||||
expect(subject |> Heap.member?(13)) |> to(be_true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "pop" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13) |> Heap.push(14)
|
|
||||||
subject do: Heap.pop heap
|
|
||||||
|
|
||||||
it "pops the root element off the heap" do
|
|
||||||
expect(Heap.root heap) |> to(eq 13)
|
|
||||||
expect(Heap.root subject) |> to(eq 14)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "root" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13)
|
|
||||||
subject do: Heap.root heap
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq 13)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "size" do
|
|
||||||
let :heap, do: Heap.new |> Heap.push(13) |> Heap.push(14)
|
|
||||||
subject do: Heap.size heap
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "sort" do
|
|
||||||
let :source, do: Enum.shuffle(1..500)
|
|
||||||
subject do: Heap.sort source, direction
|
|
||||||
|
|
||||||
context "When the direction is `:>`" do
|
|
||||||
let :direction, do: :>
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq Enum.to_list(1..500))
|
|
||||||
end
|
|
||||||
|
|
||||||
context "When the direction is `:<`" do
|
|
||||||
let :direction, do: :<
|
|
||||||
|
|
||||||
it do: is_expected |> to(eq Enum.to_list(1..500) |> Enum.reverse)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,11 +0,0 @@
|
||||||
ESpec.start
|
|
||||||
|
|
||||||
ESpec.configure fn(config) ->
|
|
||||||
config.before fn ->
|
|
||||||
{:shared, hello: :world}
|
|
||||||
end
|
|
||||||
|
|
||||||
config.finally fn(_shared) ->
|
|
||||||
:ok
|
|
||||||
end
|
|
||||||
end
|
|
4
test/heap/collectable_test.exs
Normal file
4
test/heap/collectable_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule CollectableHeapTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Collectable.Heap
|
||||||
|
end
|
4
test/heap/enumerable_test.exs
Normal file
4
test/heap/enumerable_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule EnumerableHeapTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Enumerable.Heap
|
||||||
|
end
|
4
test/heap/inspect_test.exs
Normal file
4
test/heap/inspect_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule InspectHeapTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Inspect.Heap
|
||||||
|
end
|
4
test/heap_test.exs
Normal file
4
test/heap_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule HeapTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Heap
|
||||||
|
end
|
1
test/test_helper.exs
Normal file
1
test/test_helper.exs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ExUnit.start()
|
Loading…
Reference in a new issue