#!/usr/bin/env python
#
# Copyright (C) 2009, 2010 Chris Jerdonek (chris.jerdonek@gmail.com)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Apple Inc. ("Apple") nor the names of
# its contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Run unit tests of WebKit's Perl, Python, and Ruby scripts."""

# The docstring above is passed as the "description" to the OptionParser
# used in this script's __main__ block.
#
# For the command options supported by this script, see the code below
# that instantiates the OptionParser class, or else pass --help
# while running this script (since argument help is auto-generated).

import os
import subprocess
import sys
from optparse import OptionParser

class ScriptsTester(object):

    """Supports running unit tests of WebKit scripts."""

    def __init__(self, scripts_directory):
        self.scripts_directory = scripts_directory

    def script_path(self, script_file_name):
        """Return an absolute path to the given script."""
        return os.path.join(self.scripts_directory, script_file_name)

    def run_test_script(self, script_title, script_path, args=None):
        """Run the given test script."""
        print('Testing %s:' % script_title)
        call_args = [script_path]
        if args:
            call_args.extend(args)
        return_code = subprocess.call(call_args)
        print(70 * "*") # dividing line
        return not bool(return_code)

    def main(self):
        parser = OptionParser(description=__doc__)
        parser.add_option('-a', '--all', dest='all', action='store_true',
                          default=False, help='run all available tests, '
                          'including those suppressed by default')
        (options, args) = parser.parse_args()

        webkitperl_success = self.run_test_script('Perl scripts', self.script_path('test-webkitperl'))
        webkitpy_success = self.run_test_script('Python scripts', self.script_path('test-webkitpy'),
                             ['--all'] if options.all else None)
        webkitruby_success = self.run_test_script('Ruby scripts', self.script_path('test-webkitruby'))

        if webkitperl_success and webkitpy_success and webkitruby_success:
            print('All tests completed successfully')
            sys.exit(0)
        else:
            print('The following test scripts have failed: ')
            if not webkitperl_success:
                print('test-webkitperl')
            if not webkitpy_success:
                print('test-webkitpy')
            if not webkitruby_success:
                print('test-webkitruby')
            print('Detailed results appear separately above.')
            sys.exit(1)
            
if __name__ == '__main__':
    # The scripts directory is the directory containing this file.
    tester = ScriptsTester(os.path.dirname(__file__))
    tester.main()
