mongoid_acts_as_list 0.0.3
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.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.vimrc.local +2 -0
- data/Gemfile +3 -0
- data/README.markdown +134 -0
- data/Rakefile +1 -0
- data/acts_as_list.gemspec +27 -0
- data/lib/mongoid/acts_as_list/configuration.rb +12 -0
- data/lib/mongoid/acts_as_list/list/embedded.rb +47 -0
- data/lib/mongoid/acts_as_list/list/root.rb +38 -0
- data/lib/mongoid/acts_as_list/list.rb +295 -0
- data/lib/mongoid/acts_as_list/version.rb +5 -0
- data/lib/mongoid_acts_as_list.rb +21 -0
- data/spec/acts_as_list/embeds_many_spec.rb +47 -0
- data/spec/acts_as_list/relational_spec.rb +62 -0
- data/spec/fixtures/embeds_many_models.rb +15 -0
- data/spec/fixtures/relational_models.rb +13 -0
- data/spec/mongoid_acts_as_list_spec.rb +7 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/list_examples.rb +523 -0
- metadata +121 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::ActsAsList::List do
|
4
|
+
[:position, :number].each do |default_field_name|
|
5
|
+
let(:position_field) { default_field_name }
|
6
|
+
|
7
|
+
before do
|
8
|
+
Mongoid::ActsAsList.configure do |config|
|
9
|
+
config.default_position_field = position_field
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'fixtures/relational_models'
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe Mongoid::ActsAsList::List::Root do
|
17
|
+
let(:category_1) { Category.create! }
|
18
|
+
let(:category_2) { Category.create! }
|
19
|
+
let(:category_3) { Category.create! }
|
20
|
+
|
21
|
+
before do
|
22
|
+
[category_1, category_2].each do |cat|
|
23
|
+
3.times do |n|
|
24
|
+
cat.items.create! position_field => n
|
25
|
+
end
|
26
|
+
cat.should have(3).items
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it_behaves_like 'a list'
|
31
|
+
|
32
|
+
describe ".acts_as_list" do
|
33
|
+
it "defines #scope_condition" do
|
34
|
+
item = category_1.items.first
|
35
|
+
item.scope_condition.should == {:category_id => category_1.id}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises a NoScope error if called without a scope option" do
|
39
|
+
lambda do
|
40
|
+
RootItem.acts_as_list(scope: nil)
|
41
|
+
end.should raise_exception Mongoid::ActsAsList::List::ScopeMissingError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".order_by_position" do
|
46
|
+
it "works with a condition" do
|
47
|
+
RootItem.order_by_position(:category_id => category_2.id).map(&position_field).should == [0,1,2]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "Insert a new item to the list" do
|
52
|
+
it "scopes list to the relation" do
|
53
|
+
item_1 = category_1.items.create!
|
54
|
+
item_2 = category_2.items.create!
|
55
|
+
|
56
|
+
item_1[position_field].should == item_2[position_field]
|
57
|
+
item_2[position_field].should == 3
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Category
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
4
|
+
|
5
|
+
embeds_many :items, class_name: 'EmbeddedItem'
|
6
|
+
end
|
7
|
+
|
8
|
+
class EmbeddedItem
|
9
|
+
include Mongoid::Document
|
10
|
+
include Mongoid::Timestamps
|
11
|
+
include Mongoid::ActsAsList
|
12
|
+
|
13
|
+
embedded_in :category
|
14
|
+
acts_as_list
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Category
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
4
|
+
has_many :items, class_name: 'RootItem'
|
5
|
+
end
|
6
|
+
|
7
|
+
class RootItem
|
8
|
+
include Mongoid::Document
|
9
|
+
include Mongoid::Timestamps
|
10
|
+
include Mongoid::ActsAsList
|
11
|
+
belongs_to :category
|
12
|
+
acts_as_list :scope => :category
|
13
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rspec/autorun'
|
3
|
+
require 'database_cleaner'
|
4
|
+
require 'database_cleaner/mongoid/truncation'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each do |f|
|
8
|
+
require f
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'mongoid'
|
12
|
+
require_relative '../lib/mongoid_acts_as_list'
|
13
|
+
|
14
|
+
Mongoid.configure do |config|
|
15
|
+
config.master = Mongo::Connection.new.db('acts_as_list_test')
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.filter_run focus: true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
22
|
+
|
23
|
+
config.before(:suite) do
|
24
|
+
DatabaseCleaner['mongoid'].strategy = :truncation
|
25
|
+
end
|
26
|
+
|
27
|
+
config.before(:each) do
|
28
|
+
DatabaseCleaner.start
|
29
|
+
end
|
30
|
+
|
31
|
+
config.after(:each) do
|
32
|
+
DatabaseCleaner.clean
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,523 @@
|
|
1
|
+
shared_examples_for "a list" do
|
2
|
+
describe ".acts_as_list" do
|
3
|
+
it "defines #position_field && .position_field" do
|
4
|
+
item = category_1.items.first
|
5
|
+
item.position_field.should == position_field
|
6
|
+
item.class.position_field.should == position_field
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".order_by_position" do
|
11
|
+
it "works without conditions" do
|
12
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "sorts by created_at if positions are equal" do
|
16
|
+
deuce = category_1.items.create! position_field => 1
|
17
|
+
items = category_1.items.order_by_position
|
18
|
+
items.map(&position_field).should == [0,1,1,2]
|
19
|
+
items[2].should == deuce
|
20
|
+
end
|
21
|
+
|
22
|
+
it "sorts in descending order if specified" do
|
23
|
+
deuce = category_1.items.create! position_field => 2, :created_at => Date.yesterday
|
24
|
+
items = category_1.items.order_by_position(:desc)
|
25
|
+
items.map(&position_field).should == [2,2,1,0]
|
26
|
+
items[1].should == deuce
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "Insert a new item to the list" do
|
31
|
+
it "inserts at the next available position for a given category" do
|
32
|
+
item = category_1.items.create!
|
33
|
+
item[position_field].should == 3
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "Removing items" do
|
38
|
+
before do
|
39
|
+
3.times do
|
40
|
+
category_1.items.create!
|
41
|
+
end
|
42
|
+
category_1.reload.items.map(&position_field).should == [0,1,2,3,4,5]
|
43
|
+
end
|
44
|
+
|
45
|
+
describe " #destroy" do
|
46
|
+
it "reorders the positions in the list" do
|
47
|
+
item = category_1.items.where(position_field => 3).first
|
48
|
+
item.destroy
|
49
|
+
|
50
|
+
items = item.embedded? ? category_1.items : category_1.reload.items
|
51
|
+
items.map(&position_field).should == [0,1,2,3,4]
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
it "does not shift positions if the element was already removed from the list" do
|
56
|
+
item = category_1.items.where(position_field => 2).first
|
57
|
+
item.remove_from_list
|
58
|
+
item.destroy
|
59
|
+
category_1.reload.items.map(&position_field).should == [0,1,2,3,4]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe " #remove_from_list" do
|
64
|
+
it "sets position to nil" do
|
65
|
+
item = category_1.items.where(position_field => 2).first
|
66
|
+
item.remove_from_list
|
67
|
+
item[position_field].should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "is not in list anymore" do
|
71
|
+
item = category_1.items.where(position_field => 3).first
|
72
|
+
item.remove_from_list
|
73
|
+
item.should_not be_in_list
|
74
|
+
end
|
75
|
+
|
76
|
+
it "reorders the positions in the list" do
|
77
|
+
category_1.items.where(position_field => 0).first.remove_from_list
|
78
|
+
category_1.reload.items.map(&position_field).compact.should == [0,1,2,3,4]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#first?" do
|
84
|
+
it "returns true if item is the first of the list" do
|
85
|
+
category_1.items.order_by_position.first.should be_first
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns false if item is not the first of the list" do
|
89
|
+
all_but_first = category_1.items.order_by_position.to_a[1..-1]
|
90
|
+
all_but_first.map(&:first?).uniq.should == [false]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#last?" do
|
95
|
+
it "returns true if item is the last of the list" do
|
96
|
+
category_1.items.order_by_position.last.should be_last
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns false if item is not the last of the list" do
|
100
|
+
all_but_last = category_1.items.order_by_position.to_a[0..-2]
|
101
|
+
all_but_last.map(&:last?).uniq.should == [false]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
%w[higher_item next_item].each do |method_name|
|
106
|
+
describe "##{method_name}" do
|
107
|
+
it "returns the next item in the list if there is one" do
|
108
|
+
item = category_1.items.where(position_field => 1).first
|
109
|
+
next_item = category_1.items.where(position_field => 2).first
|
110
|
+
item.send(method_name).should == next_item
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns nil if the item is already the last" do
|
114
|
+
item = category_1.items.order_by_position.last
|
115
|
+
item.send(method_name).should be_nil
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns nil if the item is not in the list" do
|
119
|
+
item = category_1.items.order_by_position.first
|
120
|
+
item.remove_from_list
|
121
|
+
item.send(method_name).should be_nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
%w[lower_item previous_item].each do |method_name|
|
127
|
+
describe "##{method_name}" do
|
128
|
+
it "returns the previous item in the list if there is one" do
|
129
|
+
item = category_1.items.where(position_field => 1).first
|
130
|
+
previous_item = category_1.items.where(position_field => 0).first
|
131
|
+
item.send(method_name).should == previous_item
|
132
|
+
end
|
133
|
+
|
134
|
+
it "returns nil if the item is already the first" do
|
135
|
+
item = category_1.items.order_by_position.first
|
136
|
+
item.send(method_name).should be_nil
|
137
|
+
end
|
138
|
+
|
139
|
+
it "returns nil if the item is not in the list" do
|
140
|
+
item = category_1.items.order_by_position.last
|
141
|
+
item.remove_from_list
|
142
|
+
item.send(method_name).should be_nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#insert_at" do
|
148
|
+
context "to a lower position" do
|
149
|
+
let(:item) { category_1.items.order_by_position.last }
|
150
|
+
|
151
|
+
it "changes the item's position" do
|
152
|
+
item.insert_at 1
|
153
|
+
item[position_field].should == 1
|
154
|
+
end
|
155
|
+
|
156
|
+
it "shuffles intermediary positions" do
|
157
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
158
|
+
positions.should == [0,1,2]
|
159
|
+
item.insert_at 1
|
160
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
161
|
+
positions.should == [0,1,2]
|
162
|
+
end
|
163
|
+
|
164
|
+
it "works for items that don't have a position yet" do
|
165
|
+
item.remove_from_list
|
166
|
+
item.insert_at 1
|
167
|
+
item[position_field].should == 1
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "to a higher position" do
|
172
|
+
let(:item) { category_1.items.order_by_position.first }
|
173
|
+
|
174
|
+
it "changes the item's position" do
|
175
|
+
item.insert_at 2
|
176
|
+
item[position_field].should == 2
|
177
|
+
end
|
178
|
+
|
179
|
+
it "shuffles intermediary positions" do
|
180
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
181
|
+
positions.should == [0,1,2]
|
182
|
+
item.insert_at 2
|
183
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
184
|
+
positions.should == [0,1,2]
|
185
|
+
end
|
186
|
+
|
187
|
+
it "works for items that don't have a position yet" do
|
188
|
+
item.remove_from_list
|
189
|
+
item.insert_at 2
|
190
|
+
item[position_field].should == 2
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "to the same position" do
|
195
|
+
it "does nothing" do
|
196
|
+
item = category_1.items.first
|
197
|
+
lambda do
|
198
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
199
|
+
positions.should == [0,1,2]
|
200
|
+
item.insert_at item[position_field]
|
201
|
+
positions = category_1.items.order_by_position.map(&position_field)
|
202
|
+
positions.should == [0,1,2]
|
203
|
+
end.should_not change(item, position_field)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "to extreme positions" do
|
208
|
+
it "like 0" do
|
209
|
+
item = category_1.items.order_by_position.last
|
210
|
+
|
211
|
+
item.remove_from_list
|
212
|
+
item.insert_at 0
|
213
|
+
|
214
|
+
item[position_field].should == 0
|
215
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
216
|
+
end
|
217
|
+
it "like the last position" do
|
218
|
+
item = category_1.items.order_by_position.first
|
219
|
+
|
220
|
+
item.remove_from_list
|
221
|
+
item.insert_at 1
|
222
|
+
|
223
|
+
item[position_field].should == 1
|
224
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
225
|
+
end
|
226
|
+
it "like the next available position" do
|
227
|
+
item = category_1.items.order_by_position.first
|
228
|
+
|
229
|
+
item.remove_from_list
|
230
|
+
item.insert_at 2
|
231
|
+
|
232
|
+
item[position_field].should == 2
|
233
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe " #move" do
|
239
|
+
context ":to =>" do
|
240
|
+
context "an Integer" do
|
241
|
+
it "inserts at a given position" do
|
242
|
+
item = category_1.items.order_by_position.first
|
243
|
+
item.should_receive(:insert_at).with 2
|
244
|
+
item.move to: 2
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "a Symbol" do
|
249
|
+
[:start, :top, :end, :bottom].each do |destination|
|
250
|
+
it "moves to #{destination}" do
|
251
|
+
item = category_1.items.first
|
252
|
+
item.should_receive("move_to_#{destination}")
|
253
|
+
item.move to: destination
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
[:before, :above, :after, :below, :forward, :backward, :lower, :higher].each do |sym|
|
260
|
+
context "#{sym} =>" do
|
261
|
+
it "delegates to the right method" do
|
262
|
+
item = category_1.items.first
|
263
|
+
other_item = category_1.items.last
|
264
|
+
item.should_receive("move_#{sym}").with(other_item)
|
265
|
+
item.move(sym => other_item)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
[:backwards, :higher].each do |sym|
|
271
|
+
context "#{sym}" do
|
272
|
+
it "delegates to the right method" do
|
273
|
+
item = category_1.items.last
|
274
|
+
item.should_receive("move_#{sym}").with()
|
275
|
+
item.move sym
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
[:top, :start].each do |sym|
|
282
|
+
describe "#move_to_#{sym}" do
|
283
|
+
it "#{sym} moves an item in list to the start of list" do
|
284
|
+
item = category_1.items.order_by_position.last
|
285
|
+
item.move to: sym
|
286
|
+
item[position_field].should == 0
|
287
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
288
|
+
end
|
289
|
+
|
290
|
+
it "#{sym} moves an item not in list to the start of list" do
|
291
|
+
item = category_1.items.order_by_position.last
|
292
|
+
item.remove_from_list
|
293
|
+
item.move to: sym
|
294
|
+
item[position_field].should == 0
|
295
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
[:end, :bottom].each do |sym|
|
301
|
+
describe "#move_to_#{sym}" do
|
302
|
+
it "#{sym} moves an item in list to the end of list" do
|
303
|
+
item = category_1.items.order_by_position.first
|
304
|
+
item.move to: sym
|
305
|
+
item[position_field].should == 2
|
306
|
+
category_1.reload.items.order_by_position.map(&position_field).should == [0,1,2]
|
307
|
+
end
|
308
|
+
|
309
|
+
it "#{sym} moves an item not in list to the end of list" do
|
310
|
+
item = category_1.items.order_by_position.first
|
311
|
+
item.remove_from_list
|
312
|
+
item.move to: sym
|
313
|
+
item[position_field].should == 2
|
314
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
[:forwards, :lower].each do |sym|
|
320
|
+
describe " #move_#{sym}" do
|
321
|
+
let(:method) { "move_#{sym}" }
|
322
|
+
|
323
|
+
context "for the last item of the list" do
|
324
|
+
let(:item) { category_1.items.order_by_position.last }
|
325
|
+
|
326
|
+
it "does not change the item's position" do
|
327
|
+
lambda do
|
328
|
+
item.send method
|
329
|
+
end.should_not change(item, position_field)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "keeps items ordered" do
|
333
|
+
item.send method
|
334
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
335
|
+
end
|
336
|
+
|
337
|
+
it "returns false" do
|
338
|
+
item.send(method).should be_false
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
context "for any other item" do
|
343
|
+
let(:item) { category_1.items.order_by_position.first }
|
344
|
+
|
345
|
+
it "moves to the next position" do
|
346
|
+
lambda do
|
347
|
+
item.send method
|
348
|
+
end.should change(item, position_field).by(1)
|
349
|
+
end
|
350
|
+
|
351
|
+
it "moves to the nth next position" do
|
352
|
+
lambda do
|
353
|
+
item.send method, 2
|
354
|
+
end.should change(item, position_field).by(2)
|
355
|
+
end
|
356
|
+
|
357
|
+
it "moves to the end of the list if n is too high" do
|
358
|
+
lambda do
|
359
|
+
item.send method, 9
|
360
|
+
end.should change(item, position_field).by(2)
|
361
|
+
end
|
362
|
+
|
363
|
+
it "keeps items ordered" do
|
364
|
+
item.send method, 2
|
365
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
366
|
+
end
|
367
|
+
|
368
|
+
it "returns true" do
|
369
|
+
item.send(method).should be_true
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
[:backwards, :higher].each do |sym|
|
376
|
+
describe " #move_#{sym}" do
|
377
|
+
let(:method) { "move_#{sym}" }
|
378
|
+
|
379
|
+
context "for the first item of the list" do
|
380
|
+
let(:item) { category_1.items.order_by_position.first }
|
381
|
+
|
382
|
+
it "does not change the item's position" do
|
383
|
+
lambda do
|
384
|
+
item.send method
|
385
|
+
end.should_not change(item, position_field)
|
386
|
+
end
|
387
|
+
|
388
|
+
it "keeps items ordered" do
|
389
|
+
item.send method
|
390
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
391
|
+
end
|
392
|
+
|
393
|
+
it "returns false" do
|
394
|
+
item.send(method).should be_false
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context "for any other item" do
|
399
|
+
let(:item) { category_1.items.order_by_position.last }
|
400
|
+
|
401
|
+
it "moves to the previous position" do
|
402
|
+
lambda do
|
403
|
+
item.send method
|
404
|
+
end.should change(item, position_field).by(-1)
|
405
|
+
end
|
406
|
+
|
407
|
+
it "moves to the nth previous position" do
|
408
|
+
lambda do
|
409
|
+
item.send method, 2
|
410
|
+
end.should change(item, position_field).by(-2)
|
411
|
+
end
|
412
|
+
|
413
|
+
it "moves to the end of the list if n is too high" do
|
414
|
+
lambda do
|
415
|
+
item.send method, 9
|
416
|
+
end.should change(item, position_field).by(-2)
|
417
|
+
end
|
418
|
+
|
419
|
+
it "keeps items ordered" do
|
420
|
+
item.send method
|
421
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
422
|
+
end
|
423
|
+
|
424
|
+
it "returns true" do
|
425
|
+
item.send(method).should be_true
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
[:before, :above].each do |sym|
|
432
|
+
describe " #move_#{sym}" do
|
433
|
+
before do
|
434
|
+
item.send("move_#{sym}", other_item)
|
435
|
+
end
|
436
|
+
|
437
|
+
context "towards the start" do
|
438
|
+
let(:other_item) { category_1.items.order_by_position.first }
|
439
|
+
let(:item) { category_1.items.order_by_position.last }
|
440
|
+
|
441
|
+
it "moves to the same position as other_item" do
|
442
|
+
item[position_field].should == 0
|
443
|
+
end
|
444
|
+
|
445
|
+
it "shifts other_item " do
|
446
|
+
other_item.reload[position_field].should == 1
|
447
|
+
end
|
448
|
+
|
449
|
+
it "shifts any item after that by 1" do
|
450
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
451
|
+
end
|
452
|
+
end
|
453
|
+
context "towards the end" do
|
454
|
+
let(:item) { category_1.items.order_by_position.first }
|
455
|
+
let(:other_item) { category_1.items.order_by_position.last }
|
456
|
+
|
457
|
+
it "moves to the same position as other_item" do
|
458
|
+
item[position_field].should == 1
|
459
|
+
end
|
460
|
+
|
461
|
+
it "shifts other_item " do
|
462
|
+
other_item[position_field].should == 2
|
463
|
+
end
|
464
|
+
|
465
|
+
it "shifts any item after that by 1" do
|
466
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
[:after, :below].each do |sym|
|
473
|
+
describe " #move_#{sym}" do
|
474
|
+
before do
|
475
|
+
item.send("move_#{sym}", other_item)
|
476
|
+
end
|
477
|
+
|
478
|
+
context "towards the start" do
|
479
|
+
let(:other_item) { category_1.items.order_by_position.first }
|
480
|
+
let(:item) { category_1.items.order_by_position.last }
|
481
|
+
|
482
|
+
it "moves to other_item's next position" do
|
483
|
+
item[position_field].should == 1
|
484
|
+
end
|
485
|
+
|
486
|
+
it "shifts any item before that by -1" do
|
487
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
488
|
+
end
|
489
|
+
end
|
490
|
+
context "towards the end" do
|
491
|
+
let(:item) { category_1.items.order_by_position.first }
|
492
|
+
let(:other_item) { category_1.items.order_by_position.last }
|
493
|
+
|
494
|
+
it "moves to the same position as other_item" do
|
495
|
+
item[position_field].should == 2
|
496
|
+
end
|
497
|
+
|
498
|
+
it "shifts any item before that by -1" do
|
499
|
+
category_1.items.order_by_position.map(&position_field).should == [0,1,2]
|
500
|
+
end
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
describe "#start_position_in_list" do
|
506
|
+
before do
|
507
|
+
@original_start = Mongoid::ActsAsList.configuration.start_list_at
|
508
|
+
end
|
509
|
+
after do
|
510
|
+
Mongoid::ActsAsList.configure {|c| c.start_list_at = @original_start}
|
511
|
+
end
|
512
|
+
|
513
|
+
it "is configurable" do
|
514
|
+
category_3.items.should be_empty
|
515
|
+
start = 1
|
516
|
+
Mongoid::ActsAsList.configure {|c| c.start_list_at = start}
|
517
|
+
item = category_3.items.create!
|
518
|
+
item[position_field].should == start
|
519
|
+
item = category_3.items.create!
|
520
|
+
item[position_field].should == start+1
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|