cubicweb/devtools/test/unittest_i18n.py
changeset 11735 7a170207acbf
parent 11460 5be729810695
child 11822 adf0212d1dcc
--- a/cubicweb/devtools/test/unittest_i18n.py	Tue Sep 27 12:28:39 2016 +0200
+++ b/cubicweb/devtools/test/unittest_i18n.py	Fri Oct 21 18:10:15 2016 +0200
@@ -18,13 +18,19 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for i18n messages generator"""
 
+from contextlib import contextmanager
+from io import StringIO, BytesIO
 import os
 import os.path as osp
 import sys
 from subprocess import PIPE, Popen, STDOUT
-
 from unittest import TestCase, main
 
+from six import PY2
+from mock import patch
+
+from cubicweb.devtools import devctl
+from cubicweb.devtools.testlib import BaseTestCase
 
 DATADIR = osp.join(osp.abspath(osp.dirname(__file__)), 'data')
 
@@ -52,6 +58,9 @@
     return msgs
 
 
+TESTCUBE_DIR = osp.join(DATADIR, 'cubes', 'i18ntestcube')
+
+
 class cubePotGeneratorTC(TestCase):
     """test case for i18n pot file generator"""
 
@@ -87,5 +96,61 @@
         self.assertEqual(msgs, newmsgs)
 
 
+class CustomMessageExtractor(devctl.I18nCubeMessageExtractor):
+    blacklist = devctl.I18nCubeMessageExtractor.blacklist | set(['excludeme'])
+
+
+@contextmanager
+def capture_stdout():
+    stream = BytesIO() if PY2 else StringIO()
+    sys.stdout = stream
+    yield stream
+    stream.seek(0)
+    sys.stdout = sys.__stdout__
+
+
+class I18nCollectorTest(BaseTestCase):
+
+    def test_i18ncube_py_collection(self):
+        extractor = CustomMessageExtractor(DATADIR, TESTCUBE_DIR)
+        collected = extractor.collect_py()
+        expected = [osp.join(TESTCUBE_DIR, path)
+                    for path in ('__init__.py', '__pkginfo__.py',
+                                 'views.py', 'schema.py')]
+        self.assertCountEqual(expected, collected)
+
+    def test_i18ncube_js_collection(self):
+        extractor = CustomMessageExtractor(DATADIR, TESTCUBE_DIR)
+        collected = extractor.collect_js()
+        self.assertCountEqual([], collected, [])
+        extractor.blacklist = ()  # don't ignore anything
+        collected = extractor.collect_js()
+        expected = [osp.join(TESTCUBE_DIR, 'node_modules/cubes.somefile.js')]
+        self.assertCountEqual(expected, collected)
+
+    class FakeMessageExtractor(devctl.I18nCubeMessageExtractor):
+        """Fake message extractor that generates no pot file."""
+
+        def generate_pot_file(self):
+            return None
+
+    @patch('pkg_resources.load_entry_point', return_value=FakeMessageExtractor)
+    def test_cube_custom_extractor(self, mock_load_entry_point):
+        for distname, cubedir in [
+            ('cubicweb_i18ntestcube',
+             osp.join(DATADIR, 'libpython', 'cubicweb_i18ntestcube')),
+            # Legacy cubes.
+            ('i18ntestcube', osp.join(DATADIR, 'cubes', 'i18ntestcube')),
+        ]:
+            with self.subTest(cubedir=cubedir):
+                with capture_stdout() as stream:
+                    devctl.update_cube_catalogs(cubedir)
+                self.assertIn(u'no message catalog for cube i18ntestcube',
+                              stream.read())
+                mock_load_entry_point.assert_called_once_with(
+                    distname, 'cubicweb.i18ncube', 'i18ntestcube')
+                mock_load_entry_point.reset_mock()
+
+
 if __name__ == '__main__':
     main()