File: test_proxy_dict.py

package info (click to toggle)
python-sqlalchemy-utils 0.41.2-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 1,252 kB
  • sloc: python: 13,566; makefile: 141
file content (133 lines) | stat: -rw-r--r-- 3,606 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import pytest
import sqlalchemy as sa
from flexmock import flexmock

from sqlalchemy_utils import proxy_dict, ProxyDict


@pytest.fixture
def ArticleTranslation(Base):
    class ArticleTranslation(Base):
        __tablename__ = 'article_translation'

        id = sa.Column(
            sa.Integer,
            sa.ForeignKey('article.id'),
            primary_key=True
        )
        locale = sa.Column(sa.String(10), primary_key=True)
        name = sa.Column(sa.UnicodeText)
    return ArticleTranslation


@pytest.fixture
def Article(Base, ArticleTranslation):

    class Article(Base):
        __tablename__ = 'article'

        id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
        description = sa.Column(sa.UnicodeText)
        _translations = sa.orm.relationship(
            ArticleTranslation,
            lazy='dynamic',
            cascade='all, delete-orphan',
            passive_deletes=True,
            backref=sa.orm.backref('parent'),
        )

        @property
        def translations(self):
            return proxy_dict(
                self,
                '_translations',
                ArticleTranslation.locale
            )
    return Article


@pytest.fixture
def init_models(ArticleTranslation, Article):
    pass


class TestProxyDict:

    def test_access_key_for_pending_parent(self, session, Article):
        article = Article()
        session.add(article)
        assert article.translations['en']

    def test_access_key_for_transient_parent(self, Article):
        article = Article()
        assert article.translations['en']

    def test_cache(self, session, Article):
        article = Article()
        (
            flexmock(ProxyDict)
            .should_receive('fetch')
            .once()
        )
        session.add(article)
        session.commit()
        article.translations['en']
        article.translations['en']

    def test_set_updates_cache(self, session, Article, ArticleTranslation):
        article = Article()
        (
            flexmock(ProxyDict)
            .should_receive('fetch')
            .once()
        )
        session.add(article)
        session.commit()
        article.translations['en']
        article.translations['en'] = ArticleTranslation(
            locale='en',
            name='something'
        )
        article.translations['en']

    def test_contains_efficiency(self, connection, session, Article):
        article = Article()
        session.add(article)
        session.commit()
        article.id
        query_count = connection.query_count
        'en' in article.translations
        'en' in article.translations
        'en' in article.translations
        assert connection.query_count == query_count + 1

    def test_getitem_with_none_value_in_cache(self, session, Article):
        article = Article()
        session.add(article)
        session.commit()
        article.id
        'en' in article.translations
        assert article.translations['en']

    def test_contains(self, Article):
        article = Article()
        assert 'en' not in article.translations
        # does not auto-append new translation
        assert 'en' not in article.translations

    def test_committing_session_empties_proxy_dict_cache(
        self,
        session,
        Article
    ):
        article = Article()
        (
            flexmock(ProxyDict)
            .should_receive('fetch')
            .twice()
        )
        session.add(article)
        session.commit()
        article.translations['en']
        session.commit()
        article.translations['en']