From 6e3d0a80faee0b9150fa0cc96b5d7d1ecd615b8c Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Fri, 5 Apr 2024 12:07:06 -0600 Subject: [PATCH 1/5] failing test --- lib/style/configs.ex | 1 + test/style/configs_test.exs | 15 +++++++++++++++ test/support/style_case.ex | 6 ++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/style/configs.ex b/lib/style/configs.ex index dddcb5fd..092aa6e7 100644 --- a/lib/style/configs.ex +++ b/lib/style/configs.ex @@ -70,6 +70,7 @@ defmodule Styler.Style.Configs do |> Enum.reverse() end) |> Style.fix_line_numbers(List.first(rest)) + |> dbg() assignments = assignments |> Enum.reverse() |> Style.reset_newlines() diff --git a/test/style/configs_test.exs b/test/style/configs_test.exs index 4a09b727..e3ac80ff 100644 --- a/test/style/configs_test.exs +++ b/test/style/configs_test.exs @@ -133,4 +133,19 @@ defmodule Styler.Style.ConfigsTest do config :c, :d """ end + + describe "playing nice with comments" do + test "lets you leave comments in large stanzas" do + assert_style """ + import Config + + config :a, B, :c + + config :a, + b: :c, + # d is here + d: :e + """ + end + end end diff --git a/test/support/style_case.ex b/test/support/style_case.ex index 80627c5a..c7056f3f 100644 --- a/test/support/style_case.ex +++ b/test/support/style_case.ex @@ -38,13 +38,11 @@ defmodule Styler.StyleCase do {before_ast, before_comments} = Styler.string_to_quoted_with_comments(before) dbg(before_ast) dbg(before_comments) - IO.puts("======Expected==========\n") - IO.puts(expected) + IO.puts("======Expected AST==========\n") {expected_ast, expected_comments} = Styler.string_to_quoted_with_comments(expected) dbg(expected_ast) dbg(expected_comments) - IO.puts("======Got===============\n") - IO.puts(styled) + IO.puts("======Got AST===============\n") dbg(styled_ast) dbg(styled_comments) IO.puts("========================\n") From a62eaa15cd6a8b62c5ddf7a7999e055548dec9d0 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Fri, 5 Apr 2024 12:20:52 -0600 Subject: [PATCH 2/5] better names for style tests --- test/support/style_case.ex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/support/style_case.ex b/test/support/style_case.ex index c7056f3f..37b7cb5f 100644 --- a/test/support/style_case.ex +++ b/test/support/style_case.ex @@ -129,23 +129,23 @@ defmodule Styler.StyleCase do end end - def format_diff(left, right, prelude \\ "Styling produced unexpected results") do + def format_diff(expected, styled, prelude \\ "Styling produced unexpected results") do # reaching into private ExUnit stuff, uh oh! # this gets us the nice diffing from ExUnit while allowing us to print our code blocks as strings rather than inspected strings - {%{left: left, right: right}, _} = ExUnit.Diff.compute(left, right, :==) - left = for {diff?, content} <- left.contents, do: if(diff?, do: [:red, content, :reset], else: content) - right = for {diff?, content} <- right.contents, do: if(diff?, do: [:green, content, :reset], else: content) + {%{left: expected, right: styled}, _} = ExUnit.Diff.compute(expected, styled, :==) + expected = for {diff?, content} <- expected.contents, do: if(diff?, do: [:red, content, :reset], else: content) + styled = for {diff?, content} <- styled.contents, do: if(diff?, do: [:green, content, :reset], else: content) header = IO.ANSI.format([:red, prelude, :reset]) - left = - [[:cyan, "left:\n", :reset] | left] + expected = + [[:cyan, "expected:\n", :reset] | expected] |> IO.ANSI.format() |> to_string() |> Macro.unescape_string() |> String.replace("\n", "\n ") - right = - [[:cyan, "right:\n", :reset] | right] + styled = + [[:cyan, "styled:\n", :reset] | styled] |> IO.ANSI.format() |> to_string() |> Macro.unescape_string() @@ -153,8 +153,8 @@ defmodule Styler.StyleCase do """ #{header} - #{left} - #{right} + #{expected} + #{styled} """ end end From 41c9e1b460cf81656984bcd9fba70beeaa06a322 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Fri, 5 Apr 2024 13:53:52 -0600 Subject: [PATCH 3/5] hmm --- .formatter.exs | 3 +- lib/style/configs.ex | 27 ++++++++---------- test/style/configs_test.exs | 55 +++++++++++++++++-------------------- test/support/style_case.ex | 2 +- 4 files changed, 39 insertions(+), 48 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index b41a4519..662f9c07 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -4,8 +4,7 @@ "{config,lib,test}/**/*.{ex,exs}" ], locals_without_parens: [ - assert_style: 1, - assert_style: 2 + assert_style: 1 ], plugins: [Styler], line_length: 122 diff --git a/lib/style/configs.ex b/lib/style/configs.ex index 092aa6e7..d3d7f119 100644 --- a/lib/style/configs.ex +++ b/lib/style/configs.ex @@ -49,33 +49,26 @@ defmodule Styler.Style.Configs do def run({{:config, _, [_, _ | _]} = config, zm}, %{mix_config?: true} = ctx) do # all of these list are reversed due to the reduce - {configs, assignments, rest} = - Enum.reduce(zm.r, {[], [], []}, fn - {:config, _, [_, _ | _]} = config, {configs, assignments, []} -> {[config | configs], assignments, []} - {:=, _, [_lhs, _rhs]} = assignment, {configs, assignments, []} -> {configs, [assignment | assignments], []} - other, {configs, assignments, rest} -> {configs, assignments, [other | rest]} - end) + {configs, assignments, rest} = accumulate(zm.r, [], []) + + left_siblings = assignments |> Enum.reverse() |> Style.reset_newlines() |> Enum.reverse(zm.l) - [config | configs] = + [config | left_siblings] = [config | configs] |> Enum.group_by(fn {:config, _, [{:__block__, _, [app]} | _]} -> app {:config, _, [arg | _]} -> Style.without_meta(arg) end) - |> Enum.sort(:desc) + |> Enum.sort() |> Enum.flat_map(fn {_app, configs} -> configs - |> Enum.sort_by(&Style.without_meta/1, :asc) + |> Enum.sort_by(&Style.without_meta/1) |> Style.reset_newlines() - |> Enum.reverse() end) |> Style.fix_line_numbers(List.first(rest)) - |> dbg() + |> Enum.reverse(left_siblings) - assignments = assignments |> Enum.reverse() |> Style.reset_newlines() - - zm = %{zm | l: configs ++ Enum.reverse(assignments, zm.l), r: Enum.reverse(rest)} - {:skip, {config, zm}, ctx} + {:skip, {config, %{zm | l: left_siblings, r: rest}}, ctx} end def run(zipper, %{config?: true} = ctx) do @@ -89,4 +82,8 @@ defmodule Styler.Style.Configs do {:halt, zipper, ctx} end end + + defp accumulate([{:config, _, [_, _ | _]} = c | siblings], cs, as), do: accumulate(siblings, [c | cs], as) + defp accumulate([{:=, _, [_lhs, _rhs]} = a | siblings], cs, as), do: accumulate(siblings, cs, [a | as]) + defp accumulate(rest, configs, assignments), do: {configs, assignments, rest} end diff --git a/test/style/configs_test.exs b/test/style/configs_test.exs index e3ac80ff..622e3fe7 100644 --- a/test/style/configs_test.exs +++ b/test/style/configs_test.exs @@ -27,28 +27,41 @@ defmodule Styler.Style.ConfigsTest do end end - test "orders configs stanzas" do - # doesn't order when we haven't seen `import Config`, so this is something else that we don't understand + test "doesn't sort when no import config" do assert_style """ - config :z, :x - config :a, :b + config :z, :x, :c + config :a, :b, :c """ + end - # 1. orders `config/2,3` relative to each other - # 2. lifts assignments above config blocks - # 3. non assignment/config separate "config" blocks + test "simple case" do + assert_style """ + import Config + + config :z, :x, :c + config :a, :b, :c + config :y, :x, :z + config :a, :c, :d + """, + """ + import Config + config :a, :b, :c + config :a, :c, :d + + config :y, :x, :z + + config :z, :x, :c + """ + end + + test "more complicated" do assert_style( """ import Config dog_sound = :woof - # z is best when configged w/ dog sounds - # dog sounds ftw config :z, :x, dog_sound - # this is my big c - # comment i'd like to leave c - # about c c = :c config :a, :b, c config :a, :c, :d @@ -56,15 +69,9 @@ defmodule Styler.Style.ConfigsTest do a_longer_name: :a_longer_value, multiple_things: :that_could_all_fit_on_one_line_though - # this is my big my_app - # comment i'd like to leave my_app - # about my_app my_app = :"dont_write_configs_like_this_yall_:(" - # this is my big your_app - # comment i'd like to leave your_app - # about your_app your_app = :not_again! config your_app, :dont_use_varrrrrrrrs config my_app, :nooooooooo @@ -79,23 +86,11 @@ defmodule Styler.Style.ConfigsTest do import Config dog_sound = :woof - # z is best when configged w/ dog sounds - # dog sounds ftw - - # this is my big c - # comment i'd like to leave c - # about c c = :c - # this is my big my_app - # comment i'd like to leave my_app - # about my_app my_app = :"dont_write_configs_like_this_yall_:(" - # this is my big your_app - # comment i'd like to leave your_app - # about your_app your_app = :not_again! config :a, :b, c diff --git a/test/support/style_case.ex b/test/support/style_case.ex index 37b7cb5f..d8ce14e5 100644 --- a/test/support/style_case.ex +++ b/test/support/style_case.ex @@ -109,7 +109,7 @@ defmodule Styler.StyleCase do assert true else flunk( - format_diff(restyled, styled, "expected styling to be idempotent, but a second pass resulted in more changes.") + format_diff(styled, restyled, "expected styling to be idempotent, but a second pass resulted in more changes.") ) end end From 0a8ed343352660b8c3ccb09dae8e402c8ae736e4 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Fri, 5 Apr 2024 14:25:43 -0600 Subject: [PATCH 4/5] more tests --- test/style/configs_test.exs | 84 +++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/test/style/configs_test.exs b/test/style/configs_test.exs index 622e3fe7..d941958d 100644 --- a/test/style/configs_test.exs +++ b/test/style/configs_test.exs @@ -142,5 +142,89 @@ defmodule Styler.Style.ConfigsTest do d: :e """ end + + test "complicated comments" do + assert_style(""" + import Config + dog_sound = :woof + # z is best when configged w/ dog sounds + # dog sounds ftw + config :z, :x, dog_sound + + # this is my big c + # comment i'd like to leave c + # about c + c = :c + config :a, :b, c + config :a, :c, :d + config :a, + a_longer_name: :a_longer_value, + multiple_things: :that_could_all_fit_on_one_line_though + + # this is my big my_app + # comment i'd like to leave my_app + # about my_app + my_app = + :"dont_write_configs_like_this_yall_:(" + + # this is my big your_app + # comment i'd like to leave your_app + # about your_app + your_app = :not_again! + config your_app, :dont_use_varrrrrrrrs + config my_app, :nooooooooo + import_config "my_config" + + cat_sound = :meow + config :z, a: :meow + a_sad_overwrite_that_will_be_hard_to_notice = :x + config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice + """, """ + import Config + + dog_sound = :woof + # z is best when configged w/ dog sounds + # dog sounds ftw + + # this is my big c + # comment i'd like to leave c + # about c + c = :c + + # this is my big my_app + # comment i'd like to leave my_app + # about my_app + my_app = + :"dont_write_configs_like_this_yall_:(" + + # this is my big your_app + # comment i'd like to leave your_app + # about your_app + your_app = :not_again! + + config :a, :b, c + config :a, :c, :d + + config :a, + a_longer_name: :a_longer_value, + multiple_things: :that_could_all_fit_on_one_line_though + + config :z, :x, dog_sound + + config my_app, :nooooooooo + + config your_app, :dont_use_varrrrrrrrs + + import_config "my_config" + + cat_sound = :meow + a_sad_overwrite_that_will_be_hard_to_notice = :x + + config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice + + config :z, a: :meow + """ + ) + end end end From d3962a5b0a15f5ac227a930be174349811eb64d2 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Fri, 5 Apr 2024 14:32:32 -0600 Subject: [PATCH 5/5] cleanup --- .formatter.exs | 3 +- test/style/configs_test.exs | 198 +++++++++++++++++++----------------- test/support/style_case.ex | 21 +++- 3 files changed, 124 insertions(+), 98 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index 662f9c07..b41a4519 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -4,7 +4,8 @@ "{config,lib,test}/**/*.{ex,exs}" ], locals_without_parens: [ - assert_style: 1 + assert_style: 1, + assert_style: 2 ], plugins: [Styler], line_length: 122 diff --git a/test/style/configs_test.exs b/test/style/configs_test.exs index d941958d..28962e94 100644 --- a/test/style/configs_test.exs +++ b/test/style/configs_test.exs @@ -35,24 +35,26 @@ defmodule Styler.Style.ConfigsTest do end test "simple case" do - assert_style """ - import Config + assert_style( + """ + import Config - config :z, :x, :c - config :a, :b, :c - config :y, :x, :z - config :a, :c, :d - """, - """ - import Config + config :z, :x, :c + config :a, :b, :c + config :y, :x, :z + config :a, :c, :d + """, + """ + import Config - config :a, :b, :c - config :a, :c, :d + config :a, :b, :c + config :a, :c, :d - config :y, :x, :z + config :y, :x, :z - config :z, :x, :c - """ + config :z, :x, :c + """ + ) end test "more complicated" do @@ -144,87 +146,93 @@ defmodule Styler.Style.ConfigsTest do end test "complicated comments" do - assert_style(""" - import Config - dog_sound = :woof - # z is best when configged w/ dog sounds - # dog sounds ftw - config :z, :x, dog_sound - - # this is my big c - # comment i'd like to leave c - # about c - c = :c - config :a, :b, c - config :a, :c, :d - config :a, - a_longer_name: :a_longer_value, - multiple_things: :that_could_all_fit_on_one_line_though - - # this is my big my_app - # comment i'd like to leave my_app - # about my_app - my_app = - :"dont_write_configs_like_this_yall_:(" - - # this is my big your_app - # comment i'd like to leave your_app - # about your_app - your_app = :not_again! - config your_app, :dont_use_varrrrrrrrs - config my_app, :nooooooooo - import_config "my_config" - - cat_sound = :meow - config :z, a: :meow - a_sad_overwrite_that_will_be_hard_to_notice = :x - config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice - """, """ - import Config - - dog_sound = :woof - # z is best when configged w/ dog sounds - # dog sounds ftw - - # this is my big c - # comment i'd like to leave c - # about c - c = :c - - # this is my big my_app - # comment i'd like to leave my_app - # about my_app - my_app = - :"dont_write_configs_like_this_yall_:(" - - # this is my big your_app - # comment i'd like to leave your_app - # about your_app - your_app = :not_again! - - config :a, :b, c - config :a, :c, :d - - config :a, - a_longer_name: :a_longer_value, - multiple_things: :that_could_all_fit_on_one_line_though - - config :z, :x, dog_sound - - config my_app, :nooooooooo - - config your_app, :dont_use_varrrrrrrrs - - import_config "my_config" - - cat_sound = :meow - a_sad_overwrite_that_will_be_hard_to_notice = :x - - config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice - - config :z, a: :meow - """ - ) + assert_style( + """ + import Config + dog_sound = :woof + # z is best when configged w/ dog sounds + # dog sounds ftw + config :z, :x, dog_sound + + # this is my big c + # comment i'd like to leave c + # about c + c = :c + config :a, :b, c + config :a, :c, :d + config :a, + a_longer_name: :a_longer_value, + # Multiline comment + # comment in a block + multiple_things: :that_could_all_fit_on_one_line_though + + # this is my big my_app + # comment i'd like to leave my_app + # about my_app + my_app = + :"dont_write_configs_like_this_yall_:(" + + # this is my big your_app + # comment i'd like to leave your_app + # about your_app + your_app = :not_again! + config your_app, :dont_use_varrrrrrrrs + config my_app, :nooooooooo + import_config "my_config" + + cat_sound = :meow + config :z, a: :meow + a_sad_overwrite_that_will_be_hard_to_notice = :x + config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice + """, + """ + import Config + + dog_sound = :woof + # z is best when configged w/ dog sounds + # dog sounds ftw + + # this is my big c + # comment i'd like to leave c + # about c + c = :c + # Multiline comment + # comment in a block + + # this is my big my_app + # comment i'd like to leave my_app + # about my_app + my_app = + :"dont_write_configs_like_this_yall_:(" + + # this is my big your_app + # comment i'd like to leave your_app + # about your_app + your_app = :not_again! + + config :a, :b, c + config :a, :c, :d + + config :a, + a_longer_name: :a_longer_value, + multiple_things: :that_could_all_fit_on_one_line_though + + config :z, :x, dog_sound + + config my_app, :nooooooooo + + config your_app, :dont_use_varrrrrrrrs + + import_config "my_config" + + cat_sound = :meow + a_sad_overwrite_that_will_be_hard_to_notice = :x + + config :a, :b, a_sad_overwrite_that_will_be_hard_to_notice + + config :z, a: :meow + """ + ) end end end diff --git a/test/support/style_case.ex b/test/support/style_case.ex index d8ce14e5..e6bbc068 100644 --- a/test/support/style_case.ex +++ b/test/support/style_case.ex @@ -133,8 +133,25 @@ defmodule Styler.StyleCase do # reaching into private ExUnit stuff, uh oh! # this gets us the nice diffing from ExUnit while allowing us to print our code blocks as strings rather than inspected strings {%{left: expected, right: styled}, _} = ExUnit.Diff.compute(expected, styled, :==) - expected = for {diff?, content} <- expected.contents, do: if(diff?, do: [:red, content, :reset], else: content) - styled = for {diff?, content} <- styled.contents, do: if(diff?, do: [:green, content, :reset], else: content) + + expected = + for {diff?, content} <- expected.contents do + cond do + diff? and String.trim_leading(Macro.unescape_string(content)) == "" -> [:red_background, content, :reset] + diff? -> [:red, content, :reset] + true -> content + end + end + + styled = + for {diff?, content} <- styled.contents do + cond do + diff? and String.trim_leading(Macro.unescape_string(content)) == "" -> [:green_background, content, :reset] + diff? -> [:green, content, :reset] + true -> content + end + end + header = IO.ANSI.format([:red, prelude, :reset]) expected =