uh-layout 0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/Gemfile +5 -0
- data/Gemfile-custom.rb +7 -0
- data/Guardfile +6 -0
- data/Rakefile +5 -0
- data/lib/uh/layout.rb +161 -0
- data/lib/uh/layout/bar.rb +159 -0
- data/lib/uh/layout/column.rb +44 -0
- data/lib/uh/layout/column/arranger.rb +66 -0
- data/lib/uh/layout/container.rb +75 -0
- data/lib/uh/layout/dumper.rb +28 -0
- data/lib/uh/layout/geo_accessors.rb +10 -0
- data/lib/uh/layout/screen.rb +32 -0
- data/lib/uh/layout/tag.rb +47 -0
- data/lib/uh/layout/version.rb +5 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/factories.rb +9 -0
- data/spec/uh/layout/column/arranger_spec.rb +181 -0
- data/spec/uh/layout/column_spec.rb +66 -0
- data/spec/uh/layout/container_spec.rb +170 -0
- data/spec/uh/layout/screen_spec.rb +40 -0
- data/spec/uh/layout/tag_spec.rb +62 -0
- data/spec/uh/layout_spec.rb +414 -0
- data/uh-layout.gemspec +22 -0
- metadata +118 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
describe Container do
|
4
|
+
let(:entries) { %i[foo bar] }
|
5
|
+
subject(:container) { described_class.new entries }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
it 'assigns no entries when no arguments are given' do
|
9
|
+
expect(described_class.new).to be_empty
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#to_ary' do
|
14
|
+
it 'supports implicit conversion to array' do
|
15
|
+
expect([] + container).to eq %i[foo bar]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#current' do
|
20
|
+
context 'when container has multiple entries' do
|
21
|
+
it 'returns the first entry' do
|
22
|
+
expect(container.current).to be :foo
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when container has no entry' do
|
27
|
+
subject(:container) { described_class.new }
|
28
|
+
|
29
|
+
it 'returns nil' do
|
30
|
+
expect(container.current).to be nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#current=' do
|
36
|
+
context 'when given argument is an entry' do
|
37
|
+
before { container.current = :bar }
|
38
|
+
|
39
|
+
it 'assigns given entry as the current one' do
|
40
|
+
expect(container.current).to be :bar
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when given argument is not an entry' do
|
45
|
+
it 'does not change current entry' do
|
46
|
+
expect { container.current = :baz }
|
47
|
+
.not_to change { container.current }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#<<' do
|
53
|
+
it 'adds given entry' do
|
54
|
+
container << :baz
|
55
|
+
expect(container).to include :baz
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#remove' do
|
60
|
+
let(:entries) { %i[foo bar baz] }
|
61
|
+
|
62
|
+
before { container.current = :bar }
|
63
|
+
|
64
|
+
it 'removes given argument from entries' do
|
65
|
+
container.remove :foo
|
66
|
+
expect(container).not_to include :foo
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'preserves the current entry' do
|
70
|
+
container.remove :foo
|
71
|
+
expect(container.current).to be :bar
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns self' do
|
75
|
+
expect(container.remove :foo).to be container
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'raises an ArgumentError when given entry is not included' do
|
79
|
+
expect { container.remove :unknown_entry }.to raise_error ArgumentError
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when the first and current entry is removed' do
|
83
|
+
before do
|
84
|
+
container.current = :foo
|
85
|
+
container.remove :foo
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'assigns next entry as the current one' do
|
89
|
+
expect(container.current).to be :bar
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when given entry is the only one' do
|
94
|
+
let(:entries) { [:foo] }
|
95
|
+
|
96
|
+
it 'has no more current entry' do
|
97
|
+
container.remove :foo
|
98
|
+
expect(container.current).to be nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#remove_if' do
|
104
|
+
it 'removes entries for which given block returns true' do
|
105
|
+
container.remove_if { |e| e == :foo }
|
106
|
+
expect(container).not_to include :foo
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#get' do
|
111
|
+
it 'returns consecutive entry in given direction' do
|
112
|
+
expect(container.get :succ).to be :bar
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'returns nil when no consecutive entry exists' do
|
116
|
+
expect(container.get :pred).to be nil
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'with cycle option' do
|
120
|
+
it 'returns consecutive entry, cycling before first one' do
|
121
|
+
expect(container.get :pred, cycle: true).to be :bar
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'returns consecutive entry, cycling after last one' do
|
125
|
+
container.current = :bar
|
126
|
+
expect(container.get :succ, cycle: true).to be :foo
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#sel' do
|
132
|
+
it 'sets consecutive entry in given direction as the current one' do
|
133
|
+
container.sel :next
|
134
|
+
expect(container.current).to be :bar
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '#set' do
|
139
|
+
let(:entries) { %i[foo bar baz] }
|
140
|
+
|
141
|
+
it 'swaps current entry with consecutive one in given direction' do
|
142
|
+
container.set :next
|
143
|
+
expect(container.to_a).to eq %i[bar foo baz]
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'does not change current entry' do
|
147
|
+
expect { container.set :next }.not_to change { container.current }
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when direction is out of range' do
|
151
|
+
it 'rotates the entries' do
|
152
|
+
container.set :pred
|
153
|
+
expect(container.to_a).to eq %i[bar baz foo]
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'does not change current entry' do
|
157
|
+
expect { container.set :pred }.not_to change { container.current }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#swap' do
|
163
|
+
it 'swaps entries matched by given indexes' do
|
164
|
+
container.swap 0, 1
|
165
|
+
expect(container.to_a).to eq %i[bar foo]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
describe Screen do
|
4
|
+
let(:geo) { build_geo }
|
5
|
+
let(:other_geo) { build_geo 640, 0, 320, 240 }
|
6
|
+
let(:client) { build_client }
|
7
|
+
subject(:screen) { described_class.new(0, geo) }
|
8
|
+
|
9
|
+
it 'has one default tag with id 1 assigned' do
|
10
|
+
expect(screen.tags).to include an_object_having_attributes id: '1'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has one default tag with screen geo copy assigned' do
|
14
|
+
expect(screen.tags.first.geo).to eq(screen.geo).and not_be screen.geo
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#height=' do
|
18
|
+
it 'changes screen height' do
|
19
|
+
expect { screen.height = 42 }.to change { screen.height }.to 42
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'changes tags height' do
|
23
|
+
expect { screen.height = 42 }
|
24
|
+
.to change { screen.tags.first.height }.to 42
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#include?' do
|
29
|
+
it 'returns false when screen does not include given client' do
|
30
|
+
expect(screen.include? client).to be false
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns true when screen includes given client' do
|
34
|
+
screen.current_tag.current_column_or_create << client
|
35
|
+
expect(screen.include? client).to be true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
describe Tag do
|
4
|
+
let(:geo) { build_geo }
|
5
|
+
let(:other_geo) { build_geo 640, 0, 320, 240 }
|
6
|
+
let(:client) { build_client }
|
7
|
+
let(:other_client) { build_client }
|
8
|
+
let(:column) { Column.new(geo) }
|
9
|
+
subject(:tag) { described_class.new('1', geo) }
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
it 'raises error unless id converts to string' do
|
13
|
+
expect { described_class.new(1, geo) }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#clients' do
|
18
|
+
it 'returns all clients contained in assigned columns' do
|
19
|
+
tag.columns << column.tap { |column| column << client << other_client }
|
20
|
+
expect(tag.clients).to eq [client, other_client]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#include?' do
|
25
|
+
it 'returns false when tag does not include given client' do
|
26
|
+
expect(tag.include? client).to be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns true when tag includes given client' do
|
30
|
+
tag.columns << column.tap { |column| column << client }
|
31
|
+
expect(tag.include? client).to be true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#current_column_or_create' do
|
36
|
+
context 'when tag has no column' do
|
37
|
+
it 'creates a new column' do
|
38
|
+
expect { tag.current_column_or_create }
|
39
|
+
.to change { tag.columns.size }.from(0).to(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the new column' do
|
43
|
+
expect(tag.current_column_or_create).to eq tag.columns.current
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when tag has a column' do
|
48
|
+
before { tag.columns << column }
|
49
|
+
|
50
|
+
it 'does not create any column' do
|
51
|
+
expect { tag.current_column_or_create }
|
52
|
+
.not_to change { tag.columns.size }
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns the current column' do
|
56
|
+
expect(tag.current_column_or_create).to be column
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,414 @@
|
|
1
|
+
module Uh
|
2
|
+
describe Layout do
|
3
|
+
let(:geo) { build_geo }
|
4
|
+
let(:client) { build_client }
|
5
|
+
let(:other_client) { build_client }
|
6
|
+
let(:widget) { double('widget').as_null_object }
|
7
|
+
subject(:layout) { described_class.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
layout.screens << Layout::Screen.new(0, geo)
|
11
|
+
layout.screens << Layout::Screen.new(1, geo)
|
12
|
+
layout.widgets << widget
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#include?' do
|
16
|
+
it 'returns false when layout does not include given client' do
|
17
|
+
expect(layout.include? client).to be false
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns true when layout includes given client' do
|
21
|
+
layout << client
|
22
|
+
expect(layout.include? client).to be true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#arranger_for_current_tag' do
|
27
|
+
it 'returns an arranger for current tag columns and geo' do
|
28
|
+
expect(layout.arranger_for_current_tag)
|
29
|
+
.to respond_to(:update_geos)
|
30
|
+
.and have_attributes(
|
31
|
+
columns: layout.current_tag.columns,
|
32
|
+
geo: layout.current_tag.geo
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#update_widgets' do
|
38
|
+
it 'updates widgets' do
|
39
|
+
expect(layout.widgets).to all receive :update
|
40
|
+
layout.update_widgets
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'redraws widgets' do
|
44
|
+
expect(layout.widgets).to all receive :redraw
|
45
|
+
layout.update_widgets
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#suggest_geo' do
|
50
|
+
it 'returns current tag geo copy' do
|
51
|
+
expect(layout.suggest_geo)
|
52
|
+
.to eq(layout.current_tag.geo)
|
53
|
+
.and not_be layout.current_tag.geo
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when current tag has a column' do
|
57
|
+
before { layout.current_tag.columns << Layout::Column.new(build_geo 42) }
|
58
|
+
|
59
|
+
it 'returns current column geo' do
|
60
|
+
expect(layout.suggest_geo)
|
61
|
+
.to eq(layout.current_column.geo)
|
62
|
+
.and not_be layout.current_column.geo
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#<<' do
|
68
|
+
before { layout << other_client }
|
69
|
+
|
70
|
+
it 'adds given client to current column' do
|
71
|
+
layout << client
|
72
|
+
expect(layout.current_column).to include client
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'sets given client as the current one in current column' do
|
76
|
+
layout << client
|
77
|
+
expect(layout.current_column.current_client).to be client
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'arranges current column clients' do
|
81
|
+
expect(layout.current_column).to receive :arrange_clients
|
82
|
+
layout << client
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'shows and hides clients in current column' do
|
86
|
+
expect(layout.current_column).to receive :show_hide_clients
|
87
|
+
layout << client
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'focuses given client' do
|
91
|
+
expect(client).to receive :focus
|
92
|
+
layout << client
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'updates widgets' do
|
96
|
+
expect(widget).to receive :update
|
97
|
+
layout << client
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns self' do
|
101
|
+
expect(layout << client).to be layout
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#remove' do
|
106
|
+
before { layout << client << other_client }
|
107
|
+
|
108
|
+
it 'removes given client from the layout' do
|
109
|
+
layout.remove client
|
110
|
+
expect(layout).not_to include client
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'redraws columns with an arranger' do
|
114
|
+
expect_any_instance_of(Layout::Column::Arranger).to receive :redraw
|
115
|
+
layout.remove client
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'arranges clients in removed client tag columns' do
|
119
|
+
expect(layout.current_tag.columns).to all receive :arrange_clients
|
120
|
+
layout.remove client
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'shows and hides clients in removed client column' do
|
124
|
+
expect(layout.current_column).to receive :show_hide_clients
|
125
|
+
layout.remove client
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'focuses the new current client' do
|
129
|
+
expect(other_client).to receive :focus
|
130
|
+
layout.remove client
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'updates widgets' do
|
134
|
+
expect(widget).to receive :update
|
135
|
+
layout.remove client
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe 'handle_screen_sel' do
|
140
|
+
it 'selects consecutive screen in given direction' do
|
141
|
+
expect { layout.handle_screen_sel :succ }
|
142
|
+
.to change { layout.current_screen.id }.from(0).to(1)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'focus selected screen current client' do
|
146
|
+
layout << client
|
147
|
+
expect(client).to receive :focus
|
148
|
+
2.times { layout.handle_screen_sel :succ }
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'updates widgets' do
|
152
|
+
expect(widget).to receive :update
|
153
|
+
layout.handle_screen_sel :succ
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'handle_screen_set' do
|
158
|
+
before { layout << client }
|
159
|
+
|
160
|
+
it 'removes current client from origin screen' do
|
161
|
+
layout.handle_screen_set :succ
|
162
|
+
expect(layout.screens[0].tags.flat_map(&:clients)).not_to include client
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'adds current client to consecutive screen in given direction' do
|
166
|
+
layout.handle_screen_set :succ
|
167
|
+
expect(layout.screens[1].tags.flat_map(&:clients)).to include client
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'selects consecutive screen in given direction' do
|
171
|
+
expect { layout.handle_screen_set :succ }
|
172
|
+
.to change { layout.current_screen.id }.from(0).to(1)
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'without client' do
|
176
|
+
before { layout.remove client }
|
177
|
+
|
178
|
+
it 'does not raise any error' do
|
179
|
+
expect { layout.handle_screen_set :succ }.not_to raise_error
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'handle_tag_sel' do
|
185
|
+
before { layout << client }
|
186
|
+
|
187
|
+
it 'hides clients on previously selected tag' do
|
188
|
+
layout.handle_tag_sel '2'
|
189
|
+
expect(client).to be_hidden
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'sets the selected tag as the current one' do
|
193
|
+
layout.handle_tag_sel '2'
|
194
|
+
expect(layout.current_tag.id).to eq '2'
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'shows and hides clients in selected tag columns' do
|
198
|
+
layout.handle_tag_sel '2'
|
199
|
+
expect(layout.current_screen.tags[0].columns)
|
200
|
+
.to all receive :show_hide_clients
|
201
|
+
layout.handle_tag_sel '1'
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'focuses selected tag current client' do
|
205
|
+
layout.handle_tag_sel '2'
|
206
|
+
expect(client).to receive :focus
|
207
|
+
layout.handle_tag_sel '1'
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'updates widgets' do
|
211
|
+
expect(widget).to receive :update
|
212
|
+
layout.handle_tag_sel '2'
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe 'handle_tag_set' do
|
217
|
+
context 'without client' do
|
218
|
+
it 'does not raise any error' do
|
219
|
+
expect { layout.handle_tag_set '2' }.not_to raise_error
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'with a client' do
|
224
|
+
before { layout << other_client << client }
|
225
|
+
|
226
|
+
it 'removes current client from origin tag' do
|
227
|
+
origin_tag = layout.current_tag
|
228
|
+
layout.handle_tag_set '2'
|
229
|
+
expect(origin_tag).not_to include client
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'shows and hides clients in current column' do
|
233
|
+
expect(layout.current_column).to receive :show_hide_clients
|
234
|
+
layout.handle_tag_set '2'
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'hides current client' do
|
238
|
+
expect(client).to receive :hide
|
239
|
+
layout.handle_tag_set '2'
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'adds current client to given tag' do
|
243
|
+
layout.handle_tag_set '2'
|
244
|
+
dest_tag = layout.current_screen.tags.find { |e| e.id == '2' }
|
245
|
+
expect(dest_tag).to include client
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'arranges clients in given tag columns' do
|
249
|
+
layout.current_screen.tags << tag = Layout::Tag.new('2', geo)
|
250
|
+
expect(tag.current_column_or_create).to receive :arrange_clients
|
251
|
+
layout.handle_tag_set '2'
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'updates widgets' do
|
255
|
+
expect(widget).to receive :update
|
256
|
+
layout.handle_tag_set '2'
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe '#handle_column_sel' do
|
262
|
+
context 'without client' do
|
263
|
+
it 'does not raise any error' do
|
264
|
+
expect { layout.handle_column_sel :succ }.not_to raise_error
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'with two clients in two columns' do
|
269
|
+
before do
|
270
|
+
layout << client
|
271
|
+
layout.current_tag.columns << Layout::Column.new(geo).tap do |o|
|
272
|
+
o << other_client
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'selects the column consecutive to current one in given direction' do
|
277
|
+
layout.handle_column_sel :succ
|
278
|
+
expect(layout.current_column).to be layout.current_tag.columns[1]
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'focuses the current client of selected column' do
|
282
|
+
expect(other_client).to receive :focus
|
283
|
+
layout.handle_column_sel :succ
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'updates widgets' do
|
287
|
+
expect(widget).to receive :update
|
288
|
+
layout.handle_column_sel :succ
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe '#handle_client_sel' do
|
294
|
+
context 'without client' do
|
295
|
+
it 'does not raise any error' do
|
296
|
+
expect { layout.handle_client_sel :succ }.not_to raise_error
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'with one column and two clients' do
|
301
|
+
before { layout << client << other_client }
|
302
|
+
|
303
|
+
it 'selects current column consecutive client in given direction' do
|
304
|
+
expect { layout.handle_client_sel :pred }
|
305
|
+
.to change { layout.current_client }.from(other_client).to(client)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'focuses current client' do
|
309
|
+
expect(client).to receive :focus
|
310
|
+
layout.handle_client_sel :pred
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'updates column clients visibility' do
|
314
|
+
expect(layout.current_column).to receive :show_hide_clients
|
315
|
+
layout.handle_client_sel :pred
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'updates widgets' do
|
319
|
+
expect(widget).to receive :update
|
320
|
+
layout.handle_client_sel :pred
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
describe '#handle_client_swap' do
|
326
|
+
context 'without client' do
|
327
|
+
it 'does not raise any error' do
|
328
|
+
expect { layout.handle_client_swap :pred }.not_to raise_error
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
context 'with one column and two clients' do
|
333
|
+
before { layout << other_client << client }
|
334
|
+
|
335
|
+
it 'swaps current client with the other client' do
|
336
|
+
layout.handle_client_swap :pred
|
337
|
+
expect(layout.current_column.clients.to_a)
|
338
|
+
.to eq [client, other_client]
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'does not change current client' do
|
342
|
+
expect { layout.handle_client_swap :pred }
|
343
|
+
.not_to change { layout.current_client }
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'updates widgets' do
|
347
|
+
expect(widget).to receive :update
|
348
|
+
layout.handle_client_swap :pred
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe '#handle_client_column_set' do
|
354
|
+
context 'without client' do
|
355
|
+
it 'does not raise any error' do
|
356
|
+
expect { layout.handle_client_column_set :succ }.not_to raise_error
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'with one column and two clients' do
|
361
|
+
let(:arranger) { instance_spy Layout::Column::Arranger }
|
362
|
+
|
363
|
+
before { layout << other_client << client }
|
364
|
+
|
365
|
+
it 'moves current client with column arranger' do
|
366
|
+
expect(arranger).to receive(:move_current_client).with(:succ)
|
367
|
+
layout.handle_client_column_set :succ, arranger: arranger
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'updates columns geos with column arranger' do
|
371
|
+
expect(arranger).to receive :update_geos
|
372
|
+
layout.handle_client_column_set :succ, arranger: arranger
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'arranges clients in current tag columns' do
|
376
|
+
expect(layout.current_tag.columns).to all receive :arrange_clients
|
377
|
+
layout.handle_client_column_set :succ
|
378
|
+
end
|
379
|
+
|
380
|
+
it 'shows and hides clients in selected tag columns' do
|
381
|
+
expect(layout.current_tag.columns).to all receive :show_hide_clients
|
382
|
+
layout.handle_client_column_set :succ
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'does not change current client' do
|
386
|
+
expect { layout.handle_client_column_set :succ }
|
387
|
+
.not_to change { layout.current_client }
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'updates widgets' do
|
391
|
+
expect(widget).to receive :update
|
392
|
+
layout.handle_client_column_set :succ
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
describe '#handle_kill_current' do
|
398
|
+
context 'without client' do
|
399
|
+
it 'does not raise any error' do
|
400
|
+
expect { layout.handle_kill_current }.not_to raise_error
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
context 'with a client' do
|
405
|
+
before { layout << client }
|
406
|
+
|
407
|
+
it 'kills current client' do
|
408
|
+
expect(client).to receive :kill
|
409
|
+
layout.handle_kill_current
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|