#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittest for the generate_stubs.py.

Since generate_stubs.py is a code generator, it is hard to do a very good
test.  Instead of creating a golden-file test, which might be flakey, this
test elects instead to verify that various components "exist" within the
generated file as a sanity check.  In particular, there is a simple hit
test to make sure that umbrella functions, etc., do try and include every
function they are responsible for invoking.  Missing an invocation is quite
easily missed.

There is no attempt to verify ordering of different components, or whether
or not those components are going to parse incorrectly because of prior
errors or positioning.  Most of that should be caught really fast anyways
during any attempt to use a badly behaving script.
"""

import generate_stubs as gs
import re
import StringIO
import sys
import unittest


def _MakeSignature(return_type, name, params):
  return {'return_type': return_type,
          'name': name,
          'params': params}


SIMPLE_SIGNATURES = [
    ('int foo(int a)', _MakeSignature('int', 'foo', ['int a'])),
    ('int bar(int a, double b)', _MakeSignature('int', 'bar',
                                                ['int a', 'double b'])),
    ('int baz(void)', _MakeSignature('int', 'baz', ['void'])),
    ('void quux(void)', _MakeSignature('void', 'quux', ['void'])),
    ('void waldo(void);', _MakeSignature('void', 'waldo', ['void'])),
    ('int corge(void);', _MakeSignature('int', 'corge', ['void'])),
    ]

TRICKY_SIGNATURES = [
    ('const struct name *foo(int a, struct Test* b);  ',
     _MakeSignature('const struct name *',
                    'foo',
                    ['int a', 'struct Test* b'])),
    ('const struct name &foo(int a, struct Test* b);',
     _MakeSignature('const struct name &',
                    'foo',
                    ['int a', 'struct Test* b'])),
    ('const struct name &_foo(int a, struct Test* b);',
     _MakeSignature('const struct name &',
                    '_foo',
                    ['int a', 'struct Test* b'])),
    ('struct name const * const _foo(int a, struct Test* b) '
     '__attribute__((inline));',
     _MakeSignature('struct name const * const',
                    '_foo',
                    ['int a', 'struct Test* b']))
    ]

INVALID_SIGNATURES = ['I am bad', 'Seriously bad(', ';;;']


class GenerateStubModuleFunctionsUnittest(unittest.TestCase):
  def testExtractModuleName(self):
    self.assertEqual('somefile-2', gs.ExtractModuleName('somefile-2.ext'))

  def testParseSignatures_EmptyFile(self):
    # Empty file just generates empty signatures.
    infile = StringIO.StringIO()
    signatures = gs.ParseSignatures(infile)
    self.assertEqual(0, len(signatures))

  def testParseSignatures_SimpleSignatures(self):
    file_contents = '\n'.join([x[0] for x in SIMPLE_SIGNATURES])
    infile = StringIO.StringIO(file_contents)
    signatures = gs.ParseSignatures(infile)
    self.assertEqual(len(SIMPLE_SIGNATURES), len(signatures))

    # We assume signatures are in order.
    for i in xrange(len(SIMPLE_SIGNATURES)):
      self.assertEqual(SIMPLE_SIGNATURES[i][1], signatures[i],
                       msg='Expected %s\nActual %s\nFor %s' %
                       (SIMPLE_SIGNATURES[i][1],
                        signatures[i],
                        SIMPLE_SIGNATURES[i][0]))

  def testParseSignatures_TrickySignatures(self):
    file_contents = '\n'.join([x[0] for x in TRICKY_SIGNATURES])
    infile = StringIO.StringIO(file_contents)
    signatures = gs.ParseSignatures(infile)
    self.assertEqual(len(TRICKY_SIGNATURES), len(signatures))

    # We assume signatures are in order.
    for i in xrange(len(TRICKY_SIGNATURES)):
      self.assertEqual(TRICKY_SIGNATURES[i][1], signatures[i],
                       msg='Expected %s\nActual %s\nFor %s' %
                       (TRICKY_SIGNATURES[i][1],
                        signatures[i],
                        TRICKY_SIGNATURES[i][0]))

  def testParseSignatures_InvalidSignatures(self):
    for i in INVALID_SIGNATURES:
      infile = StringIO.StringIO(i)
      self.assertRaises(gs.BadSignatureError, gs.ParseSignatures, infile)

  def testParseSignatures_CommentsIgnored(self):
    my_sigs = []
    my_sigs.append('# a comment')
    my_sigs.append(SIMPLE_SIGNATURES[0][0])
    my_sigs.append('# another comment')
    my_sigs.append(SIMPLE_SIGNATURES[0][0])
    my_sigs.append('# a third comment')
    my_sigs.append(SIMPLE_SIGNATURES[0][0])
    my_sigs.append('// a fourth comment')
    my_sigs.append(SIMPLE_SIGNATURES[0][0])
    my_sigs.append('//')
    my_sigs.append(SIMPLE_SIGNATURES[0][0])

    file_contents = '\n'.join(my_sigs)
    infile = StringIO.StringIO(file_contents)
    signatures = gs.ParseSignatures(infile)
    self.assertEqual(5, len(signatures))


class WindowsLibUnittest(unittest.TestCase):
  def testWriteWindowsDefFile(self):
    module_name = 'my_module-1'
    signatures = [sig[1] for sig in SIMPLE_SIGNATURES]
    outfile = StringIO.StringIO()
    gs.WriteWindowsDefFile(module_name, signatures, outfile)
    contents = outfile.getvalue()

    # Check that the file header is correct.
    self.assertTrue(contents.startswith("""LIBRARY %s
