Implement SQL localization tests.
authordbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 11 Dec 2007 00:46:47 +0000 (00:46 +0000)
committerdbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 11 Dec 2007 00:46:47 +0000 (00:46 +0000)
Refactor some test helper functions into a common module.
Clean up db-seed-i18n.py SQL output.

git-svn-id: svn://svn.open-ils.org/ILS/trunk@8194 dcc99617-32d9-48b4-a31d-7c20da2025e4

build/i18n/scripts/db-seed-i18n.py
build/i18n/tests/data/po2sql.sql [new file with mode: 0644]
build/i18n/tests/data/sql2pot.pot [new file with mode: 0644]
build/i18n/tests/data/sqlsource.po [new file with mode: 0644]
build/i18n/tests/data/sqlsource.sql [new file with mode: 0644]
build/i18n/tests/testIDL.py
build/i18n/tests/testSQL.py [new file with mode: 0644]
build/i18n/tests/testhelper.py [new file with mode: 0644]

index 09f4cd6..48f0114 100755 (executable)
@@ -104,7 +104,7 @@ class SQL(basel10n.BaseL10N):
         """
 
         insert = "INSERT INTO config.i18n_core (fq_field, identity_value," \
-            "translation, string) VALUES ('%s', '%s', '%s', '%s');"
+            " translation, string) VALUES ('%s', '%s', '%s', '%s');"
         for entry in self.pot:
             for table in entry.occurences:
                 # Escape SQL single-quotes to avoid b0rkage
@@ -148,7 +148,7 @@ def main():
         else:
             outfile = open(options.outfile, 'w')
         for insert in pot.sql: 
-            outfile.write(insert)
+            outfile.write(insert + "\n")
     else:
         opts.print_help()
 
diff --git a/build/i18n/tests/data/po2sql.sql b/build/i18n/tests/data/po2sql.sql
new file mode 100644 (file)
index 0000000..a2694cd
--- /dev/null
@@ -0,0 +1,14 @@
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.bib_source', 'oclc', 'zz-ZZ', 'OCLC');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.bib_source', 'System Local', 'zz-ZZ', 'Lorem ipsum');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.bib_source', 'Project Gutenberg', 'zz-ZZ', 'Projekt Runeberg');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.standing', 'Good', 'zz-ZZ', 'Gut');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.standing', 'Barred', 'zz-ZZ', 'största');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Preschool', 'zz-ZZ', 'årligen');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Primary', 'zz-ZZ', 'bläddra');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Pre-adolescent', 'zz-ZZ', 'hjälp');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Adolescent', 'zz-ZZ', 'utgåvor');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Adult', 'zz-ZZ', 'öppet');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Specialized', 'zz-ZZ', 'datorföreningen');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'General', 'zz-ZZ', 'skapa');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('config.audience_map', 'Juvenile', 'zz-ZZ', 'klassisk');
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('asset.copy_location', 'Stacks', 'zz-ZZ', 'Linköping');
diff --git a/build/i18n/tests/data/sql2pot.pot b/build/i18n/tests/data/sql2pot.pot
new file mode 100644 (file)
index 0000000..7bbbc51
--- /dev/null
@@ -0,0 +1,72 @@
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: Evergreen 1.4"
+"Report-Msgid-Bugs-To: open-ils-dev@list.georgialibraries.org"
+"POT-Creation-Date: 
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>"
+"Language-Team: LANGUAGE <LL@li.org>"
+"MIME-Version: 1.0"
+"Content-Type: text/plain; charset=utf-8"
+"Content-Transfer-Encoding: 8-bit"
+
+#: config.bib_source:3
+msgid "oclc"
+msgstr ""
+
+#: config.bib_source:4
+msgid "System Local"
+msgstr ""
+
+#: config.bib_source:5
+msgid "Project Gutenberg"
+msgstr ""
+
+#: config.standing:7
+msgid "Good"
+msgstr ""
+
+#: config.standing:8
+msgid "Barred"
+msgstr ""
+
+#: config.audience_map:31
+msgid "Unknown or unspecified"
+msgstr ""
+
+#: config.audience_map:32
+msgid "Preschool"
+msgstr ""
+
+#: config.audience_map:33
+msgid "Primary"
+msgstr ""
+
+#: config.audience_map:34
+msgid "Pre-adolescent"
+msgstr ""
+
+#: config.audience_map:35
+msgid "Adolescent"
+msgstr ""
+
+#: config.audience_map:36
+msgid "Adult"
+msgstr ""
+
+#: config.audience_map:37
+msgid "Specialized"
+msgstr ""
+
+#: config.audience_map:38
+msgid "General"
+msgstr ""
+
+#: config.audience_map:39
+msgid "Juvenile"
+msgstr ""
+
+#: asset.copy_location:48
+msgid "Stacks"
+msgstr ""
diff --git a/build/i18n/tests/data/sqlsource.po b/build/i18n/tests/data/sqlsource.po
new file mode 100644 (file)
index 0000000..4e9b1c9
--- /dev/null
@@ -0,0 +1,72 @@
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: Evergreen 1.4"
+"Report-Msgid-Bugs-To: open-ils-dev@list.georgialibraries.org"
+"POT-Creation-Date: 
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>"
+"Language-Team: LANGUAGE <LL@li.org>"
+"MIME-Version: 1.0"
+"Content-Type: text/plain; charset=utf-8"
+"Content-Transfer-Encoding: 8-bit"
+
+#: config.bib_source:3
+msgid "oclc"
+msgstr "OCLC"
+
+#: config.bib_source:4
+msgid "System Local"
+msgstr "Lorem ipsum"
+
+#: config.bib_source:5
+msgid "Project Gutenberg"
+msgstr "Projekt Runeberg"
+
+#: config.standing:7
+msgid "Good"
+msgstr "Gut"
+
+#: config.standing:8
+msgid "Barred"
+msgstr "största"
+
+#: config.audience_map:31
+msgid "Unknown or unspecified"
+msgstr ""
+
+#: config.audience_map:32
+msgid "Preschool"
+msgstr "årligen"
+
+#: config.audience_map:33
+msgid "Primary"
+msgstr "bläddra"
+
+#: config.audience_map:34
+msgid "Pre-adolescent"
+msgstr "hjälp"
+
+#: config.audience_map:35
+msgid "Adolescent"
+msgstr "utgåvor"
+
+#: config.audience_map:36
+msgid "Adult"
+msgstr "öppet"
+
+#: config.audience_map:37
+msgid "Specialized"
+msgstr "datorföreningen"
+
+#: config.audience_map:38
+msgid "General"
+msgstr "skapa"
+
+#: config.audience_map:39
+msgid "Juvenile"
+msgstr "klassisk"
+
+#: asset.copy_location:48
+msgid "Stacks"
+msgstr "Linköping"
diff --git a/build/i18n/tests/data/sqlsource.sql b/build/i18n/tests/data/sqlsource.sql
new file mode 100644 (file)
index 0000000..83280cf
--- /dev/null
@@ -0,0 +1,49 @@
+--002.schema.config.sql:
+INSERT INTO config.bib_source (quality, source, transcendant) VALUES 
+    (90, oils_i18n_gettext('oclc'), FALSE),
+    (10, oils_i18n_gettext('System Local'), FALSE),
+    (1, oils_i18n_gettext('Project Gutenberg'), TRUE);
+
+INSERT INTO config.standing (value) VALUES (oils_i18n_gettext('Good'));
+INSERT INTO config.standing (value) VALUES (oils_i18n_gettext('Barred'));
+
+INSERT INTO config.xml_transform VALUES ( 'marcxml', 'http://www.loc.gov/MARC21/slim', 'marc', '---' );
+INSERT INTO config.xml_transform VALUES ( 'mods', 'http://www.loc.gov/mods/', 'mods', '/home/miker/MARC21slim2MODS.xsl' );
+
+INSERT INTO config.metabib_field ( field_class, name, xpath ) VALUES 
+    ( 'series', 'seriestitle', $$//mods:mods/mods:relatedItem[@type="series"]/mods:titleInfo$$ ),
+    ( 'title', 'abbreviated', $$//mods:mods/mods:titleInfo[mods:title and (@type='abbreviated')]$$ ),
+    ( 'title', 'translated', $$//mods:mods/mods:titleInfo[mods:title and (@type='translated')]$$ ),
+    ( 'title', 'uniform', $$//mods:mods/mods:titleInfo[mods:title and (@type='uniform')]$$ ),
+    ( 'title', 'proper', $$//mods:mods/mods:titleInfo[mods:title and not (@type)]$$ ),
+    ( 'author', 'corporate', $$//mods:mods/mods:name[@type='corporate']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ),
+    ( 'author', 'personal', $$//mods:mods/mods:name[@type='personal']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ),
+    ( 'author', 'conference', $$//mods:mods/mods:name[@type='conference']/mods:namePart[../mods:role/mods:text[text()='creator']]$$ ),
+    ( 'author', 'other', $$//mods:mods/mods:name[@type='personal']/mods:namePart[not(../mods:role)]$$ ),
+    ( 'subject', 'geographic', $$//mods:mods/mods:subject/mods:geographic$$ ),
+    ( 'subject', 'name', $$//mods:mods/mods:subject/mods:name$$ ),
+    ( 'subject', 'temporal', $$//mods:mods/mods:subject/mods:temporal$$ ),
+    ( 'subject', 'topic', $$//mods:mods/mods:subject/mods:topic$$ ),
+--  ( field_class, name, xpath ) VALUES ( 'subject', 'genre', $$//mods:mods/mods:genre$$ ),
+    ( 'keyword', 'keyword', $$//mods:mods/*[not(local-name()='originInfo')]$$ ); -- /* to fool vim */
+
+INSERT INTO config.audience_map (code, value, description) VALUES 
+    ('', oils_i18n_gettext('Unknown or unspecified'), oils_i18n_gettext('The target audience for the item not known or not specified.')),
+    ('a', oils_i18n_gettext('Preschool'), oils_i18n_gettext('The item is intended for children, approximate ages 0-5 years.')),
+    ('b', oils_i18n_gettext('Primary'), oils_i18n_gettext('The item is intended for children, approximate ages 6-8 years.')),
+    ('c', oils_i18n_gettext('Pre-adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 9-13 years.')),
+    ('d', oils_i18n_gettext('Adolescent'), oils_i18n_gettext('The item is intended for young people, approximate ages 14-17 years.')),
+    ('e', oils_i18n_gettext('Adult'), oils_i18n_gettext('The item is intended for adults.')),
+    ('f', oils_i18n_gettext('Specialized'), oils_i18n_gettext('The item is aimed at a particular audience and the nature of the presentation makes the item of little interest to another audience.')),
+    ('g', oils_i18n_gettext('General'), oils_i18n_gettext('The item is of general interest and not aimed at an audience of a particular intellectual level.')),
+    ('j', oils_i18n_gettext('Juvenile'), oils_i18n_gettext('The item is intended for children and young people, approximate ages 0-15 years.'));
+
+-- Admin user
+INSERT INTO permission.usr_perm_map (usr,perm,depth) VALUES (1,-1,0);
+
+--010.schema.biblio.sql:
+INSERT INTO biblio.record_entry VALUES (-1,1,1,1,-1,NOW(),NOW(),FALSE,FALSE,'','AUTOGEN','-1','','FOO');
+
+--040.schema.asset.sql:
+INSERT INTO asset.copy_location (name,owning_lib) VALUES (oils_i18n_gettext('Stacks'),1);
+INSERT INTO asset.call_number VALUES (-1,1,NOW(),1,NOW(),-1,1,'UNCATALOGED');
index 9d90c9e..08f74b0 100644 (file)
@@ -12,7 +12,7 @@ import os
 import polib
 import re
 import subprocess
-import sys
+import testhelper
 import unittest
 
 class TestIDLL10N(unittest.TestCase):
@@ -30,17 +30,10 @@ class TestIDLL10N(unittest.TestCase):
     testpo = os.path.join(basedir, 'data/testidl.po')
 
     def setUp(self):
-        sys.path.append(os.path.join(self.basedir, '../scripts/'))
-        self.tearDown()
-        for dir in self.tmpdirs:
-            os.mkdir(dir)
+        testhelper.setUp(self)
 
     def tearDown(self):
-        for dir in self.tmpdirs:
-            if os.access(dir, os.F_OK):
-                for file in os.listdir(dir):
-                    os.remove(os.path.join(dir, file))
-                os.rmdir(dir)
+        testhelper.tearDown(self)
 
     def testentityize(self):
         """
