From 7850bdd7e882815eefd1ba4b16871b32521b8bf8 Mon Sep 17 00:00:00 2001 From: sabiwara Date: Wed, 10 Aug 2022 13:47:00 +0900 Subject: Evaluate formating charlists as ~c sigils (#12064) --- lib/eex/lib/eex.ex | 2 +- lib/eex/lib/eex/compiler.ex | 30 +- lib/eex/test/eex/tokenizer_test.exs | 272 +++++----- lib/eex/test/eex_test.exs | 2 +- lib/elixir/lib/application.ex | 2 +- lib/elixir/lib/base.ex | 12 +- lib/elixir/lib/calendar.ex | 6 +- lib/elixir/lib/code.ex | 15 +- lib/elixir/lib/code/formatter.ex | 41 +- lib/elixir/lib/code/fragment.ex | 72 +-- lib/elixir/lib/code/identifier.ex | 35 +- lib/elixir/lib/code/normalizer.ex | 2 +- lib/elixir/lib/dynamic_supervisor.ex | 2 +- lib/elixir/lib/float.ex | 4 +- lib/elixir/lib/gen_event.ex | 12 +- lib/elixir/lib/gen_server.ex | 2 +- lib/elixir/lib/inspect.ex | 22 +- lib/elixir/lib/integer.ex | 2 +- lib/elixir/lib/io.ex | 10 +- lib/elixir/lib/kernel.ex | 2 +- lib/elixir/lib/kernel/parallel_compiler.ex | 2 +- lib/elixir/lib/list/chars.ex | 2 +- lib/elixir/lib/macro.ex | 2 +- lib/elixir/lib/module.ex | 2 +- lib/elixir/lib/module/parallel_checker.ex | 2 +- lib/elixir/lib/path.ex | 4 +- lib/elixir/lib/protocol.ex | 8 +- lib/elixir/lib/regex.ex | 2 +- lib/elixir/lib/string.ex | 2 +- lib/elixir/lib/system.ex | 20 +- lib/elixir/lib/task/supervised.ex | 8 +- lib/elixir/lib/uri.ex | 4 +- lib/elixir/test/elixir/application_test.exs | 8 +- lib/elixir/test/elixir/atom_test.exs | 2 +- .../test/elixir/code_formatter/calls_test.exs | 12 +- .../test/elixir/code_formatter/general_test.exs | 54 +- .../elixir/code_formatter/integration_test.exs | 6 +- .../test/elixir/code_formatter/literals_test.exs | 230 ++++++-- .../test/elixir/code_formatter/operators_test.exs | 26 +- lib/elixir/test/elixir/code_fragment_test.exs | 597 +++++++++++---------- .../elixir/code_normalizer/quoted_ast_test.exs | 44 +- lib/elixir/test/elixir/config/provider_test.exs | 6 +- lib/elixir/test/elixir/exception_test.exs | 20 +- lib/elixir/test/elixir/file_test.exs | 16 +- lib/elixir/test/elixir/inspect_test.exs | 20 +- lib/elixir/test/elixir/integer_test.exs | 32 +- lib/elixir/test/elixir/io/ansi_test.exs | 4 +- lib/elixir/test/elixir/io_test.exs | 72 +-- lib/elixir/test/elixir/kernel/binary_test.exs | 6 +- lib/elixir/test/elixir/kernel/charlist_test.exs | 26 +- lib/elixir/test/elixir/kernel/cli_test.exs | 63 ++- .../test/elixir/kernel/comprehension_test.exs | 6 +- lib/elixir/test/elixir/kernel/errors_test.exs | 224 ++++---- lib/elixir/test/elixir/kernel/expansion_test.exs | 4 +- lib/elixir/test/elixir/kernel/fn_test.exs | 12 +- lib/elixir/test/elixir/kernel/parser_test.exs | 184 +++---- lib/elixir/test/elixir/kernel/quote_test.exs | 10 +- lib/elixir/test/elixir/kernel/sigils_test.exs | 28 +- lib/elixir/test/elixir/kernel_test.exs | 4 +- lib/elixir/test/elixir/list/chars_test.exs | 14 +- lib/elixir/test/elixir/list_test.exs | 22 +- lib/elixir/test/elixir/macro_test.exs | 14 +- .../test/elixir/module/types/integration_test.exs | 2 +- lib/elixir/test/elixir/module_test.exs | 2 +- lib/elixir/test/elixir/path_test.exs | 47 +- .../test/elixir/protocol/consolidation_test.exs | 8 +- lib/elixir/test/elixir/record_test.exs | 10 +- lib/elixir/test/elixir/string/chars_test.exs | 2 +- lib/elixir/test/elixir/string_io_test.exs | 8 +- lib/elixir/test/elixir/system_test.exs | 4 +- lib/elixir/test/elixir/test_helper.exs | 2 +- lib/elixir/test/elixir/uri_test.exs | 4 +- lib/elixir/unicode/tokenizer.ex | 8 +- lib/ex_unit/examples/difference.exs | 4 +- lib/ex_unit/examples/one_of_each.exs | 4 +- lib/ex_unit/lib/ex_unit/runner.ex | 2 +- lib/ex_unit/test/ex_unit/assertions_test.exs | 20 +- lib/ex_unit/test/ex_unit/capture_io_test.exs | 38 +- lib/ex_unit/test/ex_unit/diff_test.exs | 16 +- lib/iex/lib/iex/autocomplete.ex | 16 +- lib/iex/lib/iex/cli.ex | 6 +- lib/iex/lib/iex/evaluator.ex | 4 +- lib/iex/lib/iex/helpers.ex | 18 +- lib/iex/test/iex/autocomplete_test.exs | 373 +++++++------ lib/iex/test/iex/helpers_test.exs | 2 +- lib/iex/test/iex/info_test.exs | 2 +- lib/logger/lib/logger/formatter.ex | 2 +- lib/logger/lib/logger/translator.ex | 6 +- lib/logger/lib/logger/utils.ex | 6 +- lib/logger/test/logger/formatter_test.exs | 2 +- lib/logger/test/logger/handler_test.exs | 48 +- lib/logger/test/logger/translator_test.exs | 2 +- lib/logger/test/logger/utils_test.exs | 60 ++- lib/logger/test/logger_test.exs | 2 +- lib/mix/lib/mix/dep/elixir_scm.ex | 2 +- lib/mix/lib/mix/release.ex | 8 +- lib/mix/lib/mix/task.ex | 2 +- lib/mix/lib/mix/tasks/compile.all.ex | 2 +- lib/mix/lib/mix/tasks/compile.ex | 2 +- lib/mix/lib/mix/tasks/escript.build.ex | 12 +- lib/mix/lib/mix/tasks/help.ex | 2 +- lib/mix/lib/mix/tasks/local.ex | 2 +- lib/mix/lib/mix/tasks/test.coverage.ex | 4 +- lib/mix/lib/mix/utils.ex | 2 +- .../test/fixtures/release_test/config/config.exs | 2 +- lib/mix/test/mix/project_test.exs | 12 +- lib/mix/test/mix/rebar_test.exs | 44 +- lib/mix/test/mix/release_test.exs | 53 +- lib/mix/test/mix/tasks/app.config_test.exs | 2 +- lib/mix/test/mix/tasks/app.tree_test.exs | 8 +- lib/mix/test/mix/tasks/archive_test.exs | 20 +- lib/mix/test/mix/tasks/compile.app_test.exs | 8 +- lib/mix/test/mix/tasks/compile.erlang_test.exs | 2 +- lib/mix/test/mix/tasks/compile.protocols_test.exs | 6 +- lib/mix/test/mix/tasks/format_test.exs | 4 +- lib/mix/test/mix/tasks/loadconfig_test.exs | 2 +- lib/mix/test/mix/tasks/release_test.exs | 33 +- lib/mix/test/mix/utils_test.exs | 8 +- 118 files changed, 1792 insertions(+), 1551 deletions(-) (limited to 'lib') diff --git a/lib/eex/lib/eex.ex b/lib/eex/lib/eex.ex index 4c53460c6..92cfba16f 100644 --- a/lib/eex/lib/eex.ex +++ b/lib/eex/lib/eex.ex @@ -103,7 +103,7 @@ defmodule EEx do @type line :: non_neg_integer @type column :: non_neg_integer - @type marker :: '=' | '/' | '|' | '' + @type marker :: [?=] | [?/] | [?|] | [] @type metadata :: %{column: column, line: line} @type token :: {:comment, charlist, metadata} diff --git a/lib/eex/lib/eex/compiler.ex b/lib/eex/lib/eex/compiler.ex index cd95fbe3e..c141798d7 100644 --- a/lib/eex/lib/eex/compiler.ex +++ b/lib/eex/lib/eex/compiler.ex @@ -28,11 +28,11 @@ defmodule EEx.Compiler do tokenize(contents, line, column, state, [{line, column}], []) end - defp tokenize('<%%' ++ t, line, column, state, buffer, acc) do + defp tokenize(~c"<%%" ++ t, line, column, state, buffer, acc) do tokenize(t, line, column + 3, state, [?%, ?< | buffer], acc) end - defp tokenize('<%!--' ++ t, line, column, state, buffer, acc) do + defp tokenize(~c"<%!--" ++ t, line, column, state, buffer, acc) do case comment(t, line, column + 5, state, []) do {:error, line, column, message} -> {:error, message, %{line: line, column: column}} @@ -44,7 +44,7 @@ defmodule EEx.Compiler do end # TODO: Deprecate this on Elixir v1.18 - defp tokenize('<%#' ++ t, line, column, state, buffer, acc) do + defp tokenize(~c"<%#" ++ t, line, column, state, buffer, acc) do case expr(t, line, column + 3, state, []) do {:error, line, column, message} -> {:error, message, %{line: line, column: column}} @@ -54,7 +54,7 @@ defmodule EEx.Compiler do end end - defp tokenize('<%' ++ t, line, column, state, buffer, acc) do + defp tokenize(~c"<%" ++ t, line, column, state, buffer, acc) do {marker, t} = retrieve_marker(t) case expr(t, line, column + 2 + length(marker), state, []) do @@ -76,13 +76,13 @@ defmodule EEx.Compiler do end marker = - if key in [:middle_expr, :end_expr] and marker != '' do + if key in [:middle_expr, :end_expr] and marker != ~c"" do message = "unexpected beginning of EEx tag \"<%#{marker}\" on \"<%#{marker}#{expr}%>\", " <> "please remove \"#{marker}\"" :elixir_errors.erl_warn({line, column}, state.file, message) - '' + ~c"" else marker end @@ -92,7 +92,7 @@ defmodule EEx.Compiler do end end - defp tokenize('\n' ++ t, line, _column, state, buffer, acc) do + defp tokenize(~c"\n" ++ t, line, _column, state, buffer, acc) do tokenize(t, line + 1, state.indentation + 1, state, [?\n | buffer], acc) end @@ -119,7 +119,7 @@ defmodule EEx.Compiler do end defp retrieve_marker(t) do - {'', t} + {~c"", t} end # Tokenize a multi-line comment until we find --%> @@ -128,8 +128,8 @@ defmodule EEx.Compiler do {:ok, line, column + 4, t, buffer} end - defp comment('\n' ++ t, line, _column, state, buffer) do - comment(t, line + 1, state.indentation + 1, state, '\n' ++ buffer) + defp comment(~c"\n" ++ t, line, _column, state, buffer) do + comment(t, line + 1, state.indentation + 1, state, ~c"\n" ++ buffer) end defp comment([head | t], line, column, state, buffer) do @@ -146,7 +146,7 @@ defmodule EEx.Compiler do {:ok, Enum.reverse(buffer), line, column + 2, t} end - defp expr('\n' ++ t, line, _column, state, buffer) do + defp expr(~c"\n" ++ t, line, _column, state, buffer) do expr(t, line + 1, state.indentation + 1, state, [?\n | buffer]) end @@ -334,7 +334,7 @@ defmodule EEx.Compiler do scope, state ) do - if mark == '' do + if mark == ~c"" do message = "the contents of this expression won't be output unless the EEx block starts with \"<%=\"" @@ -362,7 +362,7 @@ defmodule EEx.Compiler do end defp generate_buffer( - [{:middle_expr, '', chars, meta} | rest], + [{:middle_expr, ~c"", chars, meta} | rest], buffer, [current | scope], state @@ -381,7 +381,7 @@ defmodule EEx.Compiler do end defp generate_buffer( - [{:end_expr, '', chars, meta} | rest], + [{:end_expr, ~c"", chars, meta} | rest], buffer, [current | _], state @@ -419,7 +419,7 @@ defmodule EEx.Compiler do defp wrap_expr(current, line, buffer, chars, state) do new_lines = List.duplicate(?\n, line - state.line) key = length(state.quoted) - placeholder = '__EEX__(' ++ Integer.to_charlist(key) ++ ');' + placeholder = ~c"__EEX__(" ++ Integer.to_charlist(key) ++ ~c");" count = current ++ placeholder ++ new_lines ++ chars new_state = %{state | quoted: [{key, state.engine.handle_end(buffer)} | state.quoted]} diff --git a/lib/eex/test/eex/tokenizer_test.exs b/lib/eex/test/eex/tokenizer_test.exs index 6b0e97e61..143a465bf 100644 --- a/lib/eex/test/eex/tokenizer_test.exs +++ b/lib/eex/test/eex/tokenizer_test.exs @@ -6,79 +6,79 @@ defmodule EEx.TokenizerTest do @opts [indentation: 0, trim: false] test "simple chars lists" do - assert EEx.tokenize('foo', @opts) == - {:ok, [{:text, 'foo', %{column: 1, line: 1}}, {:eof, %{column: 4, line: 1}}]} + assert EEx.tokenize(~c"foo", @opts) == + {:ok, [{:text, ~c"foo", %{column: 1, line: 1}}, {:eof, %{column: 4, line: 1}}]} end test "simple strings" do assert EEx.tokenize("foo", @opts) == - {:ok, [{:text, 'foo', %{column: 1, line: 1}}, {:eof, %{column: 4, line: 1}}]} + {:ok, [{:text, ~c"foo", %{column: 1, line: 1}}, {:eof, %{column: 4, line: 1}}]} end test "strings with embedded code" do - assert EEx.tokenize('foo <% bar %>', @opts) == + assert EEx.tokenize(~c"foo <% bar %>", @opts) == {:ok, [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, '', ' bar ', %{column: 5, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, ~c"", ~c" bar ", %{column: 5, line: 1}}, {:eof, %{column: 14, line: 1}} ]} end test "strings with embedded equals code" do - assert EEx.tokenize('foo <%= bar %>', @opts) == + assert EEx.tokenize(~c"foo <%= bar %>", @opts) == {:ok, [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, '=', ' bar ', %{column: 5, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" bar ", %{column: 5, line: 1}}, {:eof, %{column: 15, line: 1}} ]} end test "strings with embedded slash code" do - assert EEx.tokenize('foo <%/ bar %>', @opts) == + assert EEx.tokenize(~c"foo <%/ bar %>", @opts) == {:ok, [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, '/', ' bar ', %{column: 5, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, ~c"/", ~c" bar ", %{column: 5, line: 1}}, {:eof, %{column: 15, line: 1}} ]} end test "strings with embedded pipe code" do - assert EEx.tokenize('foo <%| bar %>', @opts) == + assert EEx.tokenize(~c"foo <%| bar %>", @opts) == {:ok, [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, '|', ' bar ', %{column: 5, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, ~c"|", ~c" bar ", %{column: 5, line: 1}}, {:eof, %{column: 15, line: 1}} ]} end test "strings with more than one line" do - assert EEx.tokenize('foo\n<%= bar %>', @opts) == + assert EEx.tokenize(~c"foo\n<%= bar %>", @opts) == {:ok, [ - {:text, 'foo\n', %{column: 1, line: 1}}, - {:expr, '=', ' bar ', %{column: 1, line: 2}}, + {:text, ~c"foo\n", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" bar ", %{column: 1, line: 2}}, {:eof, %{column: 11, line: 2}} ]} end test "strings with more than one line and expression with more than one line" do - string = ''' + string = ~c""" foo <%= bar baz %> <% foo %> - ''' + """ exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, '=', ' bar\n\nbaz ', %{column: 5, line: 1}}, - {:text, '\n', %{column: 7, line: 3}}, - {:expr, '', ' foo ', %{column: 1, line: 4}}, - {:text, '\n', %{column: 10, line: 4}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" bar\n\nbaz ", %{column: 5, line: 1}}, + {:text, ~c"\n", %{column: 7, line: 3}}, + {:expr, ~c"", ~c" foo ", %{column: 1, line: 4}}, + {:text, ~c"\n", %{column: 10, line: 4}}, {:eof, %{column: 1, line: 5}} ] @@ -86,235 +86,235 @@ defmodule EEx.TokenizerTest do end test "quotation" do - assert EEx.tokenize('foo <%% true %>', @opts) == + assert EEx.tokenize(~c"foo <%% true %>", @opts) == {:ok, [ - {:text, 'foo <% true %>', %{column: 1, line: 1}}, + {:text, ~c"foo <% true %>", %{column: 1, line: 1}}, {:eof, %{column: 16, line: 1}} ]} end test "quotation with do-end" do - assert EEx.tokenize('foo <%% true do %>bar<%% end %>', @opts) == + assert EEx.tokenize(~c"foo <%% true do %>bar<%% end %>", @opts) == {:ok, [ - {:text, 'foo <% true do %>bar<% end %>', %{column: 1, line: 1}}, + {:text, ~c"foo <% true do %>bar<% end %>", %{column: 1, line: 1}}, {:eof, %{column: 32, line: 1}} ]} end test "quotation with interpolation" do exprs = [ - {:text, 'a <% b ', %{column: 1, line: 1}}, - {:expr, '=', ' c ', %{column: 9, line: 1}}, - {:text, ' ', %{column: 17, line: 1}}, - {:expr, '=', ' d ', %{column: 18, line: 1}}, - {:text, ' e %> f', %{column: 26, line: 1}}, + {:text, ~c"a <% b ", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" c ", %{column: 9, line: 1}}, + {:text, ~c" ", %{column: 17, line: 1}}, + {:expr, ~c"=", ~c" d ", %{column: 18, line: 1}}, + {:text, ~c" e %> f", %{column: 26, line: 1}}, {:eof, %{column: 33, line: 1}} ] - assert EEx.tokenize('a <%% b <%= c %> <%= d %> e %> f', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"a <%% b <%= c %> <%= d %> e %> f", @opts) == {:ok, exprs} end test "improperly formatted quotation with interpolation" do exprs = [ - {:text, '<%% a <%= b %> c %>', %{column: 1, line: 1}}, + {:text, ~c"<%% a <%= b %> c %>", %{column: 1, line: 1}}, {:eof, %{column: 22, line: 1}} ] - assert EEx.tokenize('<%%% a <%%= b %> c %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"<%%% a <%%= b %> c %>", @opts) == {:ok, exprs} end test "EEx comments" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, {:eof, %{column: 16, line: 1}} ] - assert EEx.tokenize('foo <%# true %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%# true %>", @opts) == {:ok, exprs} exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, {:eof, %{column: 8, line: 2}} ] - assert EEx.tokenize('foo <%#\ntrue %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%#\ntrue %>", @opts) == {:ok, exprs} end test "EEx comments with do-end" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:text, 'bar', %{column: 19, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:text, ~c"bar", %{column: 19, line: 1}}, {:eof, %{column: 32, line: 1}} ] - assert EEx.tokenize('foo <%# true do %>bar<%# end %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%# true do %>bar<%# end %>", @opts) == {:ok, exprs} end test "EEx comments inside do-end" do exprs = [ - {:start_expr, '', ' if true do ', %{column: 1, line: 1}}, - {:text, 'bar', %{column: 31, line: 1}}, - {:end_expr, [], ' end ', %{column: 34, line: 1}}, + {:start_expr, ~c"", ~c" if true do ", %{column: 1, line: 1}}, + {:text, ~c"bar", %{column: 31, line: 1}}, + {:end_expr, [], ~c" end ", %{column: 34, line: 1}}, {:eof, %{column: 43, line: 1}} ] - assert EEx.tokenize('<% if true do %><%# comment %>bar<% end %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"<% if true do %><%# comment %>bar<% end %>", @opts) == {:ok, exprs} exprs = [ - {:start_expr, [], ' case true do ', %{column: 1, line: 1}}, - {:middle_expr, '', ' true -> ', %{column: 33, line: 1}}, - {:text, 'bar', %{column: 46, line: 1}}, - {:end_expr, [], ' end ', %{column: 49, line: 1}}, + {:start_expr, [], ~c" case true do ", %{column: 1, line: 1}}, + {:middle_expr, ~c"", ~c" true -> ", %{column: 33, line: 1}}, + {:text, ~c"bar", %{column: 46, line: 1}}, + {:end_expr, [], ~c" end ", %{column: 49, line: 1}}, {:eof, %{column: 58, line: 1}} ] - assert EEx.tokenize('<% case true do %><%# comment %><% true -> %>bar<% end %>', @opts) == + assert EEx.tokenize(~c"<% case true do %><%# comment %><% true -> %>bar<% end %>", @opts) == {:ok, exprs} end test "EEx multi-line comments" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:comment, ' true ', %{column: 5, line: 1}}, - {:text, ' bar', %{column: 20, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:comment, ~c" true ", %{column: 5, line: 1}}, + {:text, ~c" bar", %{column: 20, line: 1}}, {:eof, %{column: 24, line: 1}} ] - assert EEx.tokenize('foo <%!-- true --%> bar', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%!-- true --%> bar", @opts) == {:ok, exprs} exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:comment, ' \ntrue\n ', %{column: 5, line: 1}}, - {:text, ' bar', %{column: 6, line: 3}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:comment, ~c" \ntrue\n ", %{column: 5, line: 1}}, + {:text, ~c" bar", %{column: 6, line: 3}}, {:eof, %{column: 10, line: 3}} ] - assert EEx.tokenize('foo <%!-- \ntrue\n --%> bar', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%!-- \ntrue\n --%> bar", @opts) == {:ok, exprs} exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:comment, ' <%= true %> ', %{column: 5, line: 1}}, - {:text, ' bar', %{column: 27, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:comment, ~c" <%= true %> ", %{column: 5, line: 1}}, + {:text, ~c" bar", %{column: 27, line: 1}}, {:eof, %{column: 31, line: 1}} ] - assert EEx.tokenize('foo <%!-- <%= true %> --%> bar', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <%!-- <%= true %> --%> bar", @opts) == {:ok, exprs} end test "Elixir comments" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:expr, [], ' true # this is a boolean ', %{column: 5, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:expr, [], ~c" true # this is a boolean ", %{column: 5, line: 1}}, {:eof, %{column: 35, line: 1}} ] - assert EEx.tokenize('foo <% true # this is a boolean %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <% true # this is a boolean %>", @opts) == {:ok, exprs} end test "Elixir comments with do-end" do exprs = [ - {:start_expr, [], ' if true do # startif ', %{column: 1, line: 1}}, - {:text, 'text', %{column: 27, line: 1}}, - {:end_expr, [], ' end # closeif ', %{column: 31, line: 1}}, + {:start_expr, [], ~c" if true do # startif ", %{column: 1, line: 1}}, + {:text, ~c"text", %{column: 27, line: 1}}, + {:end_expr, [], ~c" end # closeif ", %{column: 31, line: 1}}, {:eof, %{column: 50, line: 1}} ] - assert EEx.tokenize('<% if true do # startif %>text<% end # closeif %>', @opts) == + assert EEx.tokenize(~c"<% if true do # startif %>text<% end # closeif %>", @opts) == {:ok, exprs} end test "strings with embedded do end" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:start_expr, '', ' if true do ', %{column: 5, line: 1}}, - {:text, 'bar', %{column: 21, line: 1}}, - {:end_expr, '', ' end ', %{column: 24, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:start_expr, ~c"", ~c" if true do ", %{column: 5, line: 1}}, + {:text, ~c"bar", %{column: 21, line: 1}}, + {:end_expr, ~c"", ~c" end ", %{column: 24, line: 1}}, {:eof, %{column: 33, line: 1}} ] - assert EEx.tokenize('foo <% if true do %>bar<% end %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"foo <% if true do %>bar<% end %>", @opts) == {:ok, exprs} end test "strings with embedded -> end" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:start_expr, '', ' cond do ', %{column: 5, line: 1}}, - {:middle_expr, '', ' false -> ', %{column: 18, line: 1}}, - {:text, 'bar', %{column: 32, line: 1}}, - {:middle_expr, '', ' true -> ', %{column: 35, line: 1}}, - {:text, 'baz', %{column: 48, line: 1}}, - {:end_expr, '', ' end ', %{column: 51, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:start_expr, ~c"", ~c" cond do ", %{column: 5, line: 1}}, + {:middle_expr, ~c"", ~c" false -> ", %{column: 18, line: 1}}, + {:text, ~c"bar", %{column: 32, line: 1}}, + {:middle_expr, ~c"", ~c" true -> ", %{column: 35, line: 1}}, + {:text, ~c"baz", %{column: 48, line: 1}}, + {:end_expr, ~c"", ~c" end ", %{column: 51, line: 1}}, {:eof, %{column: 60, line: 1}} ] - assert EEx.tokenize('foo <% cond do %><% false -> %>bar<% true -> %>baz<% end %>', @opts) == + assert EEx.tokenize(~c"foo <% cond do %><% false -> %>bar<% true -> %>baz<% end %>", @opts) == {:ok, exprs} end test "strings with fn-end with newline" do exprs = [ - {:start_expr, '=', ' a fn ->\n', %{column: 1, line: 1}}, - {:text, 'foo', %{column: 3, line: 2}}, - {:end_expr, [], ' end ', %{column: 6, line: 2}}, + {:start_expr, ~c"=", ~c" a fn ->\n", %{column: 1, line: 1}}, + {:text, ~c"foo", %{column: 3, line: 2}}, + {:end_expr, [], ~c" end ", %{column: 6, line: 2}}, {:eof, %{column: 15, line: 2}} ] - assert EEx.tokenize('<%= a fn ->\n%>foo<% end %>', @opts) == + assert EEx.tokenize(~c"<%= a fn ->\n%>foo<% end %>", @opts) == {:ok, exprs} end test "strings with multiple fn-end" do exprs = [ - {:start_expr, '=', ' a fn -> ', %{column: 1, line: 1}}, - {:text, 'foo', %{column: 15, line: 1}}, - {:middle_expr, '', ' end, fn -> ', %{column: 18, line: 1}}, - {:text, 'bar', %{column: 34, line: 1}}, - {:end_expr, '', ' end ', %{column: 37, line: 1}}, + {:start_expr, ~c"=", ~c" a fn -> ", %{column: 1, line: 1}}, + {:text, ~c"foo", %{column: 15, line: 1}}, + {:middle_expr, ~c"", ~c" end, fn -> ", %{column: 18, line: 1}}, + {:text, ~c"bar", %{column: 34, line: 1}}, + {:end_expr, ~c"", ~c" end ", %{column: 37, line: 1}}, {:eof, %{column: 46, line: 1}} ] - assert EEx.tokenize('<%= a fn -> %>foo<% end, fn -> %>bar<% end %>', @opts) == + assert EEx.tokenize(~c"<%= a fn -> %>foo<% end, fn -> %>bar<% end %>", @opts) == {:ok, exprs} end test "strings with fn-end followed by do block" do exprs = [ - {:start_expr, '=', ' a fn -> ', %{column: 1, line: 1}}, - {:text, 'foo', %{column: 15, line: 1}}, - {:middle_expr, '', ' end do ', %{column: 18, line: 1}}, - {:text, 'bar', %{column: 30, line: 1}}, - {:end_expr, '', ' end ', %{column: 33, line: 1}}, + {:start_expr, ~c"=", ~c" a fn -> ", %{column: 1, line: 1}}, + {:text, ~c"foo", %{column: 15, line: 1}}, + {:middle_expr, ~c"", ~c" end do ", %{column: 18, line: 1}}, + {:text, ~c"bar", %{column: 30, line: 1}}, + {:end_expr, ~c"", ~c" end ", %{column: 33, line: 1}}, {:eof, %{column: 42, line: 1}} ] - assert EEx.tokenize('<%= a fn -> %>foo<% end do %>bar<% end %>', @opts) == {:ok, exprs} + assert EEx.tokenize(~c"<%= a fn -> %>foo<% end do %>bar<% end %>", @opts) == {:ok, exprs} end test "strings with embedded keywords blocks" do exprs = [ - {:text, 'foo ', %{column: 1, line: 1}}, - {:start_expr, '', ' if true do ', %{column: 5, line: 1}}, - {:text, 'bar', %{column: 21, line: 1}}, - {:middle_expr, '', ' else ', %{column: 24, line: 1}}, - {:text, 'baz', %{column: 34, line: 1}}, - {:end_expr, '', ' end ', %{column: 37, line: 1}}, + {:text, ~c"foo ", %{column: 1, line: 1}}, + {:start_expr, ~c"", ~c" if true do ", %{column: 5, line: 1}}, + {:text, ~c"bar", %{column: 21, line: 1}}, + {:middle_expr, ~c"", ~c" else ", %{column: 24, line: 1}}, + {:text, ~c"baz", %{column: 34, line: 1}}, + {:end_expr, ~c"", ~c" end ", %{column: 37, line: 1}}, {:eof, %{column: 46, line: 1}} ] - assert EEx.tokenize('foo <% if true do %>bar<% else %>baz<% end %>', @opts) == + assert EEx.tokenize(~c"foo <% if true do %>bar<% else %>baz<% end %>", @opts) == {:ok, exprs} end test "trim mode" do - template = '\t<%= if true do %> \n TRUE \n <% else %>\n FALSE \n <% end %> \n\n ' + template = ~c"\t<%= if true do %> \n TRUE \n <% else %>\n FALSE \n <% end %> \n\n " exprs = [ - {:start_expr, '=', ' if true do ', %{column: 2, line: 1}}, - {:text, '\n TRUE \n', %{column: 20, line: 1}}, - {:middle_expr, '', ' else ', %{column: 3, line: 3}}, - {:text, '\n FALSE \n', %{column: 13, line: 3}}, - {:end_expr, '', ' end ', %{column: 3, line: 5}}, + {:start_expr, ~c"=", ~c" if true do ", %{column: 2, line: 1}}, + {:text, ~c"\n TRUE \n", %{column: 20, line: 1}}, + {:middle_expr, ~c"", ~c" else ", %{column: 3, line: 3}}, + {:text, ~c"\n FALSE \n", %{column: 13, line: 3}}, + {:end_expr, ~c"", ~c" end ", %{column: 3, line: 5}}, {:eof, %{column: 3, line: 7}} ] @@ -323,43 +323,43 @@ defmodule EEx.TokenizerTest do test "trim mode with comment" do exprs = [ - {:text, '\n123', %{column: 19, line: 1}}, + {:text, ~c"\n123", %{column: 19, line: 1}}, {:eof, %{column: 4, line: 2}} ] - assert EEx.tokenize(' <%# comment %> \n123', [trim: true] ++ @opts) == {:ok, exprs} + assert EEx.tokenize(~c" <%# comment %> \n123", [trim: true] ++ @opts) == {:ok, exprs} end test "trim mode with multi-line comment" do exprs = [ - {:comment, ' comment ', %{column: 3, line: 1}}, - {:text, '\n123', %{column: 23, line: 1}}, + {:comment, ~c" comment ", %{column: 3, line: 1}}, + {:text, ~c"\n123", %{column: 23, line: 1}}, {:eof, %{column: 4, line: 2}} ] - assert EEx.tokenize(' <%!-- comment --%> \n123', [trim: true] ++ @opts) == {:ok, exprs} + assert EEx.tokenize(~c" <%!-- comment --%> \n123", [trim: true] ++ @opts) == {:ok, exprs} end test "trim mode with CRLF" do exprs = [ - {:text, '0\n', %{column: 1, line: 1}}, - {:expr, '=', ' 12 ', %{column: 3, line: 2}}, - {:text, '\n34', %{column: 15, line: 2}}, + {:text, ~c"0\n", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" 12 ", %{column: 3, line: 2}}, + {:text, ~c"\n34", %{column: 15, line: 2}}, {:eof, %{column: 3, line: 3}} ] - assert EEx.tokenize('0\r\n <%= 12 %> \r\n34', [trim: true] ++ @opts) == {:ok, exprs} + assert EEx.tokenize(~c"0\r\n <%= 12 %> \r\n34", [trim: true] ++ @opts) == {:ok, exprs} end test "trim mode set to false" do exprs = [ - {:text, ' ', %{column: 1, line: 1}}, - {:expr, '=', ' 12 ', %{column: 2, line: 1}}, - {:text, ' \n', %{column: 11, line: 1}}, + {:text, ~c" ", %{column: 1, line: 1}}, + {:expr, ~c"=", ~c" 12 ", %{column: 2, line: 1}}, + {:text, ~c" \n", %{column: 11, line: 1}}, {:eof, %{column: 1, line: 2}} ] - assert EEx.tokenize(' <%= 12 %> \n', [trim: false] ++ @opts) == {:ok, exprs} + assert EEx.tokenize(~c" <%= 12 %> \n", [trim: false] ++ @opts) == {:ok, exprs} end test "trim mode no false positives" do @@ -367,28 +367,28 @@ defmodule EEx.TokenizerTest do assert EEx.tokenize(x, [trim: false] ++ @opts) == EEx.tokenize(x, @opts) end - assert_not_trimmed.('foo <%= "bar" %> ') - assert_not_trimmed.('\n <%= "foo" %>bar') - assert_not_trimmed.(' <%% hello %> ') - assert_not_trimmed.(' <%= 01 %><%= 23 %>\n') + assert_not_trimmed.(~c"foo <%= \"bar\" %> ") + assert_not_trimmed.(~c"\n <%= \"foo\" %>bar") + assert_not_trimmed.(~c" <%% hello %> ") + assert_not_trimmed.(~c" <%= 01 %><%= 23 %>\n") end test "returns error when there is start mark and no end mark" do - assert EEx.tokenize('foo <% :bar', @opts) == + assert EEx.tokenize(~c"foo <% :bar", @opts) == {:error, "missing token '%>'", %{column: 12, line: 1}} - assert EEx.tokenize('<%# true ', @opts) == + assert EEx.tokenize(~c"<%# true ", @opts) == {:error, "missing token '%>'", %{column: 10, line: 1}} - assert EEx.tokenize('<%!-- foo ', @opts) == + assert EEx.tokenize(~c"<%!-- foo ", @opts) == {:error, "missing token '--%>'", %{column: 11, line: 1}} end test "marks invalid expressions as regular expressions" do - assert EEx.tokenize('<% 1 $ 2 %>', @opts) == + assert EEx.tokenize(~c"<% 1 $ 2 %>", @opts) == {:ok, [ - {:expr, [], ' 1 $ 2 ', %{column: 1, line: 1}}, + {:expr, [], ~c" 1 $ 2 ", %{column: 1, line: 1}}, {:eof, %{column: 12, line: 1}} ]} end diff --git a/lib/eex/test/eex_test.exs b/lib/eex/test/eex_test.exs index dea891e48..a446b3282 100644 --- a/lib/eex/test/eex_test.exs +++ b/lib/eex/test/eex_test.exs @@ -673,7 +673,7 @@ defmodule EExTest do {21, {EExTest.Compiled, :after_compile, 0, [file: file, line: 21]}} assert EExTest.Compiled.unknown() == - {26, {EExTest.Compiled, :unknown, 0, [file: 'unknown', line: 26]}} + {26, {EExTest.Compiled, :unknown, 0, [file: ~c"unknown", line: 26]}} end end diff --git a/lib/elixir/lib/application.ex b/lib/elixir/lib/application.ex index 1ebe51816..1e17ec808 100644 --- a/lib/elixir/lib/application.ex +++ b/lib/elixir/lib/application.ex @@ -1075,7 +1075,7 @@ defmodule Application do "bad application start specs: #{inspect(spec)}" end - defp do_format_error({'no such file or directory', file}) do + defp do_format_error({~c"no such file or directory", file}) do "could not find application file: #{file}" end diff --git a/lib/elixir/lib/base.ex b/lib/elixir/lib/base.ex index be8cad751..b20cd02f4 100644 --- a/lib/elixir/lib/base.ex +++ b/lib/elixir/lib/base.ex @@ -95,11 +95,11 @@ defmodule Base do @type encode_case :: :upper | :lower @type decode_case :: :upper | :lower | :mixed - b16_alphabet = '0123456789ABCDEF' - b64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - b64url_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' - b32_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' - b32hex_alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUV' + b16_alphabet = ~c"0123456789ABCDEF" + b64_alphabet = ~c"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + b64url_alphabet = ~c"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" + b32_alphabet = ~c"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" + b32hex_alphabet = ~c"0123456789ABCDEFGHIJKLMNOPQRSTUV" to_lower_enc = &Enum.map(&1, fn c -> if c in ?A..?Z, do: c - ?A + ?a, else: c end) @@ -148,7 +148,7 @@ defmodule Base do defp remove_ignored(string, nil), do: string defp remove_ignored(string, :whitespace) do - for <>, char not in '\s\t\r\n', into: <<>>, do: <> + for <>, char not in ~c"\s\t\r\n", into: <<>>, do: <> end @doc """ diff --git a/lib/elixir/lib/calendar.ex b/lib/elixir/lib/calendar.ex index 05283ea3f..e613d15cf 100644 --- a/lib/elixir/lib/calendar.ex +++ b/lib/elixir/lib/calendar.ex @@ -582,12 +582,12 @@ defmodule Calendar do format_options.am_pm_names.(:am) end - defp default_pad(format) when format in 'aAbBpPZ', do: ?\s + defp default_pad(format) when format in ~c"aAbBpPZ", do: ?\s defp default_pad(_format), do: ?0 - defp default_width(format) when format in 'dHImMSy', do: 2 + defp default_width(format) when format in ~c"dHImMSy", do: 2 defp default_width(?j), do: 3 - defp default_width(format) when format in 'Yz', do: 4 + defp default_width(format) when format in ~c"Yz", do: 4 defp default_width(_format), do: 0 # Literally just % diff --git a/lib/elixir/lib/code.ex b/lib/elixir/lib/code.ex index bc422dcfd..938b321ff 100644 --- a/lib/elixir/lib/code.ex +++ b/lib/elixir/lib/code.ex @@ -468,6 +468,11 @@ defmodule Code do modifiers, where `<>` becomes `<>`. Defaults to `true`. This option changes the AST. + * `:charlists_as_sigils` (since v1.15.0) - when `true`, + formats charlists as [`~c`](`Kernel.sigil_c/2`) sigils, for example + `'foo'` becomes `~c"foo"`. + Defaults to `true`. This option changes the AST. + ## Design principles The formatter was designed under three principles. @@ -1095,10 +1100,10 @@ defmodule Code do Process.put(:code_formatter_comments, [comment | comments]) end - defp next_eol_count('\s' ++ rest, count), do: next_eol_count(rest, count) - defp next_eol_count('\t' ++ rest, count), do: next_eol_count(rest, count) - defp next_eol_count('\n' ++ rest, count), do: next_eol_count(rest, count + 1) - defp next_eol_count('\r\n' ++ rest, count), do: next_eol_count(rest, count + 1) + defp next_eol_count([?\s | rest], count), do: next_eol_count(rest, count) + defp next_eol_count([?\t | rest], count), do: next_eol_count(rest, count) + defp next_eol_count([?\n | rest], count), do: next_eol_count(rest, count + 1) + defp next_eol_count([?\r, ?\n | rest], count), do: next_eol_count(rest, count + 1) defp next_eol_count(_, count), do: count defp previous_eol_count([{token, {_, _, count}} | _]) @@ -1751,7 +1756,7 @@ defmodule Code do end end - @docs_chunk 'Docs' + @docs_chunk [?D, ?o, ?c, ?s] defp fetch_docs_from_beam(bin_or_path) do case :beam_lib.chunks(bin_or_path, [@docs_chunk]) do diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index e1bcdf1f4..3a2c5891c 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -6,6 +6,8 @@ defmodule Code.Formatter do @double_heredoc "\"\"\"" @single_quote "'" @single_heredoc "'''" + @sigil_c "~c\"" + @sigil_c_heredoc "~c\"\"\"" @newlines 2 @min_line 0 @max_line 9_999_999 @@ -198,6 +200,7 @@ defmodule Code.Formatter do file = Keyword.get(opts, :file, nil) sigils = Keyword.get(opts, :sigils, []) normalize_bitstring_modifiers = Keyword.get(opts, :normalize_bitstring_modifiers, true) + charlists_as_sigils = Keyword.get(opts, :charlists_as_sigils, true) sigils = Map.new(sigils, fn {key, value} -> @@ -221,7 +224,8 @@ defmodule Code.Formatter do comments: comments, sigils: sigils, file: file, - normalize_bitstring_modifiers: normalize_bitstring_modifiers + normalize_bitstring_modifiers: normalize_bitstring_modifiers, + charlists_as_sigils: charlists_as_sigils } end @@ -311,15 +315,18 @@ defmodule Code.Formatter do remote_to_algebra(quoted, context, state) meta[:delimiter] == ~s['''] -> + {opener, quotes} = get_charlist_quotes(true, state) + {doc, state} = entries |> prepend_heredoc_line() - |> list_interpolation_to_algebra(~s['''], state, @single_heredoc, @single_heredoc) + |> list_interpolation_to_algebra(quotes, state, opener, quotes) {force_unfit(doc), state} true -> - list_interpolation_to_algebra(entries, @single_quote, state, @single_quote, @single_quote) + {opener, quotes} = get_charlist_quotes(false, state) + list_interpolation_to_algebra(entries, quotes, state, opener, quotes) end end @@ -377,12 +384,14 @@ defmodule Code.Formatter do defp quoted_to_algebra({:__block__, meta, [list]}, _context, state) when is_list(list) do case meta[:delimiter] do ~s['''] -> - string = list |> List.to_string() |> escape_heredoc(~s[''']) - {@single_heredoc |> concat(string) |> concat(@single_heredoc) |> force_unfit(), state} + {opener, quotes} = get_charlist_quotes(true, state) + string = list |> List.to_string() |> escape_heredoc(quotes) + {opener |> concat(string) |> concat(quotes) |> force_unfit(), state} ~s['] -> - string = list |> List.to_string() |> escape_string(@single_quote) - {@single_quote |> concat(string) |> concat(@single_quote), state} + {opener, quotes} = get_charlist_quotes(false, state) + string = list |> List.to_string() |> escape_string(quotes) + {opener |> concat(string) |> concat(quotes), state} _other -> list_to_algebra(meta, list, state) @@ -1590,7 +1599,7 @@ defmodule Code.Formatter do |> String.to_charlist() |> Enum.reverse() |> Enum.chunk_every(3) - |> Enum.intersperse('_') + |> Enum.intersperse(~c"_") |> List.flatten() |> Enum.reverse() |> List.to_string() @@ -2346,4 +2355,20 @@ defmodule Code.Formatter do {left, [right]} = Enum.split(list, -1) {left, right} end + + defp get_charlist_quotes(_heredoc = false, state) do + if state.charlists_as_sigils do + {@sigil_c, @double_quote} + else + {@single_quote, @single_quote} + end + end + + defp get_charlist_quotes(_heredoc = true, state) do + if state.charlists_as_sigils do + {@sigil_c_heredoc, @double_heredoc} + else + {@single_heredoc, @single_heredoc} + end + end end diff --git a/lib/elixir/lib/code/fragment.ex b/lib/elixir/lib/code/fragment.ex index 67b88660b..e0d6e3af7 100644 --- a/lib/elixir/lib/code/fragment.ex +++ b/lib/elixir/lib/code/fragment.ex @@ -166,12 +166,12 @@ defmodule Code.Fragment do cursor_context(to_charlist(other), opts) end - @operators '\\<>+-*/:=|&~^%!' - @starter_punctuation ',([{;' - @non_starter_punctuation ')]}"\'.$' - @space '\t\s' - @trailing_identifier '?!' - @tilde_op_prefix '<=~' + @operators ~c"\\<>+-*/:=|&~^%!" + @starter_punctuation ~c",([{;" + @non_starter_punctuation ~c")]}\"'.$" + @space ~c"\t\s" + @trailing_identifier ~c"?!" + @tilde_op_prefix ~c"<=~" @non_identifier @trailing_identifier ++ @operators ++ @starter_punctuation ++ @non_starter_punctuation ++ @space @@ -186,9 +186,9 @@ defmodule Code.Fragment do # It is empty [] -> {:expr, 0} # Structs - [?%, ?:, ?: | _] -> {{:struct, ''}, 1} - [?%, ?: | _] -> {{:unquoted_atom, '%'}, 2} - [?% | _] -> {{:struct, ''}, 1} + [?%, ?:, ?: | _] -> {{:struct, ~c""}, 1} + [?%, ?: | _] -> {{:unquoted_atom, ~c"%"}, 2} + [?% | _] -> {{:struct, ~c""}, 1} # Token/AST only operators [?>, ?= | rest] when rest == [] or hd(rest) != ?: -> {:expr, 0} [?>, ?- | rest] when rest == [] or hd(rest) != ?: -> {:expr, 0} @@ -198,7 +198,7 @@ defmodule Code.Fragment do [?: | rest] when rest == [] or hd(rest) != ?: -> unquoted_atom_or_expr(spaces) # Dots [?.] -> {:none, 0} - [?. | rest] when hd(rest) not in '.:' -> dot(rest, spaces + 1, '') + [?. | rest] when hd(rest) not in ~c".:" -> dot(rest, spaces + 1, ~c"") # It is a local or remote call with parens [?( | rest] -> call_to_cursor_context(strip_spaces(rest, spaces + 1)) # A local arity definition @@ -215,7 +215,7 @@ defmodule Code.Fragment do defp strip_spaces([h | rest], count) when h in @space, do: strip_spaces(rest, count + 1) defp strip_spaces(rest, count), do: {rest, count} - defp unquoted_atom_or_expr(0), do: {{:unquoted_atom, ''}, 1} + defp unquoted_atom_or_expr(0), do: {{:unquoted_atom, ~c""}, 1} defp unquoted_atom_or_expr(_), do: {:expr, 0} defp arity_to_cursor_context({reverse, spaces}) do @@ -236,10 +236,10 @@ defmodule Code.Fragment do end end - defp identifier_to_cursor_context([?., ?., ?: | _], n, _), do: {{:unquoted_atom, '..'}, n + 3} - defp identifier_to_cursor_context([?., ?., ?. | _], n, _), do: {{:local_or_var, '...'}, n + 3} - defp identifier_to_cursor_context([?., ?: | _], n, _), do: {{:unquoted_atom, '.'}, n + 2} - defp identifier_to_cursor_context([?., ?. | _], n, _), do: {{:operator, '..'}, n + 2} + defp identifier_to_cursor_context([?., ?., ?: | _], n, _), do: {{:unquoted_atom, ~c".."}, n + 3} + defp identifier_to_cursor_context([?., ?., ?. | _], n, _), do: {{:local_or_var, ~c"..."}, n + 3} + defp identifier_to_cursor_context([?., ?: | _], n, _), do: {{:unquoted_atom, ~c"."}, n + 2} + defp identifier_to_cursor_context([?., ?. | _], n, _), do: {{:operator, ~c".."}, n + 2} defp identifier_to_cursor_context(reverse, count, call_op?) do case identifier(reverse, count) do @@ -263,10 +263,10 @@ defmodule Code.Fragment do {:alias, rest, acc, count} -> case strip_spaces(rest, count) do - {'.' ++ rest, count} when rest == [] or hd(rest) != ?. -> + {~c"." ++ rest, count} when rest == [] or hd(rest) != ?. -> nested_alias(rest, count + 1, acc) - {'%' ++ _, count} -> + {~c"%" ++ _, count} -> {{:struct, acc}, count + 1} _ -> @@ -284,7 +284,7 @@ defmodule Code.Fragment do {:identifier, rest, acc, count} -> case strip_spaces(rest, count) do - {'.' ++ rest, count} when rest == [] or hd(rest) != ?. -> + {~c"." ++ rest, count} when rest == [] or hd(rest) != ?. -> dot(rest, count + 1, acc) _ -> @@ -310,7 +310,7 @@ defmodule Code.Fragment do case tokenize_identifier(rest, count, acc) do {:identifier, [?% | _rest], acc, count} -> {:struct, {:module_attribute, acc}, count} {:identifier, _rest, acc, count} -> {:module_attribute, acc, count} - :none when acc == [] -> {:module_attribute, '', count} + :none when acc == [] -> {:module_attribute, ~c"", count} _ -> :none end end @@ -363,19 +363,19 @@ defmodule Code.Fragment do case identifier_to_cursor_context(rest, count, true) do {{:struct, prev}, count} when is_list(prev) -> - {{:struct, prev ++ '.' ++ acc}, count} + {{:struct, prev ++ ~c"." ++ acc}, count} {{:struct, {:alias, parent, prev}}, count} -> - {{:struct, {:alias, parent, prev ++ '.' ++ acc}}, count} + {{:struct, {:alias, parent, prev ++ ~c"." ++ acc}}, count} {{:struct, prev}, count} -> {{:struct, {:alias, prev, acc}}, count} {{:alias, prev}, count} -> - {{:alias, prev ++ '.' ++ acc}, count} + {{:alias, prev ++ ~c"." ++ acc}, count} {{:alias, parent, prev}, count} -> - {{:alias, parent, prev ++ '.' ++ acc}, count} + {{:alias, parent, prev ++ ~c"." ++ acc}, count} {{:local_or_var, prev}, count} -> {{:alias, {:local_or_var, prev}, acc}, count} @@ -427,18 +427,18 @@ defmodule Code.Fragment do # If we are opening a sigil, ignore the operator. defp operator([letter, ?~ | rest], _count, [op], _call_op?) - when op in '<|/' and (letter in ?A..?Z or letter in ?a..?z) and + when op in ~c"<|/" and (letter in ?A..?Z or letter in ?a..?z) and (rest == [] or hd(rest) not in @tilde_op_prefix) do {:none, 0} end - defp operator(rest, count, '~', call_op?) do + defp operator(rest, count, ~c"~", call_op?) do {rest, _} = strip_spaces(rest, count) if call_op? or match?([?. | rest] when rest == [] or hd(rest) != ?., rest) do {:none, 0} else - {{:sigil, ''}, count} + {{:sigil, ~c""}, count} end end @@ -630,8 +630,8 @@ defmodule Code.Fragment do {{:local_or_var, acc}, offset} -> build_surround({:local_or_var, acc}, reversed, line, offset) - {{:module_attribute, ''}, offset} -> - build_surround({:operator, '@'}, reversed, line, offset) + {{:module_attribute, ~c""}, offset} -> + build_surround({:operator, ~c"@"}, reversed, line, offset) {{:module_attribute, acc}, offset} -> build_surround({:module_attribute, acc}, reversed, line, offset) @@ -674,7 +674,7 @@ defmodule Code.Fragment do {{:operator, acc}, offset} -> build_surround({:operator, acc}, reversed, line, offset) - {{:sigil, ''}, offset} when hd(rest) in ?A..?Z or hd(rest) in ?a..?z -> + {{:sigil, ~c""}, offset} when hd(rest) in ?A..?Z or hd(rest) in ?a..?z -> build_surround({:sigil, [hd(rest)]}, [hd(rest) | reversed], line, offset + 1) {{:dot, _, [_ | _]} = dot, offset} -> @@ -750,7 +750,7 @@ defmodule Code.Fragment do _ -> case strip_spaces(reversed_pre, 0) do # If there is a dot to our left, make sure to move to the first character - {[?. | rest], _} when rest == [] or hd(rest) not in '.:' -> + {[?. | rest], _} when rest == [] or hd(rest) not in ~c".:" -> {post, reversed_pre} = move_spaces(post, reversed_pre) {reversed_pre, post} @@ -798,9 +798,9 @@ defmodule Code.Fragment do defp last_line(charlist) when is_list(charlist) do [last_line | lines_reverse] = charlist - |> :string.replace('\r\n', '\n', :all) - |> :string.join('') - |> :string.split('\n', :all) + |> :string.replace(~c"\r\n", ~c"\n", :all) + |> :string.join(~c"") + |> :string.split(~c"\n", :all) |> Enum.reverse() prepend_cursor_lines(lines_reverse, last_line) @@ -844,9 +844,9 @@ defmodule Code.Fragment do defp surround_line(charlist, line, column) when is_list(charlist) do charlist - |> :string.replace('\r\n', '\n', :all) - |> :string.join('') - |> :string.split('\n', :all) + |> :string.replace(~c"\r\n", ~c"\n", :all) + |> :string.join(~c"") + |> :string.split(~c"\n", :all) |> surround_lines(line, column) end diff --git a/lib/elixir/lib/code/identifier.ex b/lib/elixir/lib/code/identifier.ex index e1d7b374e..25163cbd5 100644 --- a/lib/elixir/lib/code/identifier.ex +++ b/lib/elixir/lib/code/identifier.ex @@ -88,7 +88,7 @@ defmodule Code.Identifier do end defp escape(<>, char, count, acc, fun) do - escape(t, char, decrement(count), [acc | '\\\#{'], fun) + escape(t, char, decrement(count), [acc | [?\\, ?#, ?{]], fun) end defp escape(<>, char, count, acc, fun) do @@ -97,16 +97,17 @@ defmodule Code.Identifier do end defp escape(<>, char, count, acc, fun) do - escape(t, char, decrement(count), [acc | ['\\x', to_hex(a), to_hex(b)]], fun) + escape(t, char, decrement(count), [acc | [?\\, ?x, to_hex(a), to_hex(b)]], fun) end defp escape(<<>>, _char, _count, acc, _fun) do {acc, <<>>} end - defp escape_char(0), do: '\\0' + defp escape_char(0), do: [?\\, ?0] - defp escape_char(65279), do: '\\uFEFF' + @escaped_bom :binary.bin_to_list("\\uFEFF") + defp escape_char(65279), do: @escaped_bom defp escape_char(char) when char in 0x20..0x7E @@ -118,29 +119,29 @@ defmodule Code.Identifier do defp escape_char(char) when char < 0x100 do <> = <> - ['\\x', to_hex(a), to_hex(b)] + [?\\, ?x, to_hex(a), to_hex(b)] end defp escape_char(char) when char < 0x10000 do <> = <> - ['\\x{', to_hex(a), to_hex(b), to_hex(c), to_hex(d), ?}] + [?\\, ?x, ?{, to_hex(a), to_hex(b), to_hex(c), to_hex(d), ?}] end defp escape_char(char) when char < 0x1000000 do <> = <> - ['\\x{', to_hex(a), to_hex(b), to_hex(c), to_hex(d), to_hex(e), to_hex(f), ?}] + [?\\, ?x, ?{, to_hex(a), to_hex(b), to_hex(c), to_hex(d), to_hex(e), to_hex(f), ?}] end - defp escape_map(?\a), do: '\\a' - defp escape_map(?\b), do: '\\b' - defp escape_map(?\d), do: '\\d' - defp escape_map(?\e), do: '\\e' - defp escape_map(?\f), do: '\\f' - defp escape_map(?\n), do: '\\n' - defp escape_map(?\r), do: '\\r' - defp escape_map(?\t), do: '\\t' - defp escape_map(?\v), do: '\\v' - defp escape_map(?\\), do: '\\\\' + defp escape_map(?\a), do: [?\\, ?a] + defp escape_map(?\b), do: [?\\, ?b] + defp escape_map(?\d), do: [?\\, ?d] + defp escape_map(?\e), do: [?\\, ?e] + defp escape_map(?\f), do: [?\\, ?f] + defp escape_map(?\n), do: [?\\, ?n] + defp escape_map(?\r), do: [?\\, ?r] + defp escape_map(?\t), do: [?\\, ?t] + defp escape_map(?\v), do: [?\\, ?v] + defp escape_map(?\\), do: [?\\, ?\\] defp escape_map(_), do: false @compile {:inline, to_hex: 1, decrement: 1} diff --git a/lib/elixir/lib/code/normalizer.ex b/lib/elixir/lib/code/normalizer.ex index a3018c6bf..d7c4b1bef 100644 --- a/lib/elixir/lib/code/normalizer.ex +++ b/lib/elixir/lib/code/normalizer.ex @@ -575,7 +575,7 @@ defmodule Code.Normalizer do defp keyword?([{key, _value} | rest]) when is_atom(key) do case Atom.to_charlist(key) do - 'Elixir.' ++ _ -> false + ~c"Elixir." ++ _ -> false _ -> keyword?(rest) end end diff --git a/lib/elixir/lib/dynamic_supervisor.ex b/lib/elixir/lib/dynamic_supervisor.ex index e05b3653b..92ef5b6c9 100644 --- a/lib/elixir/lib/dynamic_supervisor.ex +++ b/lib/elixir/lib/dynamic_supervisor.ex @@ -1108,6 +1108,6 @@ defmodule DynamicSupervisor do label: {__MODULE__, :unexpected_msg}, report: %{msg: msg} }) do - {'DynamicSupervisor received unexpected message: ~p~n', [msg]} + {~c"DynamicSupervisor received unexpected message: ~p~n", [msg]} end end diff --git a/lib/elixir/lib/float.ex b/lib/elixir/lib/float.ex index 8472ba017..3e92ba5b5 100644 --- a/lib/elixir/lib/float.ex +++ b/lib/elixir/lib/float.ex @@ -165,11 +165,11 @@ defmodule Float do do: parse_unsigned(rest, true, false, <>) defp parse_unsigned(<>, dot?, false, acc) - when exp_marker in 'eE' and digit in ?0..?9, + when exp_marker in ~c"eE" and digit in ?0..?9, do: parse_unsigned(rest, true, true, <>) defp parse_unsigned(<>, dot?, false, acc) - when exp_marker in 'eE' and sign in '-+' and digit in ?0..?9, + when exp_marker in ~c"eE" and sign in ~c"-+" and digit in ?0..?9, do: parse_unsigned(rest, true, true, <>) defp parse_unsigned(rest, dot?, _e?, acc), diff --git a/lib/elixir/lib/gen_event.ex b/lib/elixir/lib/gen_event.ex index e05577bfb..746e0931b 100644 --- a/lib/elixir/lib/gen_event.ex +++ b/lib/elixir/lib/gen_event.ex @@ -510,7 +510,7 @@ defmodule GenEvent do @doc false def format_status(opt, status_data) do [pdict, sys_state, parent, _debug, [name, handlers, _hib]] = status_data - header = :gen.format_status_header('Status for event handler', name) + header = :gen.format_status_header(~c"Status for event handler", name) formatted = for handler <- handlers do @@ -530,8 +530,8 @@ defmodule GenEvent do [ header: header, - data: [{'Status', sys_state}, {'Parent', parent}], - items: {'Installed handlers', formatted} + data: [{~c"Status", sys_state}, {~c"Parent", parent}], + items: {~c"Installed handlers", formatted} ] end @@ -882,9 +882,9 @@ defmodule GenEvent do formatted = report_status(handler, state) :error_logger.error_msg( - '** gen_event handler ~p crashed.~n' ++ - '** Was installed in ~p~n' ++ - '** Last event was: ~p~n' ++ '** When handler state == ~p~n' ++ '** Reason == ~p~n', + ~c"** gen_event handler ~p crashed.~n" ++ + ~c"** Was installed in ~p~n" ++ + ~c"** Last event was: ~p~n" ++ ~c"** When handler state == ~p~n" ++ ~c"** Reason == ~p~n", [handler(handler, :id), name, last_in, formatted, reason] ) end diff --git a/lib/elixir/lib/gen_server.ex b/lib/elixir/lib/gen_server.ex index ae7a42ea3..7de035508 100644 --- a/lib/elixir/lib/gen_server.ex +++ b/lib/elixir/lib/gen_server.ex @@ -1226,6 +1226,6 @@ defmodule GenServer do label: {GenServer, :no_handle_info}, report: %{module: mod, message: msg, name: proc} }) do - {'~p ~p received unexpected message in handle_info/2: ~p~n', [mod, proc, msg]} + {~c"~p ~p received unexpected message in handle_info/2: ~p~n", [mod, proc, msg]} end end diff --git a/lib/elixir/lib/inspect.ex b/lib/elixir/lib/inspect.ex index c400493c9..a82e78ee7 100644 --- a/lib/elixir/lib/inspect.ex +++ b/lib/elixir/lib/inspect.ex @@ -281,7 +281,7 @@ defimpl Inspect, for: List do @doc false def keyword?([{key, _value} | rest]) when is_atom(key) do case Atom.to_charlist(key) do - 'Elixir.' ++ _ -> false + [?E, ?l, ?i, ?x, ?i, ?r, ?.] ++ _ -> false _ -> keyword?(rest) end end @@ -397,7 +397,7 @@ defimpl Inspect, for: Regex do |> normalize(<<>>) |> Identifier.escape(?/, :infinity, &escape_map/1) - source = IO.iodata_to_binary(['~r/', escaped, ?/, regex.opts]) + source = IO.iodata_to_binary([?~, ?r, ?/, escaped, ?/, regex.opts]) color(source, :regex, opts) end @@ -406,16 +406,18 @@ defimpl Inspect, for: Regex do defp normalize(<>, acc), do: normalize(rest, <>) defp normalize(<<>>, acc), do: acc - defp escape_map(?\a), do: '\\a' - defp escape_map(?\f), do: '\\f' - defp escape_map(?\n), do: '\\n' - defp escape_map(?\r), do: '\\r' - defp escape_map(?\t), do: '\\t' - defp escape_map(?\v), do: '\\v' + defp escape_map(?\a), do: [?\\, ?a] + defp escape_map(?\f), do: [?\\, ?f] + defp escape_map(?\n), do: [?\\, ?n] + defp escape_map(?\r), do: [?\\, ?r] + defp escape_map(?\t), do: [?\\, ?t] + defp escape_map(?\v), do: [?\\, ?v] defp escape_map(_), do: false end defimpl Inspect, for: Function do + @elixir_compiler :binary.bin_to_list("elixir_compiler_") + def inspect(function, _opts) do fun_info = Function.info(function) mod = fun_info[:module] @@ -430,7 +432,7 @@ defimpl Inspect, for: Function do inspected_as_function = Macro.inspect_atom(:remote_call, name) "&#{inspected_as_atom}.#{inspected_as_function}/#{fun_info[:arity]}" - match?('elixir_compiler_' ++ _, Atom.to_charlist(mod)) -> + match?(@elixir_compiler ++ _, Atom.to_charlist(mod)) -> if function_exported?(mod, :__RELATIVE__, 0) do "#Function<#{uniq(fun_info)} in file:#{mod.__RELATIVE__}>" else @@ -511,7 +513,7 @@ end defimpl Inspect, for: Reference do def inspect(ref, _opts) do - '#Ref' ++ rest = :erlang.ref_to_list(ref) + [?#, ?R, ?e, ?f] ++ rest = :erlang.ref_to_list(ref) "#Reference" <> IO.iodata_to_binary(rest) end end diff --git a/lib/elixir/lib/integer.ex b/lib/elixir/lib/integer.ex index bd60a8ca6..67f900a98 100644 --- a/lib/elixir/lib/integer.ex +++ b/lib/elixir/lib/integer.ex @@ -287,7 +287,7 @@ defmodule Integer do end end - defp count_digits(<>, base) when sign in '+-' do + defp count_digits(<>, base) when sign in ~c"+-" do case count_digits_nosign(rest, base, 1) do 1 -> 0 count -> count diff --git a/lib/elixir/lib/io.ex b/lib/elixir/lib/io.ex index 496459423..918d1091a 100644 --- a/lib/elixir/lib/io.ex +++ b/lib/elixir/lib/io.ex @@ -150,7 +150,7 @@ defmodule IO do with :eof <- read(device, :eof) do with [_ | _] = opts <- :io.getopts(device), false <- Keyword.get(opts, :binary, true) do - '' + ~c"" else _ -> "" end @@ -158,15 +158,15 @@ defmodule IO do end def read(device, :eof) do - getn(device, '', :eof) + getn(device, ~c"", :eof) end def read(device, :line) do - :io.get_line(map_dev(device), '') + :io.get_line(map_dev(device), ~c"") end def read(device, count) when is_integer(count) and count >= 0 do - :io.get_chars(map_dev(device), '', count) + :io.get_chars(map_dev(device), ~c"", count) end @doc """ @@ -525,7 +525,7 @@ defmodule IO do defp getn_eof(device, prompt, acc) do case :io.get_line(device, prompt) do - line when is_binary(line) or is_list(line) -> getn_eof(device, '', [line | acc]) + line when is_binary(line) or is_list(line) -> getn_eof(device, ~c"", [line | acc]) :eof -> wrap_eof(:lists.reverse(acc)) other -> other end diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 3d0b08ffd..051a58058 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -2012,7 +2012,7 @@ defmodule Kernel do end erlang_error = - case :erlang.system_info(:otp_release) >= '24' do + case :erlang.system_info(:otp_release) >= [?2, ?4] do true -> fn x -> quote do diff --git a/lib/elixir/lib/kernel/parallel_compiler.ex b/lib/elixir/lib/kernel/parallel_compiler.ex index 503016530..c500b4347 100644 --- a/lib/elixir/lib/kernel/parallel_compiler.ex +++ b/lib/elixir/lib/kernel/parallel_compiler.ex @@ -776,7 +776,7 @@ defmodule Kernel.ParallelCompiler do end defp get_line(file, _reason, [{_, _, _, [file: expanding]}, {_, _, _, info} | _]) - when expanding in ['expanding macro', 'expanding struct'] do + when expanding in [~c"expanding macro", ~c"expanding struct"] do if Keyword.get(info, :file) == to_charlist(Path.relative_to_cwd(file)) do Keyword.get(info, :line) end diff --git a/lib/elixir/lib/list/chars.ex b/lib/elixir/lib/list/chars.ex index 08fd2b50d..2ffa8cad6 100644 --- a/lib/elixir/lib/list/chars.ex +++ b/lib/elixir/lib/list/chars.ex @@ -24,7 +24,7 @@ defprotocol List.Chars do end defimpl List.Chars, for: Atom do - def to_charlist(nil), do: '' + def to_charlist(nil), do: ~c"" def to_charlist(atom), do: Atom.to_charlist(atom) end diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index 3cc8274a1..64ee86242 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -2383,7 +2383,7 @@ defmodule Macro do end end - defp valid_alias?('Elixir' ++ rest), do: valid_alias_piece?(rest) + defp valid_alias?([?E, ?l, ?i, ?x, ?i, ?r] ++ rest), do: valid_alias_piece?(rest) defp valid_alias?(_other), do: false defp valid_alias_piece?([?., char | rest]) when char >= ?A and char <= ?Z, diff --git a/lib/elixir/lib/module.ex b/lib/elixir/lib/module.ex index 7433883e9..ef194e5a5 100644 --- a/lib/elixir/lib/module.ex +++ b/lib/elixir/lib/module.ex @@ -1423,7 +1423,7 @@ defmodule Module do defp normalize_macro_or_function_callback({function_name, arity}) do case :erlang.atom_to_list(function_name) do # Macros are always provided one extra argument in behaviour_info/1 - 'MACRO-' ++ tail -> + [?M, ?A, ?C, ?R, ?O, ?-] ++ tail -> {{:erlang.list_to_atom(tail), arity - 1}, :defmacro} _ -> diff --git a/lib/elixir/lib/module/parallel_checker.ex b/lib/elixir/lib/module/parallel_checker.ex index a155d9e93..74e0f611e 100644 --- a/lib/elixir/lib/module/parallel_checker.ex +++ b/lib/elixir/lib/module/parallel_checker.ex @@ -318,7 +318,7 @@ defmodule Module.ParallelChecker do defp cache_from_chunk(ets, module) do with {^module, binary, _filename} <- :code.get_object_code(module), {:ok, ^module} <- binary |> :beam_lib.info() |> Keyword.fetch(:module), - {:ok, {_, [{'ExCk', chunk}]}} <- :beam_lib.chunks(binary, ['ExCk']), + {:ok, {_, [{~c"ExCk", chunk}]}} <- :beam_lib.chunks(binary, [~c"ExCk"]), {:elixir_checker_v1, contents} <- :erlang.binary_to_term(chunk) do cache_chunk(ets, module, contents.exports) true diff --git a/lib/elixir/lib/path.ex b/lib/elixir/lib/path.ex index d015ce408..089f7a6fd 100644 --- a/lib/elixir/lib/path.ex +++ b/lib/elixir/lib/path.ex @@ -120,7 +120,7 @@ defmodule Path do defp do_absname_join(<>, relativename, [], :win32) when c1 in @slash and c2 in @slash, - do: do_absname_join(rest, relativename, '//', :win32) + do: do_absname_join(rest, relativename, ~c"//", :win32) defp do_absname_join(<>, relativename, result, :win32), do: do_absname_join(<>, relativename, result, :win32) @@ -260,7 +260,7 @@ defmodule Path do end end - defp unix_pathtype(path) when path in ["/", '/'], do: {:absolute, "."} + defp unix_pathtype(path) when path in ["/", ~c"/"], do: {:absolute, "."} defp unix_pathtype(<>), do: {:absolute, relative} defp unix_pathtype([?/ | relative]), do: {:absolute, relative} defp unix_pathtype([list | rest]) when is_list(list), do: unix_pathtype(list ++ rest) diff --git a/lib/elixir/lib/protocol.ex b/lib/elixir/lib/protocol.ex index 1d02e720c..20651e008 100644 --- a/lib/elixir/lib/protocol.ex +++ b/lib/elixir/lib/protocol.ex @@ -449,7 +449,7 @@ defmodule Protocol do """ @spec extract_protocols([charlist | String.t()]) :: [atom] def extract_protocols(paths) do - extract_matching_by_attribute(paths, 'Elixir.', fn module, attributes -> + extract_matching_by_attribute(paths, [?E, ?l, ?i, ?x, ?i, ?r, ?.], fn module, attributes -> case attributes[:__protocol__] do [fallback_to_any: _] -> module _ -> nil @@ -478,7 +478,7 @@ defmodule Protocol do """ @spec extract_impls(module, [charlist | String.t()]) :: [atom] def extract_impls(protocol, paths) when is_atom(protocol) do - prefix = Atom.to_charlist(protocol) ++ '.' + prefix = Atom.to_charlist(protocol) ++ [?.] extract_matching_by_attribute(paths, prefix, fn _mod, attributes -> case attributes[:__impl__] do @@ -504,7 +504,7 @@ defmodule Protocol do end defp extract_from_file(path, file, prefix, callback) do - if :lists.prefix(prefix, file) and :filename.extension(file) == '.beam' do + if :lists.prefix(prefix, file) and :filename.extension(file) == [?., ?b, ?e, ?a, ?m] do extract_from_beam(:filename.join(path, file), callback) end end @@ -565,7 +565,7 @@ defmodule Protocol do end defp beam_protocol(protocol) do - chunk_ids = [:debug_info, 'Docs', 'ExCk'] + chunk_ids = [:debug_info, [?D, ?o, ?c, ?s], [?E, ?x, ?C, ?k]] opts = [:allow_missing_chunks] case :beam_lib.chunks(beam_file(protocol), chunk_ids, opts) do diff --git a/lib/elixir/lib/regex.ex b/lib/elixir/lib/regex.ex index 8e17ce193..9661ad57a 100644 --- a/lib/elixir/lib/regex.ex +++ b/lib/elixir/lib/regex.ex @@ -818,7 +818,7 @@ defmodule Regex do |> IO.iodata_to_binary() end - @escapable '.^$*+?()[]{}|#-\\\t\n\v\f\r\s' + @escapable :binary.bin_to_list(".^$*+?()[]{}|#-\\\t\n\v\f\r\s") defp escape(<>, length, original) when char in @escapable do escape_char(rest, length, original, char) diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index 8ff0329a7..81d245b42 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -331,7 +331,7 @@ defmodule String do end end - for char <- '\n\r\t\v\b\f\e\d\a' do + for char <- [?\n, ?\r, ?\t, ?\v, ?\b, ?\f, ?\e, ?\d, ?\a] do defp recur_printable?(<>, character_limit) do recur_printable?(rest, decrement(character_limit)) end diff --git a/lib/elixir/lib/system.ex b/lib/elixir/lib/system.ex index 5db7f5ff3..c4affee27 100644 --- a/lib/elixir/lib/system.ex +++ b/lib/elixir/lib/system.ex @@ -141,11 +141,11 @@ defmodule System do defmacrop get_revision do null = case :os.type() do - {:win32, _} -> 'NUL' - _ -> '/dev/null' + {:win32, _} -> ~c"NUL" + _ -> ~c"/dev/null" end - 'git rev-parse --short=7 HEAD 2> ' + ~c"git rev-parse --short=7 HEAD 2> " |> Kernel.++(null) |> :os.cmd() |> strip @@ -157,7 +157,7 @@ defmodule System do # Follows https://reproducible-builds.org/specs/source-date-epoch/ defmacrop get_date do unix_epoch = - if source_date_epoch = :os.getenv('SOURCE_DATE_EPOCH') do + if source_date_epoch = :os.getenv(~c"SOURCE_DATE_EPOCH") do try do List.to_integer(source_date_epoch) rescue @@ -374,8 +374,8 @@ defmodule System do """ @spec tmp_dir() :: String.t() | nil def tmp_dir do - write_env_tmp_dir('TMPDIR') || write_env_tmp_dir('TEMP') || write_env_tmp_dir('TMP') || - write_tmp_dir('/tmp') || write_cwd_tmp_dir() + write_env_tmp_dir(~c"TMPDIR") || write_env_tmp_dir(~c"TEMP") || write_env_tmp_dir(~c"TMP") || + write_tmp_dir(~c"/tmp") || write_cwd_tmp_dir() end defp write_cwd_tmp_dir do @@ -921,7 +921,7 @@ defmodule System do # https://github.com/erlang/otp/blob/8deb96fb1d017307e22d2ab88968b9ef9f1b71d0/lib/kernel/src/os.erl#L184 case :os.type() do {:unix, _} -> - shell_path = :os.find_executable('sh') || :erlang.error(:enoent, [command, opts]) + shell_path = :os.find_executable(~c"sh") || :erlang.error(:enoent, [command, opts]) command = "(#{command}\n) 'command.com /s /c ' ++ command - {nil, _} -> 'cmd /s /c ' ++ command - {cmd, _} -> '#{cmd} /s /c ' ++ command + {nil, :windows} -> ~c"command.com /s /c " ++ command + {nil, _} -> ~c"cmd /s /c " ++ command + {cmd, _} -> ~c"#{cmd} /s /c " ++ command end do_cmd({:spawn, command}, [], opts) diff --git a/lib/elixir/lib/task/supervised.ex b/lib/elixir/lib/task/supervised.ex index 66fc9d2e2..a6d44f8fd 100644 --- a/lib/elixir/lib/task/supervised.ex +++ b/lib/elixir/lib/task/supervised.ex @@ -135,10 +135,10 @@ defmodule Task.Supervised do } }) do message = - '** Task ~p terminating~n' ++ - '** Started from ~p~n' ++ - '** When function == ~p~n' ++ - '** arguments == ~p~n' ++ '** Reason for termination == ~n' ++ '** ~p~n' + ~c"** Task ~p terminating~n" ++ + ~c"** Started from ~p~n" ++ + ~c"** When function == ~p~n" ++ + ~c"** arguments == ~p~n" ++ ~c"** Reason for termination == ~n" ++ ~c"** ~p~n" {message, [starter, name, fun, args, get_reason(reason)]} end diff --git a/lib/elixir/lib/uri.ex b/lib/elixir/lib/uri.ex index abb6fa4a8..c887fa4df 100644 --- a/lib/elixir/lib/uri.ex +++ b/lib/elixir/lib/uri.ex @@ -48,7 +48,7 @@ defmodule URI do import Bitwise - @reserved_characters ':/?#[]@!$&\'()*+,;=' + @reserved_characters ~c":/?#[]@!$&'()*+,;=" @formatted_reserved_characters Enum.map_join(@reserved_characters, ", ", &<>) @doc """ @@ -334,7 +334,7 @@ defmodule URI do """ @spec char_unreserved?(byte) :: boolean def char_unreserved?(character) do - character in ?0..?9 or character in ?a..?z or character in ?A..?Z or character in '~_-.' + character in ?0..?9 or character in ?a..?z or character in ?A..?Z or character in ~c"~_-." end @doc """ diff --git a/lib/elixir/test/elixir/application_test.exs b/lib/elixir/test/elixir/application_test.exs index 4bdd37c3a..2ebf9506c 100644 --- a/lib/elixir/test/elixir/application_test.exs +++ b/lib/elixir/test/elixir/application_test.exs @@ -142,15 +142,15 @@ defmodule ApplicationTest do test "loaded and started applications" do started = Application.started_applications() assert is_list(started) - assert {:elixir, 'elixir', _} = List.keyfind(started, :elixir, 0) + assert {:elixir, ~c"elixir", _} = List.keyfind(started, :elixir, 0) started_timeout = Application.started_applications(7000) assert is_list(started_timeout) - assert {:elixir, 'elixir', _} = List.keyfind(started_timeout, :elixir, 0) + assert {:elixir, ~c"elixir", _} = List.keyfind(started_timeout, :elixir, 0) loaded = Application.loaded_applications() assert is_list(loaded) - assert {:elixir, 'elixir', _} = List.keyfind(loaded, :elixir, 0) + assert {:elixir, ~c"elixir", _} = List.keyfind(loaded, :elixir, 0) end test "application specification" do @@ -158,7 +158,7 @@ defmodule ApplicationTest do assert Application.spec(:unknown) == nil assert Application.spec(:unknown, :description) == nil - assert Application.spec(:elixir, :description) == 'elixir' + assert Application.spec(:elixir, :description) == ~c"elixir" assert_raise FunctionClauseError, fn -> Application.spec(:elixir, :unknown) end end diff --git a/lib/elixir/test/elixir/atom_test.exs b/lib/elixir/test/elixir/atom_test.exs index 0f07a033c..d3d36ac5e 100644 --- a/lib/elixir/test/elixir/atom_test.exs +++ b/lib/elixir/test/elixir/atom_test.exs @@ -10,6 +10,6 @@ defmodule AtomTest do end test "to_charlist/1" do - assert "héllo" |> String.to_atom() |> Atom.to_charlist() == 'héllo' + assert "héllo" |> String.to_atom() |> Atom.to_charlist() == ~c"héllo" end end diff --git a/lib/elixir/test/elixir/code_formatter/calls_test.exs b/lib/elixir/test/elixir/code_formatter/calls_test.exs index cd07a0431..9705b78bf 100644 --- a/lib/elixir/test/elixir/code_formatter/calls_test.exs +++ b/lib/elixir/test/elixir/code_formatter/calls_test.exs @@ -75,16 +75,16 @@ defmodule Code.Formatter.CallsTest do test "for heredocs" do assert_same """ - foo(''' + foo(~c''' bar ''') """ - assert_same to_string(''' - foo(""" - bar - """) - ''') + assert_same ~S''' + foo(""" + bar + """) + ''' assert_same """ foo(~S''' diff --git a/lib/elixir/test/elixir/code_formatter/general_test.exs b/lib/elixir/test/elixir/code_formatter/general_test.exs index 50c44a3df..7d661b088 100644 --- a/lib/elixir/test/elixir/code_formatter/general_test.exs +++ b/lib/elixir/test/elixir/code_formatter/general_test.exs @@ -35,7 +35,7 @@ defmodule Code.Formatter.GeneralTest do test "starting with expression" do assert_same "__MODULE__.Foo.Bar" # Syntactically valid, semantically invalid - assert_same "'Foo'.Bar.Baz" + assert_same ~S[~c"Foo".Bar.Baz] end test "wraps the head in parens if it has an operator" do @@ -155,7 +155,7 @@ defmodule Code.Formatter.GeneralTest do """ formatter = fn content, opts -> - assert opts == [file: nil, line: 1, sigil: :W, modifiers: 'abc', opening_delimiter: "<"] + assert opts == [file: nil, line: 1, sigil: :W, modifiers: ~c"abc", opening_delimiter: "<"] content |> String.split(~r/ +/) |> Enum.intersperse(" ") end @@ -207,7 +207,7 @@ defmodule Code.Formatter.GeneralTest do file: nil, line: 2, sigil: :W, - modifiers: 'abc', + modifiers: ~c"abc", opening_delimiter: ~S/"""/ ] @@ -344,19 +344,19 @@ defmodule Code.Formatter.GeneralTest do end test "with heredocs" do - assert_same """ + assert_same ~S''' fn arg1 -> - ''' + """ foo - ''' + """ arg2 -> - ''' + """ bar - ''' + """ end - """ + ''' end test "with multiple empty clauses" do @@ -559,19 +559,19 @@ defmodule Code.Formatter.GeneralTest do end test "with heredocs" do - assert_same """ + assert_same ~S''' ( arg1 -> - ''' + """ foo - ''' + """ arg2 -> - ''' + """ bar - ''' + """ ) - """ + ''' end test "with multiple empty clauses" do @@ -711,17 +711,17 @@ defmodule Code.Formatter.GeneralTest do end test "with heredoc" do - assert_same """ + assert_same ~S''' block do - ''' + """ a b c - ''' + """ end - """ + ''' end test "keeps user newlines" do @@ -830,14 +830,14 @@ defmodule Code.Formatter.GeneralTest do end test "with module attributes" do - assert_same """ + assert_same ~S''' defmodule Foo do @constant 1 @constant 2 - @doc ''' + @doc """ foo - ''' + """ def foo do :ok end @@ -851,9 +851,9 @@ defmodule Code.Formatter.GeneralTest do @other_constant 3 @spec baz :: 4 - @doc ''' + @doc """ baz - ''' + """ def baz do :ok end @@ -861,15 +861,15 @@ defmodule Code.Formatter.GeneralTest do @another_constant 5 @another_constant 5 - @doc ''' + @doc """ baz - ''' + """ @spec baz :: 6 def baz do :ok end end - """ + ''' end test "as function arguments" do diff --git a/lib/elixir/test/elixir/code_formatter/integration_test.exs b/lib/elixir/test/elixir/code_formatter/integration_test.exs index 3a2a4b75f..52463653a 100644 --- a/lib/elixir/test/elixir/code_formatter/integration_test.exs +++ b/lib/elixir/test/elixir/code_formatter/integration_test.exs @@ -484,12 +484,12 @@ defmodule Code.Formatter.IntegrationTest do test "newline after stab" do assert_same """ capture_io(":erl. mof*,,l", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:":", 1}, {:atom, 1, :erl}, {:dot, 1}], 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:":", 1}, {:atom, 1, :erl}, {:dot, 1}], 1} expected_tokens = [{:atom, 1, :mof}, {:*, 1}, {:",", 1}, {:",", 1}, {:atom, 1, :l}] - assert :io.scan_erl_form('>') == {:ok, expected_tokens, 1} + assert :io.scan_erl_form(~c">") == {:ok, expected_tokens, 1} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) """ end diff --git a/lib/elixir/test/elixir/code_formatter/literals_test.exs b/lib/elixir/test/elixir/code_formatter/literals_test.exs index 909d5f4fa..b6486a892 100644 --- a/lib/elixir/test/elixir/code_formatter/literals_test.exs +++ b/lib/elixir/test/elixir/code_formatter/literals_test.exs @@ -6,6 +6,7 @@ defmodule Code.Formatter.LiteralsTest do import CodeFormatterHelpers @short_length [line_length: 10] + @keep_charlists [charlists_as_sigils: false] describe "integers" do test "in decimal base" do @@ -197,45 +198,76 @@ defmodule Code.Formatter.LiteralsTest do describe "charlists" do test "without escapes" do - assert_same ~S[''] - assert_same ~S[' '] - assert_same ~S['foo'] + assert_format ~S[''], ~S[~c""] + assert_format ~S[' '], ~S[~c" "] + assert_format ~S['foo'], ~S[~c"foo"] + + assert_same ~S[''], @keep_charlists + assert_same ~S[' '], @keep_charlists + assert_same ~S['foo'], @keep_charlists end test "with escapes" do - assert_same ~S['f\a\b\ro'] - assert_same ~S['single \' quote'] + assert_format ~S['f\a\b\ro'], ~S[~c"f\a\b\ro"] + assert_format ~S['single \' quote'], ~S[~c"single ' quote"] + assert_format ~S['double " quote'], ~S[~c"double \" quote"] + + assert_same ~S['f\a\b\ro'], @keep_charlists + assert_same ~S['single \' quote'], @keep_charlists end test "keeps literal new lines" do + assert_format """ + 'fo + o' + """, + """ + ~c"fo + o" + """ + assert_same """ - 'fo - o' - """ + 'fo + o' + """, + @keep_charlists end test "with interpolation" do - assert_same ~S['one #{2} three'] + assert_format ~S['one #{2} three'], ~S[~c"one #{2} three"] + + assert_same ~S['one #{2} three'], @keep_charlists end test "with escape and interpolation" do - assert_same ~S['one\n\'#{2}\'\nthree'] + assert_format ~S['one\n\'#{2}\'\nthree'], ~S[~c"one\n'#{2}'\nthree"] + assert_format ~S['one\n"#{2}"\nthree'], ~S[~c"one\n\"#{2}\"\nthree"] + + assert_same ~S['one\n\'#{2}\'\nthree'], @keep_charlists end test "with interpolation on line limit" do - assert_same ~S""" - 'one #{"two"} three' - """, - @short_length + assert_format ~S""" + 'one #{"two"} three' + """, + ~S""" + ~c"one #{"two"} three" + """, + @short_length end test "literal new lines don't count towards line limit" do - assert_same ~S""" - 'one - #{"two"} - three' - """, - @short_length + assert_format ~S""" + 'one + #{"two"} + three' + """, + ~S""" + ~c"one + #{"two"} + three" + """, + @short_length end end @@ -356,65 +388,149 @@ defmodule Code.Formatter.LiteralsTest do describe "charlist heredocs" do test "without escapes" do + assert_format ~S""" + ''' + hello + ''' + """, + ~S''' + ~c""" + hello + """ + ''' + assert_same ~S""" - ''' - hello - ''' - """ + ''' + hello + ''' + """, + @keep_charlists end test "with escapes" do + assert_format ~S""" + ''' + f\a\b\ro + ''' + """, + ~S''' + ~c""" + f\a\b\ro + """ + ''' + + assert_format ~S""" + ''' + multiple "\"" quotes + ''' + """, + ~S''' + ~c""" + multiple "\"" quotes + """ + ''' + assert_same ~S""" - ''' - f\a\b\ro - ''' - """ + ''' + f\a\b\ro + ''' + """, + @keep_charlists assert_same ~S""" - ''' - multiple "\"" quotes - ''' - """ + ''' + multiple "\"" quotes + ''' + """, + @keep_charlists end test "with interpolation" do - assert_same ~S""" - ''' - one - #{2} - three - ''' - """ + assert_format ~S""" + ''' + one + #{2} + three + ''' + """, + ~S''' + ~c""" + one + #{2} + three + """ + ''' + + assert_format ~S""" + ''' + one + " + #{2} + " + three + ''' + """, + ~S''' + ~c""" + one + " + #{2} + " + three + """ + ''' - assert_same ~S""" - ''' - one - " - #{2} - " - three - ''' - """ - end - - test "with interpolation on line limit" do assert_same ~S""" ''' - one #{"two two"} three + one + #{2} + three ''' """, - @short_length - end + @keep_charlists - test "literal new lines don't count towards line limit" do assert_same ~S""" ''' one - #{"two"} + " + #{2} + " three ''' """, - @short_length + @keep_charlists + end + + test "with interpolation on line limit" do + assert_format ~S""" + ''' + one #{"two two"} three + ''' + """, + ~S''' + ~c""" + one #{"two two"} three + """ + ''', + @short_length + end + + test "literal new lines don't count towards line limit" do + assert_format ~S""" + ''' + one + #{"two"} + three + ''' + """, + ~S''' + ~c""" + one + #{"two"} + three + """ + ''', + @short_length end end end diff --git a/lib/elixir/test/elixir/code_formatter/operators_test.exs b/lib/elixir/test/elixir/code_formatter/operators_test.exs index 168746e40..0e7734807 100644 --- a/lib/elixir/test/elixir/code_formatter/operators_test.exs +++ b/lib/elixir/test/elixir/code_formatter/operators_test.exs @@ -709,19 +709,19 @@ defmodule Code.Formatter.OperatorsTest do end test "with heredoc" do - heredoc = ~S""" - var = ''' + heredoc = ~S''' + var = """ one - ''' """ + ''' assert_same heredoc, @short_length - heredoc = ~S""" - var = ''' + heredoc = ~S''' + var = """ #{one} - ''' """ + ''' assert_same heredoc, @short_length end @@ -807,19 +807,19 @@ defmodule Code.Formatter.OperatorsTest do end test "with next break fits" do - attribute = """ - @doc ''' + attribute = ~S''' + @doc """ foo - ''' """ + ''' assert_same attribute - attribute = """ - @doc foo: ''' + attribute = ~S''' + @doc foo: """ bar - ''' - """ + """ + ''' assert_same attribute end diff --git a/lib/elixir/test/elixir/code_fragment_test.exs b/lib/elixir/test/elixir/code_fragment_test.exs index 8cd636651..ce9205c91 100644 --- a/lib/elixir/test/elixir/code_fragment_test.exs +++ b/lib/elixir/test/elixir/code_fragment_test.exs @@ -17,288 +17,314 @@ defmodule CodeFragmentTest do assert CF.cursor_context("foo(<<") == :expr assert CF.cursor_context("hello: ") == :expr assert CF.cursor_context("\n") == :expr - assert CF.cursor_context('\n') == :expr + assert CF.cursor_context(~c"\n") == :expr assert CF.cursor_context("\n\n") == :expr - assert CF.cursor_context('\n\n') == :expr + assert CF.cursor_context(~c"\n\n") == :expr assert CF.cursor_context("\r\n") == :expr - assert CF.cursor_context('\r\n') == :expr + assert CF.cursor_context(~c"\r\n") == :expr assert CF.cursor_context("\r\n\r\n") == :expr - assert CF.cursor_context('\r\n\r\n') == :expr + assert CF.cursor_context(~c"\r\n\r\n") == :expr end test "local_or_var" do - assert CF.cursor_context("hello_wo") == {:local_or_var, 'hello_wo'} - assert CF.cursor_context("hello_world?") == {:local_or_var, 'hello_world?'} - assert CF.cursor_context("hello_world!") == {:local_or_var, 'hello_world!'} - assert CF.cursor_context("hello/wor") == {:local_or_var, 'wor'} - assert CF.cursor_context("hello..wor") == {:local_or_var, 'wor'} - assert CF.cursor_context("hello::wor") == {:local_or_var, 'wor'} - assert CF.cursor_context("[hello_wo") == {:local_or_var, 'hello_wo'} - assert CF.cursor_context("'hello_wo") == {:local_or_var, 'hello_wo'} - assert CF.cursor_context("hellò_wó") == {:local_or_var, 'hellò_wó'} - assert CF.cursor_context("hello? world") == {:local_or_var, 'world'} - assert CF.cursor_context("hello! world") == {:local_or_var, 'world'} - assert CF.cursor_context("hello: world") == {:local_or_var, 'world'} - assert CF.cursor_context("__MODULE__") == {:local_or_var, '__MODULE__'} + assert CF.cursor_context("hello_wo") == {:local_or_var, ~c"hello_wo"} + assert CF.cursor_context("hello_world?") == {:local_or_var, ~c"hello_world?"} + assert CF.cursor_context("hello_world!") == {:local_or_var, ~c"hello_world!"} + assert CF.cursor_context("hello/wor") == {:local_or_var, ~c"wor"} + assert CF.cursor_context("hello..wor") == {:local_or_var, ~c"wor"} + assert CF.cursor_context("hello::wor") == {:local_or_var, ~c"wor"} + assert CF.cursor_context("[hello_wo") == {:local_or_var, ~c"hello_wo"} + assert CF.cursor_context("'hello_wo") == {:local_or_var, ~c"hello_wo"} + assert CF.cursor_context("hellò_wó") == {:local_or_var, ~c"hellò_wó"} + assert CF.cursor_context("hello? world") == {:local_or_var, ~c"world"} + assert CF.cursor_context("hello! world") == {:local_or_var, ~c"world"} + assert CF.cursor_context("hello: world") == {:local_or_var, ~c"world"} + assert CF.cursor_context("__MODULE__") == {:local_or_var, ~c"__MODULE__"} end test "dot" do - assert CF.cursor_context("hello.") == {:dot, {:var, 'hello'}, ''} - assert CF.cursor_context(":hello.") == {:dot, {:unquoted_atom, 'hello'}, ''} - assert CF.cursor_context("nested.map.") == {:dot, {:dot, {:var, 'nested'}, 'map'}, ''} - - assert CF.cursor_context("Hello.") == {:dot, {:alias, 'Hello'}, ''} - assert CF.cursor_context("Hello.World.") == {:dot, {:alias, 'Hello.World'}, ''} - assert CF.cursor_context("Hello.wor") == {:dot, {:alias, 'Hello'}, 'wor'} - assert CF.cursor_context("hello.wor") == {:dot, {:var, 'hello'}, 'wor'} - assert CF.cursor_context("Hello.++") == {:dot, {:alias, 'Hello'}, '++'} - assert CF.cursor_context(":hello.wor") == {:dot, {:unquoted_atom, 'hello'}, 'wor'} - assert CF.cursor_context(":hell@o.wor") == {:dot, {:unquoted_atom, 'hell@o'}, 'wor'} - assert CF.cursor_context(":he@ll@o.wor") == {:dot, {:unquoted_atom, 'he@ll@o'}, 'wor'} - assert CF.cursor_context(":hell@@o.wor") == {:dot, {:unquoted_atom, 'hell@@o'}, 'wor'} - assert CF.cursor_context("@hello.wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - - assert CF.cursor_context("@hello. wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello .wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello . wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - - assert CF.cursor_context("@hello.\nwor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello. \nwor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello.\n wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello.\r\nwor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello\n.wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello \n.wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context("@hello\n .wor") == {:dot, {:module_attribute, 'hello'}, 'wor'} + assert CF.cursor_context("hello.") == {:dot, {:var, ~c"hello"}, ~c""} + assert CF.cursor_context(":hello.") == {:dot, {:unquoted_atom, ~c"hello"}, ~c""} + assert CF.cursor_context("nested.map.") == {:dot, {:dot, {:var, ~c"nested"}, ~c"map"}, ~c""} + + assert CF.cursor_context("Hello.") == {:dot, {:alias, ~c"Hello"}, ~c""} + assert CF.cursor_context("Hello.World.") == {:dot, {:alias, ~c"Hello.World"}, ~c""} + assert CF.cursor_context("Hello.wor") == {:dot, {:alias, ~c"Hello"}, ~c"wor"} + assert CF.cursor_context("hello.wor") == {:dot, {:var, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("Hello.++") == {:dot, {:alias, ~c"Hello"}, ~c"++"} + assert CF.cursor_context(":hello.wor") == {:dot, {:unquoted_atom, ~c"hello"}, ~c"wor"} + assert CF.cursor_context(":hell@o.wor") == {:dot, {:unquoted_atom, ~c"hell@o"}, ~c"wor"} + assert CF.cursor_context(":he@ll@o.wor") == {:dot, {:unquoted_atom, ~c"he@ll@o"}, ~c"wor"} + assert CF.cursor_context(":hell@@o.wor") == {:dot, {:unquoted_atom, ~c"hell@@o"}, ~c"wor"} + assert CF.cursor_context("@hello.wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context("@hello. wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello .wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello . wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context("@hello.\nwor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello. \nwor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello.\n wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context("@hello.\r\nwor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context("@hello\n.wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello \n.wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + assert CF.cursor_context("@hello\n .wor") == {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} assert CF.cursor_context("@hello. # some comment\nwor") == - {:dot, {:module_attribute, 'hello'}, 'wor'} + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} assert CF.cursor_context("@hello. # some comment\n\nwor") == - {:dot, {:module_attribute, 'hello'}, 'wor'} + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} assert CF.cursor_context("@hello. # some comment\nsub\n.wor") == - {:dot, {:dot, {:module_attribute, 'hello'}, 'sub'}, 'wor'} + {:dot, {:dot, {:module_attribute, ~c"hello"}, ~c"sub"}, ~c"wor"} - assert CF.cursor_context('@hello.\nwor') == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context('@hello.\r\nwor') == {:dot, {:module_attribute, 'hello'}, 'wor'} - assert CF.cursor_context('@hello\n.wor') == {:dot, {:module_attribute, 'hello'}, 'wor'} + assert CF.cursor_context(~c"@hello.\nwor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} - assert CF.cursor_context('@hello. # some comment\nwor') == - {:dot, {:module_attribute, 'hello'}, 'wor'} + assert CF.cursor_context(~c"@hello.\r\nwor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} - assert CF.cursor_context('@hello. # some comment\n\nwor') == - {:dot, {:module_attribute, 'hello'}, 'wor'} + assert CF.cursor_context(~c"@hello\n.wor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} - assert CF.cursor_context('@hello. # some comment\nsub\n.wor') == - {:dot, {:dot, {:module_attribute, 'hello'}, 'sub'}, 'wor'} + assert CF.cursor_context(~c"@hello. # some comment\nwor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context(~c"@hello. # some comment\n\nwor") == + {:dot, {:module_attribute, ~c"hello"}, ~c"wor"} + + assert CF.cursor_context(~c"@hello. # some comment\nsub\n.wor") == + {:dot, {:dot, {:module_attribute, ~c"hello"}, ~c"sub"}, ~c"wor"} assert CF.cursor_context("nested.map.wor") == - {:dot, {:dot, {:var, 'nested'}, 'map'}, 'wor'} + {:dot, {:dot, {:var, ~c"nested"}, ~c"map"}, ~c"wor"} - assert CF.cursor_context("__MODULE__.") == {:dot, {:var, '__MODULE__'}, ''} + assert CF.cursor_context("__MODULE__.") == {:dot, {:var, ~c"__MODULE__"}, ~c""} assert CF.cursor_context("__MODULE__.Sub.") == - {:dot, {:alias, {:local_or_var, '__MODULE__'}, 'Sub'}, ''} + {:dot, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Sub"}, ~c""} assert CF.cursor_context("@hello.Sub.wor") == - {:dot, {:alias, {:module_attribute, 'hello'}, 'Sub'}, 'wor'} + {:dot, {:alias, {:module_attribute, ~c"hello"}, ~c"Sub"}, ~c"wor"} end test "local_arity" do - assert CF.cursor_context("hello/") == {:local_arity, 'hello'} + assert CF.cursor_context("hello/") == {:local_arity, ~c"hello"} end test "local_call" do - assert CF.cursor_context("hello\s") == {:local_call, 'hello'} - assert CF.cursor_context("hello\t") == {:local_call, 'hello'} - assert CF.cursor_context("hello(") == {:local_call, 'hello'} - assert CF.cursor_context("hello(\s") == {:local_call, 'hello'} - assert CF.cursor_context("hello(\t") == {:local_call, 'hello'} - assert CF.cursor_context("hello(\n") == {:local_call, 'hello'} - assert CF.cursor_context("hello(\r\n") == {:local_call, 'hello'} + assert CF.cursor_context("hello\s") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello\t") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello(") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello(\s") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello(\t") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello(\n") == {:local_call, ~c"hello"} + assert CF.cursor_context("hello(\r\n") == {:local_call, ~c"hello"} end test "dot_arity" do - assert CF.cursor_context("Foo.hello/") == {:dot_arity, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo.+/") == {:dot_arity, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo . hello /") == {:dot_arity, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo . + /") == {:dot_arity, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("foo.hello/") == {:dot_arity, {:var, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello/") == {:dot_arity, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context("@f.hello/") == {:dot_arity, {:module_attribute, 'f'}, 'hello'} + assert CF.cursor_context("Foo.hello/") == {:dot_arity, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo.+/") == {:dot_arity, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo . hello /") == {:dot_arity, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo . + /") == {:dot_arity, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("foo.hello/") == {:dot_arity, {:var, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello/") == + {:dot_arity, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context("@f.hello/") == {:dot_arity, {:module_attribute, ~c"f"}, ~c"hello"} end test "dot_call" do - assert CF.cursor_context("Foo.hello\s") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo.hello\t") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo.hello(") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo.hello(\s") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo.hello(\t") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo . hello (") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo . hello (\s") == {:dot_call, {:alias, 'Foo'}, 'hello'} - assert CF.cursor_context("Foo . hello (\t") == {:dot_call, {:alias, 'Foo'}, 'hello'} - - assert CF.cursor_context(":foo.hello\s") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello\t") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello(") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello(\s") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello(\t") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - assert CF.cursor_context(":foo.hello\s") == {:dot_call, {:unquoted_atom, 'foo'}, 'hello'} - - assert CF.cursor_context("foo.hello\s") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello\t") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello(") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello(\s") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello(\t") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello(\n") == {:dot_call, {:var, 'foo'}, 'hello'} - assert CF.cursor_context("foo.hello(\r\n") == {:dot_call, {:var, 'foo'}, 'hello'} - - assert CF.cursor_context("@f.hello\s") == {:dot_call, {:module_attribute, 'f'}, 'hello'} - assert CF.cursor_context("@f.hello\t") == {:dot_call, {:module_attribute, 'f'}, 'hello'} - assert CF.cursor_context("@f.hello(") == {:dot_call, {:module_attribute, 'f'}, 'hello'} - assert CF.cursor_context("@f.hello(\s") == {:dot_call, {:module_attribute, 'f'}, 'hello'} - assert CF.cursor_context("@f.hello(\t") == {:dot_call, {:module_attribute, 'f'}, 'hello'} - - assert CF.cursor_context("Foo.+\s") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo.+\t") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo.+(") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo.+(\s") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo.+(\t") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo . + (") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo . + (\s") == {:dot_call, {:alias, 'Foo'}, '+'} - assert CF.cursor_context("Foo . + (\t") == {:dot_call, {:alias, 'Foo'}, '+'} + assert CF.cursor_context("Foo.hello\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo.hello\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo.hello(") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo.hello(\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo.hello(\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo . hello (") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo . hello (\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + assert CF.cursor_context("Foo . hello (\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello\s") == + {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello\t") == + {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello(") == {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello(\s") == + {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello(\t") == + {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context(":foo.hello\s") == + {:dot_call, {:unquoted_atom, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context("foo.hello\s") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello\t") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello(") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello(\s") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello(\t") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello(\n") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + assert CF.cursor_context("foo.hello(\r\n") == {:dot_call, {:var, ~c"foo"}, ~c"hello"} + + assert CF.cursor_context("@f.hello\s") == {:dot_call, {:module_attribute, ~c"f"}, ~c"hello"} + assert CF.cursor_context("@f.hello\t") == {:dot_call, {:module_attribute, ~c"f"}, ~c"hello"} + assert CF.cursor_context("@f.hello(") == {:dot_call, {:module_attribute, ~c"f"}, ~c"hello"} + + assert CF.cursor_context("@f.hello(\s") == + {:dot_call, {:module_attribute, ~c"f"}, ~c"hello"} + + assert CF.cursor_context("@f.hello(\t") == + {:dot_call, {:module_attribute, ~c"f"}, ~c"hello"} + + assert CF.cursor_context("Foo.+\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo.+\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo.+(") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo.+(\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo.+(\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo . + (") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo . + (\s") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} + assert CF.cursor_context("Foo . + (\t") == {:dot_call, {:alias, ~c"Foo"}, ~c"+"} assert CF.cursor_context("__MODULE__.Foo.hello(") == - {:dot_call, {:alias, {:local_or_var, '__MODULE__'}, 'Foo'}, 'hello'} + {:dot_call, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo"}, ~c"hello"} assert CF.cursor_context("@foo.Foo.hello(") == - {:dot_call, {:alias, {:module_attribute, 'foo'}, 'Foo'}, 'hello'} + {:dot_call, {:alias, {:module_attribute, ~c"foo"}, ~c"Foo"}, ~c"hello"} end test "alias" do - assert CF.cursor_context("HelloWor") == {:alias, 'HelloWor'} - assert CF.cursor_context("Hello.Wor") == {:alias, 'Hello.Wor'} - assert CF.cursor_context("Hello.\nWor") == {:alias, 'Hello.Wor'} - assert CF.cursor_context("Hello.\r\nWor") == {:alias, 'Hello.Wor'} - assert CF.cursor_context("Hello . Wor") == {:alias, 'Hello.Wor'} - assert CF.cursor_context("Hello::Wor") == {:alias, 'Wor'} - assert CF.cursor_context("Hello..Wor") == {:alias, 'Wor'} - - assert CF.cursor_context("__MODULE__.Wor") == {:alias, {:local_or_var, '__MODULE__'}, 'Wor'} - - assert CF.cursor_context("@foo.Wor") == {:alias, {:module_attribute, 'foo'}, 'Wor'} + assert CF.cursor_context("HelloWor") == {:alias, ~c"HelloWor"} + assert CF.cursor_context("Hello.Wor") == {:alias, ~c"Hello.Wor"} + assert CF.cursor_context("Hello.\nWor") == {:alias, ~c"Hello.Wor"} + assert CF.cursor_context("Hello.\r\nWor") == {:alias, ~c"Hello.Wor"} + assert CF.cursor_context("Hello . Wor") == {:alias, ~c"Hello.Wor"} + assert CF.cursor_context("Hello::Wor") == {:alias, ~c"Wor"} + assert CF.cursor_context("Hello..Wor") == {:alias, ~c"Wor"} + + assert CF.cursor_context("__MODULE__.Wor") == + {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Wor"} + + assert CF.cursor_context("@foo.Wor") == {:alias, {:module_attribute, ~c"foo"}, ~c"Wor"} end test "structs" do - assert CF.cursor_context("%") == {:struct, ''} - assert CF.cursor_context(":%") == {:unquoted_atom, '%'} - assert CF.cursor_context("::%") == {:struct, ''} + assert CF.cursor_context("%") == {:struct, ~c""} + assert CF.cursor_context(":%") == {:unquoted_atom, ~c"%"} + assert CF.cursor_context("::%") == {:struct, ~c""} - assert CF.cursor_context("%HelloWor") == {:struct, 'HelloWor'} + assert CF.cursor_context("%HelloWor") == {:struct, ~c"HelloWor"} - assert CF.cursor_context("%Hello.") == {:struct, {:dot, {:alias, 'Hello'}, ''}} - assert CF.cursor_context("%Hello.nam") == {:struct, {:dot, {:alias, 'Hello'}, 'nam'}} - assert CF.cursor_context("%Hello.Wor") == {:struct, 'Hello.Wor'} - assert CF.cursor_context("% Hello . Wor") == {:struct, 'Hello.Wor'} + assert CF.cursor_context("%Hello.") == {:struct, {:dot, {:alias, ~c"Hello"}, ~c""}} + assert CF.cursor_context("%Hello.nam") == {:struct, {:dot, {:alias, ~c"Hello"}, ~c"nam"}} + assert CF.cursor_context("%Hello.Wor") == {:struct, ~c"Hello.Wor"} + assert CF.cursor_context("% Hello . Wor") == {:struct, ~c"Hello.Wor"} - assert CF.cursor_context("%__MODULE_") == {:struct, {:local_or_var, '__MODULE_'}} - assert CF.cursor_context("%__MODULE__") == {:struct, {:local_or_var, '__MODULE__'}} + assert CF.cursor_context("%__MODULE_") == {:struct, {:local_or_var, ~c"__MODULE_"}} + assert CF.cursor_context("%__MODULE__") == {:struct, {:local_or_var, ~c"__MODULE__"}} assert CF.cursor_context("%__MODULE__.") == - {:struct, {:dot, {:local_or_var, '__MODULE__'}, ''}} + {:struct, {:dot, {:local_or_var, ~c"__MODULE__"}, ~c""}} assert CF.cursor_context("%__MODULE__.Sub.") == - {:struct, {:dot, {:alias, {:local_or_var, '__MODULE__'}, 'Sub'}, ''}} + {:struct, {:dot, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Sub"}, ~c""}} assert CF.cursor_context("%__MODULE__.Wor") == - {:struct, {:alias, {:local_or_var, '__MODULE__'}, 'Wor'}} + {:struct, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Wor"}} assert CF.cursor_context("%@foo") == - {:struct, {:module_attribute, 'foo'}} + {:struct, {:module_attribute, ~c"foo"}} assert CF.cursor_context("%@foo.") == - {:struct, {:dot, {:module_attribute, 'foo'}, ''}} + {:struct, {:dot, {:module_attribute, ~c"foo"}, ~c""}} assert CF.cursor_context("%@foo.Wor") == - {:struct, {:alias, {:module_attribute, 'foo'}, 'Wor'}} + {:struct, {:alias, {:module_attribute, ~c"foo"}, ~c"Wor"}} end test "unquoted atom" do - assert CF.cursor_context(":") == {:unquoted_atom, ''} - assert CF.cursor_context(":HelloWor") == {:unquoted_atom, 'HelloWor'} - assert CF.cursor_context(":HelloWór") == {:unquoted_atom, 'HelloWór'} - assert CF.cursor_context(":hello_wor") == {:unquoted_atom, 'hello_wor'} - assert CF.cursor_context(":Óla_mundo") == {:unquoted_atom, 'Óla_mundo'} - assert CF.cursor_context(":Ol@_mundo") == {:unquoted_atom, 'Ol@_mundo'} - assert CF.cursor_context(":Ol@") == {:unquoted_atom, 'Ol@'} - assert CF.cursor_context("foo:hello_wor") == {:unquoted_atom, 'hello_wor'} + assert CF.cursor_context(":") == {:unquoted_atom, ~c""} + assert CF.cursor_context(":HelloWor") == {:unquoted_atom, ~c"HelloWor"} + assert CF.cursor_context(":HelloWór") == {:unquoted_atom, ~c"HelloWór"} + assert CF.cursor_context(":hello_wor") == {:unquoted_atom, ~c"hello_wor"} + assert CF.cursor_context(":Óla_mundo") == {:unquoted_atom, ~c"Óla_mundo"} + assert CF.cursor_context(":Ol@_mundo") == {:unquoted_atom, ~c"Ol@_mundo"} + assert CF.cursor_context(":Ol@") == {:unquoted_atom, ~c"Ol@"} + assert CF.cursor_context("foo:hello_wor") == {:unquoted_atom, ~c"hello_wor"} # Operators from atoms - assert CF.cursor_context(":+") == {:unquoted_atom, '+'} - assert CF.cursor_context(":or") == {:unquoted_atom, 'or'} - assert CF.cursor_context(":<") == {:unquoted_atom, '<'} - assert CF.cursor_context(":.") == {:unquoted_atom, '.'} - assert CF.cursor_context(":..") == {:unquoted_atom, '..'} - assert CF.cursor_context(":->") == {:unquoted_atom, '->'} - assert CF.cursor_context(":%") == {:unquoted_atom, '%'} + assert CF.cursor_context(":+") == {:unquoted_atom, ~c"+"} + assert CF.cursor_context(":or") == {:unquoted_atom, ~c"or"} + assert CF.cursor_context(":<") == {:unquoted_atom, ~c"<"} + assert CF.cursor_context(":.") == {:unquoted_atom, ~c"."} + assert CF.cursor_context(":..") == {:unquoted_atom, ~c".."} + assert CF.cursor_context(":->") == {:unquoted_atom, ~c"->"} + assert CF.cursor_context(":%") == {:unquoted_atom, ~c"%"} end test "operators" do - assert CF.cursor_context("+") == {:operator, '+'} - assert CF.cursor_context("++") == {:operator, '++'} - assert CF.cursor_context("!") == {:operator, '!'} - assert CF.cursor_context("<") == {:operator, '<'} - assert CF.cursor_context("<<<") == {:operator, '<<<'} - assert CF.cursor_context("..") == {:operator, '..'} - assert CF.cursor_context("<~") == {:operator, '<~'} - assert CF.cursor_context("=~") == {:operator, '=~'} - assert CF.cursor_context("<~>") == {:operator, '<~>'} - assert CF.cursor_context("::") == {:operator, '::'} - - assert CF.cursor_context("+ ") == {:operator_call, '+'} - assert CF.cursor_context("++ ") == {:operator_call, '++'} - assert CF.cursor_context("! ") == {:operator_call, '!'} - assert CF.cursor_context("< ") == {:operator_call, '<'} - assert CF.cursor_context("<<< ") == {:operator_call, '<<<'} - assert CF.cursor_context(".. ") == {:operator_call, '..'} - assert CF.cursor_context("<~ ") == {:operator_call, '<~'} - assert CF.cursor_context("=~ ") == {:operator_call, '=~'} - assert CF.cursor_context("<~> ") == {:operator_call, '<~>'} - assert CF.cursor_context(":: ") == {:operator_call, '::'} - - assert CF.cursor_context("+/") == {:operator_arity, '+'} - assert CF.cursor_context("++/") == {:operator_arity, '++'} - assert CF.cursor_context("!/") == {:operator_arity, '!'} - assert CF.cursor_context("/") == {:operator_arity, '<~>'} - assert CF.cursor_context("::/") == {:operator_arity, '::'} + assert CF.cursor_context("+") == {:operator, ~c"+"} + assert CF.cursor_context("++") == {:operator, ~c"++"} + assert CF.cursor_context("!") == {:operator, ~c"!"} + assert CF.cursor_context("<") == {:operator, ~c"<"} + assert CF.cursor_context("<<<") == {:operator, ~c"<<<"} + assert CF.cursor_context("..") == {:operator, ~c".."} + assert CF.cursor_context("<~") == {:operator, ~c"<~"} + assert CF.cursor_context("=~") == {:operator, ~c"=~"} + assert CF.cursor_context("<~>") == {:operator, ~c"<~>"} + assert CF.cursor_context("::") == {:operator, ~c"::"} + + assert CF.cursor_context("+ ") == {:operator_call, ~c"+"} + assert CF.cursor_context("++ ") == {:operator_call, ~c"++"} + assert CF.cursor_context("! ") == {:operator_call, ~c"!"} + assert CF.cursor_context("< ") == {:operator_call, ~c"<"} + assert CF.cursor_context("<<< ") == {:operator_call, ~c"<<<"} + assert CF.cursor_context(".. ") == {:operator_call, ~c".."} + assert CF.cursor_context("<~ ") == {:operator_call, ~c"<~"} + assert CF.cursor_context("=~ ") == {:operator_call, ~c"=~"} + assert CF.cursor_context("<~> ") == {:operator_call, ~c"<~>"} + assert CF.cursor_context(":: ") == {:operator_call, ~c"::"} + + assert CF.cursor_context("+/") == {:operator_arity, ~c"+"} + assert CF.cursor_context("++/") == {:operator_arity, ~c"++"} + assert CF.cursor_context("!/") == {:operator_arity, ~c"!"} + assert CF.cursor_context("/") == {:operator_arity, ~c"<~>"} + assert CF.cursor_context("::/") == {:operator_arity, ~c"::"} # Unknown operators altogether assert CF.cursor_context("***") == :none # Textual operators are shown as local_or_var UNLESS there is space - assert CF.cursor_context("when") == {:local_or_var, 'when'} - assert CF.cursor_context("when ") == {:operator_call, 'when'} + assert CF.cursor_context("when") == {:local_or_var, ~c"when"} + assert CF.cursor_context("when ") == {:operator_call, ~c"when"} assert CF.cursor_context("when.") == :none - assert CF.cursor_context("not") == {:local_or_var, 'not'} - assert CF.cursor_context("not ") == {:operator_call, 'not'} + assert CF.cursor_context("not") == {:local_or_var, ~c"not"} + assert CF.cursor_context("not ") == {:operator_call, ~c"not"} assert CF.cursor_context("not.") == :none end test "sigil" do - assert CF.cursor_context("~") == {:sigil, ''} + assert CF.cursor_context("~") == {:sigil, ~c""} assert CF.cursor_context("~ ") == :none - assert CF.cursor_context("~r") == {:sigil, 'r'} + assert CF.cursor_context("~r") == {:sigil, ~c"r"} assert CF.cursor_context("~r/") == :none assert CF.cursor_context("~r<") == :none - assert CF.cursor_context("~R") == {:sigil, 'R'} + assert CF.cursor_context("~R") == {:sigil, ~c"R"} assert CF.cursor_context("~R/") == :none assert CF.cursor_context("~R<") == :none @@ -307,8 +333,8 @@ defmodule CodeFragmentTest do end test "module attribute" do - assert CF.cursor_context("@") == {:module_attribute, ''} - assert CF.cursor_context("@hello_wo") == {:module_attribute, 'hello_wo'} + assert CF.cursor_context("@") == {:module_attribute, ~c""} + assert CF.cursor_context("@hello_wo") == {:module_attribute, ~c"hello_wo"} end test "none" do @@ -343,7 +369,7 @@ defmodule CodeFragmentTest do assert CF.cursor_context("@Hello") == :none assert CF.cursor_context("Hello(") == :none assert CF.cursor_context("Hello ") == :none - assert CF.cursor_context("hello.World") == {:alias, {:local_or_var, 'hello'}, 'World'} + assert CF.cursor_context("hello.World") == {:alias, {:local_or_var, ~c"hello"}, ~c"World"} # Identifier assert CF.cursor_context("foo@bar") == :none @@ -351,10 +377,17 @@ defmodule CodeFragmentTest do end test "newlines" do - assert CF.cursor_context("this+does-not*matter\nHello.") == {:dot, {:alias, 'Hello'}, ''} - assert CF.cursor_context('this+does-not*matter\nHello.') == {:dot, {:alias, 'Hello'}, ''} - assert CF.cursor_context("this+does-not*matter\r\nHello.") == {:dot, {:alias, 'Hello'}, ''} - assert CF.cursor_context('this+does-not*matter\r\nHello.') == {:dot, {:alias, 'Hello'}, ''} + assert CF.cursor_context("this+does-not*matter\nHello.") == + {:dot, {:alias, ~c"Hello"}, ~c""} + + assert CF.cursor_context(~c"this+does-not*matter\nHello.") == + {:dot, {:alias, ~c"Hello"}, ~c""} + + assert CF.cursor_context("this+does-not*matter\r\nHello.") == + {:dot, {:alias, ~c"Hello"}, ~c""} + + assert CF.cursor_context(~c"this+does-not*matter\r\nHello.") == + {:dot, {:alias, ~c"Hello"}, ~c""} end end @@ -362,19 +395,19 @@ defmodule CodeFragmentTest do test "newlines" do for i <- 1..8 do assert CF.surround_context("\n\nhello_wo\n", {3, i}) == %{ - context: {:local_or_var, 'hello_wo'}, + context: {:local_or_var, ~c"hello_wo"}, begin: {3, 1}, end: {3, 9} } assert CF.surround_context("\r\n\r\nhello_wo\r\n", {3, i}) == %{ - context: {:local_or_var, 'hello_wo'}, + context: {:local_or_var, ~c"hello_wo"}, begin: {3, 1}, end: {3, 9} } - assert CF.surround_context('\r\n\r\nhello_wo\r\n', {3, i}) == %{ - context: {:local_or_var, 'hello_wo'}, + assert CF.surround_context(~c"\r\n\r\nhello_wo\r\n", {3, i}) == %{ + context: {:local_or_var, ~c"hello_wo"}, begin: {3, 1}, end: {3, 9} } @@ -388,7 +421,7 @@ defmodule CodeFragmentTest do test "local_or_var" do for i <- 1..8 do assert CF.surround_context("hello_wo", {1, i}) == %{ - context: {:local_or_var, 'hello_wo'}, + context: {:local_or_var, ~c"hello_wo"}, begin: {1, 1}, end: {1, 9} } @@ -398,7 +431,7 @@ defmodule CodeFragmentTest do for i <- 2..9 do assert CF.surround_context(" hello_wo", {1, i}) == %{ - context: {:local_or_var, 'hello_wo'}, + context: {:local_or_var, ~c"hello_wo"}, begin: {1, 2}, end: {1, 10} } @@ -408,7 +441,7 @@ defmodule CodeFragmentTest do for i <- 1..6 do assert CF.surround_context("hello!", {1, i}) == %{ - context: {:local_or_var, 'hello!'}, + context: {:local_or_var, ~c"hello!"}, begin: {1, 1}, end: {1, 7} } @@ -418,7 +451,7 @@ defmodule CodeFragmentTest do for i <- 1..5 do assert CF.surround_context("안녕_세상", {1, i}) == %{ - context: {:local_or_var, '안녕_세상'}, + context: {:local_or_var, ~c"안녕_세상"}, begin: {1, 1}, end: {1, 6} } @@ -441,7 +474,7 @@ defmodule CodeFragmentTest do test "local call" do for i <- 1..8 do assert CF.surround_context("hello_wo(", {1, i}) == %{ - context: {:local_call, 'hello_wo'}, + context: {:local_call, ~c"hello_wo"}, begin: {1, 1}, end: {1, 9} } @@ -451,7 +484,7 @@ defmodule CodeFragmentTest do for i <- 1..8 do assert CF.surround_context("hello_wo (", {1, i}) == %{ - context: {:local_call, 'hello_wo'}, + context: {:local_call, ~c"hello_wo"}, begin: {1, 1}, end: {1, 9} } @@ -461,7 +494,7 @@ defmodule CodeFragmentTest do for i <- 1..6 do assert CF.surround_context("hello!(", {1, i}) == %{ - context: {:local_call, 'hello!'}, + context: {:local_call, ~c"hello!"}, begin: {1, 1}, end: {1, 7} } @@ -471,7 +504,7 @@ defmodule CodeFragmentTest do for i <- 1..5 do assert CF.surround_context("안녕_세상(", {1, i}) == %{ - context: {:local_call, '안녕_세상'}, + context: {:local_call, ~c"안녕_세상"}, begin: {1, 1}, end: {1, 6} } @@ -483,7 +516,7 @@ defmodule CodeFragmentTest do test "local arity" do for i <- 1..8 do assert CF.surround_context("hello_wo/", {1, i}) == %{ - context: {:local_arity, 'hello_wo'}, + context: {:local_arity, ~c"hello_wo"}, begin: {1, 1}, end: {1, 9} } @@ -493,7 +526,7 @@ defmodule CodeFragmentTest do for i <- 1..8 do assert CF.surround_context("hello_wo /", {1, i}) == %{ - context: {:local_arity, 'hello_wo'}, + context: {:local_arity, ~c"hello_wo"}, begin: {1, 1}, end: {1, 9} } @@ -503,7 +536,7 @@ defmodule CodeFragmentTest do for i <- 1..6 do assert CF.surround_context("hello!/", {1, i}) == %{ - context: {:local_arity, 'hello!'}, + context: {:local_arity, ~c"hello!"}, begin: {1, 1}, end: {1, 7} } @@ -513,7 +546,7 @@ defmodule CodeFragmentTest do for i <- 1..5 do assert CF.surround_context("안녕_세상/", {1, i}) == %{ - context: {:local_arity, '안녕_세상'}, + context: {:local_arity, ~c"안녕_세상"}, begin: {1, 1}, end: {1, 6} } @@ -535,7 +568,7 @@ defmodule CodeFragmentTest do test "dot" do for i <- 1..5 do assert CF.surround_context("Hello.wor", {1, i}) == %{ - context: {:alias, 'Hello'}, + context: {:alias, ~c"Hello"}, begin: {1, 1}, end: {1, 6} } @@ -543,7 +576,7 @@ defmodule CodeFragmentTest do for i <- 6..9 do assert CF.surround_context("Hello.wor", {1, i}) == %{ - context: {:dot, {:alias, 'Hello'}, 'wor'}, + context: {:dot, {:alias, ~c"Hello"}, ~c"wor"}, begin: {1, 1}, end: {1, 10} } @@ -553,7 +586,7 @@ defmodule CodeFragmentTest do for i <- 1..5 do assert CF.surround_context("Hello . wor", {1, i}) == %{ - context: {:alias, 'Hello'}, + context: {:alias, ~c"Hello"}, begin: {1, 1}, end: {1, 6} } @@ -561,7 +594,7 @@ defmodule CodeFragmentTest do for i <- 6..11 do assert CF.surround_context("Hello . wor", {1, i}) == %{ - context: {:dot, {:alias, 'Hello'}, 'wor'}, + context: {:dot, {:alias, ~c"Hello"}, ~c"wor"}, begin: {1, 1}, end: {1, 12} } @@ -571,7 +604,7 @@ defmodule CodeFragmentTest do for i <- 1..5 do assert CF.surround_context("hello.wor", {1, i}) == %{ - context: {:local_or_var, 'hello'}, + context: {:local_or_var, ~c"hello"}, begin: {1, 1}, end: {1, 6} } @@ -579,26 +612,26 @@ defmodule CodeFragmentTest do for i <- 6..9 do assert CF.surround_context("hello.wor", {1, i}) == %{ - context: {:dot, {:var, 'hello'}, 'wor'}, + context: {:dot, {:var, ~c"hello"}, ~c"wor"}, begin: {1, 1}, end: {1, 10} } end assert CF.surround_context("hello # comment\n .wor", {2, 4}) == %{ - context: {:dot, {:var, 'hello'}, 'wor'}, + context: {:dot, {:var, ~c"hello"}, ~c"wor"}, begin: {1, 1}, end: {2, 7} } assert CF.surround_context("123 + hello. # comment\n\n wor", {3, 4}) == %{ - context: {:dot, {:var, 'hello'}, 'wor'}, + context: {:dot, {:var, ~c"hello"}, ~c"wor"}, begin: {1, 7}, end: {3, 6} } assert CF.surround_context("hello. # comment\n\n # wor", {3, 5}) == %{ - context: {:local_or_var, 'wor'}, + context: {:local_or_var, ~c"wor"}, begin: {3, 4}, end: {3, 7} } @@ -607,7 +640,7 @@ defmodule CodeFragmentTest do test "alias" do for i <- 1..8 do assert CF.surround_context("HelloWor", {1, i}) == %{ - context: {:alias, 'HelloWor'}, + context: {:alias, ~c"HelloWor"}, begin: {1, 1}, end: {1, 9} } @@ -617,7 +650,7 @@ defmodule CodeFragmentTest do for i <- 2..9 do assert CF.surround_context(" HelloWor", {1, i}) == %{ - context: {:alias, 'HelloWor'}, + context: {:alias, ~c"HelloWor"}, begin: {1, 2}, end: {1, 10} } @@ -627,7 +660,7 @@ defmodule CodeFragmentTest do for i <- 1..9 do assert CF.surround_context("Hello.Wor", {1, i}) == %{ - context: {:alias, 'Hello.Wor'}, + context: {:alias, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 10} } @@ -637,7 +670,7 @@ defmodule CodeFragmentTest do for i <- 1..11 do assert CF.surround_context("Hello . Wor", {1, i}) == %{ - context: {:alias, 'Hello.Wor'}, + context: {:alias, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 12} } @@ -647,7 +680,7 @@ defmodule CodeFragmentTest do for i <- 1..15 do assert CF.surround_context("Foo . Bar . Baz", {1, i}) == %{ - context: {:alias, 'Foo.Bar.Baz'}, + context: {:alias, ~c"Foo.Bar.Baz"}, begin: {1, 1}, end: {1, 16} } @@ -655,7 +688,7 @@ defmodule CodeFragmentTest do for i <- 1..3 do assert CF.surround_context("Foo # dc\n. Bar .\n Baz", {i, 1}) == %{ - context: {:alias, 'Foo.Bar.Baz'}, + context: {:alias, ~c"Foo.Bar.Baz"}, begin: {1, 1}, end: {3, 5} } @@ -664,61 +697,61 @@ defmodule CodeFragmentTest do test "underscored special forms" do assert CF.surround_context("__MODULE__", {1, 1}) == %{ - context: {:local_or_var, '__MODULE__'}, + context: {:local_or_var, ~c"__MODULE__"}, begin: {1, 1}, end: {1, 11} } assert CF.surround_context("__MODULE__.Foo", {1, 12}) == %{ - context: {:alias, {:local_or_var, '__MODULE__'}, 'Foo'}, + context: {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo"}, begin: {1, 1}, end: {1, 15} } assert CF.surround_context("__MODULE__.Foo.Sub", {1, 16}) == %{ - context: {:alias, {:local_or_var, '__MODULE__'}, 'Foo.Sub'}, + context: {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo.Sub"}, begin: {1, 1}, end: {1, 19} } assert CF.surround_context("%__MODULE__{}", {1, 5}) == %{ - context: {:struct, {:local_or_var, '__MODULE__'}}, + context: {:struct, {:local_or_var, ~c"__MODULE__"}}, begin: {1, 1}, end: {1, 12} } assert CF.surround_context("%__MODULE__.Foo{}", {1, 13}) == %{ - context: {:struct, {:alias, {:local_or_var, '__MODULE__'}, 'Foo'}}, + context: {:struct, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo"}}, begin: {1, 1}, end: {1, 16} } assert CF.surround_context("%__MODULE__.Foo.Sub{}", {1, 17}) == %{ - context: {:struct, {:alias, {:local_or_var, '__MODULE__'}, 'Foo.Sub'}}, + context: {:struct, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo.Sub"}}, begin: {1, 1}, end: {1, 20} } assert CF.surround_context("__MODULE__.call()", {1, 13}) == %{ - context: {:dot, {:var, '__MODULE__'}, 'call'}, + context: {:dot, {:var, ~c"__MODULE__"}, ~c"call"}, begin: {1, 1}, end: {1, 16} } assert CF.surround_context("__MODULE__.Foo.call()", {1, 17}) == %{ - context: {:dot, {:alias, {:local_or_var, '__MODULE__'}, 'Foo'}, 'call'}, + context: {:dot, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo"}, ~c"call"}, begin: {1, 1}, end: {1, 20} } assert CF.surround_context("__MODULE__.Foo.Sub.call()", {1, 21}) == %{ - context: {:dot, {:alias, {:local_or_var, '__MODULE__'}, 'Foo.Sub'}, 'call'}, + context: {:dot, {:alias, {:local_or_var, ~c"__MODULE__"}, ~c"Foo.Sub"}, ~c"call"}, begin: {1, 1}, end: {1, 24} } assert CF.surround_context("__ENV__.module.call()", {1, 17}) == %{ - context: {:dot, {:dot, {:var, '__ENV__'}, 'module'}, 'call'}, + context: {:dot, {:dot, {:var, ~c"__ENV__"}, ~c"module"}, ~c"call"}, begin: {1, 1}, end: {1, 20} } @@ -726,49 +759,49 @@ defmodule CodeFragmentTest do test "attribute submodules" do assert CF.surround_context("@some.Foo", {1, 8}) == %{ - context: {:alias, {:module_attribute, 'some'}, 'Foo'}, + context: {:alias, {:module_attribute, ~c"some"}, ~c"Foo"}, begin: {1, 1}, end: {1, 10} } assert CF.surround_context("@some.Foo.Sub", {1, 12}) == %{ - context: {:alias, {:module_attribute, 'some'}, 'Foo.Sub'}, + context: {:alias, {:module_attribute, ~c"some"}, ~c"Foo.Sub"}, begin: {1, 1}, end: {1, 14} } assert CF.surround_context("%@some{}", {1, 5}) == %{ - context: {:struct, {:module_attribute, 'some'}}, + context: {:struct, {:module_attribute, ~c"some"}}, begin: {1, 1}, end: {1, 7} } assert CF.surround_context("%@some.Foo{}", {1, 10}) == %{ - context: {:struct, {:alias, {:module_attribute, 'some'}, 'Foo'}}, + context: {:struct, {:alias, {:module_attribute, ~c"some"}, ~c"Foo"}}, begin: {1, 1}, end: {1, 11} } assert CF.surround_context("%@some.Foo.Sub{}", {1, 14}) == %{ - context: {:struct, {:alias, {:module_attribute, 'some'}, 'Foo.Sub'}}, + context: {:struct, {:alias, {:module_attribute, ~c"some"}, ~c"Foo.Sub"}}, begin: {1, 1}, end: {1, 15} } assert CF.surround_context("@some.call()", {1, 8}) == %{ - context: {:dot, {:module_attribute, 'some'}, 'call'}, + context: {:dot, {:module_attribute, ~c"some"}, ~c"call"}, begin: {1, 1}, end: {1, 11} } assert CF.surround_context("@some.Foo.call()", {1, 12}) == %{ - context: {:dot, {:alias, {:module_attribute, 'some'}, 'Foo'}, 'call'}, + context: {:dot, {:alias, {:module_attribute, ~c"some"}, ~c"Foo"}, ~c"call"}, begin: {1, 1}, end: {1, 15} } assert CF.surround_context("@some.Foo.Sub.call()", {1, 16}) == %{ - context: {:dot, {:alias, {:module_attribute, 'some'}, 'Foo.Sub'}, 'call'}, + context: {:dot, {:alias, {:module_attribute, ~c"some"}, ~c"Foo.Sub"}, ~c"call"}, begin: {1, 1}, end: {1, 19} } @@ -782,39 +815,39 @@ defmodule CodeFragmentTest do assert CF.surround_context("::%Hello", {1, 2}) == :none assert CF.surround_context("::%Hello", {1, 3}) == %{ - context: {:struct, 'Hello'}, + context: {:struct, ~c"Hello"}, begin: {1, 3}, end: {1, 9} } assert CF.surround_context("::% Hello", {1, 3}) == %{ - context: {:struct, 'Hello'}, + context: {:struct, ~c"Hello"}, begin: {1, 3}, end: {1, 10} } assert CF.surround_context("::% Hello", {1, 4}) == %{ - context: {:struct, 'Hello'}, + context: {:struct, ~c"Hello"}, begin: {1, 3}, end: {1, 10} } # Alias assert CF.surround_context("%HelloWor", {1, 1}) == %{ - context: {:struct, 'HelloWor'}, + context: {:struct, ~c"HelloWor"}, begin: {1, 1}, end: {1, 10} } assert CF.surround_context("%HelloWor.some", {1, 12}) == %{ - context: {:struct, {:dot, {:alias, 'HelloWor'}, 'some'}}, + context: {:struct, {:dot, {:alias, ~c"HelloWor"}, ~c"some"}}, begin: {1, 1}, end: {1, 15} } for i <- 2..9 do assert CF.surround_context("%HelloWor", {1, i}) == %{ - context: {:struct, 'HelloWor'}, + context: {:struct, ~c"HelloWor"}, begin: {1, 1}, end: {1, 10} } @@ -824,14 +857,14 @@ defmodule CodeFragmentTest do # With dot assert CF.surround_context("%Hello.Wor", {1, 1}) == %{ - context: {:struct, 'Hello.Wor'}, + context: {:struct, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 11} } for i <- 2..10 do assert CF.surround_context("%Hello.Wor", {1, i}) == %{ - context: {:struct, 'Hello.Wor'}, + context: {:struct, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 11} } @@ -841,14 +874,14 @@ defmodule CodeFragmentTest do # With spaces assert CF.surround_context("% Hello . Wor", {1, 1}) == %{ - context: {:struct, 'Hello.Wor'}, + context: {:struct, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 14} } for i <- 2..13 do assert CF.surround_context("% Hello . Wor", {1, i}) == %{ - context: {:struct, 'Hello.Wor'}, + context: {:struct, ~c"Hello.Wor"}, begin: {1, 1}, end: {1, 14} } @@ -860,7 +893,7 @@ defmodule CodeFragmentTest do test "module attributes" do for i <- 1..10 do assert CF.surround_context("@hello_wor", {1, i}) == %{ - context: {:module_attribute, 'hello_wor'}, + context: {:module_attribute, ~c"hello_wor"}, begin: {1, 1}, end: {1, 11} } @@ -872,7 +905,7 @@ defmodule CodeFragmentTest do test "operators" do for i <- 2..4 do assert CF.surround_context("1<<<3", {1, i}) == %{ - context: {:operator, '<<<'}, + context: {:operator, ~c"<<<"}, begin: {1, 2}, end: {1, 5} } @@ -880,7 +913,7 @@ defmodule CodeFragmentTest do for i <- 3..5 do assert CF.surround_context("1 <<< 3", {1, i}) == %{ - context: {:operator, '<<<'}, + context: {:operator, ~c"<<<"}, begin: {1, 3}, end: {1, 6} } @@ -888,7 +921,7 @@ defmodule CodeFragmentTest do for i <- 2..3 do assert CF.surround_context("1::3", {1, i}) == %{ - context: {:operator, '::'}, + context: {:operator, ~c"::"}, begin: {1, 2}, end: {1, 4} } @@ -896,7 +929,7 @@ defmodule CodeFragmentTest do for i <- 3..4 do assert CF.surround_context("1 :: 3", {1, i}) == %{ - context: {:operator, '::'}, + context: {:operator, ~c"::"}, begin: {1, 3}, end: {1, 5} } @@ -904,7 +937,7 @@ defmodule CodeFragmentTest do for i <- 2..3 do assert CF.surround_context("x..y", {1, i}) == %{ - context: {:operator, '..'}, + context: {:operator, ~c".."}, begin: {1, 2}, end: {1, 4} } @@ -912,32 +945,32 @@ defmodule CodeFragmentTest do for i <- 3..4 do assert CF.surround_context("x .. y", {1, i}) == %{ - context: {:operator, '..'}, + context: {:operator, ~c".."}, begin: {1, 3}, end: {1, 5} } end assert CF.surround_context("@", {1, 1}) == %{ - context: {:operator, '@'}, + context: {:operator, ~c"@"}, begin: {1, 1}, end: {1, 2} } assert CF.surround_context("!", {1, 1}) == %{ - context: {:operator, '!'}, + context: {:operator, ~c"!"}, begin: {1, 1}, end: {1, 2} } assert CF.surround_context("!foo", {1, 1}) == %{ - context: {:operator, '!'}, + context: {:operator, ~c"!"}, begin: {1, 1}, end: {1, 2} } assert CF.surround_context("foo !bar", {1, 5}) == %{ - context: {:operator, '!'}, + context: {:operator, ~c"!"}, begin: {1, 5}, end: {1, 6} } @@ -950,13 +983,13 @@ defmodule CodeFragmentTest do assert CF.surround_context("~r/foo/", {1, 1}) == %{ begin: {1, 1}, - context: {:sigil, 'r'}, + context: {:sigil, ~c"r"}, end: {1, 3} } assert CF.surround_context("~r/foo/", {1, 2}) == %{ begin: {1, 1}, - context: {:sigil, 'r'}, + context: {:sigil, ~c"r"}, end: {1, 3} } @@ -964,13 +997,13 @@ defmodule CodeFragmentTest do assert CF.surround_context("~R", {1, 1}) == %{ begin: {1, 1}, - context: {:sigil, 'R'}, + context: {:sigil, ~c"R"}, end: {1, 3} } assert CF.surround_context("~R", {1, 2}) == %{ begin: {1, 1}, - context: {:sigil, 'R'}, + context: {:sigil, ~c"R"}, end: {1, 3} } @@ -980,7 +1013,7 @@ defmodule CodeFragmentTest do test "dot operator" do for i <- 4..7 do assert CF.surround_context("Foo.<<<", {1, i}) == %{ - context: {:dot, {:alias, 'Foo'}, '<<<'}, + context: {:dot, {:alias, ~c"Foo"}, ~c"<<<"}, begin: {1, 1}, end: {1, 8} } @@ -988,7 +1021,7 @@ defmodule CodeFragmentTest do for i <- 4..9 do assert CF.surround_context("Foo . <<<", {1, i}) == %{ - context: {:dot, {:alias, 'Foo'}, '<<<'}, + context: {:dot, {:alias, ~c"Foo"}, ~c"<<<"}, begin: {1, 1}, end: {1, 10} } @@ -996,7 +1029,7 @@ defmodule CodeFragmentTest do for i <- 4..6 do assert CF.surround_context("Foo.::", {1, i}) == %{ - context: {:dot, {:alias, 'Foo'}, '::'}, + context: {:dot, {:alias, ~c"Foo"}, ~c"::"}, begin: {1, 1}, end: {1, 7} } @@ -1004,7 +1037,7 @@ defmodule CodeFragmentTest do for i <- 4..8 do assert CF.surround_context("Foo . ::", {1, i}) == %{ - context: {:dot, {:alias, 'Foo'}, '::'}, + context: {:dot, {:alias, ~c"Foo"}, ~c"::"}, begin: {1, 1}, end: {1, 9} } @@ -1014,7 +1047,7 @@ defmodule CodeFragmentTest do test "unquoted atom" do for i <- 1..10 do assert CF.surround_context(":hello_wor", {1, i}) == %{ - context: {:unquoted_atom, 'hello_wor'}, + context: {:unquoted_atom, ~c"hello_wor"}, begin: {1, 1}, end: {1, 11} } @@ -1022,7 +1055,7 @@ defmodule CodeFragmentTest do for i <- 1..10 do assert CF.surround_context(":Hello@Wor", {1, i}) == %{ - context: {:unquoted_atom, 'Hello@Wor'}, + context: {:unquoted_atom, ~c"Hello@Wor"}, begin: {1, 1}, end: {1, 11} } diff --git a/lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs b/lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs index 6fc1d4bfe..e77ea69a6 100644 --- a/lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs +++ b/lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs @@ -514,7 +514,7 @@ defmodule Code.Normalizer.QuotedASTTest do test "charlist" do assert quoted_to_string(quote(do: [])) == "[]" - assert quoted_to_string(quote(do: 'abc')) == "'abc'" + assert quoted_to_string(quote(do: ~c"abc")) == ~S/~c"abc"/ end test "string" do @@ -585,32 +585,44 @@ defmodule Code.Normalizer.QuotedASTTest do end test "charlists with slash escapes" do - assert quoted_to_string(quote(do: '\a\b\e\n\r\t\v'), escape: false) == - ~s/'\a\b\e\n\r\t\v'/ + assert quoted_to_string(~c"\a\b\e\n\r\t\v", escape: false) == + ~s/~c"\a\b\e\n\r\t\v"/ - assert quoted_to_string(quote(do: '\a\b\e\n\r\t\v')) == - ~s/'\\a\\b\\e\\n\\r\\t\\v'/ + assert quoted_to_string(~c"\a\b\e\n\r\t\v") == + ~s/~c"\\a\\b\\e\\n\\r\\t\\v"/ - assert quoted_to_string({:__block__, [], ['\a\b\e\n\r\t\v']}, escape: false) == - ~s/'\a\b\e\n\r\t\v'/ + assert quoted_to_string({:__block__, [], [~c"\a\b\e\n\r\t\v"]}, escape: false) == + ~s/~c"\a\b\e\n\r\t\v"/ - assert quoted_to_string({:__block__, [], ['\a\b\e\n\r\t\v']}) == - ~s/'\\a\\b\\e\\n\\r\\t\\v'/ + assert quoted_to_string({:__block__, [], [~c"\a\b\e\n\r\t\v"]}) == + ~s/~c"\\a\\b\\e\\n\\r\\t\\v"/ end test "charlists with non printable characters" do - assert quoted_to_string(quote(do: '\x00\x01\x10'), escape: false) == ~S/[0, 1, 16]/ - assert quoted_to_string(quote(do: '\x00\x01\x10')) == ~S/[0, 1, 16]/ + assert quoted_to_string(~c"\x00\x01\x10", escape: false) == ~S/[0, 1, 16]/ + assert quoted_to_string(~c"\x00\x01\x10") == ~S/[0, 1, 16]/ end test "charlists with interpolations" do - assert quoted_to_string(quote(do: 'one #{2} three'), escape: false) == ~S/'one #{2} three'/ - assert quoted_to_string(quote(do: 'one #{2} three')) == ~S/'one #{2} three'/ + # using string_to_quoted to avoid the formatter fixing the charlists - assert quoted_to_string(quote(do: 'one\n\'#{2}\'\nthree'), escape: false) == - ~s['one\n\\'\#{2}\\'\nthree'] + assert Code.string_to_quoted!(~S/'one #{2} three'/) |> quoted_to_string(escape: false) == + ~S/~c"one #{2} three"/ - assert quoted_to_string(quote(do: 'one\n\'#{2}\'\nthree')) == ~S['one\n\'#{2}\'\nthree'] + assert Code.string_to_quoted!(~S/'one #{2} three'/) |> quoted_to_string() == + ~S/~c"one #{2} three"/ + + assert Code.string_to_quoted!(~S/'one\n\'#{2}\'\nthree'/) |> quoted_to_string(escape: false) == + ~s[~c"one\n'\#{2}'\nthree"] + + assert Code.string_to_quoted!(~S/'one\n\'#{2}\'\nthree'/) |> quoted_to_string() == + ~S[~c"one\n'#{2}'\nthree"] + + assert Code.string_to_quoted!(~S/'one\n"#{2}"\nthree'/) |> quoted_to_string(escape: false) == + ~s[~c"one\n\\"\#{2}\\"\nthree"] + + assert Code.string_to_quoted!(~S/'one\n"#{2}"\nthree'/) |> quoted_to_string() == + ~S[~c"one\n\"#{2}\"\nthree"] end test "atoms" do diff --git a/lib/elixir/test/elixir/config/provider_test.exs b/lib/elixir/test/elixir/config/provider_test.exs index 0c533227c..1c5c794d5 100644 --- a/lib/elixir/test/elixir/config/provider_test.exs +++ b/lib/elixir/test/elixir/config/provider_test.exs @@ -58,7 +58,7 @@ defmodule Config.ProviderTest do assert Provider.validate_config_path!({:system, "foo", "bar"}) == :ok assert_raise ArgumentError, fn -> Provider.validate_config_path!({:system, 1, 2}) end - assert_raise ArgumentError, fn -> Provider.validate_config_path!('baz') end + assert_raise ArgumentError, fn -> Provider.validate_config_path!(~c"baz") end end test "resolve!" do @@ -82,11 +82,11 @@ defmodule Config.ProviderTest do assert config[:elixir] == [config_provider_booted: {:booted, nil}] end - @tag sys_config: [my_app: [encoding: {:_μ, :"£", "£", '£'}]] + @tag sys_config: [my_app: [encoding: {:_μ, :"£", "£", ~c"£"}]] test "writes sys_config with encoding" do init_and_assert_boot() config = consult(@sys_config) - assert config[:my_app][:encoding] == {:_μ, :"£", "£", '£'} + assert config[:my_app][:encoding] == {:_μ, :"£", "£", ~c"£"} end @tag sys_config: [my_app: [key: :old_value, sys_key: :sys_value, extra_config: :old_value]] diff --git a/lib/elixir/test/elixir/exception_test.exs b/lib/elixir/test/elixir/exception_test.exs index 6c0676349..8826bec7b 100644 --- a/lib/elixir/test/elixir/exception_test.exs +++ b/lib/elixir/test/elixir/exception_test.exs @@ -104,35 +104,37 @@ defmodule ExceptionTest do end test "format_stacktrace_entry/1 with file and line" do - assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: 'file.ex', line: 10]}) == + assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: ~c"file.ex", line: 10]}) == "file.ex:10: Foo.bar()" - assert Exception.format_stacktrace_entry({Foo, :bar, [1, 2, 3], [file: 'file.ex', line: 10]}) == + assert Exception.format_stacktrace_entry( + {Foo, :bar, [1, 2, 3], [file: ~c"file.ex", line: 10]} + ) == "file.ex:10: Foo.bar(1, 2, 3)" - assert Exception.format_stacktrace_entry({Foo, :bar, 1, [file: 'file.ex', line: 10]}) == + assert Exception.format_stacktrace_entry({Foo, :bar, 1, [file: ~c"file.ex", line: 10]}) == "file.ex:10: Foo.bar/1" end test "format_stacktrace_entry/1 with file no line" do - assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: 'file.ex']}) == + assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: ~c"file.ex"]}) == "file.ex: Foo.bar()" - assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: 'file.ex', line: 0]}) == + assert Exception.format_stacktrace_entry({Foo, :bar, [], [file: ~c"file.ex", line: 0]}) == "file.ex: Foo.bar()" - assert Exception.format_stacktrace_entry({Foo, :bar, [1, 2, 3], [file: 'file.ex']}) == + assert Exception.format_stacktrace_entry({Foo, :bar, [1, 2, 3], [file: ~c"file.ex"]}) == "file.ex: Foo.bar(1, 2, 3)" - assert Exception.format_stacktrace_entry({Foo, :bar, 1, [file: 'file.ex']}) == + assert Exception.format_stacktrace_entry({Foo, :bar, 1, [file: ~c"file.ex"]}) == "file.ex: Foo.bar/1" end test "format_stacktrace_entry/1 with application" do - assert Exception.format_stacktrace_entry({Exception, :bar, [], [file: 'file.ex']}) == + assert Exception.format_stacktrace_entry({Exception, :bar, [], [file: ~c"file.ex"]}) == "(elixir #{System.version()}) file.ex: Exception.bar()" - assert Exception.format_stacktrace_entry({Exception, :bar, [], [file: 'file.ex', line: 10]}) == + assert Exception.format_stacktrace_entry({Exception, :bar, [], [file: ~c"file.ex", line: 10]}) == "(elixir #{System.version()}) file.ex:10: Exception.bar()" end diff --git a/lib/elixir/test/elixir/file_test.exs b/lib/elixir/test/elixir/file_test.exs index 807009228..62b5b0753 100644 --- a/lib/elixir/test/elixir/file_test.exs +++ b/lib/elixir/test/elixir/file_test.exs @@ -853,12 +853,12 @@ defmodule FileTest do end test "read with list" do - assert {:ok, "FOO\n"} = File.read(Path.expand('fixtures/file.txt', __DIR__)) - assert {:error, :enoent} = File.read(Path.expand('fixtures/missing.txt', __DIR__)) + assert {:ok, "FOO\n"} = File.read(Path.expand(~c"fixtures/file.txt", __DIR__)) + assert {:error, :enoent} = File.read(Path.expand(~c"fixtures/missing.txt", __DIR__)) end test "read with UTF-8" do - assert {:ok, "Русский\n日\n"} = File.read(Path.expand('fixtures/utf8.txt', __DIR__)) + assert {:ok, "Русский\n日\n"} = File.read(Path.expand(~c"fixtures/utf8.txt", __DIR__)) end test "read!" do @@ -875,7 +875,7 @@ defmodule FileTest do try do refute File.exists?(fixture) - assert File.write(fixture, 'test text') == :ok + assert File.write(fixture, ~c"test text") == :ok assert File.read(fixture) == {:ok, "test text"} after File.rm(fixture) @@ -915,7 +915,7 @@ defmodule FileTest do test "open file with charlist" do {:ok, file} = File.open(fixture_path("file.txt"), [:charlist]) - assert IO.gets(file, "") == 'FOO\n' + assert IO.gets(file, "") == ~c"FOO\n" assert File.close(file) == :ok end @@ -975,7 +975,7 @@ defmodule FileTest do end test "open a missing file" do - assert File.open('missing.txt') == {:error, :enoent} + assert File.open(~c"missing.txt") == {:error, :enoent} end test "open a file with function" do @@ -987,7 +987,7 @@ defmodule FileTest do message = "could not open \"missing.txt\": no such file or directory" assert_raise File.Error, message, fn -> - File.open!('missing.txt') + File.open!(~c"missing.txt") end end @@ -1166,7 +1166,7 @@ defmodule FileTest do end test "rm nonexistent file" do - assert File.rm('missing.txt') == {:error, :enoent} + assert File.rm(~c"missing.txt") == {:error, :enoent} end test "rm!" do diff --git a/lib/elixir/test/elixir/inspect_test.exs b/lib/elixir/test/elixir/inspect_test.exs index 7b3a8e3dc..632070355 100644 --- a/lib/elixir/test/elixir/inspect_test.exs +++ b/lib/elixir/test/elixir/inspect_test.exs @@ -294,13 +294,13 @@ defmodule Inspect.ListTest do end test "printable" do - assert inspect('abc') == "'abc'" + assert inspect(~c"abc") == "'abc'" end test "printable limit" do - assert inspect('hello world', printable_limit: 4) == ~s('hell' ++ ...) + assert inspect(~c"hello world", printable_limit: 4) == ~s('hell' ++ ...) # Non printable characters after the limit don't matter - assert inspect('hello world' ++ [0], printable_limit: 4) == ~s('hell' ++ ...) + assert inspect(~c"hello world" ++ [0], printable_limit: 4) == ~s('hell' ++ ...) # Non printable strings aren't affected by printable limit assert inspect([0, 1, 2, 3, 4], printable_limit: 3) == ~s([0, 1, 2, 3, 4]) end @@ -320,24 +320,24 @@ defmodule Inspect.ListTest do end test "opt infer" do - assert inspect('john' ++ [0] ++ 'doe', charlists: :infer) == + assert inspect(~c"john" ++ [0] ++ ~c"doe", charlists: :infer) == "[106, 111, 104, 110, 0, 100, 111, 101]" - assert inspect('john', charlists: :infer) == "'john'" + assert inspect(~c"john", charlists: :infer) == "'john'" assert inspect([0], charlists: :infer) == "[0]" end test "opt as strings" do - assert inspect('john' ++ [0] ++ 'doe', charlists: :as_charlists) == "'john\\0doe'" - assert inspect('john', charlists: :as_charlists) == "'john'" + assert inspect(~c"john" ++ [0] ++ ~c"doe", charlists: :as_charlists) == "'john\\0doe'" + assert inspect(~c"john", charlists: :as_charlists) == "'john'" assert inspect([0], charlists: :as_charlists) == "'\\0'" end test "opt as lists" do - assert inspect('john' ++ [0] ++ 'doe', charlists: :as_lists) == + assert inspect(~c"john" ++ [0] ++ ~c"doe", charlists: :as_lists) == "[106, 111, 104, 110, 0, 100, 111, 101]" - assert inspect('john', charlists: :as_lists) == "[106, 111, 104, 110]" + assert inspect(~c"john", charlists: :as_lists) == "[106, 111, 104, 110]" assert inspect([0], charlists: :as_lists) == "[0]" end @@ -361,7 +361,7 @@ defmodule Inspect.ListTest do end test "codepoints" do - assert inspect('é') == "[233]" + assert inspect(~c"é") == "[233]" end test "empty" do diff --git a/lib/elixir/test/elixir/integer_test.exs b/lib/elixir/test/elixir/integer_test.exs index 28c2eaf52..a435d4c55 100644 --- a/lib/elixir/test/elixir/integer_test.exs +++ b/lib/elixir/test/elixir/integer_test.exs @@ -158,7 +158,7 @@ defmodule IntegerTest do assert Integer.to_string(-42) == "-42" assert Integer.to_string(-0001) == "-1" - for n <- [42.0, :forty_two, '42', "42"] do + for n <- [42.0, :forty_two, ~c"42", "42"] do assert_raise ArgumentError, fn -> Integer.to_string(n) end @@ -171,7 +171,7 @@ defmodule IntegerTest do assert Integer.to_string(-42, 16) == "-2A" assert Integer.to_string(-042, 16) == "-2A" - for n <- [42.0, :forty_two, '42', "42"] do + for n <- [42.0, :forty_two, ~c"42", "42"] do assert_raise ArgumentError, fn -> Integer.to_string(n, 42) end @@ -191,28 +191,28 @@ defmodule IntegerTest do test "to_charlist/2" do module = Integer - assert Integer.to_charlist(42) == '42' - assert Integer.to_charlist(+42) == '42' - assert Integer.to_charlist(-42) == '-42' - assert Integer.to_charlist(-0001) == '-1' + assert Integer.to_charlist(42) == ~c"42" + assert Integer.to_charlist(+42) == ~c"42" + assert Integer.to_charlist(-42) == ~c"-42" + assert Integer.to_charlist(-0001) == ~c"-1" - for n <- [42.0, :forty_two, '42', "42"] do + for n <- [42.0, :forty_two, ~c"42", "42"] do assert_raise ArgumentError, fn -> Integer.to_charlist(n) end end - assert module.to_char_list(42) == '42' - assert module.to_char_list(42, 2) == '101010' + assert module.to_char_list(42) == ~c"42" + assert module.to_char_list(42, 2) == ~c"101010" - assert Integer.to_charlist(42, 2) == '101010' - assert Integer.to_charlist(42, 10) == '42' - assert Integer.to_charlist(42, 16) == '2A' - assert Integer.to_charlist(+42, 16) == '2A' - assert Integer.to_charlist(-42, 16) == '-2A' - assert Integer.to_charlist(-042, 16) == '-2A' + assert Integer.to_charlist(42, 2) == ~c"101010" + assert Integer.to_charlist(42, 10) == ~c"42" + assert Integer.to_charlist(42, 16) == ~c"2A" + assert Integer.to_charlist(+42, 16) == ~c"2A" + assert Integer.to_charlist(-42, 16) == ~c"-2A" + assert Integer.to_charlist(-042, 16) == ~c"-2A" - for n <- [42.0, :forty_two, '42', "42"] do + for n <- [42.0, :forty_two, ~c"42", "42"] do assert_raise ArgumentError, fn -> Integer.to_charlist(n, 42) end diff --git a/lib/elixir/test/elixir/io/ansi_test.exs b/lib/elixir/test/elixir/io/ansi_test.exs index 81d5bfc88..f8041d441 100644 --- a/lib/elixir/test/elixir/io/ansi_test.exs +++ b/lib/elixir/test/elixir/io/ansi_test.exs @@ -37,8 +37,8 @@ defmodule IO.ANSITest do end test "format charlist" do - assert IO.chardata_to_string(IO.ANSI.format('Hello, world!', true)) == "Hello, world!" - assert IO.chardata_to_string(IO.ANSI.format('Hello, world!', false)) == "Hello, world!" + assert IO.chardata_to_string(IO.ANSI.format(~c"Hello, world!", true)) == "Hello, world!" + assert IO.chardata_to_string(IO.ANSI.format(~c"Hello, world!", false)) == "Hello, world!" end test "format mixed list" do diff --git a/lib/elixir/test/elixir/io_test.exs b/lib/elixir/test/elixir/io_test.exs index 2244ed7cb..0b941c29e 100644 --- a/lib/elixir/test/elixir/io_test.exs +++ b/lib/elixir/test/elixir/io_test.exs @@ -8,47 +8,47 @@ defmodule IOTest do import ExUnit.CaptureIO test "read with count" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__), [:charlist]) - assert 'FOO' == IO.read(file, 3) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__), [:charlist]) + assert ~c"FOO" == IO.read(file, 3) assert File.close(file) == :ok end test "read with UTF-8 and binary" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8]) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__), [:utf8]) assert "Русский" == IO.read(file, 7) assert File.close(file) == :ok end test "read all charlist" do - {:ok, file} = File.open(Path.expand('fixtures/multiline_file.txt', __DIR__), [:charlist]) - assert 'this is the first line\nthis is the second line\n' == IO.read(file, :all) + {:ok, file} = File.open(Path.expand(~c"fixtures/multiline_file.txt", __DIR__), [:charlist]) + assert ~c"this is the first line\nthis is the second line\n" == IO.read(file, :all) assert File.close(file) == :ok end test "read empty file" do - {:ok, file} = File.open(Path.expand('fixtures/cp_mode', __DIR__), []) + {:ok, file} = File.open(Path.expand(~c"fixtures/cp_mode", __DIR__), []) assert IO.read(file, :all) == "" assert File.close(file) == :ok - {:ok, file} = File.open(Path.expand('fixtures/cp_mode', __DIR__), [:charlist]) - assert IO.read(file, :all) == '' + {:ok, file} = File.open(Path.expand(~c"fixtures/cp_mode", __DIR__), [:charlist]) + assert IO.read(file, :all) == ~c"" assert File.close(file) == :ok end test "binread" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__)) assert "Русский" == IO.binread(file, 14) assert File.close(file) == :ok end test "binread all" do - {:ok, file} = File.open(Path.expand('fixtures/file.bin', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.bin", __DIR__)) assert "LF\nCR\rCRLF\r\nLFCR\n\r" == IO.binread(file, :all) assert File.close(file) == :ok end test "getn" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__)) assert "F" == IO.getn(file, "") assert "O" == IO.getn(file, "") assert "O" == IO.getn(file, "") @@ -58,24 +58,24 @@ defmodule IOTest do end test "getn with count" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__), [:charlist]) - assert 'F' == IO.getn(file, "λ") - assert 'OO' == IO.getn(file, "", 2) - assert '\n' == IO.getn(file, "λ", 99) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__), [:charlist]) + assert ~c"F" == IO.getn(file, "λ") + assert ~c"OO" == IO.getn(file, "", 2) + assert ~c"\n" == IO.getn(file, "λ", 99) assert :eof == IO.getn(file, "λ", 1) assert File.close(file) == :ok end test "getn with eof" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__), [:charlist]) - assert 'F' == IO.getn(file, "λ") - assert 'OO\n' == IO.getn(file, "", :eof) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__), [:charlist]) + assert ~c"F" == IO.getn(file, "λ") + assert ~c"OO\n" == IO.getn(file, "", :eof) assert :eof == IO.getn(file, "", :eof) assert File.close(file) == :ok end test "getn with UTF-8 and binary" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8]) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__), [:utf8]) assert "Русский" == IO.getn(file, "", 7) assert "\n日\n" == IO.getn(file, "", :eof) assert :eof == IO.getn(file, "", :eof) @@ -83,70 +83,70 @@ defmodule IOTest do end test "gets" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__), [:charlist]) - assert 'FOO\n' == IO.gets(file, "") + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__), [:charlist]) + assert ~c"FOO\n" == IO.gets(file, "") assert :eof == IO.gets(file, "") assert File.close(file) == :ok end test "gets with UTF-8 and binary" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8]) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__), [:utf8]) assert "Русский\n" == IO.gets(file, "") assert "日\n" == IO.gets(file, "") assert File.close(file) == :ok end test "read with all" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__)) assert "FOO\n" == IO.read(file, :all) assert "" == IO.read(file, :all) assert File.close(file) == :ok end test "read with eof" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__)) assert "FOO\n" == IO.read(file, :eof) assert :eof == IO.read(file, :eof) assert File.close(file) == :ok end test "read with eof and UTF-8 and binary" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8]) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__), [:utf8]) assert "Русский\n日\n" == IO.read(file, :eof) assert :eof == IO.read(file, :eof) assert File.close(file) == :ok end test "readline" do - {:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/file.txt", __DIR__)) assert "FOO\n" == IO.read(file, :line) assert :eof == IO.read(file, :line) assert File.close(file) == :ok end test "readline with UTF-8 and binary" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8]) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__), [:utf8]) assert "Русский\n" == IO.read(file, :line) assert "日\n" == IO.read(file, :line) assert File.close(file) == :ok end test "binread with all" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__)) assert "Русский\n日\n" == IO.binread(file, :all) assert "" == IO.binread(file, :all) assert File.close(file) == :ok end test "binread with eof" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__)) assert "Русский\n日\n" == IO.binread(file, :eof) assert :eof == IO.binread(file, :eof) assert File.close(file) == :ok end test "binread with line" do - {:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__)) + {:ok, file} = File.open(Path.expand(~c"fixtures/utf8.txt", __DIR__)) assert "Русский\n" == IO.binread(file, :line) assert "日\n" == IO.binread(file, :line) assert File.close(file) == :ok @@ -154,7 +154,7 @@ defmodule IOTest do test "puts with chardata" do assert capture_io(fn -> IO.puts("hello") end) == "hello\n" - assert capture_io(fn -> IO.puts('hello') end) == "hello\n" + assert capture_io(fn -> IO.puts(~c"hello") end) == "hello\n" assert capture_io(fn -> IO.puts(:hello) end) == "hello\n" assert capture_io(fn -> IO.puts(13) end) == "13\n" end @@ -164,7 +164,7 @@ defmodule IOTest do assert capture_io(:stderr, fn -> IO.warn("hello") end) =~ "hello\n (ex_unit #{System.version()}) lib/ex_unit" - assert capture_io(:stderr, fn -> IO.warn('hello') end) =~ + assert capture_io(:stderr, fn -> IO.warn(~c"hello") end) =~ "hello\n (ex_unit #{System.version()}) lib/ex_unit" assert capture_io(:stderr, fn -> IO.warn(:hello) end) =~ @@ -179,7 +179,7 @@ defmodule IOTest do end test "with stacktrace" do - stacktrace = [{IEx.Evaluator, :eval, 4, [file: 'lib/iex/evaluator.ex', line: 108]}] + stacktrace = [{IEx.Evaluator, :eval, 4, [file: ~c"lib/iex/evaluator.ex", line: 108]}] assert capture_io(:stderr, fn -> IO.warn("hello", stacktrace) end) =~ """ hello @@ -238,21 +238,21 @@ defmodule IOTest do test "write with chardata" do assert capture_io(fn -> IO.write("hello") end) == "hello" - assert capture_io(fn -> IO.write('hello') end) == "hello" + assert capture_io(fn -> IO.write(~c"hello") end) == "hello" assert capture_io(fn -> IO.write(:hello) end) == "hello" assert capture_io(fn -> IO.write(13) end) == "13" end test "gets with chardata" do assert capture_io("foo\n", fn -> IO.gets("hello") end) == "hello" - assert capture_io("foo\n", fn -> IO.gets('hello') end) == "hello" + assert capture_io("foo\n", fn -> IO.gets(~c"hello") end) == "hello" assert capture_io("foo\n", fn -> IO.gets(:hello) end) == "hello" assert capture_io("foo\n", fn -> IO.gets(13) end) == "13" end test "getn with chardata" do assert capture_io("foo\n", fn -> IO.getn("hello", 3) end) == "hello" - assert capture_io("foo\n", fn -> IO.getn('hello', 3) end) == "hello" + assert capture_io("foo\n", fn -> IO.getn(~c"hello", 3) end) == "hello" assert capture_io("foo\n", fn -> IO.getn(:hello, 3) end) == "hello" assert capture_io("foo\n", fn -> IO.getn(13, 3) end) == "13" end diff --git a/lib/elixir/test/elixir/kernel/binary_test.exs b/lib/elixir/test/elixir/kernel/binary_test.exs index 132e2d393..f76bdb54f 100644 --- a/lib/elixir/test/elixir/kernel/binary_test.exs +++ b/lib/elixir/test/elixir/kernel/binary_test.exs @@ -202,7 +202,7 @@ defmodule Kernel.BinaryTest do Code.eval_string(~s[<<"foo"::float>>]) end - message = ~r"invalid literal 'foo'" + message = ~r"invalid literal ~c\"foo\"" assert_raise CompileError, message, fn -> Code.eval_string(~s[<<'foo'::binary>>]) @@ -250,7 +250,7 @@ defmodule Kernel.BinaryTest do foo = %{bar: 5} assert <<1::size(foo.bar)>> - assert <<1::size(length('abcd'))>> + assert <<1::size(length(~c"abcd"))>> assert <<255::size(hd(List.flatten([3])))>> end @@ -258,7 +258,7 @@ defmodule Kernel.BinaryTest do x = 8 assert <<1::size(x - 5)>> = <<1::3>> assert <<1::size(x - 5)-unit(8)>> = <<1::3*8>> - assert <<1::size(length('abcd'))>> = <<1::4>> + assert <<1::size(length(~c"abcd"))>> = <<1::4>> foo = %{bar: 5} assert <<1::size(foo.bar)>> = <<1::5>> diff --git a/lib/elixir/test/elixir/kernel/charlist_test.exs b/lib/elixir/test/elixir/kernel/charlist_test.exs index 796459fbe..92e4c0c6a 100644 --- a/lib/elixir/test/elixir/kernel/charlist_test.exs +++ b/lib/elixir/test/elixir/kernel/charlist_test.exs @@ -6,31 +6,31 @@ defmodule CharlistTest do test "heredoc" do assert __ENV__.line == 7 - assert 'foo\nbar\n' == ''' + assert ~c"foo\nbar\n" == ~c""" foo bar - ''' + """ assert __ENV__.line == 14 - assert 'foo\nbar \'\'\'\n' == ''' + assert ~c"foo\nbar '''\n" == ~c""" foo bar \'\'\' - ''' + """ end test "UTF-8" do - assert length(' ゆんゆん') == 5 + assert length(~c" ゆんゆん") == 5 end test "hex" do - assert '\x76' == 'v' - assert '\u00fF' == 'ÿ' - assert '\u{A}' == '\n' - assert '\u{e9}' == 'é' - assert '\u{10F}' == [271] - assert '\u{10FF}' == [4351] - assert '\u{10FFF}' == [69631] - assert '\u{10FFFF}' == [1_114_111] + assert ~c"\x76" == ~c"v" + assert ~c"\u00fF" == ~c"ÿ" + assert ~c"\u{A}" == ~c"\n" + assert ~c"\u{e9}" == ~c"é" + assert ~c"\u{10F}" == [271] + assert ~c"\u{10FF}" == [4351] + assert ~c"\u{10FFF}" == [69631] + assert ~c"\u{10FFFF}" == [1_114_111] end end diff --git a/lib/elixir/test/elixir/kernel/cli_test.exs b/lib/elixir/test/elixir/kernel/cli_test.exs index 650183400..fcb2cf8f5 100644 --- a/lib/elixir/test/elixir/kernel/cli_test.exs +++ b/lib/elixir/test/elixir/kernel/cli_test.exs @@ -62,44 +62,44 @@ defmodule Kernel.CLITest do end stderr_test "--help smoke test" do - output = elixir('--help') + output = elixir(~c"--help") assert output =~ "Usage: elixir" end test "--version smoke test" do - output = elixir('--version') + output = elixir(~c"--version") assert output =~ "Erlang/OTP #{System.otp_release()}" assert output =~ "Elixir #{System.version()}" - output = iex('--version') + output = iex(~c"--version") assert output =~ "Erlang/OTP #{System.otp_release()}" assert output =~ "IEx #{System.version()}" - output = elixir('--version -e "IO.puts(:test_output)"') + output = elixir(~c"--version -e \"IO.puts(:test_output)\"") assert output =~ "Erlang/OTP #{System.otp_release()}" assert output =~ "Elixir #{System.version()}" assert output =~ "Standalone options can't be combined with other options" end test "--short-version smoke test" do - output = elixir('--short-version') + output = elixir(~c"--short-version") assert output =~ System.version() refute output =~ "Erlang" end stderr_test "combining --help results in error" do - output = elixir('-e 1 --help') + output = elixir(~c"-e 1 --help") assert output =~ "--help : Standalone options can't be combined with other options" - output = elixir('--help -e 1') + output = elixir(~c"--help -e 1") assert output =~ "--help : Standalone options can't be combined with other options" end stderr_test "combining --short-version results in error" do - output = elixir('--short-version -e 1') + output = elixir(~c"--short-version -e 1") assert output =~ "--short-version : Standalone options can't be combined with other options" - output = elixir('-e 1 --short-version') + output = elixir(~c"-e 1 --short-version") assert output =~ "--short-version : Standalone options can't be combined with other options" end @@ -107,34 +107,39 @@ defmodule Kernel.CLITest do root = fixture_path("../../..") |> to_charlist args = - '-pa "#{root}/*" -pz "#{root}/lib/*" -e "IO.inspect(:code.get_path(), limit: :infinity)"' + ~c"-pa \"#{root}/*\" -pz \"#{root}/lib/*\" -e \"IO.inspect(:code.get_path(), limit: :infinity)\"" list = elixir(args) {path, _} = Code.eval_string(list, []) # pa - assert to_charlist(Path.expand('ebin', root)) in path - assert to_charlist(Path.expand('lib', root)) in path - assert to_charlist(Path.expand('src', root)) in path + assert to_charlist(Path.expand(~c"ebin", root)) in path + assert to_charlist(Path.expand(~c"lib", root)) in path + assert to_charlist(Path.expand(~c"src", root)) in path # pz - assert to_charlist(Path.expand('lib/list', root)) in path + assert to_charlist(Path.expand(~c"lib/list", root)) in path end stderr_test "properly formats errors" do - assert String.starts_with?(elixir('-e ":erlang.throw 1"'), "** (throw) 1") - assert String.starts_with?(elixir('-e ":erlang.error 1"'), "** (ErlangError) Erlang error: 1") - assert String.starts_with?(elixir('-e "1 +"'), "** (TokenMissingError)") + assert String.starts_with?(elixir(~c"-e \":erlang.throw 1\""), "** (throw) 1") - assert elixir('-e "Task.async(fn -> raise ArgumentError end) |> Task.await"') =~ + assert String.starts_with?( + elixir(~c"-e \":erlang.error 1\""), + "** (ErlangError) Erlang error: 1" + ) + + assert String.starts_with?(elixir(~c"-e \"1 +\""), "** (TokenMissingError)") + + assert elixir(~c"-e \"Task.async(fn -> raise ArgumentError end) |> Task.await\"") =~ "an exception was raised:\n ** (ArgumentError) argument error" - assert elixir('-e "IO.puts(Process.flag(:trap_exit, false)); exit({:shutdown, 1})"') == + assert elixir(~c"-e \"IO.puts(Process.flag(:trap_exit, false)); exit({:shutdown, 1})\"") == "false\n" end stderr_test "blames exceptions" do - error = elixir('-e "Access.fetch :foo, :bar"') + error = elixir(~c"-e \"Access.fetch :foo, :bar\"") assert error =~ "** (FunctionClauseError) no function clause matching in Access.fetch/2" assert error =~ "The following arguments were given to Access.fetch/2" assert error =~ ":foo" @@ -150,7 +155,7 @@ defmodule Kernel.CLI.RPCTest do defp rpc_eval(command) do node = "cli-rpc#{System.unique_integer()}@127.0.0.1" - elixir('--name #{node} --rpc-eval #{node} "#{command}"') + elixir(~c"--name #{node} --rpc-eval #{node} \"#{command}\"") end test "invokes command on remote node" do @@ -159,14 +164,14 @@ defmodule Kernel.CLI.RPCTest do test "invokes command on remote node without host and --name after --rpc-eval" do node = "cli-rpc#{System.unique_integer()}" - assert elixir('--rpc-eval #{node} "IO.puts :ok" --name #{node}@127.0.0.1 ') == "ok\n" + assert elixir(~c"--rpc-eval #{node} \"IO.puts :ok\" --name #{node}@127.0.0.1 ") == "ok\n" end test "can be invoked multiple times" do node = "cli-rpc#{System.unique_integer()}" assert elixir( - '--name #{node}@127.0.0.1 --rpc-eval #{node} "IO.puts :foo" --rpc-eval #{node} "IO.puts :bar"' + ~c"--name #{node}@127.0.0.1 --rpc-eval #{node} \"IO.puts :foo\" --rpc-eval #{node} \"IO.puts :bar\"" ) == "foo\nbar\n" end @@ -175,10 +180,10 @@ defmodule Kernel.CLI.RPCTest do test "fails on wrong arguments" do node = "cli-rpc#{System.unique_integer()}" - assert elixir('--name #{node}@127.0.0.1 --rpc-eval') == + assert elixir(~c"--name #{node}@127.0.0.1 --rpc-eval") == "--rpc-eval : wrong number of arguments\n" - assert elixir('--name #{node}@127.0.0.1 --rpc-eval #{node}') == + assert elixir(~c"--name #{node}@127.0.0.1 --rpc-eval #{node}") == "--rpc-eval : wrong number of arguments\n" end @@ -217,7 +222,7 @@ defmodule Kernel.CLI.CompileTest do end test "compiles code", context do - assert elixirc('#{context.fixture} -o #{context.tmp_dir}') == "" + assert elixirc(~c"#{context.fixture} -o #{context.tmp_dir}") == "" assert File.regular?(context.beam_file_path) # Assert that the module is loaded into memory with the proper destination for the BEAM file. @@ -234,7 +239,7 @@ defmodule Kernel.CLI.CompileTest do try do fixture = String.replace(context.fixture, "/", "\\") tmp_dir_path = String.replace(context.tmp_dir, "/", "\\") - assert elixirc('#{fixture} -o #{tmp_dir_path}') == "" + assert elixirc(~c"#{fixture} -o #{tmp_dir_path}") == "" assert File.regular?(context[:beam_file_path]) # Assert that the module is loaded into memory with the proper destination for the BEAM file. @@ -250,14 +255,14 @@ defmodule Kernel.CLI.CompileTest do end stderr_test "fails on missing patterns", context do - output = elixirc('#{context.fixture} non_existing.ex -o #{context.tmp_dir}') + output = elixirc(~c"#{context.fixture} non_existing.ex -o #{context.tmp_dir}") assert output =~ "non_existing.ex" refute output =~ "compile_sample.ex" refute File.exists?(context.beam_file_path) end stderr_test "fails on missing write access to .beam file", context do - compilation_args = '#{context.fixture} -o #{context.tmp_dir}' + compilation_args = ~c"#{context.fixture} -o #{context.tmp_dir}" assert elixirc(compilation_args) == "" assert File.regular?(context.beam_file_path) diff --git a/lib/elixir/test/elixir/kernel/comprehension_test.exs b/lib/elixir/test/elixir/kernel/comprehension_test.exs index 7c1ebf761..ad4050723 100644 --- a/lib/elixir/test/elixir/kernel/comprehension_test.exs +++ b/lib/elixir/test/elixir/kernel/comprehension_test.exs @@ -263,7 +263,7 @@ defmodule Kernel.ComprehensionTest do acc -> Map.update(acc, x, [y], &[y | &1]) end - assert acc == %{1 => 'olleh', 3 => 'olleh'} + assert acc == %{1 => ~c"olleh", 3 => ~c"olleh"} end test "for comprehensions with matched reduce" do @@ -371,7 +371,7 @@ defmodule Kernel.ComprehensionTest do acc -> Map.update(acc, x, [y], &[y | &1]) end - assert acc == %{1 => 'olleh', 3 => 'olleh'} + assert acc == %{1 => ~c"olleh", 3 => ~c"olleh"} end ## Binary generators (inlined by the compiler) @@ -496,6 +496,6 @@ defmodule Kernel.ComprehensionTest do acc -> Map.update(acc, x, [y], &[y | &1]) end - assert acc == %{1 => 'olleh', 3 => 'olleh'} + assert acc == %{1 => ~c"olleh", 3 => ~c"olleh"} end end diff --git a/lib/elixir/test/elixir/kernel/errors_test.exs b/lib/elixir/test/elixir/kernel/errors_test.exs index 1827e4f9e..c8a343eec 100644 --- a/lib/elixir/test/elixir/kernel/errors_test.exs +++ b/lib/elixir/test/elixir/kernel/errors_test.exs @@ -14,62 +14,62 @@ defmodule Kernel.ErrorsTest do test "no default arguments in fn" do assert_eval_raise CompileError, "nofile:1: anonymous functions cannot have optional arguments", - 'fn x \\\\ 1 -> x end' + ~c"fn x \\\\ 1 -> x end" assert_eval_raise CompileError, "nofile:1: anonymous functions cannot have optional arguments", - 'fn x, y \\\\ 1 -> x + y end' + ~c"fn x, y \\\\ 1 -> x + y end" end test "invalid __CALLER__" do assert_eval_raise CompileError, "nofile:1: __CALLER__ is available only inside defmacro and defmacrop", - 'defmodule Sample do def hello do __CALLER__ end end' + ~c"defmodule Sample do def hello do __CALLER__ end end" end test "invalid __STACKTRACE__" do assert_eval_raise CompileError, "nofile:1: __STACKTRACE__ is available only inside catch and rescue clauses of try expressions", - 'defmodule Sample do def hello do __STACKTRACE__ end end' + ~c"defmodule Sample do def hello do __STACKTRACE__ end end" assert_eval_raise CompileError, "nofile:1: __STACKTRACE__ is available only inside catch and rescue clauses of try expressions", - 'defmodule Sample do try do raise "oops" rescue _ -> def hello do __STACKTRACE__ end end end' + ~c"defmodule Sample do try do raise \"oops\" rescue _ -> def hello do __STACKTRACE__ end end end" end test "undefined function" do assert_eval_raise CompileError, "hello.ex:4: undefined function bar/0 (expected Kernel.ErrorsTest.BadForm to define such a function or for it to be imported, but none are available)", - ''' + ~c""" defmodule Kernel.ErrorsTest.BadForm do @file "hello.ex" def foo do bar() end end - ''' + """ assert_eval_raise CompileError, "nofile:2: undefined function module_info/0 (this function is auto-generated by the compiler and must always be called as a remote, as in __MODULE__.module_info/0)", - ''' + ~c""" defmodule Kernel.ErrorsTest.Info do def foo, do: module_info() end - ''' + """ assert_eval_raise CompileError, "nofile:3: undefined function behaviour_info/1 (this function is auto-generated by the compiler and must always be called as a remote, as in __MODULE__.behaviour_info/1)", - ''' + ~c""" defmodule Kernel.ErrorsTest.BehaviourInfo do @callback dummy() :: :ok def foo, do: behaviour_info(:callbacks) end - ''' + """ assert capture_io(:stderr, fn -> assert_eval_raise CompileError, "nofile:3: undefined function bar/1 (expected Kernel.ErrorsTest.BadForm to define such a function or for it to be imported, but none are available)", - ''' + ~c""" defmodule Kernel.ErrorsTest.BadForm do def foo do bar( @@ -77,12 +77,12 @@ defmodule Kernel.ErrorsTest do ) end end - ''' + """ end) =~ "undefined function baz/2" assert_eval_raise CompileError, "nofile:8: undefined function baz/0 (expected Sample to define such a function or for it to be imported, but none are available)", - ''' + ~c""" defmodule Sample do def foo do bar() @@ -93,27 +93,27 @@ defmodule Kernel.ErrorsTest do baz() end end - ''' + """ end test "undefined non-local function" do assert_eval_raise CompileError, "nofile:1: undefined function call/2 (there is no such import)", - 'call foo, do: :foo' + ~c"call foo, do: :foo" end test "function without definition" do assert_eval_raise CompileError, "nofile:2: implementation not provided for predefined def foo/0", - ''' + ~c""" defmodule Kernel.ErrorsTest.FunctionWithoutDefition do def foo end - ''' + """ assert_eval_raise CompileError, "nofile:10: implementation not provided for predefined def example/2", - ''' + ~c""" defmodule Kernel.ErrorsTest.FunctionTemplate do defmacro __using__(_) do quote do @@ -125,31 +125,31 @@ defmodule Kernel.ErrorsTest do defmodule Kernel.ErrorsTest.UseFunctionTemplate do use Kernel.ErrorsTest.FunctionTemplate end - ''' + """ end test "guard without definition" do assert_eval_raise CompileError, "nofile:2: implementation not provided for predefined defmacro foo/1", - ''' + ~c""" defmodule Kernel.ErrorsTest.GuardWithoutDefition do defguard foo(bar) end - ''' + """ end test "literal on map and struct" do assert_eval_raise CompileError, "nofile:1: expected key-value pairs in a map, got: put_in(foo.bar.baz, nil)", - 'foo = 1; %{put_in(foo.bar.baz, nil), foo}' + ~c"foo = 1; %{put_in(foo.bar.baz, nil), foo}" end test "struct fields on defstruct" do - assert_eval_raise ArgumentError, "struct field names must be atoms, got: 1", ''' + assert_eval_raise ArgumentError, "struct field names must be atoms, got: 1", ~c""" defmodule Kernel.ErrorsTest.StructFieldsOnDefstruct do defstruct [1, 2, 3] end - ''' + """ end test "struct access on body" do @@ -157,23 +157,23 @@ defmodule Kernel.ErrorsTest do "nofile:3: cannot access struct Kernel.ErrorsTest.StructAccessOnBody, " <> "the struct was not yet defined or the struct " <> "is being accessed in the same context that defines it", - ''' + ~c""" defmodule Kernel.ErrorsTest.StructAccessOnBody do defstruct %{name: "Brasilia"} %Kernel.ErrorsTest.StructAccessOnBody{} end - ''' + """ end describe "struct errors" do test "bad errors" do assert_eval_raise CompileError, ~r"nofile:1: BadStruct.__struct__/1 is undefined, cannot expand struct BadStruct", - '%BadStruct{}' + ~c"%BadStruct{}" assert_eval_raise CompileError, ~r"nofile:1: BadStruct.__struct__/0 is undefined, cannot expand struct BadStruct", - '%BadStruct{} = %{}' + ~c"%BadStruct{} = %{}" bad_struct_type_error = ~r"expected Kernel.ErrorsTest.BadStructType.__struct__/(0|1) to return a map.*, got: :invalid" @@ -189,11 +189,11 @@ defmodule Kernel.ErrorsTest do assert_eval_raise CompileError, bad_struct_type_error, - '%#{BadStructType}{} = %{}' + ~c"%#{BadStructType}{} = %{}" assert_eval_raise CompileError, bad_struct_type_error, - '%#{BadStructType}{}' + ~c"%#{BadStructType}{}" assert_raise ArgumentError, bad_struct_type_error, fn -> struct(BadStructType) @@ -219,11 +219,11 @@ defmodule Kernel.ErrorsTest do assert_eval_raise CompileError, missing_struct_key_error, - '%#{MissingStructKey}{} = %{}' + ~c"%#{MissingStructKey}{} = %{}" assert_eval_raise CompileError, missing_struct_key_error, - '%#{MissingStructKey}{}' + ~c"%#{MissingStructKey}{}" assert_raise ArgumentError, missing_struct_key_error, fn -> struct(MissingStructKey) @@ -247,11 +247,11 @@ defmodule Kernel.ErrorsTest do assert_eval_raise CompileError, invalid_struct_key_error, - '%#{InvalidStructKey}{} = %{}' + ~c"%#{InvalidStructKey}{} = %{}" assert_eval_raise CompileError, invalid_struct_key_error, - '%#{InvalidStructKey}{}' + ~c"%#{InvalidStructKey}{}" assert_raise ArgumentError, invalid_struct_key_error, fn -> struct(InvalidStructKey) @@ -277,11 +277,11 @@ defmodule Kernel.ErrorsTest do assert_eval_raise CompileError, invalid_struct_name_error, - '%#{InvalidStructName}{} = %{}' + ~c"%#{InvalidStructName}{} = %{}" assert_eval_raise CompileError, invalid_struct_name_error, - '%#{InvalidStructName}{}' + ~c"%#{InvalidStructName}{}" assert_raise ArgumentError, invalid_struct_name_error, fn -> struct(InvalidStructName) @@ -299,11 +299,11 @@ defmodule Kernel.ErrorsTest do assert_eval_raise KeyError, "key :age not found", - '%#{GoodStruct}{age: 27}' + ~c"%#{GoodStruct}{age: 27}" assert_eval_raise CompileError, "nofile:1: unknown key :age for struct Kernel.ErrorsTest.GoodStruct", - '%#{GoodStruct}{age: 27} = %{}' + ~c"%#{GoodStruct}{age: 27} = %{}" end test "enforce @enforce_keys" do @@ -324,14 +324,14 @@ defmodule Kernel.ErrorsTest do end test "invalid unquote" do - assert_eval_raise CompileError, "nofile:1: unquote called outside quote", 'unquote 1' + assert_eval_raise CompileError, "nofile:1: unquote called outside quote", ~c"unquote 1" end test "invalid unquote splicing in one-liners" do assert_eval_raise ArgumentError, "unquote_splicing only works inside arguments and block contexts, " <> "wrap it in parens if you want it to work with one-liners", - ''' + ~c""" defmodule Kernel.ErrorsTest.InvalidUnquoteSplicingInOneliners do defmacro oneliner2 do quote do: unquote_splicing 1 @@ -341,7 +341,7 @@ defmodule Kernel.ErrorsTest do oneliner2 end end - ''' + """ end test "invalid attribute" do @@ -384,17 +384,19 @@ defmodule Kernel.ErrorsTest do test "invalid case clauses" do assert_eval_raise CompileError, "nofile:1: expected one argument for :do clauses (->) in \"case\"", - 'case nil do 0, z when not is_nil(z) -> z end' + ~c"case nil do 0, z when not is_nil(z) -> z end" end test "invalid fn args" do assert_eval_raise TokenMissingError, ~r/nofile:1:5: missing terminator: end \(for "fn" starting at line 1\).*/, - 'fn 1' + ~c"fn 1" end test "invalid escape" do - assert_eval_raise TokenMissingError, ~r/nofile:1:3: invalid escape \\ at end of file/, '1 \\' + assert_eval_raise TokenMissingError, + ~r/nofile:1:3: invalid escape \\ at end of file/, + ~c"1 \\" end test "show snippet on missing tokens" do @@ -403,31 +405,31 @@ defmodule Kernel.ErrorsTest do " |\n" <> " 1 | defmodule ShowSnippet do\n" <> " | ^", - 'defmodule ShowSnippet do' + ~c"defmodule ShowSnippet do" end test "don't show snippet when error line is empty" do assert_eval_raise TokenMissingError, "nofile:3:1: missing terminator: end (for \"do\" starting at line 1)", - 'defmodule ShowSnippet do\n\n' + ~c"defmodule ShowSnippet do\n\n" end test "function local conflict" do assert_eval_raise CompileError, "nofile:3: imported Kernel.&&/2 conflicts with local function", - ''' + ~c""" defmodule Kernel.ErrorsTest.FunctionLocalConflict do def other, do: 1 && 2 def _ && _, do: :error end - ''' + """ end test "macro local conflict" do assert_eval_raise CompileError, "nofile:6: call to local macro &&/2 conflicts with imported Kernel.&&/2, " <> "please rename the local macro or remove the conflicting import", - ''' + ~c""" defmodule Kernel.ErrorsTest.MacroLocalConflict do def hello, do: 1 || 2 defmacro _ || _, do: :ok @@ -435,65 +437,65 @@ defmodule Kernel.ErrorsTest do defmacro _ && _, do: :error def world, do: 1 && 2 end - ''' + """ end test "macro with undefined local" do assert_eval_raise UndefinedFunctionError, "function Kernel.ErrorsTest.MacroWithUndefinedLocal.unknown/1" <> " is undefined (function not available)", - ''' + ~c""" defmodule Kernel.ErrorsTest.MacroWithUndefinedLocal do defmacrop bar, do: unknown(1) def baz, do: bar() end - ''' + """ end test "private macro" do assert_eval_raise UndefinedFunctionError, "function Kernel.ErrorsTest.PrivateMacro.foo/0 is undefined (function not available)", - ''' + ~c""" defmodule Kernel.ErrorsTest.PrivateMacro do defmacrop foo, do: 1 defmacro bar, do: __MODULE__.foo() defmacro baz, do: bar() end - ''' + """ end test "macro invoked before its definition" do assert_eval_raise CompileError, ~r"nofile:2: cannot invoke macro bar/0 before its definition", - ''' + ~c""" defmodule Kernel.ErrorsTest.IncorrectMacroDispatch do def foo, do: bar() defmacro bar, do: :bar end - ''' + """ assert_eval_raise CompileError, ~r"nofile:2: cannot invoke macro bar/0 before its definition", - ''' + ~c""" defmodule Kernel.ErrorsTest.IncorrectMacropDispatch do def foo, do: bar() defmacrop bar, do: :ok end - ''' + """ assert_eval_raise CompileError, ~r"nofile:2: cannot invoke macro bar/1 before its definition", - ''' + ~c""" defmodule Kernel.ErrorsTest.IncorrectMacroDispatch do defmacro bar(a) when is_atom(a), do: bar([a]) end - ''' + """ end test "macro captured before its definition" do assert_eval_raise CompileError, ~r"nofile:3: cannot invoke macro is_ok/1 before its definition", - ''' + ~c""" defmodule Kernel.ErrorsTest.IncorrectMacroDispatch.Capture do def foo do predicate = &is_ok/1 @@ -502,117 +504,117 @@ defmodule Kernel.ErrorsTest do defmacro is_ok(atom), do: atom == :ok end - ''' + """ end test "function definition with alias" do assert_eval_raise CompileError, "nofile:2: function names should start with lowercase characters or underscore, invalid name Bar", - ''' + ~c""" defmodule Kernel.ErrorsTest.FunctionDefinitionWithAlias do def Bar do :baz end end - ''' + """ end test "function import conflict" do assert_eval_raise CompileError, "nofile:3: function exit/1 imported from both :erlang and Kernel, call is ambiguous", - ''' + ~c""" defmodule Kernel.ErrorsTest.FunctionImportConflict do import :erlang, only: [exit: 1], warn: false def foo, do: exit(:test) end - ''' + """ end test "duplicated function on import options" do assert_eval_raise CompileError, "nofile:2: invalid :only option for import, flatten/1 is duplicated", - ''' + ~c""" defmodule Kernel.ErrorsTest.DuplicatedFunctionOnImportOnly do import List, only: [flatten: 1, keyfind: 4, flatten: 1] end - ''' + """ assert_eval_raise CompileError, "nofile:2: invalid :except option for import, flatten/1 is duplicated", - ''' + ~c""" defmodule Kernel.ErrorsTest.DuplicatedFunctionOnImportExcept do import List, except: [flatten: 1, keyfind: 4, flatten: 1] end - ''' + """ end test "ensure valid import :only option" do assert_eval_raise CompileError, "nofile:3: invalid :only option for import, expected value to be an atom " <> ":functions, :macros, or a list literal, got: x", - ''' + ~c""" defmodule Kernel.ErrorsTest.Only do x = [flatten: 1] import List, only: x end - ''' + """ end test "ensure valid import :except option" do assert_eval_raise CompileError, "nofile:3: invalid :except option for import, expected value to be a list " <> "literal, got: Module.__get_attribute__(Kernel.ErrorsTest.Only, :x, 3, true)", - ''' + ~c""" defmodule Kernel.ErrorsTest.Only do @x [flatten: 1] import List, except: @x end - ''' + """ end test "def defmacro clause change" do assert_eval_raise CompileError, "nofile:3: defmacro foo/1 already defined as def in nofile:2", - ''' + ~c""" defmodule Kernel.ErrorsTest.DefDefmacroClauseChange do def foo(1), do: 1 defmacro foo(x), do: x end - ''' + """ end test "def defp clause change from another file" do - assert_eval_raise CompileError, ~r"nofile:4: def hello/0 already defined as defp", ''' + assert_eval_raise CompileError, ~r"nofile:4: def hello/0 already defined as defp", ~c""" defmodule Kernel.ErrorsTest.DefDefmacroClauseChange do require Kernel.ErrorsTest defp hello, do: :world Kernel.ErrorsTest.hello() end - ''' + """ end test "internal function overridden" do assert_eval_raise CompileError, "nofile:2: cannot define def __info__/1 as it is automatically defined by Elixir", - ''' + ~c""" defmodule Kernel.ErrorsTest.InternalFunctionOverridden do def __info__(_), do: [] end - ''' + """ end test "no macros" do - assert_eval_raise CompileError, "nofile:2: could not load macros from module :lists", ''' + assert_eval_raise CompileError, "nofile:2: could not load macros from module :lists", ~c""" defmodule Kernel.ErrorsTest.NoMacros do import :lists, only: :macros end - ''' + """ end test "invalid macro" do assert_eval_raise CompileError, ~r"nofile: invalid quoted expression: {:foo, :bar, :baz, :bat}", - ''' + ~c""" defmodule Kernel.ErrorsTest.InvalidMacro do defmacrop oops do {:foo, :bar, :baz, :bat} @@ -620,63 +622,63 @@ defmodule Kernel.ErrorsTest do def test, do: oops() end - ''' + """ end test "unloaded module" do assert_eval_raise CompileError, "nofile:1: module Certainly.Doesnt.Exist is not loaded and could not be found", - 'import Certainly.Doesnt.Exist' + ~c"import Certainly.Doesnt.Exist" end test "module imported from the context it was defined in" do assert_eval_raise CompileError, ~r"nofile:4: module Kernel.ErrorsTest.ScheduledModule.Hygiene is not loaded but was defined.", - ''' + ~c""" defmodule Kernel.ErrorsTest.ScheduledModule do defmodule Hygiene do end import Kernel.ErrorsTest.ScheduledModule.Hygiene end - ''' + """ end test "module imported from the same module" do assert_eval_raise CompileError, ~r"nofile:3: you are trying to use the module Kernel.ErrorsTest.ScheduledModule.Hygiene which is currently being defined", - ''' + ~c""" defmodule Kernel.ErrorsTest.ScheduledModule do defmodule Hygiene do import Kernel.ErrorsTest.ScheduledModule.Hygiene end end - ''' + """ end test "already compiled module" do assert_eval_raise ArgumentError, "could not call Module.eval_quoted/4 because the module Record is already compiled", - 'Module.eval_quoted Record, quote(do: 1), [], file: __ENV__.file' + ~c"Module.eval_quoted Record, quote(do: 1), [], file: __ENV__.file" end test "@compile inline with undefined function" do assert_eval_raise CompileError, "nofile:1: inlined function foo/1 undefined", - 'defmodule Test do @compile {:inline, foo: 1} end' + ~c"defmodule Test do @compile {:inline, foo: 1} end" end test "invalid @dialyzer options" do assert_eval_raise CompileError, "nofile:1: undefined function foo/1 given to @dialyzer :nowarn_function", - 'defmodule Test do @dialyzer {:nowarn_function, {:foo, 1}} end' + ~c"defmodule Test do @dialyzer {:nowarn_function, {:foo, 1}} end" assert_eval_raise CompileError, "nofile:1: undefined function foo/1 given to @dialyzer :no_opaque", - 'defmodule Test do @dialyzer {:no_opaque, {:foo, 1}} end' + ~c"defmodule Test do @dialyzer {:no_opaque, {:foo, 1}} end" assert_eval_raise ArgumentError, "invalid value for @dialyzer attribute: :not_an_option", - 'defmodule Test do @dialyzer :not_an_option end' + ~c"defmodule Test do @dialyzer :not_an_option end" end test "@on_load attribute format" do @@ -699,81 +701,81 @@ defmodule Kernel.ErrorsTest do test "@on_load attribute with undefined function" do assert_eval_raise CompileError, "nofile:1: undefined function foo/0 given to @on_load", - 'defmodule UndefinedOnLoadFunction do @on_load :foo end' + ~c"defmodule UndefinedOnLoadFunction do @on_load :foo end" end test "wrong kind for @on_load attribute" do assert_eval_raise CompileError, "nofile:1: expected @on_load function foo/0 to be a function, " <> "got \"defmacro\"", - ''' + ~c""" defmodule PrivateOnLoadFunction do @on_load :foo defmacro foo, do: :ok end - ''' + """ end test "in definition module" do assert_eval_raise CompileError, "nofile:2: cannot define module Kernel.ErrorsTest.InDefinitionModule " <> "because it is currently being defined in nofile:1", - ''' + ~c""" defmodule Kernel.ErrorsTest.InDefinitionModule do defmodule Elixir.Kernel.ErrorsTest.InDefinitionModule, do: true end - ''' + """ end test "invalid definition" do assert_eval_raise CompileError, "nofile:1: invalid syntax in def 1.(hello)", - 'defmodule Kernel.ErrorsTest.InvalidDefinition, do: (def 1.(hello), do: true)' + ~c"defmodule Kernel.ErrorsTest.InvalidDefinition, do: (def 1.(hello), do: true)" end test "invalid size in bitstrings" do assert_eval_raise CompileError, "nofile:1: cannot use ^x outside of match clauses", - 'x = 8; <> = <>' + ~c"x = 8; <> = <>" end test "function head with guard" do - assert_eval_raise CompileError, "nofile:2: missing :do option in \"def\"", ''' + assert_eval_raise CompileError, "nofile:2: missing :do option in \"def\"", ~c""" defmodule Kernel.ErrorsTest.BodyessFunctionWithGuard do def foo(n) when is_number(n) end - ''' + """ - assert_eval_raise CompileError, "nofile:2: missing :do option in \"def\"", ''' + assert_eval_raise CompileError, "nofile:2: missing :do option in \"def\"", ~c""" defmodule Kernel.ErrorsTest.BodyessFunctionWithGuard do def foo(n) when is_number(n), true end - ''' + """ end test "invalid args for function head" do assert_eval_raise CompileError, ~r"nofile:2: only variables and \\\\ are allowed as arguments in function head.", - ''' + ~c""" defmodule Kernel.ErrorsTest.InvalidArgsForBodylessClause do def foo(nil) def foo(_), do: :ok end - ''' + """ end test "bad multi-call" do assert_eval_raise CompileError, "nofile:1: invalid argument for alias, expected a compile time atom or alias, got: 42", - 'alias IO.{ANSI, 42}' + ~c"alias IO.{ANSI, 42}" assert_eval_raise CompileError, "nofile:1: :as option is not supported by multi-alias call", - 'alias Elixir.{Map}, as: Dict' + ~c"alias Elixir.{Map}, as: Dict" assert_eval_raise UndefinedFunctionError, "function List.\"{}\"/1 is undefined or private", - '[List.{Chars}, "one"]' + ~c"[List.{Chars}, \"one\"]" end test "macros error stacktrace" do diff --git a/lib/elixir/test/elixir/kernel/expansion_test.exs b/lib/elixir/test/elixir/kernel/expansion_test.exs index 5584c3501..bc2b5996e 100644 --- a/lib/elixir/test/elixir/kernel/expansion_test.exs +++ b/lib/elixir/test/elixir/kernel/expansion_test.exs @@ -2533,8 +2533,8 @@ defmodule Kernel.ExpansionTest do # Other valid guard expressions are also legal for bitstring size in OTP 23+ - before_expansion = quote(do: <>) - after_expansion = quote(do: <>) + before_expansion = quote(do: <>) + after_expansion = quote(do: <>) assert expand(before_expansion) |> clean_meta([:alignment]) == clean_bit_modifiers(after_expansion) diff --git a/lib/elixir/test/elixir/kernel/fn_test.exs b/lib/elixir/test/elixir/kernel/fn_test.exs index 2a158230a..b1f8f4b42 100644 --- a/lib/elixir/test/elixir/kernel/fn_test.exs +++ b/lib/elixir/test/elixir/kernel/fn_test.exs @@ -46,8 +46,8 @@ defmodule Kernel.FnTest do end test "capture remote" do - assert (&:erlang.atom_to_list/1).(:a) == 'a' - assert (&Atom.to_charlist/1).(:a) == 'a' + assert (&:erlang.atom_to_list/1).(:a) == ~c"a" + assert (&Atom.to_charlist/1).(:a) == ~c"a" assert (&List.flatten/1).([[0]]) == [0] assert (&List.flatten/1).([[0]]) == [0] @@ -56,9 +56,9 @@ defmodule Kernel.FnTest do end test "capture local" do - assert (&atl/1).(:a) == 'a' - assert (&atl/1).(:a) == 'a' - assert (&atl(&1)).(:a) == 'a' + assert (&atl/1).(:a) == ~c"a" + assert (&atl/1).(:a) == ~c"a" + assert (&atl(&1)).(:a) == ~c"a" end test "capture local with question mark" do @@ -101,7 +101,7 @@ defmodule Kernel.FnTest do test "local partial application" do assert (&atb(&1, :utf8)).(:a) == "a" - assert (&atb(List.to_atom(&1), :utf8)).('a') == "a" + assert (&atb(List.to_atom(&1), :utf8)).(~c"a") == "a" end test "imported partial application" do diff --git a/lib/elixir/test/elixir/kernel/parser_test.exs b/lib/elixir/test/elixir/kernel/parser_test.exs index 7f73bbfbd..033501232 100644 --- a/lib/elixir/test/elixir/kernel/parser_test.exs +++ b/lib/elixir/test/elixir/kernel/parser_test.exs @@ -357,7 +357,7 @@ defmodule Kernel.ParserTest do string_to_quoted = &Code.string_to_quoted!(&1, opts) assert string_to_quoted.(~s("one")) == {:__block__, [delimiter: "\"", line: 1], ["one"]} - assert string_to_quoted.("'one'") == {:__block__, [delimiter: "'", line: 1], ['one']} + assert string_to_quoted.("'one'") == {:__block__, [delimiter: "'", line: 1], [~c"one"]} assert string_to_quoted.("?é") == {:__block__, [token: "?é", line: 1], [233]} assert string_to_quoted.("0b10") == {:__block__, [token: "0b10", line: 1], [2]} assert string_to_quoted.("12") == {:__block__, [token: "12", line: 1], [12]} @@ -386,7 +386,7 @@ defmodule Kernel.ParserTest do {:__block__, [delimiter: ~s["""], indentation: 0, line: 1], ["hello\n"]} assert string_to_quoted.("'''\nhello\n'''") == - {:__block__, [delimiter: ~s['''], indentation: 0, line: 1], ['hello\n']} + {:__block__, [delimiter: ~s['''], indentation: 0, line: 1], [~c"hello\n"]} assert string_to_quoted.(~s[fn (1) -> "hello" end]) == {:fn, [closing: [line: 1], line: 1], @@ -441,64 +441,64 @@ defmodule Kernel.ParserTest do test "missing paren" do assert_token_missing( ~r/nofile:1:9: missing terminator: \) \(for \"\(\" starting at line 1\)/, - 'case 1 (' + ~c"case 1 (" ) end test "dot terminator" do assert_token_missing( ~r/nofile:1:9: missing terminator: \" \(for function name starting at line 1\)/, - 'foo."bar' + ~c"foo.\"bar" ) end test "sigil terminator" do assert_token_missing( ~r/nofile:3:1: missing terminator: " \(for sigil ~r" starting at line 1\)/, - '~r"foo\n\n' + ~c"~r\"foo\n\n" ) assert_token_missing( ~r/nofile:3:1: missing terminator: } \(for sigil ~r{ starting at line 1\)/, - '~r{foo\n\n' + ~c"~r{foo\n\n" ) end test "string terminator" do assert_token_missing( ~r/nofile:1:5: missing terminator: \" \(for string starting at line 1\)/, - '"bar' + ~c"\"bar" ) end test "heredoc with incomplete interpolation" do assert_token_missing( ~r/nofile:2:1: missing interpolation terminator: \"}\" \(for heredoc starting at line 1\)/, - '"""\n\#{\n' + ~c"\"\"\"\n\#{\n" ) end test "heredoc terminator" do assert_token_missing( ~r/nofile:2:4: missing terminator: \"\"\" \(for heredoc starting at line 1\)/, - '"""\nbar' + ~c"\"\"\"\nbar" ) assert_token_missing( ~r/nofile:2:7: missing terminator: \"\"\" \(for heredoc starting at line 1\)/, - '"""\nbar"""' + ~c"\"\"\"\nbar\"\"\"" ) end test "missing end" do assert_token_missing( ~r/nofile:1:9: missing terminator: end \(for \"do\" starting at line 1\)/, - 'foo do 1' + ~c"foo do 1" ) assert_token_missing( ~r"HINT: it looks like the \"do\" on line 2 does not have a matching \"end\"", - ''' + ~c""" defmodule MyApp do def one do # end @@ -506,7 +506,7 @@ defmodule Kernel.ParserTest do def two do end end - ''' + """ ) end end @@ -515,94 +515,94 @@ defmodule Kernel.ParserTest do test "invalid heredoc start" do assert_syntax_error( ~r/nofile:1:1: heredoc allows only zero or more whitespace characters followed by a new line after \"\"\"/, - '"""bar\n"""' + ~c"\"\"\"bar\n\"\"\"" ) end test "invalid fn" do assert_syntax_error( ~r/nofile:1:1: expected anonymous functions to be defined with -> inside: 'fn'/, - 'fn 1 end' + ~c"fn 1 end" ) assert_syntax_error( ~r/nofile:2: unexpected operator ->. If you want to define multiple clauses,/, - 'fn 1\n2 -> 3 end' + ~c"fn 1\n2 -> 3 end" ) end test "invalid token" do assert_syntax_error( ~r/nofile:1:1: unexpected token: "#{"\u3164"}" \(column 1, code point U\+3164\)/, - 'ㅤ = 1' + ~c"ㅤ = 1" ) assert_syntax_error( ~r/nofile:1:7: unexpected token: "#{"\u200B"}" \(column 7, code point U\+200B\)/, - '[foo: \u200B]\noops' + ~c"[foo: \u200B]\noops" ) assert_syntax_error( ~r/nofile:1:1: unexpected token: carriage return \(column 1, code point U\+000D\)/, - '\r' + ~c"\r" ) end test "invalid bidi in source" do assert_syntax_error( ~r"nofile:1:1: invalid bidirectional formatting character in comment: \\u202A", - '# This is a \u202A' + ~c"# This is a \u202A" ) assert_syntax_error( ~r"nofile:1:5: invalid bidirectional formatting character in comment: \\u202A", - 'foo. # This is a \u202A' + ~c"foo. # This is a \u202A" ) assert_syntax_error( ~r"nofile:1:12: invalid bidirectional formatting character in string: \\u202A. If you want to use such character, use it in its escaped \\u202A form instead", - '"this is a \u202A"' + ~c"\"this is a \u202A\"" ) assert_syntax_error( ~r"nofile:1:13: invalid bidirectional formatting character in string: \\u202A. If you want to use such character, use it in its escaped \\u202A form instead", - '"this is a \\\u202A"' + ~c"\"this is a \\\u202A\"" ) end test "reserved tokens" do - assert_syntax_error(~r/nofile:1:1: reserved token: __aliases__/, '__aliases__') - assert_syntax_error(~r/nofile:1:1: reserved token: __block__/, '__block__') + assert_syntax_error(~r/nofile:1:1: reserved token: __aliases__/, ~c"__aliases__") + assert_syntax_error(~r/nofile:1:1: reserved token: __block__/, ~c"__block__") end test "invalid alias terminator" do - assert_syntax_error(~r/nofile:1:5: unexpected \( after alias Foo/, 'Foo()') + assert_syntax_error(~r/nofile:1:5: unexpected \( after alias Foo/, ~c"Foo()") end test "invalid quoted token" do assert_syntax_error( ~r/nofile:1:9: syntax error before: \"world\"/, - '"hello" "world"' + ~c"\"hello\" \"world\"" ) assert_syntax_error( ~r/nofile:1:3: syntax error before: 'Foobar'/, - '1 Foobar' + ~c"1 Foobar" ) assert_syntax_error( ~r/nofile:1:5: syntax error before: foo/, - 'Foo.:foo' + ~c"Foo.:foo" ) assert_syntax_error( ~r/nofile:1:5: syntax error before: \"foo\"/, - 'Foo.:"foo\#{:bar}"' + ~c"Foo.:\"foo\#{:bar}\"" ) assert_syntax_error( ~r/nofile:1:5: syntax error before: \"/, - 'Foo.:"\#{:bar}"' + ~c"Foo.:\"\#{:bar}\"" ) end @@ -611,31 +611,31 @@ defmodule Kernel.ParserTest do ~r/nofile:1:1: invalid character "@" \(code point U\+0040\) in identifier: #{name}/ end - assert_syntax_error(message.("foo@"), 'foo@') - assert_syntax_error(message.("foo@"), 'foo@ ') - assert_syntax_error(message.("foo@bar"), 'foo@bar') + assert_syntax_error(message.("foo@"), ~c"foo@") + assert_syntax_error(message.("foo@"), ~c"foo@ ") + assert_syntax_error(message.("foo@bar"), ~c"foo@bar") message = fn name -> ~r/nofile:1:1: invalid character "@" \(code point U\+0040\) in alias: #{name}/ end - assert_syntax_error(message.("Foo@"), 'Foo@') - assert_syntax_error(message.("Foo@bar"), 'Foo@bar') + assert_syntax_error(message.("Foo@"), ~c"Foo@") + assert_syntax_error(message.("Foo@bar"), ~c"Foo@bar") message = ~r/nofile:1:1: invalid character "\!" \(code point U\+0021\) in alias \(only ASCII characters, without punctuation, are allowed\): Foo\!/ - assert_syntax_error(message, 'Foo!') + assert_syntax_error(message, ~c"Foo!") message = ~r/nofile:1:1: invalid character "\?" \(code point U\+003F\) in alias \(only ASCII characters, without punctuation, are allowed\): Foo\?/ - assert_syntax_error(message, 'Foo?') + assert_syntax_error(message, ~c"Foo?") message = ~r/nofile:1:1: invalid character \"ó\" \(code point U\+00F3\) in alias \(only ASCII characters, without punctuation, are allowed\): Foó/ - assert_syntax_error(message, 'Foó') + assert_syntax_error(message, ~c"Foó") # token suggestion heuristic: # "for foO𝚳, NFKC isn't enough because 𝚳 nfkc's to Greek Μ, would be mixed script. @@ -659,7 +659,7 @@ defmodule Kernel.ParserTest do | ^ """) - assert_syntax_error(~r/#{message}/, 'foO𝚳') + assert_syntax_error(~r/#{message}/, ~c"foO𝚳") # token suggestion heuristic: # "for fooی𝚳, both NKFC and confusability would result in mixed scripts, @@ -685,7 +685,7 @@ defmodule Kernel.ParserTest do | ^ """) - assert_syntax_error(~r/#{message}/, 'fooی𝚳') + assert_syntax_error(~r/#{message}/, ~c"fooی𝚳") end test "keyword missing space" do @@ -699,22 +699,22 @@ defmodule Kernel.ParserTest do test "expression after keyword lists" do assert_syntax_error( ~r"unexpected expression after keyword list", - 'call foo: 1, :bar' + ~c"call foo: 1, :bar" ) assert_syntax_error( ~r"unexpected expression after keyword list", - 'call(foo: 1, :bar)' + ~c"call(foo: 1, :bar)" ) assert_syntax_error( ~r"unexpected expression after keyword list", - '[foo: 1, :bar]' + ~c"[foo: 1, :bar]" ) assert_syntax_error( ~r"unexpected expression after keyword list", - '%{foo: 1, :bar => :bar}' + ~c"%{foo: 1, :bar => :bar}" ) end @@ -731,21 +731,21 @@ defmodule Kernel.ParserTest do end test "unexpected end" do - assert_syntax_error("nofile:1:3: unexpected reserved word: end", '1 end') + assert_syntax_error("nofile:1:3: unexpected reserved word: end", ~c"1 end") assert_syntax_error( ~r" HINT: it looks like the \"end\" on line 2 does not have a matching \"do\" defined before it", - ''' + ~c""" defmodule MyApp do def one end def two do end end - ''' + """ ) assert_syntax_error( ~r" HINT: it looks like the \"end\" on line 3 does not have a matching \"do\" defined before it", - ''' + ~c""" defmodule MyApp do def one end @@ -753,12 +753,12 @@ defmodule Kernel.ParserTest do def two do end end - ''' + """ ) assert_syntax_error( ~r" HINT: it looks like the \"end\" on line 6 does not have a matching \"do\" defined before it", - ''' + ~c""" defmodule MyApp do def one do end @@ -766,12 +766,12 @@ defmodule Kernel.ParserTest do def two end end - ''' + """ ) assert_syntax_error( ~r"HINT: it looks like the \"do\" on line 3 does not have a matching \"end\"", - ''' + ~c""" defmodule MyApp do ( def one do @@ -781,38 +781,38 @@ defmodule Kernel.ParserTest do end ) end - ''' + """ ) end test "invalid keywords" do assert_syntax_error( ~r/nofile:1:2: syntax error before: '.'/, - '+.foo' + ~c"+.foo" ) assert_syntax_error( ~r/nofile:1:1: syntax error before: after. \"after\" is a reserved word/, - 'after = 1' + ~c"after = 1" ) end test "before sigil" do msg = fn x -> "nofile:1:9: syntax error before: sigil ~s starting with content '#{x}'" end - assert_syntax_error(msg.("bar baz"), '~s(foo) ~s(bar baz)') - assert_syntax_error(msg.(""), '~s(foo) ~s()') - assert_syntax_error(msg.("bar "), '~s(foo) ~s(bar \#{:baz})') - assert_syntax_error(msg.(""), '~s(foo) ~s(\#{:bar} baz)') + assert_syntax_error(msg.("bar baz"), ~c"~s(foo) ~s(bar baz)") + assert_syntax_error(msg.(""), ~c"~s(foo) ~s()") + assert_syntax_error(msg.("bar "), ~c"~s(foo) ~s(bar \#{:baz})") + assert_syntax_error(msg.(""), ~c"~s(foo) ~s(\#{:bar} baz)") end test "invalid do" do assert_syntax_error( ~r/nofile:1:10: unexpected reserved word: do./, - 'if true, do\n' + ~c"if true, do\n" ) - assert_syntax_error(~r/nofile:1:9: unexpected keyword: do:./, 'if true do:\n') + assert_syntax_error(~r/nofile:1:9: unexpected keyword: do:./, ~c"if true do:\n") end test "invalid parens call" do @@ -821,22 +821,22 @@ defmodule Kernel.ParserTest do "insert spaces between the function name and the opening parentheses. " <> "Syntax error before: '\\('" - assert_syntax_error(~r/#{msg}/, 'foo (hello, world)') + assert_syntax_error(~r/#{msg}/, ~c"foo (hello, world)") end test "invalid nested no parens call" do msg = ~r"nofile:1: unexpected comma. Parentheses are required to solve ambiguity" - assert_syntax_error(msg, '[foo 1, 2]') - assert_syntax_error(msg, '[foo bar 1, 2]') - assert_syntax_error(msg, '[do: foo 1, 2]') - assert_syntax_error(msg, 'foo(do: bar 1, 2)') - assert_syntax_error(msg, '{foo 1, 2}') - assert_syntax_error(msg, '{foo bar 1, 2}') - assert_syntax_error(msg, 'foo 1, foo 2, 3') - assert_syntax_error(msg, 'foo 1, @bar 3, 4') - assert_syntax_error(msg, 'foo 1, 2 + bar 3, 4') - assert_syntax_error(msg, 'foo(1, foo 2, 3)') + assert_syntax_error(msg, ~c"[foo 1, 2]") + assert_syntax_error(msg, ~c"[foo bar 1, 2]") + assert_syntax_error(msg, ~c"[do: foo 1, 2]") + assert_syntax_error(msg, ~c"foo(do: bar 1, 2)") + assert_syntax_error(msg, ~c"{foo 1, 2}") + assert_syntax_error(msg, ~c"{foo bar 1, 2}") + assert_syntax_error(msg, ~c"foo 1, foo 2, 3") + assert_syntax_error(msg, ~c"foo 1, @bar 3, 4") + assert_syntax_error(msg, ~c"foo 1, 2 + bar 3, 4") + assert_syntax_error(msg, ~c"foo(1, foo 2, 3)") interpret = fn x -> Macro.to_string(Code.string_to_quoted!(x)) end assert interpret.("f 1 + g h 2, 3") == "f(1 + g(h(2, 3)))" @@ -850,26 +850,26 @@ defmodule Kernel.ParserTest do "nofile:1:6: atom cannot be followed by an alias. If the '.' was meant to be " <> "part of the atom's name, the atom name must be quoted. Syntax error before: '.'" - assert_syntax_error(~r/#{msg}/, ':foo.Bar') - assert_syntax_error(~r/#{msg}/, ':"+".Bar') + assert_syntax_error(~r/#{msg}/, ~c":foo.Bar") + assert_syntax_error(~r/#{msg}/, ~c":\"+\".Bar") end test "invalid map/struct" do - assert_syntax_error(~r/nofile:1:5: syntax error before: '}'/, '%{:a}') - assert_syntax_error(~r/nofile:1:11: syntax error before: '}'/, '%{{:a, :b}}') - assert_syntax_error(~r/nofile:1:8: syntax error before: '{'/, '%{a, b}{a: :b}') + assert_syntax_error(~r/nofile:1:5: syntax error before: '}'/, ~c"%{:a}") + assert_syntax_error(~r/nofile:1:11: syntax error before: '}'/, ~c"%{{:a, :b}}") + assert_syntax_error(~r/nofile:1:8: syntax error before: '{'/, ~c"%{a, b}{a: :b}") end test "invalid interpolation" do assert_syntax_error( ~r/nofile:1:17: unexpected token: \). The \"do\" at line 1 is missing terminator \"end\"/, - '"foo\#{case 1 do )}bar"' + ~c"\"foo\#{case 1 do )}bar\"" ) end test "invalid end of expression" do # All valid examples - Code.eval_quoted(''' + Code.eval_quoted(~c""" 1; 2; 3 @@ -893,42 +893,42 @@ defmodule Kernel.ParserTest do after ; end - ''') + """) # All invalid examples - assert_syntax_error(~r/nofile:1:3: syntax error before: ';'/, '1+;\n2') + assert_syntax_error(~r/nofile:1:3: syntax error before: ';'/, ~c"1+;\n2") - assert_syntax_error(~r/nofile:1:8: syntax error before: ';'/, 'max(1, ;2)') + assert_syntax_error(~r/nofile:1:8: syntax error before: ';'/, ~c"max(1, ;2)") end test "invalid new line" do assert_syntax_error( "nofile:3:6: unexpectedly reached end of line. The current expression is invalid or incomplete", - 'if true do\n foo = [],\n baz\nend' + ~c"if true do\n foo = [],\n baz\nend" ) end test "invalid \"fn do expr end\"" do assert_syntax_error( "nofile:1:4: unexpected reserved word: do. Anonymous functions are written as:\n\n fn pattern -> expression end", - 'fn do :ok end' + ~c"fn do :ok end" ) end test "characters literal are printed correctly in syntax errors" do - assert_syntax_error("nofile:1:5: syntax error before: ?a", ':ok ?a') - assert_syntax_error("nofile:1:5: syntax error before: ?\\s", ':ok ?\\s') - assert_syntax_error("nofile:1:5: syntax error before: ?す", ':ok ?す') + assert_syntax_error("nofile:1:5: syntax error before: ?a", ~c":ok ?a") + assert_syntax_error("nofile:1:5: syntax error before: ?\\s", ~c":ok ?\\s") + assert_syntax_error("nofile:1:5: syntax error before: ?す", ~c":ok ?す") end test "numbers are printed correctly in syntax errors" do - assert_syntax_error(~r/nofile:1:5: syntax error before: \"12\"/, ':ok 12') - assert_syntax_error(~r/nofile:1:5: syntax error before: \"0b1\"/, ':ok 0b1') - assert_syntax_error(~r/nofile:1:5: syntax error before: \"12.3\"/, ':ok 12.3') + assert_syntax_error(~r/nofile:1:5: syntax error before: \"12\"/, ~c":ok 12") + assert_syntax_error(~r/nofile:1:5: syntax error before: \"0b1\"/, ~c":ok 0b1") + assert_syntax_error(~r/nofile:1:5: syntax error before: \"12.3\"/, ~c":ok 12.3") assert_syntax_error( ~r"nofile:1:1: invalid character \"_\" after number 123_456", - '123_456_foo' + ~c"123_456_foo" ) end diff --git a/lib/elixir/test/elixir/kernel/quote_test.exs b/lib/elixir/test/elixir/kernel/quote_test.exs index 41609c8d0..a6e71b5e4 100644 --- a/lib/elixir/test/elixir/kernel/quote_test.exs +++ b/lib/elixir/test/elixir/kernel/quote_test.exs @@ -562,25 +562,25 @@ defmodule Kernel.QuoteTest.ImportsHygieneTest do defmacrop get_list_length do quote do - length('hello') + length(~c"hello") end end defmacrop get_list_length_with_pipe do quote do - 'hello' |> length() + ~c"hello" |> length() end end defmacrop get_list_length_with_partial do quote do - (&length(&1)).('hello') + (&length(&1)).(~c"hello") end end defmacrop get_list_length_with_function do quote do - (&length/1).('hello') + (&length/1).(~c"hello") end end @@ -619,7 +619,7 @@ defmodule Kernel.QuoteTest.ImportsHygieneTest do quote do import Kernel, except: [length: 1] import String, only: [length: 1] - length('hello') + length(~c"hello") end end diff --git a/lib/elixir/test/elixir/kernel/sigils_test.exs b/lib/elixir/test/elixir/kernel/sigils_test.exs index dd7817f67..92ed109d3 100644 --- a/lib/elixir/test/elixir/kernel/sigils_test.exs +++ b/lib/elixir/test/elixir/kernel/sigils_test.exs @@ -56,20 +56,20 @@ bar) in ["foo\\\nbar", "foo\\\r\nbar"] end test "sigil c" do - assert ~c(foo) == 'foo' - assert ~c(f#{:o}o) == 'foo' - assert ~c(f\no) == 'f\no' + assert ~c(foo) == ~c"foo" + assert ~c(f#{:o}o) == ~c"foo" + assert ~c(f\no) == ~c"f\no" end test "sigil C" do - assert ~C(foo) == 'foo' - assert ~C[foo] == 'foo' - assert ~C{foo} == 'foo' - assert ~C'foo' == 'foo' - assert ~C"foo" == 'foo' - assert ~C|foo| == 'foo' - assert ~C(f#{o}o) == 'f\#{o}o' - assert ~C(f\no) == 'f\\no' + assert ~C(foo) == ~c"foo" + assert ~C[foo] == ~c"foo" + assert ~C{foo} == ~c"foo" + assert ~C'foo' == ~c"foo" + assert ~C"foo" == ~c"foo" + assert ~C|foo| == ~c"foo" + assert ~C(f#{o}o) == ~c"f\#{o}o" + assert ~C(f\no) == ~c"f\\no" end test "sigil w" do @@ -93,7 +93,7 @@ bar) in ["foo\\\nbar", "foo\\\r\nbar"] assert ~w(foo bar baz)s == ["foo", "bar", "baz"] assert ~w(foo bar baz)a == [:foo, :bar, :baz] - assert ~w(foo bar baz)c == ['foo', 'bar', 'baz'] + assert ~w(foo bar baz)c == [~c"foo", ~c"bar", ~c"baz"] bad_modifier = quote(do: ~w(foo bar baz)x) assert %ArgumentError{} = catch_error(Code.eval_quoted(bad_modifier)) @@ -101,7 +101,7 @@ bar) in ["foo\\\nbar", "foo\\\r\nbar"] assert ~w(Foo Bar)a == [:Foo, :Bar] assert ~w(Foo.#{Bar}.Baz)a == [:"Foo.Elixir.Bar.Baz"] assert ~w(Foo.Bar)s == ["Foo.Bar"] - assert ~w(Foo.#{Bar})c == ['Foo.Elixir.Bar'] + assert ~w(Foo.#{Bar})c == [~c"Foo.Elixir.Bar"] # Ensure it is fully expanded at compile time assert Macro.expand(quote(do: ~w(a b c)a), __ENV__) == [:a, :b, :c] @@ -122,7 +122,7 @@ bar) in ["foo\\\nbar", "foo\\\r\nbar"] assert ~W(foo bar baz)s == ["foo", "bar", "baz"] assert ~W(foo bar baz)a == [:foo, :bar, :baz] - assert ~W(foo bar baz)c == ['foo', 'bar', 'baz'] + assert ~W(foo bar baz)c == [~c"foo", ~c"bar", ~c"baz"] bad_modifier = quote(do: ~W(foo bar baz)x) assert %ArgumentError{} = catch_error(Code.eval_quoted(bad_modifier)) diff --git a/lib/elixir/test/elixir/kernel_test.exs b/lib/elixir/test/elixir/kernel_test.exs index 209799551..32baefc6d 100644 --- a/lib/elixir/test/elixir/kernel_test.exs +++ b/lib/elixir/test/elixir/kernel_test.exs @@ -75,8 +75,8 @@ defmodule KernelTest do [1, 2] ++ var = [1, 2, 3] assert var == [3] - 'ab' ++ var = 'abc' - assert var == 'c' + ~c"ab" ++ var = ~c"abc" + assert var == ~c"c" [:a, :b] ++ var = [:a, :b, :c] assert var == [:c] diff --git a/lib/elixir/test/elixir/list/chars_test.exs b/lib/elixir/test/elixir/list/chars_test.exs index 50679ccef..1657a567f 100644 --- a/lib/elixir/test/elixir/list/chars_test.exs +++ b/lib/elixir/test/elixir/list/chars_test.exs @@ -4,13 +4,13 @@ defmodule List.Chars.AtomTest do use ExUnit.Case, async: true test "basic" do - assert to_charlist(:foo) == 'foo' + assert to_charlist(:foo) == ~c"foo" end test "true false nil" do - assert to_charlist(false) == 'false' - assert to_charlist(true) == 'true' - assert to_charlist(nil) == '' + assert to_charlist(false) == ~c"false" + assert to_charlist(true) == ~c"true" + assert to_charlist(nil) == ~c"" end end @@ -18,7 +18,7 @@ defmodule List.Chars.BitStringTest do use ExUnit.Case, async: true test "basic" do - assert to_charlist("foo") == 'foo' + assert to_charlist("foo") == ~c"foo" end end @@ -26,11 +26,11 @@ defmodule List.Chars.NumberTest do use ExUnit.Case, async: true test "integer" do - assert to_charlist(1) == '1' + assert to_charlist(1) == ~c"1" end test "float" do - assert to_charlist(1.0) == '1.0' + assert to_charlist(1.0) == ~c"1.0" end end diff --git a/lib/elixir/test/elixir/list_test.exs b/lib/elixir/test/elixir/list_test.exs index f022bc9f6..ee02a072a 100644 --- a/lib/elixir/test/elixir/list_test.exs +++ b/lib/elixir/test/elixir/list_test.exs @@ -312,9 +312,9 @@ defmodule ListTest do end test "to_charlist/1" do - assert List.to_charlist([0x00E6, 0x00DF]) == 'æß' - assert List.to_charlist([0x0061, "bc"]) == 'abc' - assert List.to_charlist([0x0064, "ee", ['p']]) == 'deep' + assert List.to_charlist([0x00E6, 0x00DF]) == ~c"æß" + assert List.to_charlist([0x0061, "bc"]) == ~c"abc" + assert List.to_charlist([0x0064, "ee", [~c"p"]]) == ~c"deep" assert_raise UnicodeConversionError, "invalid code point 57343", fn -> List.to_charlist([0xDFFF]) @@ -373,12 +373,12 @@ defmodule ListTest do describe "ascii_printable?/2" do test "proper lists without limit" do assert List.ascii_printable?([]) - assert List.ascii_printable?('abc') - refute(List.ascii_printable?('abc' ++ [0])) - refute List.ascii_printable?('mañana') + assert List.ascii_printable?(~c"abc") + refute(List.ascii_printable?(~c"abc" ++ [0])) + refute List.ascii_printable?(~c"mañana") - printable_chars = '\a\b\t\n\v\f\r\e' ++ Enum.to_list(32..126) - non_printable_chars = '🌢áéíóúźç©¢🂭' + printable_chars = ~c"\a\b\t\n\v\f\r\e" ++ Enum.to_list(32..126) + non_printable_chars = ~c"🌢áéíóúźç©¢🂭" assert List.ascii_printable?(printable_chars) @@ -395,12 +395,12 @@ defmodule ListTest do test "proper lists with limit" do assert List.ascii_printable?([], 100) - assert List.ascii_printable?('abc' ++ [0], 2) + assert List.ascii_printable?(~c"abc" ++ [0], 2) end test "improper lists" do - refute List.ascii_printable?('abc' ++ ?d) - assert List.ascii_printable?('abc' ++ ?d, 3) + refute List.ascii_printable?(~c"abc" ++ ?d) + assert List.ascii_printable?(~c"abc" ++ ?d, 3) end end end diff --git a/lib/elixir/test/elixir/macro_test.exs b/lib/elixir/test/elixir/macro_test.exs index 5c0fd2079..2f5e7480e 100644 --- a/lib/elixir/test/elixir/macro_test.exs +++ b/lib/elixir/test/elixir/macro_test.exs @@ -388,7 +388,7 @@ defmodule MacroTest do end test "forwards options to the underlying inspect calls" do - value = 'hello' + value = ~c"hello" assert {^value, formatted} = dbg_format(value, syntax_colors: [], charlists: :as_lists) assert formatted =~ "value #=> [104, 101, 108, 108, 111]\n" end @@ -856,7 +856,8 @@ defmodule MacroTest do test "charlist" do assert macro_to_string(quote(do: [])) == "[]" - assert macro_to_string(quote(do: 'abc')) == "'abc'" + assert macro_to_string(quote(do: ~c"abc")) == ~S/~c"abc"/ + assert macro_to_string(quote(do: [?a, ?b, ?c])) == "'abc'" end test "string" do @@ -942,15 +943,18 @@ defmodule MacroTest do env = %{__ENV__ | file: "foo", line: 12} assert Macro.Env.stacktrace(env) == - [{__MODULE__, :"test env stacktrace", 1, [file: 'foo', line: 12]}] + [{__MODULE__, :"test env stacktrace", 1, [file: ~c"foo", line: 12]}] env = %{env | function: nil} - assert Macro.Env.stacktrace(env) == [{__MODULE__, :__MODULE__, 0, [file: 'foo', line: 12]}] + + assert Macro.Env.stacktrace(env) == [ + {__MODULE__, :__MODULE__, 0, [file: ~c"foo", line: 12]} + ] env = %{env | module: nil} assert Macro.Env.stacktrace(env) == - [{:elixir_compiler, :__FILE__, 1, [file: 'foo', line: 12]}] + [{:elixir_compiler, :__FILE__, 1, [file: ~c"foo", line: 12]}] end test "context modules" do diff --git a/lib/elixir/test/elixir/module/types/integration_test.exs b/lib/elixir/test/elixir/module/types/integration_test.exs index 195e0b822..707cde711 100644 --- a/lib/elixir/test/elixir/module/types/integration_test.exs +++ b/lib/elixir/test/elixir/module/types/integration_test.exs @@ -767,7 +767,7 @@ defmodule Module.Types.IntegrationTest do end defp read_chunk(binary) do - assert {:ok, {_module, [{'ExCk', chunk}]}} = :beam_lib.chunks(binary, ['ExCk']) + assert {:ok, {_module, [{~c"ExCk", chunk}]}} = :beam_lib.chunks(binary, [~c"ExCk"]) assert {:elixir_checker_v1, map} = :erlang.binary_to_term(chunk) map end diff --git a/lib/elixir/test/elixir/module_test.exs b/lib/elixir/test/elixir/module_test.exs index 3c7aff406..d6f7343d1 100644 --- a/lib/elixir/test/elixir/module_test.exs +++ b/lib/elixir/test/elixir/module_test.exs @@ -121,7 +121,7 @@ defmodule ModuleTest do end test "in memory modules are tagged as so" do - assert :code.which(__MODULE__) == '' + assert :code.which(__MODULE__) == ~c"" end ## Eval diff --git a/lib/elixir/test/elixir/path_test.exs b/lib/elixir/test/elixir/path_test.exs index 6b43b9b5e..a6b4560c4 100644 --- a/lib/elixir/test/elixir/path_test.exs +++ b/lib/elixir/test/elixir/path_test.exs @@ -84,11 +84,11 @@ defmodule PathTest do test "type/1" do assert Path.type("C:/usr/local/bin") == :absolute - assert Path.type('C:\\usr\\local\\bin') == :absolute + assert Path.type(~c"C:\\usr\\local\\bin") == :absolute assert Path.type("C:usr\\local\\bin") == :volumerelative assert Path.type("/usr/local/bin") == :volumerelative - assert Path.type('usr/local/bin') == :relative + assert Path.type(~c"usr/local/bin") == :relative assert Path.type("../usr/local/bin") == :relative assert Path.type("//host/path") == :absolute @@ -126,8 +126,8 @@ defmodule PathTest do assert Path.relative("usr/local/bin") == "usr/local/bin" assert Path.relative("../usr/local/bin") == "../usr/local/bin" assert Path.relative("/") == "." - assert Path.relative('/') == "." - assert Path.relative(['/usr', ?/, "local/bin"]) == "usr/local/bin" + assert Path.relative(~c"/") == "." + assert Path.relative([~c"/usr", ?/, "local/bin"]) == "usr/local/bin" end test "type/1" do @@ -135,13 +135,13 @@ defmodule PathTest do assert Path.type("usr/local/bin") == :relative assert Path.type("../usr/local/bin") == :relative - assert Path.type('/usr/local/bin') == :absolute - assert Path.type('usr/local/bin') == :relative - assert Path.type('../usr/local/bin') == :relative + assert Path.type(~c"/usr/local/bin") == :absolute + assert Path.type(~c"usr/local/bin") == :relative + assert Path.type(~c"../usr/local/bin") == :relative - assert Path.type(['/usr/', 'local/bin']) == :absolute - assert Path.type(['usr/', 'local/bin']) == :relative - assert Path.type(['../usr', '/local/bin']) == :relative + assert Path.type([~c"/usr/", ~c"local/bin"]) == :absolute + assert Path.type([~c"usr/", ~c"local/bin"]) == :relative + assert Path.type([~c"../usr", ~c"/local/bin"]) == :relative end end @@ -172,9 +172,9 @@ defmodule PathTest do home = System.user_home!() |> Path.absname() assert home == Path.expand("~") - assert home == Path.expand('~') + assert home == Path.expand(~c"~") assert is_binary(Path.expand("~/foo")) - assert is_binary(Path.expand('~/foo')) + assert is_binary(Path.expand(~c"~/foo")) assert Path.expand("~/file") == Path.join(home, "file") assert Path.expand("~/file", "whatever") == Path.join(home, "file") @@ -205,7 +205,8 @@ defmodule PathTest do assert drive_letter == "/bar" drive_letter = - Path.expand(['..', ?/, "bar/../bar"], '/foo/../foo/../foo') |> strip_drive_letter_if_windows + Path.expand([~c"..", ?/, "bar/../bar"], ~c"/foo/../foo/../foo") + |> strip_drive_letter_if_windows assert "/bar" == drive_letter @@ -224,10 +225,10 @@ defmodule PathTest do assert Path.relative_to("usr/local/foo", "usr/local") == "foo" assert Path.relative_to("usr/local/foo", "etc") == "usr/local/foo" - assert Path.relative_to('usr/local/foo', "etc") == "usr/local/foo" + assert Path.relative_to(~c"usr/local/foo", "etc") == "usr/local/foo" assert Path.relative_to("usr/local/foo", "usr/local") == "foo" - assert Path.relative_to(["usr", ?/, 'local/foo'], 'usr/local') == "foo" + assert Path.relative_to(["usr", ?/, ~c"local/foo"], ~c"usr/local") == "foo" end test "safe_relative/1" do @@ -250,15 +251,15 @@ defmodule PathTest do assert Path.rootname("~/foo/bar.ex", ".ex") == "~/foo/bar" assert Path.rootname("~/foo/bar.exs", ".ex") == "~/foo/bar.exs" assert Path.rootname("~/foo/bar.old.ex", ".ex") == "~/foo/bar.old" - assert Path.rootname([?~, '/foo/bar', ".old.ex"], '.ex') == "~/foo/bar.old" + assert Path.rootname([?~, ~c"/foo/bar", ".old.ex"], ~c".ex") == "~/foo/bar.old" end test "extname/1" do assert Path.extname("foo.erl") == ".erl" assert Path.extname("~/foo/bar") == "" - assert Path.extname('foo.erl') == ".erl" - assert Path.extname('~/foo/bar') == "" + assert Path.extname(~c"foo.erl") == ".erl" + assert Path.extname(~c"~/foo/bar") == "" end test "dirname/1" do @@ -268,7 +269,7 @@ defmodule PathTest do assert Path.dirname("~/foo/bar.ex") == "~/foo" assert Path.dirname("/foo/bar/baz/") == "/foo/bar/baz" - assert Path.dirname([?~, "/foo", '/bar.ex']) == "~/foo" + assert Path.dirname([?~, "/foo", ~c"/bar.ex"]) == "~/foo" end test "basename/1,2" do @@ -280,7 +281,7 @@ defmodule PathTest do assert Path.basename("~/foo/bar.exs", ".ex") == "bar.exs" assert Path.basename("~/for/bar.old.ex", ".ex") == "bar.old" - assert Path.basename([?~, "/for/bar", '.old.ex'], ".ex") == "bar.old" + assert Path.basename([?~, "/for/bar", ~c".old.ex"], ".ex") == "bar.old" end test "join/1" do @@ -289,11 +290,11 @@ defmodule PathTest do assert Path.join(["/", "foo", "bar"]) == "/foo/bar" assert Path.join(["/", "foo", "bar", "/"]) == "/foo/bar" assert Path.join(["~", "foo", "bar"]) == "~/foo/bar" - assert Path.join(['/foo/', "/bar/"]) == "/foo/bar" + assert Path.join([~c"/foo/", "/bar/"]) == "/foo/bar" assert Path.join(["/", ""]) == "/" assert Path.join(["/", "", "bar"]) == "/bar" - assert Path.join(['foo', [?b, "a", ?r]]) == "foo/bar" - assert Path.join([[?f, 'o', "o"]]) == "foo" + assert Path.join([~c"foo", [?b, "a", ?r]]) == "foo/bar" + assert Path.join([[?f, ~c"o", "o"]]) == "foo" end test "join/2" do diff --git a/lib/elixir/test/elixir/protocol/consolidation_test.exs b/lib/elixir/test/elixir/protocol/consolidation_test.exs index 8cb3e9e12..a48334ed8 100644 --- a/lib/elixir/test/elixir/protocol/consolidation_test.exs +++ b/lib/elixir/test/elixir/protocol/consolidation_test.exs @@ -45,7 +45,7 @@ defmodule Protocol.ConsolidationTest do :code.purge(Sample) :code.delete(Sample) {:ok, binary} = Protocol.consolidate(Sample, [Any, ImplStruct]) - :code.load_binary(Sample, 'protocol_test.exs', binary) + :code.load_binary(Sample, ~c"protocol_test.exs", binary) @sample_binary binary @@ -53,7 +53,7 @@ defmodule Protocol.ConsolidationTest do :code.purge(WithAny) :code.delete(WithAny) {:ok, binary} = Protocol.consolidate(WithAny, [Any, ImplStruct, Map]) - :code.load_binary(WithAny, 'protocol_test.exs', binary) + :code.load_binary(WithAny, ~c"protocol_test.exs", binary) test "consolidated?/1" do assert Protocol.consolidated?(WithAny) @@ -116,7 +116,7 @@ defmodule Protocol.ConsolidationTest do end test "consolidation keeps docs" do - {:ok, {Sample, [{'Docs', docs_bin}]}} = :beam_lib.chunks(@sample_binary, ['Docs']) + {:ok, {Sample, [{~c"Docs", docs_bin}]}} = :beam_lib.chunks(@sample_binary, [~c"Docs"]) {:docs_v1, _, _, _, _, _, docs} = :erlang.binary_to_term(docs_bin) ok_doc = List.keyfind(docs, {:function, :ok, 1}, 0) @@ -127,7 +127,7 @@ defmodule Protocol.ConsolidationTest do deprecated = [{{:ok, 1}, "Reason"}] assert deprecated == Sample.__info__(:deprecated) - {:ok, {Sample, [{'ExCk', check_bin}]}} = :beam_lib.chunks(@sample_binary, ['ExCk']) + {:ok, {Sample, [{~c"ExCk", check_bin}]}} = :beam_lib.chunks(@sample_binary, [~c"ExCk"]) assert {:elixir_checker_v1, contents} = :erlang.binary_to_term(check_bin) export_info = %{deprecated_reason: "Reason", kind: :def} assert {{:ok, 1}, export_info} in contents.exports diff --git a/lib/elixir/test/elixir/record_test.exs b/lib/elixir/test/elixir/record_test.exs index ac0164a6b..1734b600c 100644 --- a/lib/elixir/test/elixir/record_test.exs +++ b/lib/elixir/test/elixir/record_test.exs @@ -184,7 +184,7 @@ defmodule RecordTest do call: MapSet.new(), string: "abc", binary: <<1, 2, 3>>, - charlist: 'abc' + charlist: ~c"abc" ) test "records with literal defaults and on-the-fly record" do @@ -199,7 +199,7 @@ defmodule RecordTest do call: MapSet.new(), string: "abc", binary: <<1, 2, 3>>, - charlist: 'abc' + charlist: ~c"abc" ] assert defaults(defaults(), :struct) == ~D[2016-01-01] @@ -212,7 +212,7 @@ defmodule RecordTest do assert defaults(defaults(), :call) == MapSet.new() assert defaults(defaults(), :string) == "abc" assert defaults(defaults(), :binary) == <<1, 2, 3>> - assert defaults(defaults(), :charlist) == 'abc' + assert defaults(defaults(), :charlist) == ~c"abc" end test "records with literal defaults and record in a variable" do @@ -229,7 +229,7 @@ defmodule RecordTest do call: MapSet.new(), string: "abc", binary: <<1, 2, 3>>, - charlist: 'abc' + charlist: ~c"abc" ] assert defaults(defaults, :struct) == ~D[2016-01-01] @@ -242,7 +242,7 @@ defmodule RecordTest do assert defaults(defaults, :call) == MapSet.new() assert defaults(defaults, :string) == "abc" assert defaults(defaults, :binary) == <<1, 2, 3>> - assert defaults(defaults, :charlist) == 'abc' + assert defaults(defaults, :charlist) == ~c"abc" end test "records with dynamic arguments" do diff --git a/lib/elixir/test/elixir/string/chars_test.exs b/lib/elixir/test/elixir/string/chars_test.exs index 02a397a48..934425f02 100644 --- a/lib/elixir/test/elixir/string/chars_test.exs +++ b/lib/elixir/test/elixir/string/chars_test.exs @@ -60,7 +60,7 @@ defmodule String.Chars.ListTest do end test "printable" do - assert to_string('abc') == "abc" + assert to_string(~c"abc") == "abc" end test "charlist" do diff --git a/lib/elixir/test/elixir/string_io_test.exs b/lib/elixir/test/elixir/string_io_test.exs index cb89e46fc..479f27aca 100644 --- a/lib/elixir/test/elixir/string_io_test.exs +++ b/lib/elixir/test/elixir/string_io_test.exs @@ -293,12 +293,12 @@ defmodule StringIOTest do {:more, continuation ++ content} end - def until_eof_then_try_more('magic-stop-prefix' ++ continuation, :eof) do + def until_eof_then_try_more(~c"magic-stop-prefix" ++ continuation, :eof) do {:done, continuation, :eof} end def until_eof_then_try_more(continuation, :eof) do - {:more, 'magic-stop-prefix' ++ continuation} + {:more, ~c"magic-stop-prefix" ++ continuation} end def until_eof_then_try_more(continuation, content) do @@ -381,14 +381,14 @@ defmodule StringIOTest do test ":io.erl_scan_form/2" do {:ok, pid} = StringIO.open("1.") - result = :io.scan_erl_form(pid, 'p>') + result = :io.scan_erl_form(pid, ~c"p>") assert result == {:ok, [{:integer, 1, 1}, {:dot, 1}], 1} assert StringIO.contents(pid) == {"", ""} end test ":io.erl_scan_form/2 with capture_prompt" do {:ok, pid} = StringIO.open("1.", capture_prompt: true) - result = :io.scan_erl_form(pid, 'p>') + result = :io.scan_erl_form(pid, ~c"p>") assert result == {:ok, [{:integer, 1, 1}, {:dot, 1}], 1} assert StringIO.contents(pid) == {"", "p>p>"} end diff --git a/lib/elixir/test/elixir/system_test.exs b/lib/elixir/test/elixir/system_test.exs index 3424ca10c..51f768fe8 100644 --- a/lib/elixir/test/elixir/system_test.exs +++ b/lib/elixir/test/elixir/system_test.exs @@ -43,7 +43,7 @@ defmodule SystemTest do end test "argv/0" do - list = elixir('-e "IO.inspect System.argv()" -- -o opt arg1 arg2 --long-opt 10') + list = elixir(~c"-e \"IO.inspect System.argv()\" -- -o opt arg1 arg2 --long-opt 10") {args, _} = Code.eval_string(list, []) assert args == ["-o", "opt", "arg1", "arg2", "--long-opt", "10"] end @@ -92,7 +92,7 @@ defmodule SystemTest do test "cmd/3 raises with non-binary arguments" do assert_raise ArgumentError, ~r"all arguments for System.cmd/3 must be binaries", fn -> - System.cmd("ls", ['/usr']) + System.cmd("ls", [~c"/usr"]) end end diff --git a/lib/elixir/test/elixir/test_helper.exs b/lib/elixir/test/elixir/test_helper.exs index bd42ad7d1..2b8d3e3d3 100644 --- a/lib/elixir/test/elixir/test_helper.exs +++ b/lib/elixir/test/elixir/test_helper.exs @@ -55,7 +55,7 @@ defmodule PathHelpers do end defp run_cmd(executable, args) do - '#{executable} #{IO.chardata_to_string(args)}#{redirect_std_err_on_win()}' + ~c"#{executable} #{IO.chardata_to_string(args)}#{redirect_std_err_on_win()}" |> :os.cmd() |> :binary.list_to_bin() end diff --git a/lib/elixir/test/elixir/uri_test.exs b/lib/elixir/test/elixir/uri_test.exs index 4a553c483..54ea625d5 100644 --- a/lib/elixir/test/elixir/uri_test.exs +++ b/lib/elixir/test/elixir/uri_test.exs @@ -36,11 +36,11 @@ defmodule URITest do "foo%5B%5D=%2B%3D%2F%3F%26%23+%C3%91" assert_raise ArgumentError, fn -> - URI.encode_query([{"foo", 'bar'}]) + URI.encode_query([{"foo", ~c"bar"}]) end assert_raise ArgumentError, fn -> - URI.encode_query([{'foo', "bar"}]) + URI.encode_query([{~c"foo", "bar"}]) end end diff --git a/lib/elixir/unicode/tokenizer.ex b/lib/elixir/unicode/tokenizer.ex index 1e04d6781..caac26db5 100644 --- a/lib/elixir/unicode/tokenizer.ex +++ b/lib/elixir/unicode/tokenizer.ex @@ -465,13 +465,13 @@ defmodule String.Tokenizer do |> then(&(" {" <> Enum.join(&1, ",") <> "}")) end - hex = :io_lib.format('~4.16.0B', [codepoint]) + hex = :io_lib.format(~c"~4.16.0B", [codepoint]) " \\u#{hex} #{[codepoint]}#{scriptsets}\n" end - prefix = 'invalid mixed-script identifier found: ' + prefix = ~c"invalid mixed-script identifier found: " - suffix = ''' + suffix = ~c""" Mixed-script identifiers are not supported for security reasons. \ @@ -479,7 +479,7 @@ defmodule String.Tokenizer do #{breakdown} All characters in the identifier should resolve to a single script, \ or use a highly restrictive set of scripts. - ''' + """ {:error, {:not_highly_restrictive, acc, {prefix, suffix}}} end diff --git a/lib/ex_unit/examples/difference.exs b/lib/ex_unit/examples/difference.exs index 6e105f71d..20c5afdab 100644 --- a/lib/ex_unit/examples/difference.exs +++ b/lib/ex_unit/examples/difference.exs @@ -67,8 +67,8 @@ defmodule Difference do end test "charlists" do - charlist1 = 'fox hops over \'the dog' - charlist2 = 'fox jumps over the lazy cat' + charlist1 = ~c"fox hops over 'the dog" + charlist2 = ~c"fox jumps over the lazy cat" assert charlist1 == charlist2 end diff --git a/lib/ex_unit/examples/one_of_each.exs b/lib/ex_unit/examples/one_of_each.exs index 0c4b2f6d6..0a32ddf0c 100644 --- a/lib/ex_unit/examples/one_of_each.exs +++ b/lib/ex_unit/examples/one_of_each.exs @@ -10,8 +10,8 @@ defmodule TestOneOfEach do @one 1 @two 2 - @long_data_1 [field1: "one", field2: {:two1, :two2}, field3: 'three', field4: [1, 2, 3, 4]] - @long_data_2 [field1: "one", field2: {:two1, :two3}, field3: 'three', field4: [1, 2, 3, 4]] + @long_data_1 [field1: "one", field2: {:two1, :two2}, field3: ~c"three", field4: [1, 2, 3, 4]] + @long_data_2 [field1: "one", field2: {:two1, :two3}, field3: ~c"three", field4: [1, 2, 3, 4]] setup do {:ok, user_id: 1, post_id: 2, many_ids: Enum.to_list(1..50)} diff --git a/lib/ex_unit/lib/ex_unit/runner.ex b/lib/ex_unit/lib/ex_unit/runner.ex index ab6290c07..c2dbafa13 100644 --- a/lib/ex_unit/lib/ex_unit/runner.ex +++ b/lib/ex_unit/lib/ex_unit/runner.ex @@ -410,7 +410,7 @@ defmodule ExUnit.Runner do Map.put(context, :tmp_dir, path) end - @escape Enum.map(' [~#%&*{}\\:<>?/+|"]', &<<&1::utf8>>) + @escape Enum.map(~c" [~#%&*{}\\:<>?/+|\"]", &<<&1::utf8>>) defp escape_path(path) do String.replace(path, @escape, "-") diff --git a/lib/ex_unit/test/ex_unit/assertions_test.exs b/lib/ex_unit/test/ex_unit/assertions_test.exs index 3fe6ebd67..5de365ef1 100644 --- a/lib/ex_unit/test/ex_unit/assertions_test.exs +++ b/lib/ex_unit/test/ex_unit/assertions_test.exs @@ -537,32 +537,32 @@ defmodule ExUnit.AssertionsTest do end test "assert in when member" do - true = assert 'foo' in ['foo', 'bar'] + true = assert ~c"foo" in [~c"foo", ~c"bar"] end test "assert in when is not member" do try do - "This should never be tested" = assert 'foo' in 'bar' + "This should never be tested" = assert ~c"foo" in ~c"bar" rescue error in [ExUnit.AssertionError] -> - 'foo' = error.left - 'bar' = error.right - "assert 'foo' in 'bar'" = Macro.to_string(error.expr) + ~c"foo" = error.left + ~c"bar" = error.right + ~S(assert ~c"foo" in ~c"bar") = Macro.to_string(error.expr) end end test "refute in when is not member" do - false = refute 'baz' in ['foo', 'bar'] + false = refute ~c"baz" in [~c"foo", ~c"bar"] end test "refute in when is member" do try do - "This should never be tested" = refute 'foo' in ['foo', 'bar'] + "This should never be tested" = refute ~c"foo" in [~c"foo", ~c"bar"] rescue error in [ExUnit.AssertionError] -> - 'foo' = error.left - ['foo', 'bar'] = error.right - "refute 'foo' in ['foo', 'bar']" = Macro.to_string(error.expr) + ~c"foo" = error.left + [~c"foo", ~c"bar"] = error.right + ~S(refute ~c"foo" in [~c"foo", ~c"bar"]) = Macro.to_string(error.expr) end end diff --git a/lib/ex_unit/test/ex_unit/capture_io_test.exs b/lib/ex_unit/test/ex_unit/capture_io_test.exs index a0d3dfefc..f2f6a6f38 100644 --- a/lib/ex_unit/test/ex_unit/capture_io_test.exs +++ b/lib/ex_unit/test/ex_unit/capture_io_test.exs @@ -180,58 +180,58 @@ defmodule ExUnit.CaptureIOTest do test "with get until" do assert capture_io(fn -> - :io.scan_erl_form('>') + :io.scan_erl_form(~c">") end) == ">" assert capture_io("1.\n", fn -> - :io.scan_erl_form('>') + :io.scan_erl_form(~c">") end) == ">" assert capture_io("1\n.\n", fn -> - :io.scan_erl_form('>') + :io.scan_erl_form(~c">") end) == ">>" assert capture_io([capture_prompt: false], fn -> - :io.scan_erl_form('>') + :io.scan_erl_form(~c">") end) == "" capture_io(fn -> - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("1", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:integer, 1, 1}], 1} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:integer, 1, 1}], 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("1\n.", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:integer, 1, 1}, {:dot, 2}], 2} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:integer, 1, 1}, {:dot, 2}], 2} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("1.\n.", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:integer, 1, 1}, {:dot, 1}], 2} - assert :io.scan_erl_form('>') == {:ok, [dot: 1], 1} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:integer, 1, 1}, {:dot, 1}], 2} + assert :io.scan_erl_form(~c">") == {:ok, [dot: 1], 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("\"a", fn -> - assert :io.scan_erl_form('>') == {:error, {1, :erl_scan, {:string, 34, 'a'}}, 1} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:error, {1, :erl_scan, {:string, 34, ~c"a"}}, 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("\"a\n\"", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:string, 1, 'a\n'}], 2} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:string, 1, ~c"a\n"}], 2} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io(":erl. mof*,,l", fn -> - assert :io.scan_erl_form('>') == {:ok, [{:":", 1}, {:atom, 1, :erl}, {:dot, 1}], 1} + assert :io.scan_erl_form(~c">") == {:ok, [{:":", 1}, {:atom, 1, :erl}, {:dot, 1}], 1} expected_tokens = [{:atom, 1, :mof}, {:*, 1}, {:",", 1}, {:",", 1}, {:atom, 1, :l}] - assert :io.scan_erl_form('>') == {:ok, expected_tokens, 1} + assert :io.scan_erl_form(~c">") == {:ok, expected_tokens, 1} - assert :io.scan_erl_form('>') == {:eof, 1} + assert :io.scan_erl_form(~c">") == {:eof, 1} end) capture_io("a\nb\nc", fn -> diff --git a/lib/ex_unit/test/ex_unit/diff_test.exs b/lib/ex_unit/test/ex_unit/diff_test.exs index 60b1ce846..874688a1a 100644 --- a/lib/ex_unit/test/ex_unit/diff_test.exs +++ b/lib/ex_unit/test/ex_unit/diff_test.exs @@ -1010,16 +1010,22 @@ defmodule ExUnit.DiffTest do end test "charlists" do + # TODO fix these diffs refute_diff( - 'fox hops over \'the dog' = 'fox jumps over the lazy cat', - "'fox -ho-ps over -\\'-the -dog-'", + ~c"fox hops over 'the dog" = ~c"fox jumps over the lazy cat", + "-~c\"fox hops over 'the dog\"-", "'fox +jum+ps over the +lazy cat+'" ) refute_diff({[], :ok} = {[], [], :ok}, "{[], -:ok-}", "{[], +[]+, +:ok+}") - refute_diff({[], :ok} = {'foo', [], :ok}, "{'--', -:ok-}", "{'+foo+', +[]+, +:ok+}") - refute_diff({'foo', :ok} = {[], [], :ok}, "{'-foo-', -:ok-}", "{'++', +[]+, +:ok+}") - refute_diff({'foo', :ok} = {'bar', [], :ok}, "{'-foo-', -:ok-}", "{'+bar+', +[]+, +:ok+}") + refute_diff({[], :ok} = {~c"foo", [], :ok}, "{'--', -:ok-}", "{'+foo+', +[]+, +:ok+}") + refute_diff({~c"foo", :ok} = {[], [], :ok}, "{-~c\"foo\"-, -:ok-}", "{'++', +[]+, +:ok+}") + + refute_diff( + {~c"foo", :ok} = {~c"bar", [], :ok}, + "{-~c\"foo\"-, -:ok-}", + "{'+bar+', +[]+, +:ok+}" + ) end test "refs" do diff --git a/lib/iex/lib/iex/autocomplete.ex b/lib/iex/lib/iex/autocomplete.ex index 35b08eaea..3b7550fbe 100644 --- a/lib/iex/lib/iex/autocomplete.ex +++ b/lib/iex/lib/iex/autocomplete.ex @@ -25,7 +25,7 @@ defmodule IEx.Autocomplete do def remsh(node) do fn e -> case :rpc.call(node, IEx.Autocomplete, :expand, [e, IEx.Broker.shell()]) do - {:badrpc, _} -> {:no, '', []} + {:badrpc, _} -> {:no, ~c"", []} r -> r end end @@ -105,8 +105,8 @@ defmodule IEx.Autocomplete do {:struct, struct} when is_list(struct) -> expand_structs(List.to_string(struct), shell) - {:struct, {:dot, {:alias, struct}, ''}} when is_list(struct) -> - expand_structs(List.to_string(struct ++ '.'), shell) + {:struct, {:dot, {:alias, struct}, ~c""}} when is_list(struct) -> + expand_structs(List.to_string(struct ++ ~c"."), shell) # {:module_attribute, charlist} # :none @@ -116,18 +116,18 @@ defmodule IEx.Autocomplete do end defp get_helper(expr) do - with [helper | rest] when helper in 'bt' <- expr, + with [helper | rest] when helper in ~c"bt" <- expr, [space_or_paren, char | _] <- squeeze_spaces(rest), true <- - space_or_paren in ' (' and - (char in ?A..?Z or char in ?a..?z or char in ?0..?9 or char in '_:') do + space_or_paren in ~c" (" and + (char in ?A..?Z or char in ?a..?z or char in ?0..?9 or char in ~c"_:") do helper else _ -> nil end end - defp squeeze_spaces(' ' ++ rest), do: squeeze_spaces([?\s | rest]) + defp squeeze_spaces(~c" " ++ rest), do: squeeze_spaces([?\s | rest]) defp squeeze_spaces(rest), do: rest @doc false @@ -470,7 +470,7 @@ defmodule IEx.Autocomplete do end defp no do - {:no, '', []} + {:no, ~c"", []} end ## Helpers diff --git a/lib/iex/lib/iex/cli.ex b/lib/iex/lib/iex/cli.ex index 1ba38f8b3..88a832a31 100644 --- a/lib/iex/lib/iex/cli.ex +++ b/lib/iex/lib/iex/cli.ex @@ -79,7 +79,7 @@ defmodule IEx.CLI do # to do it just once. defp tty_works? do try do - port = Port.open({:spawn, 'tty_sl -c -e'}, [:eof]) + port = Port.open({:spawn, ~c"tty_sl -c -e"}, [:eof]) Port.close(port) catch _, _ -> false @@ -157,11 +157,11 @@ defmodule IEx.CLI do {:erlang, :apply, [function, []]} end - defp find_dot_iex(['--dot-iex', h | _]), do: List.to_string(h) + defp find_dot_iex([~c"--dot-iex", h | _]), do: List.to_string(h) defp find_dot_iex([_ | t]), do: find_dot_iex(t) defp find_dot_iex([]), do: nil - defp get_remsh(['--remsh', h | _]), do: List.to_atom(append_hostname(h)) + defp get_remsh([~c"--remsh", h | _]), do: List.to_atom(append_hostname(h)) defp get_remsh([_ | t]), do: get_remsh(t) defp get_remsh([]), do: nil diff --git a/lib/iex/lib/iex/evaluator.ex b/lib/iex/lib/iex/evaluator.ex index f0ea63f9e..734edc3d5 100644 --- a/lib/iex/lib/iex/evaluator.ex +++ b/lib/iex/lib/iex/evaluator.ex @@ -76,7 +76,7 @@ defmodule IEx.Evaluator do opts[:file], "incomplete expression", "", - {'', Keyword.get(opts, :line, 1), Keyword.get(opts, :column, 1)} + {~c"", Keyword.get(opts, :line, 1), Keyword.get(opts, :column, 1)} ) end @@ -128,7 +128,7 @@ defmodule IEx.Evaluator do defp adjust_operator([{op_type, _, _} | _] = tokens, line, column, file, opts, _last_op) when op_type in @op_tokens do - {:ok, prefix} = :elixir.string_to_tokens('v(-1)', line, column, file, opts) + {:ok, prefix} = :elixir.string_to_tokens(~c"v(-1)", line, column, file, opts) {:ok, prefix ++ tokens} end diff --git a/lib/iex/lib/iex/helpers.ex b/lib/iex/lib/iex/helpers.ex index c9ca9d07a..3d04b41b8 100644 --- a/lib/iex/lib/iex/helpers.ex +++ b/lib/iex/lib/iex/helpers.ex @@ -1246,7 +1246,7 @@ defmodule IEx.Helpers do """ def pid(string) when is_binary(string) do - :erlang.list_to_pid('<#{string}>') + :erlang.list_to_pid(~c"<#{string}>") end def pid(name) when is_atom(name) do @@ -1271,9 +1271,9 @@ defmodule IEx.Helpers do def pid(x, y, z) when is_integer(x) and x >= 0 and is_integer(y) and y >= 0 and is_integer(z) and z >= 0 do :erlang.list_to_pid( - '<' ++ + ~c"<" ++ Integer.to_charlist(x) ++ - '.' ++ Integer.to_charlist(y) ++ '.' ++ Integer.to_charlist(z) ++ '>' + ~c"." ++ Integer.to_charlist(y) ++ ~c"." ++ Integer.to_charlist(z) ++ ~c">" ) end @@ -1288,7 +1288,7 @@ defmodule IEx.Helpers do """ @doc since: "1.8.0" def port(string) when is_binary(string) do - :erlang.list_to_port('#Port<#{string}>') + :erlang.list_to_port(~c"#Port<#{string}>") end @doc """ @@ -1306,7 +1306,7 @@ defmodule IEx.Helpers do def port(major, minor) when is_integer(major) and major >= 0 and is_integer(minor) and minor >= 0 do :erlang.list_to_port( - '#Port<' ++ Integer.to_charlist(major) ++ '.' ++ Integer.to_charlist(minor) ++ '>' + ~c"#Port<" ++ Integer.to_charlist(major) ++ ~c"." ++ Integer.to_charlist(minor) ++ ~c">" ) end @@ -1321,7 +1321,7 @@ defmodule IEx.Helpers do """ @doc since: "1.6.0" def ref(string) when is_binary(string) do - :erlang.list_to_ref('#Ref<#{string}>') + :erlang.list_to_ref(~c"#Ref<#{string}>") end @doc """ @@ -1338,11 +1338,11 @@ defmodule IEx.Helpers do when is_integer(w) and w >= 0 and is_integer(x) and x >= 0 and is_integer(y) and y >= 0 and is_integer(z) and z >= 0 do :erlang.list_to_ref( - '#Ref<' ++ + ~c"#Ref<" ++ Integer.to_charlist(w) ++ - '.' ++ + ~c"." ++ Integer.to_charlist(x) ++ - '.' ++ Integer.to_charlist(y) ++ '.' ++ Integer.to_charlist(z) ++ '>' + ~c"." ++ Integer.to_charlist(y) ++ ~c"." ++ Integer.to_charlist(z) ++ ~c">" ) end diff --git a/lib/iex/test/iex/autocomplete_test.exs b/lib/iex/test/iex/autocomplete_test.exs index 43e02d62b..659f56117 100644 --- a/lib/iex/test/iex/autocomplete_test.exs +++ b/lib/iex/test/iex/autocomplete_test.exs @@ -23,72 +23,78 @@ defmodule IEx.AutocompleteTest do end test "Erlang module completion" do - assert expand(':zl') == {:yes, 'ib', []} + assert expand(~c":zl") == {:yes, ~c"ib", []} end test "Erlang module no completion" do - assert expand(':unknown') == {:no, '', []} + assert expand(~c":unknown") == {:no, ~c"", []} end test "Erlang module multiple values completion" do - {:yes, '', list} = expand(':user') - assert 'user' in list - assert 'user_drv' in list + {:yes, ~c"", list} = expand(~c":user") + assert ~c"user" in list + assert ~c"user_drv" in list end test "Erlang root completion" do - {:yes, '', list} = expand(':') + {:yes, ~c"", list} = expand(~c":") assert is_list(list) - assert 'lists' in list - assert 'Elixir.List' not in list + assert ~c"lists" in list + assert ~c"Elixir.List" not in list end test "Elixir proxy" do - {:yes, '', list} = expand('E') - assert 'Elixir' in list + {:yes, ~c"", list} = expand(~c"E") + assert ~c"Elixir" in list end test "Elixir completion" do - assert expand('En') == {:yes, 'um', []} - assert expand('Enumera') == {:yes, 'ble', []} + assert expand(~c"En") == {:yes, ~c"um", []} + assert expand(~c"Enumera") == {:yes, ~c"ble", []} end test "Elixir type completion" do - assert expand('t :gen_ser') == {:yes, 'ver', []} - assert expand('t String') == {:yes, '', ['String', 'StringIO']} - assert expand('t String.') == {:yes, '', ['codepoint/0', 'grapheme/0', 'pattern/0', 't/0']} - assert expand('t String.grap') == {:yes, 'heme', []} - assert expand('t String.grap') == {:yes, 'heme', []} - assert {:yes, '', ['date_time/0' | _]} = expand('t :file.') - assert expand('t :file.n') == {:yes, 'ame', []} + assert expand(~c"t :gen_ser") == {:yes, ~c"ver", []} + assert expand(~c"t String") == {:yes, ~c"", [~c"String", ~c"StringIO"]} + + assert expand(~c"t String.") == + {:yes, ~c"", [~c"codepoint/0", ~c"grapheme/0", ~c"pattern/0", ~c"t/0"]} + + assert expand(~c"t String.grap") == {:yes, ~c"heme", []} + assert expand(~c"t String.grap") == {:yes, ~c"heme", []} + assert {:yes, ~c"", [~c"date_time/0" | _]} = expand(~c"t :file.") + assert expand(~c"t :file.n") == {:yes, ~c"ame", []} end test "Elixir callback completion" do - assert expand('b :strin') == {:yes, 'g', []} - assert expand('b String') == {:yes, '', ['String', 'StringIO']} - assert expand('b String.') == {:no, '', []} - assert expand('b Access.') == {:yes, '', ['fetch/2', 'get_and_update/3', 'pop/2']} - assert expand('b GenServer.term') == {:yes, 'inate', []} - assert expand('b GenServer.term') == {:yes, 'inate', []} - assert expand('b :gen_server.handle_in') == {:yes, 'fo', []} + assert expand(~c"b :strin") == {:yes, ~c"g", []} + assert expand(~c"b String") == {:yes, ~c"", [~c"String", ~c"StringIO"]} + assert expand(~c"b String.") == {:no, ~c"", []} + assert expand(~c"b Access.") == {:yes, ~c"", [~c"fetch/2", ~c"get_and_update/3", ~c"pop/2"]} + assert expand(~c"b GenServer.term") == {:yes, ~c"inate", []} + assert expand(~c"b GenServer.term") == {:yes, ~c"inate", []} + assert expand(~c"b :gen_server.handle_in") == {:yes, ~c"fo", []} end test "Elixir helper completion with parentheses" do - assert expand('t(:gen_ser') == {:yes, 'ver', []} - assert expand('t(String') == {:yes, '', ['String', 'StringIO']} - assert expand('t(String.') == {:yes, '', ['codepoint/0', 'grapheme/0', 'pattern/0', 't/0']} - assert expand('t(String.grap') == {:yes, 'heme', []} + assert expand(~c"t(:gen_ser") == {:yes, ~c"ver", []} + assert expand(~c"t(String") == {:yes, ~c"", [~c"String", ~c"StringIO"]} + + assert expand(~c"t(String.") == + {:yes, ~c"", [~c"codepoint/0", ~c"grapheme/0", ~c"pattern/0", ~c"t/0"]} + + assert expand(~c"t(String.grap") == {:yes, ~c"heme", []} end test "Elixir completion with self" do - assert expand('Enumerable') == {:yes, '.', []} + assert expand(~c"Enumerable") == {:yes, ~c".", []} end test "Elixir completion on modules from load path" do - assert expand('Str') == {:yes, [], ['Stream', 'String', 'StringIO']} - assert expand('Ma') == {:yes, '', ['Macro', 'Map', 'MapSet', 'MatchError']} - assert expand('Dic') == {:yes, 't', []} - assert expand('Ex') == {:yes, [], ['ExUnit', 'Exception']} + assert expand(~c"Str") == {:yes, [], [~c"Stream", ~c"String", ~c"StringIO"]} + assert expand(~c"Ma") == {:yes, ~c"", [~c"Macro", ~c"Map", ~c"MapSet", ~c"MatchError"]} + assert expand(~c"Dic") == {:yes, ~c"t", []} + assert expand(~c"Ex") == {:yes, [], [~c"ExUnit", ~c"Exception"]} end test "Elixir no completion for underscored functions with no doc" do @@ -101,7 +107,7 @@ defmodule IEx.AutocompleteTest do File.write!("Elixir.Sample.beam", bytecode) assert {:docs_v1, _, _, _, _, _, _} = Code.fetch_docs(Sample) - assert expand('Sample._') == {:yes, '_bar__', []} + assert expand(~c"Sample._") == {:yes, ~c"_bar__", []} after File.rm("Elixir.Sample.beam") :code.purge(Sample) @@ -109,11 +115,11 @@ defmodule IEx.AutocompleteTest do end test "Elixir no completion for default argument functions with doc set to false" do - {:yes, '', available} = expand('String.') - refute Enum.member?(available, 'rjust/2') - assert Enum.member?(available, 'replace/3') + {:yes, ~c"", available} = expand(~c"String.") + refute Enum.member?(available, ~c"rjust/2") + assert Enum.member?(available, ~c"replace/3") - assert expand('String.r') == {:yes, 'e', []} + assert expand(~c"String.r") == {:yes, ~c"e", []} {:module, _, bytecode, _} = defmodule Elixir.DefaultArgumentFunctions do @@ -141,11 +147,13 @@ defmodule IEx.AutocompleteTest do File.write!("Elixir.DefaultArgumentFunctions.beam", bytecode) assert {:docs_v1, _, _, _, _, _, _} = Code.fetch_docs(DefaultArgumentFunctions) - functions_list = ['bar/0', 'biz/2', 'biz/3', 'foo/1', 'foo/2', 'foo/3'] - assert expand('DefaultArgumentFunctions.') == {:yes, '', functions_list} + functions_list = [~c"bar/0", ~c"biz/2", ~c"biz/3", ~c"foo/1", ~c"foo/2", ~c"foo/3"] + assert expand(~c"DefaultArgumentFunctions.") == {:yes, ~c"", functions_list} - assert expand('DefaultArgumentFunctions.bi') == {:yes, 'z', []} - assert expand('DefaultArgumentFunctions.foo') == {:yes, '', ['foo/1', 'foo/2', 'foo/3']} + assert expand(~c"DefaultArgumentFunctions.bi") == {:yes, ~c"z", []} + + assert expand(~c"DefaultArgumentFunctions.foo") == + {:yes, ~c"", [~c"foo/1", ~c"foo/2", ~c"foo/3"]} after File.rm("Elixir.DefaultArgumentFunctions.beam") :code.purge(DefaultArgumentFunctions) @@ -153,150 +161,159 @@ defmodule IEx.AutocompleteTest do end test "Elixir no completion" do - assert expand('.') == {:no, '', []} - assert expand('Xyz') == {:no, '', []} - assert expand('x.Foo') == {:no, '', []} - assert expand('x.Foo.get_by') == {:no, '', []} - assert expand('@foo.bar') == {:no, '', []} + assert expand(~c".") == {:no, ~c"", []} + assert expand(~c"Xyz") == {:no, ~c"", []} + assert expand(~c"x.Foo") == {:no, ~c"", []} + assert expand(~c"x.Foo.get_by") == {:no, ~c"", []} + assert expand(~c"@foo.bar") == {:no, ~c"", []} end test "Elixir root submodule completion" do - assert expand('Elixir.Acce') == {:yes, 'ss', []} + assert expand(~c"Elixir.Acce") == {:yes, ~c"ss", []} end test "Elixir submodule completion" do - assert expand('String.Cha') == {:yes, 'rs', []} + assert expand(~c"String.Cha") == {:yes, ~c"rs", []} end test "Elixir submodule no completion" do - assert expand('IEx.Xyz') == {:no, '', []} + assert expand(~c"IEx.Xyz") == {:no, ~c"", []} end test "function completion" do - assert expand('System.ve') == {:yes, 'rsion', []} - assert expand(':ets.fun2') == {:yes, 'ms', []} + assert expand(~c"System.ve") == {:yes, ~c"rsion", []} + assert expand(~c":ets.fun2") == {:yes, ~c"ms", []} end test "function completion with arity" do - assert expand('String.printable?') == {:yes, '', ['printable?/1', 'printable?/2']} - assert expand('String.printable?/') == {:yes, '', ['printable?/1', 'printable?/2']} + assert expand(~c"String.printable?") == {:yes, ~c"", [~c"printable?/1", ~c"printable?/2"]} + assert expand(~c"String.printable?/") == {:yes, ~c"", [~c"printable?/1", ~c"printable?/2"]} - assert expand('Enum.count') == - {:yes, '', ['count/1', 'count/2', 'count_until/2', 'count_until/3']} + assert expand(~c"Enum.count") == + {:yes, ~c"", [~c"count/1", ~c"count/2", ~c"count_until/2", ~c"count_until/3"]} - assert expand('Enum.count/') == {:yes, '', ['count/1', 'count/2']} + assert expand(~c"Enum.count/") == {:yes, ~c"", [~c"count/1", ~c"count/2"]} end test "operator completion" do - assert expand('+') == {:yes, '', ['+/1', '+/2', '++/2']} - assert expand('+/') == {:yes, '', ['+/1', '+/2']} - assert expand('++/') == {:yes, '', ['++/2']} + assert expand(~c"+") == {:yes, ~c"", [~c"+/1", ~c"+/2", ~c"++/2"]} + assert expand(~c"+/") == {:yes, ~c"", [~c"+/1", ~c"+/2"]} + assert expand(~c"++/") == {:yes, ~c"", [~c"++/2"]} end test "sigil completion" do - {:yes, '', sigils} = expand('~') - assert '~C (sigil_C)' in sigils - {:yes, '', sigils} = expand('~r') - assert '"' in sigils - assert '(' in sigils + {:yes, ~c"", sigils} = expand(~c"~") + assert ~c"~C (sigil_C)" in sigils + {:yes, ~c"", sigils} = expand(~c"~r") + assert ~c"\"" in sigils + assert ~c"(" in sigils end test "function completion using a variable bound to a module" do eval("mod = String") - assert expand('mod.print') == {:yes, 'able?', []} + assert expand(~c"mod.print") == {:yes, ~c"able?", []} end test "map atom key completion is supported" do eval("map = %{foo: 1, bar_1: 23, bar_2: 14}") - assert expand('map.f') == {:yes, 'oo', []} - assert expand('map.b') == {:yes, 'ar_', []} - assert expand('map.bar_') == {:yes, '', ['bar_1', 'bar_2']} - assert expand('map.c') == {:no, '', []} - assert expand('map.') == {:yes, '', ['bar_1', 'bar_2', 'foo']} - assert expand('map.foo') == {:no, '', []} + assert expand(~c"map.f") == {:yes, ~c"oo", []} + assert expand(~c"map.b") == {:yes, ~c"ar_", []} + assert expand(~c"map.bar_") == {:yes, ~c"", [~c"bar_1", ~c"bar_2"]} + assert expand(~c"map.c") == {:no, ~c"", []} + assert expand(~c"map.") == {:yes, ~c"", [~c"bar_1", ~c"bar_2", ~c"foo"]} + assert expand(~c"map.foo") == {:no, ~c"", []} end test "nested map atom key completion is supported" do eval("map = %{nested: %{deeply: %{foo: 1, bar_1: 23, bar_2: 14, mod: String, num: 1}}}") - assert expand('map.nested.deeply.f') == {:yes, 'oo', []} - assert expand('map.nested.deeply.b') == {:yes, 'ar_', []} - assert expand('map.nested.deeply.bar_') == {:yes, '', ['bar_1', 'bar_2']} - assert expand('map.nested.deeply.') == {:yes, '', ['bar_1', 'bar_2', 'foo', 'mod', 'num']} - assert expand('map.nested.deeply.mod.print') == {:yes, 'able?', []} + assert expand(~c"map.nested.deeply.f") == {:yes, ~c"oo", []} + assert expand(~c"map.nested.deeply.b") == {:yes, ~c"ar_", []} + assert expand(~c"map.nested.deeply.bar_") == {:yes, ~c"", [~c"bar_1", ~c"bar_2"]} + + assert expand(~c"map.nested.deeply.") == + {:yes, ~c"", [~c"bar_1", ~c"bar_2", ~c"foo", ~c"mod", ~c"num"]} + + assert expand(~c"map.nested.deeply.mod.print") == {:yes, ~c"able?", []} - assert expand('map.nested') == {:yes, '.', []} - assert expand('map.nested.deeply') == {:yes, '.', []} - assert expand('map.nested.deeply.foo') == {:no, '', []} + assert expand(~c"map.nested") == {:yes, ~c".", []} + assert expand(~c"map.nested.deeply") == {:yes, ~c".", []} + assert expand(~c"map.nested.deeply.foo") == {:no, ~c"", []} - assert expand('map.nested.deeply.c') == {:no, '', []} - assert expand('map.a.b.c.f') == {:no, '', []} + assert expand(~c"map.nested.deeply.c") == {:no, ~c"", []} + assert expand(~c"map.a.b.c.f") == {:no, ~c"", []} end test "map string key completion is not supported" do eval(~S(map = %{"foo" => 1})) - assert expand('map.f') == {:no, '', []} + assert expand(~c"map.f") == {:no, ~c"", []} end test "bound variables for modules and maps" do eval("num = 5; map = %{nested: %{num: 23}}") - assert expand('num.print') == {:no, '', []} - assert expand('map.nested.num.f') == {:no, '', []} - assert expand('map.nested.num.key.f') == {:no, '', []} + assert expand(~c"num.print") == {:no, ~c"", []} + assert expand(~c"map.nested.num.f") == {:no, ~c"", []} + assert expand(~c"map.nested.num.key.f") == {:no, ~c"", []} end test "access syntax is not supported" do eval("map = %{nested: %{deeply: %{num: 23}}}") - assert expand('map[:nested][:deeply].n') == {:no, '', []} - assert expand('map[:nested].deeply.n') == {:no, '', []} - assert expand('map.nested.[:deeply].n') == {:no, '', []} + assert expand(~c"map[:nested][:deeply].n") == {:no, ~c"", []} + assert expand(~c"map[:nested].deeply.n") == {:no, ~c"", []} + assert expand(~c"map.nested.[:deeply].n") == {:no, ~c"", []} end test "unbound variables is not supported" do eval("num = 5") - assert expand('other_var.f') == {:no, '', []} - assert expand('a.b.c.d') == {:no, '', []} + assert expand(~c"other_var.f") == {:no, ~c"", []} + assert expand(~c"a.b.c.d") == {:no, ~c"", []} end test "macro completion" do - {:yes, '', list} = expand('Kernel.is_') + {:yes, ~c"", list} = expand(~c"Kernel.is_") assert is_list(list) end test "imports completion" do - {:yes, '', list} = expand('') + {:yes, ~c"", list} = expand(~c"") assert is_list(list) - assert 'h/1' in list - assert 'unquote/1' in list - assert 'pwd/0' in list + assert ~c"h/1" in list + assert ~c"unquote/1" in list + assert ~c"pwd/0" in list end test "kernel import completion" do - assert expand('defstru') == {:yes, 'ct', []} - assert expand('put_') == {:yes, '', ['put_elem/3', 'put_in/2', 'put_in/3']} + assert expand(~c"defstru") == {:yes, ~c"ct", []} + assert expand(~c"put_") == {:yes, ~c"", [~c"put_elem/3", ~c"put_in/2", ~c"put_in/3"]} end test "variable name completion" do eval("numeral = 3; number = 3; nothing = nil") - assert expand('numb') == {:yes, 'er', []} - assert expand('num') == {:yes, '', ['number', 'numeral']} - assert expand('no') == {:yes, '', ['nothing', 'node/0', 'node/1', 'not/1']} + assert expand(~c"numb") == {:yes, ~c"er", []} + assert expand(~c"num") == {:yes, ~c"", [~c"number", ~c"numeral"]} + assert expand(~c"no") == {:yes, ~c"", [~c"nothing", ~c"node/0", ~c"node/1", ~c"not/1"]} end test "completion of manually imported functions and macros" do eval("import Enum; import Supervisor, only: [count_children: 1]; import Protocol") - assert expand('der') == {:yes, 'ive', []} + assert expand(~c"der") == {:yes, ~c"ive", []} - assert expand('take') == - {:yes, '', ['take/2', 'take_every/2', 'take_random/2', 'take_while/2']} + assert expand(~c"take") == + {:yes, ~c"", [~c"take/2", ~c"take_every/2", ~c"take_random/2", ~c"take_while/2"]} - assert expand('take/') == {:yes, '', ['take/2']} + assert expand(~c"take/") == {:yes, ~c"", [~c"take/2"]} - assert expand('count') == - {:yes, '', - ['count/1', 'count/2', 'count_children/1', 'count_until/2', 'count_until/3']} + assert expand(~c"count") == + {:yes, ~c"", + [ + ~c"count/1", + ~c"count/2", + ~c"count_children/1", + ~c"count_until/2", + ~c"count_until/3" + ]} - assert expand('count/') == {:yes, '', ['count/1', 'count/2']} + assert expand(~c"count/") == {:yes, ~c"", [~c"count/1", ~c"count/2"]} end defmacro define_var do @@ -305,40 +322,40 @@ defmodule IEx.AutocompleteTest do test "ignores quoted variables when performing variable completion" do eval("require #{__MODULE__}; #{__MODULE__}.define_var(); my_var_2 = 2") - assert expand('my_var') == {:yes, '_2', []} + assert expand(~c"my_var") == {:yes, ~c"_2", []} end test "kernel special form completion" do - assert expand('unquote_spl') == {:yes, 'icing', []} + assert expand(~c"unquote_spl") == {:yes, ~c"icing", []} end test "completion inside expression" do - assert expand('1 En') == {:yes, 'um', []} - assert expand('Test(En') == {:yes, 'um', []} - assert expand('Test :zl') == {:yes, 'ib', []} - assert expand('[:zl') == {:yes, 'ib', []} - assert expand('{:zl') == {:yes, 'ib', []} + assert expand(~c"1 En") == {:yes, ~c"um", []} + assert expand(~c"Test(En") == {:yes, ~c"um", []} + assert expand(~c"Test :zl") == {:yes, ~c"ib", []} + assert expand(~c"[:zl") == {:yes, ~c"ib", []} + assert expand(~c"{:zl") == {:yes, ~c"ib", []} end defmodule SublevelTest.LevelA.LevelB do end test "Elixir completion sublevel" do - assert expand('IEx.AutocompleteTest.SublevelTest.') == {:yes, 'LevelA', []} + assert expand(~c"IEx.AutocompleteTest.SublevelTest.") == {:yes, ~c"LevelA", []} end test "complete aliases of Elixir modules" do eval("alias List, as: MyList") - assert expand('MyL') == {:yes, 'ist', []} - assert expand('MyList') == {:yes, '.', []} - assert expand('MyList.to_integer') == {:yes, [], ['to_integer/1', 'to_integer/2']} + assert expand(~c"MyL") == {:yes, ~c"ist", []} + assert expand(~c"MyList") == {:yes, ~c".", []} + assert expand(~c"MyList.to_integer") == {:yes, [], [~c"to_integer/1", ~c"to_integer/2"]} end test "complete aliases of Erlang modules" do eval("alias :lists, as: EList") - assert expand('EL') == {:yes, 'ist', []} - assert expand('EList') == {:yes, '.', []} - assert expand('EList.map') == {:yes, [], ['map/2', 'mapfoldl/3', 'mapfoldr/3']} + assert expand(~c"EL") == {:yes, ~c"ist", []} + assert expand(~c"EList") == {:yes, ~c".", []} + assert expand(~c"EList.map") == {:yes, [], [~c"map/2", ~c"mapfoldl/3", ~c"mapfoldr/3"]} end test "completion for functions added when compiled module is reloaded" do @@ -349,7 +366,7 @@ defmodule IEx.AutocompleteTest do File.write!("Elixir.IEx.AutocompleteTest.Sample.beam", bytecode) assert {:docs_v1, _, _, _, _, _, _} = Code.fetch_docs(Sample) - assert expand('IEx.AutocompleteTest.Sample.foo') == {:yes, '', ['foo/0']} + assert expand(~c"IEx.AutocompleteTest.Sample.foo") == {:yes, ~c"", [~c"foo/0"]} Code.compiler_options(ignore_module_conflict: true) @@ -358,7 +375,7 @@ defmodule IEx.AutocompleteTest do def foobar(), do: 0 end - assert expand('IEx.AutocompleteTest.Sample.foo') == {:yes, '', ['foo/0', 'foobar/0']} + assert expand(~c"IEx.AutocompleteTest.Sample.foo") == {:yes, ~c"", [~c"foo/0", ~c"foobar/0"]} after File.rm("Elixir.IEx.AutocompleteTest.Sample.beam") Code.compiler_options(ignore_module_conflict: false) @@ -371,81 +388,81 @@ defmodule IEx.AutocompleteTest do end test "completion for struct names" do - assert {:yes, '', entries} = expand('%') - assert 'URI' in entries - assert 'IEx.History' in entries - assert 'IEx.State' in entries + assert {:yes, ~c"", entries} = expand(~c"%") + assert ~c"URI" in entries + assert ~c"IEx.History" in entries + assert ~c"IEx.State" in entries - assert {:yes, '', entries} = expand('%IEx.') - assert 'IEx.History' in entries - assert 'IEx.State' in entries + assert {:yes, ~c"", entries} = expand(~c"%IEx.") + assert ~c"IEx.History" in entries + assert ~c"IEx.State" in entries - assert expand('%IEx.AutocompleteTe') == {:yes, 'st.MyStruct{', []} - assert expand('%IEx.AutocompleteTest.MyStr') == {:yes, 'uct{', []} + assert expand(~c"%IEx.AutocompleteTe") == {:yes, ~c"st.MyStruct{", []} + assert expand(~c"%IEx.AutocompleteTest.MyStr") == {:yes, ~c"uct{", []} eval("alias IEx.AutocompleteTest.MyStruct") - assert expand('%MyStr') == {:yes, 'uct{', []} + assert expand(~c"%MyStr") == {:yes, ~c"uct{", []} end test "completion for struct keys" do - assert {:yes, '', entries} = expand('%URI{') - assert 'path:' in entries - assert 'query:' in entries + assert {:yes, ~c"", entries} = expand(~c"%URI{") + assert ~c"path:" in entries + assert ~c"query:" in entries - assert {:yes, '', entries} = expand('%URI{path: "foo",') - assert 'path:' not in entries - assert 'query:' in entries + assert {:yes, ~c"", entries} = expand(~c"%URI{path: \"foo\",") + assert ~c"path:" not in entries + assert ~c"query:" in entries - assert {:yes, 'ry: ', []} = expand('%URI{path: "foo", que') - assert {:no, [], []} = expand('%URI{path: "foo", unkno') - assert {:no, [], []} = expand('%Unkown{path: "foo", unkno') + assert {:yes, ~c"ry: ", []} = expand(~c"%URI{path: \"foo\", que") + assert {:no, [], []} = expand(~c"%URI{path: \"foo\", unkno") + assert {:no, [], []} = expand(~c"%Unkown{path: \"foo\", unkno") end test "completion for struct var keys" do eval("struct = %IEx.AutocompleteTest.MyStruct{}") - assert expand('struct.my') == {:yes, '_val', []} + assert expand(~c"struct.my") == {:yes, ~c"_val", []} end test "completion for bitstring modifiers" do - assert {:yes, '', entries} = expand('< - send(self(), expand('reduce(')) + send(self(), expand(~c"reduce(")) end) == "\nreduce(enumerable, acc, fun)" - assert_received {:yes, '', ['reduce(enumerable, fun)']} + assert_received {:yes, ~c"", [~c"reduce(enumerable, fun)"]} - assert expand('take(') == {:yes, '', ['take(enumerable, amount)']} - assert expand('derive(') == {:yes, '', ['derive(protocol, module, options \\\\ [])']} + assert expand(~c"take(") == {:yes, ~c"", [~c"take(enumerable, amount)"]} + assert expand(~c"derive(") == {:yes, ~c"", [~c"derive(protocol, module, options \\\\ [])"]} defmodule NoDocs do def sample(a), do: a end - assert {:yes, [], [_ | _]} = expand('NoDocs.sample(') + assert {:yes, [], [_ | _]} = expand(~c"NoDocs.sample(") end @tag :tmp_dir @@ -457,21 +474,21 @@ defmodule IEx.AutocompleteTest do dir |> Path.join("dir/file3") |> File.touch() dir |> Path.join("dir/file4") |> File.touch() - assert expand('"./') == path_autocompletion(".") - assert expand('"/') == path_autocompletion("/") - assert expand('"./#\{') == expand('{') - assert expand('"./#\{Str') == expand('{Str') - assert expand('Path.join("./", is_') == expand('is_') + assert expand(~c"\"./") == path_autocompletion(".") + assert expand(~c"\"/") == path_autocompletion("/") + assert expand(~c"\"./#\{") == expand(~c"{") + assert expand(~c"\"./#\{Str") == expand(~c"{Str") + assert expand(~c"Path.join(\"./\", is_") == expand(~c"is_") - assert expand('"#{dir}/') == path_autocompletion(dir) - assert expand('"#{dir}/sin') == {:yes, 'gle1', []} - assert expand('"#{dir}/single1') == {:yes, '"', []} - assert expand('"#{dir}/fi') == {:yes, 'le', []} - assert expand('"#{dir}/file') == path_autocompletion(dir, "file") - assert expand('"#{dir}/d') == {:yes, 'ir/', []} - assert expand('"#{dir}/dir') == {:yes, '/', []} - assert expand('"#{dir}/dir/') == {:yes, 'file', []} - assert expand('"#{dir}/dir/file') == dir |> Path.join("dir") |> path_autocompletion("file") + assert expand(~c"\"#{dir}/") == path_autocompletion(dir) + assert expand(~c"\"#{dir}/sin") == {:yes, ~c"gle1", []} + assert expand(~c"\"#{dir}/single1") == {:yes, ~c"\"", []} + assert expand(~c"\"#{dir}/fi") == {:yes, ~c"le", []} + assert expand(~c"\"#{dir}/file") == path_autocompletion(dir, "file") + assert expand(~c"\"#{dir}/d") == {:yes, ~c"ir/", []} + assert expand(~c"\"#{dir}/dir") == {:yes, ~c"/", []} + assert expand(~c"\"#{dir}/dir/") == {:yes, ~c"file", []} + assert expand(~c"\"#{dir}/dir/file") == dir |> Path.join("dir") |> path_autocompletion("file") end defp path_autocompletion(dir, hint \\ "") do @@ -480,8 +497,8 @@ defmodule IEx.AutocompleteTest do |> Stream.filter(&String.starts_with?(&1, hint)) |> Enum.map(&String.to_charlist/1) |> case do - [] -> {:no, '', []} - list -> {:yes, '', list} + [] -> {:no, ~c"", []} + list -> {:yes, ~c"", list} end end end diff --git a/lib/iex/test/iex/helpers_test.exs b/lib/iex/test/iex/helpers_test.exs index abb700856..b0787f6ea 100644 --- a/lib/iex/test/iex/helpers_test.exs +++ b/lib/iex/test/iex/helpers_test.exs @@ -1449,7 +1449,7 @@ defmodule IEx.HelpersTest do defstruct [] defimpl IEx.Info do - def info(_), do: [{"A", "it's A"}, {:b, "it's :b"}, {'c', "it's 'c'"}] + def info(_), do: [{"A", "it's A"}, {:b, "it's :b"}, {~c"c", "it's 'c'"}] end end diff --git a/lib/iex/test/iex/info_test.exs b/lib/iex/test/iex/info_test.exs index 33f0794de..79ff5a5be 100644 --- a/lib/iex/test/iex/info_test.exs +++ b/lib/iex/test/iex/info_test.exs @@ -62,7 +62,7 @@ defmodule IEx.InfoTest do describe "lists" do test "charlists" do - info = Info.info('foo') + info = Info.info(~c"foo") assert get_key(info, "Description") =~ "This is a list of integers that is printed" assert get_key(info, "Raw representation") == "[102, 111, 111]" end diff --git a/lib/logger/lib/logger/formatter.ex b/lib/logger/lib/logger/formatter.ex index 02e7c2dbc..c8f106d32 100644 --- a/lib/logger/lib/logger/formatter.ex +++ b/lib/logger/lib/logger/formatter.ex @@ -263,7 +263,7 @@ defmodule Logger.Formatter do end defp metadata(_, ref) when is_reference(ref) do - '#Ref' ++ rest = :erlang.ref_to_list(ref) + ~c"#Ref" ++ rest = :erlang.ref_to_list(ref) rest end diff --git a/lib/logger/lib/logger/translator.ex b/lib/logger/lib/logger/translator.ex index 1d99f1f5e..a7612f150 100644 --- a/lib/logger/lib/logger/translator.ex +++ b/lib/logger/lib/logger/translator.ex @@ -107,7 +107,7 @@ defmodule Logger.Translator do case message do # This is no longer emitted by Erlang/OTP but it may be # manually emitted by libraries like connection. - {'** Generic server ' ++ _, [name, last, state, reason | client]} -> + {~c"** Generic server " ++ _, [name, last, state, reason | client]} -> opts = Application.fetch_env!(:logger, :translator_inspect_opts) {formatted, reason} = format_reason(reason) metadata = [crash_reason: reason] ++ registered_name(name) @@ -123,7 +123,7 @@ defmodule Logger.Translator do {:ok, msg, metadata} end - {'Error in process ' ++ _, [pid, node, {reason, stack}]} -> + {~c"Error in process " ++ _, [pid, node, {reason, stack}]} -> reason = Exception.normalize(:error, reason, stack) msg = [ @@ -136,7 +136,7 @@ defmodule Logger.Translator do {:ok, msg, [crash_reason: exit_reason(:error, reason, stack)]} - {'Error in process ' ++ _, [pid, {reason, stack}]} -> + {~c"Error in process " ++ _, [pid, {reason, stack}]} -> reason = Exception.normalize(:error, reason, stack) msg = ["Process ", inspect(pid), " raised an exception" | format(:error, reason, stack)] {:ok, msg, [crash_reason: exit_reason(:error, reason, stack)]} diff --git a/lib/logger/lib/logger/utils.ex b/lib/logger/lib/logger/utils.ex index d9ebee5c1..19e00b8fa 100644 --- a/lib/logger/lib/logger/utils.ex +++ b/lib/logger/lib/logger/utils.ex @@ -137,7 +137,7 @@ defmodule Logger.Utils do width: :none } - defp handle_format_spec(%{control_char: char} = spec, opts) when char in 'wWpP' do + defp handle_format_spec(%{control_char: char} = spec, opts) when char in ~c"wWpP" do %{args: args, width: width, strings: strings?} = spec opts = %{ @@ -155,10 +155,10 @@ defmodule Logger.Utils do defp inspect_charlists(false, _), do: :as_lists defp inspect_charlists(_, opts), do: opts.charlists - defp inspect_limit(char, [_, limit], _) when char in 'WP', do: limit + defp inspect_limit(char, [_, limit], _) when char in ~c"WP", do: limit defp inspect_limit(_, _, opts), do: opts.limit - defp inspect_width(char, _) when char in 'wW', do: :infinity + defp inspect_width(char, _) when char in ~c"wW", do: :infinity defp inspect_width(_, width), do: width defp inspect_data([data | _], opts) do diff --git a/lib/logger/test/logger/formatter_test.exs b/lib/logger/test/logger/formatter_test.exs index 12b5dd4b4..6daf8b8b3 100644 --- a/lib/logger/test/logger/formatter_test.exs +++ b/lib/logger/test/logger/formatter_test.exs @@ -51,7 +51,7 @@ defmodule Logger.FormatterTest do format = format(compiled, :error, nil, nil, meta: :data) assert IO.chardata_to_string(format) == "meta=data " - pid = :erlang.list_to_pid('<0.123.4>') + pid = :erlang.list_to_pid(~c"<0.123.4>") format = format(compiled, :error, nil, nil, meta: :data, pid: pid) assert IO.chardata_to_string(format) == "meta=data pid=<0.123.4> " diff --git a/lib/logger/test/logger/handler_test.exs b/lib/logger/test/logger/handler_test.exs index 95298063f..a1ac5a2fe 100644 --- a/lib/logger/test/logger/handler_test.exs +++ b/lib/logger/test/logger/handler_test.exs @@ -3,11 +3,11 @@ defmodule Logger.HandlerTest do @moduletag :logger defmodule CustomTranslator do - def t(:debug, :info, :format, {'hello: ~p', [:ok]}) do + def t(:debug, :info, :format, {~c"hello: ~p", [:ok]}) do :skip end - def t(:debug, :info, :format, {'world: ~p', [:ok]}) do + def t(:debug, :info, :format, {~c"world: ~p", [:ok]}) do {:ok, "rewritten"} end @@ -32,11 +32,11 @@ defmodule Logger.HandlerTest do assert Logger.add_translator({CustomTranslator, :t}) assert capture_log(fn -> - :error_logger.info_msg('hello: ~p', [:ok]) + :error_logger.info_msg(~c"hello: ~p", [:ok]) end) == "" assert capture_log(fn -> - :error_logger.info_msg('world: ~p', [:ok]) + :error_logger.info_msg(~c"world: ~p", [:ok]) end) =~ "[notice] rewritten" after assert Logger.remove_translator({CustomTranslator, :t}) @@ -46,11 +46,11 @@ defmodule Logger.HandlerTest do assert Logger.add_translator({CustomTranslator, :t}) assert capture_log(fn -> - :logger.info('hello: ~p', [:ok]) + :logger.info(~c"hello: ~p", [:ok]) end) == "" assert capture_log(fn -> - :logger.info('world: ~p', [:ok]) + :logger.info(~c"world: ~p", [:ok]) end) =~ "[info] rewritten" assert capture_log(fn -> @@ -79,7 +79,7 @@ defmodule Logger.HandlerTest do message = capture_log(fn -> - :logger.info("ok", %{file: 'file.erl', line: 13, mfa: {Foo, :bar, 3}}) + :logger.info("ok", %{file: ~c"file.erl", line: 13, mfa: {Foo, :bar, 3}}) end) assert message =~ "module=Foo" @@ -98,30 +98,30 @@ defmodule Logger.HandlerTest do end test "uses Erlang log levels" do - assert capture_log(fn -> :logger.emergency('ok') end) =~ "[emergency] ok" - assert capture_log(fn -> :logger.alert('ok') end) =~ "[alert] ok" - assert capture_log(fn -> :logger.critical('ok') end) =~ "[critical] ok" - assert capture_log(fn -> :logger.error('ok') end) =~ "[error] ok" - assert capture_log(fn -> :logger.warning('ok') end) =~ "[warning] ok" - assert capture_log(fn -> :logger.notice('ok') end) =~ "[notice] ok" - assert capture_log(fn -> :logger.info('ok') end) =~ "[info] ok" - assert capture_log(fn -> :logger.debug('ok') end) =~ "[debug] ok" + assert capture_log(fn -> :logger.emergency(~c"ok") end) =~ "[emergency] ok" + assert capture_log(fn -> :logger.alert(~c"ok") end) =~ "[alert] ok" + assert capture_log(fn -> :logger.critical(~c"ok") end) =~ "[critical] ok" + assert capture_log(fn -> :logger.error(~c"ok") end) =~ "[error] ok" + assert capture_log(fn -> :logger.warning(~c"ok") end) =~ "[warning] ok" + assert capture_log(fn -> :logger.notice(~c"ok") end) =~ "[notice] ok" + assert capture_log(fn -> :logger.info(~c"ok") end) =~ "[info] ok" + assert capture_log(fn -> :logger.debug(~c"ok") end) =~ "[debug] ok" end test "include Erlang severity level information" do Logger.configure_backend(:console, metadata: [:erl_level]) - assert capture_log(fn -> :logger.emergency('ok') end) =~ "erl_level=emergency" - assert capture_log(fn -> :logger.alert('ok') end) =~ "erl_level=alert" - assert capture_log(fn -> :logger.critical('ok') end) =~ "erl_level=critical" - assert capture_log(fn -> :logger.error('ok') end) =~ "erl_level=error" - assert capture_log(fn -> :logger.warning('ok') end) =~ "erl_level=warning" - assert capture_log(fn -> :logger.info('ok') end) =~ "erl_level=info" - assert capture_log(fn -> :logger.debug('ok') end) =~ "erl_level=debug" + assert capture_log(fn -> :logger.emergency(~c"ok") end) =~ "erl_level=emergency" + assert capture_log(fn -> :logger.alert(~c"ok") end) =~ "erl_level=alert" + assert capture_log(fn -> :logger.critical(~c"ok") end) =~ "erl_level=critical" + assert capture_log(fn -> :logger.error(~c"ok") end) =~ "erl_level=error" + assert capture_log(fn -> :logger.warning(~c"ok") end) =~ "erl_level=warning" + assert capture_log(fn -> :logger.info(~c"ok") end) =~ "erl_level=info" + assert capture_log(fn -> :logger.debug(~c"ok") end) =~ "erl_level=debug" [:emergency, :alert, :critical, :error, :warning, :notice, :info, :debug] |> Enum.each(fn level -> - assert capture_log(fn -> :logger.log(level, 'ok') end) =~ "erl_level=#{level}" + assert capture_log(fn -> :logger.log(level, ~c"ok") end) =~ "erl_level=#{level}" end) after Logger.configure_backend(:console, metadata: []) @@ -182,7 +182,7 @@ defmodule Logger.HandlerTest do defp format_report(report) do send(self(), {:format, report}) - {'~p', [report]} + {~c"~p", [report]} end defp format_report(report, opts) do diff --git a/lib/logger/test/logger/translator_test.exs b/lib/logger/test/logger/translator_test.exs index 673843b78..0cb368edc 100644 --- a/lib/logger/test/logger/translator_test.exs +++ b/lib/logger/test/logger/translator_test.exs @@ -993,7 +993,7 @@ defmodule Logger.TranslatorTest do :error, :error, :format, - {'Error in process ~p on node ~p with exit value:~n~p~n', + {~c"Error in process ~p on node ~p with exit value:~n~p~n", [self(), :"name@127.0.0.1", {:badarith, [{:erlang, :/, [1, 0], []}]}]} ) diff --git a/lib/logger/test/logger/utils_test.exs b/lib/logger/test/logger/utils_test.exs index 9b50b84b4..0ed92a900 100644 --- a/lib/logger/test/logger/utils_test.exs +++ b/lib/logger/test/logger/utils_test.exs @@ -26,14 +26,14 @@ defmodule Logger.UtilsTest do assert truncate("𠜎𠜱𠝹𠱓", 15) == ["𠜎𠜱𠝹", " (truncated)"] # Charlists - assert truncate('olá', 2) == ['olá', " (truncated)"] - assert truncate('olá', 3) == ['olá', " (truncated)"] - assert truncate('olá', 4) == 'olá' + assert truncate(~c"olá", 2) == [~c"olá", " (truncated)"] + assert truncate(~c"olá", 3) == [~c"olá", " (truncated)"] + assert truncate(~c"olá", 4) == ~c"olá" # Chardata - assert truncate('ol' ++ "á", 2) == ['ol' ++ "", " (truncated)"] - assert truncate('ol' ++ "á", 3) == ['ol' ++ "", " (truncated)"] - assert truncate('ol' ++ "á", 4) == 'ol' ++ "á" + assert truncate(~c"ol" ++ "á", 2) == [~c"ol" ++ "", " (truncated)"] + assert truncate(~c"ol" ++ "á", 3) == [~c"ol" ++ "", " (truncated)"] + assert truncate(~c"ol" ++ "á", 4) == ~c"ol" ++ "á" # :infinity long_string = String.duplicate("foo", 10000) @@ -41,54 +41,58 @@ defmodule Logger.UtilsTest do end test "scan_inspect/3 formats" do - assert inspect('~p', [1]) == {'~ts', [["1"]]} - assert inspect("~p", [1]) == {'~ts', [["1"]]} - assert inspect(:"~p", [1]) == {'~ts', [["1"]]} + assert inspect(~c"~p", [1]) == {~c"~ts", [["1"]]} + assert inspect("~p", [1]) == {~c"~ts", [["1"]]} + assert inspect(:"~p", [1]) == {~c"~ts", [["1"]]} end test "scan_inspect/3 sigils" do - assert inspect('~10.10tp', [1]) == {'~ts', [["1"]]} - assert inspect('~-10.10tp', [1]) == {'~ts', [["1"]]} + assert inspect(~c"~10.10tp", [1]) == {~c"~ts", [["1"]]} + assert inspect(~c"~-10.10tp", [1]) == {~c"~ts", [["1"]]} - assert inspect('~10.10lp', [1]) == {'~ts', [["1"]]} - assert inspect('~10.10x~p~n', [1, 2, 3]) == {'~10.10x~ts~n', [1, 2, ["3"]]} + assert inspect(~c"~10.10lp", [1]) == {~c"~ts", [["1"]]} + assert inspect(~c"~10.10x~p~n", [1, 2, 3]) == {~c"~10.10x~ts~n", [1, 2, ["3"]]} end test "scan_inspect/3 with modifier t has no effect (as it is the default)" do - assert inspect('~tp', [1]) == {'~ts', [["1"]]} - assert inspect('~tw', [1]) == {'~ts', [["1"]]} + assert inspect(~c"~tp", [1]) == {~c"~ts", [["1"]]} + assert inspect(~c"~tw", [1]) == {~c"~ts", [["1"]]} end test "scan_inspect/3 with modifier l always prints lists" do - assert inspect('~lp', ['abc']) == {'~ts', [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} - assert inspect('~lw', ['abc']) == {'~ts', [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} + assert inspect(~c"~lp", [~c"abc"]) == + {~c"~ts", [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} + + assert inspect(~c"~lw", [~c"abc"]) == + {~c"~ts", [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} end test "scan_inspect/3 with modifier for width" do - assert inspect('~5lp', ['abc']) == - {'~ts', [["[", "97", ",", "\n ", "98", ",", "\n ", "99", "]"]]} + assert inspect(~c"~5lp", [~c"abc"]) == + {~c"~ts", [["[", "97", ",", "\n ", "98", ",", "\n ", "99", "]"]]} - assert inspect('~5lw', ['abc']) == {'~ts', [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} + assert inspect(~c"~5lw", [~c"abc"]) == + {~c"~ts", [["[", "97", ",", " ", "98", ",", " ", "99", "]"]]} end test "scan_inspect/3 with modifier for limit" do - assert inspect('~5lP', ['abc', 2]) == - {'~ts', [["[", "97", ",", "\n ", "98", ",", "\n ", "...", "]"]]} + assert inspect(~c"~5lP", [~c"abc", 2]) == + {~c"~ts", [["[", "97", ",", "\n ", "98", ",", "\n ", "...", "]"]]} - assert inspect('~5lW', ['abc', 2]) == - {'~ts', [["[", "97", ",", " ", "98", ",", " ", "...", "]"]]} + assert inspect(~c"~5lW", [~c"abc", 2]) == + {~c"~ts", [["[", "97", ",", " ", "98", ",", " ", "...", "]"]]} end test "scan_inspect/3 truncates binaries" do - assert inspect('~ts', ["abcdeabcdeabcdeabcde"]) == {'~ts', ["abcdeabcde"]} + assert inspect(~c"~ts", ["abcdeabcdeabcdeabcde"]) == {~c"~ts", ["abcdeabcde"]} - assert inspect('~ts~ts~ts', ["abcdeabcde", "abcde", "abcde"]) == - {'~ts~ts~ts', ["abcdeabcde", "", ""]} + assert inspect(~c"~ts~ts~ts", ["abcdeabcde", "abcde", "abcde"]) == + {~c"~ts~ts~ts", ["abcdeabcde", "", ""]} end test "scan_inspect/3 with :infinity truncate" do long_string = String.duplicate("foo", 10000) - assert inspect('~ts', [long_string], :infinity) == {'~ts', [long_string]} + assert inspect(~c"~ts", [long_string], :infinity) == {~c"~ts", [long_string]} end test "timestamp/1" do diff --git a/lib/logger/test/logger_test.exs b/lib/logger/test/logger_test.exs index 294f8a1c2..68274fb71 100644 --- a/lib/logger/test/logger_test.exs +++ b/lib/logger/test/logger_test.exs @@ -318,7 +318,7 @@ defmodule LoggerTest do describe "log with function" do test "supports iolist" do - fun = fn -> ["ok", ?:, 'example'] end + fun = fn -> ["ok", ?:, ~c"example"] end assert capture_log(fn -> assert Logger.bare_log(:info, fun, application: nil, module: FunctionTest) == :ok diff --git a/lib/mix/lib/mix/dep/elixir_scm.ex b/lib/mix/lib/mix/dep/elixir_scm.ex index e0925d80c..8dea5ea1b 100644 --- a/lib/mix/lib/mix/dep/elixir_scm.ex +++ b/lib/mix/lib/mix/dep/elixir_scm.ex @@ -26,7 +26,7 @@ defmodule Mix.Dep.ElixirSCM do {@manifest_vsn, vsn, scm} = :erlang.binary_to_term(contents) {:ok, vsn, scm} rescue - _ -> {:ok, {"1.0.0", '17'}, nil} + _ -> {:ok, {"1.0.0", ~c"17"}, nil} end _ -> diff --git a/lib/mix/lib/mix/release.ex b/lib/mix/lib/mix/release.ex index 3e0ed337d..a1cb934da 100644 --- a/lib/mix/lib/mix/release.ex +++ b/lib/mix/lib/mix/release.ex @@ -253,7 +253,7 @@ defmodule Mix.Release do defp erts_data(true) do version = :erlang.system_info(:version) - {:filename.join(:code.root_dir(), 'erts-#{version}'), :code.lib_dir(), version} + {:filename.join(:code.root_dir(), ~c"erts-#{version}"), :code.lib_dir(), version} end defp erts_data(erts_source) when is_binary(erts_source) do @@ -605,7 +605,7 @@ defmodule Mix.Release do case :systools.make_script(sys_path, sys_options) do {:ok, _module, _warnings} -> - script_path = sys_path ++ '.script' + script_path = sys_path ++ ~c".script" {:ok, [{:script, rel_info, instructions}]} = :file.consult(script_path) instructions = @@ -628,7 +628,7 @@ defmodule Mix.Release do for {_, properties} <- release.applications, not Keyword.fetch!(properties, :otp_app?), uniq: true, - do: {'RELEASE_LIB', properties |> Keyword.fetch!(:path) |> :filename.dirname()} + do: {~c"RELEASE_LIB", properties |> Keyword.fetch!(:path) |> :filename.dirname()} end defp build_paths(release) do @@ -735,7 +735,7 @@ defmodule Mix.Release do Enum.map(instructions, fn {:path, paths} -> - if Enum.any?(paths, &List.starts_with?(&1, '$RELEASE_LIB')) do + if Enum.any?(paths, &List.starts_with?(&1, ~c"$RELEASE_LIB")) do {:path, prepend_paths ++ paths} else {:path, paths} diff --git a/lib/mix/lib/mix/task.ex b/lib/mix/lib/mix/task.ex index e3c07a6d7..dd0d2f0be 100644 --- a/lib/mix/lib/mix/task.ex +++ b/lib/mix/lib/mix/task.ex @@ -595,7 +595,7 @@ defmodule Mix.Task do """ @spec task?(task_module) :: boolean def task?(module) when is_atom(module) do - match?('Elixir.Mix.Tasks.' ++ _, Atom.to_charlist(module)) and ensure_task?(module) + match?(~c"Elixir.Mix.Tasks." ++ _, Atom.to_charlist(module)) and ensure_task?(module) end defp ensure_task?(module) do diff --git a/lib/mix/lib/mix/tasks/compile.all.ex b/lib/mix/lib/mix/tasks/compile.all.ex index c33ac07b0..a394a9887 100644 --- a/lib/mix/lib/mix/tasks/compile.all.ex +++ b/lib/mix/lib/mix/tasks/compile.all.ex @@ -167,7 +167,7 @@ defmodule Mix.Tasks.Compile.All do # The app didn't come from a dep, go through the slow path (code/erl_prim_loader) defp read_app(app, nil) do - name = Atom.to_charlist(app) ++ '.app' + name = Atom.to_charlist(app) ++ ~c".app" with [_ | _] = path <- :code.where_is_file(name), {:ok, bin, _full_name} <- :erl_prim_loader.get_file(path), diff --git a/lib/mix/lib/mix/tasks/compile.ex b/lib/mix/lib/mix/tasks/compile.ex index 781b059cb..98c6f6454 100644 --- a/lib/mix/lib/mix/tasks/compile.ex +++ b/lib/mix/lib/mix/tasks/compile.ex @@ -111,7 +111,7 @@ defmodule Mix.Tasks.Compile do sorted = Enum.sort(docs) Enum.each(sorted, fn {task, doc} -> - shell.info(format('mix ~-#{max}s # ~ts', [task, doc])) + shell.info(format(~c"mix ~-#{max}s # ~ts", [task, doc])) end) consolidate_protocols? = Mix.Project.config()[:consolidate_protocols] diff --git a/lib/mix/lib/mix/tasks/escript.build.ex b/lib/mix/lib/mix/tasks/escript.build.ex index d03539a27..f3b33ea25 100644 --- a/lib/mix/lib/mix/tasks/escript.build.ex +++ b/lib/mix/lib/mix/tasks/escript.build.ex @@ -192,8 +192,8 @@ defmodule Mix.Tasks.Escript.Build do tuples = gen_main(project, escript_mod, main, app, language) ++ read_beams(beam_paths) tuples = if strip_options, do: strip_beams(tuples, strip_options), else: tuples - case :zip.create('mem', tuples, [:memory]) do - {:ok, {'mem', zip}} -> + case :zip.create(~c"mem", tuples, [:memory]) do + {:ok, {~c"mem", zip}} -> shebang = escript_opts[:shebang] || "#! /usr/bin/env escript\n" comment = build_comment(escript_opts[:comment]) emu_args = build_emu_args(escript_opts[:emu_args], escript_mod) @@ -268,7 +268,7 @@ defmodule Mix.Tasks.Escript.Build do end defp app_files(app) do - case :code.where_is_file('#{app}.app') do + case :code.where_is_file(~c"#{app}.app") do :non_existing -> Mix.raise("Could not find application #{app}") file -> get_files(Path.dirname(Path.dirname(file))) end @@ -370,7 +370,7 @@ defmodule Mix.Tasks.Escript.Build do formatted_error = case :code.ensure_loaded(Application) do {:module, Application} -> Application.format_error(reason) - {:error, _} -> :io_lib.format('~p', [reason]) + {:error, _} -> :io_lib.format(~c"~p", [reason]) end error_message = [ @@ -392,7 +392,7 @@ defmodule Mix.Tasks.Escript.Build do end {:module, ^name, binary, _} = Module.create(name, module_body, Macro.Env.location(__ENV__)) - [{'#{name}.beam', binary}] + [{~c"#{name}.beam", binary}] end defp main_body_for(:elixir, module, app, compile_config, runtime_config) do @@ -424,7 +424,7 @@ defmodule Mix.Tasks.Escript.Build do Kernel.CLI.run(fn _ -> unquote(module).main(args) end) error -> - io_error(["ERROR! Failed to start Elixir.\n", :io_lib.format('error: ~p~n', [error])]) + io_error(["ERROR! Failed to start Elixir.\n", :io_lib.format(~c"error: ~p~n", [error])]) :erlang.halt(1) end end diff --git a/lib/mix/lib/mix/tasks/help.ex b/lib/mix/lib/mix/tasks/help.ex index faf31b4aa..53cedb382 100644 --- a/lib/mix/lib/mix/tasks/help.ex +++ b/lib/mix/lib/mix/tasks/help.ex @@ -140,7 +140,7 @@ defmodule Mix.Tasks.Help do end defp where_is_file(module) do - case :code.where_is_file(Atom.to_charlist(module) ++ '.beam') do + case :code.where_is_file(Atom.to_charlist(module) ++ ~c".beam") do :non_existing -> "not available" diff --git a/lib/mix/lib/mix/tasks/local.ex b/lib/mix/lib/mix/tasks/local.ex index fb208497d..7286ae4a9 100644 --- a/lib/mix/lib/mix/tasks/local.ex +++ b/lib/mix/lib/mix/tasks/local.ex @@ -25,7 +25,7 @@ defmodule Mix.Tasks.Local do sorted = Enum.sort(docs) Enum.each(sorted, fn {task, doc} -> - shell.info(format('mix ~-#{max}s # ~ts', [task, doc])) + shell.info(format(~c"mix ~-#{max}s # ~ts", [task, doc])) end) end diff --git a/lib/mix/lib/mix/tasks/test.coverage.ex b/lib/mix/lib/mix/tasks/test.coverage.ex index a241e7719..38c5848b6 100644 --- a/lib/mix/lib/mix/tasks/test.coverage.ex +++ b/lib/mix/lib/mix/tasks/test.coverage.ex @@ -254,7 +254,7 @@ defmodule Mix.Tasks.Test.Coverage do output = Keyword.get(opts, :output, "cover") File.mkdir_p!(output) - case :cover.export('#{output}/#{name}.coverdata') do + case :cover.export(~c"#{output}/#{name}.coverdata") do :ok -> Mix.shell().info("Run \"mix test.coverage\" once all exports complete") @@ -287,7 +287,7 @@ defmodule Mix.Tasks.Test.Coverage do File.mkdir_p!(output) for mod <- modules do - {:ok, _} = :cover.analyse_to_file(mod, '#{output}/#{mod}.html', [:html]) + {:ok, _} = :cover.analyse_to_file(mod, ~c"#{output}/#{mod}.html", [:html]) end Mix.shell().info("Generated HTML coverage results in #{inspect(output)} directory") diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index 9c1914860..2b076ac60 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -651,7 +651,7 @@ defmodule Mix.Utils do # the effects of using an HTTP proxy to this function {:ok, _pid} = :inets.start(:httpc, profile: :mix) - headers = [{'user-agent', 'Mix/#{System.version()}'}] + headers = [{~c"user-agent", ~c"Mix/#{System.version()}"}] request = {:binary.bin_to_list(path), headers} # We are using relaxed: true because some servers is returning a Location diff --git a/lib/mix/test/fixtures/release_test/config/config.exs b/lib/mix/test/fixtures/release_test/config/config.exs index 7e659c2fc..e6f4c53c3 100644 --- a/lib/mix/test/fixtures/release_test/config/config.exs +++ b/lib/mix/test/fixtures/release_test/config/config.exs @@ -1,4 +1,4 @@ import Config config :release_test, :static, :was_set -config :release_test, :encoding, {:_μ, :"£", "£", '£'} +config :release_test, :encoding, {:_μ, :"£", "£", ~c"£"} diff --git a/lib/mix/test/mix/project_test.exs b/lib/mix/test/mix/project_test.exs index ea23e9d6f..ad480d898 100644 --- a/lib/mix/test/mix/project_test.exs +++ b/lib/mix/test/mix/project_test.exs @@ -118,7 +118,7 @@ defmodule Mix.ProjectTest do config = [app_path: Path.expand("_build/archive")] assert Mix.Project.build_structure(config) == :ok assert File.dir?("_build/archive/ebin") - assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", '../../priv') + assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", ~c"../../priv") end) end @@ -137,13 +137,13 @@ defmodule Mix.ProjectTest do File.mkdir_p!("include") assert Mix.Project.build_structure(config, symlink_ebin: true) == :ok - assert_proj_dir_linked_or_copied("_build/archive/ebin", "ebin", '../../ebin') - assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", '../../priv') - assert_proj_dir_linked_or_copied("_build/archive/include", "include", '../../include') + assert_proj_dir_linked_or_copied("_build/archive/ebin", "ebin", ~c"../../ebin") + assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", ~c"../../priv") + assert_proj_dir_linked_or_copied("_build/archive/include", "include", ~c"../../include") assert Mix.Project.build_structure(config) == :ok assert File.dir?("_build/archive/ebin") - assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", '../../priv') + assert_proj_dir_linked_or_copied("_build/archive/priv", "priv", ~c"../../priv") end) end @@ -183,7 +183,7 @@ defmodule Mix.ProjectTest do # relative symlink on Windows are broken, see symlink_or_copy/2 {:win32, _} -> assert path == - [source, '..', symlink_path] + [source, ~c"..", symlink_path] |> Path.join() |> Path.expand() |> String.to_charlist() diff --git a/lib/mix/test/mix/rebar_test.exs b/lib/mix/test/mix/rebar_test.exs index 9a321f9f4..aa59bc094 100644 --- a/lib/mix/test/mix/rebar_test.exs +++ b/lib/mix/test/mix/rebar_test.exs @@ -55,7 +55,7 @@ defmodule Mix.RebarTest do path = MixTest.Case.fixture_path("rebar_dep") config = Mix.Rebar.load_config(path) assert config[:erl_opts] == [:warnings_as_errors] - assert config[:SCRIPT] == 'rebar.config.script' + assert config[:SCRIPT] == ~c"rebar.config.script" end test "loads rebar.config.script on dependency directory" do @@ -65,7 +65,7 @@ defmodule Mix.RebarTest do end end - @git_rebar_charlist '../../test/fixtures/git_rebar' + @git_rebar_charlist ~c"../../test/fixtures/git_rebar" @git_rebar_string "../../test/fixtures/git_rebar" describe "deps/1" do @@ -74,24 +74,24 @@ defmodule Mix.RebarTest do end test "parses Rebar dependencies" do - assert parse_dep({:git_rebar, '~> 1.0'}) == {:git_rebar, "~> 1.0", override: true} + assert parse_dep({:git_rebar, ~c"~> 1.0"}) == {:git_rebar, "~> 1.0", override: true} - assert parse_dep({:git_rebar, '~> 1.0', {:pkg, :rebar_fork}}) == + assert parse_dep({:git_rebar, ~c"~> 1.0", {:pkg, :rebar_fork}}) == {:git_rebar, "~> 1.0", override: true, hex: :rebar_fork} assert parse_dep({:git_rebar, {:pkg, :rebar_fork}}) == {:git_rebar, override: true, hex: :rebar_fork} - assert parse_dep({:git_rebar, '0.1..*', {:git, @git_rebar_charlist, :main}}) == + assert parse_dep({:git_rebar, ~c"0.1..*", {:git, @git_rebar_charlist, :main}}) == {:git_rebar, ~r"0.1..*", override: true, git: @git_rebar_string, ref: "main"} assert parse_dep({:git_rebar, {:git, @git_rebar_charlist, :main}}) == {:git_rebar, override: true, git: @git_rebar_string, ref: "main"} - assert parse_dep({:git_rebar, '0.1..*', {:git, @git_rebar_charlist}, [:raw]}) == + assert parse_dep({:git_rebar, ~c"0.1..*", {:git, @git_rebar_charlist}, [:raw]}) == {:git_rebar, ~r"0.1..*", override: true, git: @git_rebar_string, compile: false} - assert parse_dep({:git_rebar, '', {:git, @git_rebar_charlist, {:ref, '64691eb'}}}) == + assert parse_dep({:git_rebar, ~c"", {:git, @git_rebar_charlist, {:ref, ~c"64691eb"}}}) == {:git_rebar, ~r"", override: true, git: @git_rebar_string, ref: "64691eb"} assert parse_dep(:git_rebar) == {:git_rebar, override: true} @@ -100,37 +100,37 @@ defmodule Mix.RebarTest do describe "apply_overrides/3" do test "applies overrides" do - config = [deps: {:git_rebar, '~> 2.0'}] - overrides = [{:override, [deps: [{:git_rebar, '~> 1.0'}]]}] + config = [deps: {:git_rebar, ~c"~> 2.0"}] + overrides = [{:override, [deps: [{:git_rebar, ~c"~> 1.0"}]]}] assert Mix.Rebar.apply_overrides(:foo, config, overrides) == - [deps: [{:git_rebar, '~> 1.0'}], overrides: overrides] + [deps: [{:git_rebar, ~c"~> 1.0"}], overrides: overrides] - config = [deps: [{:git_rebar, '~> 2.0'}]] - overrides = [{:override, :bar, [deps: [{:git_rebar, '~> 1.0'}]]}] + config = [deps: [{:git_rebar, ~c"~> 2.0"}]] + overrides = [{:override, :bar, [deps: [{:git_rebar, ~c"~> 1.0"}]]}] assert Mix.Rebar.apply_overrides(:foo, config, overrides) == - [deps: [{:git_rebar, '~> 2.0'}], overrides: overrides] + [deps: [{:git_rebar, ~c"~> 2.0"}], overrides: overrides] - config = [deps: [{:git_rebar, '~> 2.0'}]] - overrides = [{:override, :foo, [deps: [{:git_rebar, '~> 1.0'}]]}] + config = [deps: [{:git_rebar, ~c"~> 2.0"}]] + overrides = [{:override, :foo, [deps: [{:git_rebar, ~c"~> 1.0"}]]}] assert Mix.Rebar.apply_overrides(:foo, config, overrides) == - [deps: [{:git_rebar, '~> 1.0'}], overrides: overrides] + [deps: [{:git_rebar, ~c"~> 1.0"}], overrides: overrides] - config = [deps: [{:git_rebar, '~> 1.0'}]] - overrides = [{:add, :foo, [deps: [{:git_rebar2, '~> 2.0'}]]}] + config = [deps: [{:git_rebar, ~c"~> 1.0"}]] + overrides = [{:add, :foo, [deps: [{:git_rebar2, ~c"~> 2.0"}]]}] assert Mix.Rebar.apply_overrides(:foo, config, overrides) == - [deps: [{:git_rebar2, '~> 2.0'}, {:git_rebar, '~> 1.0'}], overrides: overrides] + [deps: [{:git_rebar2, ~c"~> 2.0"}, {:git_rebar, ~c"~> 1.0"}], overrides: overrides] end test "concatenates overrides" do - config = [deps: {:git_rebar, '~> 2.0'}, overrides: [{:add, :bar, []}]] - overrides = [{:override, [deps: [{:git_rebar, '~> 1.0'}]]}] + config = [deps: {:git_rebar, ~c"~> 2.0"}, overrides: [{:add, :bar, []}]] + overrides = [{:override, [deps: [{:git_rebar, ~c"~> 1.0"}]]}] assert Mix.Rebar.apply_overrides(:foo, config, overrides) == - [deps: [{:git_rebar, '~> 1.0'}], overrides: overrides ++ [{:add, :bar, []}]] + [deps: [{:git_rebar, ~c"~> 1.0"}], overrides: overrides ++ [{:add, :bar, []}]] end end diff --git a/lib/mix/test/mix/release_test.exs b/lib/mix/test/mix/release_test.exs index 286041c6f..56ed718e0 100644 --- a/lib/mix/test/mix/release_test.exs +++ b/lib/mix/test/mix/release_test.exs @@ -168,7 +168,7 @@ defmodule Mix.ReleaseTest do Mix.Project.in_project(:mix, project_path, app_config, fn _ -> Code.prepend_path(ebin_dir) release = from_config!(nil, app_config, []) - assert release.applications.cowboy[:vsn] == '1.1.2' + assert release.applications.cowboy[:vsn] == ~c"1.1.2" end) end) end @@ -334,9 +334,9 @@ defmodule Mix.ReleaseTest do app = {:application, :my_sample_mode, applications: [:kernel, :stdlib, :elixir, :runtime_tools, :compiler], - description: 'my_sample_mode', + description: ~c"my_sample_mode", modules: [], - vsn: '1.0.0'} + vsn: ~c"1.0.0"} File.mkdir_p!("my_sample_mode/ebin") Code.prepend_path("my_sample_mode/ebin") @@ -429,7 +429,7 @@ defmodule Mix.ReleaseTest do assert {:ok, [ - {:release, {'demo', '0.1.0'}, {:erts, @erts_version}, + {:release, {~c"demo", ~c"0.1.0"}, {:erts, @erts_version}, [ {:kernel, _, :permanent}, {:stdlib, _, :permanent}, @@ -441,14 +441,14 @@ defmodule Mix.ReleaseTest do ]} ]} = :file.consult(@boot_script_path <> ".rel") - assert {:ok, [{:script, {'demo', '0.1.0'}, instructions}]} = + assert {:ok, [{:script, {~c"demo", ~c"0.1.0"}, instructions}]} = :file.consult(@boot_script_path <> ".script") - assert {:path, ['$ROOT/lib/kernel-#{@kernel_version}/ebin']} in instructions - assert {:path, ['$RELEASE_LIB/elixir-#{@elixir_version}/ebin']} in instructions + assert {:path, [~c"$ROOT/lib/kernel-#{@kernel_version}/ebin"]} in instructions + assert {:path, [~c"$RELEASE_LIB/elixir-#{@elixir_version}/ebin"]} in instructions assert File.read!(@boot_script_path <> ".boot") |> :erlang.binary_to_term() == - {:script, {'demo', '0.1.0'}, instructions} + {:script, {~c"demo", ~c"0.1.0"}, instructions} end test "prepends relevant paths" do @@ -461,16 +461,16 @@ defmodule Mix.ReleaseTest do ["$RELEASE_LIB/sample"] ) == :ok - assert {:ok, [{:script, {'demo', '0.1.0'}, instructions}]} = + assert {:ok, [{:script, {~c"demo", ~c"0.1.0"}, instructions}]} = :file.consult(@boot_script_path <> ".script") - assert {:path, ['$ROOT/lib/kernel-#{@kernel_version}/ebin']} in instructions - refute {:path, ['$RELEASE_LIB/elixir-#{@elixir_version}/ebin']} in instructions + assert {:path, [~c"$ROOT/lib/kernel-#{@kernel_version}/ebin"]} in instructions + refute {:path, [~c"$RELEASE_LIB/elixir-#{@elixir_version}/ebin"]} in instructions - assert {:path, ['$RELEASE_LIB/sample', '$RELEASE_LIB/elixir-#{@elixir_version}/ebin']} in instructions + assert {:path, [~c"$RELEASE_LIB/sample", ~c"$RELEASE_LIB/elixir-#{@elixir_version}/ebin"]} in instructions assert File.read!(@boot_script_path <> ".boot") |> :erlang.binary_to_term() == - {:script, {'demo', '0.1.0'}, instructions} + {:script, {~c"demo", ~c"0.1.0"}, instructions} end test "works when :load/:none is set at the leaf" do @@ -586,13 +586,13 @@ defmodule Mix.ReleaseTest do test "writes sys_config with encoding" do assert make_sys_config( release([]), - [encoding: {:_μ, :"£", "£", '£'}], + [encoding: {:_μ, :"£", "£", ~c"£"}], "unused/runtime/path" ) == :ok {:ok, contents} = :file.consult(@sys_config) - assert contents == [[encoding: {:_μ, :"£", "£", '£'}]] + assert contents == [[encoding: {:_μ, :"£", "£", ~c"£"}]] end test "writes the given sys_config with config providers" do @@ -766,8 +766,11 @@ defmodule Mix.ReleaseTest do |> File.read!() |> strip_beam() - assert {:error, :beam_lib, {:missing_chunk, _, 'Dbgi'}} = :beam_lib.chunks(beam, ['Dbgi']) - assert {:error, :beam_lib, {:missing_chunk, _, 'Docs'}} = :beam_lib.chunks(beam, ['Docs']) + assert {:error, :beam_lib, {:missing_chunk, _, ~c"Dbgi"}} = + :beam_lib.chunks(beam, [~c"Dbgi"]) + + assert {:error, :beam_lib, {:missing_chunk, _, ~c"Docs"}} = + :beam_lib.chunks(beam, [~c"Docs"]) end test "can keep docs and debug info, if requested" do @@ -776,8 +779,8 @@ defmodule Mix.ReleaseTest do |> File.read!() |> strip_beam(keep: ["Docs", "Dbgi"]) - assert {:ok, {EEx, [{'Dbgi', _}]}} = :beam_lib.chunks(beam, ['Dbgi']) - assert {:ok, {EEx, [{'Docs', _}]}} = :beam_lib.chunks(beam, ['Docs']) + assert {:ok, {EEx, [{~c"Dbgi", _}]}} = :beam_lib.chunks(beam, [~c"Dbgi"]) + assert {:ok, {EEx, [{~c"Docs", _}]}} = :beam_lib.chunks(beam, [~c"Docs"]) end test "strip beams without compression" do @@ -796,9 +799,9 @@ defmodule Mix.ReleaseTest do app = {:application, :my_sample1, applications: [:kernel, :stdlib, :elixir], - description: 'my_sample1', + description: ~c"my_sample1", modules: [], - vsn: '1.0.0', + vsn: ~c"1.0.0", included_applications: [:runtime_tools]} File.mkdir_p!("my_sample1/ebin") @@ -819,9 +822,9 @@ defmodule Mix.ReleaseTest do app = {:application, :my_sample2, applications: [:kernel, :stdlib, :elixir, :runtime_tools], - description: 'my_sample', + description: ~c"my_sample", modules: [], - vsn: '1.0.0', + vsn: ~c"1.0.0", included_applications: [:runtime_tools]} File.mkdir_p!("my_sample2/ebin") @@ -843,9 +846,9 @@ defmodule Mix.ReleaseTest do {:application, :my_sample1, applications: [:kernel, :stdlib, :elixir, :unknown], optional_applications: [:unknown], - description: 'my_sample1', + description: ~c"my_sample1", modules: [], - vsn: '1.0.0'} + vsn: ~c"1.0.0"} File.mkdir_p!("my_sample1/ebin") Code.prepend_path("my_sample1/ebin") diff --git a/lib/mix/test/mix/tasks/app.config_test.exs b/lib/mix/test/mix/tasks/app.config_test.exs index e1051f47f..7eb4440d7 100644 --- a/lib/mix/test/mix/tasks/app.config_test.exs +++ b/lib/mix/test/mix/tasks/app.config_test.exs @@ -104,7 +104,7 @@ defmodule Mix.Tasks.App.ConfigTest do in_tmp(context.test, fn -> Mix.Project.push(MixTest.Case.Sample) - :ok = :application.load({:application, :loaded_sample, [vsn: '1.0.0', env: []]}) + :ok = :application.load({:application, :loaded_sample, [vsn: ~c"1.0.0", env: []]}) Mix.ProjectStack.loaded_config([:sample, :unknown_sample, :loaded_sample], []) Mix.Tasks.App.Config.run([]) diff --git a/lib/mix/test/mix/tasks/app.tree_test.exs b/lib/mix/test/mix/tasks/app.tree_test.exs index 49bfae5e7..255364730 100644 --- a/lib/mix/test/mix/tasks/app.tree_test.exs +++ b/lib/mix/test/mix/tasks/app.tree_test.exs @@ -134,14 +134,14 @@ defmodule Mix.Tasks.App.TreeTest do end defp load_apps(optional_apps \\ []) do - :ok = :application.load({:application, :app_deps4_sample, [vsn: '1.0.0', env: []]}) - :ok = :application.load({:application, :app_deps3_sample, [vsn: '1.0.0', env: []]}) + :ok = :application.load({:application, :app_deps4_sample, [vsn: ~c"1.0.0", env: []]}) + :ok = :application.load({:application, :app_deps3_sample, [vsn: ~c"1.0.0", env: []]}) - opts = [vsn: '1.0.0', env: [], included_applications: [:app_deps4_sample]] + opts = [vsn: ~c"1.0.0", env: [], included_applications: [:app_deps4_sample]] :ok = :application.load({:application, :app_deps2_sample, opts}) opts = [ - vsn: '1.0.0', + vsn: ~c"1.0.0", env: [], applications: [:app_deps2_sample, :app_deps3_sample], optional_applications: optional_apps diff --git a/lib/mix/test/mix/tasks/archive_test.exs b/lib/mix/test/mix/tasks/archive_test.exs index b41dabcf1..35d8a8117 100644 --- a/lib/mix/test/mix/tasks/archive_test.exs +++ b/lib/mix/test/mix/tasks/archive_test.exs @@ -31,10 +31,10 @@ defmodule Mix.Tasks.ArchiveTest do Mix.Tasks.Archive.Build.run(["--no-elixir-version-check"]) message = "Generated archive \"archive-0.1.0.ez\" with MIX_ENV=dev" assert_received {:mix_shell, :info, [^message]} - assert File.regular?('archive-0.1.0.ez') + assert File.regular?(~c"archive-0.1.0.ez") assert_archive_content_default() - refute has_in_zip_file?('archive-0.1.0.ez', 'archive-0.1.0/priv/.dot_file') + refute has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/priv/.dot_file") end) end @@ -43,24 +43,24 @@ defmodule Mix.Tasks.ArchiveTest do Mix.Tasks.Archive.Build.run(["--no-elixir-version-check", "--include-dot-files"]) message = "Generated archive \"archive-0.1.0.ez\" with MIX_ENV=dev" assert_received {:mix_shell, :info, [^message]} - assert File.regular?('archive-0.1.0.ez') + assert File.regular?(~c"archive-0.1.0.ez") assert_archive_content_default() - assert has_in_zip_file?('archive-0.1.0.ez', 'archive-0.1.0/priv/.dot_file') + assert has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/priv/.dot_file") end) end def assert_archive_content_default() do - assert File.regular?('archive-0.1.0.ez') - assert has_in_zip_file?('archive-0.1.0.ez', 'archive-0.1.0/.elixir') - assert has_in_zip_file?('archive-0.1.0.ez', 'archive-0.1.0/priv/not_really_an.so') + assert File.regular?(~c"archive-0.1.0.ez") + assert has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/.elixir") + assert has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/priv/not_really_an.so") assert has_in_zip_file?( - 'archive-0.1.0.ez', - 'archive-0.1.0/ebin/Elixir.Mix.Tasks.Local.Sample.beam' + ~c"archive-0.1.0.ez", + ~c"archive-0.1.0/ebin/Elixir.Mix.Tasks.Local.Sample.beam" ) - assert has_in_zip_file?('archive-0.1.0.ez', 'archive-0.1.0/ebin/archive.app') + assert has_in_zip_file?(~c"archive-0.1.0.ez", ~c"archive-0.1.0/ebin/archive.app") end test "archive install" do diff --git a/lib/mix/test/mix/tasks/compile.app_test.exs b/lib/mix/test/mix/tasks/compile.app_test.exs index ddadb14c8..3e340234e 100644 --- a/lib/mix/test/mix/tasks/compile.app_test.exs +++ b/lib/mix/test/mix/tasks/compile.app_test.exs @@ -71,7 +71,7 @@ defmodule Mix.Tasks.Compile.AppTest do assert Mix.Tasks.Compile.App.run([]) == {:ok, []} properties = parse_resource_file(:sample) - assert properties[:vsn] == '0.1.0' + assert properties[:vsn] == ~c"0.1.0" assert properties[:modules] == [A, B] assert properties[:applications] == [:kernel, :stdlib, :elixir] refute Keyword.has_key?(properties, :compile_env) @@ -114,10 +114,10 @@ defmodule Mix.Tasks.Compile.AppTest do Mix.Tasks.Compile.App.run([]) properties = parse_resource_file(:custom_project) - assert properties[:vsn] == '0.2.0' + assert properties[:vsn] == ~c"0.2.0" assert properties[:maxT] == :infinity assert properties[:optional_applications] == [:ex_unit, :mix] - assert properties[:description] == 'Some UTF-8 dëscriptión' + assert properties[:description] == ~c"Some UTF-8 dëscriptión" assert properties[:applications] == [:kernel, :stdlib, :elixir, :logger, :ex_unit, :example_app, :mix] @@ -248,7 +248,7 @@ defmodule Mix.Tasks.Compile.AppTest do properties = parse_resource_file(:sample) assert properties[:registered] == [] - assert properties[:description] == 'sample' + assert properties[:description] == ~c"sample" assert properties[:applications] == [:kernel, :stdlib, :elixir] assert Mix.Tasks.Compile.App.run([]) == {:noop, []} diff --git a/lib/mix/test/mix/tasks/compile.erlang_test.exs b/lib/mix/test/mix/tasks/compile.erlang_test.exs index ae0ccbcad..3967570c0 100644 --- a/lib/mix/test/mix/tasks/compile.erlang_test.exs +++ b/lib/mix/test/mix/tasks/compile.erlang_test.exs @@ -13,7 +13,7 @@ defmodule Mix.Tasks.Compile.ErlangTest do :ok end - @tag erlc_options: [{:d, 'foo', 'bar'}] + @tag erlc_options: [{:d, ~c"foo", ~c"bar"}] test "raises on invalid erlc_options" do in_fixture("compile_erlang", fn -> assert_raise Mix.Error, ~r"Compiling Erlang file '.*' failed", fn -> diff --git a/lib/mix/test/mix/tasks/compile.protocols_test.exs b/lib/mix/test/mix/tasks/compile.protocols_test.exs index 40ca4afda..6e7db79ad 100644 --- a/lib/mix/test/mix/tasks/compile.protocols_test.exs +++ b/lib/mix/test/mix/tasks/compile.protocols_test.exs @@ -124,7 +124,7 @@ defmodule Mix.Tasks.Compile.ProtocolsTest do compile_elixir_and_protocols() # Load consolidated - :code.add_patha('_build/dev/lib/sample/consolidated') + :code.add_patha(~c"_build/dev/lib/sample/consolidated") :code.purge(Enumerable) :code.delete(Enumerable) @@ -132,7 +132,7 @@ defmodule Mix.Tasks.Compile.ProtocolsTest do Enumerable.impl_for!(:oops) rescue Protocol.UndefinedError -> - assert [{_, _, _, [file: 'lib/enum.ex'] ++ _} | _] = __STACKTRACE__ + assert [{_, _, _, [file: ~c"lib/enum.ex"] ++ _} | _] = __STACKTRACE__ else _ -> flunk("Enumerable.impl_for!/1 should have failed") @@ -158,7 +158,7 @@ defmodule Mix.Tasks.Compile.ProtocolsTest do end defp purge_protocol(module) do - :code.del_path(:filename.absname('_build/dev/lib/sample/consolidated')) + :code.del_path(:filename.absname(~c"_build/dev/lib/sample/consolidated")) :code.purge(module) :code.delete(module) end diff --git a/lib/mix/test/mix/tasks/format_test.exs b/lib/mix/test/mix/tasks/format_test.exs index 2a21f5dbd..d9c846d86 100644 --- a/lib/mix/test/mix/tasks/format_test.exs +++ b/lib/mix/test/mix/tasks/format_test.exs @@ -217,7 +217,7 @@ defmodule Mix.Tasks.FormatTest do def format(contents, opts) do assert opts[:from_formatter_exs] == :yes assert opts[:sigil] == :W - assert opts[:modifiers] == 'abc' + assert opts[:modifiers] == ~c"abc" assert opts[:line] == 2 assert opts[:file] =~ ~r/\/a\.ex$/ contents |> String.split(~r/\s/) |> Enum.join("\n") @@ -295,7 +295,7 @@ defmodule Mix.Tasks.FormatTest do opts[:sigil] -> assert opts[:sigil] == :W assert opts[:inputs] == ["a.ex"] - assert opts[:modifiers] == 'abc' + assert opts[:modifiers] == ~c"abc" true -> flunk("Plugin not loading in correctly.") diff --git a/lib/mix/test/mix/tasks/loadconfig_test.exs b/lib/mix/test/mix/tasks/loadconfig_test.exs index d4d971bee..71105a137 100644 --- a/lib/mix/test/mix/tasks/loadconfig_test.exs +++ b/lib/mix/test/mix/tasks/loadconfig_test.exs @@ -16,7 +16,7 @@ defmodule Mix.Tasks.LoadconfigTest do assert Application.fetch_env(:my_app, :key) == {:ok, :project} # App configuration should have lower precedence - :ok = :application.load({:application, :my_app, [vsn: '1.0.0', env: [key: :app]]}) + :ok = :application.load({:application, :my_app, [vsn: ~c"1.0.0", env: [key: :app]]}) assert Application.fetch_env(:my_app, :key) == {:ok, :project} # loadconfig can be called multiple times diff --git a/lib/mix/test/mix/tasks/release_test.exs b/lib/mix/test/mix/tasks/release_test.exs index fdee5ebb0..593d54a2c 100644 --- a/lib/mix/test/mix/tasks/release_test.exs +++ b/lib/mix/test/mix/tasks/release_test.exs @@ -155,8 +155,8 @@ defmodule Mix.Tasks.ReleaseTest do beam = File.read!(Path.join(root, "lib/release_test-0.1.0/ebin/Elixir.ReleaseTest.beam")) - assert {:ok, {_, [{'Docs', _}]}} = :beam_lib.chunks(beam, ['Docs']) - assert {:error, _, _} = :beam_lib.chunks(beam, ['Dbgi']) + assert {:ok, {_, [{~c"Docs", _}]}} = :beam_lib.chunks(beam, [~c"Docs"]) + assert {:error, _, _} = :beam_lib.chunks(beam, [~c"Dbgi"]) refute root |> Path.join("bin/start") |> File.exists?() refute root |> Path.join("bin/start.bat") |> File.exists?() @@ -325,12 +325,12 @@ defmodule Mix.Tasks.ReleaseTest do cookie = File.read!(Path.join(root, "releases/COOKIE")) # Assert runtime - open_port(Path.join(root, "bin/release_test"), ['start']) + open_port(Path.join(root, "bin/release_test"), [~c"start"]) assert %{ app_dir: app_dir, cookie_env: ^cookie, - encoding: {:_μ, :"£", "£", '£'}, + encoding: {:_μ, :"£", "£", ~c"£"}, mode: :embedded, node: release_node("release_test"), protocols_consolidated?: true, @@ -411,10 +411,10 @@ defmodule Mix.Tasks.ReleaseTest do |> File.chmod(0o555) == :ok # Assert runtime - open_port(Path.join(root, "bin/runtime_config"), ['start']) + open_port(Path.join(root, "bin/runtime_config"), [~c"start"]) assert %{ - encoding: {:runtime, :_μ, :"£", "£", '£'}, + encoding: {:runtime, :_μ, :"£", "£", ~c"£"}, mode: :embedded, node: release_node("runtime_config"), protocols_consolidated?: true, @@ -451,7 +451,10 @@ defmodule Mix.Tasks.ReleaseTest do Mix.Project.in_project(:release_test, ".", config, fn _ -> root = Path.absname("_build/dev/rel/no_dist") Mix.Task.run("release", ["no_dist"]) - open_port(Path.join(root, "bin/no_dist"), ['start'], [{'RELEASE_DISTRIBUTION', 'none'}]) + + open_port(Path.join(root, "bin/no_dist"), [~c"start"], [ + {~c"RELEASE_DISTRIBUTION", ~c"none"} + ]) assert %{ mode: :embedded, @@ -489,7 +492,7 @@ defmodule Mix.Tasks.ReleaseTest do assert root |> Path.join("releases/0.2.0/remote.vm.args") |> File.exists?() # Assert runtime - open_port(Path.join(root, "bin/demo"), ['start']) + open_port(Path.join(root, "bin/demo"), [~c"start"]) assert %{ app_dir: app_dir, @@ -556,8 +559,8 @@ defmodule Mix.Tasks.ReleaseTest do "ERROR! the application :release_test has a different value set for key :static during runtime compared to compile time" # But now it does - env = [{'RELEASE_STATIC', 'was_set'}] - open_port(Path.join(root, "bin/compile_env_config"), ['start'], env) + env = [{~c"RELEASE_STATIC", ~c"was_set"}] + open_port(Path.join(root, "bin/compile_env_config"), [~c"start"], env) assert %{} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED")) end) end) @@ -584,8 +587,8 @@ defmodule Mix.Tasks.ReleaseTest do Mix.Task.run("release", ["no_compile_env_config"]) # It boots with mismatched config - env = [{'RELEASE_STATIC', 'runtime'}] - open_port(Path.join(root, "bin/no_compile_env_config"), ['start'], env) + env = [{~c"RELEASE_STATIC", ~c"runtime"}] + open_port(Path.join(root, "bin/no_compile_env_config"), [~c"start"], env) assert %{} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED")) end) end) @@ -615,7 +618,7 @@ defmodule Mix.Tasks.ReleaseTest do script = Path.join(root, "bin/permanent1") env = [{"RELEASE_DISTRIBUTION", "name"}, {"RELEASE_NODE", "permanent1@127.0.0.1"}] - open_port(script, ['start'], env) + open_port(script, [~c"start"], env) wait_until_decoded(Path.join(root, "RELEASE_BOOTED")) assert System.cmd(script, ["rpc", "ReleaseTest.hello_world()"], env: env) == @@ -655,7 +658,7 @@ defmodule Mix.Tasks.ReleaseTest do assert String.trim_trailing(hello_world) == "hello_world" refute File.exists?(Path.join(root, "RELEASE_BOOTED")) - open_port(script, ['eval', 'Application.ensure_all_started(:release_test)']) + open_port(script, [~c"eval", ~c"Application.ensure_all_started(:release_test)"]) assert %{ cookie_env: "abcdefghij", @@ -693,7 +696,7 @@ defmodule Mix.Tasks.ReleaseTest do script = Path.join(root, "bin/permanent2") env = [{"RELEASE_DISTRIBUTION", "name"}, {"RELEASE_NODE", "permanent2@127.0.0.1"}] - open_port(script, ['daemon_iex'], env) + open_port(script, [~c"daemon_iex"], env) assert %{ app_dir: app_dir, diff --git a/lib/mix/test/mix/utils_test.exs b/lib/mix/test/mix/utils_test.exs index b085f80a0..5db310a1c 100644 --- a/lib/mix/test/mix/utils_test.exs +++ b/lib/mix/test/mix/utils_test.exs @@ -100,13 +100,13 @@ defmodule Mix.UtilsTest do assert Mix.Utils.proxy_config("http://example.com") == [] System.put_env("http_proxy", "http://nopass@example.com") - assert Mix.Utils.proxy_config("http://example.com") == [proxy_auth: {'nopass', ''}] + assert Mix.Utils.proxy_config("http://example.com") == [proxy_auth: {~c"nopass", ~c""}] System.put_env("HTTP_PROXY", "http://my:proxy@example.com") - assert Mix.Utils.proxy_config("http://example.com") == [proxy_auth: {'my', 'proxy'}] + assert Mix.Utils.proxy_config("http://example.com") == [proxy_auth: {~c"my", ~c"proxy"}] System.put_env("https_proxy", "https://another:proxy@example.com") - assert Mix.Utils.proxy_config("https://example.com") == [proxy_auth: {'another', 'proxy'}] + assert Mix.Utils.proxy_config("https://example.com") == [proxy_auth: {~c"another", ~c"proxy"}] System.put_env("HTTPS_PROXY", "https://example.com") assert Mix.Utils.proxy_config("https://example.com") == [] @@ -185,7 +185,7 @@ defmodule Mix.UtilsTest do "ebin" |> Path.expand() |> String.to_charlist() _ -> - '../../ebin' + ~c"../../ebin" end {:ok, actual_link} = :file.read_link("_build/archive/ebin") -- cgit v1.2.1