1
from test.lib.testing import eq_, ne_
3
from sqlalchemy.orm import dynamic_loader, backref, configure_mappers
4
from test.lib import testing
5
from sqlalchemy import Integer, String, ForeignKey, desc, select, func, exc
6
from test.lib.schema import Table, Column
7
from sqlalchemy.orm import mapper, relationship, create_session, Query, attributes
1
from sqlalchemy.testing import eq_, is_
2
from sqlalchemy.orm import backref, configure_mappers
3
from sqlalchemy import testing
4
from sqlalchemy import desc, select, func, exc
5
from sqlalchemy.orm import mapper, relationship, create_session, Query, \
6
attributes, exc as orm_exc, Session
8
7
from sqlalchemy.orm.dynamic import AppenderMixin
9
from test.lib.testing import eq_, AssertsCompiledSQL, assert_raises_message, assert_raises
10
from test.lib import fixtures
8
from sqlalchemy.testing import AssertsCompiledSQL, \
9
assert_raises_message, assert_raises
11
10
from test.orm import _fixtures
14
class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
12
from sqlalchemy.testing.assertsql import CompiledSQL
16
class _DynamicFixture(object):
17
def _user_address_fixture(self, addresses_args={}):
18
users, Address, addresses, User = (self.tables.users,
20
self.tables.addresses,
23
mapper(User, users, properties={
24
'addresses': relationship(Address, lazy="dynamic",
27
mapper(Address, addresses)
30
def _order_item_fixture(self, items_args={}):
31
items, Order, orders, order_items, Item = (self.tables.items,
34
self.tables.order_items,
37
mapper(Order, orders, properties={
38
'items': relationship(Item,
39
secondary=order_items,
47
class DynamicTest(_DynamicFixture, _fixtures.FixtureTest, AssertsCompiledSQL):
15
49
def test_basic(self):
16
users, Address, addresses, User = (self.tables.users,
18
self.tables.addresses,
21
mapper(User, users, properties={
22
'addresses':dynamic_loader(mapper(Address, addresses))
50
User, Address = self._user_address_fixture()
24
51
sess = create_session()
25
52
q = sess.query(User)
27
u = q.filter(User.id==7).first()
30
55
addresses=[Address(id=1, email_address='jack@bean.com')])],
31
q.filter(User.id==7).all())
56
q.filter(User.id == 7).all())
32
57
eq_(self.static.user_address_result, q.all())
34
59
def test_statement(self):
35
60
"""test that the .statement accessor returns the actual statement that
36
61
would render, without any _clones called."""
38
users, Address, addresses, User = (self.tables.users,
40
self.tables.addresses,
44
mapper(User, users, properties={
45
'addresses':dynamic_loader(mapper(Address, addresses))
63
User, Address = self._user_address_fixture()
47
64
sess = create_session()
48
65
q = sess.query(User)
50
u = q.filter(User.id==7).first()
67
u = q.filter(User.id == 7).first()
51
68
self.assert_compile(
52
69
u.addresses.statement,
53
"SELECT addresses.id, addresses.user_id, addresses.email_address FROM "
70
"SELECT addresses.id, addresses.user_id, addresses.email_address "
54
72
"addresses WHERE :param_1 = addresses.user_id",
55
73
use_default_dialect=True
76
def test_detached_raise(self):
77
User, Address = self._user_address_fixture()
78
sess = create_session()
79
u = sess.query(User).get(8)
82
orm_exc.DetachedInstanceError,
83
u.addresses.filter_by,
58
87
def test_no_uselist_false(self):
59
users, Address, addresses, User = (self.tables.users,
61
self.tables.addresses,
63
mapper(Address, addresses)
64
mapper(User, users, properties={
65
"addresses": relationship(Address, lazy='dynamic', uselist=False)
88
User, Address = self._user_address_fixture(
89
addresses_args={"uselist": False})
67
90
assert_raises_message(
91
exc.InvalidRequestError,
69
92
"On relationship User.addresses, 'dynamic' loaders cannot be "
70
93
"used with many-to-one/one-to-one relationships and/or "
92
115
def test_order_by(self):
93
users, Address, addresses, User = (self.tables.users,
95
self.tables.addresses,
98
mapper(User, users, properties={
99
'addresses': dynamic_loader(mapper(Address, addresses))
116
User, Address = self._user_address_fixture()
101
117
sess = create_session()
102
118
u = sess.query(User).get(8)
104
120
list(u.addresses.order_by(desc(Address.email_address))),
105
[Address(email_address=u'ed@wood.com'), Address(email_address=u'ed@lala.com'),
106
Address(email_address=u'ed@bettyboop.com')]
122
Address(email_address=u'ed@wood.com'),
123
Address(email_address=u'ed@lala.com'),
124
Address(email_address=u'ed@bettyboop.com')
109
128
def test_configured_order_by(self):
110
users, Address, addresses, User = (self.tables.users,
111
self.classes.Address,
112
self.tables.addresses,
129
addresses = self.tables.addresses
130
User, Address = self._user_address_fixture(
133
addresses.c.email_address.desc()})
115
mapper(User, users, properties={
116
'addresses':dynamic_loader(mapper(Address, addresses), order_by=desc(Address.email_address))
118
135
sess = create_session()
119
136
u = sess.query(User).get(8)
120
eq_(list(u.addresses), [Address(email_address=u'ed@wood.com'), Address(email_address=u'ed@lala.com'), Address(email_address=u'ed@bettyboop.com')])
140
Address(email_address=u'ed@wood.com'),
141
Address(email_address=u'ed@lala.com'),
142
Address(email_address=u'ed@bettyboop.com')
122
146
# test cancellation of None, replacement with something else
124
148
list(u.addresses.order_by(None).order_by(Address.email_address)),
125
[Address(email_address=u'ed@bettyboop.com'), Address(email_address=u'ed@lala.com'), Address(email_address=u'ed@wood.com')]
150
Address(email_address=u'ed@bettyboop.com'),
151
Address(email_address=u'ed@lala.com'),
152
Address(email_address=u'ed@wood.com')
128
156
# test cancellation of None, replacement with nothing
130
158
set(u.addresses.order_by(None)),
131
set([Address(email_address=u'ed@bettyboop.com'), Address(email_address=u'ed@lala.com'), Address(email_address=u'ed@wood.com')])
160
Address(email_address=u'ed@bettyboop.com'),
161
Address(email_address=u'ed@lala.com'),
162
Address(email_address=u'ed@wood.com')
134
166
def test_count(self):
135
users, Address, addresses, User = (self.tables.users,
136
self.classes.Address,
137
self.tables.addresses,
140
mapper(User, users, properties={
141
'addresses':dynamic_loader(mapper(Address, addresses))
167
User, Address = self._user_address_fixture()
143
168
sess = create_session()
144
169
u = sess.query(User).first()
145
170
eq_(u.addresses.count(), 1)
147
def test_backref(self):
172
def test_dynamic_on_backref(self):
148
173
users, Address, addresses, User = (self.tables.users,
149
174
self.classes.Address,
150
175
self.tables.addresses,
151
176
self.classes.User)
153
178
mapper(Address, addresses, properties={
154
'user':relationship(User, backref=backref('addresses', lazy='dynamic'))
179
'user': relationship(User,
180
backref=backref('addresses', lazy='dynamic'))
156
182
mapper(User, users)
350
345
eq_(type(q).__name__, 'MyQuery')
353
class SessionTest(_fixtures.FixtureTest):
348
class UOWTest(_DynamicFixture, _fixtures.FixtureTest,
349
testing.AssertsExecutionResults):
354
350
run_inserts = None
356
def test_events(self):
357
users, Address, addresses, User = (self.tables.users,
358
self.classes.Address,
359
self.tables.addresses,
352
def test_persistence(self):
353
addresses = self.tables.addresses
354
User, Address = self._user_address_fixture()
362
mapper(User, users, properties={
363
'addresses':dynamic_loader(mapper(Address, addresses))
365
356
sess = create_session()
366
357
u1 = User(name='jack')
367
358
a1 = Address(email_address='foo')
368
359
sess.add_all([u1, a1])
371
eq_(testing.db.scalar(select([func.count(1)]).where(addresses.c.user_id!=None)), 0)
364
select([func.count(1)]).where(addresses.c.user_id != None)
372
368
u1 = sess.query(User).get(u1.id)
373
369
u1.addresses.append(a1)
376
eq_(testing.db.execute(select([addresses]).where(addresses.c.user_id!=None)).fetchall(),
377
[(a1.id, u1.id, 'foo')])
374
select([addresses]).where(addresses.c.user_id != None)
376
[(a1.id, u1.id, 'foo')]
379
379
u1.addresses.remove(a1)
381
eq_(testing.db.scalar(select([func.count(1)]).where(addresses.c.user_id!=None)), 0)
383
select([func.count(1)]).where(addresses.c.user_id != None)
383
388
u1.addresses.append(a1)
385
eq_(testing.db.execute(select([addresses]).where(addresses.c.user_id!=None)).fetchall(),
386
[(a1.id, u1.id, 'foo')])
392
select([addresses]).where(addresses.c.user_id != None)
394
[(a1.id, u1.id, 'foo')]
388
397
a2 = Address(email_address='bar')
389
398
u1.addresses.remove(a1)
390
399
u1.addresses.append(a2)
392
eq_(testing.db.execute(select([addresses]).where(addresses.c.user_id!=None)).fetchall(),
393
[(a2.id, u1.id, 'bar')])
403
select([addresses]).where(addresses.c.user_id != None)
405
[(a2.id, u1.id, 'bar')]
396
409
def test_merge(self):
397
users, Address, addresses, User = (self.tables.users,
398
self.classes.Address,
399
self.tables.addresses,
402
mapper(User, users, properties={
403
'addresses':dynamic_loader(mapper(Address, addresses), order_by=addresses.c.email_address)
410
addresses = self.tables.addresses
411
User, Address = self._user_address_fixture(
413
"order_by": addresses.c.email_address})
405
414
sess = create_session()
406
415
u1 = User(name='jack')
407
416
a1 = Address(email_address='a1')
434
def test_flush(self):
435
users, Address, addresses, User = (self.tables.users,
436
self.classes.Address,
437
self.tables.addresses,
440
mapper(User, users, properties={
441
'addresses':dynamic_loader(mapper(Address, addresses))
443
sess = create_session()
444
u1 = User(name='jack')
446
u2.addresses.append(Address(email_address='foo@bar.com'))
447
u1.addresses.append(Address(email_address='lala@hoho.com'))
448
sess.add_all((u1, u2))
451
from sqlalchemy.orm import attributes
452
eq_(attributes.get_history(u1, 'addresses'), ([], [Address(email_address='lala@hoho.com')], []))
456
# test the test fixture a little bit
457
ne_(User(name='jack', addresses=[Address(email_address='wrong')]),
458
sess.query(User).first())
459
eq_(User(name='jack', addresses=[Address(email_address='lala@hoho.com')]),
460
sess.query(User).first())
463
User(name='jack', addresses=[Address(email_address='lala@hoho.com')]),
464
User(name='ed', addresses=[Address(email_address='foo@bar.com')])
466
sess.query(User).all())
468
443
def test_hasattr(self):
469
users, Address, addresses, User = (self.tables.users,
470
self.classes.Address,
471
self.tables.addresses,
444
User, Address = self._user_address_fixture()
474
mapper(User, users, properties={
475
'addresses':dynamic_loader(mapper(Address, addresses))
477
446
u1 = User(name='jack')
479
assert 'addresses' not in u1.__dict__.keys()
448
assert 'addresses' not in u1.__dict__
480
449
u1.addresses = [Address(email_address='test')]
481
assert 'addresses' in dir(u1)
450
assert 'addresses' in u1.__dict__
483
452
def test_collection_set(self):
484
users, Address, addresses, User = (self.tables.users,
485
self.classes.Address,
486
self.tables.addresses,
489
mapper(User, users, properties={
490
'addresses':dynamic_loader(mapper(Address, addresses), order_by=addresses.c.email_address)
453
addresses = self.tables.addresses
454
User, Address = self._user_address_fixture(
456
"order_by": addresses.c.email_address})
492
457
sess = create_session(autoflush=True, autocommit=False)
493
458
u1 = User(name='jack')
494
459
a1 = Address(email_address='a1')
506
471
u1.addresses = []
507
472
eq_(list(u1.addresses), [])
474
def test_noload_append(self):
475
# test that a load of User.addresses is not emitted
476
# when flushing an append
477
User, Address = self._user_address_fixture()
480
u1 = User(name="jack", addresses=[Address(email_address="a1")])
487
u1.addresses.append(Address(email_address='a2'))
489
self.assert_sql_execution(
493
"SELECT users.id AS users_id, users.name AS users_name "
494
"FROM users WHERE users.id = :param_1",
495
lambda ctx: [{"param_1": u1_id}]),
497
"INSERT INTO addresses (user_id, email_address) "
498
"VALUES (:user_id, :email_address)",
499
lambda ctx: [{'email_address': 'a2', 'user_id': u1_id}]
503
def test_noload_remove(self):
504
# test that a load of User.addresses is not emitted
505
# when flushing a remove
506
User, Address = self._user_address_fixture()
509
u1 = User(name="jack", addresses=[Address(email_address="a1")])
510
a2 = Address(email_address='a2')
511
u1.addresses.append(a2)
519
u1.addresses.remove(a2)
521
self.assert_sql_execution(
525
"SELECT users.id AS users_id, users.name AS users_name "
526
"FROM users WHERE users.id = :param_1",
527
lambda ctx: [{"param_1": u1_id}]),
529
"SELECT addresses.id AS addresses_id, addresses.email_address "
530
"AS addresses_email_address FROM addresses "
531
"WHERE addresses.id = :param_1",
532
lambda ctx: [{u'param_1': a2_id}]
535
"UPDATE addresses SET user_id=:user_id WHERE addresses.id = "
537
lambda ctx: [{u'addresses_id': a2_id, 'user_id': None}]
509
541
def test_rollback(self):
510
users, Address, addresses, User = (self.tables.users,
511
self.classes.Address,
512
self.tables.addresses,
515
mapper(User, users, properties={
516
'addresses':dynamic_loader(mapper(Address, addresses))
518
sess = create_session(expire_on_commit=False, autocommit=False, autoflush=True)
542
User, Address = self._user_address_fixture()
543
sess = create_session(
544
expire_on_commit=False, autocommit=False, autoflush=True)
519
545
u1 = User(name='jack')
520
546
u1.addresses.append(Address(email_address='lala@hoho.com'))
524
550
u1.addresses.append(Address(email_address='foo@bar.com'))
525
eq_(u1.addresses.order_by(Address.id).all(),
526
[Address(email_address='lala@hoho.com'), Address(email_address='foo@bar.com')])
552
u1.addresses.order_by(Address.id).all(),
554
Address(email_address='lala@hoho.com'),
555
Address(email_address='foo@bar.com')
528
eq_(u1.addresses.all(), [Address(email_address='lala@hoho.com')])
530
@testing.fails_on('maxdb', 'FIXME: unknown')
561
[Address(email_address='lala@hoho.com')]
564
def _test_delete_cascade(self, expected):
565
addresses = self.tables.addresses
566
User, Address = self._user_address_fixture(addresses_args={
567
"order_by": addresses.c.id,
569
"cascade": "save-update" if expected \
573
sess = create_session(autoflush=True, autocommit=False)
576
[Address(email_address=letter) for letter in 'abcdef']
580
eq_(testing.db.scalar(
581
addresses.count(addresses.c.user_id == None)), 0)
582
eq_(testing.db.scalar(
583
addresses.count(addresses.c.user_id != None)), 6)
590
eq_(testing.db.scalar(
591
addresses.count(addresses.c.user_id == None)), 6)
592
eq_(testing.db.scalar(
593
addresses.count(addresses.c.user_id != None)), 0)
595
eq_(testing.db.scalar(addresses.count()), 0)
531
597
def test_delete_nocascade(self):
532
users, Address, addresses, User = (self.tables.users,
533
self.classes.Address,
534
self.tables.addresses,
537
mapper(User, users, properties={
538
'addresses':dynamic_loader(mapper(Address, addresses), order_by=Address.id,
541
sess = create_session(autoflush=True, autocommit=False)
543
u.addresses.append(Address(email_address='a'))
544
u.addresses.append(Address(email_address='b'))
545
u.addresses.append(Address(email_address='c'))
546
u.addresses.append(Address(email_address='d'))
547
u.addresses.append(Address(email_address='e'))
548
u.addresses.append(Address(email_address='f'))
551
eq_(Address(email_address='c'), u.addresses[2])
552
sess.delete(u.addresses[2])
553
sess.delete(u.addresses[4])
554
sess.delete(u.addresses[3])
555
eq_([Address(email_address='a'), Address(email_address='b'), Address(email_address='d')],
559
u = sess.query(User).get(u.id)
563
# u.addresses relationship will have to force the load
564
# of all addresses so that they can be updated
568
eq_(testing.db.scalar(addresses.count(addresses.c.user_id != None)), 0)
570
@testing.fails_on('maxdb', 'FIXME: unknown')
598
self._test_delete_cascade(True)
571
600
def test_delete_cascade(self):
572
users, Address, addresses, User = (self.tables.users,
573
self.classes.Address,
574
self.tables.addresses,
577
mapper(User, users, properties={
578
'addresses':dynamic_loader(mapper(Address, addresses), order_by=Address.id,
579
backref='user', cascade="all, delete-orphan")
581
sess = create_session(autoflush=True, autocommit=False)
583
u.addresses.append(Address(email_address='a'))
584
u.addresses.append(Address(email_address='b'))
585
u.addresses.append(Address(email_address='c'))
586
u.addresses.append(Address(email_address='d'))
587
u.addresses.append(Address(email_address='e'))
588
u.addresses.append(Address(email_address='f'))
591
eq_(Address(email_address='c'), u.addresses[2])
592
sess.delete(u.addresses[2])
593
sess.delete(u.addresses[4])
594
sess.delete(u.addresses[3])
595
eq_([Address(email_address='a'), Address(email_address='b'), Address(email_address='d')],
599
u = sess.query(User).get(u.id)
603
# u.addresses relationship will have to force the load
604
# of all addresses so that they can be updated
608
eq_(testing.db.scalar(addresses.count()), 0)
610
@testing.fails_on('maxdb', 'FIXME: unknown')
601
self._test_delete_cascade(False)
611
603
def test_remove_orphans(self):
612
users, Address, addresses, User = (self.tables.users,
613
self.classes.Address,
614
self.tables.addresses,
604
addresses = self.tables.addresses
605
User, Address = self._user_address_fixture(addresses_args={
606
"order_by": addresses.c.id,
608
"cascade": "all, delete-orphan"
617
mapper(User, users, properties={
618
'addresses':dynamic_loader(mapper(Address, addresses), order_by=Address.id,
619
cascade="all, delete-orphan", backref='user')
621
611
sess = create_session(autoflush=True, autocommit=False)
622
612
u = User(name='ed')
623
u.addresses.append(Address(email_address='a'))
624
u.addresses.append(Address(email_address='b'))
625
u.addresses.append(Address(email_address='c'))
626
u.addresses.append(Address(email_address='d'))
627
u.addresses.append(Address(email_address='e'))
628
u.addresses.append(Address(email_address='f'))
614
[Address(email_address=letter) for letter in 'abcdef']
631
eq_([Address(email_address='a'), Address(email_address='b'), Address(email_address='c'),
632
Address(email_address='d'), Address(email_address='e'), Address(email_address='f')],
633
sess.query(Address).all())
635
eq_(Address(email_address='c'), u.addresses[2])
644
for a in u.addresses.filter(Address.email_address.in_(['c', 'e', 'f'])):
618
for a in u.addresses.filter(
619
Address.email_address.in_(['c', 'e', 'f'])):
645
620
u.addresses.remove(a)
647
eq_([Address(email_address='a'), Address(email_address='b'), Address(email_address='d')],
650
eq_([Address(email_address='a'), Address(email_address='b'), Address(email_address='d')],
651
sess.query(Address).all())
623
set(ad for ad, in sess.query(Address.email_address)),
656
627
def _backref_test(self, autoflush, saveuser):
657
users, Address, addresses, User = (self.tables.users,
658
self.classes.Address,
659
self.tables.addresses,
662
mapper(User, users, properties={
663
'addresses':dynamic_loader(mapper(Address, addresses), backref='user')
628
User, Address = self._user_address_fixture(addresses_args={
665
631
sess = create_session(autoflush=autoflush, autocommit=False)
667
633
u = User(name='buffy')
702
668
def test_backref_savead(self):
703
669
self._backref_test(False, False)
705
class DontDereferenceTest(fixtures.MappedTest):
707
def define_tables(cls, metadata):
708
Table('users', metadata,
709
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
710
Column('name', String(40)),
711
Column('fullname', String(100)),
712
Column('password', String(15)))
714
Table('addresses', metadata,
715
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
716
Column('email_address', String(100), nullable=False),
717
Column('user_id', Integer, ForeignKey('users.id')))
720
def setup_mappers(cls):
721
users, addresses = cls.tables.users, cls.tables.addresses
723
class User(cls.Comparable):
726
class Address(cls.Comparable):
729
mapper(User, users, properties={
730
'addresses': relationship(Address, backref='user', lazy='dynamic')
671
def test_backref_events(self):
672
User, Address = self._user_address_fixture(addresses_args={
732
mapper(Address, addresses)
678
u1.addresses.append(a1)
734
681
def test_no_deref(self):
735
User, Address = self.classes.User, self.classes.Address
682
User, Address = self._user_address_fixture(addresses_args={
737
686
session = create_session()
764
713
eq_(query2(), [Address(email_address='joe@joesdomain.example')])
765
714
eq_(query3(), [Address(email_address='joe@joesdomain.example')])
716
class HistoryTest(_DynamicFixture, _fixtures.FixtureTest):
719
def _transient_fixture(self, addresses_args={}):
720
User, Address = self._user_address_fixture(
721
addresses_args=addresses_args)
727
def _persistent_fixture(self, autoflush=True, addresses_args={}):
728
User, Address = self._user_address_fixture(
729
addresses_args=addresses_args)
732
a1 = Address(email_address='a1')
733
s = Session(autoflush=autoflush)
738
def _persistent_m2m_fixture(self, autoflush=True, items_args={}):
739
Order, Item = self._order_item_fixture(items_args=items_args)
742
i1 = Item(description="i1")
743
s = Session(autoflush=autoflush)
748
def _assert_history(self, obj, compare, compare_passive=None):
749
if isinstance(obj, self.classes.User):
750
attrname = "addresses"
751
elif isinstance(obj, self.classes.Order):
755
attributes.get_history(obj, attrname),
759
if compare_passive is None:
760
compare_passive = compare
763
attributes.get_history(obj, attrname,
764
attributes.LOAD_AGAINST_COMMITTED),
768
def test_append_transient(self):
769
u1, a1 = self._transient_fixture()
770
u1.addresses.append(a1)
772
self._assert_history(u1,
776
def test_append_persistent(self):
777
u1, a1, s = self._persistent_fixture()
778
u1.addresses.append(a1)
780
self._assert_history(u1,
784
def test_remove_transient(self):
785
u1, a1 = self._transient_fixture()
786
u1.addresses.append(a1)
787
u1.addresses.remove(a1)
789
self._assert_history(u1,
793
def test_backref_pop_transient(self):
794
u1, a1 = self._transient_fixture(addresses_args={"backref": "user"})
795
u1.addresses.append(a1)
797
self._assert_history(u1,
804
self._assert_history(u1,
808
def test_remove_persistent(self):
809
u1, a1, s = self._persistent_fixture()
810
u1.addresses.append(a1)
814
u1.addresses.remove(a1)
816
self._assert_history(u1,
820
def test_backref_pop_persistent_autoflush_o2m_active_hist(self):
821
u1, a1, s = self._persistent_fixture(
822
addresses_args={"backref":
823
backref("user", active_history=True)})
824
u1.addresses.append(a1)
830
self._assert_history(u1,
834
def test_backref_pop_persistent_autoflush_m2m(self):
835
o1, i1, s = self._persistent_m2m_fixture(
836
items_args={"backref": "orders"})
843
self._assert_history(o1,
847
def test_backref_pop_persistent_noflush_m2m(self):
848
o1, i1, s = self._persistent_m2m_fixture(
849
items_args={"backref": "orders"}, autoflush=False)
856
self._assert_history(o1,
860
def test_unchanged_persistent(self):
861
Address = self.classes.Address
863
u1, a1, s = self._persistent_fixture()
864
a2, a3 = Address(email_address='a2'), Address(email_address='a3')
866
u1.addresses.append(a1)
867
u1.addresses.append(a2)
870
u1.addresses.append(a3)
871
u1.addresses.remove(a2)
873
self._assert_history(u1,
875
compare_passive=([a3], [], [a2])
878
def test_replace_transient(self):
879
Address = self.classes.Address
881
u1, a1 = self._transient_fixture()
882
a2, a3, a4, a5 = Address(email_address='a2'), \
883
Address(email_address='a3'), \
884
Address(email_address='a4'), \
885
Address(email_address='a5')
887
u1.addresses = [a1, a2]
888
u1.addresses = [a2, a3, a4, a5]
890
self._assert_history(u1,
891
([a2, a3, a4, a5], [], [])
894
def test_replace_persistent_noflush(self):
895
Address = self.classes.Address
897
u1, a1, s = self._persistent_fixture(autoflush=False)
898
a2, a3, a4, a5 = Address(email_address='a2'), \
899
Address(email_address='a3'), \
900
Address(email_address='a4'), \
901
Address(email_address='a5')
903
u1.addresses = [a1, a2]
904
u1.addresses = [a2, a3, a4, a5]
906
self._assert_history(u1,
907
([a2, a3, a4, a5], [], [])
910
def test_replace_persistent_autoflush(self):
911
Address = self.classes.Address
913
u1, a1, s = self._persistent_fixture(autoflush=True)
914
a2, a3, a4, a5 = Address(email_address='a2'), \
915
Address(email_address='a3'), \
916
Address(email_address='a4'), \
917
Address(email_address='a5')
919
u1.addresses = [a1, a2]
920
u1.addresses = [a2, a3, a4, a5]
922
self._assert_history(u1,
923
([a3, a4, a5], [a2], [a1]),
924
compare_passive=([a3, a4, a5], [], [a1])
928
def test_persistent_but_readded_noflush(self):
929
u1, a1, s = self._persistent_fixture(autoflush=False)
930
u1.addresses.append(a1)
933
u1.addresses.append(a1)
935
self._assert_history(u1,
937
compare_passive=([a1], [], [])
940
def test_persistent_but_readded_autoflush(self):
941
u1, a1, s = self._persistent_fixture(autoflush=True)
942
u1.addresses.append(a1)
945
u1.addresses.append(a1)
947
self._assert_history(u1,
949
compare_passive=([a1], [], [])
952
def test_missing_but_removed_noflush(self):
953
u1, a1, s = self._persistent_fixture(autoflush=False)
955
u1.addresses.remove(a1)
957
self._assert_history(u1,
959
compare_passive=([], [], [a1])