1Code.require_file "test_helper.exs", __DIR__ 2Code.require_file "../lib/server.exs", __DIR__ 3 4defmodule ServerTest do 5 use ExUnit.Case 6 import ExUnit.CaptureIO 7 8 setup_all do 9 on_exit fn -> 10 {_status, files} = File.ls Path.expand("fixtures", __DIR__) 11 files |> Enum.each(fn(file) -> 12 unless file == ".gitkeep" do 13 File.rm Path.expand("fixtures/#{file}", __DIR__) 14 end 15 end) 16 end 17 end 18 19 test "Expression completion" do 20 assert send_signal("COMP { 'def', [context: Elixir, imports: [], aliases: []]}") =~ """ 21 defoverridable/1 22 """ 23 end 24 25 test "Documentation lookup" do 26 assert send_signal("DOCL { 'List', [context: Elixir, imports: [], aliases: []]}") =~ """ 27 \e[0m\n\e[7m\e[33m List \e[0m\n\e[0m 28 """ 29 end 30 31 test "Getting the definition source file information of code" do 32 assert send_signal("DEFL {\"List,delete\", [context: Elixir, imports: [], aliases: []]}") =~ "/lib/elixir/lib/list.ex" 33 end 34 35 test "Evaluate the content of a file" do 36 filename = Path.expand("fixtures/eval_fixture.exs", __DIR__) 37 File.write(filename, "1+1") 38 assert send_signal("EVAL { :eval, '#{filename}' }") =~ "2" 39 end 40 41 test "Evaluate and quote the content of a file" do 42 filename = Path.expand("fixtures/eval_and_quote_fixture.exs", __DIR__) 43 File.write(filename, "[4,2,1,3] |> Enum.sort") 44 assert send_signal("EVAL { :quote, '#{filename}' }") =~ """ 45 {{:., [line: 1], [{:__aliases__, [counter: 0, line: 1], [:Enum]}, :sort]},\n [line: 1], []}]} 46 """ 47 end 48 49 test "Expand macro once" do 50 filename = Path.expand("fixtures/macro_expand_once_fixture.exs", __DIR__) 51 File.write(filename, "unless true, do: IO.puts \"this should never be printed\"") 52 assert send_signal("EVAL { :expand_once, '#{filename}' }") =~ """ 53 if(true) do 54 nil 55 else 56 IO.puts("this should never be printed") 57 end 58 """ 59 end 60 61 test "Expand macro" do 62 filename = Path.expand("fixtures/macro_expand_fixture.exs", __DIR__) 63 File.write(filename, "unless true, do: IO.puts \"this should never be printed\"") 64 assert send_signal("EVAL { :expand, '#{filename}' }") =~ """ 65 case(true) do 66 x when x in [false, nil] -> 67 IO.puts("this should never be printed") 68 _ -> 69 nil 70 end 71 """ 72 end 73 74 test "Get all available application modules" do 75 assert send_signal("INFO { :type, :modules }") =~ """ 76 Elixir.Logger 77 Elixir.Logger.Formatter 78 Elixir.Logger.Translator 79 """ 80 end 81 82 test "Get all available mix tasks by name" do 83 assert send_signal("INFO { :type, :mixtasks }") =~ """ 84 app.start 85 archive 86 archive.build 87 archive.install 88 archive.uninstall 89 clean 90 cmd 91 compile 92 """ 93 end 94 95 # The IEx.Helpers.t and IEx.Helpers.i are functionality which come with 96 # Elixir version 1.2.0 97 if Version.match?(System.version, ">=1.2.0-rc") do 98 test "Get information from data type" do 99 assert send_signal("INFO { :type, :info, List}") =~ """ 100 Reference modules\e[0m\n\e[22m Module, Atom\e[0m\nEND-OF-INFO 101 """ 102 end 103 104 test "Don't crash server if data type argument is faulty" do 105 assert send_signal("INFO { :type, :info, whatever}") =~ """ 106 END-OF-INFO 107 """ 108 end 109 110 test "Prints the types for the given module or for the given function/arity pair" do 111 assert send_signal("INFO { :type, :types, 'Agent'}") =~ """ 112 @type agent() :: pid() | {atom(), node()} | name()\e[0m\n\e[22m@type state() :: term()\e[0m\nEND-OF-INFO 113 """ 114 115 assert send_signal("INFO { :type, :types, 'Agent.on_start/0'}") =~ """ 116 @type on_start() :: {:ok, pid()} | {:error, {:already_started, pid()} | term()}\e[0m 117 """ 118 end 119 end 120 121 defp send_signal(signal) do 122 capture_io(fn -> 123 Alchemist.Server.read_input(signal) 124 end) 125 end 126end 127