15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Unittest for the generate_stubs.py.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Since generate_stubs.py is a code generator, it is hard to do a very good
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)test.  Instead of creating a golden-file test, which might be flakey, this
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)test elects instead to verify that various components "exist" within the
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)generated file as a sanity check.  In particular, there is a simple hit
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)test to make sure that umbrella functions, etc., do try and include every
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function they are responsible for invoking.  Missing an invocation is quite
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)easily missed.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)There is no attempt to verify ordering of different components, or whether
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)or not those components are going to parse incorrectly because of prior
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errors or positioning.  Most of that should be caught really fast anyways
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)during any attempt to use a badly behaving script.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import generate_stubs as gs
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import StringIO
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import unittest
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _MakeSignature(return_type, name, params):
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return {'return_type': return_type,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          'name': name,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          'params': params}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SIMPLE_SIGNATURES = [
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('int foo(int a)', _MakeSignature('int', 'foo', ['int a'])),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('int bar(int a, double b)', _MakeSignature('int', 'bar',
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ['int a', 'double b'])),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('int baz(void)', _MakeSignature('int', 'baz', ['void'])),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('void quux(void)', _MakeSignature('void', 'quux', ['void'])),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('void waldo(void);', _MakeSignature('void', 'waldo', ['void'])),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('int corge(void);', _MakeSignature('int', 'corge', ['void'])),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ]
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TRICKY_SIGNATURES = [
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('const struct name *foo(int a, struct Test* b);  ',
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     _MakeSignature('const struct name *',
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    'foo',
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ['int a', 'struct Test* b'])),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('const struct name &foo(int a, struct Test* b);',
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     _MakeSignature('const struct name &',
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    'foo',
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ['int a', 'struct Test* b'])),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('const struct name &_foo(int a, struct Test* b);',
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     _MakeSignature('const struct name &',
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    '_foo',
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ['int a', 'struct Test* b'])),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ('struct name const * const _foo(int a, struct Test* b) '
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     '__attribute__((inline));',
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     _MakeSignature('struct name const * const',
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    '_foo',
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ['int a', 'struct Test* b']))
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ]
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INVALID_SIGNATURES = ['I am bad', 'Seriously bad(', ';;;']
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GenerateStubModuleFunctionsUnittest(unittest.TestCase):
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testExtractModuleName(self):
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual('somefile-2', gs.ExtractModuleName('somefile-2.ext'))
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testParseSignatures_EmptyFile(self):
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Empty file just generates empty signatures.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    infile = StringIO.StringIO()
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signatures = gs.ParseSignatures(infile)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(0, len(signatures))
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testParseSignatures_SimpleSignatures(self):
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_contents = '\n'.join([x[0] for x in SIMPLE_SIGNATURES])
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    infile = StringIO.StringIO(file_contents)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signatures = gs.ParseSignatures(infile)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(len(SIMPLE_SIGNATURES), len(signatures))
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # We assume signatures are in order.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for i in xrange(len(SIMPLE_SIGNATURES)):
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertEqual(SIMPLE_SIGNATURES[i][1], signatures[i],
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       msg='Expected %s\nActual %s\nFor %s' %
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       (SIMPLE_SIGNATURES[i][1],
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        signatures[i],
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SIMPLE_SIGNATURES[i][0]))
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testParseSignatures_TrickySignatures(self):
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_contents = '\n'.join([x[0] for x in TRICKY_SIGNATURES])
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    infile = StringIO.StringIO(file_contents)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signatures = gs.ParseSignatures(infile)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(len(TRICKY_SIGNATURES), len(signatures))
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # We assume signatures are in order.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for i in xrange(len(TRICKY_SIGNATURES)):
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertEqual(TRICKY_SIGNATURES[i][1], signatures[i],
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       msg='Expected %s\nActual %s\nFor %s' %
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       (TRICKY_SIGNATURES[i][1],
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        signatures[i],
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        TRICKY_SIGNATURES[i][0]))
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testParseSignatures_InvalidSignatures(self):
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for i in INVALID_SIGNATURES:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      infile = StringIO.StringIO(i)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertRaises(gs.BadSignatureError, gs.ParseSignatures, infile)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testParseSignatures_CommentsIgnored(self):
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs = []
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append('# a comment')
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append(SIMPLE_SIGNATURES[0][0])
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append('# another comment')
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append(SIMPLE_SIGNATURES[0][0])
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append('# a third comment')
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_sigs.append(SIMPLE_SIGNATURES[0][0])
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    my_sigs.append('// a fourth comment')
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    my_sigs.append(SIMPLE_SIGNATURES[0][0])
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    my_sigs.append('//')
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    my_sigs.append(SIMPLE_SIGNATURES[0][0])
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_contents = '\n'.join(my_sigs)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    infile = StringIO.StringIO(file_contents)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signatures = gs.ParseSignatures(infile)
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    self.assertEqual(5, len(signatures))
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WindowsLibUnittest(unittest.TestCase):
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testWriteWindowsDefFile(self):
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    module_name = 'my_module-1'
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signatures = [sig[1] for sig in SIMPLE_SIGNATURES]
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outfile = StringIO.StringIO()
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gs.WriteWindowsDefFile(module_name, signatures, outfile)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents = outfile.getvalue()
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check that the file header is correct.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.startswith("""LIBRARY %s
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXPORTS
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" % module_name))
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check that the signatures were exported.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for sig in signatures:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pattern = '\n  %s\n' % sig['name']
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(re.search(pattern, contents),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected match of "%s" in %s' % (pattern, contents))
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testQuietRun(self):
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output = StringIO.StringIO()
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gs.QuietRun([sys.executable,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '-c', 'print "line 1 and suffix\\nline 2"'],
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                write_to=output)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual('line 1 and suffix\nline 2\n', output.getvalue())
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output = StringIO.StringIO()
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gs.QuietRun([sys.executable,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '-c', 'print "line 1 and suffix\\nline 2"'],
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 filter='line 1', write_to=output)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual('line 2\n', output.getvalue())
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PosixStubWriterUnittest(unittest.TestCase):
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def setUp(self):
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.module_name = 'my_module-1'
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.signatures = [sig[1] for sig in SIMPLE_SIGNATURES]
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.out_dir = 'out_dir'
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    self.writer = gs.PosixStubWriter(self.module_name, '', self.signatures)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testEnumName(self):
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual('kModuleMy_module1',
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     gs.PosixStubWriter.EnumName(self.module_name))
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testIsInitializedName(self):
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual('IsMy_module1Initialized',
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     gs.PosixStubWriter.IsInitializedName(self.module_name))
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testInitializeModuleName(self):
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'InitializeMy_module1',
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gs.PosixStubWriter.InitializeModuleName(self.module_name))
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testUninitializeModuleName(self):
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'UninitializeMy_module1',
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gs.PosixStubWriter.UninitializeModuleName(self.module_name))
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testStubFunctionPointer(self):
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'static int (*foo_ptr)(int a) = NULL;',
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gs.PosixStubWriter.StubFunctionPointer(SIMPLE_SIGNATURES[0][1]))
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testStubFunction(self):
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Test for a signature with a return value and a parameter.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual("""extern int foo(int a) __attribute__((weak));
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int  foo(int a) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return foo_ptr(a);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[0][1]))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Test for a signature with a void return value and no parameters.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual("""extern void waldo(void) __attribute__((weak));
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void  waldo(void) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  waldo_ptr();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[4][1]))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Test export macros.
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sig = _MakeSignature('int*', 'foo', ['bool b'])
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sig['export'] = 'TEST_EXPORT'
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    self.assertEqual("""extern int* foo(bool b) __attribute__((weak));
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int* TEST_EXPORT foo(bool b) {
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return foo_ptr(b);
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}""", gs.PosixStubWriter.StubFunction(sig))
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testWriteImplemenationContents(self):
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outfile = StringIO.StringIO()
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.writer.WriteImplementationContents('my_namespace', outfile)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents = outfile.getvalue()
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Verify namespace exists somewhere.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find('namespace my_namespace {') != -1)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Verify that each signature has an _ptr and a function call in the file.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check that the signatures were exported.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for sig in self.signatures:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.StubFunctionPointer(sig)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Verify that each signature has an stub function generated for it.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for sig in self.signatures:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.StubFunction(sig)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Find module initializer functions.  Make sure all 3 exist.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decl = gs.PosixStubWriter.InitializeModuleName(self.module_name)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find(decl) != -1,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    msg='Expected "%s" in %s' % (decl, contents))
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decl = gs.PosixStubWriter.UninitializeModuleName(self.module_name)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find(decl) != -1,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    msg='Expected "%s" in %s' % (decl, contents))
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decl = gs.PosixStubWriter.IsInitializedName(self.module_name)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find(decl) != -1,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    msg='Expected "%s" in %s' % (decl, contents))
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testWriteHeaderContents(self):
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Data for header generation.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    module_names = ['oneModule', 'twoModule']
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Make the header.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outfile = StringIO.StringIO()
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.writer.WriteHeaderContents(module_names, 'my_namespace', 'GUARD_',
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    outfile)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents = outfile.getvalue()
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check for namespace and header guard.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find('namespace my_namespace {') != -1)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find('#ifndef GUARD_') != -1)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check for umbrella initializer.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find('InitializeStubs(') != -1)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check per-module declarations.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for name in module_names:
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Check for enums.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.EnumName(name)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Check for module initializer functions.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.IsInitializedName(name)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.InitializeModuleName(name)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.UninitializeModuleName(name)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testWriteUmbrellaInitializer(self):
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Data for header generation.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    module_names = ['oneModule', 'twoModule']
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Make the header.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outfile = StringIO.StringIO()
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.writer.WriteUmbrellaInitializer(module_names, 'my_namespace', outfile)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents = outfile.getvalue()
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check for umbrella initializer declaration.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(contents.find('bool InitializeStubs(') != -1)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If the umbrella initializer is correctly written, each module will have
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # its initializer called, checked, and uninitialized on failure.  Sanity
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # check that here.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for name in module_names:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Check for module initializer functions.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.IsInitializedName(name)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.InitializeModuleName(name)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      decl = gs.PosixStubWriter.UninitializeModuleName(name)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(contents.find(decl) != -1,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      msg='Expected "%s" in %s' % (decl, contents))
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest.main()
310