[damned-lies] Refactor stats tests to not require a live git checkout



commit b15c62183b6b65aa0272d0c23d0d20dc5c103590
Author: Claude Paroz <claude 2xlibre net>
Date:   Tue Mar 13 16:01:25 2012 +0100

    Refactor stats tests to not require a live git checkout

 stats/models.py                                    |    4 +-
 stats/tests/__init__.py                            |  137 ++++++++++++--------
 stats/tests/git/gnome-hello/gnome-hello.doap       |   60 ---------
 .../help/C/figures/gnome-hello-logo.png            |  Bin 3388 -> 0 bytes
 .../help/fr/figures/gnome-hello-logo.png           |  Bin 3388 -> 0 bytes
 stats/tests/gnome-hello.tar.gz                     |  Bin 0 -> 86413 bytes
 vertimus/tests/__init__.py                         |    4 +-
 7 files changed, 86 insertions(+), 119 deletions(-)
---
diff --git a/stats/models.py b/stats/models.py
index 5f8b207..d0c56de 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -207,8 +207,8 @@ class Branch(models.Model):
             except:
                 raise ValidationError("Branch not valid: error while checking out the branch (%s)." % sys.exc_info()[1])
 
-    def save(self, force_insert=False, force_update=False, update_statistics=True):
-        super(Branch, self).save(force_insert, force_update)
+    def save(self, update_statistics=True, **kwargs):
+        super(Branch, self).save(**kwargs)
         if update_statistics:
             # The update command is launched asynchronously in a separate thread
             upd_thread = threading.Thread(target=self.update_stats, kwargs={'force':True})
diff --git a/stats/tests/__init__.py b/stats/tests/__init__.py
index 53932c9..82d162e 100644
--- a/stats/tests/__init__.py
+++ b/stats/tests/__init__.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2008-2011 Claude Paroz <claude 2xlibre net>
+# Copyright (c) 2008-2012 Claude Paroz <claude 2xlibre net>
 #
 # This file is part of Damned Lies.
 #
@@ -18,8 +18,11 @@
 # along with Damned Lies; if not, write to the Free Software Foundation, Inc.,
 # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import os, shutil
+import os
+import shutil
+import tarfile
 from datetime import date
+
 from django.test import TestCase
 from django.core import mail
 from django.core.exceptions import ValidationError
@@ -37,13 +40,25 @@ def test_scratchdir(test_func):
     def decorator(self):
         old_SCRATCHDIR = settings.SCRATCHDIR
         old_POTDIR = settings.POTDIR
-        settings.SCRATCHDIR = os.path.dirname(os.path.abspath(__file__))
+        settings.SCRATCHDIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scratch')
         settings.POTDIR = os.path.join(settings.SCRATCHDIR, "POT")
-        test_func(self)
-        settings.SCRATCHDIR = old_SCRATCHDIR
-        settings.POTDIR = old_POTDIR
+        os.makedirs(settings.POTDIR)
+        gnome_hello_tar = tarfile.open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'gnome-hello.tar.gz'))
+        gnome_hello_tar.extractall(os.path.join(settings.SCRATCHDIR, 'git'))
+        gnome_hello_tar.close()
+        try:
+            test_func(self)
+        finally:
+            shutil.rmtree(settings.SCRATCHDIR)
+            settings.SCRATCHDIR = old_SCRATCHDIR
+            settings.POTDIR = old_POTDIR
     return decorator
 
+def mocked_checkout(branch):
+    """ Replace real vcs checkout by a mocked method """
+    if branch.name == 'trunk2':
+        raise
+    return
 
 class ModuleTestCase(TestCase):
     fixtures = ['sample_data.json']
@@ -57,30 +72,23 @@ class ModuleTestCase(TestCase):
         for package, prog in self.SYS_DEPENDENCIES:
             if not check_program_presence(prog):
                 raise Exception("You are missing a required system package needed by Damned Lies (%s)" % package)
