1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6'''Unit tests for grit.gather.tr_html'''
7
8
9import os
10import sys
11if __name__ == '__main__':
12  sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
13
14import types
15import unittest
16import StringIO
17
18from grit.gather import tr_html
19from grit import clique
20from grit import util
21
22
23class ParserUnittest(unittest.TestCase):
24  def testChunkingWithoutFoldWhitespace(self):
25    self.VerifyChunking(False)
26
27  def testChunkingWithFoldWhitespace(self):
28    self.VerifyChunking(True)
29
30  def VerifyChunking(self, fold_whitespace):
31    """Use a single function to run all chunking testing.
32
33    This makes it easier to run chunking with fold_whitespace both on and off,
34    to make sure the outputs are the same.
35
36    Args:
37      fold_whitespace: Whether whitespace sequences should be folded into a
38        single space.
39    """
40    self.VerifyChunkingBasic(fold_whitespace)
41    self.VerifyChunkingDescriptions(fold_whitespace)
42    self.VerifyChunkingReplaceables(fold_whitespace)
43    self.VerifyChunkingLineBreaks(fold_whitespace)
44    self.VerifyChunkingMessageBreak(fold_whitespace)
45    self.VerifyChunkingMessageNoBreak(fold_whitespace)
46
47  def VerifyChunkingBasic(self, fold_whitespace):
48    p = tr_html.HtmlChunks()
49    chunks = p.Parse('<p>Hello <b>dear</b> how <i>are</i>you?<p>Fine!',
50                     fold_whitespace)
51    self.failUnlessEqual(chunks, [
52      (False, '<p>', ''), (True, 'Hello <b>dear</b> how <i>are</i>you?', ''),
53      (False, '<p>', ''), (True, 'Fine!', '')])
54
55    chunks = p.Parse('<p> Hello <b>dear</b> how <i>are</i>you? <p>Fine!',
56                     fold_whitespace)
57    self.failUnlessEqual(chunks, [
58      (False, '<p> ', ''), (True, 'Hello <b>dear</b> how <i>are</i>you?', ''),
59      (False, ' <p>', ''), (True, 'Fine!', '')])
60
61    chunks = p.Parse('<p> Hello <b>dear how <i>are you? <p> Fine!',
62                     fold_whitespace)
63    self.failUnlessEqual(chunks, [
64      (False, '<p> ', ''), (True, 'Hello <b>dear how <i>are you?', ''),
65      (False, ' <p> ', ''), (True, 'Fine!', '')])
66
67    # Ensure translateable sections that start with inline tags contain
68    # the starting inline tag.
69    chunks = p.Parse('<b>Hello!</b> how are you?<p><i>I am fine.</i>',
70                     fold_whitespace)
71    self.failUnlessEqual(chunks, [
72      (True, '<b>Hello!</b> how are you?', ''), (False, '<p>', ''),
73      (True, '<i>I am fine.</i>', '')])
74
75    # Ensure translateable sections that end with inline tags contain
76    # the ending inline tag.
77    chunks = p.Parse("Hello! How are <b>you?</b><p><i>I'm fine!</i>",
78                     fold_whitespace)
79    self.failUnlessEqual(chunks, [
80      (True, 'Hello! How are <b>you?</b>', ''), (False, '<p>', ''),
81      (True, "<i>I'm fine!</i>", '')])
82
83  def VerifyChunkingDescriptions(self, fold_whitespace):
84    p = tr_html.HtmlChunks()
85    # Check capitals and explicit descriptions
86    chunks = p.Parse('<!-- desc=bingo! --><B>Hello!</B> how are you?<P>'
87                     '<I>I am fine.</I>', fold_whitespace)
88    self.failUnlessEqual(chunks, [
89      (True, '<B>Hello!</B> how are you?', 'bingo!'), (False, '<P>', ''),
90      (True, '<I>I am fine.</I>', '')])
91    chunks = p.Parse('<B><!-- desc=bingo! -->Hello!</B> how are you?<P>'
92                     '<I>I am fine.</I>', fold_whitespace)
93    self.failUnlessEqual(chunks, [
94      (True, '<B>Hello!</B> how are you?', 'bingo!'), (False, '<P>', ''),
95      (True, '<I>I am fine.</I>', '')])
96    # Linebreaks get handled by the tclib message.
97    chunks = p.Parse('<B>Hello!</B> <!-- desc=bi\nngo\n! -->how are you?<P>'
98                     '<I>I am fine.</I>', fold_whitespace)
99    self.failUnlessEqual(chunks, [
100      (True, '<B>Hello!</B> how are you?', 'bi\nngo\n!'), (False, '<P>', ''),
101      (True, '<I>I am fine.</I>', '')])
102
103    # In this case, because the explicit description appears after the first
104    # translateable, it will actually apply to the second translateable.
105    chunks = p.Parse('<B>Hello!</B> how are you?<!-- desc=bingo! --><P>'
106                     '<I>I am fine.</I>', fold_whitespace)
107    self.failUnlessEqual(chunks, [
108      (True, '<B>Hello!</B> how are you?', ''), (False, '<P>', ''),
109      (True, '<I>I am fine.</I>', 'bingo!')])
110
111  def VerifyChunkingReplaceables(self, fold_whitespace):
112    # Check that replaceables within block tags (where attributes would go) are
113    # handled correctly.
114    p = tr_html.HtmlChunks()
115    chunks = p.Parse('<b>Hello!</b> how are you?<p [BINGO] [$~BONGO~$]>'
116                     '<i>I am fine.</i>', fold_whitespace)
117    self.failUnlessEqual(chunks, [
118      (True, '<b>Hello!</b> how are you?', ''),
119      (False, '<p [BINGO] [$~BONGO~$]>', ''),
120      (True, '<i>I am fine.</i>', '')])
121
122  def VerifyChunkingLineBreaks(self, fold_whitespace):
123    # Check that the contents of preformatted tags preserve line breaks.
124    p = tr_html.HtmlChunks()
125    chunks = p.Parse('<textarea>Hello\nthere\nhow\nare\nyou?</textarea>',
126                     fold_whitespace)
127    self.failUnlessEqual(chunks, [(False, '<textarea>', ''),
128      (True, 'Hello\nthere\nhow\nare\nyou?', ''), (False, '</textarea>', '')])
129
130    # ...and that other tags' line breaks are converted to spaces
131    chunks = p.Parse('<p>Hello\nthere\nhow\nare\nyou?</p>', fold_whitespace)
132    self.failUnlessEqual(chunks, [(False, '<p>', ''),
133      (True, 'Hello there how are you?', ''), (False, '</p>', '')])
134
135  def VerifyChunkingMessageBreak(self, fold_whitespace):
136    p = tr_html.HtmlChunks()
137    # Make sure that message-break comments work properly.
138    chunks = p.Parse('Break<!-- message-break --> apart '
139                     '<!--message-break-->messages', fold_whitespace)
140    self.failUnlessEqual(chunks, [(True, 'Break', ''),
141                                  (False, ' ', ''),
142                                  (True, 'apart', ''),
143                                  (False, ' ', ''),
144                                  (True, 'messages', '')])
145
146    # Make sure message-break comments work in an inline tag.
147    chunks = p.Parse('<a href=\'google.com\'><!-- message-break -->Google'
148                     '<!--message-break--></a>', fold_whitespace)
149    self.failUnlessEqual(chunks, [(False, '<a href=\'google.com\'>', ''),
150                                  (True, 'Google', ''),
151                                  (False, '</a>', '')])
152
153  def VerifyChunkingMessageNoBreak(self, fold_whitespace):
154    p = tr_html.HtmlChunks()
155    # Make sure that message-no-break comments work properly.
156    chunks = p.Parse('Please <!-- message-no-break --> <br />don\'t break',
157                     fold_whitespace)
158    self.failUnlessEqual(chunks, [(True, 'Please <!-- message-no-break --> '
159                         '<br />don\'t break', '')])
160
161    chunks = p.Parse('Please <br /> break. <!-- message-no-break --> <br /> '
162                     'But not this time.', fold_whitespace)
163    self.failUnlessEqual(chunks, [(True, 'Please', ''),
164                                  (False, ' <br /> ', ''),
165                                  (True, 'break. <!-- message-no-break --> '
166                                         '<br /> But not this time.', '')])
167
168  def testTranslateableAttributes(self):
169    p = tr_html.HtmlChunks()
170
171    # Check that the translateable attributes in <img>, <submit>, <button> and
172    # <text> elements buttons are handled correctly.
173    chunks = p.Parse('<img src=bingo.jpg alt="hello there">'
174                     '<input type=submit value="hello">'
175                     '<input type="button" value="hello">'
176                     '<input type=\'text\' value=\'Howdie\'>', False)
177    self.failUnlessEqual(chunks, [
178      (False, '<img src=bingo.jpg alt="', ''), (True, 'hello there', ''),
179      (False, '"><input type=submit value="', ''), (True, 'hello', ''),
180      (False, '"><input type="button" value="', ''), (True, 'hello', ''),
181      (False, '"><input type=\'text\' value=\'', ''), (True, 'Howdie', ''),
182      (False, '\'>', '')])
183
184
185  def testTranslateableHtmlToMessage(self):
186    msg = tr_html.HtmlToMessage(
187      'Hello <b>[USERNAME]</b>, &lt;how&gt;&nbsp;<i>are</i> you?')
188    pres = msg.GetPresentableContent()
189    self.failUnless(pres ==
190                    'Hello BEGIN_BOLDX_USERNAME_XEND_BOLD, '
191                    '<how>&nbsp;BEGIN_ITALICareEND_ITALIC you?')
192
193    msg = tr_html.HtmlToMessage('<b>Hello</b><I>Hello</I><b>Hello</b>')
194    pres = msg.GetPresentableContent()
195    self.failUnless(pres ==
196                    'BEGIN_BOLD_1HelloEND_BOLD_1BEGIN_ITALICHelloEND_ITALIC'
197                    'BEGIN_BOLD_2HelloEND_BOLD_2')
198
199    # Check that nesting (of the <font> tags) is handled correctly - i.e. that
200    # the closing placeholder numbers match the opening placeholders.
201    msg = tr_html.HtmlToMessage(
202      '''<font size=-1><font color=#FF0000>Update!</font> '''
203      '''<a href='http://desktop.google.com/whatsnew.html?hl=[$~LANG~$]'>'''
204      '''New Features</a>: Now search PDFs, MP3s, Firefox web history, and '''
205      '''more</font>''')
206    pres = msg.GetPresentableContent()
207    self.failUnless(pres ==
208                    'BEGIN_FONT_1BEGIN_FONT_2Update!END_FONT_2 BEGIN_LINK'
209                    'New FeaturesEND_LINK: Now search PDFs, MP3s, Firefox '
210                    'web history, and moreEND_FONT_1')
211
212    msg = tr_html.HtmlToMessage('''<a href='[$~URL~$]'><b>[NUM][CAT]</b></a>''')
213    pres = msg.GetPresentableContent()
214    self.failUnless(pres == 'BEGIN_LINKBEGIN_BOLDX_NUM_XX_CAT_XEND_BOLDEND_LINK')
215
216    msg = tr_html.HtmlToMessage(
217      '''<font size=-1><a class=q onClick='return window.qs?qs(this):1' '''
218      '''href='http://[WEBSERVER][SEARCH_URI]'>Desktop</a></font>&nbsp;&nbsp;'''
219      '''&nbsp;&nbsp;''')
220    pres = msg.GetPresentableContent()
221    self.failUnless(pres ==
222                    '''BEGIN_FONTBEGIN_LINKDesktopEND_LINKEND_FONTSPACE''')
223
224    msg = tr_html.HtmlToMessage(
225      '''<br><br><center><font size=-2>&copy;2005 Google </font></center>''', 1)
226    pres = msg.GetPresentableContent()
227    self.failUnless(pres ==
228                    u'BEGIN_BREAK_1BEGIN_BREAK_2BEGIN_CENTERBEGIN_FONT\xa92005'
229                    u' Google END_FONTEND_CENTER')
230
231    msg = tr_html.HtmlToMessage(
232      '''&nbsp;-&nbsp;<a class=c href=[$~CACHE~$]>Cached</a>''')
233    pres = msg.GetPresentableContent()
234    self.failUnless(pres ==
235                    '&nbsp;-&nbsp;BEGIN_LINKCachedEND_LINK')
236
237    # Check that upper-case tags are handled correctly.
238    msg = tr_html.HtmlToMessage(
239      '''You can read the <A HREF='http://desktop.google.com/privacypolicy.'''
240      '''html?hl=[LANG_CODE]'>Privacy Policy</A> and <A HREF='http://desktop'''
241      '''.google.com/privacyfaq.html?hl=[LANG_CODE]'>Privacy FAQ</A> online.''')
242    pres = msg.GetPresentableContent()
243    self.failUnless(pres ==
244                    'You can read the BEGIN_LINK_1Privacy PolicyEND_LINK_1 and '
245                    'BEGIN_LINK_2Privacy FAQEND_LINK_2 online.')
246
247    # Check that tags with linebreaks immediately preceding them are handled
248    # correctly.
249    msg = tr_html.HtmlToMessage(
250      '''You can read the
251<A HREF='http://desktop.google.com/privacypolicy.html?hl=[LANG_CODE]'>Privacy Policy</A>
252and <A HREF='http://desktop.google.com/privacyfaq.html?hl=[LANG_CODE]'>Privacy FAQ</A> online.''')
253    pres = msg.GetPresentableContent()
254    self.failUnless(pres == '''You can read the
255BEGIN_LINK_1Privacy PolicyEND_LINK_1
256and BEGIN_LINK_2Privacy FAQEND_LINK_2 online.''')
257
258    # Check that message-no-break comments are handled correctly.
259    msg = tr_html.HtmlToMessage('''Please <!-- message-no-break --><br /> don't break''')
260    pres = msg.GetPresentableContent()
261    self.failUnlessEqual(pres, '''Please BREAK don't break''')
262
263class TrHtmlUnittest(unittest.TestCase):
264  def testSetAttributes(self):
265    html = tr_html.TrHtml(StringIO.StringIO(''))
266    self.failUnlessEqual(html.fold_whitespace_, False)
267    html.SetAttributes({})
268    self.failUnlessEqual(html.fold_whitespace_, False)
269    html.SetAttributes({'fold_whitespace': 'false'})
270    self.failUnlessEqual(html.fold_whitespace_, False)
271    html.SetAttributes({'fold_whitespace': 'true'})
272    self.failUnlessEqual(html.fold_whitespace_, True)
273
274  def testFoldWhitespace(self):
275    text = '<td>   Test     Message   </td>'
276
277    html = tr_html.TrHtml(StringIO.StringIO(text))
278    html.Parse()
279    self.failUnlessEqual(html.skeleton_[1].GetMessage().GetPresentableContent(),
280                         'Test  Message')
281
282    html = tr_html.TrHtml(StringIO.StringIO(text))
283    html.fold_whitespace_ = True
284    html.Parse()
285    self.failUnlessEqual(html.skeleton_[1].GetMessage().GetPresentableContent(),
286                         'Test Message')
287
288  def testTable(self):
289    html = tr_html.TrHtml(StringIO.StringIO('''<table class="shaded-header"><tr>
290<td class="header-element b expand">Preferences</td>
291<td class="header-element s">
292<a href="http://desktop.google.com/preferences.html">Preferences&nbsp;Help</a>
293</td>
294</tr></table>'''))
295    html.Parse()
296    self.failUnless(html.skeleton_[3].GetMessage().GetPresentableContent() ==
297                    'BEGIN_LINKPreferences&nbsp;HelpEND_LINK')
298
299  def testSubmitAttribute(self):
300    html = tr_html.TrHtml(StringIO.StringIO('''</td>
301<td class="header-element"><input type=submit value="Save Preferences"
302name=submit2></td>
303</tr></table>'''))
304    html.Parse()
305    self.failUnless(html.skeleton_[1].GetMessage().GetPresentableContent() ==
306                    'Save Preferences')
307
308  def testWhitespaceAfterInlineTag(self):
309    '''Test that even if there is whitespace after an inline tag at the start
310    of a translateable section the inline tag will be included.
311    '''
312    html = tr_html.TrHtml(
313        StringIO.StringIO('''<label for=DISPLAYNONE><font size=-1> Hello</font>'''))
314    html.Parse()
315    self.failUnless(html.skeleton_[1].GetMessage().GetRealContent() ==
316                    '<font size=-1> Hello</font>')
317
318  def testSillyHeader(self):
319    html = tr_html.TrHtml(StringIO.StringIO('''[!]
320title\tHello
321bingo
322bongo
323bla
324
325<p>Other stuff</p>'''))
326    html.Parse()
327    content = html.skeleton_[1].GetMessage().GetRealContent()
328    self.failUnless(content == 'Hello')
329    self.failUnless(html.skeleton_[-1] == '</p>')
330    # Right after the translateable the nontranslateable should start with
331    # a linebreak (this catches a bug we had).
332    self.failUnless(html.skeleton_[2][0] == '\n')
333
334
335  def testExplicitDescriptions(self):
336    html = tr_html.TrHtml(
337        StringIO.StringIO('Hello [USER]<br/><!-- desc=explicit -->'
338                          '<input type="button">Go!</input>'))
339    html.Parse()
340    msg = html.GetCliques()[1].GetMessage()
341    self.failUnlessEqual(msg.GetDescription(), 'explicit')
342    self.failUnlessEqual(msg.GetRealContent(), 'Go!')
343
344    html = tr_html.TrHtml(
345        StringIO.StringIO('Hello [USER]<br/><!-- desc=explicit\nmultiline -->'
346                          '<input type="button">Go!</input>'))
347    html.Parse()
348    msg = html.GetCliques()[1].GetMessage()
349    self.failUnlessEqual(msg.GetDescription(), 'explicit multiline')
350    self.failUnlessEqual(msg.GetRealContent(), 'Go!')
351
352
353  def testRegressionInToolbarAbout(self):
354    html = tr_html.TrHtml(util.PathFromRoot(r'grit/testdata/toolbar_about.html'))
355    html.Parse()
356    cliques = html.GetCliques()
357    for cl in cliques:
358      content = cl.GetMessage().GetRealContent()
359      if content.count('De parvis grandis acervus erit'):
360        self.failIf(content.count('$/translate'))
361
362
363  def HtmlFromFileWithManualCheck(self, f):
364    html = tr_html.TrHtml(f)
365    html.Parse()
366
367    # For manual results inspection only...
368    list = []
369    for item in html.skeleton_:
370      if isinstance(item, types.StringTypes):
371        list.append(item)
372      else:
373        list.append(item.GetMessage().GetPresentableContent())
374
375    return html
376
377
378  def testPrivacyHtml(self):
379    html = self.HtmlFromFileWithManualCheck(
380      util.PathFromRoot(r'grit/testdata/privacy.html'))
381
382    self.failUnless(html.skeleton_[1].GetMessage().GetRealContent() ==
383                    'Privacy and Google Desktop Search')
384    self.failUnless(html.skeleton_[3].startswith('<'))
385    self.failUnless(len(html.skeleton_) > 10)
386
387
388  def testPreferencesHtml(self):
389    html = self.HtmlFromFileWithManualCheck(
390      util.PathFromRoot(r'grit/testdata/preferences.html'))
391
392    # Verify that we don't get '[STATUS-MESSAGE]' as the original content of
393    # one of the MessageClique objects (it would be a placeholder-only message
394    # and we're supposed to have stripped those).
395
396    for item in [x for x in html.skeleton_
397                 if isinstance(x, clique.MessageClique)]:
398      if (item.GetMessage().GetRealContent() == '[STATUS-MESSAGE]' or
399          item.GetMessage().GetRealContent() == '[ADDIN-DO] [ADDIN-OPTIONS]'):
400        self.fail()
401
402    self.failUnless(len(html.skeleton_) > 100)
403
404  def AssertNumberOfTranslateables(self, files, num):
405    '''Fails if any of the files in files don't have exactly
406    num translateable sections.
407
408    Args:
409      files: ['file1', 'file2']
410      num: 3
411    '''
412    for f in files:
413      f = util.PathFromRoot(r'grit/testdata/%s' % f)
414      html = self.HtmlFromFileWithManualCheck(f)
415      self.failUnless(len(html.GetCliques()) == num)
416
417  def testFewTranslateables(self):
418    self.AssertNumberOfTranslateables(['browser.html', 'email_thread.html',
419                                       'header.html', 'mini.html',
420                                       'oneclick.html', 'script.html',
421                                       'time_related.html', 'versions.html'], 0)
422    self.AssertNumberOfTranslateables(['footer.html', 'hover.html'], 1)
423
424  def testOtherHtmlFilesForManualInspection(self):
425    files = [
426      'about.html', 'bad_browser.html', 'cache_prefix.html',
427      'cache_prefix_file.html', 'chat_result.html', 'del_footer.html',
428      'del_header.html', 'deleted.html', 'details.html', 'email_result.html',
429      'error.html', 'explicit_web.html', 'footer.html',
430      'homepage.html', 'indexing_speed.html',
431      'install_prefs.html', 'install_prefs2.html',
432      'oem_enable.html', 'oem_non_admin.html', 'onebox.html',
433      'password.html', 'quit_apps.html', 'recrawl.html',
434      'searchbox.html', 'sidebar_h.html', 'sidebar_v.html', 'status.html',
435    ]
436    for f in files:
437      self.HtmlFromFileWithManualCheck(
438        util.PathFromRoot(r'grit/testdata/%s' % f))
439
440  def testTranslate(self):
441    # Note that the English translation of documents that use character
442    # literals (e.g. &copy;) will not be the same as the original document
443    # because the character literal will be transformed into the Unicode
444    # character itself.  So for this test we choose some relatively complex
445    # HTML without character entities (but with &nbsp; because that's handled
446    # specially).
447    html = tr_html.TrHtml(StringIO.StringIO('''  <script>
448      <!--
449      function checkOffice() { var w = document.getElementById("h7");
450      var e = document.getElementById("h8"); var o = document.getElementById("h10");
451      if (!(w.checked || e.checked)) { o.checked=0;o.disabled=1;} else {o.disabled=0;} }
452      // -->
453        </script>
454        <input type=checkbox [CHECK-DOC] name=DOC id=h7 onclick='checkOffice()'>
455        <label for=h7> Word</label><br>
456        <input type=checkbox [CHECK-XLS] name=XLS id=h8 onclick='checkOffice()'>
457        <label for=h8> Excel</label><br>
458        <input type=checkbox [CHECK-PPT] name=PPT id=h9>
459        <label for=h9> PowerPoint</label><br>
460        </span></td><td nowrap valign=top><span class="s">
461        <input type=checkbox [CHECK-PDF] name=PDF id=hpdf>
462        <label for=hpdf> PDF</label><br>
463        <input type=checkbox [CHECK-TXT] name=TXT id=h6>
464        <label for=h6> Text, media, and other files</label><br>
465       </tr>&nbsp;&nbsp;
466       <tr><td nowrap valign=top colspan=3><span class="s"><br />
467       <input type=checkbox [CHECK-SECUREOFFICE] name=SECUREOFFICE id=h10>
468        <label for=h10> Password-protected Office documents (Word, Excel)</label><br />
469        <input type=checkbox [DISABLED-HTTPS] [CHECK-HTTPS] name=HTTPS id=h12><label
470        for=h12> Secure pages (HTTPS) in web history</label></span></td></tr>
471      </table>'''))
472    html.Parse()
473    trans = html.Translate('en')
474    if (html.GetText() != trans):
475      self.fail()
476
477
478  def testHtmlToMessageWithBlockTags(self):
479    msg = tr_html.HtmlToMessage(
480      'Hello<p>Howdie<img alt="bingo" src="image.gif">', True)
481    result = msg.GetPresentableContent()
482    self.failUnless(
483      result == 'HelloBEGIN_PARAGRAPHHowdieBEGIN_BLOCKbingoEND_BLOCK')
484
485    msg = tr_html.HtmlToMessage(
486      'Hello<p>Howdie<input type="button" value="bingo">', True)
487    result = msg.GetPresentableContent()
488    self.failUnless(
489      result == 'HelloBEGIN_PARAGRAPHHowdieBEGIN_BLOCKbingoEND_BLOCK')
490
491
492  def testHtmlToMessageRegressions(self):
493    msg = tr_html.HtmlToMessage(' - ', True)
494    result = msg.GetPresentableContent()
495    self.failUnless(result == ' - ')
496
497
498  def testEscapeUnescaped(self):
499    text = '&copy;&nbsp; & &quot;&lt;hello&gt;&quot;'
500    unescaped = util.UnescapeHtml(text)
501    self.failUnless(unescaped == u'\u00a9\u00a0 & "<hello>"')
502    escaped_unescaped = util.EscapeHtml(unescaped, True)
503    self.failUnless(escaped_unescaped ==
504                    u'\u00a9\u00a0 &amp; &quot;&lt;hello&gt;&quot;')
505
506  def testRegressionCjkHtmlFile(self):
507    # TODO(joi) Fix this problem where unquoted attributes that
508    # have a value that is CJK characters causes the regular expression
509    # match never to return.  (culprit is the _ELEMENT regexp(
510    if False:
511      html = self.HtmlFromFileWithManualCheck(util.PathFromRoot(
512        r'grit/testdata/ko_oem_enable_bug.html'))
513      self.failUnless(True)
514
515  def testRegressionCpuHang(self):
516    # If this regression occurs, the unit test will never return
517    html = tr_html.TrHtml(StringIO.StringIO(
518      '''<input type=text size=12 id=advFileTypeEntry [~SHOW-FILETYPE-BOX~] value="[EXT]" name=ext>'''))
519    html.Parse()
520
521if __name__ == '__main__':
522  unittest.main()
523