Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
erl_crash.dump
*.ez
api_docs.html
api_docs.md
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,25 @@ The package can be installed as:

2. Add `context` to your `setup` function. Also pass the `conn` and `context[:test]` to `AutoDoc.document_api/2` in your setup block.

``` elixir
``` elixir
setup context do
conn =
conn()
|> AutoDoc.document_api(context[:test])
|> AutoDoc.document_api(context[:test], context[:auto_doc])
{:ok, conn: conn}
end
```

@tag auto_doc: [file_name: "priv/docs/file1", file_format: "md"]
test "testing ...." do
...
end

@tag auto_doc: [file_name: "priv/docs/file2", file_format: "html"]
test "testing ..." do
...
end

```

3. Run `mix test`. This will create a `api-docs.html` file at the root of your project which you can then open with a web browser.

Expand Down
27 changes: 21 additions & 6 deletions lib/auto_doc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,30 @@ defmodule AutoDoc do
setup context do
conn =
conn()
|> AutoDoc.document_api(context[:test])
|> AutoDoc.document_api(context[:test], context[:auto_doc])
{:ok, conn: conn}
end

@tag auto_doc: [file_name: "priv/docs/file1", file_format: "md"]
test "testing ...." do
...
end

@tag auto_doc: [file_name: "priv/docs/file2", file_format: "html"]
test "testing ..." do
...
end

