Skip to content
This repository has been archived by the owner on Dec 17, 2020. It is now read-only.

Commit

Permalink
- backport from 1.1.1:
Browse files Browse the repository at this point in the history
  - added language choice caching, is by default turned off
  - test coverage is now 100%
  • Loading branch information
Adam Groszer committed Jul 21, 2010
1 parent 4af8ece commit 96f5c86
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 15 deletions.
9 changes: 9 additions & 0 deletions CHANGES.txt
Expand Up @@ -2,6 +2,15 @@
CHANGES
=======

1.0.2 (unreleased)
------------------

- backport from 1.1.1:

- added language choice caching, is by default turned off

- test coverage is now 100%

1.0.1 (2008-01-24)
------------------

Expand Down
9 changes: 7 additions & 2 deletions buildout.cfg
@@ -1,16 +1,21 @@
[buildout]
develop = .
parts = test checker coverage
parts = test coverage-test checker coverage
find-links = http://pypi.python.org/simple/z3c.language.session

[test]
recipe = zc.recipe.testrunner
eggs = z3c.language.negotiator [test]

[coverage-test]
recipe = zc.recipe.testrunner
eggs = ${test:eggs}
defaults = ['--coverage', '../../coverage']

[checker]
recipe = lovely.recipe:importchecker
path = src/z3c/language/negotiator

[coverage]
recipe = zc.recipe.egg
eggs = z3c.coverage
eggs = z3c.coverage
29 changes: 24 additions & 5 deletions src/z3c/language/negotiator/app.py
Expand Up @@ -31,14 +31,15 @@

from z3c.language.negotiator.interfaces import INegotiatorManager
from z3c.language.negotiator.interfaces import language_policies
from z3c.language.negotiator.interfaces import LANGUAGE_CACHE_KEY



class Negotiator(persistent.Persistent, contained.Contained):
"""Loacal negotiator implementation.
The negotiator let you change the policy, which is a alias
for the lookup mechanism.
for the lookup mechanism.
'server' -- The server defines the language
Expand All @@ -62,6 +63,7 @@ class Negotiator(persistent.Persistent, contained.Contained):

serverLanguage = FieldProperty(INegotiatorManager['serverLanguage'])
offeredLanguages = FieldProperty(INegotiatorManager['offeredLanguages'])
cacheEnabled = FieldProperty(INegotiatorManager['cacheEnabled'])

def __init__(self):
self._policy = 'session --> browser --> server'
Expand All @@ -71,7 +73,7 @@ def policy():
def get(self):
"""Returns the language policy."""
return self._policy

def set(self, policy):
"""Set the language policy."""
if policy not in language_policies:
Expand All @@ -80,18 +82,18 @@ def set(self, policy):
self._policy = policy
return property(get, set)

def getLanguage(self, languages, request):
def _getLanguage(self, languages, request):
"""Returns the language dependent on the policy."""
policyList = self._policy.split(' --> ')

for policy in policyList:

# the server is handling the language
if policy == 'server':
if self.serverLanguage:
return self.serverLanguage

# the language is handled by a session
# the language is handled by a session
elif policy == 'session':
session = ILanguageSession(request)
lang = session.getLanguage()
Expand All @@ -105,3 +107,20 @@ def getLanguage(self, languages, request):
return lang

return None

def getLanguage(self, languages, request):
if self.cacheEnabled:
try:
return request.annotations[LANGUAGE_CACHE_KEY]
except KeyError:
lang = self._getLanguage(languages, request)
request.annotations[LANGUAGE_CACHE_KEY] = lang
return lang
else:
return self._getLanguage(languages, request)

def clearCache(self, request):
try:
del request.annotations[LANGUAGE_CACHE_KEY]
except KeyError:
pass
16 changes: 13 additions & 3 deletions src/z3c/language/negotiator/interfaces.py
Expand Up @@ -25,10 +25,11 @@
from z3c.i18n import MessageFactory as _


language_policies = ['server', 'session', 'browser',
'browser --> session --> server', 'browser --> server',
language_policies = ['server', 'session', 'browser',
'browser --> session --> server', 'browser --> server',
'session --> browser --> server', 'session --> server']

LANGUAGE_CACHE_KEY = 'z3c.language.negotiator.cache'

class INegotiatorManager(zope.interface.Interface):
"""Local negotiator utility manager interface."""
Expand Down Expand Up @@ -58,6 +59,15 @@ class INegotiatorManager(zope.interface.Interface):
required=False,
)

cacheEnabled = zope.schema.Bool(
title=_(u"Language caching enabled"),
description=_(u"Language caching enabled (per request)"),
default=False,
)

def clearCache(request):
"""Clear the cached language value"""


class IOfferedLanguages(zope.interface.Interface):

Expand All @@ -74,7 +84,7 @@ class IOfferedLanguagesVocabulary(IVocabularyTokenized):

class IAvailableTranslationDomainLanguagesVocabulary(IVocabularyTokenized):
"""Available translation domain languages.
If you use this, take care on that you use the right translation domain.
So you probably have to implement your own vocabulary for your ``correct``
translation domain.
Expand Down
6 changes: 4 additions & 2 deletions src/z3c/language/negotiator/testing.py
Expand Up @@ -27,6 +27,7 @@
from zope.session.interfaces import ISessionDataContainer
from zope.session.http import CookieClientIdManager
from zope.session import session
from zope.publisher.base import TestRequest