-        # Delete the checkout if it exists prior to running the test suite
-        self.co_path = os.path.join(settings.SCRATCHDIR, 'git', 'gnome-hello')
-        if os.access(self.co_path, os.X_OK):
-            shutil.rmtree(self.co_path)
 
     def setUp(self):
         Branch.checkout_on_creation = False
+        Branch.checkout = mocked_checkout
         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):
-            command = "cd \"%s\" && git reset --hard origin/master" % self.co_path
-            run_shell_command(command, raise_on_error=True)
-
-    def testModuleFunctions(self):
+    def test_module_methods(self):
         self.assertEqual(self.mod.get_description(), 'gnome-hello')
 
-    def testBranchFunctions(self):
+    def test_branch_methods(self):
         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):
+    @test_scratchdir
+    def test_branch_stats(self):
         lang = Language.objects.create(name='xxx', locale='xxx')
         ghost_stat = Statistics.objects.create(branch=self.branch, domain=self.mod.domain_set.get(name='po'), language=lang)
         # Check stats
@@ -88,25 +96,34 @@ class ModuleTestCase(TestCase):
         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.branch, domain__name='help', language__locale='fr')
-        self.assertEqual(fr_doc_stat.translated(), 16)
+        self.assertEqual(fr_doc_stat.translated(), 13)
         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")
         self.assertRaises(Statistics.DoesNotExist, Statistics.objects.get, pk=ghost_stat.pk)
+        from stats.utils import has_toolkit
+        if has_toolkit:
+            self.assertEqual(fr_po_stat.po_url(reduced=True), u"/POT/gnome-hello.master/gnome-hello.master.fr.reduced.po")
+            self.assertEqual(fr_po_stat.translated(scope='part'), 44)
 
-    def testCreateAndDeleteBranch(self):
-        Branch.checkout_on_creation = True
-        # Create branch (include checkout)
-        branch = Branch(name="gnome-hello-1-4", module = self.mod)
-        branch.save()
-        # Delete the branch (removing the repo checkout in the file system)
-        checkout_path = branch.co_path()
-        branch = Branch.objects.get(name="gnome-hello-1-4", module = self.mod)
+    @test_scratchdir
+    def test_delete_branch(self):
+        """ Deleting the master branch of a git module deletes the checkout dir """
+        checkout_path = self.branch.co_path()
+        branch = Branch.objects.create(name="gnome-hello-1-4", module = self.mod)
         branch.delete()
-        # FIXME: deleting a git branch doesn't delete the repo
-        #self.assertFalse(os.access(checkout_path, os.F_OK))
+        self.assertTrue(os.access(checkout_path, os.F_OK))
+        self.branch.delete()
+        self.assertFalse(os.access(checkout_path, os.F_OK))
+
+    def test_create_unexisting_branch(self):
+        """ Try to create a non-existing branch """
+        Branch.checkout_on_creation = True
+        branch = Branch(name="trunk2",
+                        module = self.mod)
+        self.assertRaises(ValidationError, branch.clean)
 
-    def testBranchSorting(self):
+    def test_branch_sorting(self):
         b1 = Branch(name='a-branch', module=self.mod)
         b1.save(update_statistics=False)
         b2 = Branch(name='p-branch', module=self.mod)
@@ -116,7 +133,8 @@ class ModuleTestCase(TestCase):
         b1.save(update_statistics=False)
         self.assertEqual([b.name for b in sorted(self.mod.branch_set.all())], ['master','a-branch','p-branch'])
 
-    def testStringFrozenMail(self):
+    @test_scratchdir
+    def test_string_frozen_mail(self):
         """ String change for a module of a string_frozen release should generate a message """
         mail.outbox = []
         self.branch.update_stats(force=False)
@@ -124,7 +142,7 @@ class ModuleTestCase(TestCase):
         # Create a new file with translation
         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 = open(new_file_path, 'w')
         f.write("a = _('%s')\n" % new_string)
         f.close()
         # Add the new file to POTFILES.in
