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
|
-module(xdg_pipe_menu_watcher_tests).
-include_lib("eunit/include/eunit.hrl").
%% Exercises the real debounce-timer-reset-then-invalidate wiring by
%% sending the watcher a synthetic message of the exact shape `fs'
%% delivers, rather than waiting on a real inotify event -- `fs'
%% itself is treated as out of scope for this test.
debounced_event_invalidates_cache_test() ->
Root = mk_tmp_dir(),
AppDir = filename:join(Root, "applications"),
ok = file:make_dir(AppDir),
write_desktop(AppDir, "foo.desktop", "Foo", "foo"),
PrevDebounce = application:get_env(xdg_pipe_menu, debounce_ms),
application:set_env(xdg_pipe_menu, debounce_ms, 20),
with_env(
[{"XDG_DATA_HOME", Root}, {"XDG_DATA_DIRS", "/does-not-exist-eunit"}],
fun() ->
{ok, CachePid} = xdg_pipe_menu_cache:start_link(),
{ok, WatcherPid} = xdg_pipe_menu_watcher:start_link(),
write_desktop(AppDir, "bar.desktop", "Bar", "bar"),
WatcherPid ! {self(), {fs, file_event}, {"dummy", [modified]}},
timer:sleep(100),
Menu = xdg_pipe_menu_cache:get_menu(),
stop(WatcherPid),
stop(CachePid),
?assert(binary:match(Menu, <<"Bar">>) =/= nomatch)
end
),
ok = rm_rf(Root),
restore_env(xdg_pipe_menu, debounce_ms, PrevDebounce).
%% -- helpers ----------------------------------------------------------------
%% start_link/0 links the started process to us (the test process);
%% unlink before killing it so the kill signal doesn't propagate back
%% and take the test process down with it.
stop(Pid) ->
unlink(Pid),
true = erlang:exit(Pid, kill).
restore_env(App, Key, undefined) -> application:unset_env(App, Key);
restore_env(App, Key, {ok, Value}) -> application:set_env(App, Key, Value).
with_env(Vars, Fun) ->
Saved = [{Name, os:getenv(Name)} || {Name, _} <- Vars],
try
lists:foreach(fun({Name, Value}) -> set_env(Name, Value) end, Vars),
Fun()
after
lists:foreach(fun({Name, Value}) -> set_env(Name, Value) end, Saved)
end.
set_env(Name, false) -> os:unsetenv(Name);
set_env(Name, Value) -> os:putenv(Name, Value).
write_desktop(Dir, FileName, Name, Exec) ->
ok = file:write_file(
filename:join(Dir, FileName),
iolist_to_binary(["[Desktop Entry]\nName=", Name, "\nExec=", Exec, "\n"])
).
mk_tmp_dir() ->
Path = filename:join(
test_tmp_dir(), "eunit-watcher-" ++ integer_to_list(erlang:unique_integer([positive]))
),
ok = file:make_dir(Path),
Path.
test_tmp_dir() ->
case os:getenv("TMPDIR") of
false -> "/tmp";
Dir -> Dir
end.
rm_rf(Path) ->
case filelib:is_dir(Path) of
true ->
{ok, Entries} = file:list_dir(Path),
lists:foreach(fun(E) -> rm_rf(filename:join(Path, E)) end, Entries),
file:del_dir(Path);
false ->
file:delete(Path)
end.
|