Gustavo Picon is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

tabo / django-treebeard

Efficient tree implementations for Django 1.0+ :: https://tabo.pe/projects/django-treebeard/

Clone this repository (size: 602.0 KB): HTTPS / SSH
hg clone https://bitbucket.org/tabo/django-treebeard
hg clone ssh://hg@bitbucket.org/tabo/django-treebeard
commit
0f2a87d336ee
parent
f45c785ede80
parent
b38bf3705bca
branch
1.6.X

merging from 1.61 tag to 1.6.X branch

1
92fc5f1c56f4
"Unit/Functional tests"
2
c50d8b82040f
3
5ce21f964dd8
import functools
4
5ce21f964dd8
import os
5
7a62dd4d475f
from django.contrib.admin.options import ModelAdmin
6
7a62dd4d475f
from django.contrib.admin.sites import AdminSite
7
c59b969c4100
from django.test import TestCase
8
5956967b8676
from django.db import models, transaction
9
3599a4f7c819
from django.contrib.auth.models import User
10
825d0e0b5e08
from django.db.models import Q
11
825d0e0b5e08
from django.conf import settings
12
b943312fad8f
from django import VERSION as DJANGO_VERSION
13
ac1ecbb55c06
14
eff7959f5c38
from treebeard import numconv
15
eff7959f5c38
from treebeard.exceptions import InvalidPosition, InvalidMoveToDescendant, \
16
eff7959f5c38
    PathOverflow, MissingNodeOrderBy
17
5956967b8676
from treebeard.mp_tree import MP_Node
18
c1e2edeb3b9e
from treebeard.al_tree import AL_Node
19
032b45fe0bd4
from treebeard.ns_tree import NS_Node
20
ebe6fd3444ee
from treebeard.forms import MoveNodeForm
21
c59b969c4100
22
825d0e0b5e08
# ghetto app detection, there is probably some introspection method,
23
825d0e0b5e08
# but meh, this works
24
825d0e0b5e08
HAS_DJANGO_AUTH = 'django.contrib.auth' in settings.INSTALLED_APPS
25
825d0e0b5e08
26
c59b969c4100
BASE_DATA = [
27
c59b969c4100
  {'data':{'desc':'1'}},
28
c59b969c4100
  {'data':{'desc':'2'}, 'children':[
29
c59b969c4100
    {'data':{'desc':'21'}},
30
c59b969c4100
    {'data':{'desc':'22'}},
31
c59b969c4100
    {'data':{'desc':'23'}, 'children':[
32
c59b969c4100
      {'data':{'desc':'231'}},
33
c59b969c4100
    ]},
34
c59b969c4100
    {'data':{'desc':'24'}},
35
c59b969c4100
  ]},
36
c59b969c4100
  {'data':{'desc':'3'}},
37
c59b969c4100
  {'data':{'desc':'4'}, 'children':[
38
c59b969c4100
    {'data':{'desc':'41'}},
39
c59b969c4100
  ]},
40
c59b969c4100
]
41
c59b969c4100
42
c59b969c4100
43
5956967b8676
class MP_TestNode(MP_Node):
44
c59b969c4100
    steplen = 3
45
c59b969c4100
46
c59b969c4100
    desc = models.CharField(max_length=255)
47
c59b969c4100
48
f875c152df5d
    def __unicode__(self):  # pragma: no cover
49
7a62dd4d475f
        return 'Node %d' % self.id
50
7a62dd4d475f
51
c59b969c4100
52
5956967b8676
class MP_TestNodeSomeDep(models.Model):
53
5956967b8676
    node = models.ForeignKey(MP_TestNode)
54
e570e2483a41
55
f875c152df5d
    def __unicode__(self):  # pragma: no cover
56
7a62dd4d475f
        return 'Node %d' % self.id
57
7a62dd4d475f
58
e570e2483a41
59
032b45fe0bd4
class NS_TestNode(NS_Node):
60
032b45fe0bd4
    desc = models.CharField(max_length=255)
61
032b45fe0bd4
62
f875c152df5d
    def __unicode__(self):  # pragma: no cover
63
7a62dd4d475f
        return 'Node %d' % self.id
64
7a62dd4d475f
65
032b45fe0bd4
66
032b45fe0bd4
class NS_TestNodeSomeDep(models.Model):
67
032b45fe0bd4
    node = models.ForeignKey(NS_TestNode)
68
032b45fe0bd4
69
f875c152df5d
    def __unicode__(self):  # pragma: no cover
70
7a62dd4d475f
        return 'Node %d' % self.id
71
7a62dd4d475f
72
032b45fe0bd4
73
c1e2edeb3b9e
class AL_TestNode(AL_Node):
74
c1e2edeb3b9e
    parent = models.ForeignKey('self',
75
c1e2edeb3b9e
                               related_name='children_set',
76
c1e2edeb3b9e
                               null=True,
77
c1e2edeb3b9e
                               db_index=True)
78
c1e2edeb3b9e
    sib_order = models.PositiveIntegerField()
79
c1e2edeb3b9e
    desc = models.CharField(max_length=255)
80
c1e2edeb3b9e
81
f875c152df5d
    def __unicode__(self):  # pragma: no cover
82
7a62dd4d475f
        return 'Node %d' % self.id
83
7a62dd4d475f
84
c1e2edeb3b9e
85
c1e2edeb3b9e
class AL_TestNodeSomeDep(models.Model):
86
c1e2edeb3b9e
    node = models.ForeignKey(AL_TestNode)
87
c1e2edeb3b9e
88
f875c152df5d
    def __unicode__(self):  # pragma: no cover
89
7a62dd4d475f
        return 'Node %d' % self.id
90
7a62dd4d475f
91
c1e2edeb3b9e
92
5956967b8676
class MP_TestNodeSorted(MP_Node):
93
c59b969c4100
    steplen = 1
94
c59b969c4100
    node_order_by = ['val1', 'val2', 'desc']
95
c59b969c4100
    val1 = models.IntegerField()
96
c59b969c4100
    val2 = models.IntegerField()
97
c59b969c4100
    desc = models.CharField(max_length=255)
98
c59b969c4100
99
f875c152df5d
    def __unicode__(self):  # pragma: no cover
100
7a62dd4d475f
        return 'Node %d' % self.id
101
7a62dd4d475f
102
c59b969c4100
103
032b45fe0bd4
class NS_TestNodeSorted(NS_Node):
104
032b45fe0bd4
    node_order_by = ['val1', 'val2', 'desc']
105
032b45fe0bd4
    val1 = models.IntegerField()
106
032b45fe0bd4
    val2 = models.IntegerField()
107
032b45fe0bd4
    desc = models.CharField(max_length=255)
108
032b45fe0bd4
109
f875c152df5d
    def __unicode__(self):  # pragma: no cover
110
7a62dd4d475f
        return 'Node %d' % self.id
111
7a62dd4d475f
112
032b45fe0bd4
113
c1e2edeb3b9e
class AL_TestNodeSorted(AL_Node):
114
c1e2edeb3b9e
    parent = models.ForeignKey('self',
115
c1e2edeb3b9e
                               related_name='children_set',
116
c1e2edeb3b9e
                               null=True,
117
c1e2edeb3b9e
                               db_index=True)
118
c1e2edeb3b9e
    node_order_by = ['val1', 'val2', 'desc']
119
c1e2edeb3b9e
    val1 = models.IntegerField()
120
c1e2edeb3b9e
    val2 = models.IntegerField()
121
c1e2edeb3b9e
    desc = models.CharField(max_length=255)
122
c1e2edeb3b9e
123
f875c152df5d
    def __unicode__(self):  # pragma: no cover
124
7a62dd4d475f
        return 'Node %d' % self.id
125
7a62dd4d475f
126
c1e2edeb3b9e
127
5956967b8676
class MP_TestNodeAlphabet(MP_Node):
128
f090c68767a8
    steplen = 2
129
f090c68767a8
130
f090c68767a8
    numval = models.IntegerField()
131
f090c68767a8
132
f875c152df5d
    def __unicode__(self):  # pragma: no cover
133
7a62dd4d475f
        return 'Node %d' % self.id
134
7a62dd4d475f
135
c59b969c4100
136
5956967b8676
class MP_TestNodeSmallStep(MP_Node):
137
7855e638023a
    steplen = 1
138
7855e638023a
    alphabet = '0123456789'
139
7855e638023a
140
f875c152df5d
    def __unicode__(self):  # pragma: no cover
141
7a62dd4d475f
        return 'Node %d' % self.id
142
7a62dd4d475f
143
7855e638023a
144
5956967b8676
class MP_TestNodeSortedAutoNow(MP_Node):
145
9bbcfbe7a52b
    desc = models.CharField(max_length=255)
146
9bbcfbe7a52b
    created = models.DateTimeField(auto_now_add=True)
147
9bbcfbe7a52b
148
9bbcfbe7a52b
    node_order_by = ['created']
149
9bbcfbe7a52b
150
f875c152df5d
    def __unicode__(self):  # pragma: no cover
151
7a62dd4d475f
        return 'Node %d' % self.id
152
7a62dd4d475f
153
9bbcfbe7a52b
154
5956967b8676
class MP_TestNodeShortPath(MP_Node):
155
9bbcfbe7a52b
    steplen = 1
156
cfe76918146d
    alphabet = '01234'
157
cfe76918146d
    desc = models.CharField(max_length=255)
158
9bbcfbe7a52b
159
f875c152df5d
    def __unicode__(self):  # pragma: no cover
160
7a62dd4d475f
        return 'Node %d' % self.id
161
7a62dd4d475f
162
9bbcfbe7a52b
# This is how you change the default fields defined in a Django abstract class
163
5956967b8676
# (in this case, MP_Node), since Django doesn't allow overriding fields, only
164
9bbcfbe7a52b
# mehods and attributes
165
5956967b8676
MP_TestNodeShortPath._meta.get_field('path').max_length = 4
166
9bbcfbe7a52b
167
9bbcfbe7a52b
168
b943312fad8f
if DJANGO_VERSION >= (1, 1):  # pragma: no cover
169
b943312fad8f
170
b943312fad8f
    class MP_TestNode_Proxy(MP_TestNode):
171
b943312fad8f
        class Meta:
172
b943312fad8f
            proxy = True
173
b943312fad8f
174
b943312fad8f
175
b943312fad8f
    class NS_TestNode_Proxy(NS_TestNode):
176
b943312fad8f
        class Meta:
177
b943312fad8f
            proxy = True
178
b943312fad8f
179
b943312fad8f
180
b943312fad8f
    class AL_TestNode_Proxy(AL_TestNode):
181
b943312fad8f
        class Meta:
182
b943312fad8f
            proxy = True
183
b943312fad8f
184
b943312fad8f
185
c1e2edeb3b9e
class MP_TestSortedNodeShortPath(MP_Node):
186
cfe76918146d
    steplen = 1
187
cfe76918146d
    alphabet = '01234'
188
cfe76918146d
    desc = models.CharField(max_length=255)
189
cfe76918146d
190
cfe76918146d
    node_order_by = ['desc']
191
7a62dd4d475f
192
f875c152df5d
    def __unicode__(self):  # pragma: no cover
193
7a62dd4d475f
        return 'Node %d' % self.id
194
7a62dd4d475f
195
c1e2edeb3b9e
MP_TestSortedNodeShortPath._meta.get_field('path').max_length = 4
196
cfe76918146d
197
cfe76918146d
198
825d0e0b5e08
if HAS_DJANGO_AUTH:
199
5ce21f964dd8
200
825d0e0b5e08
    class MP_TestIssue14(MP_Node):
201
825d0e0b5e08
        name = models.CharField(max_length=255)
202
825d0e0b5e08
        users = models.ManyToManyField(User)
203
825d0e0b5e08
204
825d0e0b5e08
205
81fa32fd2e26
def testtype(treetype, proxy):
206
5ce21f964dd8
207
5956967b8676
    def decorator(f):
208
5956967b8676
209
5956967b8676
        @functools.wraps(f)
210
a1c1c555e5ee
        def _testtype(self):
211
a1c1c555e5ee
            {'MP': self.set_MP,
212
a1c1c555e5ee
             'AL': self.set_AL,
213
81fa32fd2e26
             'NS': self.set_NS}[treetype](proxy)
214
5956967b8676
            try:
215
a1c1c555e5ee
                f(self)
216
5956967b8676
            finally:
217
a1c1c555e5ee
                transaction.rollback()
218
5956967b8676
                self.model = None
219
5956967b8676
                self.sorted_model = None
220
5956967b8676
                self.dep_model = None
221
a1c1c555e5ee
        return _testtype
222
5956967b8676
    return decorator
223
5956967b8676
224
cfe76918146d
225
81fa32fd2e26
def _load_test_methods(cls, proxy=True):
226
b943312fad8f
    if proxy and DJANGO_VERSION >= (1, 1):
227
b943312fad8f
        proxyopts = (False, True)
228
b943312fad8f
    else:
229
b943312fad8f
        proxyopts = (False,)
230
a1c1c555e5ee
    for m in dir(cls):
231
a1c1c555e5ee
        if not m.startswith('_multi_'):
232
a1c1c555e5ee
            continue
233
a1c1c555e5ee
        for t in ('MP', 'AL', 'NS'):
234
81fa32fd2e26
            for p in proxyopts:
235
81fa32fd2e26
                deco = testtype(t, p)
236
81fa32fd2e26
                name = 'test_%s%s_%s' % (t.lower(),
237
81fa32fd2e26
                                          '_proxy' if p else '',
238
81fa32fd2e26
                                          m.split('_', 2)[2])
239
81fa32fd2e26
                setattr(cls, name, deco(getattr(cls, m)))
240
a1c1c555e5ee
241
a1c1c555e5ee
242
c59b969c4100
class TestTreeBase(TestCase):
243
c59b969c4100
244
c59b969c4100
    def setUp(self):
245
5956967b8676
        self.set_MP()
246
ac1ecbb55c06
        self.unchanged = [(u'1', 1, 0),
247
ac1ecbb55c06
                          (u'2', 1, 4),
248
ac1ecbb55c06
                          (u'21', 2, 0),
249
ac1ecbb55c06
                          (u'22', 2, 0),
250
ac1ecbb55c06
                          (u'23', 2, 1),
251
ac1ecbb55c06
                          (u'231', 3, 0),
252
ac1ecbb55c06
                          (u'24', 2, 0),
253
ac1ecbb55c06
                          (u'3', 1, 0),
254
ac1ecbb55c06
                          (u'4', 1, 1),
255
ac1ecbb55c06
                          (u'41', 2, 0)]
256
c59b969c4100
257
81fa32fd2e26
    def set_MP(self, proxy=False):
258
b943312fad8f
        if proxy and DJANGO_VERSION >= (1, 1):
259
b943312fad8f
            self.model = MP_TestNode_Proxy
260
b943312fad8f
        else:
261
b943312fad8f
            self.model = MP_TestNode
262
5956967b8676
        self.sorted_model = MP_TestNodeSorted
263
5956967b8676
        self.dep_model = MP_TestNodeSomeDep
264
5ce21f964dd8
265
81fa32fd2e26
    def set_NS(self, proxy=False):
266
b943312fad8f
        if proxy and DJANGO_VERSION >= (1, 1):
267
b943312fad8f
            self.model = NS_TestNode_Proxy
268
b943312fad8f
        else:
269
b943312fad8f
            self.model = NS_TestNode
270
032b45fe0bd4
        self.sorted_model = NS_TestNodeSorted
271
032b45fe0bd4
        self.dep_model = NS_TestNodeSomeDep
272
5956967b8676
273
81fa32fd2e26
    def set_AL(self, proxy=False):
274
b943312fad8f
        if proxy and DJANGO_VERSION >= (1, 1):
275
b943312fad8f
            self.model = AL_TestNode_Proxy
276
b943312fad8f
        else:
277
b943312fad8f
            self.model = AL_TestNode
278
c1e2edeb3b9e
        self.sorted_model = AL_TestNodeSorted
279
c1e2edeb3b9e
        self.dep_model = AL_TestNodeSomeDep
280
c1e2edeb3b9e
281
ac1ecbb55c06
    def got(self):
282
b943312fad8f
        nsmodels = [NS_TestNode]
283
b943312fad8f
        if DJANGO_VERSION >= (1, 1):
284
b943312fad8f
            nsmodels.append(NS_TestNode_Proxy)
285
b943312fad8f
        if self.model in nsmodels:
286
032b45fe0bd4
            # this slows down nested sets tests quite a bit, but it has the
