-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathmemoize_test.exs
182 lines (146 loc) · 3.83 KB
/
memoize_test.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
defmodule MemoizeTest do
use Memoize.Case
use Memoize
defmemo foo(x, y) when x == 0 do
y
end
defmemo foo(1, y) do
y * 2
end
defmemo foo(x, y, z \\ 0) when x == 2 do
y * z
end
test "defmemo defines foo" do
assert 2 == foo(0, 2)
assert 8 == foo(1, 4)
assert 0 == foo(2, 4)
assert 40 == foo(2, 4, 10)
end
defmemo bar(x, y) do
x + y
end
defmemo bar(x, y, z) do
x + y + z
end
test "defmemo defines bar" do
assert 3 == bar(1, 2)
assert 7 == bar(1, 2, 4)
end
defmemop pri() do
10
end
test "defmemop defines pri" do
assert 10 == pri()
end
test "invalidates cached values when call invalidate/{0-3}" do
f = fn -> 10 end
Memoize.Cache.invalidate()
Memoize.Cache.get_or_run({:mod1, :fun1, [1]}, f)
Memoize.Cache.get_or_run({:mod1, :fun1, [2]}, f)
Memoize.Cache.get_or_run({:mod1, :fun2, [1]}, f)
Memoize.Cache.get_or_run({:mod2, :fun1, [1]}, f)
assert 1 == Memoize.invalidate(:mod1, :fun1, [1])
assert 0 == Memoize.invalidate(:mod1, :fun1, [1])
assert 1 == Memoize.invalidate(:mod1, :fun1)
assert 1 == Memoize.invalidate(:mod1)
Memoize.Cache.get_or_run({:mod1, :fun1, [%{a: 1}]}, f)
assert 1 == Memoize.invalidate(:mod1, :fun1, [%{a: 1}])
assert 1 == Memoize.invalidate()
end
defmemo(nothing_do(x))
defmemo(nothing_do(x) when x == 0, do: 0)
defmemo(nothing_do(x) when x == 1, do: x * 2)
test "even if the `def` function has not `do`, defmemo is passed" do
assert 0 == nothing_do(0)
assert 2 == nothing_do(1)
end
defmemo has_expire(pid), expires_in: 100 do
send(pid, :ok)
end
@tag cache: "default"
test "defmemo with expire" do
assert :ok == has_expire(self())
assert_received :ok
# cached
assert :ok == has_expire(self())
refute_received _
# wait to expire
Process.sleep(120)
assert :ok == has_expire(self())
assert_received :ok
# cached
assert :ok == has_expire(self())
refute_received _
end
defmodule Tarai do
use Memoize
defmemo(tarai(x, y, _z) when x <= y, do: y)
defmemo tarai(x, y, z) do
tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y))
end
end
test "tarai" do
assert 12 == Tarai.tarai(12, 6, 0)
end
defmemo accepts_map_type(value) do
value
end
test "accepts map type" do
value = DateTime.from_iso8601("2000-02-29T06:20:00Z")
assert value == accepts_map_type(value)
map = %{a: 10, b: 20}
nested_map = %{c: 30, d: map}
keyword = [a: 10, b: 20]
tuple = {{:a, 10}, {:b, 20}}
fun = fn -> :ok end
gocha = {map, nested_map, keyword, tuple, fun}
assert map == accepts_map_type(map)
assert nested_map == accepts_map_type(nested_map)
assert keyword == accepts_map_type(keyword)
assert tuple == accepts_map_type(tuple)
assert fun == accepts_map_type(fun)
assert gocha == accepts_map_type(gocha)
end
# test defmemo with unquote
name = :foobar
defmemo(unquote(name)())
defmemo unquote(name)() do
123
end
defmemo unquote(name)(1, y) when y == 2 do
456
end
defmemo unquote(name)(_x, _y, _z \\ 3) do
789
end
test "defmemo with unquote" do
assert 123 == foobar()
assert 456 == foobar(1, 2)
assert 789 == foobar(2, 2)
assert 789 == foobar(1, 2, 3)
end
defmemo waiter_config(), max_waiters: 1, waiter_sleep_ms: 10 do
Process.sleep(100)
1234
end
test "defmemo with waiter config" do
ps =
for _ <- 1..100, into: %{} do
{pid, ref} =
Process.spawn(
fn ->
assert 1234 == waiter_config()
end,
[:monitor]
)
{pid, ref}
end
for _ <- 1..100 do
receive do
{:DOWN, ref, :process, pid, reason} ->
assert ps[pid] == ref
assert reason == :normal
end
end
end
end