diff options
Diffstat (limited to 'test/xdg_pipe_menu_watcher_tests.erl')
| -rw-r--r-- | test/xdg_pipe_menu_watcher_tests.erl | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/test/xdg_pipe_menu_watcher_tests.erl b/test/xdg_pipe_menu_watcher_tests.erl new file mode 100644 index 0000000..cca5cc2 --- /dev/null +++ b/test/xdg_pipe_menu_watcher_tests.erl @@ -0,0 +1,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. |
