aboutsummaryrefslogtreecommitdiff
path: root/test/er_xdg_pipe_menu_renderer_tests.erl
blob: 7273625aee021de7576ef15e47839ff06179aa9e (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
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
-module(er_xdg_pipe_menu_renderer_tests).

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

entry(Name, Exec, Icon) ->
    entry(Name, Exec, Icon, []).

entry(Name, Exec, Icon, Categories) ->
    entry(Name, Exec, Icon, Categories, false).

entry(Name, Exec, Icon, Categories, Hidden) ->
    #desktop_entry{
        name = Name, exec = Exec, icon = Icon, categories = Categories, hidden = Hidden
    }.

empty_list_renders_empty_menu_test() ->
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "</openbox_pipe_menu>\n">>,
        er_xdg_pipe_menu_renderer:render([])
    ).

single_entry_with_icon_test() ->
    Rendered = er_xdg_pipe_menu_renderer:render([
        entry(<<"Firefox">>, <<"firefox">>, <<"firefox">>, [<<"Network">>])
    ]),
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "  <menu id=\"Network\" label=\"Network\">\n"
          "    <item label=\"Firefox\" icon=\"firefox\">\n"
          "      <action name=\"Execute\">\n"
          "        <command>firefox</command>\n"
          "      </action>\n"
          "    </item>\n"
          "  </menu>\n"
          "</openbox_pipe_menu>\n">>,
        Rendered
    ).

entry_without_icon_omits_icon_attr_test() ->
    Rendered = er_xdg_pipe_menu_renderer:render([
        entry(<<"Foo">>, <<"foo">>, undefined, [<<"Utility">>])
    ]),
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "  <menu id=\"Utility\" label=\"Utility\">\n"
          "    <item label=\"Foo\">\n"
          "      <action name=\"Execute\">\n"
          "        <command>foo</command>\n"
          "      </action>\n"
          "    </item>\n"
          "  </menu>\n"
          "</openbox_pipe_menu>\n">>,
        Rendered
    ).

entries_without_categories_go_in_other_submenu_test() ->
    Rendered = er_xdg_pipe_menu_renderer:render([entry(<<"Foo">>, <<"foo">>, undefined)]),
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "  <menu id=\"Other\" label=\"Other\">\n"
          "    <item label=\"Foo\">\n"
          "      <action name=\"Execute\">\n"
          "        <command>foo</command>\n"
          "      </action>\n"
          "    </item>\n"
          "  </menu>\n"
          "</openbox_pipe_menu>\n">>,
        Rendered
    ).

hidden_entries_are_dropped_test() ->
    Entries = [
        entry(<<"Visible">>, <<"visible">>, undefined, [<<"Utility">>]),
        entry(<<"Invisible">>, <<"invisible">>, undefined, [<<"Utility">>], true)
    ],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    ?assertNot(binary:match(Rendered, <<"Invisible">>) =/= nomatch),
    ?assert(binary:match(Rendered, <<"Visible">>) =/= nomatch).

hidden_entry_leaves_no_empty_submenu_test() ->
    Entries = [entry(<<"Invisible">>, <<"invisible">>, undefined, [<<"Utility">>], true)],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    ?assertNot(binary:match(Rendered, <<"Utility">>) =/= nomatch).

entries_are_sorted_case_insensitively_within_a_submenu_test() ->
    Entries = [
        entry(<<"zeta">>, <<"zeta">>, undefined, [<<"Utility">>]),
        entry(<<"Alpha">>, <<"alpha">>, undefined, [<<"Utility">>]),
        entry(<<"beta">>, <<"beta">>, undefined, [<<"Utility">>])
    ],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    Positions = [
        element(1, binary:match(Rendered, <<"label=\"Alpha\"">>)),
        element(1, binary:match(Rendered, <<"label=\"beta\"">>)),
        element(1, binary:match(Rendered, <<"label=\"zeta\"">>))
    ],
    ?assertEqual(Positions, lists:sort(Positions)).

submenus_are_sorted_case_insensitively_test() ->
    Entries = [
        entry(<<"Zed App">>, <<"zed">>, undefined, [<<"zeta">>]),
        entry(<<"Alpha App">>, <<"alpha">>, undefined, [<<"Alpha">>]),
        entry(<<"Beta App">>, <<"beta">>, undefined, [<<"beta">>])
    ],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    Positions = [
        element(1, binary:match(Rendered, <<"label=\"Alpha\"">>)),
        element(1, binary:match(Rendered, <<"label=\"beta\"">>)),
        element(1, binary:match(Rendered, <<"label=\"zeta\"">>))
    ],
    ?assertEqual(Positions, lists:sort(Positions)).

entry_with_multiple_categories_appears_in_each_submenu_test() ->
    Entries = [entry(<<"Foo">>, <<"foo">>, undefined, [<<"Utility">>, <<"Development">>])],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    {Doc, _Rest} = xmerl_scan:string(binary_to_list(Rendered)),
    Menus = [E || E = #xmlElement{name = menu} <- Doc#xmlElement.content],
    ?assertEqual([<<"Development">>, <<"Utility">>], lists:sort([menu_id(M) || M <- Menus])),
    Items = [I || M <- Menus, I = #xmlElement{name = item} <- M#xmlElement.content],
    ?assertEqual(2, length(Items)).

escapes_special_characters_test() ->
    Entry = entry(
        <<"Foo & <Bar> \"Baz\"">>,
        <<"foo --title=\"<x>&y\"">>,
        <<"icon\"&<>">>,
        [<<"Foo & <Bar>">>]
    ),
    Rendered = er_xdg_pipe_menu_renderer:render([Entry]),
    ?assertEqual(
        <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          "<openbox_pipe_menu>\n"
          "  <menu id=\"Foo &amp; &lt;Bar>\" label=\"Foo &amp; &lt;Bar>\">\n"
          "    <item label=\"Foo &amp; &lt;Bar> &quot;Baz&quot;\" icon=\"icon&quot;&amp;&lt;>\">\n"
          "      <action name=\"Execute\">\n"
          "        <command>foo --title=\"&lt;x&gt;&amp;y\"</command>\n"
          "      </action>\n"
          "    </item>\n"
          "  </menu>\n"
          "</openbox_pipe_menu>\n">>,
        Rendered
    ).

output_is_well_formed_xml_test() ->
    Entries = [
        entry(<<"Firefox">>, <<"firefox">>, <<"firefox">>, [<<"Network">>]),
        entry(<<"Foo & Bar">>, <<"foo">>, undefined, [<<"Network">>])
    ],
    Rendered = er_xdg_pipe_menu_renderer:render(Entries),
    {Doc, _Rest} = xmerl_scan:string(binary_to_list(Rendered)),
    ?assertEqual(openbox_pipe_menu, Doc#xmlElement.name),
    Menus = [E || E = #xmlElement{name = menu} <- Doc#xmlElement.content],
    ?assertEqual(1, length(Menus)),
    [Menu] = Menus,
    Items = [E || E = #xmlElement{name = item} <- Menu#xmlElement.content],
    ?assertEqual(2, length(Items)).

menu_id(#xmlElement{attributes = Attrs}) ->
    [Value] = [V || #xmlAttribute{name = id, value = V} <- Attrs],
    list_to_binary(Value).