EXPORTS
""" % module_name))

    # Check that the signatures were exported.
    for sig in signatures:
      pattern = '\n  %s\n' % sig['name']
      self.assertTrue(re.search(pattern, contents),
                      msg='Expected match of "%s" in %s' % (pattern, contents))

  def testQuietRun(self):
    output = StringIO.StringIO()
    gs.QuietRun([sys.executable,
                 '-c', 'print "line 1 and suffix\\nline 2"'],
                write_to=output)
    self.assertEqual('line 1 and suffix\nline 2\n', output.getvalue())

    output = StringIO.StringIO()
    gs.QuietRun([sys.executable,
                 '-c', 'print "line 1 and suffix\\nline 2"'],
                 filter='line 1', write_to=output)
    self.assertEqual('line 2\n', output.getvalue())


class PosixStubWriterUnittest(unittest.TestCase):
  def setUp(self):
    self.module_name = 'my_module-1'
    self.signatures = [sig[1] for sig in SIMPLE_SIGNATURES]
    self.out_dir = 'out_dir'
    self.writer = gs.PosixStubWriter(self.module_name, self.signatures)

  def testEnumName(self):
    self.assertEqual('kModuleMy_module1',
                     gs.PosixStubWriter.EnumName(self.module_name))

  def testIsInitializedName(self):
    self.assertEqual('IsMy_module1Initialized',
                     gs.PosixStubWriter.IsInitializedName(self.module_name))

  def testInitializeModuleName(self):
    self.assertEqual(
        'InitializeMy_module1',
        gs.PosixStubWriter.InitializeModuleName(self.module_name))

  def testUninitializeModuleName(self):
    self.assertEqual(
        'UninitializeMy_module1',
        gs.PosixStubWriter.UninitializeModuleName(self.module_name))

  def testStubFunctionPointer(self):
    self.assertEqual(
        'static int (*foo_ptr)(int a) = NULL;',
        gs.PosixStubWriter.StubFunctionPointer(SIMPLE_SIGNATURES[0][1]))

  def testStubFunction(self):
    # Test for a signature with a return value and a parameter.
    self.assertEqual("""extern int foo(int a) __attribute__((weak));
int foo(int a) {
  return foo_ptr(a);
}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[0][1]))

    # Test for a signature with a void return value and no parameters.
    self.assertEqual("""extern void waldo(void) __attribute__((weak));
void waldo(void) {
  waldo_ptr();
}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[4][1]))

  def testWriteImplemenationContents(self):
    outfile = StringIO.StringIO()
    self.writer.WriteImplementationContents('my_namespace', outfile)
    contents = outfile.getvalue()

    # Verify namespace exists somewhere.
    self.assertTrue(contents.find('namespace my_namespace {') != -1)

    # Verify that each signature has an _ptr and a function call in the file.
    # Check that the signatures were exported.
    for sig in self.signatures:
      decl = gs.PosixStubWriter.StubFunctionPointer(sig)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))

    # Verify that each signature has an stub function generated for it.
    for sig in self.signatures:
      decl = gs.PosixStubWriter.StubFunction(sig)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))

    # Find module initializer functions.  Make sure all 3 exist.
    decl = gs.PosixStubWriter.InitializeModuleName(self.module_name)
    self.assertTrue(contents.find(decl) != -1,
                    msg='Expected "%s" in %s' % (decl, contents))
    decl = gs.PosixStubWriter.UninitializeModuleName(self.module_name)
    self.assertTrue(contents.find(decl) != -1,
                    msg='Expected "%s" in %s' % (decl, contents))
    decl = gs.PosixStubWriter.IsInitializedName(self.module_name)
    self.assertTrue(contents.find(decl) != -1,
                    msg='Expected "%s" in %s' % (decl, contents))

  def testWriteHeaderContents(self):
    # Data for header generation.
    module_names = ['oneModule', 'twoModule']

    # Make the header.
    outfile = StringIO.StringIO()
    self.writer.WriteHeaderContents(module_names, 'my_namespace', 'GUARD_',
                                    outfile)
    contents = outfile.getvalue()

    # Check for namespace and header guard.
    self.assertTrue(contents.find('namespace my_namespace {') != -1)
    self.assertTrue(contents.find('#ifndef GUARD_') != -1)

    # Check for umbrella initializer.
    self.assertTrue(contents.find('InitializeStubs(') != -1)

    # Check per-module declarations.
    for name in module_names:
      # Check for enums.
      decl = gs.PosixStubWriter.EnumName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))

      # Check for module initializer functions.
      decl = gs.PosixStubWriter.IsInitializedName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))
      decl = gs.PosixStubWriter.InitializeModuleName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))
      decl = gs.PosixStubWriter.UninitializeModuleName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))

  def testWriteUmbrellaInitializer(self):
    # Data for header generation.
    module_names = ['oneModule', 'twoModule']

    # Make the header.
    outfile = StringIO.StringIO()
    self.writer.WriteUmbrellaInitializer(module_names, 'my_namespace', outfile)
    contents = outfile.getvalue()

    # Check for umbrella initializer declaration.
    self.assertTrue(contents.find('bool InitializeStubs(') != -1)

    # If the umbrella initializer is correctly written, each module will have
    # its initializer called, checked, and uninitialized on failure.  Sanity
    # check that here.
    for name in module_names:
      # Check for module initializer functions.
      decl = gs.PosixStubWriter.IsInitializedName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))
      decl = gs.PosixStubWriter.InitializeModuleName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))
      decl = gs.PosixStubWriter.UninitializeModuleName(name)
      self.assertTrue(contents.find(decl) != -1,
                      msg='Expected "%s" in %s' % (decl, contents))

if __name__ == '__main__':
  unittest.main()