287
032b45fe0bd4
            # advantage that we'll check the node edges are correct
288
032b45fe0bd4
            d = {}
289
5ce21f964dd8
            for tree_id, lft, rgt in self.model.objects.values_list('tree_id',
290
5ce21f964dd8
                                                                    'lft',
291
5ce21f964dd8
                                                                    'rgt'):
292
032b45fe0bd4
                d.setdefault(tree_id, []).extend([lft, rgt])
293
032b45fe0bd4
            for tree_id, got_edges in d.items():
294
032b45fe0bd4
                self.assertEqual(len(got_edges), max(got_edges))
295
66a6725a50c1
                good_edges = range(1, len(got_edges) + 1)
296
032b45fe0bd4
                self.assertEqual(sorted(got_edges), good_edges)
297
032b45fe0bd4
298
5956967b8676
        return [(o.desc, o.get_depth(), o.get_children_count())
299
5956967b8676
                for o in self.model.get_tree()]
300
c59b969c4100
301
6e740b76775d
    def _assert_get_annotated_list(self, expected, parent=None):
302
6e740b76775d
        got = [
303
6e740b76775d
            (obj[0].desc, obj[1]['open'], obj[1]['close'], obj[1]['level'])
304
6e740b76775d
            for obj in self.model.get_annotated_list(parent)]
305
6e740b76775d
        self.assertEqual(expected, got)
306
6e740b76775d
307
c59b969c4100
308
c59b969c4100
class TestEmptyTree(TestTreeBase):
309
c59b969c4100
310
a1c1c555e5ee
    def _multi_load_bulk_empty(self):
311
af911c482a44
        ids = self.model.load_bulk(BASE_DATA)
312
af911c482a44
        got_descs = [obj.desc
313
af911c482a44
                     for obj in self.model.objects.filter(id__in=ids)]
314
ac1ecbb55c06
        expected_descs = [x[0] for x in self.unchanged]
315
ac1ecbb55c06
        self.assertEqual(sorted(got_descs), sorted(expected_descs))
316
c59b969c4100
        self.assertEqual(self.got(), self.unchanged)
317
c59b969c4100
318
a1c1c555e5ee
    def _multi_dump_bulk_empty(self):
319
af911c482a44
        self.assertEqual(self.model.dump_bulk(), [])
320
d6711a31e14f
321
a1c1c555e5ee
    def _multi_add_root_empty(self):
322
fafdcac71620
        self.model.add_root(desc='1')
323
ac1ecbb55c06
        expected = [(u'1', 1, 0)]
324
c59b969c4100
        self.assertEqual(self.got(), expected)
325
c59b969c4100
326
a1c1c555e5ee
    def _multi_get_root_nodes_empty(self):
327
af911c482a44
        got = self.model.get_root_nodes()
328
c59b969c4100
        expected = []
329
a39c4f341471
        self.assertEqual([node.desc for node in got], expected)
330
c59b969c4100
331
a1c1c555e5ee
    def _multi_get_first_root_node_empty(self):
332
af911c482a44
        got = self.model.get_first_root_node()
333
c59b969c4100
        self.assertEqual(got, None)
334
c59b969c4100
335
a1c1c555e5ee
    def _multi_get_last_root_node_empty(self):
336
af911c482a44
        got = self.model.get_last_root_node()
337
c59b969c4100
        self.assertEqual(got, None)
338
c59b969c4100
339
a1c1c555e5ee
    def _multi_get_tree(self):
340
c1e2edeb3b9e
        got = list(self.model.get_tree())
341
c1e2edeb3b9e
        self.assertEqual(got, [])
342
c1e2edeb3b9e
343
a1c1c555e5ee
    def _multi_get_annotated_list(self):
344
6e740b76775d
        expected = []
345
6e740b76775d
        self._assert_get_annotated_list(expected)
346
6e740b76775d
347
c1e2edeb3b9e
348
c59b969c4100
class TestNonEmptyTree(TestTreeBase):
349
c59b969c4100
350
c59b969c4100
    def setUp(self):
351
c59b969c4100
        super(TestNonEmptyTree, self).setUp()
352
5956967b8676
        MP_TestNode.load_bulk(BASE_DATA)
353
c1e2edeb3b9e
        AL_TestNode.load_bulk(BASE_DATA)
354
032b45fe0bd4
        NS_TestNode.load_bulk(BASE_DATA)
355
c59b969c4100
356
c59b969c4100
357
5956967b8676
class TestClassMethods(TestNonEmptyTree):
358
c59b969c4100
359
c59b969c4100
    def setUp(self):
360
5956967b8676
        super(TestClassMethods, self).setUp()
361
c59b969c4100
362
a1c1c555e5ee
    def _multi_load_bulk_existing(self):
363
c59b969c4100
364
c59b969c4100
        # inserting on an existing node
365
c59b969c4100
366
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
367
032b45fe0bd4
        ids = self.model.load_bulk(BASE_DATA, node)
368
ac1ecbb55c06
        expected = [(u'1', 1, 0),
369
ac1ecbb55c06
                    (u'2', 1, 4),
370
ac1ecbb55c06
                    (u'21', 2, 0),
371
ac1ecbb55c06
                    (u'22', 2, 0),
372
ac1ecbb55c06
                    (u'23', 2, 1),
373
ac1ecbb55c06
                    (u'231', 3, 4),
374
ac1ecbb55c06
                    (u'1', 4, 0),
375
ac1ecbb55c06
                    (u'2', 4, 4),
376
ac1ecbb55c06
                    (u'21', 5, 0),
377
ac1ecbb55c06
                    (u'22', 5, 0),
378
ac1ecbb55c06
                    (u'23', 5, 1),
379
ac1ecbb55c06
                    (u'231', 6, 0),
380
ac1ecbb55c06
                    (u'24', 5, 0),
381
ac1ecbb55c06
                    (u'3', 4, 0),
382
ac1ecbb55c06
                    (u'4', 4, 1),
383
ac1ecbb55c06
                    (u'41', 5, 0),
384
ac1ecbb55c06
                    (u'24', 2, 0),
385
ac1ecbb55c06
                    (u'3', 1, 0),
386
ac1ecbb55c06
                    (u'4', 1, 1),
387
ac1ecbb55c06
                    (u'41', 2, 0)]
388
5ce21f964dd8
        expected_descs = [u'1', u'2', u'21', u'22', u'23', u'231', u'24',
389
5ce21f964dd8
                          u'3', u'4', u'41']
390
af911c482a44
        got_descs = [obj.desc
391
af911c482a44
                     for obj in self.model.objects.filter(id__in=ids)]
392
ac1ecbb55c06
        self.assertEqual(sorted(got_descs), sorted(expected_descs))
393
c59b969c4100
        self.assertEqual(self.got(), expected)
394
c59b969c4100
395
a1c1c555e5ee
    def _multi_get_tree_all(self):
396
c1e2edeb3b9e
        got = [(o.desc, o.get_depth(), o.get_children_count())
397
c1e2edeb3b9e
                for o in self.model.get_tree()]
398
c1e2edeb3b9e
        self.assertEqual(got, self.unchanged)
399
c1e2edeb3b9e
400
a1c1c555e5ee
    def _multi_dump_bulk_all(self):
401
af911c482a44
        self.assertEqual(self.model.dump_bulk(keep_ids=False), BASE_DATA)
402
d6711a31e14f
403
a1c1c555e5ee
    def _multi_get_tree_node(self):
404
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
405
032b45fe0bd4
        self.model.load_bulk(BASE_DATA, node)
406
032b45fe0bd4
407
c6d9e339d6bb
        # the tree was modified by load_bulk, so we reload our node object
408
c6d9e339d6bb
        node = self.model.objects.get(pk=node.id)
409
032b45fe0bd4
410
c1e2edeb3b9e
        got = [(o.desc, o.get_depth(), o.get_children_count())
411
032b45fe0bd4
                for o in self.model.get_tree(node)]
412
c1e2edeb3b9e
        expected = [(u'231', 3, 4),
413
c1e2edeb3b9e
                    (u'1', 4, 0),
414
c1e2edeb3b9e
                    (u'2', 4, 4),
415
c1e2edeb3b9e
                    (u'21', 5, 0),
416
c1e2edeb3b9e
                    (u'22', 5, 0),
417
c1e2edeb3b9e
                    (u'23', 5, 1),
418
c1e2edeb3b9e
                    (u'231', 6, 0),
419
c1e2edeb3b9e
                    (u'24', 5, 0),
420
c1e2edeb3b9e
                    (u'3', 4, 0),
421
c1e2edeb3b9e
                    (u'4', 4, 1),
422
c1e2edeb3b9e
                    (u'41', 5, 0)]
423
c1e2edeb3b9e
        self.assertEqual(got, expected)
424
c1e2edeb3b9e
425
a1c1c555e5ee
    def _multi_get_tree_leaf(self):
426
8655b0025792
        node = self.model.objects.get(desc=u'1')
427
8655b0025792
428
8655b0025792
        self.assertEqual(0, node.get_children_count())
429
8655b0025792
        got = [(o.desc, o.get_depth(), o.get_children_count())
430
8655b0025792
                for o in self.model.get_tree(node)]
431
8655b0025792
        expected = [(u'1', 1, 0)]
432
8655b0025792
        self.assertEqual(got, expected)
433
8655b0025792
434
a1c1c555e5ee
    def _multi_get_annotated_list_all(self):
435
6e740b76775d
        expected = [(u'1', True, [], 0), (u'2', False, [], 0),
436
6e740b76775d
                    (u'21', True, [], 1), (u'22', False, [], 1),
437
6e740b76775d
                    (u'23', False, [], 1), (u'231', True, [0], 2),
438
6e740b76775d
                    (u'24', False, [0], 1), (u'3', False, [], 0),
439
6e740b76775d
                    (u'4', False, [], 0), (u'41', True, [0, 1], 1)]
440
6e740b76775d
        self._assert_get_annotated_list(expected)
441
6e740b76775d
442
a1c1c555e5ee
    def _multi_get_annotated_list_node(self):
443
6e740b76775d
        node = self.model.objects.get(desc=u'2')
444
6e740b76775d
        expected = [(u'2', True, [], 0), (u'21', True, [], 1),
445
6e740b76775d
                    (u'22', False, [], 1), (u'23', False, [], 1),
446
6e740b76775d
                    (u'231', True, [0], 2), (u'24', False, [0, 1], 1)]
447
6e740b76775d
        self._assert_get_annotated_list(expected, node)
448
6e740b76775d
449
a1c1c555e5ee
    def _multi_get_annotated_list_leaf(self):
450
6e740b76775d
        node = self.model.objects.get(desc=u'1')
451
6e740b76775d
        expected = [(u'1', True, [0], 0)]
452
6e740b76775d
        self._assert_get_annotated_list(expected, node)
453
6e740b76775d
454
a1c1c555e5ee
    def _multi_dump_bulk_node(self):
455
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
456
032b45fe0bd4
        self.model.load_bulk(BASE_DATA, node)
457
5ce21f964dd8
458
c6d9e339d6bb
        # the tree was modified by load_bulk, so we reload our node object
459
c6d9e339d6bb
        node = self.model.objects.get(pk=node.id)
460
c1e2edeb3b9e
461
032b45fe0bd4
        got = self.model.dump_bulk(node, False)
462
d6711a31e14f
        expected = [{'data':{'desc':u'231'}, 'children':BASE_DATA}]
463
c1e2edeb3b9e
        self.assertEqual(got, expected)
464
e570e2483a41
465
a1c1c555e5ee
    def _multi_load_and_dump_bulk_keeping_ids(self):
466
af911c482a44
        exp = self.model.dump_bulk(keep_ids=True)
467
af911c482a44
        self.model.objects.all().delete()
468
af911c482a44
        self.model.load_bulk(exp, None, True)
469
af911c482a44
        got = self.model.dump_bulk(keep_ids=True)
470
e570e2483a41
        self.assertEqual(got, exp)
471
81fa32fd2e26
        # do we really have an unchaged tree after the dump/delete/load?
472
81fa32fd2e26
        got = [(o.desc, o.get_depth(), o.get_children_count())
473
81fa32fd2e26
                for o in self.model.get_tree()]
474
81fa32fd2e26
        self.assertEqual(got, self.unchanged)
475
e570e2483a41
476
a1c1c555e5ee
    def _multi_get_root_nodes(self):
477
af911c482a44
        got = self.model.get_root_nodes()
478
ac1ecbb55c06
        expected = ['1', '2', '3', '4']
479
ac1ecbb55c06
        self.assertEqual([node.desc for node in got], expected)
480
ac1ecbb55c06
481
a1c1c555e5ee
    def _multi_get_first_root_node(self):
482
af911c482a44
        got = self.model.get_first_root_node()
483
ac1ecbb55c06
        self.assertEqual(got.desc, '1')
484
ac1ecbb55c06
485
a1c1c555e5ee
    def _multi_get_last_root_node(self):
486
af911c482a44
        got = self.model.get_last_root_node()
487
ac1ecbb55c06
        self.assertEqual(got.desc, '4')
488
ac1ecbb55c06
489
a1c1c555e5ee
    def _multi_add_root(self):
490
5956967b8676
        obj = self.model.add_root(desc='5')
491
5956967b8676
        self.assertEqual(obj.get_depth(), 1)
492
5956967b8676
        self.assertEqual(self.model.get_last_root_node().desc, '5')
493
c59b969c4100
494
c59b969c4100
495
c59b969c4100
class TestSimpleNodeMethods(TestNonEmptyTree):
496
c59b969c4100
497
a1c1c555e5ee
    def _multi_is_root(self):
498
c1e2edeb3b9e
        data = [
499
c1e2edeb3b9e
            ('2', True),
500
c1e2edeb3b9e
            ('1', True),
501
c1e2edeb3b9e
            ('4', True),
502
c1e2edeb3b9e
            ('21', False),
503
c1e2edeb3b9e
            ('24', False),
504
c1e2edeb3b9e
            ('22', False),
505
c1e2edeb3b9e
            ('231', False),
506
c1e2edeb3b9e
        ]
507
c1e2edeb3b9e
        for desc, expected in data:
508
c1e2edeb3b9e
            got = self.model.objects.get(desc=desc).is_root()
509
c1e2edeb3b9e
            self.assertEqual(got, expected)
510
c1e2edeb3b9e
511
a1c1c555e5ee
    def _multi_is_leaf(self):
512
c1e2edeb3b9e
        data = [
513
c1e2edeb3b9e
            ('2', False),
514
c1e2edeb3b9e
            ('23', False),
515
c1e2edeb3b9e
            ('231', True),
516
c1e2edeb3b9e
        ]
517
c1e2edeb3b9e
        for desc, expected in data:
518
c1e2edeb3b9e
            got = self.model.objects.get(desc=desc).is_leaf()
519
c1e2edeb3b9e
            self.assertEqual(got, expected)
520
c1e2edeb3b9e
521
a1c1c555e5ee
    def _multi_get_root(self):
522
c59b969c4100
        data = [
523
ac1ecbb55c06
            ('2', '2'),
524
ac1ecbb55c06
            ('1', '1'),
525
ac1ecbb55c06
            ('4', '4'),
526
ac1ecbb55c06
            ('21', '2'),
527
ac1ecbb55c06
            ('24', '2'),
528
ac1ecbb55c06
            ('22', '2'),
529
ac1ecbb55c06
            ('231', '2'),
530
c59b969c4100
        ]
531
ac1ecbb55c06
        for desc, expected in data:
532
5956967b8676
            node = self.model.objects.get(desc=desc).get_root()
533
ac1ecbb55c06
            self.assertEqual(node.desc, expected)
534
c59b969c4100
535
a1c1c555e5ee
    def _multi_get_parent(self):
536
bf04b808ddb1
        data = [
537
ac1ecbb55c06
            ('2', None),
538
ac1ecbb55c06
            ('1', None),
539
ac1ecbb55c06
            ('4', None),
540
ac1ecbb55c06
            ('21', '2'),
541
ac1ecbb55c06
            ('24', '2'),
542
ac1ecbb55c06
            ('22', '2'),
543
ac1ecbb55c06
            ('231', '23'),
544
bf04b808ddb1
        ]
545
bf04b808ddb1
        data = dict(data)
546
bf04b808ddb1
        objs = {}
547
ac1ecbb55c06
        for desc, expected in data.items():
548
5956967b8676
            node = self.model.objects.get(desc=desc)
549
bf04b808ddb1
            parent = node.get_parent()