```
"""
@spec document_api(Plug.Conn.t, binary) :: no_return
def document_api(%Plug.Conn{} = conn, test_name) do
Plug.Conn.register_before_send(conn, fn(conn) ->
AutoDoc.Agent.add_test_to_docs(conn, test_name)
end)
@spec document_api(Plug.Conn.t, binary, list) :: no_return
def document_api(%Plug.Conn{} = conn, test_name, opts \\ []) do
if Process.whereis(AutoDoc.Agent) do
Plug.Conn.register_before_send(conn, fn(conn) ->
AutoDoc.Agent.add_test_to_docs(conn, test_name, opts)
end)
else
conn
end
end
end
25 changes: 17 additions & 8 deletions lib/auto_doc/agent.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ defmodule AutoDoc.Agent do
end

@doc false
def add_test_to_docs(conn, test_name) do
def add_test_to_docs(conn, test_name, opts \\ []) do
opts = opts ++ [file_name: "#{Path.expand(".")}/api_docs", file_format: "html"]
request = Request.new(conn)
response = Response.new(conn)

Agent.get_and_update(__MODULE__, fn(docs) ->
{docs, [%{test_name: test_name, request: request, response: response}| docs]}
{docs, [%{test_name: test_name,
request: request,
response: response,
file_name: opts[:file_name],
file_format: opts[:file_format]}| docs]}
end)

conn
Expand All @@ -33,12 +38,16 @@ defmodule AutoDoc.Agent do
1 ->
Mix.Shell.IO.info("Tests have failed. No docs will be generated")
0 ->
tests = Agent.get(__MODULE__, fn(docs) -> docs end)
file_contents =
Path.join([__DIR__, "..", "templates/api_docs.html.eex"])
|> Path.expand
|> EEx.eval_file([tests: tests])
File.write!("#{Path.expand(".")}/api_docs.html", file_contents)
__MODULE__
|> Agent.get(fn(docs) -> docs end)
|> Enum.group_by(fn(item) -> {item[:file_name], item[:file_format]} end)
|> Enum.map(fn({{file_name, file_format}, tests}) ->
file_contents =
Path.join([__DIR__, "..", "templates/api_docs.#{file_format}.eex"])
|> Path.expand
|> EEx.eval_file([tests: tests])
File.write!("#{file_name}.#{file_format}", file_contents)
end)
Mix.Shell.IO.info("Api docs have been created.")
_ ->
Mix.Shell.IO.info("Something Bad has happened. No docs have been generated.")
Expand Down
2 changes: 1 addition & 1 deletion lib/auto_doc/request/request.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule AutoDoc.Request do


@doc false
def new(%Plug.Conn{req_headers: headers, method: method, params: params, request_path: path} = conn) do
def new(%Plug.Conn{req_headers: headers, method: method, params: params, request_path: path} = _conn) do
%Request{headers: headers, method: method, params: params, path: path}
end
end
12 changes: 6 additions & 6 deletions lib/auto_doc/response/response.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ defmodule AutoDoc.Response do
alias AutoDoc.Response

@doc false
def new(%Plug.Conn{resp_body: body, status: status, resp_headers: headers} = conn) do
def new(%Plug.Conn{resp_body: body, status: status, resp_headers: headers} = _conn) do
%Response{body: IO.iodata_to_binary(body), status: status, headers: headers}
end

defp has_json_header?(headers) do
Enum.any?(headers, fn({k,v}) ->
k == "content-type" && v == "application/json"
end)
end
# defp has_json_header?(headers) do
# Enum.any?(headers, fn({k,v}) ->
# k == "content-type" && v == "application/json"
# end)
# end
end
2 changes: 1 addition & 1 deletion lib/mix/tasks/auto_doc.document.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Mix.Tasks.AutoDoc.Document do

def run(_args) do
Mix.env(:test)
AutoDoc.Agent.start
AutoDoc.start
Mix.Task.run "test"
end
end
23 changes: 2 additions & 21 deletions lib/templates/api_docs.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@
<% end %>
<%= if Map.size(test.request.params) > 0 do %>
<h5>Params</h5>
<pre class="json">
<%= Poison.encode!(test.request.params) %>
</pre>
<pre class="json"><%= Poison.encode!(test.request.params, pretty: true) %></pre>
<% end %>
</div>
<hr>
Expand All @@ -65,9 +63,7 @@
</div>
<%= if String.length(test.response.body) > 0 do %>
<h5>Body</h5>
<pre class="json">
<%= test.response.body %>
</pre>
<pre class="json"><%= test.response.body |> Poison.decode!() |> Poison.encode!(pretty: true) %></pre>
<% end %>
</div>
</div>
Expand All @@ -76,20 +72,5 @@
</div>
<% end %>
</div>

<script type="text/javascript">
(function prettyPrintJson() {
var jsonNodes = document.getElementsByClassName("json");
for (i = 0; i < jsonNodes.length; i++) {
try {
var json = JSON.parse(jsonNodes[i].innerText.trim());
jsonNodes[i].innerText = JSON.stringify(json, null, 2);
jsonNodes[i].className = jsonNodes[i].className + " prettyprint";
} catch (error) {
console.error("Error: " + error);
}
}
})();
</script>
</body>
</html>
23 changes: 23 additions & 0 deletions lib/templates/api_docs.md.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<%= for test <- tests do %># <%= test.test_name %>

## <%= test.request.method %> <%= test.request.path %>

### Request
<%= if Enum.count(test.request.headers) > 0 do %><%= for headers <- test.request.headers do %>* <%= "#{Enum.join(Tuple.to_list(headers), ": `")}`" |> String.strip %>
<% end %><% end %>
<%= if Map.size(test.request.params) > 0 do %>```json
<%= Poison.encode!(test.request.params, pretty: true) %>
```
<% end %>
### Response

* Status: `<%= test.response.status %>`
<%= if Enum.count(test.response.headers) > 0 do %><%= for headers <- test.response.headers do %>* <%= "#{Enum.join(Tuple.to_list(headers), ": `")}`" |> String.strip %>
<% end %><% end %>
<%= if String.length(test.response.body) > 0 do %>Returns this body response :

```json
<%= test.response.body |> Poison.decode!() |> Poison.encode!(pretty: true) %>
```<% end %>

<% end %>
17 changes: 8 additions & 9 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule AutoDoc.Mixfile do
use Mix.Project

