uh-wm 0.0.2.pre → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +15 -0
  5. data/Gemfile +5 -0
  6. data/Guardfile +12 -0
  7. data/LICENSE +30 -0
  8. data/README.md +68 -0
  9. data/Rakefile +40 -0
  10. data/bin/uhwm +5 -0
  11. data/config/cucumber.yaml +1 -0
  12. data/features/actions/execute.feature +9 -0
  13. data/features/actions/layout_delegation.feature +31 -0
  14. data/features/actions/quit.feature +9 -0
  15. data/features/cli/debug.feature +5 -0
  16. data/features/cli/layout.feature +15 -0
  17. data/features/cli/require.feature +5 -0
  18. data/features/cli/run_control.feature +9 -0
  19. data/features/cli/usage.feature +11 -0
  20. data/features/cli/verbose.feature +5 -0
  21. data/features/cli/version.feature +6 -0
  22. data/features/cli/worker.feature +9 -0
  23. data/features/layout/manage.feature +12 -0
  24. data/features/layout/protocol.feature +24 -0
  25. data/features/layout/unmanage.feature +10 -0
  26. data/features/manager/check_other_wm.feature +8 -0
  27. data/features/manager/input_events.feature +8 -0
  28. data/features/manager/manage.feature +14 -0
  29. data/features/manager/unmanage.feature +13 -0
  30. data/features/manager/x_errors.feature +17 -0
  31. data/features/run_control/evaluation.feature +18 -0
  32. data/features/run_control/key.feature +33 -0
  33. data/features/run_control/modifier.feature +10 -0
  34. data/features/run_control/worker.feature +9 -0
  35. data/features/session/connection.feature +5 -0
  36. data/features/session/termination.feature +13 -0
  37. data/features/steps/filesystem_steps.rb +3 -0
  38. data/features/steps/output_steps.rb +44 -0
  39. data/features/steps/run_control_steps.rb +3 -0
  40. data/features/steps/run_steps.rb +41 -0
  41. data/features/steps/x_steps.rb +53 -0
  42. data/features/support/env.rb +33 -0
  43. data/lib/uh/wm.rb +8 -0
  44. data/lib/uh/wm/actions_handler.rb +46 -0
  45. data/lib/uh/wm/cli.rb +20 -13
  46. data/lib/uh/wm/client.rb +64 -0
  47. data/lib/uh/wm/dispatcher.rb +3 -1
  48. data/lib/uh/wm/env.rb +15 -9
  49. data/lib/uh/wm/env_logging.rb +8 -0
  50. data/lib/uh/wm/logger_formatter.rb +16 -0
  51. data/lib/uh/wm/manager.rb +96 -14
  52. data/lib/uh/wm/run_control.rb +8 -3
  53. data/lib/uh/wm/runner.rb +82 -14
  54. data/lib/uh/wm/testing/acceptance_helpers.rb +140 -18
  55. data/lib/uh/wm/version.rb +1 -1
  56. data/lib/uh/wm/workers.rb +21 -0
  57. data/lib/uh/wm/workers/base.rb +27 -0
  58. data/lib/uh/wm/workers/blocking.rb +11 -0
  59. data/lib/uh/wm/workers/mux.rb +18 -0
  60. data/spec/spec_helper.rb +26 -0
  61. data/spec/support/exit_helpers.rb +6 -0
  62. data/spec/support/filesystem_helpers.rb +11 -0
  63. data/spec/uh/wm/actions_handler_spec.rb +30 -0
  64. data/spec/uh/wm/cli_spec.rb +214 -0
  65. data/spec/uh/wm/client_spec.rb +133 -0
  66. data/spec/uh/wm/dispatcher_spec.rb +76 -0
  67. data/spec/uh/wm/env_spec.rb +145 -0
  68. data/spec/uh/wm/manager_spec.rb +355 -0
  69. data/spec/uh/wm/run_control_spec.rb +102 -0
  70. data/spec/uh/wm/runner_spec.rb +186 -0
  71. data/uh-wm.gemspec +25 -0
  72. metadata +112 -9