550
bf04b808ddb1
            if expected:
551
ac1ecbb55c06
                self.assertEqual(parent.desc, expected)
552
bf04b808ddb1
            else:
553
bf04b808ddb1
                self.assertEqual(parent, None)
554
ac1ecbb55c06
            objs[desc] = node
555
bf04b808ddb1
            # corrupt the objects' parent cache
556
bf04b808ddb1
            node._parent_obj = 'CORRUPTED!!!'
557
bf04b808ddb1
558
ac1ecbb55c06
        for desc, expected in data.items():
559
ac1ecbb55c06
            node = objs[desc]
560
5ce21f964dd8
            # asking get_parent to not use the parent cache (since we
561
5ce21f964dd8
            # corrupted it in the previous loop)
562
bf04b808ddb1
            parent = node.get_parent(True)
563
bf04b808ddb1
            if expected:
564
ac1ecbb55c06
                self.assertEqual(parent.desc, expected)
565
bf04b808ddb1
            else:
566
bf04b808ddb1
                self.assertEqual(parent, None)
567
bf04b808ddb1
568
a1c1c555e5ee
    def _multi_get_children(self):
569
c59b969c4100
        data = [
570
ac1ecbb55c06
            ('2', ['21', '22', '23', '24']),
571
ac1ecbb55c06
            ('23', ['231']),
572
ac1ecbb55c06
            ('231', []),
573
c59b969c4100
        ]
574
ac1ecbb55c06
        for desc, expected in data:
575
5956967b8676
            children = self.model.objects.get(desc=desc).get_children()
576
ac1ecbb55c06
            self.assertEqual([node.desc for node in children], expected)
577
c59b969c4100
578
a1c1c555e5ee
    def _multi_get_children_count(self):
579
5956967b8676
        data = [
580
5956967b8676
            ('2', 4),
581
5956967b8676
            ('23', 1),
582
5956967b8676
            ('231', 0),
583
5956967b8676
        ]
584
5956967b8676
        for desc, expected in data:
585
5956967b8676
            got = self.model.objects.get(desc=desc).get_children_count()
586
5956967b8676
            self.assertEqual(got, expected)
587
c59b969c4100
588
a1c1c555e5ee
    def _multi_get_siblings(self):
589
c59b969c4100
        data = [
590
ac1ecbb55c06
            ('2', ['1', '2', '3', '4']),
591
ac1ecbb55c06
            ('21', ['21', '22', '23', '24']),
592
ac1ecbb55c06
            ('231', ['231']),
593
c59b969c4100
        ]
594
ac1ecbb55c06
        for desc, expected in data:
595
5956967b8676
            siblings = self.model.objects.get(desc=desc).get_siblings()
596
ac1ecbb55c06
            self.assertEqual([node.desc for node in siblings], expected)
597
c59b969c4100
598
a1c1c555e5ee
    def _multi_get_first_sibling(self):
599
c59b969c4100
        data = [
600
ac1ecbb55c06
            ('2', '1'),
601
ac1ecbb55c06
            ('1', '1'),
602
ac1ecbb55c06
            ('4', '1'),
603
ac1ecbb55c06
            ('21', '21'),
604
ac1ecbb55c06
            ('24', '21'),
605
ac1ecbb55c06
            ('22', '21'),
606
ac1ecbb55c06
            ('231', '231'),
607
c59b969c4100
        ]
608
ac1ecbb55c06
        for desc, expected in data:
609
5956967b8676
            node = self.model.objects.get(desc=desc).get_first_sibling()
610
ac1ecbb55c06
            self.assertEqual(node.desc, expected)
611
c59b969c4100
612
a1c1c555e5ee
    def _multi_get_prev_sibling(self):
613
c59b969c4100
        data = [
614
ac1ecbb55c06
            ('2', '1'),
615
ac1ecbb55c06
            ('1', None),
616
ac1ecbb55c06
            ('4', '3'),
617
ac1ecbb55c06
            ('21', None),
618
ac1ecbb55c06
            ('24', '23'),
619
ac1ecbb55c06
            ('22', '21'),
620
ac1ecbb55c06
            ('231', None),
621
c59b969c4100
        ]
622
ac1ecbb55c06
        for desc, expected in data:
623
5956967b8676
            node = self.model.objects.get(desc=desc).get_prev_sibling()
624
c59b969c4100
            if expected is None:
625
c59b969c4100
                self.assertEqual(node, None)
626
c59b969c4100
            else:
627
ac1ecbb55c06
                self.assertEqual(node.desc, expected)
628
5ce21f964dd8
629
a1c1c555e5ee
    def _multi_get_next_sibling(self):
630
c59b969c4100
        data = [
631
ac1ecbb55c06
            ('2', '3'),
632
ac1ecbb55c06
            ('1', '2'),
633
ac1ecbb55c06
            ('4', None),
634
ac1ecbb55c06
            ('21', '22'),
635
ac1ecbb55c06
            ('24', None),
636
ac1ecbb55c06
            ('22', '23'),
637
ac1ecbb55c06
            ('231', None),
638
c59b969c4100
        ]
639
ac1ecbb55c06
        for desc, expected in data:
640
5956967b8676
            node = self.model.objects.get(desc=desc).get_next_sibling()
641
c59b969c4100
            if expected is None:
642
c59b969c4100
                self.assertEqual(node, None)
643
c59b969c4100
            else:
644
ac1ecbb55c06
                self.assertEqual(node.desc, expected)
645
c59b969c4100
646
a1c1c555e5ee
    def _multi_get_last_sibling(self):
647
c59b969c4100
        data = [
648
ac1ecbb55c06
            ('2', '4'),
649
ac1ecbb55c06
            ('1', '4'),
650
ac1ecbb55c06
            ('4', '4'),
651
ac1ecbb55c06
            ('21', '24'),
652
ac1ecbb55c06
            ('24', '24'),
653
ac1ecbb55c06
            ('22', '24'),
654
ac1ecbb55c06
            ('231', '231'),
655
c59b969c4100
        ]
656
ac1ecbb55c06
        for desc, expected in data:
657
5956967b8676
            node = self.model.objects.get(desc=desc).get_last_sibling()
658
ac1ecbb55c06
            self.assertEqual(node.desc, expected)
659
c59b969c4100
660
a1c1c555e5ee
    def _multi_get_first_child(self):
661
c59b969c4100
        data = [
662
ac1ecbb55c06
            ('2', '21'),
663
ac1ecbb55c06
            ('21', None),
664
ac1ecbb55c06
            ('23', '231'),
665
ac1ecbb55c06
            ('231', None),
666
c59b969c4100
        ]
667
ac1ecbb55c06
        for desc, expected in data:
668
5956967b8676
            node = self.model.objects.get(desc=desc).get_first_child()
669
c59b969c4100
            if expected is None:
670
c59b969c4100
                self.assertEqual(node, None)
671
c59b969c4100
            else:
672
ac1ecbb55c06
                self.assertEqual(node.desc, expected)
673
c59b969c4100
674
a1c1c555e5ee
    def _multi_get_last_child(self):
675
c59b969c4100
        data = [
676
ac1ecbb55c06
            ('2', '24'),
677
ac1ecbb55c06
            ('21', None),
678
ac1ecbb55c06
            ('23', '231'),
679
ac1ecbb55c06
            ('231', None),
680
c59b969c4100
        ]
681
ac1ecbb55c06
        for desc, expected in data:
682
5956967b8676
            node = self.model.objects.get(desc=desc).get_last_child()
683
c59b969c4100
            if expected is None:
684
c59b969c4100
                self.assertEqual(node, None)
685
c59b969c4100
            else:
686
ac1ecbb55c06
                self.assertEqual(node.desc, expected)
687
c59b969c4100
688
a1c1c555e5ee
    def _multi_get_ancestors(self):
689
c59b969c4100
        data = [
690
ac1ecbb55c06
            ('2', []),
691
ac1ecbb55c06
            ('21', ['2']),
692
ac1ecbb55c06
            ('231', ['2', '23']),
693
c59b969c4100
        ]
694
ac1ecbb55c06
        for desc, expected in data:
695
5956967b8676
            nodes = self.model.objects.get(desc=desc).get_ancestors()
696
ac1ecbb55c06
            self.assertEqual([node.desc for node in nodes], expected)
697
c59b969c4100
698
a1c1c555e5ee
    def _multi_get_descendants(self):
699
c59b969c4100
        data = [
700
ac1ecbb55c06
            ('2', ['21', '22', '23', '231', '24']),
701
ac1ecbb55c06
            ('23', ['231']),
702
ac1ecbb55c06
            ('231', []),
703
ac1ecbb55c06
            ('1', []),
704
ac1ecbb55c06
            ('4', ['41']),
705
c59b969c4100
        ]
706
ac1ecbb55c06
        for desc, expected in data:
707
5956967b8676
            nodes = self.model.objects.get(desc=desc).get_descendants()
708
ac1ecbb55c06
            self.assertEqual([node.desc for node in nodes], expected)
709
c59b969c4100
710
a1c1c555e5ee
    def _multi_get_descendant_count(self):
711
5956967b8676
        data = [
712
5956967b8676
            ('2', 5),
713
5956967b8676
            ('23', 1),
714
5956967b8676
            ('231', 0),
715
5956967b8676
            ('1', 0),
716
5956967b8676
            ('4', 1),
717
5956967b8676
        ]
718
5956967b8676
        for desc, expected in data:
719
5956967b8676
            got = self.model.objects.get(desc=desc).get_descendant_count()
720
5956967b8676
            self.assertEqual(got, expected)
721
5956967b8676
722
a1c1c555e5ee
    def _multi_is_sibling_of(self):
723
c59b969c4100
        data = [
724
ac1ecbb55c06
            ('2', '2', True),
725
ac1ecbb55c06
            ('2', '1', True),
726
ac1ecbb55c06
            ('21', '2', False),
727
ac1ecbb55c06
            ('231', '2', False),
728
ac1ecbb55c06
            ('22', '23', True),
729
ac1ecbb55c06
            ('231', '23', False),
730
ac1ecbb55c06
            ('231', '231', True),
731
c59b969c4100
        ]
732
ac1ecbb55c06
        for desc1, desc2, expected in data:
733
5956967b8676
            node1 = self.model.objects.get(desc=desc1)
734
5956967b8676
            node2 = self.model.objects.get(desc=desc2)
735
c59b969c4100
            self.assertEqual(node1.is_sibling_of(node2), expected)
736
c59b969c4100
737
a1c1c555e5ee
    def _multi_is_child_of(self):
738
c59b969c4100
        data = [
739
ac1ecbb55c06
            ('2', '2', False),
740
ac1ecbb55c06
            ('2', '1', False),
741
ac1ecbb55c06
            ('21', '2', True),
742
ac1ecbb55c06
            ('231', '2', False),
743
ac1ecbb55c06
            ('231', '23', True),
744
ac1ecbb55c06
            ('231', '231', False),
745
c59b969c4100
        ]
746
ac1ecbb55c06
        for desc1, desc2, expected in data:
747
5956967b8676
            node1 = self.model.objects.get(desc=desc1)
748
5956967b8676
            node2 = self.model.objects.get(desc=desc2)
749
c59b969c4100
            self.assertEqual(node1.is_child_of(node2), expected)
750
c59b969c4100
751
a1c1c555e5ee
    def _multi_is_descendant_of(self):
752
c59b969c4100
        data = [
753
ac1ecbb55c06
            ('2', '2', False),
754
ac1ecbb55c06
            ('2', '1', False),
755
ac1ecbb55c06
            ('21', '2', True),
756
ac1ecbb55c06
            ('231', '2', True),
757
ac1ecbb55c06
            ('231', '23', True),
758
ac1ecbb55c06
            ('231', '231', False),
759
c59b969c4100
        ]
760
ac1ecbb55c06
        for desc1, desc2, expected in data:
761
5956967b8676
            node1 = self.model.objects.get(desc=desc1)
762
5956967b8676
            node2 = self.model.objects.get(desc=desc2)
763
c59b969c4100
            self.assertEqual(node1.is_descendant_of(node2), expected)
764
c59b969c4100
765
c59b969c4100
766
c59b969c4100
class TestAddChild(TestNonEmptyTree):
767
c59b969c4100
768
a1c1c555e5ee
    def _multi_add_child_to_leaf(self):
769
fafdcac71620
        self.model.objects.get(desc=u'231').add_child(desc='2311')
770
ac1ecbb55c06
        expected = [(u'1', 1, 0),
771
ac1ecbb55c06
                    (u'2', 1, 4),
772
ac1ecbb55c06
                    (u'21', 2, 0),
773
ac1ecbb55c06
                    (u'22', 2, 0),
774
ac1ecbb55c06
                    (u'23', 2, 1),
775
ac1ecbb55c06
                    (u'231', 3, 1),
776
ac1ecbb55c06
                    (u'2311', 4, 0),
777
ac1ecbb55c06
                    (u'24', 2, 0),
778
ac1ecbb55c06
                    (u'3', 1, 0),
779
ac1ecbb55c06
                    (u'4', 1, 1),
780
ac1ecbb55c06
                    (u'41', 2, 0)]
781
c59b969c4100
        self.assertEqual(self.got(), expected)
782
c59b969c4100
783
a1c1c555e5ee
    def _multi_add_child_to_node(self):
784
fafdcac71620
        self.model.objects.get(desc=u'2').add_child(desc='25')
785
ac1ecbb55c06
        expected = [(u'1', 1, 0),
786
ac1ecbb55c06
                    (u'2', 1, 5),
787
ac1ecbb55c06
                    (u'21', 2, 0),
788
ac1ecbb55c06
                    (u'22', 2, 0),
789
ac1ecbb55c06
                    (u'23', 2, 1),
790
ac1ecbb55c06
                    (u'231', 3, 0),
791
ac1ecbb55c06
                    (u'24', 2, 0),
792
ac1ecbb55c06
                    (u'25', 2, 0),
793
ac1ecbb55c06
                    (u'3', 1, 0),
794
ac1ecbb55c06
                    (u'4', 1, 1),
795
ac1ecbb55c06
                    (u'41', 2, 0)]
796
c59b969c4100
        self.assertEqual(self.got(), expected)
797
c59b969c4100
798
c59b969c4100
799
c59b969c4100
class TestAddSibling(TestNonEmptyTree):
800
c59b969c4100
801
a1c1c555e5ee
    def _multi_add_sibling_invalid_pos(self):
802
5ce21f964dd8
        method = self.model.objects.get(desc=u'231').add_sibling
803
c59b969c4100
        self.assertRaises(InvalidPosition, method, 'invalid_pos')
804
7855e638023a
805
a1c1c555e5ee
    def _multi_add_sibling_missing_nodeorderby(self):
806
5956967b8676
        node_wchildren = self.model.objects.get(desc=u'2')
807
5956967b8676
        method = node_wchildren.add_sibling
808
7855e638023a
        self.assertRaises(MissingNodeOrderBy, method, 'sorted-sibling',
809
7855e638023a
                          desc='aaa')
810
5ce21f964dd8
811
a1c1c555e5ee
    def _multi_add_sibling_last_root(self):
812
5956967b8676
        node_wchildren = self.model.objects.get(desc=u'2')
813
5956967b8676
        obj = node_wchildren.add_sibling('last-sibling', desc='5')
814
5956967b8676
        self.assertEqual(obj.get_depth(), 1)
815
5956967b8676
        self.assertEqual(node_wchildren.get_last_sibling().desc, u'5')
816
c59b969c4100
817
a1c1c555e5ee
    def _multi_add_sibling_last(self):
818
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
819
032b45fe0bd4
        obj = node.add_sibling('last-sibling', desc='232')
820
5956967b8676
        self.assertEqual(obj.get_depth(), 3)
821
032b45fe0bd4
        self.assertEqual(node.get_last_sibling().desc, u'232')
822
c59b969c4100
823
a1c1c555e5ee
    def _multi_add_sibling_first_root(self):
824
5956967b8676
        node_wchildren = self.model.objects.get(desc=u'2')
825
5956967b8676
        obj = node_wchildren.add_sibling('first-sibling', desc='new')
826
5956967b8676
        self.assertEqual(obj.get_depth(), 1)
