aboutsummaryrefslogtreecommitdiff
path: root/test/xdg_pipe_menu_cache_tests.erl
blob: 4b9dfbb7051ec23b55d3139891bcdf561be5aa61 (plain)
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
-module(xdg_pipe_menu_cache_tests).

-include_lib("eunit/include/eunit.hrl").

build_renders_entries_from_dir_test() ->
    Dir = mk_tmp_dir(),
    write_desktop(Dir, "foo.desktop", "Foo", "foo"),
    Menu = xdg_pipe_menu_cache:build([Dir]),
    ok = rm_rf(Dir),
    ?assert(binary:match(Menu, <<"Foo">>) =/= nomatch).

build_groups_by_category_test() ->
    Dir = mk_tmp_dir(),
    write_desktop(Dir, "foo.desktop", "Foo", "foo", "Utility"),
    Menu = xdg_pipe_menu_cache:build([Dir]),
    ok = rm_rf(Dir),
    ?assert(binary:match(Menu, <<"label=\"Utility\"">>) =/= nomatch).

build_skips_hidden_entries_test() ->
    Dir = mk_tmp_dir(),
    write_desktop(Dir, "visible.desktop", "Visible", "visible"),
    ok = file:write_file(
        filename:join(Dir, "hidden.desktop"),
        <<"[Desktop Entry]\nName=Hidden\nExec=hidden\nNoDisplay=true\n">>
    ),
    Menu = xdg_pipe_menu_cache:build([Dir]),
    ok = rm_rf(Dir),
    ?assert(binary:match(Menu, <<"Visible">>) =/= nomatch),
    ?assertEqual(nomatch, binary:match(Menu, <<"Hidden">>)).

build_skips_unparseable_files_without_failing_test() ->
    Dir = mk_tmp_dir(),
    write_desktop(Dir, "good.desktop", "Good", "good"),
    ok = file:write_file(filename:join(Dir, "bad.desktop"), <<"[Desktop Entry]\nExec=bad\n">>),
    Menu = xdg_pipe_menu_cache:build([Dir]),
    ok = rm_rf(Dir),
    ?assert(binary:match(Menu, <<"Good">>) =/= nomatch).

build_skips_missing_dirs_test() ->
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "</openbox_pipe_menu>\n">>,
        xdg_pipe_menu_cache:build(["/does-not-exist"])
    ).

gen_server_serves_and_invalidates_test() ->
    Root = mk_tmp_dir(),
    AppDir = filename:join(Root, "applications"),
    ok = file:make_dir(AppDir),
    write_desktop(AppDir, "foo.desktop", "Foo", "foo"),
    with_env(
        [{"XDG_DATA_HOME", Root}, {"XDG_DATA_DIRS", "/does-not-exist-eunit"}],
        fun() ->
            {ok, Pid} = xdg_pipe_menu_cache:start_link(),
            Menu1 = xdg_pipe_menu_cache:get_menu(),
            ?assert(binary:match(Menu1, <<"Foo">>) =/= nomatch),

            write_desktop(AppDir, "bar.desktop", "Bar", "bar"),
            ok = xdg_pipe_menu_cache:invalidate(),
            Menu2 = xdg_pipe_menu_cache:get_menu(),
            stop(Pid),
            ?assert(binary:match(Menu2, <<"Bar">>) =/= nomatch)
        end
    ),
    ok = rm_rf(Root).

%% -- 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).

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"])
    ).

write_desktop(Dir, FileName, Name, Exec, Categories) ->
    ok = file:write_file(
        filename:join(Dir, FileName),
        iolist_to_binary([
            "[Desktop Entry]\nName=",
            Name,
            "\nExec=",
            Exec,
            "\nCategories=",
            Categories,
            ";\n"
        ])
    ).

mk_tmp_dir() ->
    Path = filename:join(
        test_tmp_dir(), "eunit-cache-" ++ 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.