waiter 0.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.rspec +2 -0
- data/README.md +34 -32
- data/Rakefile +10 -0
- data/app/assets/images/waiter/bg.gif +0 -0
- data/app/assets/images/waiter/selected-bg.gif +0 -0
- data/app/assets/stylesheets/waiter/menu.css.scss +129 -0
- data/app/views/waiter/_item.haml +8 -0
- data/app/views/waiter/_menu_bar.haml +3 -0
- data/app/views/waiter/_section.haml +5 -0
- data/app/views/waiter/_sub_item.haml +2 -0
- data/app/views/waiter/_submenu.haml +6 -0
- data/lib/waiter/dsl.rb +24 -0
- data/lib/waiter/menu/drawer.rb +7 -55
- data/lib/waiter/menu/item.rb +137 -0
- data/lib/waiter/menu/item_list.rb +19 -0
- data/lib/waiter/menu/section.rb +21 -0
- data/lib/waiter/menu.rb +54 -12
- data/lib/waiter/version.rb +1 -1
- data/lib/waiter.rb +12 -3
- data/spec/spec_helper.rb +89 -0
- data/spec/support/matchers/have_a_submenu.rb +34 -0
- data/spec/support/matchers/have_exactly.rb +24 -0
- data/spec/support/matchers/have_menu_items_named.rb +32 -0
- data/spec/support/matchers/have_options.rb +23 -0
- data/spec/support/shared_examples/menu_item_shared_examples.rb +67 -0
- data/spec/waiter/menu/item_list_spec.rb +38 -0
- data/spec/waiter/menu/item_spec.rb +161 -0
- data/spec/waiter/menu/section_spec.rb +21 -0
- data/spec/waiter/menu_spec.rb +298 -0
- data/waiter.gemspec +4 -0
- metadata +97 -13
- data/lib/waiter/menu/builder.rb +0 -18
@@ -0,0 +1,298 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'waiter/menu'
|
3
|
+
|
4
|
+
RSpec.describe Waiter::Menu do
|
5
|
+
describe '.serve' do
|
6
|
+
context 'basic DSL' do
|
7
|
+
context 'when explicitly specifying block params' do
|
8
|
+
subject do
|
9
|
+
Waiter::Menu.serve(:test) do |menu|
|
10
|
+
menu.first
|
11
|
+
menu.second
|
12
|
+
menu.third do |submenu|
|
13
|
+
submenu.item1
|
14
|
+
submenu.item2
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it { is_expected.to have_exactly(3).items }
|
20
|
+
it { is_expected.to have_menu_items_named(:first, :second, :third) }
|
21
|
+
it { is_expected.to have_menu_items_named(:second, :third) }
|
22
|
+
it { is_expected.to_not have_a_menu_item_named(:item1) }
|
23
|
+
|
24
|
+
its([:first]) { is_expected.to_not have_a_submenu }
|
25
|
+
its([:second]) { is_expected.to_not have_a_submenu }
|
26
|
+
its([:third]) { is_expected.to have_a_submenu.containing(2).items }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when omitting block params' do
|
30
|
+
subject do
|
31
|
+
Waiter::Menu.serve(:test) do
|
32
|
+
first
|
33
|
+
second
|
34
|
+
third do
|
35
|
+
item1
|
36
|
+
item2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it { is_expected.to have_exactly(3).items }
|
42
|
+
it { is_expected.to have_menu_items_named(:first, :second, :third) }
|
43
|
+
it { is_expected.to have_menu_items_named(:second, :third) }
|
44
|
+
it { is_expected.to_not have_a_menu_item_named(:item1) }
|
45
|
+
|
46
|
+
its([:first]) { is_expected.to_not have_a_submenu }
|
47
|
+
its([:second]) { is_expected.to_not have_a_submenu }
|
48
|
+
its([:third]) { is_expected.to have_a_submenu.containing(2).items }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'sections' do
|
53
|
+
subject do
|
54
|
+
Waiter::Menu.serve(:test) do
|
55
|
+
section do
|
56
|
+
first
|
57
|
+
second
|
58
|
+
end
|
59
|
+
|
60
|
+
section do
|
61
|
+
third
|
62
|
+
fourth
|
63
|
+
end
|
64
|
+
|
65
|
+
fifth
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it { is_expected.to have_exactly(2).sections }
|
70
|
+
it { is_expected.to have_a_menu_item_named(:fifth) }
|
71
|
+
it { is_expected.to_not have_a_menu_item_named(:fourth) }
|
72
|
+
|
73
|
+
its('sections.first') { is_expected.to have_exactly(2).items }
|
74
|
+
its('sections.first') { is_expected.to have_menu_items_named(:first, :second) }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'using methods provided in context object' do
|
78
|
+
let(:context) { double('Context Object', foo: 1, bar: 2) }
|
79
|
+
|
80
|
+
subject do
|
81
|
+
Waiter::Menu.serve(:test, context) do
|
82
|
+
first if foo == 1
|
83
|
+
second if foo == 2
|
84
|
+
|
85
|
+
third do
|
86
|
+
fourth if bar == 2
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it { is_expected.to have_exactly(2).items }
|
92
|
+
it { is_expected.to have_menu_items_named(:first, :third) }
|
93
|
+
it { is_expected.to_not have_a_menu_item_named(:second) }
|
94
|
+
|
95
|
+
its([:third]) { is_expected.to have_a_submenu.containing(1).item }
|
96
|
+
its([:third]) { is_expected.to have_a_menu_item_named(:fourth) }
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'options' do
|
100
|
+
subject do
|
101
|
+
Waiter::Menu.serve(:test, nil, foo: 1) do
|
102
|
+
first bar: 2
|
103
|
+
second(bar: 3) do
|
104
|
+
third
|
105
|
+
end
|
106
|
+
|
107
|
+
section(foo: 2) do
|
108
|
+
fourth
|
109
|
+
fifth foo: 3
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
before { allow_any_instance_of(Waiter::Menu::Section).to receive(:collect_controllers) }
|
115
|
+
before { allow_any_instance_of(Waiter::Menu::Item).to receive(:collect_controllers) }
|
116
|
+
|
117
|
+
its([:first]) { is_expected.to have_options(foo: 1, bar: 2) }
|
118
|
+
its([:second]) { is_expected.to have_options(foo: 1, bar: 3) }
|
119
|
+
its('sections.first') { is_expected.to have_options(foo: 2) }
|
120
|
+
|
121
|
+
it 'should pass options to submenus' do
|
122
|
+
expect(subject[:second][:third]).to have_options(foo: 1, bar: 3)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should pass options to sections' do
|
126
|
+
expect(subject.sections.first[:fourth]).to have_options(foo: 2)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should allow passed on options to be overriden' do
|
130
|
+
expect(subject.sections.first[:fifth]).to have_options(foo: 3)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '.new' do
|
136
|
+
let(:context) { double('Context') }
|
137
|
+
|
138
|
+
subject { described_class.new(:test, context) }
|
139
|
+
|
140
|
+
its(:context) { is_expected.to eq context }
|
141
|
+
its(:items) { is_expected.to be_empty }
|
142
|
+
its(:items) { is_expected.to be_a Waiter::Menu::ItemList }
|
143
|
+
its(:options) { is_expected.to be_empty }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#draw' do
|
147
|
+
let(:drawer) { double(Waiter::Menu::Drawer).as_null_object }
|
148
|
+
|
149
|
+
subject do
|
150
|
+
Waiter::Menu.serve(:test) do |menu|
|
151
|
+
menu.first
|
152
|
+
menu.second
|
153
|
+
menu.third do |submenu|
|
154
|
+
submenu.item1
|
155
|
+
submenu.item2
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
before do
|
161
|
+
allow(Waiter::Menu::Drawer).to receive(:new).and_return(drawer)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should create a new drawer' do
|
165
|
+
expect(Waiter::Menu::Drawer).to receive(:new).with(subject, nil)
|
166
|
+
subject.draw
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should draw the menu' do
|
170
|
+
expect(drawer).to receive(:draw)
|
171
|
+
subject.draw
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe '#add' do
|
176
|
+
subject do
|
177
|
+
m = described_class.new(:test, nil)
|
178
|
+
m.add(:foo, { controller: :path }, { do_something: true })
|
179
|
+
m[:foo]
|
180
|
+
end
|
181
|
+
|
182
|
+
before { allow_any_instance_of(Waiter::Menu::Item).to receive(:collect_controllers) }
|
183
|
+
|
184
|
+
it { is_expected.to be_a Waiter::Menu::Item }
|
185
|
+
it { is_expected.to have_options(do_something: true) }
|
186
|
+
its(:path) { is_expected.to eq(controller: '/path', action: :index) }
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#add_section' do
|
190
|
+
subject do
|
191
|
+
m = described_class.new(:test, nil)
|
192
|
+
m.add_section({ do_something: true }) do
|
193
|
+
item1
|
194
|
+
end
|
195
|
+
m.sections.last
|
196
|
+
end
|
197
|
+
|
198
|
+
before { allow_any_instance_of(Waiter::Menu::Section).to receive(:collect_controllers) }
|
199
|
+
before { allow_any_instance_of(Waiter::Menu::Item).to receive(:collect_controllers) }
|
200
|
+
|
201
|
+
it { is_expected.to be_a Waiter::Menu::Section }
|
202
|
+
it { is_expected.to have_options(do_something: true) }
|
203
|
+
|
204
|
+
it 'should not add a blank section' do
|
205
|
+
m = described_class.new(:test, nil)
|
206
|
+
m.add_section
|
207
|
+
expect(m.sections.count).to eq 0
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should not add blank nested sections' do
|
211
|
+
m = described_class.new(:test, nil)
|
212
|
+
m.add_section do
|
213
|
+
section {}
|
214
|
+
end
|
215
|
+
expect(m.sections.count).to eq 0
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#sections' do
|
220
|
+
context 'when sections are defined' do
|
221
|
+
subject do
|
222
|
+
m = described_class.new(:test, nil)
|
223
|
+
3.times { m.add_section { item1 } }
|
224
|
+
2.times { |i| m.add("item#{i}".to_sym, :path) }
|
225
|
+
m.sections
|
226
|
+
end
|
227
|
+
|
228
|
+
it { is_expected.to all(be_a(Waiter::Menu::Section)) }
|
229
|
+
its(:size) { is_expected.to eq 3 }
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when sections are not defined' do
|
233
|
+
subject do
|
234
|
+
m = described_class.new(:test, nil)
|
235
|
+
2.times { |i| m.add("item#{i}".to_sym, :path) }
|
236
|
+
m.sections
|
237
|
+
end
|
238
|
+
|
239
|
+
it { is_expected.to be_empty }
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe '#[]' do
|
244
|
+
subject { described_class.new(:test, nil) }
|
245
|
+
|
246
|
+
context 'when the menu has no items' do
|
247
|
+
its([:item1]) { is_expected.to be_nil }
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'when the menu has items' do
|
251
|
+
before { 2.times { |i| subject.add("item#{i}".to_sym, :path) } }
|
252
|
+
|
253
|
+
its([:item1]) { is_expected.to be_a Waiter::Menu::Item }
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#items' do
|
258
|
+
before { allow_any_instance_of(Waiter::Menu::Item).to receive(:translate) { |_, key| key.to_sym } }
|
259
|
+
|
260
|
+
subject do
|
261
|
+
described_class.serve(:test, nil, @options) do
|
262
|
+
foo
|
263
|
+
bar
|
264
|
+
baz
|
265
|
+
quux
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'should sort by item title' do
|
270
|
+
@options = { sort: :item_title }
|
271
|
+
expect(subject.items(true).names).to match [:bar, :baz, :foo, :quux]
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should reverse' do
|
275
|
+
@options = { reverse: true }
|
276
|
+
expect(subject.items(true).names).to match [:quux, :baz, :bar, :foo]
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'should sort and reverse at the same time' do
|
280
|
+
@options = { sort: :item_title, reverse: true }
|
281
|
+
expect(subject.items(true).names).to match [:quux, :foo, :baz, :bar]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe '#top?' do
|
286
|
+
it 'should be true for a new menu' do
|
287
|
+
expect(described_class.new(:test, nil)).to be_top
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should be false for a submenu' do
|
291
|
+
item = Waiter::Menu::Item.new(double('Parent', options: {}).as_null_object, :item1) do
|
292
|
+
item2
|
293
|
+
end
|
294
|
+
|
295
|
+
expect(item.submenu).to_not be_top
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
data/waiter.gemspec
CHANGED
@@ -18,4 +18,8 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_dependency "activesupport", "> 3.0.0"
|
21
|
+
gem.add_dependency "haml"
|
22
|
+
gem.add_development_dependency "rspec", ">= 3.1.0"
|
23
|
+
gem.add_development_dependency "rspec-its"
|
24
|
+
gem.add_development_dependency "rake"
|
21
25
|
end
|
metadata
CHANGED
@@ -1,32 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: waiter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.1
|
4
|
+
version: 2.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Daniel Vandersluis
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-09-24 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
prerelease: false
|
16
14
|
type: :runtime
|
15
|
+
prerelease: false
|
16
|
+
name: activesupport
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>'
|
21
20
|
- !ruby/object:Gem::Version
|
22
21
|
version: 3.0.0
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
23
|
requirements:
|
26
24
|
- - ! '>'
|
27
25
|
- !ruby/object:Gem::Version
|
28
26
|
version: 3.0.0
|
29
|
-
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
type: :runtime
|
29
|
+
prerelease: false
|
30
|
+
name: haml
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
type: :development
|
43
|
+
prerelease: false
|
44
|
+
name: rspec
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 3.1.0
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
name: rspec-its
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
name: rake
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
30
83
|
description: Provides an easy DSL for serving up menus
|
31
84
|
email:
|
32
85
|
- dvandersluis@selfmgmt.com
|
@@ -35,39 +88,70 @@ extensions: []
|
|
35
88
|
extra_rdoc_files: []
|
36
89
|
files:
|
37
90
|
- .gitignore
|
91
|
+
- .rspec
|
38
92
|
- Gemfile
|
39
93
|
- LICENSE.txt
|
40
94
|
- README.md
|
41
95
|
- Rakefile
|
96
|
+
- app/assets/images/waiter/bg.gif
|
97
|
+
- app/assets/images/waiter/selected-bg.gif
|
98
|
+
- app/assets/stylesheets/waiter/menu.css.scss
|
99
|
+
- app/views/waiter/_item.haml
|
100
|
+
- app/views/waiter/_menu_bar.haml
|
101
|
+
- app/views/waiter/_section.haml
|
102
|
+
- app/views/waiter/_sub_item.haml
|
103
|
+
- app/views/waiter/_submenu.haml
|
42
104
|
- lib/waiter.rb
|
105
|
+
- lib/waiter/dsl.rb
|
43
106
|
- lib/waiter/menu.rb
|
44
|
-
- lib/waiter/menu/builder.rb
|
45
107
|
- lib/waiter/menu/drawer.rb
|
108
|
+
- lib/waiter/menu/item.rb
|
109
|
+
- lib/waiter/menu/item_list.rb
|
110
|
+
- lib/waiter/menu/section.rb
|
46
111
|
- lib/waiter/version.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
- spec/support/matchers/have_a_submenu.rb
|
114
|
+
- spec/support/matchers/have_exactly.rb
|
115
|
+
- spec/support/matchers/have_menu_items_named.rb
|
116
|
+
- spec/support/matchers/have_options.rb
|
117
|
+
- spec/support/shared_examples/menu_item_shared_examples.rb
|
118
|
+
- spec/waiter/menu/item_list_spec.rb
|
119
|
+
- spec/waiter/menu/item_spec.rb
|
120
|
+
- spec/waiter/menu/section_spec.rb
|
121
|
+
- spec/waiter/menu_spec.rb
|
47
122
|
- waiter.gemspec
|
48
123
|
homepage: https://github.com/dvandersluis/waiter
|
49
124
|
licenses: []
|
125
|
+
metadata: {}
|
50
126
|
post_install_message:
|
51
127
|
rdoc_options: []
|
52
128
|
require_paths:
|
53
129
|
- lib
|
54
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
131
|
requirements:
|
57
132
|
- - ! '>='
|
58
133
|
- !ruby/object:Gem::Version
|
59
134
|
version: '0'
|
60
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
136
|
requirements:
|
63
137
|
- - ! '>='
|
64
138
|
- !ruby/object:Gem::Version
|
65
139
|
version: '0'
|
66
140
|
requirements: []
|
67
141
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.
|
142
|
+
rubygems_version: 2.1.5
|
69
143
|
signing_key:
|
70
|
-
specification_version:
|
144
|
+
specification_version: 4
|
71
145
|
summary: Quick and easy DSL for generating menus for use in Rails applications
|
72
|
-
test_files:
|
146
|
+
test_files:
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
- spec/support/matchers/have_a_submenu.rb
|
149
|
+
- spec/support/matchers/have_exactly.rb
|
150
|
+
- spec/support/matchers/have_menu_items_named.rb
|
151
|
+
- spec/support/matchers/have_options.rb
|
152
|
+
- spec/support/shared_examples/menu_item_shared_examples.rb
|
153
|
+
- spec/waiter/menu/item_list_spec.rb
|
154
|
+
- spec/waiter/menu/item_spec.rb
|
155
|
+
- spec/waiter/menu/section_spec.rb
|
156
|
+
- spec/waiter/menu_spec.rb
|
73
157
|
has_rdoc:
|
data/lib/waiter/menu/builder.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Waiter
|
2
|
-
class Menu
|
3
|
-
# Builds a menu structure from the DSL
|
4
|
-
class Builder
|
5
|
-
def initialize(menu)
|
6
|
-
@menu = menu
|
7
|
-
end
|
8
|
-
|
9
|
-
def method_missing(name, *args, &block)
|
10
|
-
@menu.add name, *args
|
11
|
-
if block_given?
|
12
|
-
@menu.submenus[name] = Menu.new(@menu.options.merge(:controller => (args.first.andand[:controller] || name)))
|
13
|
-
yield Builder.new(@menu.submenus[name])
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|