827
032b45fe0bd4
        expected = [(u'new', 1, 0),
828
ac1ecbb55c06
                    (u'1', 1, 0),
829
ac1ecbb55c06
                    (u'2', 1, 4),
830
ac1ecbb55c06
                    (u'21', 2, 0),
831
ac1ecbb55c06
                    (u'22', 2, 0),
832
ac1ecbb55c06
                    (u'23', 2, 1),
833
ac1ecbb55c06
                    (u'231', 3, 0),
834
ac1ecbb55c06
                    (u'24', 2, 0),
835
ac1ecbb55c06
                    (u'3', 1, 0),
836
ac1ecbb55c06
                    (u'4', 1, 1),
837
ac1ecbb55c06
                    (u'41', 2, 0)]
838
c59b969c4100
        self.assertEqual(self.got(), expected)
839
c59b969c4100
840
a1c1c555e5ee
    def _multi_add_sibling_first(self):
841
032b45fe0bd4
        node_wchildren = self.model.objects.get(desc=u'23')
842
032b45fe0bd4
        obj = node_wchildren.add_sibling('first-sibling', desc='new')
843
032b45fe0bd4
        self.assertEqual(obj.get_depth(), 2)
844
032b45fe0bd4
        expected = [(u'1', 1, 0),
845
032b45fe0bd4
                    (u'2', 1, 5),
846
032b45fe0bd4
                    (u'new', 2, 0),
847
032b45fe0bd4
                    (u'21', 2, 0),
848
032b45fe0bd4
                    (u'22', 2, 0),
849
032b45fe0bd4
                    (u'23', 2, 1),
850
032b45fe0bd4
                    (u'231', 3, 0),
851
032b45fe0bd4
                    (u'24', 2, 0),
852
032b45fe0bd4
                    (u'3', 1, 0),
853
032b45fe0bd4
                    (u'4', 1, 1),
854
032b45fe0bd4
                    (u'41', 2, 0)]
855
032b45fe0bd4
        self.assertEqual(self.got(), expected)
856
032b45fe0bd4
857
a1c1c555e5ee
    def _multi_add_sibling_left_root(self):
858
5956967b8676
        node_wchildren = self.model.objects.get(desc=u'2')
859
5956967b8676
        obj = node_wchildren.add_sibling('left', desc='new')
860
5956967b8676
        self.assertEqual(obj.get_depth(), 1)
861
ac1ecbb55c06
        expected = [(u'1', 1, 0),
862
ac1ecbb55c06
                    (u'new', 1, 0),
863
ac1ecbb55c06
                    (u'2', 1, 4),
864
ac1ecbb55c06
                    (u'21', 2, 0),
865
ac1ecbb55c06
                    (u'22', 2, 0),
866
ac1ecbb55c06
                    (u'23', 2, 1),
867
ac1ecbb55c06
                    (u'231', 3, 0),
868
ac1ecbb55c06
                    (u'24', 2, 0),
869
ac1ecbb55c06
                    (u'3', 1, 0),
870
ac1ecbb55c06
                    (u'4', 1, 1),
871
ac1ecbb55c06
                    (u'41', 2, 0)]
872
c59b969c4100
        self.assertEqual(self.got(), expected)
873
c59b969c4100
874
a1c1c555e5ee
    def _multi_add_sibling_left(self):
875
032b45fe0bd4
        node_wchildren = self.model.objects.get(desc=u'23')
876
032b45fe0bd4
        obj = node_wchildren.add_sibling('left', desc='new')
877
032b45fe0bd4
        self.assertEqual(obj.get_depth(), 2)
878
032b45fe0bd4
        expected = [(u'1', 1, 0),
879
032b45fe0bd4
                    (u'2', 1, 5),
880
032b45fe0bd4
                    (u'21', 2, 0),
881
032b45fe0bd4
                    (u'22', 2, 0),
882
032b45fe0bd4
                    (u'new', 2, 0),
883
032b45fe0bd4
                    (u'23', 2, 1),
884
032b45fe0bd4
                    (u'231', 3, 0),
885
032b45fe0bd4
                    (u'24', 2, 0),
886
032b45fe0bd4
                    (u'3', 1, 0),
887
032b45fe0bd4
                    (u'4', 1, 1),
888
032b45fe0bd4
                    (u'41', 2, 0)]
889
032b45fe0bd4
        self.assertEqual(self.got(), expected)
890
032b45fe0bd4
891
a1c1c555e5ee
    def _multi_add_sibling_left_noleft_root(self):
892
032b45fe0bd4
        node = self.model.objects.get(desc=u'1')
893
032b45fe0bd4
        obj = node.add_sibling('left', desc='new')
894
032b45fe0bd4
        self.assertEqual(obj.get_depth(), 1)
895
032b45fe0bd4
        expected = [(u'new', 1, 0),
896
032b45fe0bd4
                    (u'1', 1, 0),
897
032b45fe0bd4
                    (u'2', 1, 4),
898
032b45fe0bd4
                    (u'21', 2, 0),
899
032b45fe0bd4
                    (u'22', 2, 0),
900
032b45fe0bd4
                    (u'23', 2, 1),
901
032b45fe0bd4
                    (u'231', 3, 0),
902
032b45fe0bd4
                    (u'24', 2, 0),
903
032b45fe0bd4
                    (u'3', 1, 0),
904
032b45fe0bd4
                    (u'4', 1, 1),
905
032b45fe0bd4
                    (u'41', 2, 0)]
906
032b45fe0bd4
        self.assertEqual(self.got(), expected)
907
032b45fe0bd4
908
a1c1c555e5ee
    def _multi_add_sibling_left_noleft(self):
909
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
910
032b45fe0bd4
        obj = node.add_sibling('left', desc='new')
911
5956967b8676
        self.assertEqual(obj.get_depth(), 3)
912
ac1ecbb55c06
        expected = [(u'1', 1, 0),
913
ac1ecbb55c06
                    (u'2', 1, 4),
914
ac1ecbb55c06
                    (u'21', 2, 0),
915
ac1ecbb55c06
                    (u'22', 2, 0),
916
ac1ecbb55c06
                    (u'23', 2, 2),
917
ac1ecbb55c06
                    (u'new', 3, 0),
918
ac1ecbb55c06
                    (u'231', 3, 0),
919
ac1ecbb55c06
                    (u'24', 2, 0),
920
ac1ecbb55c06
                    (u'3', 1, 0),
921
ac1ecbb55c06
                    (u'4', 1, 1),
922
ac1ecbb55c06
                    (u'41', 2, 0)]
923
c59b969c4100
        self.assertEqual(self.got(), expected)
924
c59b969c4100
925
a1c1c555e5ee
    def _multi_add_sibling_right_root(self):
926
5956967b8676
        node_wchildren = self.model.objects.get(desc=u'2')
927
5956967b8676
        obj = node_wchildren.add_sibling('right', desc='new')
928
5956967b8676
        self.assertEqual(obj.get_depth(), 1)
929
ac1ecbb55c06
        expected = [(u'1', 1, 0),
930
ac1ecbb55c06
                    (u'2', 1, 4),
931
ac1ecbb55c06
                    (u'21', 2, 0),
932
ac1ecbb55c06
                    (u'22', 2, 0),
933
ac1ecbb55c06
                    (u'23', 2, 1),
934
ac1ecbb55c06
                    (u'231', 3, 0),
935
ac1ecbb55c06
                    (u'24', 2, 0),
936
ac1ecbb55c06
                    (u'new', 1, 0),
937
ac1ecbb55c06
                    (u'3', 1, 0),
938
ac1ecbb55c06
                    (u'4', 1, 1),
939
ac1ecbb55c06
                    (u'41', 2, 0)]
940
c59b969c4100
        self.assertEqual(self.got(), expected)
941
c59b969c4100
942
a1c1c555e5ee
    def _multi_add_sibling_right(self):
943
032b45fe0bd4
        node_wchildren = self.model.objects.get(desc=u'23')
944
032b45fe0bd4
        obj = node_wchildren.add_sibling('right', desc='new')
945
032b45fe0bd4
        self.assertEqual(obj.get_depth(), 2)
946
032b45fe0bd4
        expected = [(u'1', 1, 0),
947
032b45fe0bd4
                    (u'2', 1, 5),
948
032b45fe0bd4
                    (u'21', 2, 0),
949
032b45fe0bd4
                    (u'22', 2, 0),
950
032b45fe0bd4
                    (u'23', 2, 1),
951
032b45fe0bd4
                    (u'231', 3, 0),
952
032b45fe0bd4
                    (u'new', 2, 0),
953
032b45fe0bd4
                    (u'24', 2, 0),
954
032b45fe0bd4
                    (u'3', 1, 0),
955
032b45fe0bd4
                    (u'4', 1, 1),
956
032b45fe0bd4
                    (u'41', 2, 0)]
957
032b45fe0bd4
        self.assertEqual(self.got(), expected)
958
032b45fe0bd4
959
a1c1c555e5ee
    def _multi_add_sibling_right_noright_root(self):
960
032b45fe0bd4
        node = self.model.objects.get(desc=u'4')
961
032b45fe0bd4
        obj = node.add_sibling('right', desc='new')
962
032b45fe0bd4
        self.assertEqual(obj.get_depth(), 1)
963
032b45fe0bd4
        expected = [(u'1', 1, 0),
964
032b45fe0bd4
                    (u'2', 1, 4),
965
032b45fe0bd4
                    (u'21', 2, 0),
966
032b45fe0bd4
                    (u'22', 2, 0),
967
032b45fe0bd4
                    (u'23', 2, 1),
968
032b45fe0bd4
                    (u'231', 3, 0),
969
032b45fe0bd4
                    (u'24', 2, 0),
970
032b45fe0bd4
                    (u'3', 1, 0),
971
032b45fe0bd4
                    (u'4', 1, 1),
972
032b45fe0bd4
                    (u'41', 2, 0),
973
032b45fe0bd4
                    (u'new', 1, 0)]
974
032b45fe0bd4
        self.assertEqual(self.got(), expected)
975
032b45fe0bd4
976
a1c1c555e5ee
    def _multi_add_sibling_right_noright(self):
977
032b45fe0bd4
        node = self.model.objects.get(desc=u'231')
978
032b45fe0bd4
        obj = node.add_sibling('right', desc='new')
979
5956967b8676
        self.assertEqual(obj.get_depth(), 3)
980
ac1ecbb55c06
        expected = [(u'1', 1, 0),
981
ac1ecbb55c06
                    (u'2', 1, 4),
982
ac1ecbb55c06
                    (u'21', 2, 0),
983
ac1ecbb55c06
                    (u'22', 2, 0),
984
ac1ecbb55c06
                    (u'23', 2, 2),
985
ac1ecbb55c06
                    (u'231', 3, 0),
986
ac1ecbb55c06
                    (u'new', 3, 0),
987
ac1ecbb55c06
                    (u'24', 2, 0),
988
ac1ecbb55c06
                    (u'3', 1, 0),
989
ac1ecbb55c06
                    (u'4', 1, 1),
990
ac1ecbb55c06
                    (u'41', 2, 0)]
991
c59b969c4100
        self.assertEqual(self.got(), expected)
992
c59b969c4100
993
c59b969c4100
994
c59b969c4100
class TestDelete(TestNonEmptyTree):
995
c59b969c4100
996
e570e2483a41
    def setUp(self):
997
e570e2483a41
        super(TestDelete, self).setUp()
998
5956967b8676
        for node in self.model.objects.all():
999
5956967b8676
            self.dep_model(node=node).save()
1000
e570e2483a41
1001
a1c1c555e5ee
    def _multi_delete_leaf(self):
1002
5956967b8676
        self.model.objects.get(desc=u'231').delete()
1003
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1004
ac1ecbb55c06
                    (u'2', 1, 4),
1005
ac1ecbb55c06
                    (u'21', 2, 0),
1006
ac1ecbb55c06
                    (u'22', 2, 0),
1007
ac1ecbb55c06
                    (u'23', 2, 0),
1008
ac1ecbb55c06
                    (u'24', 2, 0),
1009
ac1ecbb55c06
                    (u'3', 1, 0),
1010
ac1ecbb55c06
                    (u'4', 1, 1),
1011
ac1ecbb55c06
                    (u'41', 2, 0)]
1012
c59b969c4100
        self.assertEqual(self.got(), expected)
1013
c59b969c4100
1014
a1c1c555e5ee
    def _multi_delete_node(self):
1015
5956967b8676
        self.model.objects.get(desc=u'23').delete()
1016
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1017
ac1ecbb55c06
                    (u'2', 1, 3),
1018
ac1ecbb55c06
                    (u'21', 2, 0),
1019
ac1ecbb55c06
                    (u'22', 2, 0),
1020
ac1ecbb55c06
                    (u'24', 2, 0),
1021
ac1ecbb55c06
                    (u'3', 1, 0),
1022
ac1ecbb55c06
                    (u'4', 1, 1),
1023
ac1ecbb55c06
                    (u'41', 2, 0)]
1024
c59b969c4100
        self.assertEqual(self.got(), expected)
1025
c59b969c4100
1026
a1c1c555e5ee
    def _multi_delete_root(self):
1027
5956967b8676
        self.model.objects.get(desc=u'2').delete()
1028
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1029
ac1ecbb55c06
                    (u'3', 1, 0),
1030
ac1ecbb55c06
                    (u'4', 1, 1),
1031
ac1ecbb55c06
                    (u'41', 2, 0)]
1032
c59b969c4100
        self.assertEqual(self.got(), expected)
1033
c59b969c4100
1034
a1c1c555e5ee
    def _multi_delete_filter_root_nodes(self):
1035
5956967b8676
        self.model.objects.filter(desc__in=('2', '3')).delete()
1036
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1037
ac1ecbb55c06
                    (u'4', 1, 1),
1038
ac1ecbb55c06
                    (u'41', 2, 0)]
1039
c59b969c4100
        self.assertEqual(self.got(), expected)
1040
c59b969c4100
1041
a1c1c555e5ee
    def _multi_delete_filter_children(self):
1042
5956967b8676
        self.model.objects.filter(
1043
ac1ecbb55c06
            desc__in=('2', '23', '231')).delete()
1044
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1045
ac1ecbb55c06
                    (u'3', 1, 0),
1046
ac1ecbb55c06
                    (u'4', 1, 1),
1047
ac1ecbb55c06
                    (u'41', 2, 0)]
1048
c59b969c4100
        self.assertEqual(self.got(), expected)
1049
c59b969c4100
1050
a1c1c555e5ee
    def _multi_delete_nonexistant_nodes(self):
1051
5956967b8676
        self.model.objects.filter(desc__in=('ZZZ', 'XXX')).delete()
1052
c59b969c4100
        self.assertEqual(self.got(), self.unchanged)
1053
c59b969c4100
1054
a1c1c555e5ee
    def _multi_delete_same_node_twice(self):
1055
5956967b8676
        self.model.objects.filter(
1056
ac1ecbb55c06
            desc__in=('2', '2')).delete()
1057
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1058
ac1ecbb55c06
                    (u'3', 1, 0),
1059
ac1ecbb55c06
                    (u'4', 1, 1),
1060
ac1ecbb55c06
                    (u'41', 2, 0)]
1061
c59b969c4100
        self.assertEqual(self.got(), expected)
1062
c59b969c4100
1063
a1c1c555e5ee
    def _multi_delete_all_root_nodes(self):
1064
5956967b8676
        self.model.get_root_nodes().delete()
1065
5956967b8676
        count = self.model.objects.count()
1066
c59b969c4100
        self.assertEqual(count, 0)
1067
c59b969c4100
1068
a1c1c555e5ee
    def _multi_delete_all_nodes(self):
1069
5956967b8676
        self.model.objects.all().delete()
1070
5956967b8676
        count = self.model.objects.count()
1071
c59b969c4100
        self.assertEqual(count, 0)
1072
c59b969c4100
1073
c59b969c4100
1074
c59b969c4100
class TestMoveErrors(TestNonEmptyTree):
1075
c59b969c4100
1076
a1c1c555e5ee
    def _multi_move_invalid_pos(self):
1077
5956967b8676
        node = self.model.objects.get(desc=u'231')
1078
bf04b808ddb1
        self.assertRaises(InvalidPosition, node.move, node, 'invalid_pos')
1079
c59b969c4100
1080
a1c1c555e5ee
    def _multi_move_to_descendant(self):
1081
5956967b8676
        node = self.model.objects.get(desc=u'2')
1082
5956967b8676
        target = self.model.objects.get(desc=u'231')
1083
bf04b808ddb1
        self.assertRaises(InvalidMoveToDescendant, node.move, target,
1084
bf04b808ddb1
            'first-sibling')
1085
c59b969c4100
1086
a1c1c555e5ee
    def _multi_move_missing_nodeorderby(self):
