[damned-lies] Partially redesigned utils.generate_doc_pot_file and stats tests
- From: Claude Paroz <claudep src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies] Partially redesigned utils.generate_doc_pot_file and stats tests
- Date: Wed, 31 Aug 2011 08:18:21 +0000 (UTC)
commit f6db20dcfe3e784b470e5d78d4f98a04bf89a28e
Author: Claude Paroz <claude 2xlibre net>
Date: Wed Aug 31 10:16:59 2011 +0200
Partially redesigned utils.generate_doc_pot_file and stats tests
common/fields.py | 3 +
stats/fixtures/sample_data.json | 177 ++++++++++++++------
stats/models.py | 9 +-
stats/templatetags/stats_extras.py | 2 +-
stats/tests/__init__.py | 143 +++++++---------
stats/tests/fixture_factory.py | 8 +-
.../help/C/figures/gnome-hello-logo.png | Bin 0 -> 3388 bytes
.../help/fr/figures/gnome-hello-logo.png | Bin 0 -> 3388 bytes
stats/utils.py | 125 +++++++++-----
teams/tests.py | 2 +-
10 files changed, 278 insertions(+), 191 deletions(-)
---
diff --git a/common/fields.py b/common/fields.py
index 4fb0ce8..1794c96 100644
--- a/common/fields.py
+++ b/common/fields.py
@@ -87,6 +87,9 @@ class JSONField(models.TextField):
return super(JSONField, self).get_db_prep_save(value, connection=connection)
+ def value_to_string(self, obj):
+ return simplejson.dumps(self._get_val_from_obj(obj), cls=DjangoJSONEncoder)
+
# rules for South migrations tool (for version >= 0.7)
try:
diff --git a/stats/fixtures/sample_data.json b/stats/fixtures/sample_data.json
index 516fac1..2f8ad8a 100644
--- a/stats/fixtures/sample_data.json
+++ b/stats/fixtures/sample_data.json
@@ -9,12 +9,12 @@
"is_active": true,
"is_superuser": false,
"is_staff": false,
- "last_login": "2011-08-08 22:23:57",
+ "last_login": "2011-08-30 23:11:56",
"groups": [],
"user_permissions": [],
"password": "!",
"email": "bob example org",
- "date_joined": "2011-08-08 22:23:57"
+ "date_joined": "2011-08-30 23:11:56"
}
},
{
@@ -27,12 +27,12 @@
"is_active": true,
"is_superuser": false,
"is_staff": false,
- "last_login": "2011-08-08 22:23:57",
+ "last_login": "2011-08-30 23:11:56",
"groups": [],
"user_permissions": [],
"password": "!",
"email": "coord example org",
- "date_joined": "2011-08-08 22:23:57"
+ "date_joined": "2011-08-30 23:11:56"
}
},
{
@@ -45,12 +45,12 @@
"is_active": true,
"is_superuser": false,
"is_staff": false,
- "last_login": "2011-08-08 22:23:57",
+ "last_login": "2011-08-30 23:11:56",
"groups": [],
"user_permissions": [],
"password": "!",
"email": "alessio example org",
- "date_joined": "2011-08-08 22:23:57"
+ "date_joined": "2011-08-30 23:11:56"
}
},
{
@@ -199,7 +199,7 @@
"vcs_web": "http://git.gnome.org/browse/gnome-hello/",
"name": "gnome-hello",
"vcs_root": "git://git.gnome.org/gnome-hello",
- "bugs_product": "gnome-hello",
+ "bugs_product": "test",
"ext_platform": null,
"maintainers": [],
"bugs_component": "test",
@@ -446,8 +446,11 @@
"pk": 1,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 47,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -458,8 +461,11 @@
"pk": 2,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 47,
@@ -470,8 +476,11 @@
"pk": 3,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 7,
+ "translated_words": 0,
"figures": null,
"fuzzy": 10,
"translated": 30,
@@ -482,9 +491,12 @@
"pk": 4,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 20,
- "figures": null,
+ "translated_words": 0,
+ "figures": "[{\"path\": \"figures/gnome-hello-new.png\", \"hash\": \"8a1fcc6f46a22a1f500cfef9ca51b481\"}, {\"path\": \"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\"}]",
"fuzzy": 0,
"translated": 0,
"path": null
@@ -494,9 +506,12 @@
"pk": 5,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
- "figures": null,
+ "translated_words": 0,
+ "figures": "[{\"translated\": false, \"path\": \"figures/gnome-hello-new.png\", \"hash\": \"8a1fcc6f46a22a1f500cfef9ca51b481\", \"fuzzy\": true}, {\"translated\": false, \"path\": \"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\", \"fuzzy\": false}]",
"fuzzy": 0,
"translated": 20,
"path": null
@@ -506,8 +521,11 @@
"pk": 6,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 20,
@@ -518,8 +536,11 @@
"pk": 7,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-08 22:23:57",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 136,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -530,8 +551,11 @@
"pk": 8,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 128,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -542,8 +566,11 @@
"pk": 9,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 136,
@@ -554,8 +581,11 @@
"pk": 10,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 6,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 130,
@@ -566,8 +596,11 @@
"pk": 11,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 28,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 100,
@@ -578,8 +611,11 @@
"pk": 12,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 259,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -590,8 +626,11 @@
"pk": 13,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 259,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -602,8 +641,11 @@
"pk": 14,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 259,
@@ -614,8 +656,11 @@
"pk": 15,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 149,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -626,8 +671,11 @@
"pk": 16,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 4,
"translated": 255,
@@ -638,8 +686,11 @@
"pk": 17,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 259,
@@ -650,8 +701,11 @@
"pk": 18,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 259,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -662,8 +716,11 @@
"pk": 19,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 259,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -674,8 +731,11 @@
"pk": 20,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 259,
@@ -686,8 +746,11 @@
"pk": 21,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 626,
+ "translated_words": 0,
"figures": null,
"fuzzy": 0,
"translated": 0,
@@ -698,8 +761,11 @@
"pk": 22,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 2,
+ "translated_words": 0,
"figures": null,
"fuzzy": 20,
"translated": 598,
@@ -710,8 +776,11 @@
"pk": 23,
"model": "stats.pofile",
"fields": {
- "updated": "2011-08-10 14:15:49",
+ "updated": "2011-08-30 23:11:56",
+ "untranslated_words": 0,
+ "fuzzy_words": 0,
"untranslated": 0,
+ "translated_words": 0,
"figures": null,
"fuzzy": 6,
"translated": 620,
@@ -724,7 +793,7 @@
"fields": {
"domain": 1,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 1,
@@ -739,7 +808,7 @@
"fields": {
"domain": 1,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 2,
@@ -754,7 +823,7 @@
"fields": {
"domain": 1,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 3,
@@ -769,7 +838,7 @@
"fields": {
"domain": 2,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 4,
@@ -784,7 +853,7 @@
"fields": {
"domain": 2,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 5,
@@ -799,7 +868,7 @@
"fields": {
"domain": 2,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 6,
@@ -814,7 +883,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 7,
@@ -829,7 +898,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 9,
@@ -844,7 +913,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 10,
@@ -859,7 +928,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 12,
@@ -874,7 +943,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 13,
@@ -889,7 +958,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 14,
@@ -904,7 +973,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 15,
@@ -919,7 +988,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 16,
@@ -934,7 +1003,7 @@
"fields": {
"domain": 3,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 17,
@@ -949,7 +1018,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 18,
@@ -964,7 +1033,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 19,
@@ -979,7 +1048,7 @@
"fields": {
"domain": 4,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 20,
@@ -994,7 +1063,7 @@
"fields": {
"domain": 5,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 21,
@@ -1009,7 +1078,7 @@
"fields": {
"domain": 5,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 22,
@@ -1024,7 +1093,7 @@
"fields": {
"domain": 5,
"old_translated": 0,
- "old_date": "2011-08-10 14:15:49",
+ "old_date": "2011-08-30 23:11:56",
"old_fuzzy": 0,
"old_untranslated": 0,
"full_po": 23,
@@ -1042,4 +1111,4 @@
"description": "Error regenerating POT file for zenity:\n<pre>intltool-update -g 'zenity' -p\nERROR: xgettext failed to generate PO template file.</pre>"
}
}
-]
\ No newline at end of file
+]
diff --git a/stats/models.py b/stats/models.py
index 5b87de3..9b47625 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -490,13 +490,8 @@ class Branch(models.Model):
fig_stats = None
if dom.dtype == "doc":
fig_stats = utils.get_fig_stats(outpo, pot_method)
- for fig in fig_stats:
- trans_path = os.path.join(domain_path, lang, fig['path'])
- if os.access(trans_path, os.R_OK):
- fig_file = open(trans_path, 'rb').read()
- trans_hash = hashlib.md5(fig_file).hexdigest()
- if fig['hash'] == trans_hash:
- langstats['errors'].append(("warn-ext", "Figures should not be copied when identical to original (%s)." % trans_path))
+ fig_errors = utils.check_identical_figures(fig_stats, domain_path, lang)
+ langstats['errors'].extend(fig_errors)
if settings.DEBUG: print >>sys.stderr, lang + ":\n" + str(langstats)
# Save in DB
diff --git a/stats/templatetags/stats_extras.py b/stats/templatetags/stats_extras.py
index 19ce6a1..fd612e8 100644
--- a/stats/templatetags/stats_extras.py
+++ b/stats/templatetags/stats_extras.py
@@ -62,7 +62,7 @@ def num_stats(stat, scope='full'):
result = '<pre class="stats"><b>%(prc)3s%%</b> %(translated)6s %(fuzzy)5s %(untranslated)5s </pre>' % stats
result = result.replace(" 0 ", '<span class="zero"> 0 </span>')
else:
- result = "(%(translated)s/%(fuzzy)s/%(untranslated)s)"
+ result = "(%(translated)s/%(fuzzy)s/%(untranslated)s)" % stats
return mark_safe(result)
@register.filter
diff --git a/stats/tests/__init__.py b/stats/tests/__init__.py
index 0aafa22..461716a 100644
--- a/stats/tests/__init__.py
+++ b/stats/tests/__init__.py
@@ -47,6 +47,7 @@ def test_scratchdir(test_func):
class ModuleTestCase(TestCase):
+ fixtures = ['sample_data.json']
SYS_DEPENDENCIES = (
('gettext', 'msgfmt'),
('intltool', 'intltool-update'),
@@ -63,28 +64,9 @@ class ModuleTestCase(TestCase):
shutil.rmtree(self.co_path)
def setUp(self):
- # TODO: load bulk data from fixtures
Branch.checkout_on_creation = False
- self.mod = Module.objects.create(
- name="gnome-hello",
- bugs_base="http://bugzilla.gnome.org",
- bugs_product="test", # This product really exists
- bugs_component="test",
- vcs_type="git",
- vcs_root="git://git.gnome.org/gnome-hello",
- vcs_web="http://git.gnome.org/browse/gnome-hello/")
- self.mod.save()
- dom = Domain.objects.create(module=self.mod, name='po', description='UI Translations', dtype='ui', directory='po')
- dom = Domain.objects.create(module=self.mod, name='help', description='User Guide', dtype='doc', directory='help')
-
- self.b = Branch(name='master', module=self.mod)
- self.b.save(update_statistics=False)
-
- self.rel = Release.objects.create(
- name='gnome-2-24', status='official',
- description='GNOME 2.24 (stable)', string_frozen=True)
-
- self.cat = Category.objects.create(release=self.rel, branch=self.b, name='desktop')
+ self.mod = Module.objects.get(name="gnome-hello")
+ self.branch = self.mod.branch_set.get(name="master")
def tearDown(self):
if os.access(self.co_path, os.X_OK):
@@ -92,20 +74,23 @@ class ModuleTestCase(TestCase):
run_shell_command(command, raise_on_error=True)
def testModuleFunctions(self):
- self.assertEquals(self.mod.get_description(), 'gnome-hello')
+ self.assertEqual(self.mod.get_description(), 'gnome-hello')
def testBranchFunctions(self):
- self.assertTrue(self.b.is_head())
- self.assertEquals(self.b.get_vcs_url(), "git://git.gnome.org/gnome-hello")
- self.assertEquals(self.b.get_vcs_web_url(), "http://git.gnome.org/browse/gnome-hello/")
+ self.assertTrue(self.branch.is_head())
+ self.assertEqual(self.branch.get_vcs_url(), "git://git.gnome.org/gnome-hello")
+ self.assertEqual(self.branch.get_vcs_web_url(), "http://git.gnome.org/browse/gnome-hello/")
def testBranchStats(self):
# Check stats
- self.b.update_stats(force=True)
- fr_po_stat = Statistics.objects.get(branch=self.b, domain__name='po', language__locale='fr')
+ self.branch.update_stats(force=True)
+ fr_po_stat = Statistics.objects.get(branch=self.branch, domain__name='po', language__locale='fr')
self.assertEqual(fr_po_stat.translated(), 44)
- fr_doc_stat = Statistics.objects.get(branch=self.b, domain__name='help', language__locale='fr')
+ fr_doc_stat = Statistics.objects.get(branch=self.branch, domain__name='help', language__locale='fr')
self.assertEqual(fr_doc_stat.translated(), 16)
+ self.assertEqual(fr_po_stat.po_url(), u"/POT/gnome-hello.master/gnome-hello.master.fr.po")
+ self.assertEqual(fr_po_stat.pot_url(), u"/POT/gnome-hello.master/gnome-hello.master.pot")
+ self.assertEqual(fr_doc_stat.po_url(), u"/POT/gnome-hello.master/docs/gnome-hello-help.master.fr.po")
def testCreateAndDeleteBranch(self):
Branch.checkout_on_creation = True
@@ -124,54 +109,52 @@ class ModuleTestCase(TestCase):
b1.save(update_statistics=False)
b2 = Branch(name='p-branch', module=self.mod)
b2.save(update_statistics=False)
- self.assertEquals([b.name for b in sorted(self.mod.branch_set.all())], ['master','p-branch','a-branch'])
+ self.assertEqual([b.name for b in sorted(self.mod.branch_set.all())], ['master','p-branch','a-branch'])
b1.weight = -1
b1.save(update_statistics=False)
- self.assertEquals([b.name for b in sorted(self.mod.branch_set.all())], ['master','a-branch','p-branch'])
+ self.assertEqual([b.name for b in sorted(self.mod.branch_set.all())], ['master','a-branch','p-branch'])
def testStringFrozenMail(self):
""" String change for a module of a string_frozen release should generate a message """
mail.outbox = []
- self.rel.string_frozen = True
- self.rel.save()
- self.b.update_stats(force=False)
+ self.branch.update_stats(force=False)
# Create a new file with translation
- new_file_path = os.path.join(self.b.co_path(), "dummy_file.py")
+ new_file_path = os.path.join(self.branch.co_path(), "dummy_file.py")
new_string = "Dummy string for D-L tests"
f = open(new_file_path,'w')
f.write("a = _('%s')\n" % new_string)
f.close()
# Add the new file to POTFILES.in
- f = open(os.path.join(self.b.co_path(), "po", "POTFILES.in"), 'a')
+ f = open(os.path.join(self.branch.co_path(), "po", "POTFILES.in"), 'a')
f.write("dummy_file.py\n")
f.close()
# Regenerate stats (mail should be sent)
- self.b.update_stats(force=False, checkout=False)
+ self.branch.update_stats(force=False, checkout=False)
# Assertions
- self.assertEquals(len(mail.outbox), 1);
- self.assertEquals(mail.outbox[0].subject, "String additions to 'gnome-hello.master'")
+ self.assertEqual(len(mail.outbox), 1);
+ self.assertEqual(mail.outbox[0].subject, "String additions to 'gnome-hello.master'")
self.assertTrue(mail.outbox[0].message().as_string().find(new_string)>-1)
def testReadFileVariable(self):
from stats.utils import search_variable_in_file
file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "help_docbook", "Makefile.am")
var_content = search_variable_in_file(file_path, "DOC_INCLUDES")
- self.assertEquals(var_content.split(), ['rnusers.xml', 'rnlookingforward.xml', '$(NULL)'])
+ self.assertEqual(var_content.split(), ['rnusers.xml', 'rnlookingforward.xml', '$(NULL)'])
def testGenerateDocPotfile(self):
- from stats.utils import generate_doc_pot_file, get_fig_stats
+ from stats.utils import generate_doc_pot_file, get_fig_stats, DocFormat
# Docbook-style help
help_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "help_docbook")
- generate_doc_pot_file(help_path, 'release-notes', 'release-notes')
+ potfile, errs, doc_format = generate_doc_pot_file(help_path, 'release-notes', 'release-notes')
pot_path = os.path.join(help_path, "C", "release-notes.pot")
self.assertTrue(os.access(pot_path, os.R_OK))
- res = get_fig_stats(pot_path, image_method='xml2po')
+ res = get_fig_stats(pot_path, doc_format=doc_format)
self.assertEqual(len(res), 1)
os.remove(pot_path)
# Mallard-style help (with itstool)
pot_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "help_mallard", "gnome-help-itstool.pot")
- res = get_fig_stats(pot_path, image_method='itstool')
+ res = get_fig_stats(pot_path, doc_format=DocFormat(True, True))
self.assertEqual(len(res), 2)
self.assertEqual(res[0]['path'], "figures/gnome.png")
@@ -180,43 +163,10 @@ class ModuleTestCase(TestCase):
module=self.mod, name='http-po',
description='UI Translations', dtype='ui',
pot_method='http://l10n.gnome.org/POT/damned-lies.master/damned-lies.master.pot')
- self.b.checkout()
- potfile, errs = dom.generate_pot_file(self.b)
+ self.branch.checkout()
+ potfile, errs = dom.generate_pot_file(self.branch)
self.assertTrue(os.path.exists(potfile))
- def testIdenticalFigureWarning(self):
- """ Detect warning if translated figure is identical to original figure """
- self.b.checkout()
- orig_figure = os.path.join(self.b.co_path(), "help", "C", "figures", "gnome-hello-new.png")
- shutil.copy(orig_figure, os.path.join(self.b.co_path(), "help", "cs", "figures", "gnome-hello-new.png"))
- self.b.update_stats(force=True, checkout=False)
- doc_stat = Statistics.objects.get(branch=self.b, domain__name='help', language__locale='cs')
- warn_infos = Information.objects.filter(statistics=doc_stat, type='warn-ext')
- self.assertEquals(len(warn_infos), 1);
- ui_stat = Statistics.objects.get(branch=self.b, domain__name='po', language__locale='cs')
- self.assertEquals(ui_stat.po_url(), u"/POT/gnome-hello.master/gnome-hello.master.cs.po");
- self.assertEquals(ui_stat.pot_url(), u"/POT/gnome-hello.master/gnome-hello.master.pot");
- self.assertEquals(doc_stat.po_url(), u"/POT/gnome-hello.master/docs/gnome-hello-help.master.cs.po");
-
- def testFigureURLs(self):
- """ Test if figure urls are properly constructed """
- self.b.update_stats(force=True)
- stat = Statistics.objects.get(branch=self.b, domain__dtype='doc', language__locale='cs')
- figs = stat.get_figures()
- self.assertEquals(figs[0]['orig_remote_url'], 'http://git.gnome.org/browse/gnome-hello/plain/help/C/figures/gnome-hello-new.png?h=master')
- self.assertEquals(figs[0]['trans_remote_url'], 'http://git.gnome.org/browse/gnome-hello/plain/help/cs/figures/gnome-hello-new.png?h=master')
-
- def testFigureView(self):
- self.b.update_stats(force=True)
- url = reverse('stats.views.docimages', args=[self.mod.name, 'help', self.b.name, 'fr'])
- response = self.client.get(url)
- self.assertContains(response, "gnome-hello-new.png")
- # Same for a non-existing language
- Language.objects.create(name='Afrikaans', locale='af')
- url = reverse('stats.views.docimages', args=[self.mod.name, 'help', self.b.name, 'af'])
- response = self.client.get(url)
- self.assertContains(response, "gnome-hello-new.png")
-
def testCreateUnexistingBranch(self):
""" Try to create a non-existing branch """
Branch.checkout_on_creation = True
@@ -227,7 +177,7 @@ class ModuleTestCase(TestCase):
def testDynamicPO(self):
""" Test the creation of a blank po file for a new language """
lang = Language.objects.create(name="Tamil", locale="ta")
- self.b.update_stats(force=True) # At least POT stats needed
+ self.branch.update_stats(force=False) # At least POT stats needed
response = self.client.get('/module/po/gnome-hello.po.master.ta.po')
self.assertContains(response, """# Tamil translation for gnome-hello.
# Copyright (C) %s gnome-hello's COPYRIGHT HOLDER
@@ -251,15 +201,15 @@ class ModuleTestCase(TestCase):
pers.save()
self.mod.maintainers.add(pers)
update_doap_infos(self.mod)
- self.assertEquals(self.mod.maintainers.count(), 6)
+ self.assertEqual(self.mod.maintainers.count(), 6)
claude = self.mod.maintainers.get(email='claude 2xlibre net')
- self.assertEquals(claude.username, 'claudep')
+ self.assertEqual(claude.username, 'claudep')
@test_scratchdir
def testUpdateDoapInfos(self):
from stats.doap import update_doap_infos
update_doap_infos(self.mod)
- self.assertEquals(self.mod.homepage, "http://git.gnome.org/browse/gnome-hello")
+ self.assertEqual(self.mod.homepage, "http://git.gnome.org/browse/gnome-hello")
class StatisticsTests(TestCase):
@@ -288,3 +238,32 @@ class StatisticsTests(TestCase):
stats = FakeLangStatistics(pot_stats, Language.objects.get(locale='bem'))
self.assertEqual(stats.po_url(), "/module/po/zenity.po.gnome-2-30.bem.po")
self.assertEqual(stats.po_url(reduced=True), "/module/po/zenity.po.gnome-2-30.bem-reduced.po")
+
+class FigureTests(TestCase):
+ fixtures = ['sample_data.json']
+ def testFigureView(self):
+ url = reverse('stats.views.docimages', args=['gnome-hello', 'help', 'master', 'fr'])
+ response = self.client.get(url)
+ self.assertContains(response, "gnome-hello-new.png")
+ # Same for a non-existing language
+ Language.objects.create(name='Afrikaans', locale='af')
+ url = reverse('stats.views.docimages', args=['gnome-hello', 'help', 'master', 'af'])
+ response = self.client.get(url)
+ self.assertContains(response, "gnome-hello-new.png")
+
+ def testFigureURLs(self):
+ """ Test if figure urls are properly constructed """
+ stat = Statistics.objects.get(branch__module__name='gnome-hello', branch__name='master', domain__dtype='doc', language__locale='fr')
+ figs = stat.get_figures()
+ self.assertEqual(figs[0]['orig_remote_url'], 'http://git.gnome.org/browse/gnome-hello/plain/help/C/figures/gnome-hello-new.png?h=master')
+ self.assertFalse('trans_remote_url' in figs[0])
+
+ @test_scratchdir
+ def testIdenticalFigureWarning(self):
+ """ Detect warning if translated figure is identical to original figure """
+ from stats.utils import check_identical_figures
+ branch = Branch.objects.get(module__name='gnome-hello', name='master')
+ doc_stat = Statistics.objects.get(branch=branch, domain__name='help', language__locale='fr')
+ errs = check_identical_figures(doc_stat.get_figures(), os.path.join(branch.co_path(), 'help'), 'fr')
+ self.assertEqual(len(errs), 1)
+ self.assertTrue(errs[0][1].startswith("Figures should not be copied"))
diff --git a/stats/tests/fixture_factory.py b/stats/tests/fixture_factory.py
index 9563df8..166e2b7 100644
--- a/stats/tests/fixture_factory.py
+++ b/stats/tests/fixture_factory.py
@@ -55,7 +55,7 @@ class FixtureFactory(TestCase):
vcs_root="git://git.gnome.org/gnome-hello",
vcs_web="http://git.gnome.org/browse/gnome-hello/",
bugs_base="http://bugzilla.gnome.org",
- bugs_product="gnome-hello",
+ bugs_product="test", # This product really exists
bugs_component="test")
zenity = Module.objects.create(name="zenity", vcs_type="git",
vcs_root="git://git.gnome.org/zenity",
@@ -114,9 +114,11 @@ class FixtureFactory(TestCase):
Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_fr, full_po=pofile, part_po=pofile)
pofile = PoFile.objects.create(translated=30, fuzzy=10, untranslated=7)
Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_it, full_po=pofile, part_po=pofile)
- pofile = PoFile.objects.create(untranslated=20)
+ pofile = PoFile.objects.create(untranslated=20,
+ figures = [{"path": "figures/gnome-hello-new.png", "hash": "8a1fcc6f46a22a1f500cfef9ca51b481"}, {"path": "figures/gnome-hello-logo.png", "hash": "1ae47b7a7c4fbeb1f6bb72c0cf18d389"}])
Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=None, full_po=pofile, part_po=pofile)
- pofile = PoFile.objects.create(translated=20)
+ pofile = PoFile.objects.create(translated=20,
+ figures = [{"translated": False, "path": "figures/gnome-hello-new.png", "hash": "8a1fcc6f46a22a1f500cfef9ca51b481", "fuzzy": True}, {"translated": False, "path": "figures/gnome-hello-logo.png", "hash": "1ae47b7a7c4fbeb1f6bb72c0cf18d389", "fuzzy": False}])
Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_fr, full_po=pofile, part_po=pofile)
pofile = PoFile.objects.create(translated=20)
Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_it, full_po=pofile, part_po=pofile)
diff --git a/stats/tests/git/gnome-hello/help/C/figures/gnome-hello-logo.png b/stats/tests/git/gnome-hello/help/C/figures/gnome-hello-logo.png
new file mode 100644
index 0000000..b52af4b
Binary files /dev/null and b/stats/tests/git/gnome-hello/help/C/figures/gnome-hello-logo.png differ
diff --git a/stats/tests/git/gnome-hello/help/fr/figures/gnome-hello-logo.png b/stats/tests/git/gnome-hello/help/fr/figures/gnome-hello-logo.png
new file mode 100644
index 0000000..b52af4b
Binary files /dev/null and b/stats/tests/git/gnome-hello/help/fr/figures/gnome-hello-logo.png differ
diff --git a/stats/utils.py b/stats/utils.py
index ba50284..dacfdff 100644
--- a/stats/utils.py
+++ b/stats/utils.py
@@ -47,25 +47,61 @@ CHANGED_WITH_ADDITIONS = 2
CHANGED_NO_ADDITIONS = 3
ITSTOOL_PATH = getattr(settings, 'ITSTOOL_PATH', '')
-extract_tools = {
- 'xml2po': {
- 'command' : "cd \"%(dir)s\" && xml2po %(opts)s -o %(potfile)s -e %(files)s",
- 'mod_var' : "DOC_ID",
- 'incl_var': "DOC_PAGES",
- 'img_grep': "^msgid \"@@image:",
+
+class DocFormat(object):
+ itstool_regex = re.compile("^msgid \"external ref=\'(?P<path>[^\']*)\' md5=\'(?P<hash>[^\']*)\'\"")
+ xml2po_regex = re.compile("^msgid \"@@image: \'(?P<path>[^\']*)\'; md5=(?P<hash>[^\"]*)\"")
+ def __init__(self, is_itstool, is_mallard):
+ self.format = is_mallard and "mallard" or "docbook"
+ self.tool = is_itstool and "itstool" or "xml2po"
+
+ @property
+ def command(self):
+ if self.tool == "itstool":
+ return "cd \"%%(dir)s\" && %sitstool -o %%(potfile)s %%(files)s" % ITSTOOL_PATH
+ elif self.format == "mallard":
+ return "cd \"%(dir)s\" && xml2po -m mallard -o %(potfile)s -e %(files)s"
+ else:
+ return "cd \"%(dir)s\" && xml2po -o %(potfile)s -e %(files)s"
+
+ @property
+ def module_var(self):
+ if self.tool == "itstool":
+ return "HELP_ID"
+ elif self.format == "mallard":
+ return "DOC_ID"
+ else:
+ return "DOC_MODULE"
+
+ @property
+ def include_var(self):
+ if self.tool == "itstool":
+ return "HELP_FILES"
+ elif self.format == "mallard":
+ return "DOC_PAGES"
+ else:
+ return "DOC_INCLUDES"
+
+ @property
+ def img_grep(self):
+ if self.tool == "itstool":
+ return "^msgid \"external ref="
+ else:
+ return "^msgid \"@@image:"
+
+ @property
+ def img_grep(self):
+ return self.tool == "itstool" and "^msgid \"external ref=" or "^msgid \"@@image:"
+
+ @property
+ def bef_line(self):
# Lines to keep before matched grep to catch the ,fuzzy or #|msgid line
- 'bef_line': 1,
- 'img_regex': re.compile("^msgid \"@@image: \'(?P<path>[^\']*)\'; md5=(?P<hash>[^\"]*)\""),
- },
- 'itstool': {
- 'command' : "cd \"%%(dir)s\" && %sitstool -o %%(potfile)s %%(files)s" % ITSTOOL_PATH,
- 'mod_var' : "HELP_ID",
- 'incl_var': "HELP_FILES",
- 'img_grep': "^msgid \"external ref=",
- 'bef_line': 2,
- 'img_regex': re.compile("^msgid \"external ref=\'(?P<path>[^\']*)\' md5=\'(?P<hash>[^\']*)\'\""),
- },
-}
+ return self.tool == "itstool" and 2 or 1
+
+ @property
+ def img_regex(self):
+ return self.tool == "itstool" and self.itstool_regex or self.xml2po_regex
+
def sort_object_list(lst, sort_meth):
""" Sort an object list with sort_meth (which should return a translated string) """
@@ -173,25 +209,18 @@ def generate_doc_pot_file(vcs_path, potbase, moduleid):
errors = []
doc_id = read_makefile_variable([vcs_path], "HELP_ID")
- if doc_id:
- tool = "itstool"
- else:
- tool = "xml2po"
+ has_index_page = os.access(os.path.join(vcs_path, "C", "index.page"), os.R_OK)
+ doc_format = DocFormat(bool(doc_id), has_index_page)
- options = ""
- if os.access(os.path.join(vcs_path, "C", "index.page"), os.R_OK):
- # a Mallard document
+ if doc_format.format == "mallard":
files = ["index.page"]
- if tool == "xml2po":
- options = "-m mallard"
- incl_var = extract_tools[tool]['incl_var']
else:
- modulename = read_makefile_variable([vcs_path], "DOC_MODULE")
+ modulename = read_makefile_variable([vcs_path], doc_format.module_var)
if not modulename:
- return "", (("error", ugettext_noop("Module %s doesn't look like gnome-doc-utils module.") % moduleid),), tool
+ return "", (("error", ugettext_noop("Module %s doesn't look like gnome-doc-utils module.") % moduleid),), doc_format
if not os.access(os.path.join(vcs_path, "C", modulename + ".xml"), os.R_OK):
if os.access(os.path.join(vcs_path, "C", moduleid + ".xml"), os.R_OK):
- errors.append(("warn", ugettext_noop("DOC_MODULE doesn't resolve to a real file, using '%s.xml'.") % (moduleid)))
+ errors.append(("warn", ugettext_noop("%s doesn't resolve to a real file, using '%s.xml'.") % (doc_format.module_var, moduleid)))
modulename = moduleid
else:
# Last try: only one xml file in C/...
@@ -199,17 +228,16 @@ def generate_doc_pot_file(vcs_path, potbase, moduleid):
if len(xml_files) == 1:
modulename = os.path.basename(xml_files[0])[:-4]
else:
- errors.append(("error", ugettext_noop("DOC_MODULE doesn't point to a real file, probably a macro.")))
- return "", errors, tool
+ errors.append(("error", ugettext_noop("%s doesn't point to a real file, probably a macro.") % doc_format.module_var))
+ return "", errors, doc_format
files = [modulename + ".xml"]
- incl_var = "DOC_INCLUDES"
- includes = read_makefile_variable([vcs_path], incl_var)
+ includes = read_makefile_variable([vcs_path], doc_format.include_var)
if includes:
files.extend(filter(lambda x:x not in ("", "$(NULL)"), includes.split()))
files = " ".join([os.path.join("C", f) for f in files])
potfile = os.path.join(vcs_path, "C", potbase + ".pot")
- command = extract_tools[tool]['command'] % {'dir': vcs_path, 'opts': options, 'potfile': potfile, 'files': files}
+ command = doc_format.command % {'dir': vcs_path, 'potfile': potfile, 'files': files}
(status, output, errs) = run_shell_command(command)
if status != STATUS_OK:
@@ -222,9 +250,9 @@ def generate_doc_pot_file(vcs_path, potbase, moduleid):
potfile = ""
if not os.access(potfile, os.R_OK):
- return "", errors, tool
+ return "", errors, doc_format
else:
- return potfile, errors, tool
+ return potfile, errors, doc_format
def read_makefile_variable(vcs_paths, variable):
""" vcs_paths is a list of potential path where Makefile.am could be found """
@@ -408,15 +436,15 @@ def get_doc_linguas(module_path, po_path):
return {'langs': linguas.split(),
'error': ugettext_noop("DOC_LINGUAS list doesn't include this language.") }
-def get_fig_stats(pofile, image_method, trans_stats=True):
+def get_fig_stats(pofile, doc_format, trans_stats=True):
""" Extract image strings from pofile and return a list of figures dict:
[{'path':, 'hash':, 'fuzzy':, 'translated':}, ...] """
- if image_method not in ('xml2po', 'itstool'):
+ if not isinstance(doc_format, DocFormat):
return []
# Extract image strings: beforeline/msgid/msgstr/grep auto output a fourth line
- before_lines = extract_tools[image_method]['bef_line']
+ before_lines = doc_format.bef_line
command = "msgcat --no-wrap %(pofile)s| grep -A 1 -B %(before)s '%(grep)s'" % {
- 'pofile': pofile, 'grep': extract_tools[image_method]['img_grep'], 'before': before_lines,
+ 'pofile': pofile, 'grep': doc_format.img_grep, 'before': before_lines,
}
(status, output, errs) = run_shell_command(command)
if status != STATUS_OK:
@@ -430,7 +458,7 @@ def get_fig_stats(pofile, image_method, trans_stats=True):
for i, line in islice(enumerate(lines), 0, None, 3+before_lines):
# TODO: add image size
fig = {"path": '', "hash": ''}
- m = extract_tools[image_method]['img_regex'].match(lines[i+before_lines])
+ m = doc_format.img_regex.match(lines[i+before_lines])
if m:
fig["path"] = m.group('path')
fig["hash"] = m.group('hash')
@@ -440,6 +468,17 @@ def get_fig_stats(pofile, image_method, trans_stats=True):
figures.append(fig)
return figures
+def check_identical_figures(fig_stats, base_path, lang):
+ errors = []
+ for fig in fig_stats:
+ trans_path = os.path.join(base_path, lang, fig['path'])
+ if os.access(trans_path, os.R_OK):
+ fig_file = open(trans_path, 'rb').read()
+ trans_hash = hashlib.md5(fig_file).hexdigest()
+ if fig['hash'] == trans_hash:
+ errors.append(("warn-ext", "Figures should not be copied when identical to original (%s)." % trans_path))
+ return errors
+
def add_custom_header(po_path, header, value):
""" Add a custom po file header """
grep_cmd = """grep "%s" %s""" % (header, po_path)
diff --git a/teams/tests.py b/teams/tests.py
index e7293be..a5d1b54 100644
--- a/teams/tests.py
+++ b/teams/tests.py
@@ -187,7 +187,7 @@ class RoleTest(TeamsAndRolesTests):
self.pt.last_login = datetime.now()-timedelta(days=10) # active person
self.pt.save()
- self.pr.last_login = datetime.now()-timedelta(days=30*6) # inactive person
+ self.pr.last_login = datetime.now()-timedelta(days=30*6+1) # inactive person
self.pr.save()
self.pc.last_login = datetime.now()-timedelta(days=30*6-1) #active person, but in limit date
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]