1from zope.interface import implements 2 3from twisted.trial import unittest 4from cStringIO import StringIO 5from nevow import inevow, flat, context, tags, loaders, rend 6from nevow import i18n 7from nevow.testutil import FakeRequest 8 9def mockTranslator(s, languages=None, domain=None): 10 args = {} 11 if domain is not None: 12 args['domain'] = domain 13 return 'MOCK(%s)[%s]' % (', '.join(['%s=%r' % (k,v) 14 for k,v in args.items()]), 15 s) 16 17class Misc(unittest.TestCase): 18 def test_simple(self): 19 s = i18n._('foo') 20 21 def test_simple_flat(self): 22 s = i18n._('foo') 23 r = flat.ten.flatten(s, None) 24 self.assertEquals(r, 'foo') 25 26 def test_translator(self): 27 _ = i18n.Translator(translator=mockTranslator) 28 s = _('foo') 29 r = flat.ten.flatten(s, None) 30 self.assertEquals(r, 'MOCK()[foo]') 31 32class Config(unittest.TestCase): 33 def test_remember(self): 34 ctx = context.WebContext() 35 cfg = i18n.I18NConfig(domain='foo') 36 ctx.remember(cfg) 37 38class Domain(unittest.TestCase): 39 def test_classInit(self): 40 _ = i18n.Translator(translator=mockTranslator, 41 domain='bar') 42 s = _('foo') 43 r = flat.ten.flatten(s, None) 44 self.assertEquals(r, "MOCK(domain='bar')[foo]") 45 46 def test_runTime(self): 47 _ = i18n.Translator(translator=mockTranslator) 48 s = _('foo', domain='baz') 49 r = flat.ten.flatten(s, None) 50 self.assertEquals(r, "MOCK(domain='baz')[foo]") 51 52 def test_context(self): 53 _ = i18n.Translator(translator=mockTranslator) 54 ctx = context.WebContext() 55 cfg = i18n.I18NConfig(domain='thud') 56 ctx.remember(cfg) 57 s = _('foo') 58 r = flat.ten.flatten(s, ctx) 59 self.assertEquals(r, "MOCK(domain='thud')[foo]") 60 61 def test_runTime_beats_all(self): 62 _ = i18n.Translator(translator=mockTranslator, 63 domain='not-used1') 64 ctx = context.WebContext() 65 cfg = i18n.I18NConfig(domain='not-used2') 66 ctx.remember(cfg) 67 s = _('foo', domain='baz') 68 r = flat.ten.flatten(s, None) 69 self.assertEquals(r, "MOCK(domain='baz')[foo]") 70 71 72 def test_classInit_beats_context(self): 73 _ = i18n.Translator(translator=mockTranslator, 74 domain='baz') 75 ctx = context.WebContext() 76 cfg = i18n.I18NConfig(domain='not-used') 77 ctx.remember(cfg) 78 s = _('foo') 79 r = flat.ten.flatten(s, None) 80 self.assertEquals(r, "MOCK(domain='baz')[foo]") 81 82class Format(unittest.TestCase): 83 def test_simple(self): 84 _ = i18n.Translator(translator=mockTranslator) 85 s = _('foo %s') % 'bar' 86 r = flat.ten.flatten(s, None) 87 self.assertEquals(r, "MOCK()[foo bar]") 88 89 def test_multiple(self): 90 _ = i18n.Translator(translator=mockTranslator) 91 s = _('foo %s') 92 s = s % 'bar %s' 93 s = s % 'baz' 94 r = flat.ten.flatten(s, None) 95 self.assertEquals(r, "MOCK()[foo bar baz]") 96 97 98 99class Languages(unittest.TestCase): 100 def test_noLanguages(self): 101 request = FakeRequest(headers={}) 102 ctx = context.RequestContext(tag=request) 103 r = inevow.ILanguages(ctx) 104 self.assertEquals(r, []) 105 106 def test_oneLanguage(self): 107 request = FakeRequest(headers={ 108 'accept-language': 'fo', 109 }) 110 ctx = context.RequestContext(tag=request) 111 r = inevow.ILanguages(ctx) 112 self.assertEquals(r, ['fo']) 113 114 def test_multipleLanguages(self): 115 request = FakeRequest(headers={ 116 'accept-language': 'fo,ba,th', 117 }) 118 ctx = context.RequestContext(tag=request) 119 r = inevow.ILanguages(ctx) 120 self.assertEquals(r, ['fo', 'ba', 'th']) 121 122 def test_quality_simple(self): 123 request = FakeRequest(headers={ 124 'accept-language': 'fo;q=0.4', 125 }) 126 ctx = context.RequestContext(tag=request) 127 r = inevow.ILanguages(ctx) 128 self.assertEquals(r, ['fo']) 129 130 def test_quality_sort(self): 131 request = FakeRequest(headers={ 132 'accept-language': 'fo;q=0.4,ba;q=0.2,xy;q=0.9', 133 }) 134 ctx = context.RequestContext(tag=request) 135 r = inevow.ILanguages(ctx) 136 self.assertEquals(r, ['xy', 'fo', 'ba']) 137 138 def test_quality_invalid_notQ(self): 139 request = FakeRequest(headers={ 140 'accept-language': 'fo;q=0.4,ba;z=0.2', 141 }) 142 ctx = context.RequestContext(tag=request) 143 r = inevow.ILanguages(ctx) 144 self.assertEquals(r, ['ba', 'fo']) 145 146 def test_quality_invalid_notFloat(self): 147 request = FakeRequest(headers={ 148 'accept-language': 'fo;q=0.4,ba;q=junk', 149 }) 150 ctx = context.RequestContext(tag=request) 151 r = inevow.ILanguages(ctx) 152 self.assertEquals(r, ['ba', 'fo']) 153 154class Render(unittest.TestCase): 155 def makePage(self, content): 156 _ = i18n.Translator(translator=mockTranslator) 157 page = rend.Page( 158 docFactory=loaders.stan(tags.invisible(render=tags.directive('i18n'))[content])) 159 page.render_i18n = i18n.render(_) 160 doc = page.docFactory.load() 161 ctx = context.WovenContext(context.PageContext(tag=page), 162 tags.invisible[doc]) 163 page.rememberStuff(ctx) 164 165 io = StringIO() 166 writer = io.write 167 168 def finisher(result): 169 return io.getvalue() 170 171 return page.flattenFactory(doc, ctx, writer, finisher) 172 173 def test_empty(self): 174 return self.makePage(['']).addCallback( 175 lambda r: self.assertEquals(r, 'MOCK()[]')) 176 177 def test_simple(self): 178 return self.makePage(['foo']).addCallback( 179 lambda r: self.assertEquals(r, 'MOCK()[foo]')) 180 181 def test_stan(self): 182 return self.makePage([tags.p['You should really avoid tags in i18n input.']]).addCallback( 183 lambda r: self.assertEquals(r, 'MOCK()[<p>You should really avoid tags in i18n input.</p>]')) 184 185class InterpolateTests: 186 def test_mod_string(self): 187 self.check('foo %s', 'bar', 188 'foo bar') 189 190 def test_mod_unicode(self): 191 self.check('foo %s', u'bar', 192 'foo bar') 193 194 def test_mod_int(self): 195 self.check('foo %d', 42, 196 'foo 42') 197 198 def test_mod_float(self): 199 self.check('foo %.3f', 42.0, 200 'foo 42.000') 201 202 def test_mod_char(self): 203 self.check('foo %c', 42, 204 'foo *') 205 self.check('foo %c', '*', 206 'foo *') 207 208 # Tuples are a special case, 'foo %s' % ('bar', 'baz') does not 209 # work. Also, 'foo %s %s' only works with tuples. 210 211 def test_mod_tuple_two(self): 212 self.check('foo %s %s', ('bar', 'baz'), 213 "foo bar baz") 214 215 def test_mod_tuple_complex(self): 216 self.check('foo %s %s %s', ([1, 2], (3, 4), {5: 6}), 217 "foo [1, 2] (3, 4) {5: 6}") 218 219 def test_mod_list_stringify(self): 220 self.check('foo %s', ['bar', 'baz'], 221 "foo ['bar', 'baz']") 222 223 def test_mod_list_reprify(self): 224 self.check('foo %r', ['bar', 'baz'], 225 "foo ['bar', 'baz']") 226 227 def test_mod_dict_stringify(self): 228 self.check('foo %s', {'bar': 1, 'baz': 2}, 229 "foo {'bar': 1, 'baz': 2}", 230 "foo {'baz': 2, 'bar': 1}") 231 232 def test_mod_dict_reprify(self): 233 self.check('foo %r', {'bar': 1, 'baz': 2}, 234 "foo {'bar': 1, 'baz': 2}", 235 "foo {'baz': 2, 'bar': 1}") 236 237 def test_mod_dict_two(self): 238 self.check('foo %(bar)s %(baz)s', {'bar': 1, 'baz': 2}, 239 "foo 1 2") 240 241 def test_mod_dict_two_as_ints(self): 242 self.check('foo %(bar)d %(baz)d', {'bar': 1, 'baz': 2}, 243 "foo 1 2") 244 245 def test_mod_dict_two_as_floats(self): 246 self.check('foo %(bar).1f %(baz).1f', {'bar': 1.2, 'baz': 2.3}, 247 "foo 1.2 2.3") 248 249 def test_mod_dict_two_as_chars(self): 250 self.check('foo %(bar)c %(baz)c', {'bar': 52, 'baz': '2'}, 251 "foo 4 2") 252 253class InterpolateMixin: 254 def setUp(self): 255 self._ = i18n.Translator(translator=mockTranslator) 256 257 def mangle(self, s): 258 raise NotImplementedError, 'override mangle somewhere' 259 260 def check(self, fmt, args, *wants): 261 got = self.mangle(self._(fmt) % args) 262 self.failUnlessIn(got, wants) 263 264class Repr(InterpolateMixin, unittest.TestCase, InterpolateTests): 265 def mangle(self, s): 266 return repr(s) 267 268 def check(self, fmt, args, *wants): 269 InterpolateMixin.check(self, fmt, args, 270 "PlaceHolder(*%r, translator=%r) %% %r" % \ 271 ((fmt,), mockTranslator, args)) 272 273class Str(InterpolateMixin, unittest.TestCase, InterpolateTests): 274 def mangle(self, s): 275 return str(s) 276 277 def check(self, fmt, args, *wants): 278 InterpolateMixin.check(self, fmt, args, 279 "PlaceHolder(*%r, translator=%r) %% %r" % \ 280 ((fmt,), mockTranslator, args)) 281 282class Interpolation(InterpolateMixin, unittest.TestCase, InterpolateTests): 283 def mangle(self, s): 284 r = flat.ten.flatten(s, None) 285 return r 286 287 def check(self, fmt, args, *wants): 288 InterpolateMixin.check(self, fmt, args, 289 *['MOCK()[%s]' % x for x in wants]) 290 291class UNGettext(unittest.TestCase): 292 def test_simple(self): 293 s1 = i18n.ungettext('%d foo', '%d foos', 1) 294 s2 = i18n.ungettext('%d foo', '%d foos', 42) 295 296 def test_simple_flat_one(self): 297 s = i18n.ungettext('%d foo', '%d foos', 1) 298 r = flat.ten.flatten(s, None) 299 self.assertEquals(r, '%d foo') 300 301 def test_simple_flat_many(self): 302 s = i18n.ungettext('%d foo', '%d foos', 42) 303 r = flat.ten.flatten(s, None) 304 self.assertEquals(r, '%d foos') 305 306 def test_simple_flat_many(self): 307 s = i18n.ungettext('%d foo', '%d foos', 42) 308 r = flat.ten.flatten(s, None) 309 self.assertEquals(r, '%d foos') 310 311 def test_format_one(self): 312 s = i18n.ungettext('%d foo', '%d foos', 1) % 1 313 r = flat.ten.flatten(s, None) 314 self.assertEquals(r, "1 foo") 315 316 def test_format_many(self): 317 s = i18n.ungettext('%d foo', '%d foos', 42) % 42 318 r = flat.ten.flatten(s, None) 319 self.assertEquals(r, "42 foos") 320