Skip to content

Commit ec6f4f0

Browse files
committed
Assert results more precise, Add tests
1 parent cb716f1 commit ec6f4f0

File tree

5 files changed

+143
-46
lines changed

5 files changed

+143
-46
lines changed
2.41 KB
Binary file not shown.
700 Bytes
Binary file not shown.

test/examples/type/record.ex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule RecordEx do
2+
require Record
3+
Record.defrecord(:user, name: "john", age: 25)
4+
5+
@type user :: record(:user, name: String.t(), age: integer)
6+
7+
@spec ret_wrong_record() :: user()
8+
def ret_wrong_record(), do: :ok
9+
10+
@spec ret_wrong_record2() :: user()
11+
def ret_wrong_record2(), do: user(name: 12)
12+
end

test/examples/type/wrong_ret.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ defmodule WrongRet do
2626
@spec ret_out_of_range_int() :: 1..10
2727
def ret_out_of_range_int, do: 12
2828

29+
@spec ret_wrong_float() :: float()
30+
def ret_wrong_float() do
31+
1
32+
end
33+
34+
@spec ret_wrong_float2() :: float()
35+
def ret_wrong_float2() do
36+
nil
37+
end
38+
39+
@spec ret_wrong_char() :: char()
40+
def ret_wrong_char() do
41+
'Ala ma kota'
42+
end
43+
44+
@spec ret_wrong_char2() :: ?o
45+
def ret_wrong_char2() do
46+
nil
47+
end
48+
2949
@spec ret_wrong_boolean() :: boolean()
3050
def ret_wrong_boolean, do: :ok
3151

test/gradient/elixir_fmt_test.exs

Lines changed: 111 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ defmodule Gradient.ElixirFmtTest do
99
@example_module_path "test/examples/simple_app.ex"
1010

1111
setup_all config do
12-
load_wrong_ret_error_examples(config)
12+
config
13+
|> load_wrong_ret_error_examples()
14+
|> load_record_type_example()
1315
end
1416

1517
test "try_highlight_in_context/2" do
@@ -26,108 +28,151 @@ defmodule Gradient.ElixirFmtTest do
2628

2729
describe "types format" do
2830
test "return integer() instead atom()", %{wrong_ret_errors: errors} do
29-
msg = format_error_to_binary(errors.ret_wrong_atom)
31+
[expected, actual] = format_error_to_binary(errors.ret_wrong_atom)
3032

31-
assert String.contains?(msg, "atom()")
32-
assert String.contains?(msg, "1")
33+
assert String.contains?(expected, "atom()")
34+
assert String.contains?(actual, "1")
3335
end
3436

3537
test "return tuple() instead atom()", %{wrong_ret_errors: errors} do
36-
msg = format_error_to_binary(errors.ret_wrong_atom2)
38+
[expected, actual] = format_error_to_binary(errors.ret_wrong_atom2)
3739

38-
assert String.contains?(msg, "atom()")
39-
assert String.contains?(msg, "{:ok, []}")
40+
assert String.contains?(expected, "atom()")
41+
assert String.contains?(actual, "{:ok, []}")
4042
end
4143

4244
test "return map() instead atom()", %{wrong_ret_errors: errors} do
43-
msg = format_error_to_binary(errors.ret_wrong_atom3)
45+
[expected, actual] = format_error_to_binary(errors.ret_wrong_atom3)
4446

45-
assert String.contains?(msg, "atom()")
46-
assert String.contains?(msg, "%{required(:a) => 1}")
47+
assert String.contains?(expected, "atom()")
48+
assert String.contains?(actual, "%{required(:a) => 1}")
4749
end
4850

4951
test "return float() instead integer()", %{wrong_ret_errors: errors} do
50-
msg = format_error_to_binary(errors.ret_wrong_integer)
52+
[expected, actual] = format_error_to_binary(errors.ret_wrong_integer)
5153

52-
assert String.contains?(msg, "integer()")
53-
assert String.contains?(msg, "1.0")
54+
assert String.contains?(expected, "integer()")
55+
assert String.contains?(actual, "float()")
5456
end
5557

