fusuma-plugin-wmctrl 0.4.0.pre2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,358 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fusuma/plugin/executors/executor'
6
+ require 'fusuma/plugin/events/event'
7
+ require 'fusuma/plugin/events/records/index_record'
8
+
9
+ require './lib/fusuma/plugin/executors/wmctrl_executor'
10
+
11
+ module Fusuma
12
+ module Plugin
13
+ module Executors
14
+ RSpec.describe WmctrlExecutor do
15
+ before do
16
+ @workspace = double(Workspace)
17
+ allow(Workspace)
18
+ .to receive(:new)
19
+ .and_return(@workspace)
20
+
21
+ index = Config::Index.new([:dummy, 1, :direction])
22
+ record = Events::Records::IndexRecord.new(index: index)
23
+ @event = Events::Event.new(tag: 'dummy_detector', record: record)
24
+ @executor = WmctrlExecutor.new
25
+ allow(@executor).to receive(:search_command).and_return 'dummy command'
26
+ end
27
+
28
+ around do |example|
29
+ ConfigHelper.load_config_yml = <<~CONFIG
30
+ dummy:
31
+ 1:
32
+ direction:
33
+ workspace: 'prev'
34
+ CONFIG
35
+
36
+ example.run
37
+
38
+ Config.custom_path = nil
39
+ end
40
+
41
+ describe '#execute' do
42
+ it 'detach' do
43
+ pid = rand(20)
44
+ allow(Process).to receive(:spawn).with(@executor.search_command(@event))
45
+ .and_return pid
46
+
47
+ expect(Process).to receive(:detach).with(pid)
48
+
49
+ @executor.execute(@event)
50
+ end
51
+ end
52
+
53
+ describe '#executable?' do
54
+ context 'when given valid event tagged as xxxx_detector' do
55
+ it { expect(@executor.executable?(@event)).to be_truthy }
56
+ end
57
+
58
+ context 'when given INVALID event tagged as invalid_tag' do
59
+ before do
60
+ @event.tag = 'invalid_tag'
61
+ end
62
+ it { expect(@executor.executable?(@event)).to be_falsey }
63
+ end
64
+ end
65
+
66
+ describe '#search_command' do
67
+ before do
68
+ allow(@executor).to receive(:search_command).and_call_original
69
+
70
+ @current_workspace = 1
71
+ @total_workspaces = 3
72
+ allow(@workspace)
73
+ .to receive(:workspace_values)
74
+ .and_return([@current_workspace, @total_workspaces])
75
+ end
76
+ context "when workspace: 'prev'" do
77
+ around do |example|
78
+ ConfigHelper.load_config_yml = <<~CONFIG
79
+ dummy:
80
+ 1:
81
+ direction:
82
+ workspace: 'prev'
83
+ CONFIG
84
+
85
+ example.run
86
+
87
+ Config.custom_path = nil
88
+ end
89
+
90
+ it 'should return wmctrl command' do
91
+ expect(@workspace).to receive(:move_command).with(direction: 'prev')
92
+ @executor.search_command(@event)
93
+ end
94
+ end
95
+
96
+ context "when window: 'prev'" do
97
+ around do |example|
98
+ ConfigHelper.load_config_yml = <<~CONFIG
99
+ dummy:
100
+ 1:
101
+ direction:
102
+ window: 'prev'
103
+ CONFIG
104
+
105
+ example.run
106
+
107
+ Config.custom_path = nil
108
+ end
109
+
110
+ it 'should return wmctrl command' do
111
+ expect(@workspace).to receive(:move_window_command).with(direction: 'prev')
112
+ @executor.search_command(@event)
113
+ end
114
+ end
115
+
116
+ context "when window: 'fullscreen'" do
117
+ around do |example|
118
+ ConfigHelper.load_config_yml = <<~CONFIG
119
+ dummy:
120
+ 1:
121
+ direction:
122
+ window: 'fullscreen'
123
+ CONFIG
124
+
125
+ example.run
126
+
127
+ Config.custom_path = nil
128
+ end
129
+
130
+ it 'should return wmctrl command' do
131
+ expect(@executor.search_command(@event))
132
+ .to match(/wmctrl -r :ACTIVE: -b toggle,fullscreen/)
133
+ end
134
+ end
135
+
136
+ context 'when window: [fullscreen: something]' do
137
+ context "when fullscreen: 'toggle'" do
138
+ around do |example|
139
+ ConfigHelper.load_config_yml = <<~CONFIG
140
+ dummy:
141
+ 1:
142
+ direction:
143
+ window:
144
+ fullscreen: 'toggle'
145
+ CONFIG
146
+
147
+ example.run
148
+
149
+ Config.custom_path = nil
150
+ end
151
+
152
+ it 'should return wmctrl command' do
153
+ expect(@executor.search_command(@event))
154
+ .to match(/wmctrl -r :ACTIVE: -b toggle,fullscreen/)
155
+ end
156
+ end
157
+
158
+ context "when fullscreen: 'add'" do
159
+ around do |example|
160
+ ConfigHelper.load_config_yml = <<~CONFIG
161
+ dummy:
162
+ 1:
163
+ direction:
164
+ window:
165
+ fullscreen: 'add'
166
+ CONFIG
167
+
168
+ example.run
169
+
170
+ Config.custom_path = nil
171
+ end
172
+
173
+ it 'should return wmctrl command' do
174
+ expect(@executor.search_command(@event))
175
+ .to match(/wmctrl -r :ACTIVE: -b add,fullscreen/)
176
+ end
177
+ end
178
+
179
+ context "when fullscreen: 'remove'" do
180
+ around do |example|
181
+ ConfigHelper.load_config_yml = <<~CONFIG
182
+ dummy:
183
+ 1:
184
+ direction:
185
+ window:
186
+ fullscreen: 'remove'
187
+ CONFIG
188
+
189
+ example.run
190
+
191
+ Config.custom_path = nil
192
+ end
193
+
194
+ it 'should return wmctrl command' do
195
+ expect(@executor.search_command(@event))
196
+ .to match(/wmctrl -r :ACTIVE: -b remove,fullscreen/)
197
+ end
198
+ end
199
+ end
200
+
201
+ context "when window: 'maximized'" do
202
+ around do |example|
203
+ ConfigHelper.load_config_yml = <<~CONFIG
204
+ dummy:
205
+ 1:
206
+ direction:
207
+ window: 'maximized'
208
+ CONFIG
209
+
210
+ example.run
211
+
212
+ Config.custom_path = nil
213
+ end
214
+
215
+ it 'should return wmctrl command' do
216
+ expect(@executor.search_command(@event))
217
+ .to match(/wmctrl -r :ACTIVE: -b toggle,maximized/)
218
+ end
219
+ end
220
+
221
+ context 'when window: [maximized: something]' do
222
+ context "when maximized: 'toggle'" do
223
+ around do |example|
224
+ ConfigHelper.load_config_yml = <<~CONFIG
225
+ dummy:
226
+ 1:
227
+ direction:
228
+ window:
229
+ maximized: 'toggle'
230
+ CONFIG
231
+
232
+ example.run
233
+
234
+ Config.custom_path = nil
235
+ end
236
+
237
+ it 'should return wmctrl command' do
238
+ expect(@executor.search_command(@event))
239
+ .to match(/wmctrl -r :ACTIVE: -b toggle,maximized/)
240
+ end
241
+ end
242
+
243
+ context "when maximized: 'add'" do
244
+ around do |example|
245
+ ConfigHelper.load_config_yml = <<~CONFIG
246
+ dummy:
247
+ 1:
248
+ direction:
249
+ window:
250
+ maximized: 'add'
251
+ CONFIG
252
+
253
+ example.run
254
+
255
+ Config.custom_path = nil
256
+ end
257
+
258
+ it 'should return wmctrl command' do
259
+ expect(@executor.search_command(@event))
260
+ .to match(/wmctrl -r :ACTIVE: -b add,maximized/)
261
+ end
262
+ end
263
+
264
+ context "when maximized: 'remove'" do
265
+ around do |example|
266
+ ConfigHelper.load_config_yml = <<~CONFIG
267
+ dummy:
268
+ 1:
269
+ direction:
270
+ window:
271
+ maximized: 'remove'
272
+ CONFIG
273
+
274
+ example.run
275
+
276
+ Config.custom_path = nil
277
+ end
278
+
279
+ it 'should return wmctrl command' do
280
+ expect(@executor.search_command(@event))
281
+ .to match(/wmctrl -r :ACTIVE: -b remove,maximized/)
282
+ end
283
+ end
284
+ end
285
+ context "when window: 'close'" do
286
+ around do |example|
287
+ ConfigHelper.load_config_yml = <<~CONFIG
288
+ dummy:
289
+ 1:
290
+ direction:
291
+ window: 'close'
292
+ CONFIG
293
+
294
+ example.run
295
+
296
+ Config.custom_path = nil
297
+ end
298
+
299
+ it 'should return wmctrl command' do
300
+ expect(@executor.search_command(@event))
301
+ .to match(/wmctrl -c :ACTIVE:/)
302
+ end
303
+ end
304
+
305
+ describe 'wrap_navigation: true' do
306
+ around do |example|
307
+ ConfigHelper.load_config_yml = <<~CONFIG
308
+ plugin:
309
+ executors:
310
+ wmctrl_executor:
311
+ wrap-navigation: true
312
+ CONFIG
313
+
314
+ example.run
315
+
316
+ Config.custom_path = nil
317
+ end
318
+
319
+ it 'should wrap-navigation mode' do
320
+ expect(Workspace).to receive(:new).with(
321
+ wrap_navigation: true,
322
+ matrix_col_size: nil
323
+ )
324
+ WmctrlExecutor.new
325
+ end
326
+ end
327
+
328
+ describe 'matrix-col-size' do
329
+ context "with matrix-col-size: '3', right" do
330
+ around do |example|
331
+ ConfigHelper.load_config_yml = <<~CONFIG
332
+ dummy:
333
+ 1:
334
+ direction:
335
+ window: 'right'
336
+ plugin:
337
+ executors:
338
+ wmctrl_executor:
339
+ matrix-col-size: 3
340
+ CONFIG
341
+
342
+ example.run
343
+
344
+ Config.custom_path = nil
345
+ end
346
+
347
+ it 'should return wmctrl command with index of right(next) workspace' do
348
+ expect(@workspace).to receive(:move_window_command_for_matrix)
349
+ .with(direction: 'right')
350
+ @executor.search_command(@event)
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require './lib/fusuma/plugin/wmctrl/workspace'
5
+
6
+ module Fusuma
7
+ module Plugin
8
+ module Wmctrl
9
+ RSpec.describe Workspace do
10
+ def stub_workspace_values(current:, total:)
11
+ allow(@workspace).to receive(:workspace_values).and_return([current, total])
12
+ end
13
+
14
+ before { @workspace = Workspace.new }
15
+
16
+ describe '#move_command' do
17
+ before { stub_workspace_values(current: 1, total: 3) }
18
+
19
+ context "with 'direction: next'" do
20
+ before { @direction = 'next' }
21
+ it 'returns wmctrl command to move NEXT workspace' do
22
+ expect(@workspace.move_command(direction: @direction))
23
+ .to match(/wmctrl -s 2/)
24
+ end
25
+ it 'calls next_workspace_num' do
26
+ expect(@workspace).to receive(:next_workspace_num).with(step: 1)
27
+ @workspace.move_command(direction: @direction)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#move_command_for_matrix' do
33
+ before do
34
+ @workspace = Workspace.new(matrix_col_size: 3)
35
+ stub_workspace_values(current: 0, total: 9)
36
+ end
37
+
38
+ context "with direction: 'right'" do
39
+ before { @direction = 'right' }
40
+
41
+ it 'returns wmctrl command to move RIGHT workspace' do
42
+ expect(@workspace.move_command_for_matrix(direction: @direction))
43
+ .to match(/wmctrl -s 1/)
44
+ end
45
+ it 'calls next_workspace_num_for_matrix' do
46
+ expect(@workspace).to receive(:next_workspace_num_for_matrix)
47
+ .with(direction: @direction)
48
+ @workspace.move_command_for_matrix(direction: @direction)
49
+ end
50
+ end
51
+ context "with direction: 'down'" do
52
+ before { @direction = 'down' }
53
+
54
+ it 'returns wmctrl command to move workspace to DOWN' do
55
+ expect(@workspace.move_command_for_matrix(direction: @direction))
56
+ .to match(/wmctrl -s 3/)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#move_window_command' do
62
+ before { stub_workspace_values(current: 1, total: 3) }
63
+
64
+ context "with direction: 'next'" do
65
+ before { @direction = 'next' }
66
+
67
+ it 'returns wmctrl command to move NEXT workspace' do
68
+ wmctrl_move_window = /wmctrl -r :ACTIVE: -t 2/
69
+ wmctrl_move_workspace = /wmctrl -s 2/
70
+ expect(@workspace.move_window_command(direction: @direction))
71
+ .to match(wmctrl_move_window)
72
+ expect(@workspace.move_window_command(direction: @direction))
73
+ .to match(wmctrl_move_workspace)
74
+ end
75
+ end
76
+
77
+ context "with direction: 'prev'" do
78
+ before { @direction = 'prev' }
79
+
80
+ it 'returns wmctrl command to move NEXT workspace' do
81
+ wmctrl_move_window = /wmctrl -r :ACTIVE: -t 0/
82
+ wmctrl_move_workspace = /wmctrl -s 0/
83
+ expect(@workspace.move_window_command(direction: @direction))
84
+ .to match(wmctrl_move_window)
85
+ expect(@workspace.move_window_command(direction: @direction))
86
+ .to match(wmctrl_move_workspace)
87
+ end
88
+ end
89
+ end
90
+
91
+ describe '#move_window_command_for_matrix' do
92
+ before do
93
+ @workspace = Workspace.new(matrix_col_size: 3)
94
+ stub_workspace_values(current: 0, total: 9)
95
+ end
96
+
97
+ context "with direction: 'right'" do
98
+ before { @direction = 'right' }
99
+
100
+ it 'returns wmctrl command to move NEXT workspace' do
101
+ wmctrl_move_window = /wmctrl -r :ACTIVE: -t 1/
102
+ wmctrl_move_workspace = /wmctrl -s 1/
103
+ expect(@workspace.move_window_command_for_matrix(direction: @direction))
104
+ .to match(wmctrl_move_window)
105
+ expect(@workspace.move_window_command_for_matrix(direction: @direction))
106
+ .to match(wmctrl_move_workspace)
107
+ end
108
+ end
109
+ context "with direction: 'down'" do
110
+ before { @direction = 'down' }
111
+
112
+ it 'returns wmctrl command to move NEXT workspace' do
113
+ wmctrl_move_window = /wmctrl -r :ACTIVE: -t 3/
114
+ wmctrl_move_workspace = /wmctrl -s 3/
115
+ expect(@workspace.move_window_command_for_matrix(direction: @direction))
116
+ .to match(wmctrl_move_window)
117
+ expect(@workspace.move_window_command_for_matrix(direction: @direction))
118
+ .to match(wmctrl_move_workspace)
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#next_workspace_num' do
124
+ before { stub_workspace_values(current: 1, total: 3) }
125
+ context 'with step: 1' do
126
+ before { @step = 1 }
127
+ it { expect(@workspace.next_workspace_num(step: @step)).to eq 1 + @step }
128
+ end
129
+ end
130
+
131
+ describe '#next_workspace_num_for_matrix' do
132
+ context 'without matrix option' do
133
+ before { @workspace = Workspace.new(matrix_col_size: nil) }
134
+
135
+ it 'raises InvalidOption' do
136
+ expect do
137
+ @workspace.next_workspace_num_for_matrix(direction: 'prev')
138
+ end.to raise_error(Workspace::InvalidOption)
139
+ end
140
+ end
141
+
142
+ context 'with matrix_col_size: 3' do
143
+ # +---+---+---+
144
+ # | 0 | 1 | 2 |
145
+ # +---+---+---+
146
+ # | 3 | 4 | 5 |
147
+ # +---+---+---+
148
+ # | 6 | 7 | 8 |
149
+ # +---+---+---+
150
+ before do
151
+ @workspace = Workspace.new(matrix_col_size: 3)
152
+ stub_workspace_values(current: 1, total: 9)
153
+ end
154
+
155
+ context 'with invalid direction' do
156
+ before { @direction = 'foo' }
157
+ it 'raises InvalidOption' do
158
+ expect do
159
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
160
+ end.to raise_error(RuntimeError, "#{@direction} is invalid key")
161
+ end
162
+ end
163
+
164
+ context 'with direction: right' do
165
+ before { @direction = 'right' }
166
+ it 'next workspace' do
167
+ expect(
168
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
169
+ ).to eq 2
170
+ end
171
+ context 'when current_workspace is right edge' do
172
+ before { stub_workspace_values(current: 2, total: 9) }
173
+ it 'same workspace' do
174
+ expect(
175
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
176
+ ).to eq 2
177
+ end
178
+
179
+ context 'with wrap_navigation: true' do
180
+ before { @workspace.instance_variable_set(:@wrap_navigation, true) }
181
+ it 'same workspace' do
182
+ expect(
183
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
184
+ ).to eq 0
185
+ end
186
+ end
187
+ end
188
+ end
189
+ context 'with direction: down' do
190
+ before { @direction = 'down' }
191
+ it 'next workspace' do
192
+ expect(
193
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
194
+ ).to eq 4
195
+ end
196
+ context 'when current_workspace is bottom' do
197
+ before { stub_workspace_values(current: 7, total: 9) }
198
+ it 'same workspace' do
199
+ expect(
200
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
201
+ ).to eq 7
202
+ end
203
+
204
+ context 'with wrap_navigation: true' do
205
+ before { @workspace.instance_variable_set(:@wrap_navigation, true) }
206
+ it 'same workspace' do
207
+ expect(
208
+ @workspace.next_workspace_num_for_matrix(direction: @direction)
209
+ ).to eq 1
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ describe '#matrix_size' do
218
+ context 'with matrix_col_size' do
219
+ before do
220
+ @workspace = Workspace.new(matrix_col_size: 3)
221
+ stub_workspace_values(current: 1, total: 3)
222
+ end
223
+ it { expect(@workspace.matrix_size(3)).to eq [1, 3] }
224
+ end
225
+ context 'with matrix_col_size' do
226
+ before do
227
+ @workspace = Workspace.new(matrix_col_size: nil)
228
+ stub_workspace_values(current: 1, total: 3)
229
+ end
230
+ it { expect { @workspace.matrix_size(3) }.to raise_error Workspace::InvalidOption }
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end