def testEarlyEnoughPlatformSpecification(self): # This is a regression test for issue # https://code.google.com/p/grit-i18n/issues/detail?id=23 grd_text = u'''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="1" current_release="1"> <release seq="1"> <messages> <if expr="not pp_ifdef('use_titlecase')"> <message name="IDS_XYZ">foo</message> </if> <!-- The assumption is that use_titlecase is never true for this platform. When the platform isn't set to 'android' early enough, we get a duplicate message name. --> <if expr="os == '%s'"> <message name="IDS_XYZ">boo</message> </if> </messages> </release> </grit>''' % sys.platform with util.TempDir({}) as temp_dir: grd_reader.Parse(StringIO.StringIO(grd_text), temp_dir.GetPath(), target_platform='android')
def Run(self, globopt, args): args = self.Setup(globopt, args) if len(args) != 3: self.Out('This tool takes exactly three arguments:\n' ' 1. The path to the original RC file\n' ' 2. The path to the translated RC file\n' ' 3. The output file path.\n') return 2 grd = grd_reader.Parse(self.o.input, debug=self.o.extra_verbose) grd.RunGatherers() source_rc = util.ReadFile(args[0], self.rc2grd.input_encoding) transl_rc = util.ReadFile(args[1], self.rc2grd.input_encoding) translations = self.ExtractTranslations(grd, source_rc, args[0], transl_rc, args[1]) with util.WrapOutputStream(open(args[2], 'w')) as output_file: self.WriteTranslations(output_file, translations.items()) self.Out('Wrote output file %s' % args[2])
def testGetInputFilesFromIncludes(self): chrome_html_path = util.PathFromRoot('grit/testdata/chrome_html.html') xml = '''<?xml version="1.0" encoding="utf-8"?> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="default.pak" type="data_package" context="default_100_percent" /> <output filename="special.pak" type="data_package" context="special_100_percent" fallback_to_default_layout="false" /> </outputs> <release seq="1"> <includes> <include name="IDR_TESTDATA_CHROME_HTML" file="%s" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> </includes> </release> </grit>''' % chrome_html_path grd = grd_reader.Parse(StringIO.StringIO(xml), util.PathFromRoot('grit/testdata')) expected = ['chrome_html.html', 'included_sample.html'] actual = [os.path.relpath(path, util.PathFromRoot('grit/testdata')) for path in grd.GetInputFiles()] # Convert path separator for Windows paths. actual = [path.replace('\\', '/') for path in actual] self.assertEquals(expected, actual)
def ParseGrdForUnittest(body, base_dir=None): '''Parse a skeleton .grd file and return it, for use in unit tests. Args: body: XML that goes inside the <release> element. base_dir: The base_dir attribute of the <grit> tag. ''' import StringIO from grit import grd_reader if isinstance(body, unicode): body = body.encode('utf-8') if base_dir is None: base_dir = PathFromRoot('.') body = '''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" current_release="3" source_lang_id="en" base_dir="%s"> <outputs> </outputs> <release seq="3"> %s </release> </grit>''' % (base_dir, body) return grd_reader.Parse(StringIO.StringIO(body), dir=".")
def Inputs(filename, defines, ids_file): grd = grd_reader.Parse(filename, debug=False, defines=defines, tags_to_ignore=set(['message']), first_ids_file=ids_file) files = set() for lang, ctx in grd.GetConfigurations(): grd.SetOutputLanguage(lang or grd.GetSourceLanguage()) grd.SetOutputContext(ctx) for node in grd.ActiveDescendants(): with node: if (node.name == 'structure' or node.name == 'skeleton' or (node.name == 'file' and node.parent and node.parent.name == 'translations')): files.add(grd.ToRealPath(node.GetInputPath())) # If it's a flattened node, grab inlined resources too. if node.name == 'structure' and node.attrs[ 'flattenhtml'] == 'true': node.RunPreSubstitutionGatherer() files.update(node.GetHtmlResourceFilenames()) elif node.name == 'grit': first_ids_file = node.GetFirstIdsFile() if first_ids_file: files.add(first_ids_file) elif node.name == 'include': files.add(grd.ToRealPath(node.GetInputPath())) # If it's a flattened node, grab inlined resources too. if node.attrs['flattenhtml'] == 'true': files.update(node.GetHtmlResourceFilenames()) elif node.name == 'part': files.add( util.normpath( os.path.join(os.path.dirname(filename), node.GetInputPath()))) cwd = os.getcwd() return [os.path.relpath(f, cwd) for f in sorted(files)]
def Run(self, opts, args): self.SetOptions(opts) limit_file = None limit_is_grd = False limit_file_dir = None own_opts, args = getopt.getopt(args, 'l:D:ih') for key, val in own_opts: if key == '-l': limit_file = open(val, 'r') limit_file_dir = util.dirname(val) if not len(limit_file_dir): limit_file_dir = '.' limit_is_grd = os.path.splitext(val)[1] == '.grd' elif key == '-i': self.format = self.FORMAT_IDS_ONLY elif key == '-D': name, val = util.ParseDefine(val) self.defines[name] = val if not len(args) == 1: print( 'grit xmb takes exactly one argument, the path to the XMB file ' 'to output.') return 2 xmb_path = args[0] res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose) res_tree.SetOutputLanguage('en') res_tree.SetDefines(self.defines) res_tree.OnlyTheseTranslations([]) res_tree.RunGatherers(True) with open(xmb_path, 'wb') as output_file: self.Process(res_tree, output_file, limit_file, limit_is_grd, limit_file_dir) if limit_file: limit_file.close() print "Wrote %s" % xmb_path
def testRcHeaderFormat(self): grd = grd_reader.Parse( StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> <release seq="3"> <includes first_id="300" comment="bingo"> <include type="gif" name="IDR_LOGO" file="images/logo.gif" /> </includes> <messages first_id="10000"> <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? </message> <message name="IDS_BONGO"> Bongo! </message> </messages> </release> </grit>'''), '.') # Using the default rc_header format string. output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), grd.GetRcHeaderFormat()) self.assertEqual(('#define IDR_LOGO 300\n' '#define IDS_GREETING 10000\n' '#define IDS_BONGO 10001\n'), ''.join(output)) # Using a custom rc_header format string. grd.AssignRcHeaderFormat( '#define {textual_id} _Pragma("{textual_id}") {numeric_id}') output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), grd.GetRcHeaderFormat()) self.assertEqual( ('#define IDR_LOGO _Pragma("IDR_LOGO") 300\n' '#define IDS_GREETING _Pragma("IDS_GREETING") 10000\n' '#define IDS_BONGO _Pragma("IDS_BONGO") 10001\n'), ''.join(output))
def testEmit(self): grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> <outputs> <output type="rc_all" filename="dummy"> <emit emit_type="prepend">Wrong</emit> </output> <if expr="False"> <output type="rc_header" filename="dummy"> <emit emit_type="prepend">No</emit> </output> </if> <output type="rc_header" filename="dummy"> <emit emit_type="append">Error</emit> </output> <output type="rc_header" filename="dummy"> <emit emit_type="prepend">Bingo</emit> </output> </outputs> </grit>'''), '.') output = ''.join(rc_header.Format(grd, 'en', '.')) output = util.StripBlankLinesAndComments(output) self.assertEqual('#pragma once\nBingo', output)
def testSkeleton(self): grd = grd_reader.Parse( StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <release seq="3"> <structures> <structure type="dialog" name="IDD_ABOUTBOX" file="klonk.rc" encoding="utf-16-le"> <skeleton expr="lang == 'fr'" variant_of_revision="1" file="klonk-alternate-skeleton.rc" /> </structure> </structures> </release> </grit>'''), dir=util.PathFromRoot('grit\\test\\data')) grd.RunGatherers(recursive=True) grd.output_language = 'fr' node = grd.GetNodeById('IDD_ABOUTBOX') formatter = node.ItemFormatter('rc_all') self.failUnless(formatter) transl = formatter.Format(node, 'fr') self.failUnless(transl.count('040704') and transl.count('110978')) self.failUnless(transl.count('2005",IDC_STATIC'))
def doTestAssignFirstIds(self, first_ids_path): input = u'''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="." first_ids_file="%s"> <release seq="3"> <messages> <message name="IDS_TEST" desc="test"> test </message> </messages> </release> </grit>''' % first_ids_path pseudo_file = StringIO.StringIO(input) grit_root_dir = os.path.join( os.path.abspath(os.path.dirname(__file__)), '..') fake_input_path = os.path.join( grit_root_dir, "grit/testdata/chrome/app/generated_resources.grd") root = grd_reader.Parse(pseudo_file, os.path.split(fake_input_path)[0]) root.AssignFirstIds(fake_input_path, {}) messages_node = root.children[0].children[0] self.failUnless(isinstance(messages_node, empty.MessagesNode)) self.failUnless(messages_node.attrs["first_id"] != empty.MessagesNode().DefaultAttributes()["first_id"])
def main(): argparser = argparse.ArgumentParser() argparser.add_argument("--chromium-file") argparser.add_argument("--vivaldi-file") argparser.add_argument("--locale") argparser.add_argument("--messages") argparser.add_argument("grd_file") argparser.add_argument("output_file") options = argparser.parse_args() resources = grd_reader.Parse(options.grd_file) resources.SetOutputLanguage('en') resources.RunGatherers() message_list = None if options.messages: with open(options.messages, "r") as f: message_list = [x.strip() for x in f.readlines()] with open(options.output_file, "w") as f: print >> f, 'msgid ""' print >> f, 'msgstr ""' if options.locale: print >> f, '"Language: %s\\n"' % options.locale print >> f, '"MIME-Version: 1.0\\n"' print >> f, '"Content-Type: text/plain; charset=UTF-8\\n"' print >> f, '' for node in resources: if (not isinstance(node, message.MessageNode) or not node.IsTranslateable() or "name" not in node.attrs): continue if message_list and node.attrs["name"] not in message_list: continue write_message(f, options, node, options.locale)
def Outputs(filename, defines, ids_file, target_platform=None): grd = grd_reader.Parse(filename, defines=defines, tags_to_ignore=set(['messages']), first_ids_file=ids_file, target_platform=target_platform) target = [] lang_folders = {} # Add all explicitly-specified output files for output in grd.GetOutputFiles(): path = output.GetFilename() target.append(path) if path.endswith('.h'): path, filename = os.path.split(path) if output.attrs['lang']: lang_folders[output.attrs['lang']] = os.path.dirname(path) # Add all generated files, once for each output language. for node in grd: if node.name == 'structure': with node: # TODO(joi) Should remove the "if sconsdep is true" thing as it is a # hack - see grit/node/structure.py if node.HasFileForLanguage( ) and node.attrs['sconsdep'] == 'true': for lang in lang_folders: path = node.FileForLanguage( lang, lang_folders[lang], create_file=False, return_if_not_generated=False) if path: target.append(path) return [t.replace('\\', '/') for t in target]
def testRcIncludeFlattenedHtmlFile(self): input_file = util.PathFromRoot('grit/testdata/include_test.html') output_file = '%s/HTML_FILE1_include_test.html' % tempfile.gettempdir() root = grd_reader.Parse(StringIO.StringIO(''' <includes> <include name="HTML_FILE1" flattenhtml="true" file="%s" type="BINDATA" /> </includes>''' % input_file), flexible_root = True) util.FixRootForUnittest(root, '.') buf = StringIO.StringIO() build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en', output_file), buf) output = buf.getvalue() expected = u'HTML_FILE1 BINDATA "HTML_FILE1_include_test.html"' # hackety hack to work on win32&lin output = re.sub('"[c-zC-Z]:', '"', output) self.failUnless(output.strip() == expected) fo = file(output_file) file_contents = fo.read() fo.close() # Check for the content added by the <include> tag. self.failUnless(file_contents.find('Hello Include!') != -1) # Check for the content that was removed by if tag. self.failUnless(file_contents.find('should be removed') == -1) # Check for the content that was kept in place by if. self.failUnless(file_contents.find('should be kept') != -1) self.failUnless(file_contents.find('in the middle...') != -1) self.failUnless(file_contents.find('at the end...') != -1) # Check for nested content that was kept self.failUnless(file_contents.find('nested true should be kept') != -1) self.failUnless(file_contents.find('silbing true should be kept') != -1) # Check for removed "<if>" and "</if>" tags. self.failUnless(file_contents.find('<if expr=') == -1) self.failUnless(file_contents.find('</if>') == -1)
def testPredeterminedIds(self): predetermined_ids_file = self._MakeTempPredeterminedIdsFile( 'IDS_BONGO 101\nID_LOGO 102\n') grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> <release seq="3"> <includes first_id="300" comment="bingo"> <include type="gif" name="ID_LOGO" file="images/logo.gif" /> </includes> <messages first_id="10000"> <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? </message> <message name="IDS_BONGO"> Bongo! </message> </messages> </release> </grit>'''), '.', predetermined_ids_file=predetermined_ids_file) output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), grd.GetRcHeaderFormat()) self.assertEqual(('#define ID_LOGO 102\n' '#define IDS_GREETING 10000\n' '#define IDS_BONGO 101\n'), ''.join(output))
def testParsingAndXmlOutput(self): input = u'''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <release seq="3"> <includes> <include name="ID_LOGO" file="images/logo.gif" type="gif" /> </includes> <messages> <if expr="True"> <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? </message> </if> </messages> <structures> <structure name="IDD_NARROW_DIALOG" file="rc_files/dialogs.rc" type="dialog"> <skeleton variant_of_revision="3" expr="lang == 'fr-FR'" file="bla.rc" /> </structure> <structure name="VS_VERSION_INFO" file="rc_files/version.rc" type="version" /> </structures> </release> <translations> <file lang="nl" path="nl_translations.xtb" /> </translations> <outputs> <output type="rc_header" filename="resource.h" /> <output lang="en-US" type="rc_all" filename="resource.rc" /> </outputs> </grit>''' pseudo_file = StringIO.StringIO(input) tree = grd_reader.Parse(pseudo_file, '.') output = unicode(tree) # All but first two lines are the same (sans enc_check) self.failUnless('\n'.join(input.split('\n')[2:]) == '\n'.join(output.split('\n')[2:])) self.failUnless(tree.GetNodeById('IDS_GREETING'))
def testFormatter(self): grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> <release seq="3"> <includes first_id="300" comment="bingo"> <include type="gif" name="ID_LOGO" file="images/logo.gif" /> </includes> <messages first_id="10000"> <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? </message> <message name="IDS_BONGO"> Bongo! </message> </messages> <structures> <structure type="dialog" name="IDD_NARROW_DIALOG" file="rc_files/dialogs.rc" /> <structure type="version" name="VS_VERSION_INFO" file="rc_files/version.rc" /> </structures> </release> </grit>'''), '.') output = self.FormatAll(grd) self.failUnless(output.count('IDS_GREETING10000')) self.failUnless(output.count('ID_LOGO300'))
def testStructureNodeOutputfile(self): input_file = util.PathFromRoot('grit/test/data/simple.html') root = grd_reader.Parse(StringIO.StringIO( '<structure type="tr_html" name="IDR_HTML" file="%s" />' % input_file), flexible_root=True) util.FixRootForUnittest(root, '.') # We must run the gatherers since we'll be wanting the translation of the # file. The file exists in the location pointed to. root.RunGatherers(recursive=True) output_dir = tempfile.gettempdir() en_file = root.FileForLanguage('en', output_dir) self.failUnless(en_file == input_file) fr_file = root.FileForLanguage('fr', output_dir) self.failUnless(fr_file == os.path.join(output_dir, 'fr_simple.html')) fo = file(fr_file) contents = fo.read() fo.close() self.failUnless( contents.find('<p>') != -1) # should contain the markup self.failUnless(contents.find('Hello!') == -1) # should be translated
def testMessages(self): grd_text = u""" <messages> <message name="IDS_SIMPLE_MESSAGE"> Simple message. </message> <message name="IDS_QUOTES"> element\u2019s \u201c<ph name="NAME">%s<ex>name</ex></ph>\u201d attribute </message> <message name="IDS_PLACEHOLDERS"> <ph name="ERROR_COUNT">%1$d<ex>1</ex></ph> error, <ph name="WARNING_COUNT">%2$d<ex>1</ex></ph> warning </message> <message name="IDS_STARTS_WITH_SPACE"> ''' (<ph name="COUNT">%d<ex>2</ex></ph>) </message> <message name="IDS_DOUBLE_QUOTES"> A "double quoted" message. </message> </messages> """ root = grd_reader.Parse(StringIO.StringIO(grd_text.encode('utf-8')), flexible_root=True) util.FixRootForUnittest(root) buf = StringIO.StringIO() build.RcBuilder.ProcessNode(root, DummyOutput('js_map_format', 'en'), buf) output = buf.getvalue() test = u""" localizedStrings["Simple message."] = "Simple message."; localizedStrings["element\u2019s \u201c%s\u201d attribute"] = "element\u2019s \u201c%s\u201d attribute"; localizedStrings["%d error, %d warning"] = "%1$d error, %2$d warning"; localizedStrings[" (%d)"] = " (%d)"; localizedStrings["A \\\"double quoted\\\" message."] = "A \\\"double quoted\\\" message."; """ self.failUnless(output.strip() == test.strip())
def testIffynessWithOutputNodes(self): grd = grd_reader.Parse(StringIO(''' <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <outputs> <output filename="uncond1.rc" type="rc_data" /> <if expr="lang == 'fr' or 'hello' in defs"> <output filename="only_fr.adm" type="adm" /> <output filename="only_fr.plist" type="plist" /> </if> <if expr="lang == 'ru'"> <output filename="doc.html" type="document" /> </if> <output filename="uncond2.adm" type="adm" /> <output filename="iftest.h" type="rc_header"> <emit emit_type='prepend'></emit> </output> </outputs> </grit>'''), dir='.') outputs_node = grd.children[0] uncond1_output = outputs_node.children[0] only_fr_adm_output = outputs_node.children[1].children[0] only_fr_plist_output = outputs_node.children[1].children[1] doc_output = outputs_node.children[2].children[0] uncond2_output = outputs_node.children[0] self.assertTrue(uncond1_output.name == 'output') self.assertTrue(only_fr_adm_output.name == 'output') self.assertTrue(only_fr_plist_output.name == 'output') self.assertTrue(doc_output.name == 'output') self.assertTrue(uncond2_output.name == 'output') grd.SetOutputLanguage('ru') grd.SetDefines({'hello': '1'}) outputs = [output.GetFilename() for output in grd.GetOutputFiles()] self.assertEquals(outputs, [ 'uncond1.rc', 'only_fr.adm', 'only_fr.plist', 'doc.html', 'uncond2.adm', 'iftest.h' ]) grd.SetOutputLanguage('ru') grd.SetDefines({'bingo': '2'}) outputs = [output.GetFilename() for output in grd.GetOutputFiles()] self.assertEquals( outputs, ['uncond1.rc', 'doc.html', 'uncond2.adm', 'iftest.h']) grd.SetOutputLanguage('fr') grd.SetDefines({'hello': '1'}) outputs = [output.GetFilename() for output in grd.GetOutputFiles()] self.assertEquals(outputs, [ 'uncond1.rc', 'only_fr.adm', 'only_fr.plist', 'uncond2.adm', 'iftest.h' ]) grd.SetOutputLanguage('en') grd.SetDefines({'bingo': '1'}) outputs = [output.GetFilename() for output in grd.GetOutputFiles()] self.assertEquals(outputs, ['uncond1.rc', 'uncond2.adm', 'iftest.h']) grd.SetOutputLanguage('fr') grd.SetDefines({'bingo': '1'}) outputs = [output.GetFilename() for output in grd.GetOutputFiles()] self.assertNotEquals(outputs, ['uncond1.rc', 'uncond2.adm', 'iftest.h'])
def Process(self, res_tree, output_file, limit_file=None, limit_is_grd=False, dir=None, missing_translate_for_lang=None): """Writes a document with the contents of res_tree into output_file, limiting output to the IDs specified in limit_file, which is a GRD file if limit_is_grd is true, otherwise a file with one ID per line. The format of the output document depends on this object's format attribute. It can be FORMAT_XMB or FORMAT_IDS_ONLY. The FORMAT_IDS_ONLY format causes this function to write just a list of the IDs of all messages that would have been added to the XMB file, one ID per line. The FORMAT_XMB format causes this function to output the (default) XMB format. Args: res_tree: base.Node() output_file: file open for writing limit_file: None or file open for reading limit_is_grd: True | False dir: Directory of the limit file """ if limit_file: if limit_is_grd: limit_list = [] limit_tree = grd_reader.Parse(limit_file, dir=dir, debug=self.o.extra_verbose) for node in limit_tree: if 'name' in node.attrs: limit_list.append(node.attrs['name']) else: # Not a GRD file, so it's just a file with one ID per line limit_list = [ item.strip() for item in limit_file.read().split('\n') ] if missing_translate_for_lang: active_nodes = [ x.GetCliques()[0].GetId() for x in res_tree.ActiveDescendants() if x.GetCliques() ] ids_already_done = {} messages = [] for node in res_tree: if (limit_file and not ('name' in node.attrs and node.attrs['name'] in limit_list)): continue if not node.IsTranslateable(): continue for clique in node.GetCliques(): if not clique.IsTranslateable(): continue if not clique.GetMessage().GetRealContent(): continue # Some explanation is in order here. Note that we can have # many messages with the same ID. # # The way we work around this is to maintain a list of cliques # per message ID (in the UberClique) and select the "best" one # (the first one that has a description, or an arbitrary one # if there is no description) for inclusion in the XMB file. # The translations are all going to be the same for messages # with the same ID, although the way we replace placeholders # might be slightly different. id = clique.GetMessage().GetId() if id in ids_already_done: continue ids_already_done[id] = 1 #print missing_translate_for_lang, ":", clique.GetMessage().GetId(),":", clique.GetMessage().GetDescription(), "--::--", clique.MessageForLanguage(missing_translate_for_lang).GetPresentableContent() if missing_translate_for_lang: if id not in active_nodes: continue try: if clique.MessageForLanguage( missing_translate_for_lang, missing_translation_is_error=True): continue except: pass message = node.UberClique().BestClique(id).GetMessage() messages += [message] # Ensure a stable order of messages, to help regression testing. messages.sort(key=lambda x: x.GetId()) if self.format == self.FORMAT_IDS_ONLY: # We just print the list of IDs to the output file. for msg in messages: output_file.write(msg.GetId()) output_file.write('\n') else: assert self.format == self.FORMAT_XMB WriteXmbFile(output_file, messages)
def testIffyness(self): grd = grd_reader.Parse(StringIO(''' <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <release seq="3"> <messages> <if expr="'bingo' in defs"> <message name="IDS_BINGO"> Bingo! </message> </if> <if expr="'hello' in defs"> <message name="IDS_HELLO"> Hello! </message> </if> <if expr="lang == 'fr' or 'FORCE_FRENCH' in defs"> <message name="IDS_HELLO" internal_comment="French version"> Good morning </message> </if> <if expr="is_win"> <message name="IDS_ISWIN">is_win</message> </if> </messages> </release> </grit>'''), dir='.') messages_node = grd.children[0].children[0] bingo_message = messages_node.children[0].children[0] hello_message = messages_node.children[1].children[0] french_message = messages_node.children[2].children[0] is_win_message = messages_node.children[3].children[0] self.assertTrue(bingo_message.name == 'message') self.assertTrue(hello_message.name == 'message') self.assertTrue(french_message.name == 'message') grd.SetOutputLanguage('fr') grd.SetDefines({'hello': '1'}) active = set(grd.ActiveDescendants()) self.failUnless(bingo_message not in active) self.failUnless(hello_message in active) self.failUnless(french_message in active) grd.SetOutputLanguage('en') grd.SetDefines({'bingo': 1}) active = set(grd.ActiveDescendants()) self.failUnless(bingo_message in active) self.failUnless(hello_message not in active) self.failUnless(french_message not in active) grd.SetOutputLanguage('en') grd.SetDefines({'FORCE_FRENCH': '1', 'bingo': '1'}) active = set(grd.ActiveDescendants()) self.failUnless(bingo_message in active) self.failUnless(hello_message not in active) self.failUnless(french_message in active) grd.SetOutputLanguage('en') grd.SetDefines({}) self.failUnless(grd.target_platform == sys.platform) grd.SetTargetPlatform('darwin') active = set(grd.ActiveDescendants()) self.failUnless(is_win_message not in active) grd.SetTargetPlatform('win32') active = set(grd.ActiveDescendants()) self.failUnless(is_win_message in active)
def Run(self, opts, args): os.environ['cwd'] = os.getcwd() self.output_directory = '.' first_ids_file = None predetermined_ids_file = None whitelist_filenames = [] assert_output_files = [] target_platform = None depfile = None depdir = None whitelist_support = False write_only_new = False depend_on_stamp = False js_minifier = None replace_ellipsis = True (own_opts, args) = getopt.getopt(args, 'a:p:o:D:E:f:w:t:', ('depdir=','depfile=','assert-file-list=', 'help', 'output-all-resource-defines', 'no-output-all-resource-defines', 'no-replace-ellipsis', 'depend-on-stamp', 'js-minifier=', 'write-only-new=', 'whitelist-support')) for (key, val) in own_opts: if key == '-a': assert_output_files.append(val) elif key == '--assert-file-list': with open(val) as f: assert_output_files += f.read().splitlines() elif key == '-o': self.output_directory = val elif key == '-D': name, val = util.ParseDefine(val) self.defines[name] = val elif key == '-E': (env_name, env_value) = val.split('=', 1) os.environ[env_name] = env_value elif key == '-f': # TODO([email protected]): Remove this override once change # lands in WebKit.grd to specify the first_ids_file in the # .grd itself. first_ids_file = val elif key == '-w': whitelist_filenames.append(val) elif key == '--no-replace-ellipsis': replace_ellipsis = False elif key == '-p': predetermined_ids_file = val elif key == '-t': target_platform = val elif key == '--depdir': depdir = val elif key == '--depfile': depfile = val elif key == '--write-only-new': write_only_new = val != '0' elif key == '--depend-on-stamp': depend_on_stamp = True elif key == '--js-minifier': js_minifier = val elif key == '--whitelist-support': whitelist_support = True elif key == '--help': self.ShowUsage() sys.exit(0) if len(args): print 'This tool takes no tool-specific arguments.' return 2 self.SetOptions(opts) if self.scons_targets: self.VerboseOut('Using SCons targets to identify files to output.\n') else: self.VerboseOut('Output directory: %s (absolute path: %s)\n' % (self.output_directory, os.path.abspath(self.output_directory))) if whitelist_filenames: self.whitelist_names = set() for whitelist_filename in whitelist_filenames: self.VerboseOut('Using whitelist: %s\n' % whitelist_filename); whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT) self.whitelist_names.update(whitelist_contents.strip().split('\n')) if js_minifier: minifier.SetJsMinifier(js_minifier) self.write_only_new = write_only_new self.res = grd_reader.Parse(opts.input, debug=opts.extra_verbose, first_ids_file=first_ids_file, predetermined_ids_file=predetermined_ids_file, defines=self.defines, target_platform=target_platform) # Set an output context so that conditionals can use defines during the # gathering stage; we use a dummy language here since we are not outputting # a specific language. self.res.SetOutputLanguage('en') self.res.SetWhitelistSupportEnabled(whitelist_support) self.res.RunGatherers() # Replace ... with the single-character version. http://crbug.com/621772 if replace_ellipsis: for node in self.res: if isinstance(node, message.MessageNode): node.SetReplaceEllipsis(True) self.Process() if assert_output_files: if not self.CheckAssertedOutputFiles(assert_output_files): return 2 if depfile and depdir: self.GenerateDepfile(depfile, depdir, first_ids_file, depend_on_stamp) return 0
def update_resources(res, input_file, params={}, whitelist_support=None, active_only=True): ReplaceGoogle(res, exceptions=REPLACE_GOOGLE_EXCEPTIONS) new_resources = grd_reader.Parse(input_file, **params) util.PathSearcher.Configure([ os.path.dirname(input_file), res.GetBaseDir(), ]) new_resources.SetOutputLanguage('en') new_resources.SetWhitelistSupportEnabled(whitelist_support) new_resources.UberClique().keep_additional_translations_ = True new_resources.RunGatherers() nodes = new_resources.GetChildrenOfType(empty.OutputsNode) if nodes: assert (len(nodes) == 1) new_node = nodes[0] nodes = res.GetChildrenOfType(empty.OutputsNode) assert (nodes) if nodes: assert (len(nodes) == 1) old_node = nodes[0] old_node.children.extend(new_node.children) resource_list = {} for node in (new_resources.ActiveDescendants() if active_only else new_resources): if "name" not in node.attrs: continue if isinstance(node, (message.PhNode, message.ExNode)): continue resource_list.setdefault(node.attrs["name"], []).append(node) names = list(resource_list.keys()) done_names = set() for node in (res.ActiveDescendants() if active_only else res): node_name = node.attrs.get("name", None) if not node_name: continue if isinstance(node, (message.PhNode, message.ExNode)): continue new_nodes = resource_list.pop(node_name, []) if not new_nodes: if node_name in done_names: assert not active_only, "Multiple active entries for {} in Chromium are not permitted".format( node_name) par_node = node.parent index = par_node.children.index(node) # non-active mode: We already inserted all our entries earlier. # Remove all other entries with this name in the upstream resources del par_node.children[index] continue assert len( new_nodes ) == 1 or not active_only, "Multiple active entries for {} in Vivaldi are not permitted".format( node_name) assert not isinstance(node, message.MessageNode) or getattr(node, "modified_string", False) or any(node.GetCdata() != new_node.GetCdata() for new_node in new_nodes), \ "Vivaldi Message string {} matches corresponding Chromium string, which is not permitted".format(node_name) par_node = node.parent try: index = par_node.children.index(node) par_node.children[index:index + 1] = new_nodes for new_node in new_nodes: new_node.parent = par_node for item in new_node.Preorder(): item.uberclique = res.UberClique() for item in new_node.GetCliques(): item.uberclique = res.UberClique() except: raise Exception( "{} was not registered in parent".format(node_name)) done_names.add(node_name) for name, nodes in resource_list.items(): for node in nodes: if isinstance(node, message.MessageNode): par_node = res.GetChildrenOfType(empty.MessagesNode) assert par_node, "No Messages node in file for {}".format(name) elif isinstance(node, structure.StructureNode): par_node = res.GetChildrenOfType(empty.StructuresNode) assert par_node, "No Structures node in file for {}".format( name) elif isinstance(node, include.IncludeNode): par_node = res.GetChildrenOfType(empty.IncludesNode) assert par_node, "No Includes node in file for {}".format(name) elif isinstance(node, (message.PhNode, message.ExNode)): continue else: raise Exception("Unknown node type {} for {}".format( node, name)) assert len( par_node ) == 1, "There were more than one item of parent type for {}".format( name) par_node[0].children.append(node) node.parent = par_node[0] for item in node.Preorder(): item.uberclique = res.UberClique() for item in node.GetCliques(): item.uberclique = res.UberClique() #print("Inserted {} in {} {}".format(name, node.parent.__class__, node.parent)) for lang, extra_translation_items in new_resources.UberClique( ).additional_translations_.items(): xtb_callback = res.UberClique().GenerateXtbParserCallback( lang, override_exisiting=True, debug=params.get("debug", False)) for tid, string in extra_translation_items.items(): #print "Item", tid, type(string), string xtb_callback(tid, string) return names
def testFormatResourceMapWithOutputAllEqualsFalseForStructures(self): grd = grd_reader.Parse( StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="." output_all_resource_defines="false"> <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" filename="the_resource_map_header.h" /> <output type="resource_map_source" filename="the_resource_map_header.cc" /> </outputs> <release seq="3"> <structures first_id="300"> <structure type="chrome_scaled_image" name="IDR_KLONKMENU" file="foo.png" /> <if expr="False"> <structure type="chrome_scaled_image" name="IDR_MISSING" file="bar.png" /> </if> <if expr="True"> <structure type="chrome_scaled_image" name="IDR_BLOB" file="blob.png" /> </if> <if expr="True"> <then> <structure type="chrome_scaled_image" name="IDR_METEOR" file="meteor.png" /> </then> <else> <structure type="chrome_scaled_image" name="IDR_METEOR" file="roetem.png" /> </else> </if> <if expr="False"> <structure type="chrome_scaled_image" name="IDR_LAST" file="zyx.png" /> </if> <if expr="True"> <structure type="chrome_scaled_image" name="IDR_LAST" file="xyz.png" /> </if> </structures> </release> </grit>'''), util.PathFromRoot('.')) grd.SetOutputLanguage('en') grd.RunGatherers() output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual( '''\ #include <stddef.h> #ifndef GRIT_RESOURCE_MAP_STRUCT_ #define GRIT_RESOURCE_MAP_STRUCT_ struct GritResourceMap { const char* const name; int value; }; #endif // GRIT_RESOURCE_MAP_STRUCT_ extern const GritResourceMap kTheRcHeader[]; extern const size_t kTheRcHeaderSize;''', output) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_source')(grd, 'en', '.'))) self.assertEqual( '''\ #include "the_resource_map_header.h" #include <stddef.h> #include "base/macros.h" #include "the_rc_header.h" const GritResourceMap kTheRcHeader[] = { {"IDR_KLONKMENU", IDR_KLONKMENU}, {"IDR_BLOB", IDR_BLOB}, {"IDR_METEOR", IDR_METEOR}, {"IDR_LAST", IDR_LAST}, }; const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_source')(grd, 'en', '.'))) self.assertEqual( '''\ #include "the_resource_map_header.h" #include <stddef.h> #include "base/macros.h" #include "the_rc_header.h" const GritResourceMap kTheRcHeader[] = { {"IDR_KLONKMENU", IDR_KLONKMENU}, {"IDR_BLOB", IDR_BLOB}, {"IDR_METEOR", IDR_METEOR}, {"IDR_LAST", IDR_LAST}, }; const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output)
def testPolicyTranslation(self): # Create test policy_templates.json data. caption = "The main policy" caption_translation = "Die Hauptrichtlinie" message = \ "Red cabbage stays red cabbage and wedding dress stays wedding dress" message_translation = \ "Blaukraut bleibt Blaukraut und Brautkleid bleibt Brautkleid" schema_key_description = "Number of users" schema_key_description_translation = "Anzahl der Nutzer" policy_json = """ { "policy_definitions": [ { 'name': 'MainPolicy', 'type': 'main', 'schema': { 'properties': { 'default_launch_container': { 'enum': [ 'tab', 'window', ], 'type': 'string', }, 'users_number': { 'description': '''%s''', 'type': 'integer', }, }, 'type': 'object', }, 'supported_on': ['chrome_os:29-'], 'features': { 'can_be_recommended': True, 'dynamic_refresh': True, }, 'example_value': True, 'caption': '''%s''', 'tags': [], 'desc': '''This policy does stuff.''' }, ], "policy_atomic_group_definitions": [], "placeholders": [], "messages": { 'message_string_id': { 'desc': '''The description is removed from the grit output''', 'text': '''%s''' } } }""" % (schema_key_description, caption, message) # Create translations. The translation IDs are hashed from the English text. caption_id = grit.extern.tclib.GenerateMessageId(caption) message_id = grit.extern.tclib.GenerateMessageId(message) schema_key_description_id = grit.extern.tclib.GenerateMessageId( schema_key_description) policy_xtb = """ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="de"> <translation id="%s">%s</translation> <translation id="%s">%s</translation> <translation id="%s">%s</translation> </translationbundle>""" % (caption_id, caption_translation, message_id, message_translation, schema_key_description_id, schema_key_description_translation) # Write both to a temp file. tmp_dir_name = tempfile.gettempdir() json_file_path = os.path.join(tmp_dir_name, 'test.json') with open(json_file_path, 'w') as f: f.write(policy_json.strip()) xtb_file_path = os.path.join(tmp_dir_name, 'test.xtb') with open(xtb_file_path, 'w') as f: f.write(policy_xtb.strip()) # Assemble a test grit tree, similar to policy_templates.grd. grd_text = ''' <grit base_dir="." latest_public_release="0" current_release="1" source_lang_id="en"> <translations> <file path="%s" lang="de" /> </translations> <release seq="1"> <structures> <structure name="IDD_POLICY_SOURCE_FILE" file="%s" type="policy_template_metafile" /> </structures> </release> </grit>''' % (xtb_file_path, json_file_path) grd_string_io = StringIO.StringIO(grd_text) # Parse the grit tree and load the policies' JSON with a gatherer. grd = grd_reader.Parse(grd_string_io, dir=tmp_dir_name) grd.SetOutputLanguage('en') grd.RunGatherers() # Remove the temp files. os.unlink(xtb_file_path) os.unlink(json_file_path) # Run grit with en->de translation. env_lang = 'en' out_lang = 'de' env_defs = {'_google_chrome': '1'} grd.SetOutputLanguage(env_lang) grd.SetDefines(env_defs) buf = StringIO.StringIO() build.RcBuilder.ProcessNode(grd, DummyOutput('policy_templates', out_lang), buf) output = buf.getvalue() # Caption and message texts get taken from xtb. # desc is 'translated' to some pseudo-English # 'ThïPïs pôPôlïPïcýPý dôéPôés stüPüff'. expected = u"""{ 'policy_definitions': [ { 'caption': '''%s''', 'features': {'can_be_recommended': True, 'dynamic_refresh': True}, 'name': 'MainPolicy', 'tags': [], 'desc': '''Th\xefP\xefs p\xf4P\xf4l\xefP\xefc\xfdP\xfd d\xf4\xe9P\xf4\xe9s st\xfcP\xfcff.''', 'type': 'main', 'example_value': True, 'supported_on': ['chrome_os:29-'], 'schema': { 'properties': { 'default_launch_container': { 'enum': [ 'tab', 'window', ], 'type': 'string', }, 'users_number': { 'description': '''%s''', 'type': 'integer', }, }, 'type': 'object', }, }, ], 'policy_atomic_group_definitions': [ ], 'messages': { 'message_string_id': { 'text': '''%s''' }, }, }""" % (caption_translation, schema_key_description_translation, message_translation) self.assertEqual(expected, output)
def testFormatResourceMap(self): grd = grd_reader.Parse(StringIO.StringIO( '''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" filename="the_resource_map_header.h" /> </outputs> <release seq="3"> <structures first_id="300"> <structure type="menu" name="IDC_KLONKMENU" file="grit\\testdata\\klonk.rc" encoding="utf-16" /> </structures> <includes first_id="10000"> <include type="foo" file="abc" name="IDS_FIRSTPRESENT" /> <if expr="False"> <include type="foo" file="def" name="IDS_MISSING" /> </if> <if expr="lang != 'es'"> <include type="foo" file="ghi" name="IDS_LANGUAGESPECIFIC" /> </if> <if expr="lang == 'es'"> <include type="foo" file="jkl" name="IDS_LANGUAGESPECIFIC" /> </if> <include type="foo" file="mno" name="IDS_THIRDPRESENT" /> </includes> </release> </grit>'''), util.PathFromRoot('.')) grd.SetOutputLanguage('en') grd.RunGatherers() output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual('''\ #include <stddef.h> #ifndef GRIT_RESOURCE_MAP_STRUCT_ #define GRIT_RESOURCE_MAP_STRUCT_ struct GritResourceMap { const char* const name; int value; }; #endif // GRIT_RESOURCE_MAP_STRUCT_ extern const GritResourceMap kTheRcHeader[]; extern const size_t kTheRcHeaderSize;''', output) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_source')(grd, 'en', '.'))) self.assertEqual('''\ #include "the_resource_map_header.h" #include <stddef.h> #include "base/macros.h" #include "the_rc_header.h" const GritResourceMap kTheRcHeader[] = { {"IDC_KLONKMENU", IDC_KLONKMENU}, {"IDS_FIRSTPRESENT", IDS_FIRSTPRESENT}, {"IDS_MISSING", IDS_MISSING}, {"IDS_LANGUAGESPECIFIC", IDS_LANGUAGESPECIFIC}, {"IDS_THIRDPRESENT", IDS_THIRDPRESENT}, }; const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_file_map_source')(grd, 'en', '.'))) self.assertEqual('''\ #include "the_resource_map_header.h" #include <stddef.h> #include "base/macros.h" #include "the_rc_header.h" const GritResourceMap kTheRcHeader[] = { {"grit/testdata/klonk.rc", IDC_KLONKMENU}, {"abc", IDS_FIRSTPRESENT}, {"def", IDS_MISSING}, {"ghi", IDS_LANGUAGESPECIFIC}, {"jkl", IDS_LANGUAGESPECIFIC}, {"mno", IDS_THIRDPRESENT}, }; const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output)
def Run(self, opts, args): self.output_directory = '.' first_ids_file = None whitelist_filenames = [] assert_output_files = [] target_platform = None depfile = None depdir = None rc_header_format = None (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:', ('depdir=','depfile=','assert-file-list=')) for (key, val) in own_opts: if key == '-a': assert_output_files.append(val) elif key == '--assert-file-list': with open(val) as f: assert_output_files += f.read().splitlines() elif key == '-o': self.output_directory = val elif key == '-D': name, val = util.ParseDefine(val) self.defines[name] = val elif key == '-E': (env_name, env_value) = val.split('=', 1) os.environ[env_name] = env_value elif key == '-f': # TODO([email protected]): Remove this override once change # lands in WebKit.grd to specify the first_ids_file in the # .grd itself. first_ids_file = val elif key == '-w': whitelist_filenames.append(val) elif key == '-t': target_platform = val elif key == '-h': rc_header_format = val elif key == '--depdir': depdir = val elif key == '--depfile': depfile = val if len(args): print 'This tool takes no tool-specific arguments.' return 2 self.SetOptions(opts) if self.scons_targets: self.VerboseOut('Using SCons targets to identify files to output.\n') else: self.VerboseOut('Output directory: %s (absolute path: %s)\n' % (self.output_directory, os.path.abspath(self.output_directory))) if whitelist_filenames: self.whitelist_names = set() for whitelist_filename in whitelist_filenames: self.VerboseOut('Using whitelist: %s\n' % whitelist_filename); whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT) self.whitelist_names.update(whitelist_contents.strip().split('\n')) self.res = grd_reader.Parse(opts.input, debug=opts.extra_verbose, first_ids_file=first_ids_file, defines=self.defines, target_platform=target_platform) # Set an output context so that conditionals can use defines during the # gathering stage; we use a dummy language here since we are not outputting # a specific language. self.res.SetOutputLanguage('en') if rc_header_format: self.res.AssignRcHeaderFormat(rc_header_format) self.res.RunGatherers() self.Process() if assert_output_files: if not self.CheckAssertedOutputFiles(assert_output_files): return 2 if depfile and depdir: self.GenerateDepfile(depfile, depdir) return 0
def testExtractTranslations(self): path = util.PathFromRoot('grit/testdata') current_grd = grd_reader.Parse( StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <release seq="3"> <messages> <message name="IDS_SIMPLE"> One </message> <message name="IDS_PLACEHOLDER"> <ph name="NUMBIRDS">%s<ex>3</ex></ph> birds </message> <message name="IDS_PLACEHOLDERS"> <ph name="ITEM">%d<ex>1</ex></ph> of <ph name="COUNT">%d<ex>3</ex></ph> </message> <message name="IDS_REORDERED_PLACEHOLDERS"> <ph name="ITEM">$1<ex>1</ex></ph> of <ph name="COUNT">$2<ex>3</ex></ph> </message> <message name="IDS_CHANGED"> This is the new version </message> <message name="IDS_TWIN_1">Hello</message> <message name="IDS_TWIN_2">Hello</message> <message name="IDS_NOT_TRANSLATEABLE" translateable="false">:</message> <message name="IDS_LONGER_TRANSLATED"> Removed document <ph name="FILENAME">$1<ex>c:\temp</ex></ph> </message> <message name="IDS_DIFFERENT_TWIN_1">Howdie</message> <message name="IDS_DIFFERENT_TWIN_2">Howdie</message> </messages> <structures> <structure type="dialog" name="IDD_ABOUTBOX" encoding="utf-16" file="klonk.rc" /> <structure type="menu" name="IDC_KLONKMENU" encoding="utf-16" file="klonk.rc" /> </structures> </release> </grit>'''), path) current_grd.RunGatherers(recursive=True) source_rc_path = util.PathFromRoot('grit/testdata/source.rc') source_rc = file(source_rc_path).read() transl_rc_path = util.PathFromRoot('grit/testdata/transl.rc') transl_rc = file(transl_rc_path).read() tool = transl2tc.TranslationToTc() output_buf = StringIO.StringIO() globopts = MakeOptions() globopts.verbose = True globopts.output_stream = output_buf tool.Setup(globopts, []) translations = tool.ExtractTranslations(current_grd, source_rc, source_rc_path, transl_rc, transl_rc_path) values = translations.values() output = output_buf.getvalue() self.failUnless('Ein' in values) self.failUnless('NUMBIRDS Vogeln' in values) self.failUnless('ITEM von COUNT' in values) self.failUnless(values.count('Hallo') == 1) self.failIf('Dass war die alte Version' in values) self.failIf(':' in values) self.failIf('Dokument FILENAME ist entfernt worden' in values) self.failIf('Nicht verwendet' in values) self.failUnless( ('Howdie' in values or 'Hallo sagt man' in values) and not ('Howdie' in values and 'Hallo sagt man' in values)) self.failUnless( 'XX01XX&SkraXX02XX&HaettaXX03XXThetta er "Klonk" sem eg fylaXX04XXgonkurinnXX05XXKlonk && er "gott"XX06XX&HjalpXX07XX&Um...XX08XX' in values) self.failUnless('I lagi' in values) self.failUnless( output.count( 'Structure of message IDS_REORDERED_PLACEHOLDERS has changed')) self.failUnless(output.count('Message IDS_CHANGED has changed')) self.failUnless( output.count( 'Structure of message IDS_LONGER_TRANSLATED has changed')) self.failUnless( output.count('Two different translations for "Howdie"')) self.failUnless( output.count( 'IDD_DIFFERENT_LENGTH_IN_TRANSL has wrong # of cliques'))
def testSubstitutionRc(self): root = grd_reader.Parse( StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> <grit latest_public_release="2" source_lang_id="en-US" current_release="3" base_dir="."> <outputs> <output lang="en" type="rc_all" filename="grit\\testdata\klonk_resources.rc"/> </outputs> <release seq="1" allow_pseudo="False"> <structures> <structure type="menu" name="IDC_KLONKMENU" file="grit\\testdata\klonk.rc" encoding="utf-16" expand_variables="true" /> </structures> <messages> <message name="good" sub_variable="true"> excellent </message> </messages> </release> </grit> '''), util.PathFromRoot('.')) root.SetOutputLanguage('en') root.RunGatherers() buf = StringIO.StringIO() build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) output = buf.getvalue() self.assertEqual( ''' // This file is automatically generated by GRIT. Do not edit. #include "resource.h" #include <winresrc.h> #ifdef IDC_STATIC #undef IDC_STATIC #endif #define IDC_STATIC (-1) LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDC_KLONKMENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", IDM_EXIT MENUITEM "This be ""Klonk"" me like", ID_FILE_THISBE POPUP "gonk" BEGIN MENUITEM "Klonk && is excellent", ID_GONK_KLONKIS END END POPUP "&Help" BEGIN MENUITEM "&About ...", IDM_ABOUT END END STRINGTABLE BEGIN good "excellent" END '''.strip(), output.strip())
def testRcSection(self): root = grd_reader.Parse(StringIO.StringIO(''' <structures> <structure type="menu" name="IDC_KLONKMENU" file="grit\\test\data\klonk.rc" encoding="utf-16" /> <structure type="dialog" name="IDD_ABOUTBOX" file="grit\\test\data\klonk.rc" encoding="utf-16" /> <structure type="version" name="VS_VERSION_INFO" file="grit\\test\data\klonk.rc" encoding="utf-16" /> </structures>'''), flexible_root=True) util.FixRootForUnittest(root) root.RunGatherers(recursive=True) buf = StringIO.StringIO() build.RcBuilder.ProcessNode(root, DummyOutput('rc_all', 'en'), buf) output = buf.getvalue() self.failUnless(output.strip() == u''' IDC_KLONKMENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", IDM_EXIT MENUITEM "This be ""Klonk"" me like", ID_FILE_THISBE POPUP "gonk" BEGIN MENUITEM "Klonk && is ""good""", ID_GONK_KLONKIS END END POPUP "&Help" BEGIN MENUITEM "&About ...", IDM_ABOUT END END IDD_ABOUTBOX DIALOGEX 22, 17, 230, 75 STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "System", 0, 0, 0x0 BEGIN ICON IDI_KLONK,IDC_MYICON,14,9,20,20 LTEXT "klonk Version ""yibbee"" 1.0",IDC_STATIC,49,10,119,8, SS_NOPREFIX LTEXT "Copyright (C) 2005",IDC_STATIC,49,20,119,8 DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP CONTROL "Jack ""Black"" Daniels",IDC_RADIO1,"Button", BS_AUTORADIOBUTTON,46,51,84,10 END VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "klonk Application" VALUE "FileVersion", "1, 0, 0, 1" VALUE "InternalName", "klonk" VALUE "LegalCopyright", "Copyright (C) 2005" VALUE "OriginalFilename", "klonk.exe" VALUE "ProductName", " klonk Application" VALUE "ProductVersion", "1, 0, 0, 1" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END'''.strip())