@@ -64,8 +57,9 @@ class TestIDLL10N(unittest.TestCase):
             '--output', self.savepot),
             0, None, None, devnull, devnull).wait()
 
-        mungepothead(self.savepot)
-        mungepothead(self.testpot)
+        # Avoid timestamp mismatches
+        testhelper.mungepothead(self.savepot)
+        testhelper.mungepothead(self.testpot)
 
         self.assertEqual(filecmp.cmp(self.savepot, self.testpot), 1)
 
@@ -80,23 +74,5 @@ class TestIDLL10N(unittest.TestCase):
             0, None, None, devnull, devnull).wait()
         self.assertEqual(filecmp.cmp(self.saveentities, self.idlentities), 1)
 
-
-def mungepothead(file):
-    """
-    Change POT header to avoid annoying timestamp mismatch
-    """
-    lines = [] 
-    mungefile = open(file)
-    for line in mungefile:
-        line = re.sub(r'^("POT-Creation-Date: ).+"$', r'\1', line)
-        lines.append(line)
-    mungefile.close()
-
-    # Write the changed lines back out
-    mungefile = open(file, 'w')
-    for line in lines:
-        mungefile.write(line)
-    mungefile.close()
-
 if __name__ == '__main__':
     unittest.main()
diff --git a/build/i18n/tests/testSQL.py b/build/i18n/tests/testSQL.py
new file mode 100644 (file)
index 0000000..9723e2d
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Perform the following tests:
+#  1. Generate a POT file from a set of marked SQL statements
+#  2. Generate an SQL file from a translated PO file
+
+import filecmp
+import os
+import subprocess
+import testhelper
+import unittest
+
+class TestSQLFramework(unittest.TestCase):
+
+    basedir = os.path.dirname(__file__)
+    script = os.path.join(basedir, '../scripts/db-seed-i18n.py')
+    tmpdirs = [(os.path.join(basedir, 'tmp/'))]
+    sqlsource = os.path.join(basedir, 'data/sqlsource.sql')
+    canonpot = os.path.join(basedir, 'data/sql2pot.pot')
+    canonpo = os.path.join(basedir, 'data/sqlsource.po')
+    testpot = os.path.join(basedir, 'tmp/sql2pot.pot')
+    canonsql = os.path.join(basedir, 'data/po2sql.sql')
+    testsql = os.path.join(basedir, 'tmp/testi18n.sql')
+
+    def setUp(self):
+        testhelper.setUp(self)
+
+    def tearDown(self):
+        testhelper.tearDown(self)
+
+    def testgenpot(self):
+        """
+        Create a POT file from our test SQL statements.
+        """
+        devnull = open('/dev/null', 'w')
+        proc = subprocess.Popen(
+            ('python', self.script, '--pot', self.sqlsource,
+            '--output', self.testpot),
+            0, None, None).wait()
+
+        # avoid basic timestamp conflicts
+        testhelper.mungepothead(self.testpot)
+        testhelper.mungepothead(self.canonpot)
+
+        self.assertEqual(filecmp.cmp(self.canonpot, self.testpot), 1)
+
+    def testgensql(self):
+        """
+        Create a SQL file from a translated PO file.
+        """
+        devnull = open('/dev/null', 'w')
+        proc = subprocess.Popen(
+            ('python', self.script, '--sql', self.canonpo,
+            '--locale', 'zz-ZZ', '--output', self.testsql),
+            0, None, None, devnull, devnull).wait()
+        self.assertEqual(filecmp.cmp(self.canonsql, self.testsql), 1)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/build/i18n/tests/testhelper.py b/build/i18n/tests/testhelper.py
new file mode 100644 (file)
index 0000000..44f5007
--- /dev/null
@@ -0,0 +1,36 @@
+import os
+import re
+import sys
+
+def mungepothead(file):
+    """
+    Change POT header to avoid annoying timestamp mismatch
+    """
+    lines = [] 
+    mungefile = open(file)
+    for line in mungefile:
+        line = re.sub(r'^("POT-Creation-Date: ).+"$', r'\1', line)
+        lines.append(line)
+    mungefile.close()
+
+    # Write the changed lines back out
+    mungefile = open(file, 'w')
+    for line in lines:
+        mungefile.write(line)
+    mungefile.close()
+
+def setUp(self):
+    sys.path.append(os.path.join(self.basedir, '../scripts/'))
+    sys.path.append(self.basedir)
+    self.tearDown()
+    for dir in self.tmpdirs:
+        os.mkdir(dir)
+
+def tearDown(self):
+    for dir in self.tmpdirs:
+        if os.access(dir, os.F_OK):
+            for file in os.listdir(dir):
+                os.remove(os.path.join(dir, file))
+            os.rmdir(dir)
+
+