aboutsummaryrefslogtreecommitdiff
path: root/test/xdg_pipe_menu_socket_tests.erl
diff options
context:
space:
mode:
authorChristopher R. Nelson <christopher.nelson@languidnights.com>2026-07-21 11:44:41 -0400
committerChristopher R. Nelson <christopher.nelson@languidnights.com>2026-07-21 11:44:41 -0400
commit5ff1fbe175af17fbb808c5ea942f465a932da3af (patch)
treeb6a26b4b7e896e5ed5d85a5003c4d176ed5c8e9e /test/xdg_pipe_menu_socket_tests.erl
parent7e8472e1e2a0b39746ef86c041d56b92bab5a6b7 (diff)
Rename app from er_xdg_pipe_menu to xdg_pipe_menuHEADmain
Drop the "er-" prefix throughout: module/atom names, filenames, socket paths, and docs. It was an implementation detail, not part of the app's identity. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'test/xdg_pipe_menu_socket_tests.erl')
-rw-r--r--test/xdg_pipe_menu_socket_tests.erl93
1 files changed, 93 insertions, 0 deletions
diff --git a/test/xdg_pipe_menu_socket_tests.erl b/test/xdg_pipe_menu_socket_tests.erl
new file mode 100644
index 0000000..91cd3e4
--- /dev/null
+++ b/test/xdg_pipe_menu_socket_tests.erl
@@ -0,0 +1,93 @@
+-module(xdg_pipe_menu_socket_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+serves_the_cached_menu_test() ->
+ Root = mk_tmp_dir(),
+ AppDir = filename:join(Root, "applications"),
+ ok = file:make_dir(AppDir),
+ write_desktop(AppDir, "foo.desktop", "Foo", "foo"),
+ SockPath = filename:join(
+ test_tmp_dir(), "eunit-socket-" ++ integer_to_list(erlang:unique_integer([positive]))
+ ),
+ PrevSockPath = application:get_env(xdg_pipe_menu, socket_path),
+ application:set_env(xdg_pipe_menu, socket_path, SockPath),
+ with_env(
+ [{"XDG_DATA_HOME", Root}, {"XDG_DATA_DIRS", "/does-not-exist-eunit"}],
+ fun() ->
+ {ok, CachePid} = xdg_pipe_menu_cache:start_link(),
+ {ok, SocketPid} = xdg_pipe_menu_socket:start_link(),
+
+ {ok, Conn} = gen_tcp:connect({local, SockPath}, 0, [binary, {active, false}], 1000),
+ Received = recv_all(Conn, []),
+ gen_tcp:close(Conn),
+
+ Expected = xdg_pipe_menu_cache:get_menu(),
+ stop(SocketPid),
+ stop(CachePid),
+ ?assertEqual(Expected, Received),
+ ?assert(binary:match(Received, <<"Foo">>) =/= nomatch)
+ end
+ ),
+ _ = file:delete(SockPath),
+ ok = rm_rf(Root),
+ restore_env(xdg_pipe_menu, socket_path, PrevSockPath).
+
+%% -- 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).
+
+recv_all(Socket, Acc) ->
+ case gen_tcp:recv(Socket, 0, 1000) of
+ {ok, Data} -> recv_all(Socket, [Data | Acc]);
+ {error, closed} -> iolist_to_binary(lists:reverse(Acc))
+ end.
+
+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-socket-dir-" ++ 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.