5658
test "return atom() instead integer()", %{wrong_ret_errors: errors} do
57-
msg = format_error_to_binary(errors.ret_wrong_integer2)
59+
[expected, actual] = format_error_to_binary(errors.ret_wrong_integer2)
5860

59-
assert String.contains?(msg, "integer()")
60-
assert String.contains?(msg, ":ok")
61+
assert String.contains?(expected, "integer()")
62+
assert String.contains?(actual, ":ok")
6163
end
6264

6365
test "return boolean() instead integer()", %{wrong_ret_errors: errors} do
64-
msg = format_error_to_binary(errors.ret_wrong_integer3)
66+
[expected, actual] = format_error_to_binary(errors.ret_wrong_integer3)
6567

66-
assert String.contains?(msg, "integer()")
67-
assert String.contains?(msg, "true")
68+
assert String.contains?(expected, "integer()")
69+
assert String.contains?(actual, "true")
6870
end
6971

7072
test "return list() instead integer()", %{wrong_ret_errors: errors} do
71-
msg = format_error_to_binary(errors.ret_wrong_integer4)
73+
[expected, actual] = format_error_to_binary(errors.ret_wrong_integer4)
7274

73-
assert String.contains?(msg, "integer()")
74-
assert String.contains?(msg, "nonempty_list()")
75+
assert String.contains?(expected, "integer()")
76+
assert String.contains?(actual, "nonempty_list()")
7577
end
7678

7779
test "return integer() out of the range()", %{wrong_ret_errors: errors} do
78-
msg = format_error_to_binary(errors.ret_out_of_range_int)
80+
[expected, actual] = format_error_to_binary(errors.ret_out_of_range_int)
7981

80-
assert String.contains?(msg, "range(1, 10)")
81-
assert String.contains?(msg, "12")
82+
assert String.contains?(expected, "1..10")
83+
assert String.contains?(actual, "12")
84+
end
85+
86+
test "return integer() instead float()", %{wrong_ret_errors: errors} do
87+
[expected, actual] = format_error_to_binary(errors.ret_wrong_float)
88+
89+
assert String.contains?(expected, "float()")
90+
assert String.contains?(actual, "1")
91+
end
92+
93+
test "return nil() instead float()", %{wrong_ret_errors: errors} do
94+
[expected, actual] = format_error_to_binary(errors.ret_wrong_float2)
95+
96+
assert String.contains?(expected, "float()")
97+
assert String.contains?(actual, "nil")
98+
end
99+
100+
test "return charlist() instead char()", %{wrong_ret_errors: errors} do
101+
[expected, actual] = format_error_to_binary(errors.ret_wrong_char)
102+
103+
assert String.contains?(expected, "char()")
104+
assert String.contains?(actual, "nonempty_list()")
105+
end
106+
107+
test "return nil() instead char()", %{wrong_ret_errors: errors} do
108+
[expected, actual] = format_error_to_binary(errors.ret_wrong_char2)
109+
110+
# unfortunately char is represented as {:integer, 0, _}
111+
assert String.contains?(expected, "111")
112+
assert String.contains?(actual, "nil")
82113
end
83114

84115
test "return atom() instead boolean()", %{wrong_ret_errors: errors} do
85-
msg = format_error_to_binary(errors.ret_wrong_boolean)
116+
[expected, actual] = format_error_to_binary(errors.ret_wrong_boolean)
86117

87-
assert String.contains?(msg, "boolean()")
88-
assert String.contains?(msg, ":ok")
118+
assert String.contains?(expected, "boolean()")
119+
assert String.contains?(actual, ":ok")
89120
end
90121

91122
test "return binary() instead boolean()", %{wrong_ret_errors: errors} do
92-
msg = format_error_to_binary(errors.ret_wrong_boolean2)
123+
[expected, actual] = format_error_to_binary(errors.ret_wrong_boolean2)
93124

94-
assert String.contains?(msg, "boolean()")
95-
assert String.contains?(msg, "binary()")
125+
assert String.contains?(expected, "boolean()")
126+
assert String.contains?(actual, "binary()")
96127
end
97128

