dm-is-nested_set 0.9.11 → 0.10.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.
- data/{History.txt → History.rdoc} +4 -0
- data/Manifest.txt +2 -2
- data/{README.txt → README.rdoc} +0 -0
- data/Rakefile +2 -3
- data/lib/dm-is-nested_set/is/nested_set.rb +68 -64
- data/lib/dm-is-nested_set/is/version.rb +1 -1
- data/lib/dm-is-nested_set.rb +2 -8
- data/spec/integration/nested_set_spec.rb +44 -47
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -8
- data/tasks/install.rb +1 -1
- data/tasks/spec.rb +4 -4
- metadata +14 -31
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
File without changes
|
data/Rakefile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'pathname'
|
2
|
-
require 'rubygems'
|
3
2
|
|
4
3
|
ROOT = Pathname(__FILE__).dirname.expand_path
|
5
4
|
JRUBY = RUBY_PLATFORM =~ /java/
|
@@ -14,10 +13,10 @@ GEM_NAME = 'dm-is-nested_set'
|
|
14
13
|
GEM_VERSION = DataMapper::Is::NestedSet::VERSION
|
15
14
|
GEM_DEPENDENCIES = [['dm-core', GEM_VERSION], ['dm-adjust', GEM_VERSION]]
|
16
15
|
GEM_CLEAN = %w[ log pkg coverage ]
|
17
|
-
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.
|
16
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.rdoc LICENSE TODO History.rdoc ] }
|
18
17
|
|
19
18
|
PROJECT_NAME = 'datamapper'
|
20
|
-
PROJECT_URL = "http://github.com/
|
19
|
+
PROJECT_URL = "http://github.com/datamapper/dm-more/tree/master/#{GEM_NAME}"
|
21
20
|
PROJECT_DESCRIPTION = PROJECT_SUMMARY = 'DataMapper plugin allowing the creation of nested sets from data models'
|
22
21
|
|
23
22
|
[ ROOT, ROOT.parent ].each do |dir|
|
@@ -6,12 +6,12 @@ module DataMapper
|
|
6
6
|
# docs in the works
|
7
7
|
#
|
8
8
|
def is_nested_set(options={})
|
9
|
-
options = { :child_key => [:parent_id], :scope => [] }.merge(options)
|
9
|
+
options = { :child_key => [ :parent_id ], :scope => [] }.merge(options)
|
10
10
|
|
11
11
|
extend DataMapper::Is::NestedSet::ClassMethods
|
12
12
|
include DataMapper::Is::NestedSet::InstanceMethods
|
13
13
|
|
14
|
-
@nested_set_scope
|
14
|
+
@nested_set_scope = options[:scope]
|
15
15
|
@nested_set_parent = options[:child_key]
|
16
16
|
|
17
17
|
property :lft, Integer, :writer => :private
|
@@ -21,36 +21,36 @@ module DataMapper
|
|
21
21
|
# be cut down to 1 instead of 2 queries. this would be the other way, but seems hackish:
|
22
22
|
# options[:child_key].each{|pname| property(pname, Integer) unless properties.detect{|p| p.name == pname}}
|
23
23
|
|
24
|
-
belongs_to :parent, :
|
25
|
-
has n, :children, :
|
24
|
+
belongs_to :parent, :model => self, :child_key => options[:child_key], :order => [ :lft ], :nullable => true
|
25
|
+
has n, :children, :model => self, :child_key => options[:child_key], :order => [ :lft ]
|
26
26
|
|
27
27
|
before :create do
|
28
|
-
if !
|
28
|
+
if !parent
|
29
29
|
# TODO must change for nested sets
|
30
|
-
|
31
|
-
elsif
|
32
|
-
|
30
|
+
root ? move_without_saving(:into => root) : move_without_saving(:to => 1)
|
31
|
+
elsif parent && !lft
|
32
|
+
move_without_saving(:into => parent)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
before :update do
|
37
|
-
if
|
37
|
+
if nested_set_scope != original_nested_set_scope
|
38
38
|
# TODO detach from old list first. many edge-cases here, need good testing
|
39
|
-
self.lft,self.rgt = nil,nil
|
40
|
-
#puts "#{
|
41
|
-
|
42
|
-
elsif (
|
39
|
+
self.lft, self.rgt = nil, nil
|
40
|
+
#puts "#{root.inspect} - #{[nested_set_scope,original_nested_set_scope].inspect}"
|
41
|
+
root ? move_without_saving(:into => root) : move_without_saving(:to => 1)
|
42
|
+
elsif (parent && !lft) || (parent != ancestor)
|
43
43
|
# if the parent is set, we try to move this into that parent, otherwise move into root.
|
44
|
-
|
44
|
+
parent ? move_without_saving(:into => parent) : move_without_saving(:into => model.root)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
before :destroy do
|
49
|
-
|
49
|
+
send(:detach)
|
50
50
|
end
|
51
51
|
|
52
|
-
after_class_method :inherited do |retval,target|
|
53
|
-
target.instance_variable_set(:@nested_set_scope,
|
52
|
+
after_class_method :inherited do |retval, target|
|
53
|
+
target.instance_variable_set(:@nested_set_scope, @nested_set_scope.dup)
|
54
54
|
target.instance_variable_set(:@nested_set_parent, @nested_set_parent.dup)
|
55
55
|
end
|
56
56
|
|
@@ -60,8 +60,8 @@ module DataMapper
|
|
60
60
|
attr_reader :nested_set_scope, :nested_set_parent
|
61
61
|
|
62
62
|
def adjust_gap!(scoped_set,at,adjustment)
|
63
|
-
scoped_set.all(:rgt.gt => at).adjust!({:rgt => adjustment},true)
|
64
|
-
scoped_set.all(:lft.gt => at).adjust!({:lft => adjustment},true)
|
63
|
+
scoped_set.all(:rgt.gt => at).adjust!({ :rgt => adjustment }, true)
|
64
|
+
scoped_set.all(:lft.gt => at).adjust!({ :lft => adjustment }, true)
|
65
65
|
end
|
66
66
|
|
67
67
|
##
|
@@ -88,7 +88,7 @@ module DataMapper
|
|
88
88
|
def leaves
|
89
89
|
# TODO scoping, how should it act?
|
90
90
|
# TODO supply filtering-option?
|
91
|
-
all(:conditions => [
|
91
|
+
all(:conditions => [ 'rgt = lft + ?', 1 ], :order => [ :lft ])
|
92
92
|
end
|
93
93
|
|
94
94
|
##
|
@@ -104,7 +104,7 @@ module DataMapper
|
|
104
104
|
##
|
105
105
|
# rebuilds the nested set using parent/child relationships and a chosen order
|
106
106
|
#
|
107
|
-
def rebuild_set_from_tree(order=nil)
|
107
|
+
def rebuild_set_from_tree(order = nil)
|
108
108
|
# TODO pending
|
109
109
|
end
|
110
110
|
end
|
@@ -115,7 +115,7 @@ module DataMapper
|
|
115
115
|
#
|
116
116
|
# @private
|
117
117
|
def nested_set_scope
|
118
|
-
|
118
|
+
model.base_model.nested_set_scope.map{ |p| [ p, attribute_get(p) ] }.to_hash
|
119
119
|
end
|
120
120
|
|
121
121
|
##
|
@@ -123,7 +123,7 @@ module DataMapper
|
|
123
123
|
# @private
|
124
124
|
def original_nested_set_scope
|
125
125
|
# TODO commit
|
126
|
-
|
126
|
+
model.base_model.nested_set_scope.map{ |p| [ p, (property = properties[p]) && original_attributes.key?(property) ? original_attributes[property] : attribute_get(p) ] }.to_hash
|
127
127
|
end
|
128
128
|
|
129
129
|
##
|
@@ -131,7 +131,7 @@ module DataMapper
|
|
131
131
|
#
|
132
132
|
def nested_set
|
133
133
|
# TODO add option for serving it as a nested array
|
134
|
-
|
134
|
+
model.base_model.all(nested_set_scope.merge(:order => [ :lft ]))
|
135
135
|
end
|
136
136
|
|
137
137
|
##
|
@@ -167,21 +167,25 @@ module DataMapper
|
|
167
167
|
##
|
168
168
|
# @see move
|
169
169
|
def move_without_saving(vector)
|
170
|
-
if vector.
|
170
|
+
if vector.kind_of?(Hash)
|
171
|
+
action, object = vector.keys[0], vector.values[0]
|
172
|
+
else
|
173
|
+
action = vector
|
174
|
+
end
|
171
175
|
|
172
176
|
changed_scope = nested_set_scope != original_nested_set_scope
|
173
177
|
|
174
178
|
position = case action
|
175
|
-
when :higher then left_sibling ? left_sibling.lft
|
176
|
-
when :highest then ancestor ? ancestor.lft+1 : nil
|
177
|
-
when :lower then right_sibling ? right_sibling.rgt+1 : nil
|
178
|
-
when :lowest then ancestor ? ancestor.rgt
|
179
|
-
when :indent then left_sibling ? left_sibling.rgt
|
180
|
-
when :outdent then ancestor ? ancestor.rgt+1 : nil
|
181
|
-
when :into then object ? object.rgt
|
182
|
-
when :above then object ? object.lft
|
183
|
-
when :below then object ? object.rgt+1 : nil
|
184
|
-
when :to then object ? object.to_i
|
179
|
+
when :higher then left_sibling ? left_sibling.lft : nil # : "already at the top"
|
180
|
+
when :highest then ancestor ? ancestor.lft + 1 : nil # : "is root, or has no parent"
|
181
|
+
when :lower then right_sibling ? right_sibling.rgt + 1 : nil # : "already at the bottom"
|
182
|
+
when :lowest then ancestor ? ancestor.rgt : nil # : "is root, or has no parent"
|
183
|
+
when :indent then left_sibling ? left_sibling.rgt : nil # : "cannot find a sibling to indent into"
|
184
|
+
when :outdent then ancestor ? ancestor.rgt + 1 : nil # : "is root, or has no parent"
|
185
|
+
when :into then object ? object.rgt : nil # : "supply an object"
|
186
|
+
when :above then object ? object.lft : nil # : "supply an object"
|
187
|
+
when :below then object ? object.rgt + 1 : nil # : "supply an object"
|
188
|
+
when :to then object ? object.to_i : nil # : "supply a number"
|
185
189
|
end
|
186
190
|
|
187
191
|
##
|
@@ -192,45 +196,45 @@ module DataMapper
|
|
192
196
|
# raise UnableToPositionError unless position.is_a?(Integer) && position > 0
|
193
197
|
return false if !position || position < 1
|
194
198
|
# return false if you are trying to move this into another scope
|
195
|
-
return false if [:into, :above
|
199
|
+
return false if [ :into, :above, :below ].include?(action) && nested_set_scope != object.nested_set_scope
|
196
200
|
# if node is already in the requested position
|
197
|
-
if
|
198
|
-
self.parent =
|
201
|
+
if lft == position || rgt == position - 1
|
202
|
+
self.parent = ancestor # must set this again, because it might have been changed by the user before move.
|
199
203
|
return false
|
200
204
|
end
|
201
205
|
|
202
|
-
|
203
|
-
DataMapper::Transaction.new(self.repository) do |transaction|
|
206
|
+
model.transaction do
|
204
207
|
|
205
208
|
##
|
206
209
|
# if this node is already positioned we need to move it, and close the gap it leaves behind etc
|
207
210
|
# otherwise we only need to open a gap in the set, and smash that buggar in
|
208
211
|
#
|
209
|
-
if
|
210
|
-
# raise exception if node is trying to move into one of its descendants (
|
211
|
-
raise RecursiveNestingError if position >
|
212
|
+
if lft && rgt
|
213
|
+
# raise exception if node is trying to move into one of its descendants (infinite loop, spacetime will warp)
|
214
|
+
raise RecursiveNestingError if position > lft && position < rgt
|
212
215
|
# find out how wide this node is, as we need to make a gap large enough for it to fit in
|
213
|
-
gap =
|
216
|
+
gap = rgt - lft + 1
|
214
217
|
|
215
218
|
# make a gap at position, that is as wide as this node
|
216
|
-
|
219
|
+
model.base_model.adjust_gap!(nested_set, position - 1, gap)
|
217
220
|
|
218
221
|
# offset this node (and all its descendants) to the right position
|
219
|
-
|
220
|
-
old_position =
|
222
|
+
reload_attributes([ :lft, :rgt ])
|
223
|
+
old_position = lft
|
221
224
|
offset = position - old_position
|
222
225
|
|
223
|
-
nested_set.all(:rgt =>
|
226
|
+
nested_set.all(:rgt => lft..rgt).adjust!({ :lft => offset, :rgt => offset }, true)
|
227
|
+
|
224
228
|
# close the gap this movement left behind.
|
225
|
-
|
226
|
-
|
229
|
+
model.base_model.adjust_gap!(nested_set, old_position, -gap)
|
230
|
+
reload_attributes([ :lft, :rgt ])
|
227
231
|
else
|
228
232
|
# make a gap where the new node can be inserted
|
229
|
-
|
233
|
+
model.base_model.adjust_gap!(nested_set, position - 1, 2)
|
230
234
|
# set the position fields
|
231
235
|
self.lft, self.rgt = position, position + 1
|
232
236
|
end
|
233
|
-
self.parent =
|
237
|
+
self.parent = ancestor
|
234
238
|
end
|
235
239
|
end
|
236
240
|
|
@@ -258,7 +262,7 @@ module DataMapper
|
|
258
262
|
# @see #self_and_ancestors
|
259
263
|
def ancestors
|
260
264
|
nested_set.all(:lft.lt => lft, :rgt.gt => rgt)
|
261
|
-
#self_and_ancestors.reject{|r| r.key ==
|
265
|
+
#self_and_ancestors.reject{|r| r.key == key } # because identitymap is not used in console
|
262
266
|
end
|
263
267
|
|
264
268
|
##
|
@@ -266,7 +270,7 @@ module DataMapper
|
|
266
270
|
#
|
267
271
|
# @return <Resource, NilClass> returns the parent-object, or nil if this is root/detached
|
268
272
|
def ancestor
|
269
|
-
ancestors.
|
273
|
+
ancestors.last
|
270
274
|
end
|
271
275
|
|
272
276
|
##
|
@@ -302,7 +306,7 @@ module DataMapper
|
|
302
306
|
def descendants
|
303
307
|
# TODO add argument for returning as a nested array.
|
304
308
|
# TODO supply filtering-option?
|
305
|
-
nested_set.all(:lft => (lft+1)..(rgt-1))
|
309
|
+
nested_set.all(:lft => (lft + 1)..(rgt - 1))
|
306
310
|
end
|
307
311
|
|
308
312
|
##
|
@@ -311,7 +315,7 @@ module DataMapper
|
|
311
315
|
# @return <Collection>
|
312
316
|
def leaves
|
313
317
|
# TODO supply filtering-option?
|
314
|
-
nested_set.all(:lft => (lft+1)..rgt, :conditions=>[
|
318
|
+
nested_set.all(:lft => (lft + 1)..rgt, :conditions => [ 'rgt = lft + ?', 1 ])
|
315
319
|
end
|
316
320
|
|
317
321
|
##
|
@@ -320,7 +324,7 @@ module DataMapper
|
|
320
324
|
#
|
321
325
|
# @par
|
322
326
|
def leaf?
|
323
|
-
rgt-lft == 1
|
327
|
+
rgt - lft == 1
|
324
328
|
end
|
325
329
|
|
326
330
|
##
|
@@ -328,7 +332,7 @@ module DataMapper
|
|
328
332
|
#
|
329
333
|
# @return <Collection>
|
330
334
|
def self_and_siblings
|
331
|
-
parent ? parent.children : [self]
|
335
|
+
parent ? parent.children : [ self ]
|
332
336
|
end
|
333
337
|
|
334
338
|
##
|
@@ -339,7 +343,7 @@ module DataMapper
|
|
339
343
|
def siblings
|
340
344
|
# TODO find a way to return this as a collection?
|
341
345
|
# TODO supply filtering-option?
|
342
|
-
self_and_siblings.reject{|r| r.key ==
|
346
|
+
self_and_siblings.reject { |r| r.key == key } # because identitymap is not used in console
|
343
347
|
end
|
344
348
|
|
345
349
|
##
|
@@ -348,7 +352,7 @@ module DataMapper
|
|
348
352
|
# @return <Resource, NilClass> the resource to the left, or nil if self is leftmost
|
349
353
|
# @see #self_and_siblings
|
350
354
|
def left_sibling
|
351
|
-
self_and_siblings.
|
355
|
+
self_and_siblings.detect { |v| v.rgt == lft - 1 }
|
352
356
|
end
|
353
357
|
|
354
358
|
##
|
@@ -357,14 +361,14 @@ module DataMapper
|
|
357
361
|
# @return <Resource, NilClass> the resource to the right, or nil if self is rightmost
|
358
362
|
# @see #self_and_siblings
|
359
363
|
def right_sibling
|
360
|
-
self_and_siblings.
|
364
|
+
self_and_siblings.detect { |v| v.lft == rgt + 1 }
|
361
365
|
end
|
362
366
|
|
363
367
|
private
|
364
368
|
def detach
|
365
|
-
offset =
|
366
|
-
|
367
|
-
self.lft,self.rgt = nil,nil
|
369
|
+
offset = lft - rgt - 1
|
370
|
+
model.base_model.adjust_gap!(nested_set, rgt, offset)
|
371
|
+
self.lft, self.rgt = nil, nil
|
368
372
|
end
|
369
373
|
|
370
374
|
end
|
data/lib/dm-is-nested_set.rb
CHANGED
@@ -1,10 +1,4 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'rubygems'
|
3
|
-
|
4
|
-
gem 'dm-core', '0.9.11'
|
5
|
-
require 'dm-core'
|
6
|
-
|
7
|
-
#gem 'dm-adjust', '0.9.11'
|
8
1
|
require 'dm-adjust'
|
9
2
|
|
10
|
-
require
|
3
|
+
require 'dm-is-nested_set/is/nested_set'
|
4
|
+
require 'dm-is-nested_set/is/version'
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
5
4
|
|
@@ -33,7 +32,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
33
32
|
class ::User
|
34
33
|
include DataMapper::Resource
|
35
34
|
|
36
|
-
property :id,
|
35
|
+
property :id, Serial
|
37
36
|
property :name, String
|
38
37
|
|
39
38
|
has n, :categories
|
@@ -43,8 +42,8 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
43
42
|
class ::Category
|
44
43
|
include DataMapper::Resource
|
45
44
|
|
46
|
-
property :id,
|
47
|
-
property :name,
|
45
|
+
property :id, Serial
|
46
|
+
property :name, String
|
48
47
|
property :class_name, Discriminator
|
49
48
|
|
50
49
|
belongs_to :user
|
@@ -59,26 +58,26 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
59
58
|
|
60
59
|
DataMapper.auto_migrate!
|
61
60
|
|
62
|
-
repository
|
63
|
-
@
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
61
|
+
DataMapper.repository do
|
62
|
+
@user = User.create(:name => 'paul')
|
63
|
+
@other = User.create(:name => 'john')
|
64
|
+
|
65
|
+
electronics = @user.categories.create( :name => 'Electronics')
|
66
|
+
televisions = @user.categories.create(:parent => electronics, :name => 'Televisions')
|
67
|
+
tube = @user.categories.create(:parent => televisions, :name => 'Tube')
|
68
|
+
lcd = @user.categories.create(:parent => televisions, :name => 'LCD')
|
69
|
+
plasma = @user.categories.create(:parent => televisions, :name => 'Plasma')
|
70
|
+
portable_electronics = @user.categories.create(:parent => electronics, :name => 'Portable Electronics')
|
71
|
+
mp3_players = @user.categories.create(:parent => portable_electronics, :name => 'MP3 Players')
|
72
|
+
flash = @user.categories.create(:parent => mp3_players, :name => 'Flash')
|
73
|
+
cd_players = @user.categories.create(:parent => portable_electronics, :name => 'CD Players')
|
74
|
+
two_way_radios = @user.categories.create(:parent => portable_electronics, :name => '2 Way Radios')
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
78
|
describe 'Class#rebuild_tree_from_set' do
|
80
79
|
it 'should reset all parent_ids correctly' do
|
81
|
-
repository(:default) do
|
80
|
+
DataMapper.repository(:default) do
|
82
81
|
plasma = Category.get(5)
|
83
82
|
plasma.parent_id.should == 2
|
84
83
|
plasma.ancestor.id.should == 2
|
@@ -92,13 +91,13 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
92
91
|
|
93
92
|
describe 'Class#root and #root' do
|
94
93
|
it 'should return the toplevel node' do
|
95
|
-
Category.root.name.should ==
|
94
|
+
Category.root.name.should == 'Electronics'
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|
99
98
|
describe 'Class#leaves and #leaves' do
|
100
99
|
it 'should return all nodes without descendants' do
|
101
|
-
repository(:default) do
|
100
|
+
DataMapper.repository(:default) do
|
102
101
|
Category.leaves.length.should == 6
|
103
102
|
|
104
103
|
r = Category.root
|
@@ -110,56 +109,56 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
110
109
|
|
111
110
|
describe '#ancestor, #ancestors and #self_and_ancestors' do
|
112
111
|
it 'should return ancestors in an array' do
|
113
|
-
repository(:default) do |repos|
|
112
|
+
DataMapper.repository(:default) do |repos|
|
114
113
|
c8 = Category.get(8)
|
115
114
|
c8.ancestor.should == Category.get(7)
|
116
115
|
c8.ancestor.should == c8.parent
|
117
116
|
|
118
|
-
c8.ancestors.map{|a|a.name}.should == [
|
119
|
-
c8.self_and_ancestors.map{|a|a.name}.should == [
|
117
|
+
c8.ancestors.map{|a|a.name}.should == ['Electronics','Portable Electronics','MP3 Players']
|
118
|
+
c8.self_and_ancestors.map{|a|a.name}.should == ['Electronics','Portable Electronics','MP3 Players','Flash']
|
120
119
|
end
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
124
123
|
describe '#children' do
|
125
124
|
it 'should return children of node' do
|
126
|
-
repository(:default) do |repos|
|
125
|
+
DataMapper.repository(:default) do |repos|
|
127
126
|
r = Category.root
|
128
127
|
r.children.length.should == 2
|
129
128
|
|
130
129
|
t = r.children.first
|
131
130
|
t.children.length.should == 3
|
132
|
-
t.children.first.name.should ==
|
133
|
-
t.children[2].name.should ==
|
131
|
+
t.children.first.name.should == 'Tube'
|
132
|
+
t.children[2].name.should == 'Plasma'
|
134
133
|
end
|
135
134
|
end
|
136
135
|
end
|
137
136
|
|
138
137
|
describe '#descendants and #self_and_descendants' do
|
139
138
|
it 'should return all subnodes of node' do
|
140
|
-
repository(:default) do
|
139
|
+
DataMapper.repository(:default) do
|
141
140
|
r = Category.get(1)
|
142
141
|
r.self_and_descendants.length.should == 10
|
143
142
|
r.descendants.length.should == 9
|
144
|
-
r.name.should ==
|
143
|
+
r.name.should == 'Electronics'
|
145
144
|
t = r.children[1]
|
146
|
-
t.name.should ==
|
145
|
+
t.name.should == 'Portable Electronics'
|
147
146
|
t.descendants.length.should == 4
|
148
|
-
t.descendants.map{|a|a.name}.should == [
|
147
|
+
t.descendants.map{|a|a.name}.should == ['MP3 Players','Flash','CD Players','2 Way Radios']
|
149
148
|
end
|
150
149
|
end
|
151
150
|
end
|
152
151
|
|
153
152
|
describe '#siblings and #self_and_siblings' do
|
154
153
|
it 'should return all siblings of node' do
|
155
|
-
repository(:default) do
|
154
|
+
DataMapper.repository(:default) do
|
156
155
|
r = Category.root
|
157
156
|
r.self_and_siblings.length.should == 1
|
158
157
|
r.descendants.length.should == 9
|
159
158
|
|
160
159
|
televisions = r.children[0]
|
161
160
|
televisions.siblings.length.should == 1
|
162
|
-
televisions.siblings.map{|a|a.name}.should == [
|
161
|
+
televisions.siblings.map{|a|a.name}.should == ['Portable Electronics']
|
163
162
|
end
|
164
163
|
end
|
165
164
|
end
|
@@ -181,7 +180,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
181
180
|
# 10 | 17 | 18 | - 2 Way Radios
|
182
181
|
|
183
182
|
it 'should move items correctly with :higher / :highest / :lower / :lowest' do
|
184
|
-
repository(:default) do |repos|
|
183
|
+
DataMapper.repository(:default) do |repos|
|
185
184
|
|
186
185
|
Category.get(4).pos.should == [5,6]
|
187
186
|
|
@@ -212,7 +211,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
212
211
|
end
|
213
212
|
|
214
213
|
it 'should move items correctly with :indent / :outdent' do
|
215
|
-
repository(:default) do |repos|
|
214
|
+
DataMapper.repository(:default) do |repos|
|
216
215
|
|
217
216
|
mp3_players = Category.get(7)
|
218
217
|
|
@@ -240,18 +239,18 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
240
239
|
|
241
240
|
describe 'moving objects with #move_* #and place_node_at' do
|
242
241
|
it 'should set left/right when choosing a parent' do
|
243
|
-
repository(:default) do |repos|
|
242
|
+
DataMapper.repository(:default) do |repos|
|
244
243
|
Category.auto_migrate!
|
245
244
|
|
246
|
-
c1 =
|
245
|
+
c1 = @user.categories.create(:name => 'New Electronics')
|
247
246
|
|
248
|
-
c2 =
|
247
|
+
c2 = @user.categories.create(:name => 'OLED TVs')
|
249
248
|
|
250
249
|
c1.pos.should == [1,4]
|
251
250
|
c1.root.should == c1
|
252
251
|
c2.pos.should == [2,3]
|
253
252
|
|
254
|
-
c3 =
|
253
|
+
c3 = @user.categories.create(:name => 'Portable Electronics')
|
255
254
|
c3.parent=c1
|
256
255
|
c3.save
|
257
256
|
|
@@ -273,8 +272,8 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
273
272
|
c2.pos.should == [2,5]
|
274
273
|
c3.pos.should == [3,4]
|
275
274
|
|
276
|
-
c4 =
|
277
|
-
c5 =
|
275
|
+
c4 = @user.categories.create(:name => 'Tube', :parent => c2)
|
276
|
+
c5 = @user.categories.create(:name => 'Flatpanel', :parent => c2)
|
278
277
|
|
279
278
|
c1.pos.should == [1,10]
|
280
279
|
c2.pos.should == [2,9]
|
@@ -293,11 +292,10 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
293
292
|
|
294
293
|
describe 'scoping' do
|
295
294
|
it 'should detach from list when changing scope' do
|
296
|
-
repository(:default) do |repos|
|
295
|
+
DataMapper.repository(:default) do |repos|
|
297
296
|
plasma = Category.get(5)
|
298
297
|
plasma.pos.should == [7,8]
|
299
|
-
plasma.
|
300
|
-
plasma.save
|
298
|
+
plasma.update(:user => @other)
|
301
299
|
plasma.pos.should == [1,2]
|
302
300
|
end
|
303
301
|
end
|
@@ -305,7 +303,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
305
303
|
|
306
304
|
describe 'integrity' do
|
307
305
|
it 'should detach object from list when deleted' do
|
308
|
-
repository(:default) do |repos|
|
306
|
+
DataMapper.repository(:default) do |repos|
|
309
307
|
lcd = Category.get(4)
|
310
308
|
lcd.pos.should == [5,6]
|
311
309
|
Category.get(3).destroy
|
@@ -313,6 +311,5 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
313
311
|
end
|
314
312
|
end
|
315
313
|
end
|
316
|
-
|
317
314
|
end
|
318
315
|
end
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'rubygems'
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
# use local dm-core if running from a typical dev checkout.
|
4
|
+
lib = File.join('..', '..', 'dm-core', 'lib')
|
5
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
6
|
+
require 'dm-core'
|
6
7
|
|
7
|
-
|
8
|
+
# use local dm-adjust if running from a typical dev checkout.
|
9
|
+
lib = File.join('..', 'dm-adjust', 'lib')
|
10
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
11
|
+
require 'dm-adjust'
|
8
12
|
|
9
|
-
#
|
10
|
-
lib
|
11
|
-
$LOAD_PATH.unshift(lib) if lib.directory?
|
13
|
+
# Support running specs with 'rake spec' and 'spec'
|
14
|
+
$LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
|
12
15
|
|
13
|
-
require
|
16
|
+
require 'dm-is-nested_set'
|
14
17
|
|
15
18
|
def load_driver(name, default_uri)
|
16
19
|
return false if ENV['ADAPTER'] != name.to_s
|
data/tasks/install.rb
CHANGED
@@ -4,7 +4,7 @@ end
|
|
4
4
|
|
5
5
|
desc "Install #{GEM_NAME} #{GEM_VERSION}"
|
6
6
|
task :install => [ :package ] do
|
7
|
-
sudo_gem "install
|
7
|
+
sudo_gem "install pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
|
data/tasks/spec.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
begin
|
2
|
-
gem 'rspec', '~>1.2'
|
3
|
-
require 'spec'
|
4
2
|
require 'spec/rake/spectask'
|
5
3
|
|
6
4
|
task :default => [ :spec ]
|
@@ -8,16 +6,18 @@ begin
|
|
8
6
|
desc 'Run specifications'
|
9
7
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
10
8
|
t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
11
|
-
t.
|
9
|
+
t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
|
12
10
|
|
13
11
|
begin
|
14
|
-
|
12
|
+
require 'rcov'
|
15
13
|
t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
|
16
14
|
t.rcov_opts << '--exclude' << 'spec'
|
17
15
|
t.rcov_opts << '--text-summary'
|
18
16
|
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
19
17
|
rescue LoadError
|
20
18
|
# rcov not installed
|
19
|
+
rescue SyntaxError
|
20
|
+
# rcov syntax invalid
|
21
21
|
end
|
22
22
|
end
|
23
23
|
rescue LoadError
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-nested_set
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sindre Aarsaether
|
@@ -9,29 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: dm-core
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - "="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.11
|
24
|
-
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: dm-adjust
|
27
|
-
type: :runtime
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.9.11
|
34
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
35
16
|
description: DataMapper plugin allowing the creation of nested sets from data models
|
36
17
|
email:
|
37
18
|
- sindre [a] identu [d] no
|
@@ -40,15 +21,15 @@ executables: []
|
|
40
21
|
extensions: []
|
41
22
|
|
42
23
|
extra_rdoc_files:
|
43
|
-
- README.
|
24
|
+
- README.rdoc
|
44
25
|
- LICENSE
|
45
26
|
- TODO
|
46
|
-
- History.
|
27
|
+
- History.rdoc
|
47
28
|
files:
|
48
|
-
- History.
|
29
|
+
- History.rdoc
|
49
30
|
- LICENSE
|
50
31
|
- Manifest.txt
|
51
|
-
- README.
|
32
|
+
- README.rdoc
|
52
33
|
- Rakefile
|
53
34
|
- TODO
|
54
35
|
- lib/dm-is-nested_set.rb
|
@@ -60,11 +41,13 @@ files:
|
|
60
41
|
- tasks/install.rb
|
61
42
|
- tasks/spec.rb
|
62
43
|
has_rdoc: true
|
63
|
-
homepage: http://github.com/
|
44
|
+
homepage: http://github.com/datamapper/dm-more/tree/master/dm-is-nested_set
|
45
|
+
licenses: []
|
46
|
+
|
64
47
|
post_install_message:
|
65
48
|
rdoc_options:
|
66
49
|
- --main
|
67
|
-
- README.
|
50
|
+
- README.rdoc
|
68
51
|
require_paths:
|
69
52
|
- lib
|
70
53
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -82,9 +65,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
65
|
requirements: []
|
83
66
|
|
84
67
|
rubyforge_project: datamapper
|
85
|
-
rubygems_version: 1.3.
|
68
|
+
rubygems_version: 1.3.5
|
86
69
|
signing_key:
|
87
|
-
specification_version:
|
70
|
+
specification_version: 3
|
88
71
|
summary: DataMapper plugin allowing the creation of nested sets from data models
|
89
72
|
test_files: []
|
90
73
|
|