1087
5956967b8676
        node = self.model.objects.get(desc=u'231')
1088
7855e638023a
        self.assertRaises(MissingNodeOrderBy, node.move, node,
1089
7855e638023a
                          'sorted-child')
1090
7855e638023a
        self.assertRaises(MissingNodeOrderBy, node.move, node,
1091
7855e638023a
                          'sorted-sibling')
1092
7855e638023a
1093
952e3b329377
1094
81fa32fd2e26
class TestMoveSortedErrors(TestNonEmptyTree):
1095
81fa32fd2e26
1096
81fa32fd2e26
    def _multi_nonsorted_move_in_sorted(self):
1097
81fa32fd2e26
        node = self.sorted_model.add_root(val1=3, val2=3, desc='zxy')
1098
81fa32fd2e26
        self.assertRaises(InvalidPosition, node.move, node, 'left')
1099
7855e638023a
1100
952e3b329377
1101
14dd36f8989e
class TestMoveLeafRoot(TestNonEmptyTree):
1102
c59b969c4100
1103
a1c1c555e5ee
    def _multi_move_leaf_last_sibling_root(self):
1104
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1105
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'last-sibling')
1106
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1107
ac1ecbb55c06
                    (u'2', 1, 4),
1108
ac1ecbb55c06
                    (u'21', 2, 0),
1109
ac1ecbb55c06
                    (u'22', 2, 0),
1110
ac1ecbb55c06
                    (u'23', 2, 0),
1111
ac1ecbb55c06
                    (u'24', 2, 0),
1112
ac1ecbb55c06
                    (u'3', 1, 0),
1113
ac1ecbb55c06
                    (u'4', 1, 1),
1114
ac1ecbb55c06
                    (u'41', 2, 0),
1115
ac1ecbb55c06
                    (u'231', 1, 0)]
1116
c59b969c4100
        self.assertEqual(self.got(), expected)
1117
c59b969c4100
1118
a1c1c555e5ee
    def _multi_move_leaf_first_sibling_root(self):
1119
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1120
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'first-sibling')
1121
ac1ecbb55c06
        expected = [(u'231', 1, 0),
1122
ac1ecbb55c06
                    (u'1', 1, 0),
1123
ac1ecbb55c06
                    (u'2', 1, 4),
1124
ac1ecbb55c06
                    (u'21', 2, 0),
1125
ac1ecbb55c06
                    (u'22', 2, 0),
1126
ac1ecbb55c06
                    (u'23', 2, 0),
1127
ac1ecbb55c06
                    (u'24', 2, 0),
1128
ac1ecbb55c06
                    (u'3', 1, 0),
1129
ac1ecbb55c06
                    (u'4', 1, 1),
1130
ac1ecbb55c06
                    (u'41', 2, 0)]
1131
c59b969c4100
        self.assertEqual(self.got(), expected)
1132
c59b969c4100
1133
a1c1c555e5ee
    def _multi_move_leaf_left_sibling_root(self):
1134
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1135
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'left')
1136
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1137
ac1ecbb55c06
                    (u'231', 1, 0),
1138
ac1ecbb55c06
                    (u'2', 1, 4),
1139
ac1ecbb55c06
                    (u'21', 2, 0),
1140
ac1ecbb55c06
                    (u'22', 2, 0),
1141
ac1ecbb55c06
                    (u'23', 2, 0),
1142
ac1ecbb55c06
                    (u'24', 2, 0),
1143
ac1ecbb55c06
                    (u'3', 1, 0),
1144
ac1ecbb55c06
                    (u'4', 1, 1),
1145
ac1ecbb55c06
                    (u'41', 2, 0)]
1146
c59b969c4100
        self.assertEqual(self.got(), expected)
1147
c59b969c4100
1148
a1c1c555e5ee
    def _multi_move_leaf_right_sibling_root(self):
1149
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1150
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'right')
1151
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1152
ac1ecbb55c06
                    (u'2', 1, 4),
1153
ac1ecbb55c06
                    (u'21', 2, 0),
1154
ac1ecbb55c06
                    (u'22', 2, 0),
1155
ac1ecbb55c06
                    (u'23', 2, 0),
1156
ac1ecbb55c06
                    (u'24', 2, 0),
1157
ac1ecbb55c06
                    (u'231', 1, 0),
1158
ac1ecbb55c06
                    (u'3', 1, 0),
1159
ac1ecbb55c06
                    (u'4', 1, 1),
1160
ac1ecbb55c06
                    (u'41', 2, 0)]
1161
c59b969c4100
        self.assertEqual(self.got(), expected)
1162
c59b969c4100
1163
a1c1c555e5ee
    def _multi_move_leaf_last_child_root(self):
1164
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1165
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'last-child')
1166
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1167
ac1ecbb55c06
                    (u'2', 1, 5),
1168
ac1ecbb55c06
                    (u'21', 2, 0),
1169
ac1ecbb55c06
                    (u'22', 2, 0),
1170
ac1ecbb55c06
                    (u'23', 2, 0),
1171
ac1ecbb55c06
                    (u'24', 2, 0),
1172
ac1ecbb55c06
                    (u'231', 2, 0),
1173
ac1ecbb55c06
                    (u'3', 1, 0),
1174
ac1ecbb55c06
                    (u'4', 1, 1),
1175
ac1ecbb55c06
                    (u'41', 2, 0)]
1176
7bf1eff4cfc3
        self.assertEqual(self.got(), expected)
1177
c59b969c4100
1178
a1c1c555e5ee
    def _multi_move_leaf_first_child_root(self):
1179
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1180
5ce21f964dd8
            self.model.objects.get(desc=u'2'), 'first-child')
1181
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1182
ac1ecbb55c06
                    (u'2', 1, 5),
1183
ac1ecbb55c06
                    (u'231', 2, 0),
1184
ac1ecbb55c06
                    (u'21', 2, 0),
1185
ac1ecbb55c06
                    (u'22', 2, 0),
1186
ac1ecbb55c06
                    (u'23', 2, 0),
1187
ac1ecbb55c06
                    (u'24', 2, 0),
1188
ac1ecbb55c06
                    (u'3', 1, 0),
1189
ac1ecbb55c06
                    (u'4', 1, 1),
1190
5ce21f964dd8
                    (u'41', 2, 0)]
1191
7bf1eff4cfc3
        self.assertEqual(self.got(), expected)
1192
7bf1eff4cfc3
1193
7bf1eff4cfc3
1194
14dd36f8989e
class TestMoveLeaf(TestNonEmptyTree):
1195
14dd36f8989e
1196
a1c1c555e5ee
    def _multi_move_leaf_last_sibling(self):
1197
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1198
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'last-sibling')
1199
14dd36f8989e
        expected = [(u'1', 1, 0),
1200
14dd36f8989e
                    (u'2', 1, 5),
1201
14dd36f8989e
                    (u'21', 2, 0),
1202
14dd36f8989e
                    (u'22', 2, 0),
1203
14dd36f8989e
                    (u'23', 2, 0),
1204
14dd36f8989e
                    (u'24', 2, 0),
1205
14dd36f8989e
                    (u'231', 2, 0),
1206
14dd36f8989e
                    (u'3', 1, 0),
1207
14dd36f8989e
                    (u'4', 1, 1),
1208
14dd36f8989e
                    (u'41', 2, 0)]
1209
14dd36f8989e
        self.assertEqual(self.got(), expected)
1210
14dd36f8989e
1211
a1c1c555e5ee
    def _multi_move_leaf_first_sibling(self):
1212
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1213
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'first-sibling')
1214
14dd36f8989e
        expected = [(u'1', 1, 0),
1215
14dd36f8989e
                    (u'2', 1, 5),
1216
14dd36f8989e
                    (u'231', 2, 0),
1217
14dd36f8989e
                    (u'21', 2, 0),
1218
14dd36f8989e
                    (u'22', 2, 0),
1219
14dd36f8989e
                    (u'23', 2, 0),
1220
14dd36f8989e
                    (u'24', 2, 0),
1221
14dd36f8989e
                    (u'3', 1, 0),
1222
14dd36f8989e
                    (u'4', 1, 1),
1223
14dd36f8989e
                    (u'41', 2, 0)]
1224
14dd36f8989e
        self.assertEqual(self.got(), expected)
1225
14dd36f8989e
1226
a1c1c555e5ee
    def _multi_move_leaf_left_sibling(self):
1227
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1228
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'left')
1229
14dd36f8989e
        expected = [(u'1', 1, 0),
1230
14dd36f8989e
                    (u'2', 1, 5),
1231
14dd36f8989e
                    (u'21', 2, 0),
1232
14dd36f8989e
                    (u'231', 2, 0),
1233
14dd36f8989e
                    (u'22', 2, 0),
1234
14dd36f8989e
                    (u'23', 2, 0),
1235
14dd36f8989e
                    (u'24', 2, 0),
1236
14dd36f8989e
                    (u'3', 1, 0),
1237
14dd36f8989e
                    (u'4', 1, 1),
1238
14dd36f8989e
                    (u'41', 2, 0)]
1239
14dd36f8989e
        self.assertEqual(self.got(), expected)
1240
14dd36f8989e
1241
a1c1c555e5ee
    def _multi_move_leaf_right_sibling(self):
1242
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1243
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'right')
1244
14dd36f8989e
        expected = [(u'1', 1, 0),
1245
14dd36f8989e
                    (u'2', 1, 5),
1246
14dd36f8989e
                    (u'21', 2, 0),
1247
14dd36f8989e
                    (u'22', 2, 0),
1248
14dd36f8989e
                    (u'231', 2, 0),
1249
14dd36f8989e
                    (u'23', 2, 0),
1250
14dd36f8989e
                    (u'24', 2, 0),
1251
14dd36f8989e
                    (u'3', 1, 0),
1252
14dd36f8989e
                    (u'4', 1, 1),
1253
14dd36f8989e
                    (u'41', 2, 0)]
1254
14dd36f8989e
        self.assertEqual(self.got(), expected)
1255
14dd36f8989e
1256
a1c1c555e5ee
    def _multi_move_leaf_left_sibling_itself(self):
1257
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1258
5ce21f964dd8
            self.model.objects.get(desc=u'231'), 'left')
1259
14dd36f8989e
        self.assertEqual(self.got(), self.unchanged)
1260
14dd36f8989e
1261
a1c1c555e5ee
    def _multi_move_leaf_last_child(self):
1262
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1263
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'last-child')
1264
14dd36f8989e
        expected = [(u'1', 1, 0),
1265
14dd36f8989e
                    (u'2', 1, 4),
1266
14dd36f8989e
                    (u'21', 2, 0),
1267
14dd36f8989e
                    (u'22', 2, 1),
1268
14dd36f8989e
                    (u'231', 3, 0),
1269
14dd36f8989e
                    (u'23', 2, 0),
1270
14dd36f8989e
                    (u'24', 2, 0),
1271
14dd36f8989e
                    (u'3', 1, 0),
1272
14dd36f8989e
                    (u'4', 1, 1),
1273
14dd36f8989e
                    (u'41', 2, 0)]
1274
14dd36f8989e
        self.assertEqual(self.got(), expected)
1275
14dd36f8989e
1276
a1c1c555e5ee
    def _multi_move_leaf_first_child(self):
1277
5ce21f964dd8
        self.model.objects.get(desc=u'231').move(
1278
5ce21f964dd8
            self.model.objects.get(desc=u'22'), 'first-child')
1279
14dd36f8989e
        expected = [(u'1', 1, 0),
1280
14dd36f8989e
                    (u'2', 1, 4),
1281
14dd36f8989e
                    (u'21', 2, 0),
1282
14dd36f8989e
                    (u'22', 2, 1),
1283
14dd36f8989e
                    (u'231', 3, 0),
1284
14dd36f8989e
                    (u'23', 2, 0),
1285
14dd36f8989e
                    (u'24', 2, 0),
1286
14dd36f8989e
                    (u'3', 1, 0),
1287
14dd36f8989e
                    (u'4', 1, 1),
1288
14dd36f8989e
                    (u'41', 2, 0)]
1289
14dd36f8989e
        self.assertEqual(self.got(), expected)
1290
14dd36f8989e
1291
14dd36f8989e
1292
14dd36f8989e
class TestMoveBranchRoot(TestNonEmptyTree):
1293
14dd36f8989e
1294
a1c1c555e5ee
    def _multi_move_branch_first_sibling_root(self):
1295
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1296
5ce21f964dd8
            self.model.objects.get(desc='2'), 'first-sibling')
1297
5ce21f964dd8
        expected = [(u'4', 1, 1),
1298
5ce21f964dd8
                    (u'41', 2, 0),
1299
5ce21f964dd8
                    (u'1', 1, 0),
1300
5ce21f964dd8
                    (u'2', 1, 4),
1301
5ce21f964dd8
                    (u'21', 2, 0),
1302
5ce21f964dd8
                    (u'22', 2, 0),
1303
5ce21f964dd8
                    (u'23', 2, 1),
1304
5ce21f964dd8
                    (u'231', 3, 0),
1305
5ce21f964dd8
                    (u'24', 2, 0),
1306
5ce21f964dd8
                    (u'3', 1, 0)]
1307
14dd36f8989e
        self.assertEqual(self.got(), expected)
1308
14dd36f8989e
1309
a1c1c555e5ee
    def _multi_move_branch_last_sibling_root(self):
1310
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1311
5ce21f964dd8
            self.model.objects.get(desc='2'), 'last-sibling')
1312
14dd36f8989e
        expected = [(u'1', 1, 0),
1313
14dd36f8989e
                    (u'2', 1, 4),
1314
14dd36f8989e
                    (u'21', 2, 0),
1315
14dd36f8989e
                    (u'22', 2, 0),
1316
14dd36f8989e
                    (u'23', 2, 1),
1317
14dd36f8989e
                    (u'231', 3, 0),
1318
14dd36f8989e
                    (u'24', 2, 0),
1319
14dd36f8989e
                    (u'3', 1, 0),
1320
14dd36f8989e
                    (u'4', 1, 1),
1321
14dd36f8989e
                    (u'41', 2, 0)]
1322
14dd36f8989e
        self.assertEqual(self.got(), expected)
1323
14dd36f8989e
1324
a1c1c555e5ee
    def _multi_move_branch_left_sibling_root(self):
1325
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1326
5ce21f964dd8
            self.model.objects.get(desc='2'), 'left')
1327
14dd36f8989e
        expected = [(u'1', 1, 0),
1328
14dd36f8989e
                    (u'4', 1, 1),
1329
14dd36f8989e
                    (u'41', 2, 0),
1330
14dd36f8989e
                    (u'2', 1, 4),
1331
14dd36f8989e
                    (u'21', 2, 0),
1332
14dd36f8989e
                    (u'22', 2, 0),
1333
14dd36f8989e
                    (u'23', 2, 1),
1334
14dd36f8989e
                    (u'231', 3, 0),
1335
14dd36f8989e
                    (u'24', 2, 0),
1336
14dd36f8989e
                    (u'3', 1, 0)]
1337
14dd36f8989e
        self.assertEqual(self.got(), expected)
1338
14dd36f8989e
1339
a1c1c555e5ee
    def _multi_move_branch_right_sibling_root(self):
1340
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1341
5ce21f964dd8
            self.model.objects.get(desc='2'), 'right')
1342
14dd36f8989e
        expected = [(u'1', 1, 0),
1343
14dd36f8989e
                    (u'2', 1, 4),
1344
14dd36f8989e
                    (u'21', 2, 0),
1345
14dd36f8989e
                    (u'22', 2, 0),
1346
14dd36f8989e
                    (u'23', 2, 1),
1347
14dd36f8989e
                    (u'231', 3, 0),
1348
14dd36f8989e
                    (u'24', 2, 0),
1349
14dd36f8989e
                    (u'4', 1, 1),
1350
14dd36f8989e
                    (u'41', 2, 0),
1351
14dd36f8989e
                    (u'3', 1, 0)]
1352
14dd36f8989e
        self.assertEqual(self.got(), expected)
1353
14dd36f8989e
1354
a1c1c555e5ee
    def _multi_move_branch_left_noleft_sibling_root(self):
1355
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1356
5ce21f964dd8
            self.model.objects.get(desc='2').get_first_sibling(), 'left')
