# Copyright (c) 2011 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
TestGyp.py:  a testing framework for GYP integration tests.
"""

import os
import re
import shutil
import stat
import sys
import tempfile

import TestCommon
from TestCommon import __all__

__all__.extend([
  'TestGyp',
])


class TestGypBase(TestCommon.TestCommon):
  """
  Class for controlling end-to-end tests of gyp generators.

  Instantiating this class will create a temporary directory and
  arrange for its destruction (via the TestCmd superclass) and
  copy all of the non-gyptest files in the directory hierarchy of the
  executing script.

  The default behavior is to test the 'gyp' or 'gyp.bat' file in the
  current directory.  An alternative may be specified explicitly on
  instantiation, or by setting the TESTGYP_GYP environment variable.

  This class should be subclassed for each supported gyp generator
  (format).  Various abstract methods below define calling signatures
  used by the test scripts to invoke builds on the generated build
  configuration and to run executables generated by those builds.
  """

  build_tool = None
  build_tool_list = []

  _exe = TestCommon.exe_suffix
  _obj = TestCommon.obj_suffix
  shobj_ = TestCommon.shobj_prefix
  _shobj = TestCommon.shobj_suffix
  lib_ = TestCommon.lib_prefix
  _lib = TestCommon.lib_suffix
  dll_ = TestCommon.dll_prefix
  _dll = TestCommon.dll_suffix

  # Constants to represent different targets.
  ALL = '__all__'
  DEFAULT = '__default__'

  # Constants for different target types.
  EXECUTABLE = '__executable__'
  STATIC_LIB = '__static_lib__'
  SHARED_LIB = '__shared_lib__'

  def __init__(self, gyp=None, *args, **kw):
    self.origin_cwd = os.path.abspath(os.path.dirname(sys.argv[0]))

    if not gyp:
      gyp = os.environ.get('TESTGYP_GYP')
      if not gyp:
        if sys.platform == 'win32':
          gyp = 'gyp.bat'
        else:
          gyp = 'gyp'
    self.gyp = os.path.abspath(gyp)

    self.initialize_build_tool()

    if not kw.has_key('match'):
      kw['match'] = TestCommon.match_exact

    # Put test output in out/testworkarea by default.
    # Use temporary names so there are no collisions.
    workdir = os.path.join('out', kw.get('workdir', 'testworkarea'))
    # Create work area if it doesn't already exist.
    try:
      os.makedirs(workdir)
    except OSError:
      pass
    kw['workdir'] = tempfile.mktemp(prefix='testgyp.', dir=workdir)

    formats = kw.get('formats', [])
    if kw.has_key('formats'):
      del kw['formats']

    super(TestGypBase, self).__init__(*args, **kw)

    excluded_formats = set([f for f in formats if f[0] == '!'])
    included_formats = set(formats) - excluded_formats
    if ('!'+self.format in excluded_formats or
        included_formats and self.format not in included_formats):
      msg = 'Invalid test for %r format; skipping test.\n'
      self.skip_test(msg % self.format)

    self.copy_test_configuration(self.origin_cwd, self.workdir)
    self.set_configuration(None)

    # Set $HOME so that gyp doesn't read the user's actual
    # ~/.gyp/include.gypi file, which may contain variables
    # and other settings that would change the output.
    os.environ['HOME'] = self.workpath()
    # Clear $GYP_DEFINES for the same reason.
    if 'GYP_DEFINES' in os.environ:
      del os.environ['GYP_DEFINES']

  def built_file_must_exist(self, name, type=None, **kw):
    """
    Fails the test if the specified built file name does not exist.
    """
    return self.must_exist(self.built_file_path(name, type, **kw))

  def built_file_must_not_exist(self, name, type=None, **kw):
    """
    Fails the test if the specified built file name exists.
    """
    return self.must_not_exist(self.built_file_path(name, type, **kw))

  def built_file_must_match(self, name, contents, **kw):
    """
    Fails the test if the contents of the specified built file name
    do not match the specified contents.
    """
    return self.must_match(self.built_file_path(name, **kw), contents)

  def built_file_must_not_match(self, name, contents, **kw):
    """
    Fails the test if the contents of the specified built file name
    match the specified contents.
    """
    return self.must_not_match(self.built_file_path(name, **kw), contents)

  def copy_test_configuration(self, source_dir, dest_dir):
    """
    Copies the test configuration from the specified source_dir
    (the directory in which the test script lives) to the
    specified dest_dir (a temporary working directory).

    This ignores all files and directories that begin with
    the string 'gyptest', and all '.svn' subdirectories.
    """
    for root, dirs, files in os.walk(source_dir):
      if '.svn' in dirs:
        dirs.remove('.svn')
      dirs = [ d for d in dirs if not d.startswith('gyptest') ]
      files = [ f for f in files if not f.startswith('gyptest') ]
      for dirname in dirs:
        source = os.path.join(root, dirname)
        destination = source.replace(source_dir, dest_dir)
        os.mkdir(destination)
        if sys.platform != 'win32':
          shutil.copystat(source, destination)
      for filename in files:
        source = os.path.join(root, filename)
        destination = source.replace(source_dir, dest_dir)
        shutil.copy2(source, destination)

  def initialize_build_tool(self):
    """
    Initializes the .build_tool attribute.

    Searches the .build_tool_list for an executable name on the user's
    $PATH.  The first tool on the list is used as-is if nothing is found
    on the current $PATH.
    """
    for build_tool in self.build_tool_list:
      if not build_tool:
        continue
      if os.path.isabs(build_tool):
        self.build_tool = build_tool
        return
      build_tool = self.where_is(build_tool)
      if build_tool:
        self.build_tool = build_tool
        return

    if self.build_tool_list:
      self.build_tool = self.build_tool_list[0]

  def relocate(self, source, destination):
    """
    Renames (relocates) the specified source (usually a directory)
    to the specified destination, creating the destination directory
    first if necessary.

    Note:  Don't use this as a generic "rename" operation.  In the
    future, "relocating" parts of a GYP tree may affect the state of
    the test to modify the behavior of later method calls.
    """
    destination_dir = os.path.dirname(destination)
    if not os.path.exists(destination_dir):
      self.subdir(destination_dir)
    os.rename(source, destination)

  def report_not_up_to_date(self):
    """
    Reports that a build is not up-to-date.

    This provides common reporting for formats that have complicated
    conditions for checking whether a build is up-to-date.  Formats
    that expect exact output from the command (make, scons) can
    just set stdout= when they call the run_build() method.
    """
    print "Build is not up-to-date:"
    print self.banner('STDOUT ')
    print self.stdout()
    stderr = self.stderr()
    if stderr:
      print self.banner('STDERR ')
      print stderr

  def run_gyp(self, gyp_file, *args, **kw):
    """
    Runs gyp against the specified gyp_file with the specified args.
    """
    # TODO:  --depth=. works around Chromium-specific tree climbing.
    args = ('--depth=.', '--format='+self.format, gyp_file) + args
    return self.run(program=self.gyp, arguments=args, **kw)

  def run(self, *args, **kw):
    """
    Executes a program by calling the superclass .run() method.

    This exists to provide a common place to filter out keyword
    arguments implemented in this layer, without having to update
    the tool-specific subclasses or clutter the tests themselves
    with platform-specific code.
    """
    if kw.has_key('SYMROOT'):
      del kw['SYMROOT']
    super(TestGypBase, self).run(*args, **kw)

  def set_configuration(self, configuration):
    """
    Sets the configuration, to be used for invoking the build
    tool and testing potential built output.
    """
    self.configuration = configuration

  def configuration_dirname(self):
    if self.configuration:
      return self.configuration.split('|')[0]
    else:
      return 'Default'

  def configuration_buildname(self):
    if self.configuration:
      return self.configuration
    else:
      return 'Default'

  #
  # Abstract methods to be defined by format-specific subclasses.
  #

  def build(self, gyp_file, target=None, **kw):
    """
    Runs a build of the specified target against the configuration
    generated from the specified gyp_file.

    A 'target' argument of None or the special value TestGyp.DEFAULT
    specifies the default argument for the underlying build tool.
    A 'target' argument of TestGyp.ALL specifies the 'all' target
    (if any) of the underlying build tool.
    """
    raise NotImplementedError

  def built_file_path(self, name, type=None, **kw):
    """
    Returns a path to the specified file name, of the specified type.
    """
    raise NotImplementedError

  def built_file_basename(self, name, type=None, **kw):
    """
    Returns the base name of the specified file name, of the specified type.

    A bare=True keyword argument specifies that prefixes and suffixes shouldn't
    be applied.
    """
    if not kw.get('bare'):
      if type == self.EXECUTABLE:
        name = name + self._exe
      elif type == self.STATIC_LIB:
        name = self.lib_ + name + self._lib
      elif type == self.SHARED_LIB:
        name = self.dll_ + name + self._dll
    return name

  def run_built_executable(self, name, *args, **kw):
    """
    Runs an executable program built from a gyp-generated configuration.

    The specified name should be independent of any particular generator.
    Subclasses should find the output executable in the appropriate
    output build directory, tack on any necessary executable suffix, etc.
    """
    raise NotImplementedError

  def up_to_date(self, gyp_file, target=None, **kw):
    """
    Verifies that a build of the specified target is up to date.

    The subclass should implement this by calling build()
    (or a reasonable equivalent), checking whatever conditions
    will tell it the build was an "up to date" null build, and
    failing if it isn't.
    """
    raise NotImplementedError


class TestGypGypd(TestGypBase):
  """
  Subclass for testing the GYP 'gypd' generator (spit out the
  internal data structure as pretty-printed Python).
  """
  format = 'gypd'


class TestGypMake(TestGypBase):
  """
  Subclass for testing the GYP Make generator.
  """
  format = 'make'
  build_tool_list = ['make']
  ALL = 'all'
  def build(self, gyp_file, target=None, **kw):
    """
    Runs a Make build using the Makefiles generated from the specified
    gyp_file.
    """
    arguments = kw.get('arguments', [])[:]
    if self.configuration:
      arguments.append('BUILDTYPE=' + self.configuration)
    if target not in (None, self.DEFAULT):
      arguments.append(target)
    # Sub-directory builds provide per-gyp Makefiles (i.e.
    # Makefile.gyp_filename), so use that if there is no Makefile.
    chdir = kw.get('chdir', '')
    if not os.path.exists(os.path.join(chdir, 'Makefile')):
      print "NO Makefile in " + os.path.join(chdir, 'Makefile')
      arguments.insert(0, '-f')
      arguments.insert(1, os.path.splitext(gyp_file)[0] + '.Makefile')
    kw['arguments'] = arguments
    return self.run(program=self.build_tool, **kw)
  def up_to_date(self, gyp_file, target=None, **kw):
    """
    Verifies that a build of the specified Make target is up to date.
    """
    if target in (None, self.DEFAULT):
      message_target = 'all'
    else:
      message_target = target
    kw['stdout'] = "make: Nothing to be done for `%s'.\n" % message_target
    return self.build(gyp_file, target, **kw)
  def run_built_executable(self, name, *args, **kw):
    """
    Runs an executable built by Make.
    """
    configuration = self.configuration_dirname()
    libdir = os.path.join('out', configuration, 'lib')
    # TODO(piman): when everything is cross-compile safe, remove lib.target
    os.environ['LD_LIBRARY_PATH'] = libdir + '.host:' + libdir + '.target'
    # Enclosing the name in a list avoids prepending the original dir.
    program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
    return self.run(program=program, *args, **kw)
  def built_file_path(self, name, type=None, **kw):
    """
    Returns a path to the specified file name, of the specified type,
    as built by Make.

    Built files are in the subdirectory 'out/{configuration}'.
    The default is 'out/Default'.

    A chdir= keyword argument specifies the source directory
    relative to which  the output subdirectory can be found.

    "type" values of STATIC_LIB or SHARED_LIB append the necessary
    prefixes and suffixes to a platform-independent library base name.

    A subdir= keyword argument specifies a library subdirectory within
    the default 'obj.target'.
    """
    result = []
    chdir = kw.get('chdir')
    if chdir:
      result.append(chdir)
    configuration = self.configuration_dirname()
    result.extend(['out', configuration])
    if type == self.STATIC_LIB and sys.platform != 'darwin':
      result.append('obj.target')
    elif type == self.SHARED_LIB and sys.platform != 'darwin':
      result.append('lib.target')
    subdir = kw.get('subdir')
    if subdir:
      result.append(subdir)
    result.append(self.built_file_basename(name, type, **kw))
    return self.workpath(*result)


class TestGypNinja(TestGypBase):
  """
  Subclass for testing the GYP Ninja generator.
  """
  format = 'ninja'
  build_tool_list = ['ninja']
  ALL = 'all'
  DEFAULT = 'all'

  # The default library prefix is computed from TestCommon.lib_prefix,
  # but ninja uses no prefix for static libraries.
  lib_ = ''

  def run_gyp(self, gyp_file, *args, **kw):
    # We must pass the desired configuration as a parameter.
    if self.configuration:
      args = list(args) + ['-Gconfig=' + self.configuration]
    # Stash the gyp configuration we used to run gyp, so we can
    # know whether we need to rerun it later.
    self.last_gyp_configuration = self.configuration
    TestGypBase.run_gyp(self, gyp_file, *args, **kw)

  def build(self, gyp_file, target=None, **kw):
    if self.last_gyp_configuration != self.configuration:
      # Rerun gyp if necessary.
      self.run_gyp(gyp_file)

    arguments = kw.get('arguments', [])[:]

    # Add a -C output/path to the command line.
    arguments.append('-C')
    arguments.append(os.path.join('out', self.configuration_dirname()))

    if target is None:
      target = 'all'
    arguments.append(target)

    kw['arguments'] = arguments
    return self.run(program=self.build_tool, **kw)

  def run_built_executable(self, name, *args, **kw):
    # Enclosing the name in a list avoids prepending the original dir.
    program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
    return self.run(program=program, *args, **kw)

  def built_file_path(self, name, type=None, **kw):
    result = []
    chdir = kw.get('chdir')
    if chdir:
      result.append(chdir)
    result.append('out')
    result.append(self.configuration_dirname())
    if type in (self.STATIC_LIB,):
      result.append('obj')
    elif type in (self.SHARED_LIB,):
      result.append('lib')
    subdir = kw.get('subdir')
    if subdir:
      result.append(subdir)
    result.append(self.built_file_basename(name, type, **kw))
    return self.workpath(*result)

  def up_to_date(self, gyp_file, target=None, **kw):
    kw['stdout'] = "ninja: no work to do.\n"
    return self.build(gyp_file, target, **kw)


class TestGypMSVS(TestGypBase):
  """
  Subclass for testing the GYP Visual Studio generator.
  """
  format = 'msvs'

  u = r'=== Build: 0 succeeded, 0 failed, (\d+) up-to-date, 0 skipped ==='
  up_to_date_re = re.compile(u, re.M)

  # Initial None element will indicate to our .initialize_build_tool()
  # method below that 'devenv' was not found on %PATH%.
  #
  # Note:  we must use devenv.com to be able to capture build output.
  # Directly executing devenv.exe only sends output to BuildLog.htm.
  build_tool_list = [None, 'devenv.com']

  def initialize_build_tool(self):
    """ Initializes the Visual Studio .build_tool and .uses_msbuild parameters.

    We use the value specified by GYP_MSVS_VERSION.  If not specified, we
    search %PATH% and %PATHEXT% for a devenv.{exe,bat,...} executable.
    Failing that, we search for likely deployment paths.
    """
    super(TestGypMSVS, self).initialize_build_tool()
    possible_roots = ['C:\\Program Files (x86)', 'C:\\Program Files',
                      'E:\\Program Files (x86)', 'E:\\Program Files']
    possible_paths = {
        '2010': r'Microsoft Visual Studio 10.0\Common7\IDE\devenv.com',
        '2008': r'Microsoft Visual Studio 9.0\Common7\IDE\devenv.com',
        '2005': r'Microsoft Visual Studio 8\Common7\IDE\devenv.com'}
    msvs_version = os.environ.get('GYP_MSVS_VERSION', 'auto')
    if msvs_version in possible_paths:
      # Check that the path to the specified GYP_MSVS_VERSION exists.
      path = possible_paths[msvs_version]
      for r in possible_roots:
        bt = os.path.join(r, path)
        if os.path.exists(bt):
          self.build_tool = bt
          self.uses_msbuild = msvs_version >= '2010'
          return
      else:
        print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" '
               'but corresponding "%s" was not found.' % (msvs_version, path))
    if self.build_tool:
      # We found 'devenv' on the path, use that and try to guess the version.
      for version, path in possible_paths.iteritems():
        if self.build_tool.find(path) >= 0:
          self.uses_msbuild = version >= '2010'
          return
      else:
        # If not, assume not MSBuild.
        self.uses_msbuild = False
      return
    # Neither GYP_MSVS_VERSION nor the path help us out.  Iterate through
    # the choices looking for a match.
    for version, path in possible_paths.iteritems():
      for r in possible_roots:
        bt = os.path.join(r, path)
        if os.path.exists(bt):
          self.build_tool = bt
          self.uses_msbuild = msvs_version >= '2010'
          return
    print 'Error: could not find devenv'
    sys.exit(1)
  def build(self, gyp_file, target=None, rebuild=False, **kw):
    """
    Runs a Visual Studio build using the configuration generated
    from the specified gyp_file.
    """
    configuration = self.configuration_buildname()
    if rebuild:
      build = '/Rebuild'
    else:
      build = '/Build'
    arguments = kw.get('arguments', [])[:]
    arguments.extend([gyp_file.replace('.gyp', '.sln'),
                      build, configuration])
    # Note:  the Visual Studio generator doesn't add an explicit 'all'
    # target, so we just treat it the same as the default.
    if target not in (None, self.ALL, self.DEFAULT):
      arguments.extend(['/Project', target])
    if self.configuration:
      arguments.extend(['/ProjectConfig', self.configuration])
    kw['arguments'] = arguments
    return self.run(program=self.build_tool, **kw)
  def up_to_date(self, gyp_file, target=None, **kw):
    """
    Verifies that a build of the specified Visual Studio target is up to date.

    Beware that VS2010 will behave strangely if you build under
    C:\USERS\yourname\AppData\Local. It will cause needless work.  The ouptut
    will be "1 succeeded and 0 up to date".  MSBuild tracing reveals that:
    "Project 'C:\Users\...\AppData\Local\...vcxproj' not up to date because
    'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 10.0\VC\BIN\1033\CLUI.DLL'
    was modified at 02/21/2011 17:03:30, which is newer than '' which was
    modified at 01/01/0001 00:00:00.
    
    The workaround is to specify a workdir when instantiating the test, e.g.
    test = TestGyp.TestGyp(workdir='workarea')
    """
    result = self.build(gyp_file, target, **kw)
    if not result:
      stdout = self.stdout()

      m = self.up_to_date_re.search(stdout)
      up_to_date = m and m.group(1) == '1'
      if not up_to_date:
        self.report_not_up_to_date()
        self.fail_test()
    return result
  def run_built_executable(self, name, *args, **kw):
    """
    Runs an executable built by Visual Studio.
    """
    configuration = self.configuration_dirname()
    # Enclosing the name in a list avoids prepending the original dir.
    program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
    return self.run(program=program, *args, **kw)
  def built_file_path(self, name, type=None, **kw):
    """
    Returns a path to the specified file name, of the specified type,
    as built by Visual Studio.

    Built files are in a subdirectory that matches the configuration
    name.  The default is 'Default'.

    A chdir= keyword argument specifies the source directory
    relative to which  the output subdirectory can be found.

    "type" values of STATIC_LIB or SHARED_LIB append the necessary
    prefixes and suffixes to a platform-independent library base name.
    """
    result = []
    chdir = kw.get('chdir')
    if chdir:
      result.append(chdir)
    result.append(self.configuration_dirname())
    if type == self.STATIC_LIB:
      result.append('lib')
    result.append(self.built_file_basename(name, type, **kw))
    return self.workpath(*result)


class TestGypSCons(TestGypBase):
  """
  Subclass for testing the GYP SCons generator.
  """
  format = 'scons'
  build_tool_list = ['scons', 'scons.py']
  ALL = 'all'
  def build(self, gyp_file, target=None, **kw):
    """
    Runs a scons build using the SCons configuration generated from the
    specified gyp_file.
    """
    arguments = kw.get('arguments', [])[:]
    dirname = os.path.dirname(gyp_file)
    if dirname:
      arguments.extend(['-C', dirname])
    if self.configuration:
      arguments.append('--mode=' + self.configuration)
    if target not in (None, self.DEFAULT):
      arguments.append(target)
    kw['arguments'] = arguments
    return self.run(program=self.build_tool, **kw)
  def up_to_date(self, gyp_file, target=None, **kw):
    """
    Verifies that a build of the specified SCons target is up to date.
    """
    if target in (None, self.DEFAULT):
      up_to_date_targets = 'all'
    else:
      up_to_date_targets = target
    up_to_date_lines = []
    for arg in up_to_date_targets.split():
      up_to_date_lines.append("scons: `%s' is up to date.\n" % arg)
    kw['stdout'] = ''.join(up_to_date_lines)
    arguments = kw.get('arguments', [])[:]
    arguments.append('-Q')
    kw['arguments'] = arguments
    return self.build(gyp_file, target, **kw)
  def run_built_executable(self, name, *args, **kw):
    """
    Runs an executable built by scons.
    """
    configuration = self.configuration_dirname()
    os.environ['LD_LIBRARY_PATH'] = os.path.join(configuration, 'lib')
    # Enclosing the name in a list avoids prepending the original dir.
    program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
    return self.run(program=program, *args, **kw)
  def built_file_path(self, name, type=None, **kw):
    """
    Returns a path to the specified file name, of the specified type,
    as built by Scons.

    Built files are in a subdirectory that matches the configuration
    name.  The default is 'Default'.

    A chdir= keyword argument specifies the source directory
    relative to which  the output subdirectory can be found.

    "type" values of STATIC_LIB or SHARED_LIB append the necessary
    prefixes and suffixes to a platform-independent library base name.
    """
    result = []
    chdir = kw.get('chdir')
    if chdir:
      result.append(chdir)
    result.append(self.configuration_dirname())
    if type in (self.STATIC_LIB, self.SHARED_LIB):
      result.append('lib')
    result.append(self.built_file_basename(name, type, **kw))
    return self.workpath(*result)


class TestGypXcode(TestGypBase):
  """
  Subclass for testing the GYP Xcode generator.
  """
  format = 'xcode'
  build_tool_list = ['xcodebuild']

  phase_script_execution = ("\n"
                            "PhaseScriptExecution /\\S+/Script-[0-9A-F]+\\.sh\n"
                            "    cd /\\S+\n"
                            "    /bin/sh -c /\\S+/Script-[0-9A-F]+\\.sh\n"
                            "(make: Nothing to be done for `all'\\.\n)?")

  strip_up_to_date_expressions = [
    # Various actions or rules can run even when the overall build target
    # is up to date.  Strip those phases' GYP-generated output.
    re.compile(phase_script_execution, re.S),

    # The message from distcc_pump can trail the "BUILD SUCCEEDED"
    # message, so strip that, too.
    re.compile('__________Shutting down distcc-pump include server\n', re.S),
  ]

  up_to_date_endings = (
    'Checking Dependencies...\n** BUILD SUCCEEDED **\n', # Xcode 3.0/3.1
    'Check dependencies\n** BUILD SUCCEEDED **\n\n',     # Xcode 3.2
  )

  def build(self, gyp_file, target=None, **kw):
    """
    Runs an xcodebuild using the .xcodeproj generated from the specified
    gyp_file.
    """
    # Be sure we're working with a copy of 'arguments' since we modify it.
    # The caller may not be expecting it to be modified.
    arguments = kw.get('arguments', [])[:]
    arguments.extend(['-project', gyp_file.replace('.gyp', '.xcodeproj')])
    if target == self.ALL:
      arguments.append('-alltargets',)
    elif target not in (None, self.DEFAULT):
      arguments.extend(['-target', target])
    if self.configuration:
      arguments.extend(['-configuration', self.configuration])
    symroot = kw.get('SYMROOT', '$SRCROOT/build')
    if symroot:
      arguments.append('SYMROOT='+symroot)
    kw['arguments'] = arguments
    return self.run(program=self.build_tool, **kw)
  def up_to_date(self, gyp_file, target=None, **kw):
    """
    Verifies that a build of the specified Xcode target is up to date.
    """
    result = self.build(gyp_file, target, **kw)
    if not result:
      output = self.stdout()
      for expression in self.strip_up_to_date_expressions:
        output = expression.sub('', output)
      if not output.endswith(self.up_to_date_endings):
        self.report_not_up_to_date()
        self.fail_test()
    return result
  def run_built_executable(self, name, *args, **kw):
    """
    Runs an executable built by xcodebuild.
    """
    configuration = self.configuration_dirname()
    os.environ['DYLD_LIBRARY_PATH'] = os.path.join('build', configuration)
    # Enclosing the name in a list avoids prepending the original dir.
    program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
    return self.run(program=program, *args, **kw)
  def built_file_path(self, name, type=None, **kw):
    """
    Returns a path to the specified file name, of the specified type,
    as built by Xcode.

    Built files are in the subdirectory 'build/{configuration}'.
    The default is 'build/Default'.

    A chdir= keyword argument specifies the source directory
    relative to which  the output subdirectory can be found.

    "type" values of STATIC_LIB or SHARED_LIB append the necessary
    prefixes and suffixes to a platform-independent library base name.
    """
    result = []
    chdir = kw.get('chdir')
    if chdir:
      result.append(chdir)
    configuration = self.configuration_dirname()
    result.extend(['build', configuration])
    result.append(self.built_file_basename(name, type, **kw))
    return self.workpath(*result)


format_class_list = [
  TestGypGypd,
  TestGypMake,
  TestGypMSVS,
  TestGypNinja,
  TestGypSCons,
  TestGypXcode,
]

def TestGyp(*args, **kw):
  """
  Returns an appropriate TestGyp* instance for a specified GYP format.
  """
  format = kw.get('format')
  if format:
    del kw['format']
  else:
    format = os.environ.get('TESTGYP_FORMAT')
  for format_class in format_class_list:
    if format == format_class.format:
      return format_class(*args, **kw)
  raise Exception, "unknown format %r" % format