from z3c import testing
from z3c.language.session.interfaces import ILanguageSession
Expand All @@ -48,7 +49,7 @@ def __new__(cls, request):


class LanguageSessionStub(object):

zope.interface.implements(ILanguageSession)
zope.component.adapts(IUserPreferredLanguages)

Expand All @@ -59,11 +60,12 @@ def getLanguage(self):
return 'fr'


class EnvStub(object):
class EnvStub(TestRequest):
zope.interface.implements(IUserPreferredLanguages)

def __init__(self, langs=()):
self.langs = langs
TestRequest.__init__(self, '/')

def getPreferredLanguages(self):
return self.langs
Expand Down
72 changes: 69 additions & 3 deletions src/z3c/language/negotiator/tests.py
Expand Up @@ -23,7 +23,6 @@
from zope.testing import doctest
from zope.testing.doctestunit import DocFileSuite

from z3c.language.negotiator import testing
from z3c.language.negotiator import app
from z3c.language.negotiator import testing

Expand All @@ -34,7 +33,7 @@ def getTestClass(self):
return app.Negotiator


class NegotiatorTest(zope.component.testing.PlacelessSetup,
class NegotiatorTest(zope.component.testing.PlacelessSetup,
unittest.TestCase):

def setUp(self):
Expand All @@ -58,7 +57,7 @@ def test_offeredLanguages(self):
self.negotiator.offeredLanguages = [u'de', u'en']
self.assertEqual(self.negotiator.offeredLanguages, [u'de', u'en'])

def test_getLanguages(self):
def test_getLanguagesBrowser(self):
# first set the default policy to 'browser'
self.negotiator.policy = 'browser'
self.assertEqual(self.negotiator.policy, 'browser')
Expand All @@ -76,6 +75,73 @@ def test_getLanguages(self):
self.assertEqual(self.negotiator.getLanguage(obj_langs, env),
expected)

def test_getLanguagesServer(self):
self.negotiator.policy = 'server'
self.assertEqual(self.negotiator.policy, 'server')

self.negotiator.serverLanguage = u'de'
self.assertEqual(self.negotiator.serverLanguage, u'de')

_cases = (
(('en','de'), ('en','de','fr'), 'de'),
(('en'), ('it','de','fr'), 'de'),
(('pt-br','de'), ('pt_BR','de','fr'), 'de'),
(('pt-br','en'), ('pt', 'en', 'fr'), 'de'),
(('pt-br','en-us', 'de'), ('de', 'en', 'fr'), 'de'),
)

for user_pref_langs, obj_langs, expected in _cases:
env = testing.EnvStub(user_pref_langs)
self.assertEqual(self.negotiator.getLanguage(obj_langs, env),
expected)

def test_getLanguagesSession(self):
self.negotiator.policy = 'session'
self.assertEqual(self.negotiator.policy, 'session')

_cases = (
(('en','de'), ('en','de','fr'), 'fr'),
(('en'), ('it','de','fr'), 'fr'),
(('pt-br','de'), ('pt_BR','de','fr'), 'fr'),
(('pt-br','en'), ('pt', 'en', 'fr'), 'fr'),
(('pt-br','en-us', 'de'), ('de', 'en', 'fr'), 'fr'),
)

for user_pref_langs, obj_langs, expected in _cases:
env = testing.EnvStub(user_pref_langs)
self.assertEqual(self.negotiator.getLanguage(obj_langs, env),
expected)

def test_getLanguagesCached(self):
self.negotiator.cacheEnabled = True

self.negotiator.policy = 'server'
self.assertEqual(self.negotiator.policy, 'server')

self.negotiator.serverLanguage = u'de'

env = testing.EnvStub(('pt-br','en'))
self.assertEqual(self.negotiator.getLanguage(('en', 'de'), env), 'de')

self.negotiator.serverLanguage = u'en'

self.assertEqual(self.negotiator.getLanguage(('en', 'de'), env), 'de')

env = testing.EnvStub(('pt-br','en'))

self.assertEqual(self.negotiator.getLanguage(('en', 'de'), env), 'en')

self.negotiator.serverLanguage = u'de'

self.assertEqual(self.negotiator.getLanguage(('en', 'de'), env), 'en')

self.negotiator.clearCache(env)

self.assertEqual(self.negotiator.getLanguage(('en', 'de'), env), 'de')

self.negotiator.clearCache(env)
self.negotiator.clearCache(env)


def test_suite():
return unittest.TestSuite((
Expand Down

0 comments on commit 96f5c86

Please sign in to comment.