1357
14dd36f8989e
        expected = [(u'4', 1, 1),
1358
14dd36f8989e
                    (u'41', 2, 0),
1359
14dd36f8989e
                    (u'1', 1, 0),
1360
14dd36f8989e
                    (u'2', 1, 4),
1361
14dd36f8989e
                    (u'21', 2, 0),
1362
14dd36f8989e
                    (u'22', 2, 0),
1363
14dd36f8989e
                    (u'23', 2, 1),
1364
14dd36f8989e
                    (u'231', 3, 0),
1365
14dd36f8989e
                    (u'24', 2, 0),
1366
14dd36f8989e
                    (u'3', 1, 0)]
1367
14dd36f8989e
        self.assertEqual(self.got(), expected)
1368
14dd36f8989e
1369
a1c1c555e5ee
    def _multi_move_branch_right_noright_sibling_root(self):
1370
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1371
5ce21f964dd8
            self.model.objects.get(desc='2').get_last_sibling(), 'right')
1372
14dd36f8989e
        expected = [(u'1', 1, 0),
1373
14dd36f8989e
                    (u'2', 1, 4),
1374
14dd36f8989e
                    (u'21', 2, 0),
1375
14dd36f8989e
                    (u'22', 2, 0),
1376
14dd36f8989e
                    (u'23', 2, 1),
1377
14dd36f8989e
                    (u'231', 3, 0),
1378
14dd36f8989e
                    (u'24', 2, 0),
1379
14dd36f8989e
                    (u'3', 1, 0),
1380
14dd36f8989e
                    (u'4', 1, 1),
1381
14dd36f8989e
                    (u'41', 2, 0)]
1382
14dd36f8989e
        self.assertEqual(self.got(), expected)
1383
14dd36f8989e
1384
a1c1c555e5ee
    def _multi_move_branch_first_child_root(self):
1385
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1386
5ce21f964dd8
            self.model.objects.get(desc='2'), 'first-child')
1387
14dd36f8989e
        expected = [(u'1', 1, 0),
1388
14dd36f8989e
                   (u'2', 1, 5),
1389
14dd36f8989e
                   (u'4', 2, 1),
1390
14dd36f8989e
                   (u'41', 3, 0),
1391
14dd36f8989e
                   (u'21', 2, 0),
1392
14dd36f8989e
                   (u'22', 2, 0),
1393
14dd36f8989e
                   (u'23', 2, 1),
1394
14dd36f8989e
                   (u'231', 3, 0),
1395
14dd36f8989e
                   (u'24', 2, 0),
1396
14dd36f8989e
                   (u'3', 1, 0)]
1397
14dd36f8989e
        self.assertEqual(self.got(), expected)
1398
14dd36f8989e
1399
a1c1c555e5ee
    def _multi_move_branch_last_child_root(self):
1400
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1401
5ce21f964dd8
            self.model.objects.get(desc='2'), 'last-child')
1402
14dd36f8989e
        expected = [(u'1', 1, 0),
1403
14dd36f8989e
                    (u'2', 1, 5),
1404
14dd36f8989e
                    (u'21', 2, 0),
1405
14dd36f8989e
                    (u'22', 2, 0),
1406
14dd36f8989e
                    (u'23', 2, 1),
1407
14dd36f8989e
                    (u'231', 3, 0),
1408
14dd36f8989e
                    (u'24', 2, 0),
1409
14dd36f8989e
                    (u'4', 2, 1),
1410
14dd36f8989e
                    (u'41', 3, 0),
1411
14dd36f8989e
                    (u'3', 1, 0)]
1412
14dd36f8989e
        self.assertEqual(self.got(), expected)
1413
14dd36f8989e
1414
14dd36f8989e
1415
7bf1eff4cfc3
class TestMoveBranch(TestNonEmptyTree):
1416
c59b969c4100
1417
a1c1c555e5ee
    def _multi_move_branch_first_sibling(self):
1418
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1419
5ce21f964dd8
            self.model.objects.get(desc='23'), 'first-sibling')
1420
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1421
ac1ecbb55c06
                    (u'2', 1, 5),
1422
ac1ecbb55c06
                    (u'4', 2, 1),
1423
ac1ecbb55c06
                    (u'41', 3, 0),
1424
ac1ecbb55c06
                    (u'21', 2, 0),
1425
ac1ecbb55c06
                    (u'22', 2, 0),
1426
ac1ecbb55c06
                    (u'23', 2, 1),
1427
ac1ecbb55c06
                    (u'231', 3, 0),
1428
ac1ecbb55c06
                    (u'24', 2, 0),
1429
ac1ecbb55c06
                    (u'3', 1, 0)]
1430
c59b969c4100
        self.assertEqual(self.got(), expected)
1431
c59b969c4100
1432
a1c1c555e5ee
    def _multi_move_branch_last_sibling(self):
1433
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1434
5ce21f964dd8
            self.model.objects.get(desc='23'), 'last-sibling')
1435
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1436
ac1ecbb55c06
                    (u'2', 1, 5),
1437
ac1ecbb55c06
                    (u'21', 2, 0),
1438
ac1ecbb55c06
                    (u'22', 2, 0),
1439
ac1ecbb55c06
                    (u'23', 2, 1),
1440
ac1ecbb55c06
                    (u'231', 3, 0),
1441
ac1ecbb55c06
                    (u'24', 2, 0),
1442
ac1ecbb55c06
                    (u'4', 2, 1),
1443
ac1ecbb55c06
                    (u'41', 3, 0),
1444
ac1ecbb55c06
                    (u'3', 1, 0)]
1445
c59b969c4100
        self.assertEqual(self.got(), expected)
1446
c59b969c4100
1447
a1c1c555e5ee
    def _multi_move_branch_left_sibling(self):
1448
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1449
5ce21f964dd8
            self.model.objects.get(desc='23'), 'left')
1450
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1451
ac1ecbb55c06
                    (u'2', 1, 5),
1452
ac1ecbb55c06
                    (u'21', 2, 0),
1453
ac1ecbb55c06
                    (u'22', 2, 0),
1454
ac1ecbb55c06
                    (u'4', 2, 1),
1455
ac1ecbb55c06
                    (u'41', 3, 0),
1456
ac1ecbb55c06
                    (u'23', 2, 1),
1457
ac1ecbb55c06
                    (u'231', 3, 0),
1458
ac1ecbb55c06
                    (u'24', 2, 0),
1459
ac1ecbb55c06
                    (u'3', 1, 0)]
1460
c59b969c4100
        self.assertEqual(self.got(), expected)
1461
c59b969c4100
1462
a1c1c555e5ee
    def _multi_move_branch_right_sibling(self):
1463
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1464
5ce21f964dd8
            self.model.objects.get(desc='23'), 'right')
1465
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1466
ac1ecbb55c06
                    (u'2', 1, 5),
1467
ac1ecbb55c06
                    (u'21', 2, 0),
1468
ac1ecbb55c06
                    (u'22', 2, 0),
1469
ac1ecbb55c06
                    (u'23', 2, 1),
1470
ac1ecbb55c06
                    (u'231', 3, 0),
1471
ac1ecbb55c06
                    (u'4', 2, 1),
1472
ac1ecbb55c06
                    (u'41', 3, 0),
1473
ac1ecbb55c06
                    (u'24', 2, 0),
1474
ac1ecbb55c06
                    (u'3', 1, 0)]
1475
c59b969c4100
        self.assertEqual(self.got(), expected)
1476
c59b969c4100
1477
a1c1c555e5ee
    def _multi_move_branch_left_noleft_sibling(self):
1478
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1479
5ce21f964dd8
            self.model.objects.get(desc='23').get_first_sibling(), 'left')
1480
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1481
ac1ecbb55c06
                    (u'2', 1, 5),
1482
ac1ecbb55c06
                    (u'4', 2, 1),
1483
ac1ecbb55c06
                    (u'41', 3, 0),
1484
ac1ecbb55c06
                    (u'21', 2, 0),
1485
ac1ecbb55c06
                    (u'22', 2, 0),
1486
ac1ecbb55c06
                    (u'23', 2, 1),
1487
ac1ecbb55c06
                    (u'231', 3, 0),
1488
ac1ecbb55c06
                    (u'24', 2, 0),
1489
ac1ecbb55c06
                    (u'3', 1, 0)]
1490
c59b969c4100
        self.assertEqual(self.got(), expected)
1491
c59b969c4100
1492
a1c1c555e5ee
    def _multi_move_branch_right_noright_sibling(self):
1493
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1494
5ce21f964dd8
            self.model.objects.get(desc='23').get_last_sibling(), 'right')
1495
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1496
ac1ecbb55c06
                    (u'2', 1, 5),
1497
ac1ecbb55c06
                    (u'21', 2, 0),
1498
ac1ecbb55c06
                    (u'22', 2, 0),
1499
ac1ecbb55c06
                    (u'23', 2, 1),
1500
ac1ecbb55c06
                    (u'231', 3, 0),
1501
ac1ecbb55c06
                    (u'24', 2, 0),
1502
ac1ecbb55c06
                    (u'4', 2, 1),
1503
ac1ecbb55c06
                    (u'41', 3, 0),
1504
ac1ecbb55c06
                    (u'3', 1, 0)]
1505
c59b969c4100
        self.assertEqual(self.got(), expected)
1506
c59b969c4100
1507
a1c1c555e5ee
    def _multi_move_branch_left_itself_sibling(self):
1508
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1509
5ce21f964dd8
            self.model.objects.get(desc='4'), 'left')
1510
c59b969c4100
        self.assertEqual(self.got(), self.unchanged)
1511
c59b969c4100
1512
a1c1c555e5ee
    def _multi_move_branch_first_child(self):
1513
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1514
5ce21f964dd8
            self.model.objects.get(desc='23'), 'first-child')
1515
ac1ecbb55c06
        expected = [(u'1', 1, 0),
1516
ac1ecbb55c06
                    (u'2', 1, 4),
1517
ac1ecbb55c06
                    (u'21', 2, 0),
1518
ac1ecbb55c06
                    (u'22', 2, 0),
1519
ac1ecbb55c06
                    (u'23', 2, 2),
1520
ac1ecbb55c06
                    (u'4', 3, 1),
1521
ac1ecbb55c06
                    (u'41', 4, 0),
1522
ac1ecbb55c06
                    (u'231', 3, 0),
1523
ac1ecbb55c06
                    (u'24', 2, 0),
1524
ac1ecbb55c06
                    (u'3', 1, 0)]
1525
7bf1eff4cfc3
        self.assertEqual(self.got(), expected)
1526
7bf1eff4cfc3
1527
a1c1c555e5ee
    def _multi_move_branch_last_child(self):
1528
5ce21f964dd8
        self.model.objects.get(desc='4').move(
1529
5ce21f964dd8
            self.model.objects.get(desc='23'), 'last-child')
1530
5ce21f964dd8
        expected = [(u'1', 1, 0),
1531
5ce21f964dd8
                    (u'2', 1, 4),
1532
5ce21f964dd8
                    (u'21', 2, 0),
1533
5ce21f964dd8
                    (u'22', 2, 0),
1534
5ce21f964dd8
                    (u'23', 2, 2),
1535
5ce21f964dd8
                    (u'231', 3, 0),
1536
5ce21f964dd8
                    (u'4', 3, 1),
1537
5ce21f964dd8
                    (u'41', 4, 0),
1538
5ce21f964dd8
                    (u'24', 2, 0),
1539
5ce21f964dd8
                    (u'3', 1, 0)]
1540
7bf1eff4cfc3
        self.assertEqual(self.got(), expected)
1541
7bf1eff4cfc3
1542
7bf1eff4cfc3
1543
af911c482a44
class TestTreeSorted(TestTreeBase):
1544
c59b969c4100
1545
c59b969c4100
    def got(self):
1546
5956967b8676
        return [(o.val1, o.val2, o.desc, o.get_depth(), o.get_children_count())
1547
5956967b8676
                 for o in self.sorted_model.get_tree()]
1548
c59b969c4100
1549
a1c1c555e5ee
    def _multi_add_root_sorted(self):
1550
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='zxy')
1551
af911c482a44
        self.sorted_model.add_root(val1=1, val2=4, desc='bcd')
1552
af911c482a44
        self.sorted_model.add_root(val1=2, val2=5, desc='zxy')
1553
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='abc')
1554
af911c482a44
        self.sorted_model.add_root(val1=4, val2=1, desc='fgh')
1555
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='abc')
1556
af911c482a44
        self.sorted_model.add_root(val1=2, val2=2, desc='qwe')
1557
af911c482a44
        self.sorted_model.add_root(val1=3, val2=2, desc='vcx')
1558
ac1ecbb55c06
        expected = [(1, 4, u'bcd', 1, 0),
1559
ac1ecbb55c06
                    (2, 2, u'qwe', 1, 0),
1560
ac1ecbb55c06
                    (2, 5, u'zxy', 1, 0),
1561
ac1ecbb55c06
                    (3, 2, u'vcx', 1, 0),
1562
ac1ecbb55c06
                    (3, 3, u'abc', 1, 0),
1563
ac1ecbb55c06
                    (3, 3, u'abc', 1, 0),
1564
ac1ecbb55c06
                    (3, 3, u'zxy', 1, 0),
1565
ac1ecbb55c06
                    (4, 1, u'fgh', 1, 0)]
1566
c59b969c4100
        self.assertEqual(self.got(), expected)
1567
c59b969c4100
1568
5b26c536bc7a
    def _multi_add_child_root_sorted(self):
1569
af911c482a44
        root = self.sorted_model.add_root(val1=0, val2=0, desc='aaa')
1570
c59b969c4100
        root.add_child(val1=3, val2=3, desc='zxy')
1571
c59b969c4100
        root.add_child(val1=1, val2=4, desc='bcd')
1572
c59b969c4100
        root.add_child(val1=2, val2=5, desc='zxy')
1573
c59b969c4100
        root.add_child(val1=3, val2=3, desc='abc')
1574
c59b969c4100
        root.add_child(val1=4, val2=1, desc='fgh')
1575
c59b969c4100
        root.add_child(val1=3, val2=3, desc='abc')
1576
c59b969c4100
        root.add_child(val1=2, val2=2, desc='qwe')
1577
c59b969c4100
        root.add_child(val1=3, val2=2, desc='vcx')
1578
ac1ecbb55c06
        expected = [(0, 0, u'aaa', 1, 8),
1579
ac1ecbb55c06
                    (1, 4, u'bcd', 2, 0),
1580
ac1ecbb55c06
                    (2, 2, u'qwe', 2, 0),
1581
ac1ecbb55c06
                    (2, 5, u'zxy', 2, 0),
1582
ac1ecbb55c06
                    (3, 2, u'vcx', 2, 0),
1583
ac1ecbb55c06
                    (3, 3, u'abc', 2, 0),
1584
ac1ecbb55c06
                    (3, 3, u'abc', 2, 0),
1585
ac1ecbb55c06
                    (3, 3, u'zxy', 2, 0),
1586
ac1ecbb55c06
                    (4, 1, u'fgh', 2, 0)]
1587
c59b969c4100
        self.assertEqual(self.got(), expected)
1588
c59b969c4100
1589
5b26c536bc7a
    def _multi_add_child_nonroot_sorted(self):
1590
0804307bd900
1591
0804307bd900
        get_node = lambda node_id: self.sorted_model.objects.get(pk=node_id)
1592
0804307bd900
1593
0804307bd900
        root_id = self.sorted_model.add_root(val1=0, val2=0, desc='a').id
1594
0804307bd900
        node_id = get_node(root_id).add_child(val1=0, val2=0, desc='ac').id
1595
0804307bd900
        get_node(root_id).add_child(val1=0, val2=0, desc='aa')
1596
0804307bd900
        get_node(root_id).add_child(val1=0, val2=0, desc='av')
1597
0804307bd900
        get_node(node_id).add_child(val1=0, val2=0, desc='aca')
1598
0804307bd900
        get_node(node_id).add_child(val1=0, val2=0, desc='acc')
1599
0804307bd900
        get_node(node_id).add_child(val1=0, val2=0, desc='acb')
1600
0804307bd900
1601
4097b45d9af8
        expected = [(0, 0, u'a', 1, 3),
1602
6456a5b24d97
                    (0, 0, u'aa', 2, 0),
1603
6456a5b24d97
                    (0, 0, u'ac', 2, 3),
1604
6456a5b24d97
                    (0, 0, u'aca', 3, 0),
1605
6456a5b24d97
                    (0, 0, u'acb', 3, 0),
1606
6456a5b24d97
                    (0, 0, u'acc', 3, 0),
1607
6456a5b24d97
                    (0, 0, u'av', 2, 0)]
