Skip to content

Commit

Permalink
Use correct line length for results (#8)
Browse files Browse the repository at this point in the history
* Use correct line length for results

* Update changelog

* Fix compilation warning
  • Loading branch information
angelikatyborska authored Feb 27, 2024
1 parent d64c340 commit 79d0b3b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Support parsing multiline doctests with `iex>` on all lines, but reformat them using `...>` on every line but the first one.
- Fix implementation for multiline results. Multiline results are allowed, and they can be terminated with an empty new line or another doctest.
- Support exception expressions (`** (ModuleName) message`) in results.
- Desired line length for doctest result now accounts for its indentation.

## 0.1.0 (2024-02-25)

Expand Down
47 changes: 28 additions & 19 deletions lib/doctest_formatter/formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ defmodule DoctestFormatter.Formatter do
end

def do_format_expression(%DoctestExpression{} = chunk, opts) do
format_lines(chunk, opts) ++ format_result(chunk, opts)
end

defp format_lines(chunk, opts) do
first_line_symbol = "iex> "
next_line_symbol = "...> "

Expand All @@ -78,17 +82,25 @@ defmodule DoctestFormatter.Formatter do
line_length =
desired_line_length - elem(chunk.indentation, 1) - String.length(first_line_symbol)

formatted_lines =
chunk.lines
|> Enum.join("\n")
|> Code.format_string!(Keyword.put(opts, :line_length, line_length))
|> IO.iodata_to_binary()
|> String.split("\n")
|> Enum.with_index()
|> Enum.map(fn {line, index} ->
symbol = if(index == 0, do: first_line_symbol, else: next_line_symbol)
Indentation.indent(symbol <> line, chunk.indentation)
end)
opts = Keyword.put(opts, :line_length, line_length)

chunk.lines
|> Enum.join("\n")
|> Code.format_string!(opts)
|> IO.iodata_to_binary()
|> String.split("\n")
|> Enum.with_index()
|> Enum.map(fn {line, index} ->
symbol = if(index == 0, do: first_line_symbol, else: next_line_symbol)
Indentation.indent(symbol <> line, chunk.indentation)
end)
end

defp format_result(chunk, opts) do
desired_line_length = Keyword.get(opts, :line_length, default_elixir_line_length())

line_length = desired_line_length - elem(chunk.indentation, 1)
opts = Keyword.put(opts, :line_length, line_length)

string_result =
chunk.result
Expand All @@ -104,14 +116,11 @@ defmodule DoctestFormatter.Formatter do
|> IO.iodata_to_binary()
end

formatted_result =
string_result
|> String.split("\n")
|> Enum.map(fn line ->
Indentation.indent(line, chunk.indentation)
end)

formatted_lines ++ formatted_result
string_result
|> String.split("\n")
|> Enum.map(fn line ->
Indentation.indent(line, chunk.indentation)
end)
end

defp exception_result?(string) do
Expand Down
30 changes: 29 additions & 1 deletion test/doctest_formatter/formatter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ defmodule DoctestFormatter.FormatterTest do
assert output == desired_output
end

test "adjust desired line length to fit the indentation and 'iex> '" do
test "adjust desired test code line length to fit the indentation and 'iex> '" do
opts = [line_length: 30]

input =
Expand Down Expand Up @@ -677,6 +677,34 @@ defmodule DoctestFormatter.FormatterTest do
assert output == desired_output
end

test "adjust desired result line length to fit the indentation" do
opts = [line_length: 30]

input =
"""
defmodule Foo do
@doc \"""
iex> "aaa"
"a" <> "a" <> "a"
\"""
end
"""

desired_output =
"""
defmodule Foo do
@doc \"""
iex> "aaa"
"a" <>
"a" <> "a"
\"""
end
"""

output = format(input, opts)
assert output == desired_output
end

test "can handle exceptions in results" do
input =
"""
Expand Down

0 comments on commit 79d0b3b

Please sign in to comment.