skip_test_without_comment.ex (2314B)
1 defmodule Credo.Check.Design.SkipTestWithoutComment do 2 use Credo.Check, 3 base_priority: :normal, 4 explanations: [ 5 check: """ 6 Skipped tests should have a comment documenting why the test is skipped. 7 8 Tests are often skipped using `@tag :skip` when some issue arises that renders 9 the test temporarily broken or unable to run. This temporary skip often becomes 10 a permanent one because the reason for the test being skipped is not documented. 11 12 A comment should exist on the line prior to the skip tag describing why the test is 13 skipped. 14 15 Example: 16 17 # john: skipping this since our credentials expired, working on getting new ones 18 @tag :skip 19 test "vendor api returns data" do 20 # ... 21 end 22 23 While the pure existence of a comment does not change anything per se, a thoughtful 24 comment can improve the odds for future iteration on the issue. 25 """ 26 ], 27 param_defaults: [included: ["test/**/*_test.exs"]] 28 29 @tag_skip_regex ~r/^\s*\@tag :skip\s*$/ 30 @comment_regex ~r/^\s*\#.*$/ 31 32 @doc false 33 @impl true 34 def run(source_file, params) do 35 issue_meta = IssueMeta.for(source_file, params) 36 37 source_file 38 |> Credo.Code.clean_charlists_strings_and_sigils() 39 |> String.split("\n") 40 |> Enum.with_index(1) 41 |> Enum.map(&transform_line/1) 42 |> check_lines([], issue_meta) 43 end 44 45 defp transform_line({line, line_number}) do 46 cond do 47 line =~ @tag_skip_regex -> {:tag_skip, line_number} 48 line =~ @comment_regex -> {:comment, line_number} 49 true -> {line, line_number} 50 end 51 end 52 53 defp check_lines([{:tag_skip, line_number} | rest], issues, issue_meta) do 54 check_lines(rest, [issue_for(issue_meta, line_number) | issues], issue_meta) 55 end 56 57 defp check_lines([{:comment, _}, {:tag_skip, _} | rest], issues, issue_meta) do 58 check_lines(rest, issues, issue_meta) 59 end 60 61 defp check_lines([_hd | tl], issues, issue_meta), do: check_lines(tl, issues, issue_meta) 62 defp check_lines([], issues, _issue_meta), do: issues 63 64 defp issue_for(issue_meta, line_no) do 65 format_issue( 66 issue_meta, 67 message: "Tests tagged to be skipped should have a comment preceding the `@tag :skip`", 68 trigger: "@tag :skip", 69 line_no: line_no 70 ) 71 end 72 end