1608
5b26c536bc7a
        self.assertEqual(self.got(), expected)
1609
5b26c536bc7a
1610
a1c1c555e5ee
    def _multi_move_sorted(self):
1611
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='zxy')
1612
af911c482a44
        self.sorted_model.add_root(val1=1, val2=4, desc='bcd')
1613
af911c482a44
        self.sorted_model.add_root(val1=2, val2=5, desc='zxy')
1614
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='abc')
1615
af911c482a44
        self.sorted_model.add_root(val1=4, val2=1, desc='fgh')
1616
af911c482a44
        self.sorted_model.add_root(val1=3, val2=3, desc='abc')
1617
af911c482a44
        self.sorted_model.add_root(val1=2, val2=2, desc='qwe')
1618
af911c482a44
        self.sorted_model.add_root(val1=3, val2=2, desc='vcx')
1619
af911c482a44
        root_nodes = self.sorted_model.get_root_nodes()
1620
bf04b808ddb1
        target = root_nodes[0]
1621
bf04b808ddb1
        for node in root_nodes[1:]:
1622
14dd36f8989e
1623
14dd36f8989e
            # because raw queries don't update django objects
1624
c6d9e339d6bb
            node = self.sorted_model.objects.get(pk=node.id)
1625
c6d9e339d6bb
            target = self.sorted_model.objects.get(pk=target.id)
1626
14dd36f8989e
1627
bf04b808ddb1
            node.move(target, 'sorted-child')
1628
ac1ecbb55c06
        expected = [(1, 4, u'bcd', 1, 7),
1629
ac1ecbb55c06
                    (2, 2, u'qwe', 2, 0),
1630
ac1ecbb55c06
                    (2, 5, u'zxy', 2, 0),
1631
ac1ecbb55c06
                    (3, 2, u'vcx', 2, 0),
1632
ac1ecbb55c06
                    (3, 3, u'abc', 2, 0),
1633
ac1ecbb55c06
                    (3, 3, u'abc', 2, 0),
1634
ac1ecbb55c06
                    (3, 3, u'zxy', 2, 0),
1635
ac1ecbb55c06
                    (4, 1, u'fgh', 2, 0)]
1636
bf04b808ddb1
        self.assertEqual(self.got(), expected)
1637
bf04b808ddb1
1638
bf04b808ddb1
1639
5956967b8676
class TestMP_TreeAlphabet(TestCase):
1640
f090c68767a8
1641
f090c68767a8
    def test_alphabet(self):
1642
f090c68767a8
        if not os.getenv('TREEBEARD_TEST_ALPHABET', False):
1643
f090c68767a8
            # run this test only if the enviroment variable is set
1644
f090c68767a8
            return
1645
f090c68767a8
        basealpha = numconv.BASE85
1646
f090c68767a8
        got_err = False
1647
f090c68767a8
        last_good = None
1648
66a6725a50c1
        for alphabetlen in range(35, len(basealpha) + 1):
1649
f090c68767a8
            alphabet = basealpha[0:alphabetlen]
1650
66a6725a50c1
            expected = [alphabet[0] + char for char in alphabet[1:]]
1651
66a6725a50c1
            expected.extend([alphabet[1] + char for char in alphabet])
1652
66a6725a50c1
            expected.append(alphabet[2] + alphabet[0])
1653
f090c68767a8
1654
f090c68767a8
            # remove all nodes
1655
5956967b8676
            MP_TestNodeAlphabet.objects.all().delete()
1656
f090c68767a8
1657
f090c68767a8
            # change the model's alphabet
1658
5956967b8676
            MP_TestNodeAlphabet.alphabet = alphabet
1659
f090c68767a8
1660
f090c68767a8
            # insert root nodes
1661
66a6725a50c1
            for pos in range(len(alphabet) * 2):
1662
f090c68767a8
                try:
1663
5956967b8676
                    MP_TestNodeAlphabet.add_root(numval=pos)
1664
f090c68767a8
                except:
1665
f090c68767a8
                    got_err = True
1666
f090c68767a8
                    break
1667
f090c68767a8
            if got_err:
1668
f090c68767a8
                break
1669
4afaa319560c
            got = [obj.path for obj in MP_TestNodeAlphabet.objects.all()]
1670
4afaa319560c
            if got != expected:
1671
4afaa319560c
                got_err = True
1672
4afaa319560c
            last_good = alphabet
1673
4afaa319560c
        print '\nThe best BASE85 based alphabet for your setup is: %s' \
1674
5ce21f964dd8
            % (last_good, )
1675
c59b969c4100
1676
7855e638023a
1677
a39c4f341471
class TestHelpers(TestTreeBase):
1678
a39c4f341471
1679
a39c4f341471
    def setUp(self):
1680
d5c8b5de2272
        for model in (MP_TestNode, AL_TestNode, NS_TestNode):
1681
5956967b8676
            model.load_bulk(BASE_DATA)
1682
5956967b8676
            for node in model.get_root_nodes():
1683
5956967b8676
                model.load_bulk(BASE_DATA, node)
1684
5956967b8676
            model.add_root(desc='5')
1685
a39c4f341471
1686
a1c1c555e5ee
    def _multi_descendants_group_count_root(self):
1687
5956967b8676
        expected = [(o.desc, o.get_descendant_count())
1688
5956967b8676
                    for o in self.model.get_root_nodes()]
1689
a39c4f341471
        got = [(o.desc, o.descendants_count)
1690
5956967b8676
               for o in self.model.get_descendants_group_count()]
1691
a39c4f341471
        self.assertEqual(got, expected)
1692
a39c4f341471
1693
a1c1c555e5ee
    def _multi_descendants_group_count_node(self):
1694
5956967b8676
        parent = self.model.get_root_nodes().get(desc='2')
1695
5956967b8676
        expected = [(o.desc, o.get_descendant_count())
1696
a39c4f341471
                    for o in parent.get_children()]
1697
a39c4f341471
        got = [(o.desc, o.descendants_count)
1698
5956967b8676
               for o in self.model.get_descendants_group_count(parent)]
1699
a39c4f341471
        self.assertEqual(got, expected)
1700
a39c4f341471
1701
a39c4f341471
1702
5956967b8676
class TestMP_TreeSortedAutoNow(TestCase):
1703
a39c4f341471
    """
1704
a39c4f341471
    The sorting mechanism used by treebeard when adding a node can fail if the
1705
a39c4f341471
    ordering is using an "auto_now" field
1706
a39c4f341471
    """
1707
a39c4f341471
1708
a39c4f341471
    def test_sorted_by_autonow_workaround(self):
1709
a39c4f341471
        """
1710
a39c4f341471
        workaround
1711
a39c4f341471
        """
1712
a39c4f341471
        import datetime
1713
a39c4f341471
        for i in range(1, 5):
1714
5ce21f964dd8
            MP_TestNodeSortedAutoNow.add_root(desc='node%d' % (i, ),
1715
a39c4f341471
                                             created=datetime.datetime.now())
1716
a39c4f341471
1717
a39c4f341471
    def test_sorted_by_autonow_FAIL(self):
1718
a39c4f341471
        """
1719
a39c4f341471
        This test asserts that we have a problem.
1720
a39c4f341471
        fix this, somehow
1721
a39c4f341471
        """
1722
5956967b8676
        MP_TestNodeSortedAutoNow.add_root(desc='node1')
1723
5956967b8676
        self.assertRaises(ValueError, MP_TestNodeSortedAutoNow.add_root,
1724
a39c4f341471
                          desc='node2')
1725
a39c4f341471
1726
a39c4f341471
1727
5ce21f964dd8
class TestMP_TreeStepOverflow(TestCase):
1728
a39c4f341471
1729
7855e638023a
    def test_add_root(self):
1730
5956967b8676
        method = MP_TestNodeSmallStep.add_root
1731
7855e638023a
        for i in range(1, 10):
1732
7855e638023a
            method()
1733
7855e638023a
        self.assertRaises(PathOverflow, method)
1734
7855e638023a
1735
7855e638023a
    def test_add_child(self):
1736
5956967b8676
        root = MP_TestNodeSmallStep.add_root()
1737
7855e638023a
        method = root.add_child
1738
7855e638023a
        for i in range(1, 10):
1739
7855e638023a
            method()
1740
7855e638023a
        self.assertRaises(PathOverflow, method)
1741
7855e638023a
1742
7855e638023a
    def test_add_sibling(self):
1743
5956967b8676
        root = MP_TestNodeSmallStep.add_root()
1744
7855e638023a
        for i in range(1, 10):
1745
7855e638023a
            root.add_child()
1746
7855e638023a
        method = root.get_last_child().add_sibling
1747
7855e638023a
        positions = ('first-sibling', 'left', 'right', 'last-sibling')
1748
7855e638023a
        for pos in positions:
1749
7855e638023a
            self.assertRaises(PathOverflow, method, pos)
1750
7855e638023a
1751
7855e638023a
    def test_move(self):
1752
5956967b8676
        root = MP_TestNodeSmallStep.add_root()
1753
7855e638023a
        for i in range(1, 10):
1754
7855e638023a
            root.add_child()
1755
5956967b8676
        newroot = MP_TestNodeSmallStep.add_root()
1756
7855e638023a
        targets = [(root, ['first-child', 'last-child']),
1757
7855e638023a
                   (root.get_first_child(), ['first-sibling',
1758
7855e638023a
                                            'left',
1759
7855e638023a
                                            'right',
1760
7855e638023a
                                            'last-sibling'])]
1761
7855e638023a
        for target, positions in targets:
1762
7855e638023a
            for pos in positions:
1763
7855e638023a
                self.assertRaises(PathOverflow, newroot.move, target, pos)
1764
7855e638023a
1765
7855e638023a
1766
5956967b8676
class TestMP_TreeShortPath(TestCase):
1767
9bbcfbe7a52b
    """
1768
9bbcfbe7a52b
    Here we test a tree with a very small path field (max_length=4) and a
1769
9bbcfbe7a52b
    steplen of 1
1770
9bbcfbe7a52b
    """
1771
5ce21f964dd8
1772
9bbcfbe7a52b
    def test_short_path(self):
1773
5ce21f964dd8
        obj = MP_TestNodeShortPath.add_root()
1774
5ce21f964dd8
        obj = obj.add_child().add_child().add_child()
1775
9bbcfbe7a52b
        self.assertRaises(PathOverflow, obj.add_child)
1776
9bbcfbe7a52b
1777
cfe76918146d
1778
5956967b8676
class TestMP_TreeFindProblems(TestTreeBase):
1779
ac1ecbb55c06
1780
ac1ecbb55c06
    def test_find_problems(self):
1781
5956967b8676
        model = MP_TestNodeAlphabet
1782
4e6b7fd55773
        model.alphabet = '01234'
1783
cfe76918146d
        model(path='01', depth=1, numchild=0, numval=0).save()
1784
cfe76918146d
        model(path='1', depth=1, numchild=0, numval=0).save()
1785
cfe76918146d
        model(path='111', depth=1, numchild=0, numval=0).save()
1786
cfe76918146d
        model(path='abcd', depth=1, numchild=0, numval=0).save()
1787
cfe76918146d
        model(path='qa#$%!', depth=1, numchild=0, numval=0).save()
1788
cfe76918146d
        model(path='0201', depth=2, numchild=0, numval=0).save()
1789
cfe76918146d
        model(path='020201', depth=3, numchild=0, numval=0).save()
1790
4e6b7fd55773
        model(path='03', depth=1, numchild=2, numval=0).save()
1791
4e6b7fd55773
        model(path='0301', depth=2, numchild=0, numval=0).save()
1792
4e6b7fd55773
        model(path='030102', depth=3, numchild=10, numval=0).save()
1793
4e6b7fd55773
        model(path='04', depth=10, numchild=1, numval=0).save()
1794
4e6b7fd55773
        model(path='0401', depth=20, numchild=0, numval=0).save()
1795
cfe76918146d
1796
4e6b7fd55773
        evil_chars, bad_steplen, orphans, wrong_depth, wrong_numchild = \
1797
4e6b7fd55773
                                                        model.find_problems()
1798
cfe76918146d
        self.assertEqual(['abcd', 'qa#$%!'],
1799
cfe76918146d
            [o.path for o in model.objects.filter(id__in=evil_chars)])
1800
cfe76918146d
        self.assertEqual(['1', '111'],
1801
cfe76918146d
            [o.path for o in model.objects.filter(id__in=bad_steplen)])
1802
cfe76918146d
        self.assertEqual(['0201', '020201'],
1803
cfe76918146d
            [o.path for o in model.objects.filter(id__in=orphans)])
1804
4e6b7fd55773
        self.assertEqual(['03', '0301', '030102'],
1805
4e6b7fd55773
            [o.path for o in model.objects.filter(id__in=wrong_numchild)])
1806
4e6b7fd55773
        self.assertEqual(['04', '0401'],
1807
4e6b7fd55773
            [o.path for o in model.objects.filter(id__in=wrong_depth)])
1808
cfe76918146d
1809
cfe76918146d
1810
5ce21f964dd8
class TestMP_TreeFix(TestTreeBase):
1811
cfe76918146d
1812
5b4ab568ff33
    def setUp(self):
1813
5b4ab568ff33
        super(TestMP_TreeFix, self).setUp()
1814
5b4ab568ff33
        self.expected_no_holes = {
1815
5b4ab568ff33
            MP_TestNodeShortPath: [
1816
5b4ab568ff33
                (u'1', u'b', 1, 2),
1817
5b4ab568ff33
                (u'11', u'u', 2, 1),
1818
5b4ab568ff33
                (u'111', u'i', 3, 1),
1819
5b4ab568ff33
                (u'1111', u'e', 4, 0),
1820
5b4ab568ff33
                (u'12', u'o', 2, 0),
1821
5b4ab568ff33
                (u'2', u'd', 1, 0),
1822
5b4ab568ff33
                (u'3', u'g', 1, 0),
1823
5b4ab568ff33
                (u'4', u'a', 1, 4),
1824
5b4ab568ff33
                (u'41', u'a', 2, 0),
1825
5b4ab568ff33
                (u'42', u'a', 2, 0),
1826
5b4ab568ff33
                (u'43', u'u', 2, 1),
1827
5b4ab568ff33
                (u'431', u'i', 3, 1),
1828
5b4ab568ff33
                (u'4311', u'e', 4, 0),
1829
5b4ab568ff33
                (u'44', u'o', 2, 0)],
1830
5b4ab568ff33
            MP_TestSortedNodeShortPath: [
1831
5b4ab568ff33
                (u'1', u'a', 1, 4),
1832
5b4ab568ff33
                (u'11', u'a', 2, 0),
1833
5b4ab568ff33
                (u'12', u'a', 2, 0),
1834
5b4ab568ff33
                (u'13', u'o', 2, 0),
1835
5b4ab568ff33
                (u'14', u'u', 2, 1),
1836
5ce21f964dd8
                (u'141', u'i', 3, 1),
1837
5b4ab568ff33
                (u'1411', u'e', 4, 0),
1838
5b4ab568ff33
                (u'2', u'b', 1, 2),
1839
5b4ab568ff33
                (u'21', u'o', 2, 0),
1840
5b4ab568ff33
                (u'22', u'u', 2, 1),
1841
5b4ab568ff33
                (u'221', u'i', 3, 1),
1842
5b4ab568ff33
                (u'2211', u'e', 4, 0),
1843
5b4ab568ff33
                (u'3', u'd', 1, 0),
1844
5b4ab568ff33
                (u'4', u'g', 1, 0)]}