@@ -0,0 +1,133 @@
1
+ module Uh
2
+ module WM
3
+ RSpec.describe Client do
4
+ let(:geo) { Geo.new(0, 0, 640, 480) }
5
+ let(:window) do
6
+ instance_spy Window, 'window', to_s: 'wid',
7
+ name: 'wname', wclass: 'wclass'
8
+ end
9
+ subject(:client) { described_class.new window, geo }
10
+
11
+ it 'is not visible' do
12
+ expect(client).not_to be_visible
13
+ end
14
+
15
+ it 'is hidden' do
16
+ expect(client).to be_hidden
17
+ end
18
+
19
+ it 'has an unmap count of 0' do
20
+ expect(client.unmap_count).to eq 0
21
+ end
22
+
23
+ describe '#to_s' do
24
+ it 'includes window name' do
25
+ expect(client.to_s).to include 'wname'
26
+ end
27
+
28
+ it 'includes window class' do
29
+ expect(client.to_s).to include 'wclass'
30
+ end
31
+
32
+ it 'includes geo' do
33
+ expect(client.to_s).to include geo.to_s
34
+ end
35
+
36
+ it 'includes window id' do
37
+ expect(client.to_s).to include 'wid'
38
+ end
39
+ end
40
+
41
+ describe '#name' do
42
+ it 'returns the window name' do
43
+ expect(client.name).to eq window.name
44
+ end
45
+ end
46
+
47
+ describe '#wclass' do
48
+ it 'returns the window class' do
49
+ expect(client.wclass).to eq window.wclass
50
+ end
51
+ end
52
+
53
+ describe '#configure' do
54
+ it 'configures the window with client geo' do
55
+ expect(window).to receive(:configure).with geo
56
+ client.configure
57
+ end
58
+
59
+ it 'returns self' do
60
+ expect(client.configure).to be client
61
+ end
62
+ end
63
+
64
+ describe '#moveresize' do
65
+ it 'moveresizes the window with client geo' do
66
+ expect(window).to receive(:moveresize).with geo
67
+ client.moveresize
68
+ end
69
+
70
+ it 'returns self' do
71
+ expect(client.moveresize).to be client
72
+ end
73
+ end
74
+
75
+ describe '#show' do
76
+ it 'maps the window' do
77
+ expect(window).to receive :map
78
+ client.show
79
+ end
80
+
81
+ it 'toggles the client as visible' do
82
+ expect { client.show }
83
+ .to change { client.visible? }
84
+ .from(false).to true
85
+ end
86
+
87
+ it 'returns self' do
88
+ expect(client.show).to be client
89
+ end
90
+ end
91
+
92
+ describe '#hide' do
93
+ it 'unmaps the window' do
94
+ expect(window).to receive :unmap
95
+ client.hide
96
+ end
97
+
98
+ it 'toggles the client as hidden' do
99
+ client.show
100
+ expect { client.hide }
101
+ .to change { client.hidden? }
102
+ .from(false).to true
103
+ end
104
+
105
+ it 'increments the unmap count' do
106
+ expect { client.hide }
107
+ .to change { client.unmap_count }
108
+ .from(0).to 1
109
+ end
110
+
111
+ it 'returns self' do
112
+ expect(client.hide).to be client
113
+ end
114
+ end
115
+
116
+ describe '#focus' do
117
+ it 'raises the window' do
118
+ expect(window).to receive :raise
119
+ client.focus
120
+ end
121
+
122
+ it 'focuses the window' do
123
+ expect(window).to receive :focus
124
+ client.focus
125
+ end
126
+
127
+ it 'returns self' do
128
+ expect(client.focus).to be client
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,76 @@
1
+ module Uh
2
+ module WM
3
+ RSpec.describe Dispatcher do
4
+ subject(:dispatcher) { described_class.new }
5
+
6
+ describe '#[]' do
7
+ context 'when given key for existing hook' do
8
+ before { dispatcher.hooks[:hook_key] = [:hook] }
9
+
10
+ it 'returns registered hooks for this key' do
11
+ expect(dispatcher[:hook_key]).to eq [:hook]
12
+ end
13
+ end
14
+
15
+ context 'when given multiple keys for existing hook' do
16
+ before { dispatcher.hooks[%i[hook key]] = [:hook] }
17
+
18
+ it 'returns registered hooks for this key' do
19
+ expect(dispatcher[:hook, :key]).to eq [:hook]
20
+ end
21
+ end
22
+
23
+ context 'when given key for unknown hook' do
24
+ it 'returns an empty array' do
25
+ expect(dispatcher[:unknown_hook]).to eq []
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#on' do
31
+ it 'registers given hook for given key' do
32
+ dispatcher.on(:hook_key) { :hook }
33
+ expect(dispatcher.hooks[:hook_key]).to be
34
+ end
35
+
36
+ it 'registers given hook for given multiple keys' do
37
+ dispatcher.on(:hook, :key) { :hook }
38
+ expect(dispatcher.hooks[%i[hook key]]).to be
39
+ end
40
+ end
41
+
42
+ describe '#emit' do
43
+ it 'calls hooks registered for given key' do
44
+ dispatcher.on(:hook_key) { throw :hook_code }
45
+ expect { dispatcher.emit :hook_key }.to throw_symbol :hook_code
46
+ end
47
+
48
+ it 'returns the value returned by a registered hook' do
49
+ dispatcher.on(:hook_key) { :hook_code }
50
+ expect(dispatcher.emit :hook_key).to eq :hook_code
51
+ end
52
+
53
+ context 'when no hooks are registered for given key' do
54
+ it 'does not call another hook' do
55
+ dispatcher.on(:hook_key) { throw :hook_code }
56
+ expect { dispatcher.emit :other_hook_key }.not_to throw_symbol
57
+ end
58
+ end
59
+
60
+ context 'when no hooks are registered at all' do
61
+ it 'does not raise any error' do
62
+ expect { dispatcher.emit :hook_key }.not_to raise_error
63
+ end
64
+ end
65
+
66
+ context 'when args keyword argument is given' do
67
+ it 'calls hooks with given args' do
68
+ dispatcher.on(:hook_key) { |arg1, arg2| throw arg2 }
69
+ expect { dispatcher.emit :hook_key, args: %i[arg1 arg2] }
70
+ .to throw_symbol :arg2
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,145 @@
1
+ module Uh
2
+ module WM
3
+ RSpec.describe Env do
4
+ let(:output) { StringIO.new }
5
+ let(:logger) { Logger.new(StringIO.new) }
6
+ subject(:env) { described_class.new output }
7
+
8
+ it 'has verbose mode disabled' do
9
+ expect(env).not_to be_verbose
10
+ end
11
+
12
+ it 'has debug mode disabled' do
13
+ expect(env).not_to be_debug
14
+ end
15
+
16
+ it 'has the default rc path set' do
17
+ expect(env.rc_path).to eq '~/.uhwmrc.rb'
18
+ end
19
+
20
+ it 'has no layout_class set' do
21
+ expect(env.layout_class).not_to be
22
+ end
23
+
24
+ it 'has the default modifier set' do
25
+ expect(env.modifier).to eq :mod1
26
+ end
27
+
28
+ it 'has default key binding for quit set' do
29
+ expect(env.keybinds.keys).to include [:q, :shift]
30
+ end
31
+
32
+ it 'has the blocking worker by default' do
33
+ expect(env.worker).to eq :block
34
+ end
35
+
36
+ describe '#verbose?' do
37
+ context 'when verbose mode is disabled' do
38
+ before { env.verbose = false }
39
+
40
+ it 'returns false' do
41
+ expect(env.verbose?).to be false
42
+ end
43
+ end
44
+
45
+ context 'when verbose mode is enabled' do
46
+ before { env.verbose = true }
47
+
48
+ it 'returns true' do
49
+ expect(env.verbose?).to be true
50
+ end
51
+ end
52
+ end
53
+
54
+ describe '#debug?' do
55
+ context 'when debug mode is disabled' do
56
+ before { env.debug = false }
57
+
58
+ it 'returns false' do
59
+ expect(env.debug?).to be false
60
+ end
61
+ end
62
+
63
+ context 'when debug mode is enabled' do
64
+ before { env.debug = true }
65
+
66
+ it 'returns true' do
67
+ expect(env.debug?).to be true
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#layout' do
73
+ context 'when a layout class is set' do
74
+ let(:some_layout) { Class.new }
75
+
76
+ before { env.layout_class = some_layout }
77
+
78
+ it 'returns a new instance of this layout class' do
79
+ expect(env.layout).to be_an_instance_of some_layout
80
+ end
81
+ end
82
+
83
+ context 'when a layout class is not set' do
84
+ it 'returns an instance of the default layout' do
85
+ expect(env.layout).to be_an_instance_of ::Uh::Layout
86
+ end
87
+ end
88
+ end
89
+
90
+ describe '#logger' do
91
+ it 'returns a logger' do
92
+ expect(env.logger).to be_a Logger
93
+ end
94
+
95
+ it 'has logger level warn set' do
96
+ expect(env.logger.level).to be Logger::WARN
97
+ end
98
+
99
+ context 'when verbose mode is enabled' do
100
+ before { env.verbose = true }
101
+
102
+ it 'has logger level info set' do
103
+ expect(env.logger.level).to be Logger::INFO
104
+ end
105
+ end
106
+
107
+ context 'when debug mode is enabled' do
108
+ before { env.debug = true }
109
+
110
+ it 'has logger level debug set' do
111
+ expect(env.logger.level).to be Logger::DEBUG
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#log' do
117
+ it 'logs given message at info level' do
118
+ expect(env.logger).to receive(:info).with 'some message'
119
+ env.log 'some message'
120
+ end
121
+ end
122
+
123
+ describe '#log_debug' do
124
+ it 'logs given message at debug level' do
125
+ expect(env.logger).to receive(:debug).with 'some message'
126
+ env.log_debug 'some message'
127
+ end
128
+ end
129
+
130
+ describe '#log_logger_level' do
131
+ it 'logs the logger level' do
132
+ expect(env.logger).to receive(:info).with /log.+(warn|info|debug).+level/i
133
+ env.log_logger_level
134
+ end
135
+ end
136
+
137
+ describe '#print' do
138
+ it 'prints the message to the output' do
139
+ env.print 'some message'
140
+ expect(output.string).to eq 'some message'
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,355 @@
1
+ module Uh
2
+ module WM
3
+ RSpec.describe Manager do
4
+ let(:block) { proc { } }
5
+ let(:window) { instance_spy Window, override_redirect?: false }
6
+ let(:events) { Dispatcher.new }
7
+ let(:modifier) { :mod1 }
8
+ let(:display) { Display.new }
9
+ subject(:manager) { described_class.new events, modifier, display }
10
+
11
+ it 'has a new display' do
12
+ expect(manager.display).to be_a Display
13
+ end
14
+
15
+ it 'has no clients' do
16
+ expect(manager.clients).to be_empty
17
+ end
18
+
19
+ describe '#to_io', :xvfb do
20
+ context 'when connected' do
21
+ before { manager.connect }
22
+
23
+ it 'returns an IO object wrapping the display file descriptor' do
24
+ expect(manager.to_io)
25
+ .to be_an(IO)
26
+ .and have_attributes(fileno: display.fileno)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#connect', :xvfb do
32
+ it 'opens the display' do
33
+ expect(manager.display).to receive(:open).and_call_original
34
+ manager.connect
35
+ end
36
+
37
+ it 'emits :connecting event with the display' do
38
+ events.on :connecting, &block
39
+ expect(block).to receive(:call) do |*args|
40
+ expect(args).to eq [display]
41
+ end
42
+ manager.connect
43
+ end
44
+
45
+ it 'emits :connected event with the display' do
46
+ events.on :connected, &block
47
+ expect(block).to receive(:call) do |*args|
48
+ expect(args).to eq [display]
49
+ end
50
+ manager.connect
51
+ end
52
+
53
+ it 'updates the root window mask in order to manage windows' do
54
+ manager.connect
55
+ expect(display.root.mask).to eq Events::PROPERTY_CHANGE_MASK |
56
+ Events::SUBSTRUCTURE_REDIRECT_MASK |
57
+ Events::SUBSTRUCTURE_NOTIFY_MASK |
58
+ Events::STRUCTURE_NOTIFY_MASK
59
+ end
60
+
61
+ context 'when connection fails' do
62
+ before { allow(display).to receive(:open) { fail } }
63
+
64
+ it 'does not emit :connected event' do
65
+ events.on :connected, &block
66
+ expect(block).not_to receive :call
67
+ manager.connect rescue nil
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#disconnect' do
73
+ it 'closes the display' do
74
+ expect(display).to receive :close
75
+ manager.disconnect
76
+ end
77
+
78
+ it 'emits :disconnected event' do
79
+ allow(display).to receive :close
80
+ events.on :disconnected, &block
81
+ expect(block).to receive :call
82
+ manager.disconnect
83
+ end
84
+ end
85
+
86
+ describe '#flush' do
87
+ it 'flushes the display' do
88
+ expect(display).to receive :flush
89
+ manager.flush
90
+ end
91
+ end
92
+
93
+ describe '#grab_key' do
94
+ it 'grabs given key on the display' do
95
+ expect(manager.display)
96
+ .to receive(:grab_key).with('f', KEY_MODIFIERS[modifier])
97
+ manager.grab_key :f
98
+ end
99
+
100
+ context 'when a modifier is given' do
101
+ it 'grabs the key with given modifier' do
102
+ expect(manager.display)
103
+ .to receive(:grab_key)
104
+ .with('f', KEY_MODIFIERS[modifier] | KEY_MODIFIERS[:shift])
105
+ manager.grab_key :f, :shift
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#configure' do
111
+ context 'with new window' do
112
+ it 'sends a configure event to the window with a default geo' do
113
+ expect(window)
114
+ .to receive(:configure_event).with(Geo.new(0, 0, 320, 240))
115
+ manager.configure window
116
+ end
117
+
118
+ context 'when :configure event returns a geo' do
119
+ it 'sends a configure event with geo returned by event' do
120
+ geo = Geo.new(0, 0, 42, 42)
121
+ events.on(:configure) { geo }
122
+ expect(window).to receive(:configure_event).with geo
123
+ manager.configure window
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'with known window' do
129
+ before { manager.map window }
130
+
131
+ it 'tells the client to configure' do
132
+ expect(manager.clients[0]).to receive :configure
133
+ manager.configure window
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '#map' do
139
+ it 'registers a new client wrapping the given window' do
140
+ manager.map window
141
+ expect(manager.clients[0])
142
+ .to be_a(Client)
143
+ .and have_attributes(window: window)
144
+ end
145
+
146
+ it 'registers new client only once for a given window' do
147
+ manager.map window
148
+ expect { manager.map window }.not_to change { manager.clients }
149
+ end
150
+
151
+ it 'ignores event when window has override redirect' do
152
+ allow(window).to receive(:override_redirect?) { true }
153
+ expect { manager.map window }.not_to change { manager.clients }
154
+ end
155
+
156
+ it 'emits :manage event with the registered client' do
157
+ events.on :manage, &block
158
+ expect(block).to receive :call do |client|
159
+ expect(client)
160
+ .to be_a(Client)
161
+ .and have_attributes(window: window)
162
+ end
163
+ manager.map window
164
+ end
165
+ end
166
+
167
+ describe '#unmap' do
168
+ before { manager.map window }
169
+
170
+ context 'when client unmap count is 0 or less' do
171
+ it 'preserves the client unmap count' do
172
+ client = manager.clients[0]
173
+ expect { manager.unmap window }
174
+ .not_to change { client.unmap_count }
175
+ end
176
+
177
+ it 'unregisters the client' do
178
+ expect { manager.unmap window }
179
+ .to change { manager.clients.size }.from(1).to 0
180
+ end
181
+
182
+ it 'emits :unmanage event with the client' do
183
+ events.on :unmanage, &block
184
+ expect(block).to receive(:call).with manager.clients[0]
185
+ manager.unmap window
186
+ end
187
+ end
188
+
189
+ context 'when client unmap count is strictly positive' do
190
+ before { manager.clients[0].unmap_count += 1 }
191
+
192
+ it 'does not unregister the client' do
193
+ expect { manager.unmap window }.not_to change { manager.clients }
194
+ end
195
+
196
+ it 'decrements the unmap count' do
197
+ manager.unmap window
198
+ expect(manager.clients[0].unmap_count).to eq 0
199
+ end
200
+ end
201
+
202
+ context 'with unknown window' do
203
+ let(:unknown_window) { window.dup }
204
+
205
+ it 'does not change registered clients' do
206
+ expect { manager.unmap unknown_window }
207
+ .not_to change { manager.clients }
208
+ end
209
+
210
+ it 'does not emit any event' do
211
+ expect(events).not_to receive :emit
212
+ manager.unmap unknown_window
213
+ end
214
+ end
215
+ end
216
+
217
+ describe '#destroy' do
218
+ before { manager.map window }
219
+
220
+ it 'unregisters the client' do
221
+ expect { manager.destroy window }
222
+ .to change { manager.clients.size }.from(1).to 0
223
+ end
224
+
225
+ it 'emits :unmanage event with the client' do
226
+ events.on :unmanage, &block
227
+ expect(block).to receive(:call).with manager.clients[0]
228
+ manager.destroy window
229
+ end
230
+
231
+ context 'with unknown window' do
232
+ let(:unknown_window) { window.dup }
233
+
234
+ it 'does not change registered clients' do
235
+ expect { manager.destroy unknown_window }
236
+ .not_to change { manager.clients }
237
+ end
238
+
239
+ it 'does not emit any event' do
240
+ expect(events).not_to receive :emit
241
+ manager.destroy unknown_window
242
+ end
243
+ end
244
+ end
245
+
246
+ describe '#handle_next_event' do
247
+ it 'handles the next available event on display' do
248
+ event = double 'event'
249
+ allow(display).to receive(:next_event) { event }
250
+ expect(manager).to receive(:handle).with(event).once
251
+ manager.handle_next_event
252
+ end
253
+ end
254
+
255
+ describe '#handle_pending_events' do
256
+ let(:event) { double 'event' }
257
+
258
+ context 'when an event is pending on display' do
259
+ before do
260
+ allow(display).to receive(:pending?).and_return true, false
261
+ allow(display).to receive(:next_event) { event }
262
+ end
263
+
264
+ it 'handles the event' do
265
+ expect(manager).to receive(:handle).with(event).once
266
+ manager.handle_pending_events
267
+ end
268
+ end
269
+
270
+ context 'when multiple events are pending on display' do
271
+ before do
272
+ allow(display).to receive(:pending?).and_return true, true, false
273
+ allow(display).to receive(:next_event) { event }
274
+ end
275
+
276
+ it 'handles all pending events' do
277
+ expect(manager).to receive(:handle).with(event).twice
278
+ manager.handle_pending_events
279
+ end
280
+ end
281
+ end
282
+
283
+ describe '#handle' do
284
+ let(:event) { double 'event', type: :any }
285
+
286
+ it 'emits :xevent event with the X event' do
287
+ events.on :xevent, &block
288
+ manager.handle event
289
+ end
290
+
291
+ context 'when key_press event is given' do
292
+ let(:mod_mask) { KEY_MODIFIERS[modifier] }
293
+ let(:event) do
294
+ double 'event',
295
+ type: :key_press,
296
+ key: 'f',
297
+ modifier_mask: mod_mask
298
+ end
299
+
300
+ it 'emits :key event with the corresponding key' do
301
+ events.on(:key, :f) { throw :key_press_code }
302
+ expect { manager.handle event }.to throw_symbol :key_press_code
303
+ end
304
+
305
+ context 'whith shift key modifier' do
306
+ let(:mod_mask) { KEY_MODIFIERS[modifier] | KEY_MODIFIERS[:shift] }
307
+
308
+ it 'emits :key event with the corresponding key and :shift' do
309
+ events.on(:key, :f, :shift) { throw :key_press_code }
310
+ expect { manager.handle event }.to throw_symbol :key_press_code
311
+ end
312
+ end
313
+ end
314
+
315
+ context 'when configure request event is given' do
316
+ let(:event) do
317
+ double 'event', type: :configure_request, window: :window
318
+ end
319
+
320
+ it 'configures the event window' do
321
+ expect(manager).to receive(:configure).with :window
322
+ manager.handle event
323
+ end
324
+ end
325
+
326
+ context 'when destroy_notify event is given' do
327
+ let(:event) { double 'event', type: :destroy_notify, window: :window }
328
+
329
+ it 'destroy the event window' do
330
+ expect(manager).to receive(:destroy).with :window
331
+ manager.handle event
332
+ end
333
+ end
334
+
335
+ context 'when map_request event is given' do
336
+ let(:event) { double 'event', type: :map_request, window: :window }
337
+
338
+ it 'maps the event window' do
339
+ expect(manager).to receive(:map).with :window
340
+ manager.handle event
341
+ end
342
+ end
343
+
344
+ context 'when unmap_notify event is given' do
345
+ let(:event) { double 'event', type: :unmap_notify, window: :window }
346
+
347
+ it 'unmap the event window' do
348
+ expect(manager).to receive(:unmap).with :window
349
+ manager.handle event
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end