1224 lines
23 KiB
Elixir
1224 lines
23 KiB
Elixir
Code.require_file("../test_helper.exs", __DIR__)
|
|
|
|
defmodule Code.Formatter.CallsTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
import CodeFormatterHelpers
|
|
|
|
@short_length [line_length: 10]
|
|
@medium_length [line_length: 20]
|
|
|
|
describe "next break fits" do
|
|
test "does not apply to function calls" do
|
|
bad = "foo(very_long_call(bar))"
|
|
|
|
good = """
|
|
foo(
|
|
very_long_call(
|
|
bar
|
|
)
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "does not apply to strings" do
|
|
bad = "foo(\"very long string\")"
|
|
|
|
good = """
|
|
foo(
|
|
"very long string"
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "for functions" do
|
|
assert_same """
|
|
foo(fn x -> y end)
|
|
"""
|
|
|
|
assert_same """
|
|
foo(fn
|
|
a1 -> :ok
|
|
b2 -> :error
|
|
end)
|
|
"""
|
|
|
|
assert_same """
|
|
foo(bar, fn
|
|
a1 -> :ok
|
|
b2 -> :error
|
|
end)
|
|
"""
|
|
|
|
assert_same """
|
|
foo(fn x ->
|
|
:really_long_atom
|
|
end)
|
|
""",
|
|
@medium_length
|
|
|
|
assert_same """
|
|
foo(bar, fn
|
|
a1 ->
|
|
:ok
|
|
|
|
b2 ->
|
|
:really_long_error
|
|
end)
|
|
""",
|
|
@medium_length
|
|
end
|
|
|
|
test "for heredocs" do
|
|
assert_same """
|
|
foo(~c'''
|
|
bar
|
|
''')
|
|
"""
|
|
|
|
assert_same ~S'''
|
|
foo("""
|
|
bar
|
|
""")
|
|
'''
|
|
|
|
assert_same """
|
|
foo(~S'''
|
|
bar
|
|
''')
|
|
"""
|
|
|
|
assert_same """
|
|
foo(~S'''
|
|
very long line does trigger another break
|
|
''')
|
|
""",
|
|
@short_length
|
|
end
|
|
|
|
test "for lists" do
|
|
bad = "foo([1, 2, 3, 4])"
|
|
|
|
good = """
|
|
foo([
|
|
1,
|
|
2,
|
|
3,
|
|
4
|
|
])
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "for {} calls" do
|
|
bad = """
|
|
alias Foo.{
|
|
Bar, Baz
|
|
}
|
|
"""
|
|
|
|
good = """
|
|
alias Foo.{
|
|
Bar,
|
|
Baz
|
|
}
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "for binaries only on eol" do
|
|
bad = "foo(<<1, 2, 3, 4>>)"
|
|
|
|
good = """
|
|
foo(
|
|
<<1, 2,
|
|
3, 4>>
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
|
|
bad = """
|
|
foo(<<
|
|
# foo
|
|
1,
|
|
2,
|
|
3,
|
|
4>>)
|
|
"""
|
|
|
|
good = """
|
|
foo(<<
|
|
# foo
|
|
1,
|
|
2,
|
|
3,
|
|
4
|
|
>>)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
end
|
|
|
|
describe "local calls" do
|
|
test "without arguments" do
|
|
assert_format "foo( )", "foo()"
|
|
end
|
|
|
|
test "without arguments doesn't split on line limit" do
|
|
assert_same "very_long_function_name()", @short_length
|
|
end
|
|
|
|
test "removes outer parens except for unquote_splicing/1" do
|
|
assert_format "(foo())", "foo()"
|
|
assert_same "(unquote_splicing(123))"
|
|
end
|
|
|
|
test "with arguments" do
|
|
assert_format "foo( :one ,:two,\n :three)", "foo(:one, :two, :three)"
|
|
end
|
|
|
|
test "with arguments splits on line limit" do
|
|
bad = """
|
|
fun(x, y, z)
|
|
"""
|
|
|
|
good = """
|
|
fun(
|
|
x,
|
|
y,
|
|
z
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "with arguments on comma limit" do
|
|
bad = """
|
|
import(foo(abc, cde), :next)
|
|
"""
|
|
|
|
good = """
|
|
import(
|
|
foo(abc, cde),
|
|
:next
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "with keyword lists" do
|
|
assert_same "foo(foo: 1, bar: 2)"
|
|
assert_same "foo(:hello, foo: 1, bar: 2)"
|
|
|
|
bad = """
|
|
foo(:hello, foo: 1, bar: 2)
|
|
"""
|
|
|
|
good = """
|
|
foo(
|
|
:hello,
|
|
foo: 1,
|
|
bar: 2
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
|
|
bad = """
|
|
foo(:hello, foo: 1,
|
|
bar: 2, baz: 3)
|
|
"""
|
|
|
|
assert_format bad, """
|
|
foo(:hello, foo: 1, bar: 2, baz: 3)
|
|
"""
|
|
end
|
|
|
|
test "with lists maybe rewritten as keyword lists" do
|
|
assert_format "foo([foo: 1, bar: 2])", "foo(foo: 1, bar: 2)"
|
|
assert_format "foo(:arg, [foo: 1, bar: 2])", "foo(:arg, foo: 1, bar: 2)"
|
|
assert_same "foo(:arg, [:elem, foo: 1, bar: 2])"
|
|
end
|
|
|
|
test "without parens" do
|
|
assert_same "import :foo, :bar"
|
|
assert_same "bar = if foo, do: bar, else: baz"
|
|
|
|
assert_same """
|
|
for :one,
|
|
:two,
|
|
:three,
|
|
fn ->
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
for :one, fn ->
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "without parens on line limit" do
|
|
bad = "import :long_atom, :other_arg"
|
|
|
|
good = """
|
|
import :long_atom,
|
|
:other_arg
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "without parens on comma limit" do
|
|
bad = """
|
|
import foo(abc, cde), :next
|
|
"""
|
|
|
|
good = """
|
|
import foo(
|
|
abc,
|
|
cde
|
|
),
|
|
:next
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "without parens and with keyword lists preserves multiline" do
|
|
assert_same """
|
|
defstruct foo: 1,
|
|
bar: 2
|
|
"""
|
|
|
|
assert_same """
|
|
config :app,
|
|
foo: 1
|
|
"""
|
|
|
|
assert_same """
|
|
config :app,
|
|
foo: 1,
|
|
bar: 2
|
|
"""
|
|
|
|
assert_same """
|
|
config :app, :key,
|
|
foo: 1,
|
|
bar: 2
|
|
"""
|
|
|
|
assert_same """
|
|
config :app,
|
|
:key,
|
|
foo: 1,
|
|
bar: 2
|
|
"""
|
|
|
|
bad = """
|
|
config :app, foo: 1,
|
|
bar: 2
|
|
"""
|
|
|
|
assert_format bad, """
|
|
config :app,
|
|
foo: 1,
|
|
bar: 2
|
|
"""
|
|
end
|
|
|
|
test "without parens and with keyword lists on comma limit" do
|
|
bad = """
|
|
import foo(abc, cde), opts: :next
|
|
"""
|
|
|
|
good = """
|
|
import foo(
|
|
abc,
|
|
cde
|
|
),
|
|
opts: :next
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "without parens and with keyword lists on line limit" do
|
|
assert_same "import :atom, opts: [foo: :bar]"
|
|
|
|
bad = "import :atom, opts: [foo: :bar]"
|
|
|
|
good = """
|
|
import :atom,
|
|
opts: [foo: :bar]
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
|
|
bad = "import :atom, really_long_key: [foo: :bar]"
|
|
|
|
good = """
|
|
import :atom,
|
|
really_long_key: [
|
|
foo: :bar
|
|
]
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
|
|
assert_same """
|
|
import :foo,
|
|
one: two,
|
|
three: four,
|
|
five: [6, 7, 8, 9]
|
|
""",
|
|
@medium_length
|
|
|
|
assert_same """
|
|
import :really_long_atom_but_no_breaks,
|
|
one: two,
|
|
three: four
|
|
""",
|
|
@medium_length
|
|
|
|
bad = "with :really_long_atom1, :really_long_atom2, opts: [foo: :bar]"
|
|
|
|
good = """
|
|
with :really_long_atom1,
|
|
:really_long_atom2,
|
|
opts: [
|
|
foo: :bar
|
|
]
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "without parens from option" do
|
|
assert_format "foo bar", "foo(bar)"
|
|
assert_same "foo bar", locals_without_parens: [foo: 1]
|
|
assert_same "foo(bar)", locals_without_parens: [foo: 1]
|
|
assert_same "foo bar", locals_without_parens: [foo: :*]
|
|
assert_same "foo(bar)", locals_without_parens: [foo: :*]
|
|
end
|
|
|
|
test "without parens on unique argument" do
|
|
assert_same "foo(for 1, 2, 3)"
|
|
assert_same "foo(bar, for(1, 2, 3))"
|
|
assert_same "assert for 1, 2, 3"
|
|
assert_same "assert foo, for(1, 2, 3)"
|
|
|
|
assert_same """
|
|
assert for 1, 2, 3 do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
assert foo, for(1, 2, 3) do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
assert for(1, 2, 3) do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
assert (for 1, 2, 3 do
|
|
:ok
|
|
end)
|
|
"""
|
|
end
|
|
|
|
test "call on call" do
|
|
assert_same "unquote(call)()"
|
|
assert_same "unquote(call)(one, two)"
|
|
|
|
assert_same """
|
|
unquote(call)() do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
unquote(call)(one, two) do
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "call on call on line limit" do
|
|
bad = "foo(bar)(one, two, three)"
|
|
|
|
good = """
|
|
foo(bar)(
|
|
one,
|
|
two,
|
|
three
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "with generators" do
|
|
assert_same "foo(bar <- baz, is_bat(bar))"
|
|
assert_same "for bar <- baz, is_bat(bar)"
|
|
|
|
assert_same """
|
|
foo(
|
|
bar <- baz,
|
|
is_bat(bar),
|
|
bat <- bar
|
|
)
|
|
"""
|
|
|
|
assert_same """
|
|
for bar <- baz,
|
|
is_bat(bar),
|
|
bat <- bar
|
|
"""
|
|
|
|
assert_same """
|
|
for bar <- baz,
|
|
is_bat(bar),
|
|
bat <- bar do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
for bar <- baz,
|
|
is_bat(bar),
|
|
bat <- bar,
|
|
into: %{}
|
|
"""
|
|
end
|
|
|
|
test "preserves user choice on parens even when it fits" do
|
|
assert_same """
|
|
call(
|
|
:hello,
|
|
:foo,
|
|
:bar
|
|
)
|
|
"""
|
|
|
|
assert_same """
|
|
call(
|
|
:hello,
|
|
:foo,
|
|
:bar
|
|
) do
|
|
1 + 2
|
|
end
|
|
"""
|
|
|
|
# Doesn't preserve this because only the ending has a newline
|
|
assert_format "call(foo, bar, baz\n)", "call(foo, bar, baz)"
|
|
|
|
# Doesn't preserve because there are no args
|
|
bad = """
|
|
call() do
|
|
1 + 2
|
|
end
|
|
"""
|
|
|
|
assert_format bad, """
|
|
call do
|
|
1 + 2
|
|
end
|
|
"""
|
|
|
|
# Doesn't preserve because we have a single argument with next break fits
|
|
bad = """
|
|
call(
|
|
%{
|
|
key: :value
|
|
}
|
|
)
|
|
"""
|
|
|
|
assert_format bad, """
|
|
call(%{
|
|
key: :value
|
|
})
|
|
"""
|
|
end
|
|
end
|
|
|
|
describe "remote calls" do
|
|
test "with no arguments" do
|
|
assert_format "Foo . Bar . baz", "Foo.Bar.baz()"
|
|
assert_format ":erlang.\nget_stacktrace", ":erlang.get_stacktrace()"
|
|
assert_format "@foo.bar", "@foo.bar"
|
|
assert_format "@foo.bar()", "@foo.bar()"
|
|
assert_format "(@foo).bar()", "@foo.bar()"
|
|
assert_format "__MODULE__.start_link", "__MODULE__.start_link()"
|
|
assert_format "Foo.bar.baz.bong", "Foo.bar().baz.bong"
|
|
assert_format "(1 + 2).foo", "(1 + 2).foo"
|
|
assert_format "(1 + 2).foo()", "(1 + 2).foo()"
|
|
end
|
|
|
|
test "with arguments" do
|
|
assert_format "Foo . Bar. baz(1, 2, 3)", "Foo.Bar.baz(1, 2, 3)"
|
|
assert_format ":erlang.\nget(\n:some_key)", ":erlang.get(:some_key)"
|
|
assert_format ":erlang.\nget(:some_key\n)", ":erlang.get(:some_key)"
|
|
assert_same "@foo.bar(1, 2, 3)"
|
|
assert_same "__MODULE__.start_link(1, 2, 3)"
|
|
assert_same "foo.bar(1).baz(2, 3)"
|
|
end
|
|
|
|
test "inspects function names correctly" do
|
|
assert_same ~S[MyModule."my function"(1, 2)]
|
|
assert_same ~S[MyModule."Foo.Bar"(1, 2)]
|
|
assert_same ~S[Kernel.+(1, 2)]
|
|
assert_same ~S[:erlang.+(1, 2)]
|
|
assert_same ~S[foo."bar baz"(1, 2)]
|
|
end
|
|
|
|
test "splits on arguments and dot on line limit" do
|
|
bad = """
|
|
MyModule.Foo.bar(:one, :two, :three)
|
|
"""
|
|
|
|
good = """
|
|
MyModule.Foo.bar(
|
|
:one,
|
|
:two,
|
|
:three
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
|
|
bad = """
|
|
My_function.foo().bar(2, 3).baz(4, 5)
|
|
"""
|
|
|
|
good = """
|
|
My_function.foo().bar(
|
|
2,
|
|
3
|
|
).baz(4, 5)
|
|
"""
|
|
|
|
assert_format bad, good, @medium_length
|
|
end
|
|
|
|
test "doesn't split on parens on empty arguments" do
|
|
assert_same "Mod.func()", @short_length
|
|
end
|
|
|
|
test "with keyword lists" do
|
|
assert_same "mod.foo(foo: 1, bar: 2)"
|
|
|
|
assert_same "mod.foo(:hello, foo: 1, bar: 2)"
|
|
|
|
assert_same """
|
|
mod.really_long_function_name(
|
|
:hello,
|
|
foo: 1,
|
|
bar: 2
|
|
)
|
|
""",
|
|
@short_length
|
|
|
|
assert_same """
|
|
really_long_module_name.foo(
|
|
:hello,
|
|
foo: 1,
|
|
bar: 2
|
|
)
|
|
""",
|
|
@short_length
|
|
end
|
|
|
|
test "wraps left side in parens if it is an anonymous function" do
|
|
assert_same "(fn -> :ok end).foo"
|
|
end
|
|
|
|
test "wraps left side in parens if it is a do-end block" do
|
|
assert_same """
|
|
(if true do
|
|
:ok
|
|
end).foo
|
|
"""
|
|
end
|
|
|
|
test "wraps left side in parens if it is a do-end block as an argument" do
|
|
assert_same """
|
|
import (if true do
|
|
:ok
|
|
end).foo
|
|
"""
|
|
end
|
|
|
|
test "call on call" do
|
|
assert_same "foo.bar(call)()"
|
|
assert_same "foo.bar(call)(one, two)"
|
|
|
|
assert_same """
|
|
foo.bar(call)() do
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
foo.bar(call)(one, two) do
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "call on call on line limit" do
|
|
bad = "a.b(foo)(one, two, three)"
|
|
|
|
good = """
|
|
a.b(foo)(
|
|
one,
|
|
two,
|
|
three
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "on vars" do
|
|
assert_same "foo.bar"
|
|
assert_same "foo.bar()"
|
|
end
|
|
|
|
test "on vars before blocks" do
|
|
assert_same """
|
|
if var.field do
|
|
raise "oops"
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "on vars before brackets" do
|
|
assert_same """
|
|
exception.opts[:foo]
|
|
"""
|
|
end
|
|
|
|
test "preserves user choice on parens even when it fits" do
|
|
assert_same """
|
|
Remote.call(
|
|
:hello,
|
|
:foo,
|
|
:bar
|
|
)
|
|
"""
|
|
|
|
# Doesn't preserve this because only the ending has a newline
|
|
assert_format "Remote.call(foo, bar, baz\n)", "Remote.call(foo, bar, baz)"
|
|
|
|
assert_same """
|
|
Remote.call(
|
|
:hello,
|
|
:foo,
|
|
fn -> :bar end
|
|
)
|
|
"""
|
|
end
|
|
end
|
|
|
|
describe "anonymous function calls" do
|
|
test "without arguments" do
|
|
assert_format "foo . ()", "foo.()"
|
|
assert_format "(foo.()).().()", "foo.().().()"
|
|
assert_same "@foo.()"
|
|
assert_same "(1 + 1).()"
|
|
assert_same ":foo.()"
|
|
end
|
|
|
|
test "with arguments" do
|
|
assert_format "foo . (1, 2 , 3 )", "foo.(1, 2, 3)"
|
|
assert_format "foo . (1, 2 ).(3,4)", "foo.(1, 2).(3, 4)"
|
|
assert_same "@foo.(:one, :two)"
|
|
assert_same "foo.(1 + 1).(hello)"
|
|
end
|
|
|
|
test "does not split on dot on line limit" do
|
|
assert_same "my_function.()", @short_length
|
|
end
|
|
|
|
test "splits on arguments on line limit" do
|
|
bad = """
|
|
my_function.(1, 2, 3)
|
|
"""
|
|
|
|
good = """
|
|
my_function.(
|
|
1,
|
|
2,
|
|
3
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
|
|
bad = """
|
|
my_function.(1, 2).f(3, 4).(5, 6)
|
|
"""
|
|
|
|
good = """
|
|
my_function.(
|
|
1,
|
|
2
|
|
).f(3, 4).(
|
|
5,
|
|
6
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "with keyword lists" do
|
|
assert_same "foo.(foo: 1, bar: 2)"
|
|
|
|
assert_same "foo.(:hello, foo: 1, bar: 2)"
|
|
|
|
assert_same """
|
|
foo.(
|
|
:hello,
|
|
foo: 1,
|
|
bar: 2
|
|
)
|
|
""",
|
|
@short_length
|
|
end
|
|
|
|
test "wraps left side in parens if it is an anonymous function" do
|
|
assert_same "(fn -> :ok end).()"
|
|
end
|
|
|
|
test "wraps left side in parens if it is a do-end block" do
|
|
assert_same """
|
|
(if true do
|
|
:ok
|
|
end).()
|
|
"""
|
|
end
|
|
|
|
test "wraps left side in parens if it is a do-end block as an argument" do
|
|
assert_same """
|
|
import (if true do
|
|
:ok
|
|
end).()
|
|
"""
|
|
end
|
|
|
|
test "preserves user choice on parens even when it fits" do
|
|
assert_same """
|
|
call.(
|
|
:hello,
|
|
:foo,
|
|
:bar
|
|
)
|
|
"""
|
|
|
|
# Doesn't preserve this because only the ending has a newline
|
|
assert_format "call.(foo, bar, baz\n)", "call.(foo, bar, baz)"
|
|
end
|
|
end
|
|
|
|
describe "do-end blocks" do
|
|
test "with non-block keywords" do
|
|
assert_same "foo(do: nil)"
|
|
end
|
|
|
|
test "with forced block keywords" do
|
|
good = """
|
|
foo do
|
|
nil
|
|
end
|
|
"""
|
|
|
|
assert_format "foo(do: nil)", good, force_do_end_blocks: true
|
|
|
|
# Avoid false positives
|
|
assert_same "foo(do: 1, do: 2)", force_do_end_blocks: true
|
|
assert_same "foo(do: 1, another: 2)", force_do_end_blocks: true
|
|
end
|
|
|
|
test "with multiple keywords" do
|
|
assert_same """
|
|
foo do
|
|
:do
|
|
rescue
|
|
:rescue
|
|
catch
|
|
:catch
|
|
else
|
|
:else
|
|
after
|
|
:after
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "with multiple keywords and arrows" do
|
|
assert_same """
|
|
foo do
|
|
a1 -> a2
|
|
b1 -> b2
|
|
rescue
|
|
a1 -> a2
|
|
b1 -> b2
|
|
catch
|
|
a1 -> a2
|
|
b1 -> b2
|
|
else
|
|
a1 -> a2
|
|
b1 -> b2
|
|
after
|
|
a1 -> a2
|
|
b1 -> b2
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "with no extra arguments" do
|
|
assert_same """
|
|
foo do
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "with no extra arguments and line breaks" do
|
|
assert_same """
|
|
foo do
|
|
a1 ->
|
|
really_long_line
|
|
|
|
b1 ->
|
|
b2
|
|
rescue
|
|
c1
|
|
catch
|
|
d1 -> d1
|
|
e1 -> e1
|
|
else
|
|
f2
|
|
after
|
|
g1 ->
|
|
really_long_line
|
|
|
|
h1 ->
|
|
h2
|
|
end
|
|
""",
|
|
@medium_length
|
|
end
|
|
|
|
test "with extra arguments" do
|
|
assert_same """
|
|
foo bar, baz do
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "with extra arguments and line breaks" do
|
|
assert_same """
|
|
foo bar do
|
|
a1 ->
|
|
really_long_line
|
|
|
|
b1 ->
|
|
b2
|
|
rescue
|
|
c1
|
|
catch
|
|
d1 -> d1
|
|
e1 -> e1
|
|
else
|
|
f2
|
|
after
|
|
g1 ->
|
|
really_long_line
|
|
|
|
h1 ->
|
|
h2
|
|
end
|
|
""",
|
|
@medium_length
|
|
|
|
assert_same """
|
|
foo really,
|
|
long,
|
|
list,
|
|
of,
|
|
arguments do
|
|
a1 ->
|
|
really_long_line
|
|
|
|
b1 ->
|
|
b2
|
|
rescue
|
|
c1
|
|
catch
|
|
d1 -> d1
|
|
e1 -> e1
|
|
else
|
|
f2
|
|
after
|
|
g1 ->
|
|
really_long_line
|
|
|
|
h1 ->
|
|
h2
|
|
end
|
|
""",
|
|
@medium_length
|
|
end
|
|
|
|
test "when empty" do
|
|
assert_same """
|
|
foo do
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
foo do
|
|
rescue
|
|
catch
|
|
else
|
|
after
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "inside call" do
|
|
bad = "foo (bar do :ok end)"
|
|
|
|
good = """
|
|
foo(
|
|
bar do
|
|
:ok
|
|
end
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good
|
|
|
|
bad = "import (bar do :ok end)"
|
|
|
|
good = """
|
|
import (bar do
|
|
:ok
|
|
end)
|
|
"""
|
|
|
|
assert_format bad, good
|
|
end
|
|
|
|
test "inside operator" do
|
|
bad = "foo + bar do :ok end"
|
|
|
|
good = """
|
|
foo +
|
|
bar do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_format bad, good
|
|
end
|
|
|
|
test "inside operator inside argument" do
|
|
bad = "fun foo + (bar do :ok end)"
|
|
|
|
good = """
|
|
fun(
|
|
foo +
|
|
bar do
|
|
:ok
|
|
end
|
|
)
|
|
"""
|
|
|
|
assert_format bad, good
|
|
|
|
bad = "if foo + (bar do :ok end) do :ok end"
|
|
|
|
good = """
|
|
if foo +
|
|
(bar do
|
|
:ok
|
|
end) do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_format bad, good
|
|
end
|
|
|
|
test "inside operator inside argument with remote call" do
|
|
bad = "if foo + (Bar.baz do :ok end) do :ok end"
|
|
|
|
good = """
|
|
if foo +
|
|
(Bar.baz do
|
|
:ok
|
|
end) do
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_format bad, good
|
|
end
|
|
|
|
test "keeps repeated keys" do
|
|
assert_same """
|
|
receive do
|
|
:ok
|
|
after
|
|
0 -> 1
|
|
after
|
|
2 -> 3
|
|
end
|
|
"""
|
|
end
|
|
|
|
test "preserves user choice even when it fits" do
|
|
assert_same """
|
|
case do
|
|
1 ->
|
|
:ok
|
|
|
|
2 ->
|
|
:ok
|
|
end
|
|
"""
|
|
|
|
assert_same """
|
|
case do
|
|
1 ->
|
|
:ok
|
|
|
|
2 ->
|
|
:ok
|
|
|
|
3 ->
|
|
:ok
|
|
end
|
|
"""
|
|
end
|
|
end
|
|
|
|
describe "tuple calls" do
|
|
test "without arguments" do
|
|
assert_format "foo . {}", "foo.{}"
|
|
end
|
|
|
|
test "with arguments" do
|
|
assert_format "foo.{bar,baz,bat,}", "foo.{bar, baz, bat}"
|
|
end
|
|
|
|
test "with arguments on line limit" do
|
|
bad = "foo.{bar,baz,bat,}"
|
|
|
|
good = """
|
|
foo.{
|
|
bar,
|
|
baz,
|
|
bat
|
|
}
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
|
|
bad = "really_long_expression.{bar,baz,bat,}"
|
|
|
|
good = """
|
|
really_long_expression.{
|
|
bar,
|
|
baz,
|
|
bat
|
|
}
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "with keywords" do
|
|
assert_same "expr.{:hello, foo: bar, baz: bat}"
|
|
end
|
|
|
|
test "preserves user choice on parens even when it fits" do
|
|
assert_same """
|
|
call.{
|
|
:hello,
|
|
:foo,
|
|
:bar
|
|
}
|
|
"""
|
|
|
|
assert_format "call.{foo, bar, baz\n}", "call.{foo, bar, baz}"
|
|
end
|
|
end
|
|
|
|
describe "access" do
|
|
test "with one argument" do
|
|
assert_format "foo[ bar ]", "foo[bar]"
|
|
end
|
|
|
|
test "with arguments on line limit" do
|
|
bad = "foo[really_long_argument()]"
|
|
|
|
good = """
|
|
foo[
|
|
really_long_argument()
|
|
]
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
|
|
bad = "really_long_expression[really_long_argument()]"
|
|
|
|
good = """
|
|
really_long_expression[
|
|
really_long_argument()
|
|
]
|
|
"""
|
|
|
|
assert_format bad, good, @short_length
|
|
end
|
|
|
|
test "with do-end blocks" do
|
|
assert_same """
|
|
(if true do
|
|
false
|
|
end)[key]
|
|
"""
|
|
end
|
|
|
|
test "with keywords" do
|
|
assert_format "expr[[]]", "expr[[]]"
|
|
assert_format "expr[foo: bar, baz: bat]", "expr[foo: bar, baz: bat]"
|
|
assert_format "expr[[foo: bar, baz: bat]]", "expr[[foo: bar, baz: bat]]"
|
|
end
|
|
end
|
|
end
|