@version "0.0.2"
@version "0.0.3"

def project do
[app: :auto_doc,
Expand All @@ -25,11 +25,10 @@ defmodule AutoDoc.Mixfile do

defp deps do
[{:plug, "~> 1.0"},
{:poison, "~> 1.5"},

# Docs dependencies
{:earmark, "~> 0.1", only: :docs},
{:ex_doc, "~> 0.10", only: :docs}]
{:poison, "~> 1.5"},
# Docs dependencies
{:earmark, "~> 0.1", only: :docs},
{:ex_doc, "~> 0.10", only: :docs}]
end

defp elixirc_paths(:test), do: ["lib", "test/support"]
Expand All @@ -43,8 +42,8 @@ defmodule AutoDoc.Mixfile do

defp package do
[files: ["lib", "mix.exs", "README*"],
maintainers: ["Michael Eatherly"],
licenses: ["MIT"],
links: %{"GitHub" => "https://github.com/meatherly/auto_doc"}]
maintainers: ["Michael Eatherly", "Hugues Dubois"],
licenses: ["MIT"],
links: %{"GitHub" => "https://github.com/meatherly/auto_doc"}]
end
end
8 changes: 4 additions & 4 deletions test/auto_doc/agent_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ defmodule AutoDoc.AgentTest do
# alias AutoDoc.Agent

test "It should not generate api docs file if exit code is 1" do
capture_io(fn ->
assert capture_io(fn ->
AutoDoc.Agent.write_file(1)
end) == "Tests have failed. No docs will be generated"
end) == "Tests have failed. No docs will be generated\n"
end


test "It should generate api docs file if the exit code is 0" do
capture_io(fn ->
assert capture_io(fn ->
AutoDoc.Agent.write_file(0)
assert File.exists?("#{Path.expand(".")}/api_docs.html")
end) == "Tests have failed. No docs will be generated"
end) == "Api docs have been created.\n"
end
end
24 changes: 16 additions & 8 deletions test/auto_doc_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ defmodule AutoDocTest do
assert Agent.get(agent, fn(docs) -> docs end)
|> Enum.any?(fn(doc) ->
doc == %{response: AutoDoc.Response.new(conn),
request: AutoDoc.Request.new(conn),
test_name: "Retrieve a list of users"}
request: AutoDoc.Request.new(conn),
test_name: "Retrieve a list of users",
file_name: "#{Path.expand(".")}/api_docs",
file_format: "html"}
end)
end

Expand All @@ -36,8 +38,10 @@ defmodule AutoDocTest do
assert Agent.get(agent, fn(docs) -> docs end)
|> Enum.any?(fn(doc) ->
doc == %{response: AutoDoc.Response.new(conn),
request: AutoDoc.Request.new(conn),
test_name: "Add a new user"}
request: AutoDoc.Request.new(conn),
test_name: "Add a new user",
file_name: "#{Path.expand(".")}/api_docs",
file_format: "html"}
end)
end

Expand All @@ -50,8 +54,10 @@ defmodule AutoDocTest do
assert Agent.get(agent, fn(docs) -> docs end)
|> Enum.any?(fn(doc) ->
doc == %{response: AutoDoc.Response.new(conn),
request: AutoDoc.Request.new(conn),
test_name: "Update a user"}
request: AutoDoc.Request.new(conn),
test_name: "Update a user",
file_name: "#{Path.expand(".")}/api_docs",
file_format: "html"}
end)
end

Expand All @@ -64,8 +70,10 @@ defmodule AutoDocTest do
assert Agent.get(agent, fn(docs) -> docs end)
|> Enum.any?(fn(doc) ->
doc == %{response: AutoDoc.Response.new(conn),
request: AutoDoc.Request.new(conn),
test_name: "Delete a user"}
request: AutoDoc.Request.new(conn),
test_name: "Delete a user",
file_name: "#{Path.expand(".")}/api_docs",
file_format: "html"}
end)
end
end