134 lines
3.5 KiB
Python
134 lines
3.5 KiB
Python
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(object):
|
|
|
|
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=u'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']
|