98129
test "return integer() instead boolean()", %{wrong_ret_errors: errors} do
99-
msg = format_error_to_binary(errors.ret_wrong_boolean3)
130+
[expected, actual] = format_error_to_binary(errors.ret_wrong_boolean3)
100131

101-
assert String.contains?(msg, "boolean()")
102-
assert String.contains?(msg, "1")
132+
assert String.contains?(expected, "boolean()")
133+
assert String.contains?(actual, "1")
103134
end
104135

105136
test "return keyword() instead boolean()", %{wrong_ret_errors: errors} do
106-
msg = format_error_to_binary(errors.ret_wrong_boolean4)
137+
[expected, actual] = format_error_to_binary(errors.ret_wrong_boolean4)
107138

108-
assert String.contains?(msg, "boolean()")
109-
assert String.contains?(msg, "nonempty_list()")
139+
assert String.contains?(expected, "boolean()")
140+
assert String.contains?(actual, "nonempty_list()")
110141
end
111142

112143
test "return list() instead keyword()", %{wrong_ret_errors: errors} do
113-
msg = format_error_to_binary(errors.ret_wrong_keyword)
144+
[expected, actual] = format_error_to_binary(errors.ret_wrong_keyword)
114145

115-
assert String.contains?(msg, "{atom(), any()}")
116-
assert String.contains?(msg, "1")
146+
assert String.contains?(expected, "{atom(), any()}")
147+
assert String.contains?(actual, "1")
117148
end
118149

119150
test "return tuple() instead map()", %{wrong_ret_errors: errors} do
120-
msg = format_error_to_binary(errors.ret_wrong_map)
151+
[expected, actual] = format_error_to_binary(errors.ret_wrong_map)
121152

122-
assert String.contains?(msg, "map()")
123-
assert String.contains?(msg, "{:a, 1, 2}")
153+
assert String.contains?(expected, "map()")
154+
assert String.contains?(actual, "{:a, 1, 2}")
124155
end
125156

126157
test "return lambda with wrong returned type", %{wrong_ret_errors: errors} do
127-
msg = format_error_to_binary(errors.ret_wrong_fun)
158+
[expected, actual] = format_error_to_binary(errors.ret_wrong_fun)
159+
160+
assert String.contains?(expected, "atom()")
161+
assert String.contains?(actual, "12")
162+
end
128163

129-
assert String.contains?(msg, "atom()")
130-
assert String.contains?(msg, "12")
164+
test "return atom() instead record()", %{record_type_errors: errors} do
165+
[expected, actual] = format_error_to_binary(errors.ret_wrong_record)
166+
167+
assert String.contains?(expected, "user()")
168+
assert String.contains?(actual, ":ok")
169+
end
170+
171+
test "return wrong record value type", %{record_type_errors: errors} do
172+
[expected, actual] = format_error_to_binary(errors.ret_wrong_record2)
173+
174+
assert String.contains?(expected, "String.t()")
175+
assert String.contains?(actual, "12")
131176
end
132177
end
133178

@@ -165,6 +210,26 @@ defmodule Gradient.ElixirFmtTest do
165210
error
166211
|> ElixirFmt.format_error(opts)
167212
|> :erlang.iolist_to_binary()
213+
|> String.split("have type")
214+
|> List.last()
215+
|> String.split("but it has type")
216+
end
217+
218+
@spec load_record_type_example(map()) :: map()
219+
defp load_record_type_example(config) do
220+
{_tokens, ast} = load("/type/Elixir.RecordEx.beam", "/type/record.ex")
221+
222+
{errors, forms} = type_check_file(ast, [])
223+
224+
names =
225+
get_function_names_from_ast(forms)
226+
|> Enum.drop(3)
227+
228+
errors_map =
229+
Enum.zip(names, errors)
230+
|> Map.new()
231+
232+
Map.put(config, :record_type_errors, errors_map)
168233
end
169234

170235
@spec load_wrong_ret_error_examples(map()) :: map()

0 commit comments

Comments
 (0)