Repository: rrrene/credo (elixir)

Issue:
`mix credo` task fails with exception `protocol String.Chars not implemented for ...`
### Environment

* Credo version (`mix credo -v`): 0.8.10
* Erlang/Elixir version (`elixir -v`): 1.6.1
* Operating system: macOS 10.13.3

### What were you trying to do?

I'm trying to run style checks for source code containing macro like 

```
defmacro foo(quoted_module, ..., ...) do
  {module, []} = Code.eval_quoted(quoted_module)
  quote do
    defmodule unquote(module).Bar do
      unquote(...)
    end
  end
end
```

Compiler gives no warnings, generated module works as expected. But when I'm trying to run style checks with `mix credo` command, it fails with error

```
Error while running Elixir.Credo.Check.Readability.ModuleNames on 
** (EXIT from #PID<0.73.0>) an exception was raised:
    ** (Protocol.UndefinedError) protocol String.Chars not implemented for {:unquote, [line: 22], [{:module, [line: 22], nil}]}
        (elixir) lib/string/chars.ex:3: String.Chars.impl_for!/1
        (elixir) lib/string/chars.ex:22: String.Chars.to_string/1
        (elixir) lib/enum.ex:1899: Enum."-join/2-lists^foldl/2-0-"/3
        (elixir) lib/enum.ex:1899: Enum.join/2
        lib/credo/check/readability/module_names.ex:45: Credo.Check.Readability.ModuleNames.issues_for_def/3
        lib/credo/check/readability/module_names.ex:36: Credo.Check.Readability.ModuleNames.traverse/3
        (elixir) lib/macro.ex:277: anonymous fn/4 in Macro.do_traverse_args/4
        (elixir) lib/enum.ex:1397: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
```

Pull request:
Filter module names which can be converted to strings
Fixes #506

Patch:
diff --git a/lib/credo/check/readability/module_names.ex b/lib/credo/check/readability/module_names.ex
index eff521cc..d0615ab9 100644
--- a/lib/credo/check/readability/module_names.ex
+++ b/lib/credo/check/readability/module_names.ex
@@ -43,7 +43,10 @@ defmodule Credo.Check.Readability.ModuleNames do
   defp issues_for_def(body, issues, issue_meta) do
     case Enum.at(body, 0) do
       {:__aliases__, meta, names} ->
-        names |> Enum.join(".") |> issues_for_name(meta, issues, issue_meta)
+        names
+        |> Enum.filter(&String.Chars.impl_for/1)
+        |> Enum.join(".")
+        |> issues_for_name(meta, issues, issue_meta)
 
       _ ->
         issues


Test patch:
diff --git a/test/credo/check/readability/module_names_test.exs b/test/credo/check/readability/module_names_test.exs
index f9e21a79..4369c11e 100644
--- a/test/credo/check/readability/module_names_test.exs
+++ b/test/credo/check/readability/module_names_test.exs
@@ -16,6 +16,20 @@ defmodule Credo.Check.Readability.ModuleNamesTest do
     |> refute_issues(@described_check)
   end
 
+  test "it should NOT report if module name cannot be determinated" do
+    """
+    defmacro foo(quoted_module) do
+      {module, []} = Code.eval_quoted(quoted_module)
+      quote do
+        defmodule unquote(module).Bar do
+        end
+      end
+    end
+    """
+    |> to_source_file
+    |> refute_issues(@described_check)
+  end
+
   #
   # cases raising issues
   #