107 lines
3.5 KiB
Python
107 lines
3.5 KiB
Python
import sqlalchemy as sa
|
|
from flexmock import flexmock
|
|
from pytest import mark
|
|
from sqlalchemy.dialects.postgresql import HSTORE
|
|
|
|
from sqlalchemy_utils import i18n, TranslationHybrid # noqa
|
|
from tests import TestCase
|
|
|
|
|
|
@mark.skipif('i18n.babel is None')
|
|
class TestTranslationHybrid(TestCase):
|
|
dns = 'postgres://postgres@localhost/sqlalchemy_utils_test'
|
|
|
|
def create_models(self):
|
|
class City(self.Base):
|
|
__tablename__ = 'city'
|
|
id = sa.Column(sa.Integer, primary_key=True)
|
|
name_translations = sa.Column(HSTORE)
|
|
name = self.translation_hybrid(name_translations)
|
|
locale = 'en'
|
|
|
|
self.City = City
|
|
|
|
def setup_method(self, method):
|
|
self.translation_hybrid = TranslationHybrid('fi', 'en')
|
|
TestCase.setup_method(self, method)
|
|
|
|
def test_using_hybrid_as_constructor(self):
|
|
city = self.City(name='Helsinki')
|
|
assert city.name_translations['fi'] == 'Helsinki'
|
|
|
|
def test_if_no_translation_exists_returns_none(self):
|
|
city = self.City()
|
|
assert city.name is None
|
|
|
|
def test_custom_default_value(self):
|
|
self.translation_hybrid.default_value = 'Some value'
|
|
city = self.City()
|
|
assert city.name is 'Some value'
|
|
|
|
def test_fall_back_to_default_translation(self):
|
|
city = self.City(name_translations={'en': 'Helsinki'})
|
|
self.translation_hybrid.current_locale = 'sv'
|
|
assert city.name == 'Helsinki'
|
|
|
|
def test_fallback_to_dynamic_locale(self):
|
|
self.translation_hybrid.current_locale = 'en'
|
|
self.translation_hybrid.default_locale = lambda self: self.locale
|
|
city = self.City(name_translations={})
|
|
city.locale = 'fi'
|
|
city.name_translations['fi'] = 'Helsinki'
|
|
|
|
assert city.name == 'Helsinki'
|
|
|
|
@mark.parametrize(
|
|
('name_translations', 'name'),
|
|
(
|
|
({'fi': 'Helsinki', 'en': 'Helsing'}, 'Helsinki'),
|
|
({'en': 'Helsinki'}, 'Helsinki'),
|
|
({'fi': 'Helsinki'}, 'Helsinki'),
|
|
({}, None),
|
|
)
|
|
)
|
|
def test_hybrid_as_an_expression(self, name_translations, name):
|
|
city = self.City(name_translations=name_translations)
|
|
self.session.add(city)
|
|
self.session.commit()
|
|
|
|
assert self.session.query(self.City.name).scalar() == name
|
|
|
|
def test_dynamic_locale(self):
|
|
translation_hybrid = TranslationHybrid(
|
|
lambda obj: obj.locale,
|
|
'fi'
|
|
)
|
|
|
|
class Article(self.Base):
|
|
__tablename__ = 'article'
|
|
id = sa.Column(sa.Integer, primary_key=True)
|
|
name_translations = sa.Column(HSTORE)
|
|
name = translation_hybrid(name_translations)
|
|
locale = sa.Column(sa.String)
|
|
|
|
assert (
|
|
'coalesce(article.name_translations -> article.locale'
|
|
in str(Article.name)
|
|
)
|
|
|
|
def test_locales_casted_only_in_compilation_phase(self):
|
|
class LocaleGetter(object):
|
|
def current_locale(self):
|
|
return lambda obj: obj.locale
|
|
|
|
flexmock(LocaleGetter).should_receive('current_locale').never()
|
|
translation_hybrid = TranslationHybrid(
|
|
LocaleGetter().current_locale,
|
|
'fi'
|
|
)
|
|
class Article(self.Base):
|
|
__tablename__ = 'article'
|
|
id = sa.Column(sa.Integer, primary_key=True)
|
|
name_translations = sa.Column(HSTORE)
|
|
name = translation_hybrid(name_translations)
|
|
locale = sa.Column(sa.String)
|
|
|
|
Article.name
|