1845
5b4ab568ff33
        self.expected_with_holes = {
1846
5b4ab568ff33
            MP_TestNodeShortPath: [
1847
5b4ab568ff33
                (u'1', u'b', 1L, 2L),
1848
5b4ab568ff33
                (u'13', u'u', 2L, 1L),
1849
5b4ab568ff33
                (u'134', u'i', 3L, 1L),
1850
5b4ab568ff33
                (u'1343', u'e', 4L, 0L),
1851
5b4ab568ff33
                (u'14', u'o', 2L, 0L),
1852
5b4ab568ff33
                (u'2', u'd', 1L, 0L),
1853
5b4ab568ff33
                (u'3', u'g', 1L, 0L),
1854
5b4ab568ff33
                (u'4', u'a', 1L, 4L),
1855
5b4ab568ff33
                (u'41', u'a', 2L, 0L),
1856
5b4ab568ff33
                (u'42', u'a', 2L, 0L),
1857
5b4ab568ff33
                (u'43', u'u', 2L, 1L),
1858
5b4ab568ff33
                (u'434', u'i', 3L, 1L),
1859
5b4ab568ff33
                (u'4343', u'e', 4L, 0L),
1860
5b4ab568ff33
                (u'44', u'o', 2L, 0L)],
1861
5b4ab568ff33
            MP_TestSortedNodeShortPath: [
1862
5b4ab568ff33
                (u'1', u'b', 1L, 2L),
1863
5b4ab568ff33
                (u'13', u'u', 2L, 1L),
1864
5b4ab568ff33
                (u'134', u'i', 3L, 1L),
1865
5b4ab568ff33
                (u'1343', u'e', 4L, 0L),
1866
5b4ab568ff33
                (u'14', u'o', 2L, 0L),
1867
5b4ab568ff33
                (u'2', u'd', 1L, 0L),
1868
5b4ab568ff33
                (u'3', u'g', 1L, 0L),
1869
5b4ab568ff33
                (u'4', u'a', 1L, 4L),
1870
5b4ab568ff33
                (u'41', u'a', 2L, 0L),
1871
5b4ab568ff33
                (u'42', u'a', 2L, 0L),
1872
5b4ab568ff33
                (u'43', u'u', 2L, 1L),
1873
5b4ab568ff33
                (u'434', u'i', 3L, 1L),
1874
5b4ab568ff33
                (u'4343', u'e', 4L, 0L),
1875
5b4ab568ff33
                (u'44', u'o', 2L, 0L)]}
1876
cfe76918146d
1877
ac1ecbb55c06
    def got(self, model):
1878
5956967b8676
        return [(o.path, o.desc, o.get_depth(), o.get_children_count())
1879
5956967b8676
                for o in model.get_tree()]
1880
5ce21f964dd8
1881
5b4ab568ff33
    def add_broken_test_data(self, model):
1882
5b4ab568ff33
        model(path='4', depth=2, numchild=2, desc='a').save()
1883
5b4ab568ff33
        model(path='13', depth=1000, numchild=0, desc='u').save()
1884
5b4ab568ff33
        model(path='14', depth=4, numchild=500, desc='o').save()
1885
5b4ab568ff33
        model(path='134', depth=321, numchild=543, desc='i').save()
1886
5b4ab568ff33
        model(path='1343', depth=321, numchild=543, desc='e').save()
1887
5b4ab568ff33
        model(path='42', depth=1, numchild=1, desc='a').save()
1888
5b4ab568ff33
        model(path='43', depth=1000, numchild=0, desc='u').save()
1889
5b4ab568ff33
        model(path='44', depth=4, numchild=500, desc='o').save()
1890
5b4ab568ff33
        model(path='434', depth=321, numchild=543, desc='i').save()
1891
5b4ab568ff33
        model(path='4343', depth=321, numchild=543, desc='e').save()
1892
5b4ab568ff33
        model(path='41', depth=1, numchild=1, desc='a').save()
1893
5b4ab568ff33
        model(path='3', depth=221, numchild=322, desc='g').save()
1894
5b4ab568ff33
        model(path='1', depth=10, numchild=3, desc='b').save()
1895
5b4ab568ff33
        model(path='2', depth=10, numchild=3, desc='d').save()
1896
ac1ecbb55c06
1897
5b4ab568ff33
    def test_fix_tree_non_destructive(self):
1898
ac1ecbb55c06
1899
c1e2edeb3b9e
        for model in (MP_TestNodeShortPath, MP_TestSortedNodeShortPath):
1900
5b4ab568ff33
            self.add_broken_test_data(model)
1901
5b4ab568ff33
            model.fix_tree(destructive=False)
1902
5b4ab568ff33
            self.assertEqual(self.got(model), self.expected_with_holes[model])
1903
5b4ab568ff33
            model.find_problems()
1904
af911c482a44
1905
5b4ab568ff33
    def test_fix_tree_destructive(self):
1906
5b4ab568ff33
1907
5b4ab568ff33
        for model in (MP_TestNodeShortPath, MP_TestSortedNodeShortPath):
1908
5b4ab568ff33
            self.add_broken_test_data(model)
1909
5b4ab568ff33
            model.fix_tree(destructive=True)
1910
5b4ab568ff33
            self.assertEqual(self.got(model), self.expected_no_holes[model])
1911
5b4ab568ff33
            model.find_problems()
1912
cfe76918146d
1913
825d0e0b5e08
1914
808594dcc96e
class TestIssues(TestCase):
1915
808594dcc96e
    "test for http://code.google.com/p/django-treebeard/issues/detail?id=14"
1916
825d0e0b5e08
1917
808594dcc96e
    def test_many_to_many_django_user_anonymous(self):
1918
66a6725a50c1
        if not HAS_DJANGO_AUTH:  # pragma: no cover
1919
825d0e0b5e08
            self.fail('this test needs django.contrib.auth in INSTALLED_APPS')
1920
825d0e0b5e08
1921
825d0e0b5e08
        # Using AnonymousUser() in the querysets will expose non-treebeard
1922
825d0e0b5e08
        # related problems in Django 1.0
1923
825d0e0b5e08
        #
1924
825d0e0b5e08
        # Postgres:
1925
825d0e0b5e08
        #   ProgrammingError: can't adapt
1926
825d0e0b5e08
        # SQLite:
1927
825d0e0b5e08
        #   InterfaceError: Error binding parameter 4 - probably unsupported
1928
825d0e0b5e08
        #   type.
1929
825d0e0b5e08
        # MySQL compared a string to an integer field:
1930
825d0e0b5e08
        #   `treebeard_mp_testissue14_users`.`user_id` = 'AnonymousUser'
1931
825d0e0b5e08
        #
1932
825d0e0b5e08
        # Using a None field instead works (will be translated to IS NULL).
1933
825d0e0b5e08
        #
1934
825d0e0b5e08
        # anonuserobj = AnonymousUser()
1935
825d0e0b5e08
        anonuserobj = None
1936
825d0e0b5e08
1937
825d0e0b5e08
        def qs_check(qs, expected):
1938
825d0e0b5e08
            self.assertEqual(
1939
825d0e0b5e08
                [o.name for o in qs],
1940
5ce21f964dd8
                expected)
1941
825d0e0b5e08
1942
825d0e0b5e08
        user = User.objects.create_user('test_user', 'test@example.com',
1943
825d0e0b5e08
                                        'testpasswd')
1944
825d0e0b5e08
        user.save()
1945
825d0e0b5e08
        root = MP_TestIssue14.add_root(name="the root node")
1946
825d0e0b5e08
1947
fafdcac71620
        root.add_child(name="first")
1948
825d0e0b5e08
        second = root.add_child(name="second")
1949
825d0e0b5e08
1950
825d0e0b5e08
        qs_check(root.get_children(), ['first', 'second'])
1951
825d0e0b5e08
        qs_check(root.get_children().filter(Q(name="first")), ['first'])
1952
825d0e0b5e08
        qs_check(root.get_children().filter(Q(users=user)), [])
1953
825d0e0b5e08
        qs_check(
1954
825d0e0b5e08
            root.get_children().filter(Q(name="first") | Q(users=user)),
1955
825d0e0b5e08
            ['first'])
1956
5ce21f964dd8
1957
825d0e0b5e08
        user = anonuserobj
1958
825d0e0b5e08
        qs_check(
1959
825d0e0b5e08
            root.get_children().filter(Q(name="first") | Q(users=user)),
1960
825d0e0b5e08
            ['first', 'second'])
1961
825d0e0b5e08
1962
825d0e0b5e08
        user = User.objects.get(username="test_user")
1963
825d0e0b5e08
        second.users.add(user)
1964
825d0e0b5e08
1965
825d0e0b5e08
        qs_check(
1966
825d0e0b5e08
            root.get_children().filter(Q(name="first") | Q(users=user)),
1967
825d0e0b5e08
            ['first', 'second'])
1968
825d0e0b5e08
1969
825d0e0b5e08
        user = anonuserobj
1970
825d0e0b5e08
        qs_check(
1971
825d0e0b5e08
            root.get_children().filter(Q(name="first") | Q(users=user)),
1972
825d0e0b5e08
            ['first'])
1973
7a62dd4d475f
1974
7a62dd4d475f
1975
7a62dd4d475f
class TestModelAdmin(ModelAdmin):
1976
ebe6fd3444ee
    form = MoveNodeForm
1977
7a62dd4d475f
1978
7a62dd4d475f
1979
ebe6fd3444ee
class TestMoveNodeForm(TestTreeBase):
1980
ebe6fd3444ee
1981
ebe6fd3444ee
    tpl = (u'<tr><th><label for="id__position">Position:</label></th>'
1982
ebe6fd3444ee
           '<td><select name="_position" id="id__position">\n'
1983
ebe6fd3444ee
           '<option value="first-child">First child of</option>\n'
1984
ebe6fd3444ee
           '<option value="left">Before</option>\n'
1985
ebe6fd3444ee
           '<option value="right">After</option>\n'
1986
ebe6fd3444ee
           '</select></td></tr>\n'
1987
ebe6fd3444ee
           '<tr><th><label for="id__ref_node_id">Relative to:</label>'
1988
ebe6fd3444ee
           '</th><td><select name="_ref_node_id" id="id__ref_node_id">\n'
1989
ebe6fd3444ee
           '<option value="0">-- root --</option>\n')
1990
7a62dd4d475f
1991
a1c1c555e5ee
    def _multi_form_html_root_node(self):
1992
ebe6fd3444ee
        self.model.load_bulk(BASE_DATA)
1993
ebe6fd3444ee
        node = self.model.get_tree()[0]
1994
ebe6fd3444ee
        form = MoveNodeForm(instance=node)
1995
ebe6fd3444ee
        rtpl = self.tpl
1996
66a6725a50c1
        self.assertEqual(['_position', '_ref_node_id'],
1997
66a6725a50c1
                         form.base_fields.keys())
1998
ebe6fd3444ee
        for obj in self.model.get_tree():
1999
ebe6fd3444ee
            if node != obj or obj.is_descendant_of(node):
2000
ebe6fd3444ee
                rtpl += '<option value="%d">%sNode %d</option>\n' % (
2001
66a6725a50c1
                    obj.id, '. . ' * (obj.get_depth() - 1), obj.id)
2002
ebe6fd3444ee
        rtpl += '</select></td></tr>'
2003
ebe6fd3444ee
        formstr = unicode(form).replace(u' selected="selected"', u'')
2004
ebe6fd3444ee
        self.assertEqual(rtpl, formstr)
2005
ebe6fd3444ee
2006
a1c1c555e5ee
    def _multi_form_html_leaf_node(self):
2007
ebe6fd3444ee
        self.model.load_bulk(BASE_DATA)
2008
ebe6fd3444ee
        nodes = list(self.model.get_tree())
2009
ebe6fd3444ee
        node = nodes[-1]
2010
ebe6fd3444ee
        form = MoveNodeForm(instance=node)
2011
ebe6fd3444ee
        rtpl = self.tpl
2012
66a6725a50c1
        self.assertEqual(['_position', '_ref_node_id'],
2013
66a6725a50c1
                         form.base_fields.keys())
2014
ebe6fd3444ee
        for obj in self.model.get_tree():
2015
ebe6fd3444ee
            if node != obj or obj.is_descendant_of(node):
2016
ebe6fd3444ee
                rtpl += '<option value="%d">%sNode %d</option>\n' % (
2017
66a6725a50c1
                    obj.id, '. . ' * (obj.get_depth() - 1), obj.id)
2018
ebe6fd3444ee
        rtpl += '</select></td></tr>'
2019
ebe6fd3444ee
        formstr = unicode(form).replace(u' selected="selected"', u'')
2020
ebe6fd3444ee
        self.assertEqual(rtpl, formstr)
2021
ebe6fd3444ee
2022
a1c1c555e5ee
    def _multi_admin_html(self):
2023
7a62dd4d475f
        tpl = ('<tr><th><label for="id_desc">Desc:</label>'
2024
7a62dd4d475f
               '</th><td><input id="id_desc" type="text" class="vTextField" '
2025
7a62dd4d475f
               'name="desc" maxlength="255" /></td></tr>\n'
2026
ebe6fd3444ee
               '<tr><th><label for="id__position">Position:</label></th>'
2027
ebe6fd3444ee
               '<td><select name="_position" id="id__position">\n'
2028
7a62dd4d475f
               '<option value="first-child">First child of</option>\n'
2029
7a62dd4d475f
               '<option value="left">Before</option>\n'
2030
7a62dd4d475f
               '<option value="right">After</option>\n'
2031
7a62dd4d475f
               '</select></td></tr>\n'
2032
7a62dd4d475f
               '<tr><th><label for="id__ref_node_id">Relative to:</label>'
2033
7a62dd4d475f
               '</th><td><select name="_ref_node_id" id="id__ref_node_id">\n'
2034
7a62dd4d475f
               '<option value="0">-- root --</option>\n'
2035
7a62dd4d475f
               '<option value="%d">Node %d</option>\n'
2036
7a62dd4d475f
               '<option value="%d">Node %d</option>\n'
2037
7a62dd4d475f
               '<option value="%d">. . Node %d</option>\n'
2038
7a62dd4d475f
               '<option value="%d">. . Node %d</option>\n'
2039
7a62dd4d475f
               '<option value="%d">. . Node %d</option>\n'
2040
7a62dd4d475f
               '<option value="%d">. . . . Node %d</option>\n'
2041
7a62dd4d475f
               '<option value="%d">. . Node %d</option>\n'
2042
7a62dd4d475f
               '<option value="%d">Node %d</option>\n'
2043
7a62dd4d475f
               '<option value="%d">Node %d</option>\n'
2044
7a62dd4d475f
               '<option value="%d">. . Node %d</option>\n'
2045
7a62dd4d475f
               '</select></td></tr>')
2046
7a62dd4d475f
        request = None
2047
7a62dd4d475f
        self.model.load_bulk(BASE_DATA)
2048
7a62dd4d475f
        for node in self.model.objects.all():
2049
7a62dd4d475f
            site = AdminSite()
2050
7a62dd4d475f
            ma = TestModelAdmin(self.model, site)
2051
7a62dd4d475f
            self.assertEqual(
2052
7a62dd4d475f
                ['desc', '_position', '_ref_node_id'],
2053
66a6725a50c1
                ma.get_form(request).base_fields.keys())
2054
7a62dd4d475f
            self.assertEqual(
2055
7a62dd4d475f
                [(None, {'fields': ['desc', '_position', '_ref_node_id']})],
2056
66a6725a50c1
                ma.get_fieldsets(request))
2057
7a62dd4d475f
            self.assertEqual(
2058
7a62dd4d475f
                [(None, {'fields': ['desc', '_position', '_ref_node_id']})],
2059
66a6725a50c1
                ma.get_fieldsets(request, node))
2060
7a62dd4d475f
            form = ma.get_form(request)()
2061
7a62dd4d475f
            ids = []
2062
7a62dd4d475f
            for obj in self.model.get_tree():
2063
66a6725a50c1
                ids.extend([obj.id] * 2)
2064
7a62dd4d475f
            self.assertEqual(tpl % tuple(ids), unicode(form))
2065
a1c1c555e5ee
2066
02cdb123cbfa
2067
a1c1c555e5ee
_load_test_methods(TestMoveNodeForm)
2068
a1c1c555e5ee
_load_test_methods(TestEmptyTree)
2069
a1c1c555e5ee
_load_test_methods(TestClassMethods)
2070
a1c1c555e5ee
_load_test_methods(TestSimpleNodeMethods)
2071
a1c1c555e5ee
_load_test_methods(TestAddChild)
2072
a1c1c555e5ee
_load_test_methods(TestAddSibling)
2073
a1c1c555e5ee
_load_test_methods(TestDelete)
2074
a1c1c555e5ee
_load_test_methods(TestMoveErrors)
2075
a1c1c555e5ee
_load_test_methods(TestMoveLeafRoot)
2076
a1c1c555e5ee
_load_test_methods(TestMoveLeaf)
2077
a1c1c555e5ee
_load_test_methods(TestMoveBranchRoot)
2078
a1c1c555e5ee
_load_test_methods(TestMoveBranch)
2079
a1c1c555e5ee
_load_test_methods(TestHelpers)
2080
952e3b329377
# we didn't create extra sorted-proxy models
2081
81fa32fd2e26
_load_test_methods(TestMoveSortedErrors, proxy=False)
2082
81fa32fd2e26
_load_test_methods(TestTreeSorted, proxy=False)