fix git support for v1.5.3 (or higher) by setting "--work-tree"
[translate_toolkit.git] / storage / test_poheader.py
blob0dca59dbe2f9f9063f32ba8114d29b3212b183d7
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 import os, time
5 from translate.storage import po
6 from translate.storage import poxliff
7 from translate.storage import poheader
8 from translate.misc.dictutils import ordereddict
9 from translate.misc import wStringIO
12 def test_parseheaderstring():
13 """ test for the header parsing function"""
14 source = r'''item1: one
15 item2: two:two
16 this item must get ignored because there is no colon sign in it
17 item3: three
18 '''
19 d = poheader.parseheaderstring(source)
20 print type(d)
21 assert type(d) == ordereddict
22 assert len(d) == 3
23 assert d['item1'] == 'one'
24 assert d['item2'] == 'two:two'
25 assert d['item3'] == 'three'
27 def test_update():
28 '''test the update function'''
29 # do we really add nothing if add==False ?
30 d = poheader.update({}, test='hello')
31 assert len(d) == 0
32 # do we add if add==True ?
33 d = poheader.update({}, add=True, Test='hello')
34 assert len(d) == 1
35 assert d['Test'] == 'hello'
36 # do we really update ?
37 d = poheader.update({'Test':'hello'}, add=True, Test='World')
38 assert len(d) == 1
39 assert d['Test'] == 'World'
40 # does key rewrite work ?
41 d = poheader.update({}, add=True, test_me='hello')
42 assert d['Test-Me'] == 'hello'
43 # is the order correct ?
44 d = ordereddict()
45 d['Project-Id-Version'] = 'abc'
46 d['POT-Creation-Date'] = 'now'
47 d = poheader.update(d, add=True, Test='hello', Report_Msgid_Bugs_To='bugs@list.org')
48 assert d.keys()[0] == "Project-Id-Version"
49 assert d.keys()[1] == "Report-Msgid-Bugs-To"
50 assert d.keys()[2] == "POT-Creation-Date"
51 assert d.keys()[3] == "Test"
54 def poparse(posource):
55 """helper that parses po source without requiring files"""
56 dummyfile = wStringIO.StringIO(posource)
57 return po.pofile(dummyfile)
59 def poxliffparse(posource):
60 """helper that parses po source into poxliffFile"""
61 poxli = poxliff.PoXliffFile()
62 poxli.parse(posource)
63 return poxli
65 def check_po_date(datestring):
66 """Check the validity of a PO date.
68 The datestring must be in the format: 2007-06-08 10:08+0200
69 """
71 # We don't include the timezone offset as part of our format,
72 # because time.strptime() does not recognize %z
73 # The use of %z is deprecated in any case.
74 date_format = "%Y-%m-%d %H:%M"
76 # Get the timezone offset (last 4 digits):
77 tz = datestring[-4:]
78 assert type(int(tz)) == int
80 # Strip the timezone from the string, typically something like "+0200".
81 # This is to make the datestring conform to the specified format,
82 # we can't add %z to the format.
83 datestring = datestring[0:-5]
85 # Check that the date can be parsed
86 assert type(time.strptime(datestring, date_format)) == time.struct_time
88 def test_po_dates():
89 pofile = po.pofile()
90 headerdict = pofile.makeheaderdict(po_revision_date=True)
91 check_po_date(headerdict["POT-Creation-Date"])
92 check_po_date(headerdict["PO-Revision-Date"])
94 headerdict = pofile.makeheaderdict(pot_creation_date=time.localtime(),
95 po_revision_date=time.localtime())
96 check_po_date(headerdict["POT-Creation-Date"])
97 check_po_date(headerdict["PO-Revision-Date"])
99 def test_timezones():
100 pofile = po.pofile()
102 # The following will only work on Unix because of tzset() and %z
103 if time.__dict__.has_key('tzset'):
104 os.environ['TZ'] = 'Asia/Kabul'
105 time.tzset()
106 assert time.timezone == -16200
107 # Typically "+0430"
108 assert poheader.tzstring() == time.strftime("%z")
110 os.environ['TZ'] = 'Asia/Tehran'
111 time.tzset()
112 assert time.timezone == -12600
113 # Typically "+0330"
114 assert poheader.tzstring() == time.strftime("%z")
116 os.environ['TZ'] = 'Canada/Newfoundland'
117 time.tzset()
118 assert time.timezone == 12600
119 # Typically "-0230"
120 assert poheader.tzstring() == time.strftime("%z")
122 os.environ['TZ'] = 'US/Eastern'
123 time.tzset()
124 assert time.timezone == 18000
125 # Typically "-0400"
126 assert poheader.tzstring() == time.strftime("%z")
128 os.environ['TZ'] = 'Asia/Seoul'
129 time.tzset()
130 assert time.timezone == -32400
131 # Typically "+0900"
132 assert poheader.tzstring() == time.strftime("%z")
134 os.environ['TZ'] = 'Africa/Johannesburg'
135 time.tzset()
136 assert time.timezone == -7200
137 # Typically "+0200"
138 assert poheader.tzstring() == time.strftime("%z")
140 os.environ['TZ'] = 'Africa/Windhoek'
141 time.tzset()
142 assert time.timezone == -3600
143 # Typically "+0100"
144 # For some reason python's %z doesn't know about Windhoek DST
145 #assert poheader.tzstring() == time.strftime("%z")
147 os.environ['TZ'] = 'Egypt'
148 time.tzset()
149 assert time.timezone == -7200
150 # Typically "+0300"
151 assert poheader.tzstring() == time.strftime("%z")
153 os.environ['TZ'] = 'UTC'
154 time.tzset()
155 assert time.timezone == 0
156 # Typically "+0000"
157 assert poheader.tzstring() == time.strftime("%z")
159 def test_header_blank():
161 def compare(pofile):
162 print pofile
163 assert len(pofile.units) == 1
164 header = pofile.header()
165 assert header.isheader()
166 assert not header.isblank()
168 headeritems = pofile.parseheader()
169 assert headeritems["Project-Id-Version"] == "PACKAGE VERSION"
170 assert headeritems["Report-Msgid-Bugs-To"] == ""
171 check_po_date(headeritems["POT-Creation-Date"])
172 assert headeritems["PO-Revision-Date"] == "YEAR-MO-DA HO:MI+ZONE"
173 assert headeritems["Last-Translator"] == "FULL NAME <EMAIL@ADDRESS>"
174 assert headeritems["Language-Team"] == "LANGUAGE <LL@li.org>"
175 assert headeritems["MIME-Version"] == "1.0"
176 assert headeritems["Content-Type"] == "text/plain; charset=UTF-8"
177 assert headeritems["Content-Transfer-Encoding"] == "8bit"
178 assert headeritems["Plural-Forms"] == "nplurals=INTEGER; plural=EXPRESSION;"
181 """test header functionality"""
182 posource = r'''# other comment\n
183 msgid ""
184 msgstr ""
185 "Project-Id-Version: PACKAGE VERSION\n"
186 "Report-Msgid-Bugs-To: \n"
187 "POT-Creation-Date: 2006-03-08 17:30+0200\n"
188 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
189 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
190 "Language-Team: LANGUAGE <LL@li.org>\n"
191 "MIME-Version: 1.0\n"
192 "Content-Type: text/plain; charset=UTF-8\n"
193 "Content-Transfer-Encoding: 8bit\n"
194 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
196 pofile = poparse(posource)
197 compare(pofile)
199 ## TODO: enable this code if PoXliffFile is able to parse a header
201 ## poxliffsource = r'''<?xml version="1.0" encoding="utf-8"?>
202 ##<xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1">
204 ##<file datatype="po" original="test.po" source-language="en-US"><body><trans-unit approved="no" id="1" restype="x-gettext-domain-header" xml:space="preserve"><source>Project-Id-Version: PACKAGE VERSION
205 ##Report-Msgid-Bugs-To:
206 ##POT-Creation-Date: 2006-03-08 17:30+0200
207 ##PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
208 ##Last-Translator: FULL NAME <ph id="1">&lt;EMAIL@ADDRESS&gt;</ph>
209 ##Language-Team: LANGUAGE <ph id="2">&lt;LL@li.org&gt;</ph>
210 ##MIME-Version: 1.0
211 ##Content-Type: text/plain; charset=UTF-8
212 ##Content-Transfer-Encoding: 8bit
213 ##Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;
214 ##</source><target>Project-Id-Version: PACKAGE VERSION
215 ##Report-Msgid-Bugs-To:
216 ##POT-Creation-Date: 2006-03-08 17:30+0200
217 ##PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
218 ##Last-Translator: FULL NAME <ph id="1">&lt;EMAIL@ADDRESS&gt;</ph>
219 ##Language-Team: LANGUAGE <ph id="2">&lt;LL@li.org&gt;</ph>
220 ##MIME-Version: 1.0
221 ##Content-Type: text/plain; charset=UTF-8
222 ##Content-Transfer-Encoding: 8bit
223 ##Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;
224 ##</target><context-group name="po-entry" purpose="information"><context context-type="x-po-trancomment">other comment\n</context></context-group><note from="po-translator">other comment\n</note></trans-unit></body></file></xliff>
225 ##'''
226 ## pofile = poparse(poxliffsource)
227 ## compare(pofile)
230 def test_plural_equation():
231 """test that we work with the equation even is the last semicolon is left out, since gettext
232 tools don't seem to mind"""
233 posource = r'''msgid ""
234 msgstr ""
235 "Plural-Forms: nplurals=2; plural=(n != 1)%s\n"
237 for colon in ("", ";"):
238 pofile = poparse(posource % colon)
239 print pofile
240 assert len(pofile.units) == 1
241 header = pofile.units[0]
242 assert header.isheader()
243 assert not header.isblank()
245 headeritems = pofile.parseheader()
246 nplural, plural = pofile.getheaderplural()
247 assert nplural == "2"
248 assert plural == "(n != 1)"
249 ## TODO: add the same test for PoXliffFile
251 def test_plural_equation_across_lines():
252 """test that we work if the plural equation spans more than one line"""
253 posource = r'''msgid ""
254 msgstr ""
255 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
256 "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
258 pofile = poparse(posource)
259 print pofile
260 assert len(pofile.units) == 1
261 header = pofile.units[0]
262 assert header.isheader()
263 assert not header.isblank()
265 headeritems = pofile.parseheader()
266 nplural, plural = pofile.getheaderplural()
267 assert nplural == "3"
268 assert plural == "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)"
269 ## TODO: add the same test for PoXliffFile