diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-02-16 15:43:22 -0500 | 
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-02-16 15:43:22 -0500 | 
| commit | c46b49496c44db30b5a801cca8321837c5ac8ce4 (patch) | |
| tree | d471dc5748d0a3d678c0a12721256d90ea644180 /test/ext/test_mutable.py | |
| parent | e310a8e423d9a4eeb511b7b84dbeccc90c234a1f (diff) | |
| parent | f7354b43e4c993e9070ad104fcaab424ad2df276 (diff) | |
| download | sqlalchemy-c46b49496c44db30b5a801cca8321837c5ac8ce4.tar.gz | |
Merge remote-tracking branch 'origin/pr/236'
Diffstat (limited to 'test/ext/test_mutable.py')
| -rw-r--r-- | test/ext/test_mutable.py | 413 | 
1 files changed, 412 insertions, 1 deletions
diff --git a/test/ext/test_mutable.py b/test/ext/test_mutable.py index 602ff911a..1e1a75e7e 100644 --- a/test/ext/test_mutable.py +++ b/test/ext/test_mutable.py @@ -8,7 +8,7 @@ from sqlalchemy.testing import eq_, assert_raises_message, assert_raises  from sqlalchemy.testing.util import picklers  from sqlalchemy.testing import fixtures  from sqlalchemy.ext.mutable import MutableComposite -from sqlalchemy.ext.mutable import MutableDict +from sqlalchemy.ext.mutable import MutableDict, MutableList, MutableSet  class Foo(fixtures.BasicEntity): @@ -261,6 +261,383 @@ class _MutableDictTestBase(_MutableDictTestFixture):          eq_(f1.non_mutable_data, {'a': 'b'}) +class _MutableListTestFixture(object): +    @classmethod +    def _type_fixture(cls): +        return MutableList + +    def teardown(self): +        # clear out mapper events +        Mapper.dispatch._clear() +        ClassManager.dispatch._clear() +        super(_MutableListTestFixture, self).teardown() + + +class _MutableListTestBase(_MutableListTestFixture): +    run_define_tables = 'each' + +    def setup_mappers(cls): +        foo = cls.tables.foo + +        mapper(Foo, foo) + +    def test_coerce_none(self): +        sess = Session() +        f1 = Foo(data=None) +        sess.add(f1) +        sess.commit() +        eq_(f1.data, None) + +    def test_coerce_raise(self): +        assert_raises_message( +            ValueError, +            "Attribute 'data' does not accept objects of type", +            Foo, data=set([1, 2, 3]) +        ) + +    def test_in_place_mutation(self): +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data[0] = 3 +        sess.commit() + +        eq_(f1.data, [3, 2]) + +    def test_in_place_slice_mutation(self): +        sess = Session() + +        f1 = Foo(data=[1, 2, 3, 4]) +        sess.add(f1) +        sess.commit() + +        f1.data[1:3] = 5, 6 +        sess.commit() + +        eq_(f1.data, [1, 5, 6, 4]) + +    def test_del_slice(self): +        sess = Session() + +        f1 = Foo(data=[1, 2, 3, 4]) +        sess.add(f1) +        sess.commit() + +        del f1.data[1:3] +        sess.commit() + +        eq_(f1.data, [1, 4]) + +    def test_clear(self): +        if not hasattr(list, 'clear'): +            # py2 list doesn't have 'clear' +            return +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.clear() +        sess.commit() + +        eq_(f1.data, []) + +    def test_pop(self): +        sess = Session() + +        f1 = Foo(data=[1, 2, 3]) +        sess.add(f1) +        sess.commit() + +        eq_(f1.data.pop(), 3) +        eq_(f1.data.pop(0), 1) +        sess.commit() + +        assert_raises(IndexError, f1.data.pop, 5) + +        eq_(f1.data, [2]) + +    def test_append(self): +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.append(5) +        sess.commit() + +        eq_(f1.data, [1, 2, 5]) + +    def test_extend(self): +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.extend([5]) +        sess.commit() + +        eq_(f1.data, [1, 2, 5]) + +    def test_insert(self): +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.insert(1, 5) +        sess.commit() + +        eq_(f1.data, [1, 5, 2]) + +    def test_remove(self): +        sess = Session() + +        f1 = Foo(data=[1, 2, 3]) +        sess.add(f1) +        sess.commit() + +        f1.data.remove(2) +        sess.commit() + +        eq_(f1.data, [1, 3]) + +    def test_sort(self): +        sess = Session() + +        f1 = Foo(data=[1, 3, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.sort() +        sess.commit() + +        eq_(f1.data, [1, 2, 3]) + +    def test_reverse(self): +        sess = Session() + +        f1 = Foo(data=[1, 3, 2]) +        sess.add(f1) +        sess.commit() + +        f1.data.reverse() +        sess.commit() + +        eq_(f1.data, [2, 3, 1]) + +    def test_pickle_parent(self): +        sess = Session() + +        f1 = Foo(data=[1, 2]) +        sess.add(f1) +        sess.commit() +        f1.data +        sess.close() + +        for loads, dumps in picklers(): +            sess = Session() +            f2 = loads(dumps(f1)) +            sess.add(f2) +            f2.data[0] = 3 +            assert f2 in sess.dirty + +    def test_unrelated_flush(self): +        sess = Session() +        f1 = Foo(data=[1, 2], unrelated_data="unrelated") +        sess.add(f1) +        sess.flush() +        f1.unrelated_data = "unrelated 2" +        sess.flush() +        f1.data[0] = 3 +        sess.commit() +        eq_(f1.data[0], 3) + + +class _MutableSetTestFixture(object): +    @classmethod +    def _type_fixture(cls): +        return MutableSet + +    def teardown(self): +        # clear out mapper events +        Mapper.dispatch._clear() +        ClassManager.dispatch._clear() +        super(_MutableSetTestFixture, self).teardown() + + +class _MutableSetTestBase(_MutableSetTestFixture): +    run_define_tables = 'each' + +    def setup_mappers(cls): +        foo = cls.tables.foo + +        mapper(Foo, foo) + +    def test_coerce_none(self): +        sess = Session() +        f1 = Foo(data=None) +        sess.add(f1) +        sess.commit() +        eq_(f1.data, None) + +    def test_coerce_raise(self): +        assert_raises_message( +            ValueError, +            "Attribute 'data' does not accept objects of type", +            Foo, data=[1, 2, 3] +        ) + +    def test_clear(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.clear() +        sess.commit() + +        eq_(f1.data, set()) + +    def test_pop(self): +        sess = Session() + +        f1 = Foo(data=set([1])) +        sess.add(f1) +        sess.commit() + +        eq_(f1.data.pop(), 1) +        sess.commit() + +        assert_raises(KeyError, f1.data.pop) + +        eq_(f1.data, set()) + +    def test_add(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.add(5) +        sess.commit() + +        eq_(f1.data, set([1, 2, 5])) + +    def test_update(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.update(set([2, 5])) +        sess.commit() + +        eq_(f1.data, set([1, 2, 5])) + +    def test_intersection_update(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.intersection_update(set([2, 5])) +        sess.commit() + +        eq_(f1.data, set([2])) + +    def test_difference_update(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.difference_update(set([2, 5])) +        sess.commit() + +        eq_(f1.data, set([1])) + +    def test_symmetric_difference_update(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() + +        f1.data.symmetric_difference_update(set([2, 5])) +        sess.commit() + +        eq_(f1.data, set([1, 5])) + +    def test_remove(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2, 3])) +        sess.add(f1) +        sess.commit() + +        f1.data.remove(2) +        sess.commit() + +        eq_(f1.data, set([1, 3])) + +    def test_discard(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2, 3])) +        sess.add(f1) +        sess.commit() + +        f1.data.discard(2) +        sess.commit() + +        eq_(f1.data, set([1, 3])) + +        f1.data.discard(2) +        sess.commit() + +        eq_(f1.data, set([1, 3])) + +    def test_pickle_parent(self): +        sess = Session() + +        f1 = Foo(data=set([1, 2])) +        sess.add(f1) +        sess.commit() +        f1.data +        sess.close() + +        for loads, dumps in picklers(): +            sess = Session() +            f2 = loads(dumps(f1)) +            sess.add(f2) +            f2.data.add(3) +            assert f2 in sess.dirty + +    def test_unrelated_flush(self): +        sess = Session() +        f1 = Foo(data=set([1, 2]), unrelated_data="unrelated") +        sess.add(f1) +        sess.flush() +        f1.unrelated_data = "unrelated 2" +        sess.flush() +        f1.data.add(3) +        sess.commit() +        eq_(f1.data, set([1, 2, 3])) + +  class MutableColumnDefaultTest(_MutableDictTestFixture, fixtures.MappedTest):      @classmethod      def define_tables(cls, metadata): @@ -349,6 +726,40 @@ class MutableWithScalarJSONTest(_MutableDictTestBase, fixtures.MappedTest):          self._test_non_mutable() +class MutableListWithScalarPickleTest(_MutableListTestBase, fixtures.MappedTest): + +    @classmethod +    def define_tables(cls, metadata): +        MutableList = cls._type_fixture() + +        mutable_pickle = MutableList.as_mutable(PickleType) +        Table('foo', metadata, +              Column('id', Integer, primary_key=True, +                     test_needs_autoincrement=True), +              Column('skip', mutable_pickle), +              Column('data', mutable_pickle), +              Column('non_mutable_data', PickleType), +              Column('unrelated_data', String(50)) +              ) + + +class MutableSetWithScalarPickleTest(_MutableSetTestBase, fixtures.MappedTest): + +    @classmethod +    def define_tables(cls, metadata): +        MutableSet = cls._type_fixture() + +        mutable_pickle = MutableSet.as_mutable(PickleType) +        Table('foo', metadata, +              Column('id', Integer, primary_key=True, +                     test_needs_autoincrement=True), +              Column('skip', mutable_pickle), +              Column('data', mutable_pickle), +              Column('non_mutable_data', PickleType), +              Column('unrelated_data', String(50)) +              ) + +  class MutableAssocWithAttrInheritTest(_MutableDictTestBase,                                        fixtures.MappedTest):  | 
