#12850 closed defect (fixed)
Test failure with trac.wiki.tests.functional.TestWikiDelete
Reported by: | Ryan J Ollos | Owned by: | Jun Omae |
---|---|---|---|
Priority: | normal | Milestone: | 1.3.2 |
Component: | wiki system | Version: | |
Severity: | normal | Keywords: | |
Cc: | Branch: | ||
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Fix wrong |
Description
Failure seen on AppVeyor and Travis CI.
====================================================================== FAIL: runTest (trac.wiki.tests.functional.TestWikiDelete) Delete a wiki page. ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/travis/build/edgewall/trac/trac/wiki/tests/functional.py", line 76, in runTest r'version=2">all 2 versions</a>\s+of the page' % name) File "/home/travis/build/edgewall/trac/trac/tests/functional/better_twill.py", line 224, in better_find (to_unicode(e), filename)) TwillAssertionError: no match to 'Removing\s+<a href="/wiki/BagpipeTongue\?action=history&version=2">all 2 versions</a>\s+of the page' at file:///home/travis/build/edgewall/trac/testenv/trac/log/TestWikiDelete.html ---------------------------------------------------------------------- Ran 222 tests in 677.196s FAILED (failures=1) make: *** [functional-test] Error 1
Attachments (0)
Change History (9)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
extract_messages
command's behavior is right. msgid_plural
is used only when messages catalog is not found for active language. msgid
is used as a key and must be unique without msgid_plural
. Therefore, usage of ngettext
in wiki_delete.html is wrong.
-
trac/wiki/templates/wiki_delete.html
diff --git a/trac/wiki/templates/wiki_delete.html b/trac/wiki/templates/wiki_delete.html index d9b68553c..172e87830 100644
a b 130 130 # else: 131 131 # set num_versions 132 132 <a href="${history_href}">${ 133 ngettext("%(num)d version", " all%(num)d versions", num=num_versions)133 ngettext("%(num)d version", "%(num)d versions", num=num_versions) 134 134 }</a> 135 135 # endset 136 136 # trans num_versions, created = first_modified, modified = last_modified 137 137 138 Removing ${num_versions} of the page, which was created138 Removing all ${num_versions} of the page, which was created 139 139 ${created} and last modified ${modified}. 140 140 141 141 # endtrans -
trac/wiki/tests/functional.py
diff --git a/trac/wiki/tests/functional.py b/trac/wiki/tests/functional.py index 292099581..a46c5d769 100755
a b class TestWikiDelete(FunctionalTwillTestCaseSetup): 72 72 tc.formvalue('delete', 'action', 'delete') 73 73 tc.submit('delete_page') 74 74 tc.find("Are you sure you want to completely delete this page?") 75 tc.find(r'Removing \s+<a href="/wiki/%s\?action=history&'76 r'version=2"> all2 versions</a>\s+of the page' % name)75 tc.find(r'Removing all\s+<a href="/wiki/%s\?action=history&' 76 r'version=2">2 versions</a>\s+of the page' % name) 77 77 tc.notfind("The following attachments will also be deleted:") 78 78 tc.submit('delete', 'delete-confirm') 79 79 tc.find("The page %s has been deleted." % name)
comment:3 by , 8 years ago
Release Notes: | modified (diff) |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
Committed in [16076].
comment:4 by , 8 years ago
At least for English, it seems that the plural form will always be used because it's inside a conditional where num_versions != 1
: trunk/trac/wiki/templates/wiki_delete.html@16076:120,130#L115.
comment:5 by , 8 years ago
If compiled catalog is used, 2nd argument of ngettext
is ignored.
$ grep -F '%(num)d version' trac/locale/messages.pot trac/locale/en_US/LC_MESSAGES/messages.po trac/locale/messages.pot:msgid "%(num)d version" trac/locale/messages.pot:msgid_plural "%(num)d versions" trac/locale/en_US/LC_MESSAGES/messages.po:msgid "%(num)d version" trac/locale/en_US/LC_MESSAGES/messages.po:msgid_plural "%(num)d versions" $ make compile-en_US python setup.py compile_catalog -l en_US compile_catalog_js -l en_US compile_catalog_tracini -l en_US \ generate_messages_js -l en_US running compile_catalog compiling catalog trac/locale/en_US/LC_MESSAGES/messages.po to trac/locale/en_US/LC_MESSAGES/messages.mo running compile_catalog_js compiling catalog trac/locale/en_US/LC_MESSAGES/messages-js.po to trac/locale/en_US/LC_MESSAGES/messages-js.mo running compile_catalog_tracini compiling catalog trac/locale/en_US/LC_MESSAGES/tracini.po to trac/locale/en_US/LC_MESSAGES/tracini.mo running generate_messages_js generating messages javascript 'trac/locale/en_US/LC_MESSAGES/messages-js.mo' to 'trac/htdocs/js/messages/en_US.js'
$ make start-python Python 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from trac.util.translation import make_activable, ngettext, translations >>> make_activable(lambda: 'en_US') >>> ngettext('%(num)d version', 'all %(num)d versions', 1) u'1 version' >>> ngettext('%(num)d version', 'all %(num)d versions', 2) u'2 versions' # <== not 'all %(num)d versions' >>> translations.active.files ['trac/locale/en_US/LC_MESSAGES/messages.mo']
$ make start-python Python 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from trac.util.translation import make_activable, ngettext, translations >>> make_activable(lambda: 'en_US') >>> ngettext('%(num)d version', 'all %(num)d versions', 1) u'1 version' >>> ngettext('%(num)d version', 'all %(num)d versions', 2) u'all 2 versions' >>> translations.active.files Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: NullTranslationsBabel instance has no attribute 'files'
comment:6 by , 8 years ago
Okay, I think I might understand the reason now. I had wondered why the following wasn't used:
-
trac/wiki/templates/wiki_delete.html
$git diff trac/wiki/templates/wiki_delete.html diff --git a/trac/wiki/templates/wiki_delete.html b/trac/wiki/templates/wiki_delete.html index 172e87830..872a027a0 100644
a b 129 129 # endtrans 130 130 # else: 131 131 # set num_versions 132 <a href="${history_href}">${ 133 ngettext("%(num)d version", "%(num)d versions", num=num_versions) 134 }</a> 132 <a href="${history_href}">${_("%(num)d versions", num=num_versions)}</a> 135 133 # endset 136 134 # trans num_versions, created = first_modified, modified = last_modified
But on making the change I see that it would result in an extra entry in the catalog:
@@ -7596,28 +7596,33 @@ msgid "" "%(created)s." msgstr "" -#: trac/wiki/templates/wiki_delete.html:136 +#: trac/wiki/templates/wiki_delete.html:132 +#, python-format +msgid "%(num)d versions" +msgstr "" + +#: trac/wiki/templates/wiki_delete.html:134 #, python-format msgid "" "Removing all %(num_versions)s of the page, which was created %(created)s " "and last modified %(modified)s." msgstr ""
comment:7 by , 8 years ago
I've considered the same idea but plural expression is more complex than English (nplural=2), Japanese (nplural=1), etc. I consider we should use ngettext()
to be able to translate as plural.
E.g. and see also https://github.com/python-babel/babel/blob/v2.4.0/babel/messages/plurals.py#L22.
# Russian 'ru': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
ngettext()
is used in wiki_delete.html like this:extract_messages
command extracts"%(num)d version"
and"%(num)d versions"
from the above but"all %(num)d versions"
is not extracted.