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'), autoincrement=True, 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']