@@ -138,13 +156,13 @@ class ModuleTestCase(TestCase):
         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):
+    def test_read_file_variable(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.assertEqual(var_content.split(), ['rnusers.xml', 'rnlookingforward.xml', '$(NULL)'])
 
-    def testGenerateDocPotfile(self):
+    def test_generate_doc_potfile(self):
         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")
@@ -160,7 +178,8 @@ class ModuleTestCase(TestCase):
         self.assertEqual(len(res), 2)
         self.assertEqual(res[0]['path'], "figures/gnome.png")
 
-    def testHttpPot(self):
+    @test_scratchdir
+    def test_http_pot(self):
         dom = Domain.objects.create(
             module=self.mod, name='http-po',
             description='UI Translations', dtype='ui',
@@ -169,14 +188,8 @@ class ModuleTestCase(TestCase):
         potfile, errs = dom.generate_pot_file(self.branch)
         self.assertTrue(os.path.exists(potfile))
 
-    def testCreateUnexistingBranch(self):
-        """ Try to create a non-existing branch """
-        Branch.checkout_on_creation = True
-        branch = Branch(name="trunk2",
-                        module = self.mod)
-        self.assertRaises(ValidationError, branch.clean)
-
-    def testDynamicPO(self):
+    @test_scratchdir
+    def test_dynamic_po(self):
         """ Test the creation of a blank po file for a new language """
         lang = Language.objects.create(name="Tamil", locale="ta")
         self.branch.update_stats(force=False) # At least POT stats needed
@@ -186,16 +199,25 @@ class ModuleTestCase(TestCase):
 # This file is distributed under the same license as the gnome-hello package.
 # FIRST AUTHOR <EMAIL ADDRESS>, YEAR.""" % date.today().year)
         self.assertContains(response, "Language-Team: Tamil <ta li org>")
-        response = self.client.get('/module/po/gnome-hello/po/master/ta-reduced.po')
+        try:
+            response = self.client.get('/module/po/gnome-hello/po/master/ta-reduced.po')
+        except OSError, e:
+            if "msginit" in str(e):
+                print "You are probably running an unpatched version of the translate-toolkit"
+                print "See http://bugs.locamotion.org/show_bug.cgi?id=2129";
+                return
+            else:
+                raise e
         self.assertContains(response, """# Tamil translation for gnome-hello.""")
 
     @test_scratchdir
-    def testBranchFileChanged(self):
+    def test_branch_file_changed(self):
+        # file_hashes is empty in fixture, so first call should always return True
         self.assertTrue(self.mod.get_head_branch().file_changed("gnome-hello.doap"))
         self.assertFalse(self.mod.get_head_branch().file_changed("gnome-hello.doap"))
 
     @test_scratchdir
-    def testUpdateMaintainersFromDoapFile(self):
+    def test_update_maintainers_from_doap_file(self):
         from stats.doap import update_doap_infos
         from people.models import Person
         # Add a maintainer which will be removed
@@ -203,12 +225,12 @@ class ModuleTestCase(TestCase):
         pers.save()
         self.mod.maintainers.add(pers)
         update_doap_infos(self.mod)
-        self.assertEqual(self.mod.maintainers.count(), 6)
+        self.assertEqual(self.mod.maintainers.count(), 3)
         claude = self.mod.maintainers.get(email='claude 2xlibre net')
         self.assertEqual(claude.username, 'claudep')
 
     @test_scratchdir
-    def testUpdateDoapInfos(self):
+    def test_update_doap_infos(self):
         from stats.doap import update_doap_infos
         update_doap_infos(self.mod)
         self.assertEqual(self.mod.homepage, "http://git.gnome.org/browse/gnome-hello";)
@@ -216,7 +238,7 @@ class ModuleTestCase(TestCase):
 
 class StatisticsTests(TestCase):
     fixtures = ['sample_data.json']
-    def testTotalStatsForLang(self):
+    def test_total_stats_for_lang(self):
         rel  = Release.objects.get(name="gnome-2-30")
         total_for_lang = rel.total_for_lang(Language.objects.get(locale='fr'))
         self.assertEqual(total_for_lang['ui']['total'], total_for_lang['ui_part']['total'])
@@ -226,7 +248,7 @@ class StatisticsTests(TestCase):
         self.assertEqual(total_for_lang['ui']['untranslated'], 183)
         self.assertEqual(total_for_lang['ui_part']['untranslated'], 175)
 
-    def testStatsLinks(self):
+    def test_stats_links(self):
         pot_stats = Statistics.objects.get(
             branch__module__name='zenity', branch__name='gnome-2-30',
             domain__name='po', language__isnull=True)
@@ -238,10 +260,10 @@ class StatisticsTests(TestCase):
         self.assertEqual(stats.po_url(reduced=True), "/POT/zenity.gnome-2-30/zenity.gnome-2-30.it.reduced.po")
         # Same for a fake stats
         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")
+        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")
 
-    def testSetTranslationStats(self):
+    def test_set_translation_stats(self):
         from vertimus.models import State, StateTranslating
         # Get a stat that has full_po and part_po
         stat = Statistics.objects.get(branch__module__name='zenity', branch__name='gnome-2-30', language__locale='it', domain__dtype='ui')
@@ -258,7 +280,7 @@ class StatisticsTests(TestCase):
 
 class FigureTests(TestCase):
     fixtures = ['sample_data.json']
-    def testFigureView(self):
+    def test_figure_view(self):
         url = reverse('stats.views.docimages', args=['gnome-hello', 'help', 'master', 'fr'])
         response = self.client.get(url)
         self.assertContains(response, "gnome-hello-new.png")
@@ -268,7 +290,7 @@ class FigureTests(TestCase):
         response = self.client.get(url)
         self.assertContains(response, "gnome-hello-new.png")
 
-    def testFigureURLs(self):
+    def test_figure_URLs(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()
@@ -276,10 +298,13 @@ class FigureTests(TestCase):
         self.assertFalse('trans_remote_url' in figs[0])
 
     @test_scratchdir
-    def testIdenticalFigureWarning(self):
+    def test_identical_figure_warning(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')
+        pot_stat = Statistics.objects.get(branch=branch, domain__name='help', language__isnull=True)
+        fig_path = os.path.join(pot_stat.branch.co_path(), pot_stat.domain.directory, 'C', pot_stat.get_figures()[0]['path'])
+        shutil.copyfile(fig_path, fig_path.replace('/C/', '/fr/'))
         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)
diff --git a/stats/tests/gnome-hello.tar.gz b/stats/tests/gnome-hello.tar.gz
new file mode 100644
index 0000000..08b5fcb
Binary files /dev/null and b/stats/tests/gnome-hello.tar.gz differ
diff --git a/vertimus/tests/__init__.py b/vertimus/tests/__init__.py
index 866c2cb..7ae11bd 100644
--- a/vertimus/tests/__init__.py
+++ b/vertimus/tests/__init__.py
@@ -233,9 +233,11 @@ class VertimusTest(TeamsAndRolesTests):
 
         action = Action.new_by_name('UT', person=self.pt, comment="Done by translator.", file=File(test_file))
         action.apply_on(state, action.send_mail_to_ml)
+
         self.assertEqual(action.file.url, '/media/upload/gedit-gnome-2-24-po-fr-%d.po' % state.id)
         self.assertEqual(action.merged_file.url(), '/media/upload/gedit-gnome-2-24-po-fr-%d.merged.po' % state.id)
-        self.files_to_clean.extend([action.file.path, action.merged_file.path])
+        # Merged file will not be really produced as no pot file exists on the file system
+        self.files_to_clean.append(action.file.path)
 
         self.assertTrue(isinstance(state, StateTranslated))
         # Mail sent to mailing list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]