fusuma-plugin-wmctrl 0.4.0.pre2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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