Bureaucrat
Bureaucrat is a library that lets you generate API documentation of your Phoenix app from tests.
Installation
First, add Bureaucrat to your mix.exs dependencies:
defp deps do
[{:bureaucrat, "~> 0.1.4"}]
end
Then, update your dependencies:
$ mix deps.get
Next, in your test/test_helper.exs you should start Bureaucrat and configure
ExUnit to use its formatter. You would probably like to keep the default
ExUnit.CLIFormatter as well.
Bureaucrat.start
ExUnit.start(formatters: [ExUnit.CLIFormatter, Bureaucrat.Formatter])
And finally, import Bureaucrat helpers in test/support/conn_case.ex:
defmodule Spell.ConnCase do
using do
quote do
import Bureaucrat.Helpers
end
end
end
To generate Phoenix channel documentation, import the helpers in test/support/channel_case.ex alike.
Usage
Bureaucrat collects data from connection structs used in tests.
If you want a connection to be documented, pass it to the doc/1 function:
test "GET /api/v1/products" do
conn = conn()
|> get("/api/v1/products")
|> doc
assert conn.status == 200
end
Additional options can be passed to the backend formatter:
test "GET /api/v1/products" do
conn = conn()
|> get("/api/v1/products")
|> doc(description: "List all products", operation_id: "list_products")
assert conn.status == 200
end
Then, to generate the documentation file(s) run DOC=1 mix test.
The default output file is web/controllers/README.md.
Custom intro sections
To add a custom intro section, for each output file, bureaucrat will look for an intro markdown file in the output directory,
named like the output file with a _intro or _INTRO suffix (before .md, if present), e.g.
web/controllers/README->web/controllers/README_INTROweb/controllers/readme.md->web/controllers/readme_intro.md
Currently only supported by the (default) Bureaucrat.MarkdownWriter.
Documenting Phoenix Channels
Bureaucrat can also generate documentation for messages, replies and broadcasts in Phoenix Channels.
Results of assert_push, assert_broadcast and the underlying assert_receive (if used for messages or broadcasts) can be passed to the doc function.
To document usage of Phoenix.ChannelTest helpers push, broadcast_from and broadcast_from!, Bureaucrat includes documenting alternatives, prefixed with doc_:
doc_pushdoc_broadcast_fromdoc_broadcast_from!
test "message:new broadcasts are pushed to the client", %{socket: socket} do
doc_broadcast_from! socket, "message:new", %{body: "Hello there!", timestamp: 1483971926566, user: "marla"}
assert_push("message:new", %{body: "Hello there!", timestamp: 1483971926566, user: "marla"})
|> doc
end
Channels docs output is currently only supported by the Bureaucrat.MarkdownWriter and only to the default_path (see Configuration below).
Swagger & Slate Integration
Bureaucrat comes with the Bureaucrat.SwaggerSlateMarkdownWriter backend that will merge test examples with a swagger spec to produce markdown files that can be processed with the slate static generator.
To configure swagger integration, first write a swagger file by hand or generate one using phoenix_swagger. In the example below, the swagger file exists in the project at priv/static/swagger.json.
Clone the slate project into a directory in your project:
git clone --shallow https://github.com/lord/slate doc
Configure Bureaucrat writer, default_path and swagger:
Bureaucrat.start(
env_var: "DOC",
writer: Bureaucrat.SwaggerSlateMarkdownWriter,
default_path: "doc/source/index.html.md",
swagger: "priv/static/swagger.json" |> File.read!() |> Poison.decode!())
Within each test, link the test example to a swagger operation by passing an operation_id to the doc helper:
test "creates and renders resource when data is valid", %{conn: conn} do
conn =
conn
|> post(user_path(conn, :create), user: @valid_attrs)
|> doc(operation_id: "create_user")
assert json_response(conn, 201)["data"]["id"]
assert Repo.get_by(User, @valid_attrs)
end
Now generate documentation with DOC=1 mix test.
Use slate to convert the markdown to HTML:
cd doc
bundle install
bundle exec middleman build
To serve the documentation directly from your application, copy the slate build output to your priv/static directory:
mkdir priv/static/doc
cp -R doc/build/* priv/static/doc
Whitelist the doc directory for static assets in the Plug.Static configuration:
plug Plug.Static,
at: "/", from: :swagger_demo, gzip: false,
only: ~w(css doc fonts images js favicon.ico robots.txt)
Run your application with mix phoenix.server and visit http://localhost:4000/doc/index.html to see your documentation.
For a full example see the examples/swagger_demo project.
Configuration
The configuration options can be passed to Bureaucrat.start:
Bureaucrat.start(
writer: Bureaucrat.MarkdownWriter,
default_path: "web/controllers/README.md",
paths: [],
titles: [],
env_var: "DOC"
)
The available options are:
:writer: The module used to generate docs from the list of captured connections.:default_path: The path where the docs are written by default.:paths: Allows you to specify different doc paths for some of your modules. For example[{YourApp.Api.V1, "web/controllers/api/v1/README.md"}]will cause the docs for controllers underYourApp.Api.V1namespace to be written toweb/controllers/api/v1/README.md.:titles: Allows you to specify explicit titles for some of your modules. For example[{YourApp.Api.V1.UserController, "API /v1/users"}]will change the title (Table of Contents entry and heading) for this controller.:env_var: The environment variable used as a flag to trigger doc generation.