r299759 - [scan-build-py] merge runner module to analyzer

Laszlo Nagy via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 7 04:04:50 PDT 2017


Author: rizsotto
Date: Fri Apr  7 06:04:49 2017
New Revision: 299759

URL: http://llvm.org/viewvc/llvm-project?rev=299759&view=rev
Log:
[scan-build-py] merge runner module to analyzer

Differential Revision: https://reviews.llvm.org/D31237

Removed:
    cfe/trunk/tools/scan-build-py/libscanbuild/runner.py
    cfe/trunk/tools/scan-build-py/tests/unit/test_runner.py
Modified:
    cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py
    cfe/trunk/tools/scan-build-py/tests/unit/__init__.py
    cfe/trunk/tools/scan-build-py/tests/unit/test_analyze.py
    cfe/trunk/tools/scan-build-py/tests/unit/test_report.py

Modified: cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py?rev=299759&r1=299758&r2=299759&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py (original)
+++ cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py Fri Apr  7 06:04:49 2017
@@ -16,18 +16,23 @@ import os
 import os.path
 import json
 import logging
-import tempfile
 import multiprocessing
+import tempfile
+import functools
+import subprocess
 import contextlib
 import datetime
+
 from libscanbuild import command_entry_point, compiler_wrapper, \
-    wrapper_environment, run_build
+    wrapper_environment, run_build, run_command
 from libscanbuild.arguments import parse_args_for_scan_build, \
     parse_args_for_analyze_build
-from libscanbuild.runner import run
 from libscanbuild.intercept import capture
 from libscanbuild.report import document
-from libscanbuild.compilation import split_command
+from libscanbuild.compilation import split_command, classify_source, \
+    compiler_language
+from libscanbuild.clang import get_version, get_arguments
+from libscanbuild.shell import decode
 
 __all__ = ['scan_build', 'analyze_build', 'analyze_compiler_wrapper']
 
@@ -51,7 +56,7 @@ def scan_build():
             exit_code = capture(args)
             # Run the analyzer against the captured commands.
             if need_analyzer(args.build):
-                run_analyzer(args)
+                run_analyzer_parallel(args)
         else:
             # Run build command and analyzer with compiler wrappers.
             environment = setup_environment(args)
@@ -70,7 +75,7 @@ def analyze_build():
     # will re-assign the report directory as new output
     with report_directory(args.output, args.keep_empty) as args.output:
         # Run the analyzer against a compilation db.
-        run_analyzer(args)
+        run_analyzer_parallel(args)
         # Cover report generation and bug counting.
         number_of_bugs = document(args)
         # Set exit status as it was requested.
@@ -90,7 +95,7 @@ def need_analyzer(args):
     return len(args) and not re.search('configure|autogen', args[0])
 
 
-def run_analyzer(args):
+def run_analyzer_parallel(args):
     """ Runs the analyzer against the given compilation database. """
 
     def exclude(filename):
@@ -259,3 +264,277 @@ def analyzer_params(args):
         result.append('-analyzer-viz-egraph-ubigraph')
 
     return prefix_with('-Xclang', result)
+
+
+def require(required):
+    """ Decorator for checking the required values in state.
+
+    It checks the required attributes in the passed state and stop when
+    any of those is missing. """
+
+    def decorator(function):
+        @functools.wraps(function)
+        def wrapper(*args, **kwargs):
+            for key in required:
+                if key not in args[0]:
+                    raise KeyError('{0} not passed to {1}'.format(
+                        key, function.__name__))
+
+            return function(*args, **kwargs)
+
+        return wrapper
+
+    return decorator
+
+
+ at require(['command',  # entry from compilation database
+          'directory',  # entry from compilation database
+          'file',  # entry from compilation database
+          'clang',  # clang executable name (and path)
+          'direct_args',  # arguments from command line
+          'force_debug',  # kill non debug macros
+          'output_dir',  # where generated report files shall go
+          'output_format',  # it's 'plist' or 'html' or both
+          'output_failures'])  # generate crash reports or not
+def run(opts):
+    """ Entry point to run (or not) static analyzer against a single entry
+    of the compilation database.
+
+    This complex task is decomposed into smaller methods which are calling
+    each other in chain. If the analyzis is not possibe the given method
+    just return and break the chain.
+
+    The passed parameter is a python dictionary. Each method first check
+    that the needed parameters received. (This is done by the 'require'
+    decorator. It's like an 'assert' to check the contract between the
+    caller and the called method.) """
+
+    try:
+        command = opts.pop('command')
+        command = command if isinstance(command, list) else decode(command)
+        logging.debug("Run analyzer against '%s'", command)
+        opts.update(classify_parameters(command))
+
+        return arch_check(opts)
+    except Exception:
+        logging.error("Problem occured during analyzis.", exc_info=1)
+        return None
+
+
+ at require(['clang', 'directory', 'flags', 'file', 'output_dir', 'language',
+          'error_output', 'exit_code'])
+def report_failure(opts):
+    """ Create report when analyzer failed.
+
+    The major report is the preprocessor output. The output filename generated
+    randomly. The compiler output also captured into '.stderr.txt' file.
+    And some more execution context also saved into '.info.txt' file. """
+
+    def extension():
+        """ Generate preprocessor file extension. """
+
+        mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'}
+        return mapping.get(opts['language'], '.i')
+
+    def destination():
+        """ Creates failures directory if not exits yet. """
+
+        failures_dir = os.path.join(opts['output_dir'], 'failures')
+        if not os.path.isdir(failures_dir):
+            os.makedirs(failures_dir)
+        return failures_dir
+
+    # Classify error type: when Clang terminated by a signal it's a 'Crash'.
+    # (python subprocess Popen.returncode is negative when child terminated
+    # by signal.) Everything else is 'Other Error'.
+    error = 'crash' if opts['exit_code'] < 0 else 'other_error'
+    # Create preprocessor output file name. (This is blindly following the
+    # Perl implementation.)
+    (handle, name) = tempfile.mkstemp(suffix=extension(),
+                                      prefix='clang_' + error + '_',
+                                      dir=destination())
+    os.close(handle)
+    # Execute Clang again, but run the syntax check only.
+    cwd = opts['directory']
+    cmd = get_arguments(
+        [opts['clang'], '-fsyntax-only', '-E'
+         ] + opts['flags'] + [opts['file'], '-o', name], cwd)
+    run_command(cmd, cwd=cwd)
+    # write general information about the crash
+    with open(name + '.info.txt', 'w') as handle:
+        handle.write(opts['file'] + os.linesep)
+        handle.write(error.title().replace('_', ' ') + os.linesep)
+        handle.write(' '.join(cmd) + os.linesep)
+        handle.write(' '.join(os.uname()) + os.linesep)
+        handle.write(get_version(opts['clang']))
+        handle.close()
+    # write the captured output too
+    with open(name + '.stderr.txt', 'w') as handle:
+        handle.writelines(opts['error_output'])
+        handle.close()
+
+
+ at require(['clang', 'directory', 'flags', 'direct_args', 'file', 'output_dir',
+          'output_format'])
+def run_analyzer(opts, continuation=report_failure):
+    """ It assembles the analysis command line and executes it. Capture the
+    output of the analysis and returns with it. If failure reports are
+    requested, it calls the continuation to generate it. """
+
+    def target():
+        """ Creates output file name for reports. """
+        if opts['output_format'] in {'plist', 'plist-html'}:
+            (handle, name) = tempfile.mkstemp(prefix='report-',
+                                              suffix='.plist',
+                                              dir=opts['output_dir'])
+            os.close(handle)
+            return name
+        return opts['output_dir']
+
+    try:
+        cwd = opts['directory']
+        cmd = get_arguments([opts['clang'], '--analyze'] +
+                            opts['direct_args'] + opts['flags'] +
+                            [opts['file'], '-o', target()],
+                            cwd)
+        output = run_command(cmd, cwd=cwd)
+        return {'error_output': output, 'exit_code': 0}
+    except subprocess.CalledProcessError as ex:
+        result = {'error_output': ex.output, 'exit_code': ex.returncode}
+        if opts.get('output_failures', False):
+            opts.update(result)
+            continuation(opts)
+        return result
+
+
+ at require(['flags', 'force_debug'])
+def filter_debug_flags(opts, continuation=run_analyzer):
+    """ Filter out nondebug macros when requested. """
+
+    if opts.pop('force_debug'):
+        # lazy implementation just append an undefine macro at the end
+        opts.update({'flags': opts['flags'] + ['-UNDEBUG']})
+
+    return continuation(opts)
+
+
+ at require(['language', 'compiler', 'file', 'flags'])
+def language_check(opts, continuation=filter_debug_flags):
+    """ Find out the language from command line parameters or file name
+    extension. The decision also influenced by the compiler invocation. """
+
+    accepted = frozenset({
+        'c', 'c++', 'objective-c', 'objective-c++', 'c-cpp-output',
+        'c++-cpp-output', 'objective-c-cpp-output'
+    })
+
+    # language can be given as a parameter...
+    language = opts.pop('language')
+    compiler = opts.pop('compiler')
+    # ... or find out from source file extension
+    if language is None and compiler is not None:
+        language = classify_source(opts['file'], compiler == 'c')
+
+    if language is None:
+        logging.debug('skip analysis, language not known')
+        return None
+    elif language not in accepted:
+        logging.debug('skip analysis, language not supported')
+        return None
+    else:
+        logging.debug('analysis, language: %s', language)
+        opts.update({'language': language,
+                     'flags': ['-x', language] + opts['flags']})
+        return continuation(opts)
+
+
+ at require(['arch_list', 'flags'])
+def arch_check(opts, continuation=language_check):
+    """ Do run analyzer through one of the given architectures. """
+
+    disabled = frozenset({'ppc', 'ppc64'})
+
+    received_list = opts.pop('arch_list')
+    if received_list:
+        # filter out disabled architectures and -arch switches
+        filtered_list = [a for a in received_list if a not in disabled]
+        if filtered_list:
+            # There should be only one arch given (or the same multiple
+            # times). If there are multiple arch are given and are not
+            # the same, those should not change the pre-processing step.
+            # But that's the only pass we have before run the analyzer.
+            current = filtered_list.pop()
+            logging.debug('analysis, on arch: %s', current)
+
+            opts.update({'flags': ['-arch', current] + opts['flags']})
+            return continuation(opts)
+        else:
+            logging.debug('skip analysis, found not supported arch')
+            return None
+    else:
+        logging.debug('analysis, on default arch')
+        return continuation(opts)
+
+# To have good results from static analyzer certain compiler options shall be
+# omitted. The compiler flag filtering only affects the static analyzer run.
+#
+# Keys are the option name, value number of options to skip
+IGNORED_FLAGS = {
+    '-c': 0,  # compile option will be overwritten
+    '-fsyntax-only': 0,  # static analyzer option will be overwritten
+    '-o': 1,  # will set up own output file
+    # flags below are inherited from the perl implementation.
+    '-g': 0,
+    '-save-temps': 0,
+    '-install_name': 1,
+    '-exported_symbols_list': 1,
+    '-current_version': 1,
+    '-compatibility_version': 1,
+    '-init': 1,
+    '-e': 1,
+    '-seg1addr': 1,
+    '-bundle_loader': 1,
+    '-multiply_defined': 1,
+    '-sectorder': 3,
+    '--param': 1,
+    '--serialize-diagnostics': 1
+}
+
+
+def classify_parameters(command):
+    """ Prepare compiler flags (filters some and add others) and take out
+    language (-x) and architecture (-arch) flags for future processing. """
+
+    result = {
+        'flags': [],  # the filtered compiler flags
+        'arch_list': [],  # list of architecture flags
+        'language': None,  # compilation language, None, if not specified
+        'compiler': compiler_language(command)  # 'c' or 'c++'
+    }
+
+    # iterate on the compile options
+    args = iter(command[1:])
+    for arg in args:
+        # take arch flags into a separate basket
+        if arg == '-arch':
+            result['arch_list'].append(next(args))
+        # take language
+        elif arg == '-x':
+            result['language'] = next(args)
+        # parameters which looks source file are not flags
+        elif re.match(r'^[^-].+', arg) and classify_source(arg):
+            pass
+        # ignore some flags
+        elif arg in IGNORED_FLAGS:
+            count = IGNORED_FLAGS[arg]
+            for _ in range(count):
+                next(args)
+        # we don't care about extra warnings, but we should suppress ones
+        # that we don't want to see.
+        elif re.match(r'^-W.+', arg) and not re.match(r'^-Wno-.+', arg):
+            pass
+        # and consider everything else as compilation flag.
+        else:
+            result['flags'].append(arg)
+
+    return result

Removed: cfe/trunk/tools/scan-build-py/libscanbuild/runner.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libscanbuild/runner.py?rev=299758&view=auto
==============================================================================
--- cfe/trunk/tools/scan-build-py/libscanbuild/runner.py (original)
+++ cfe/trunk/tools/scan-build-py/libscanbuild/runner.py (removed)
@@ -1,294 +0,0 @@
-# -*- coding: utf-8 -*-
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-""" This module is responsible to run the analyzer commands. """
-
-import re
-import os
-import os.path
-import tempfile
-import functools
-import subprocess
-import logging
-from libscanbuild import run_command
-from libscanbuild.compilation import classify_source, compiler_language
-from libscanbuild.clang import get_version, get_arguments
-from libscanbuild.shell import decode
-
-__all__ = ['run']
-
-# To have good results from static analyzer certain compiler options shall be
-# omitted. The compiler flag filtering only affects the static analyzer run.
-#
-# Keys are the option name, value number of options to skip
-IGNORED_FLAGS = {
-    '-c': 0,  # compile option will be overwritten
-    '-fsyntax-only': 0,  # static analyzer option will be overwritten
-    '-o': 1,  # will set up own output file
-    # flags below are inherited from the perl implementation.
-    '-g': 0,
-    '-save-temps': 0,
-    '-install_name': 1,
-    '-exported_symbols_list': 1,
-    '-current_version': 1,
-    '-compatibility_version': 1,
-    '-init': 1,
-    '-e': 1,
-    '-seg1addr': 1,
-    '-bundle_loader': 1,
-    '-multiply_defined': 1,
-    '-sectorder': 3,
-    '--param': 1,
-    '--serialize-diagnostics': 1
-}
-
-
-def require(required):
-    """ Decorator for checking the required values in state.
-
-    It checks the required attributes in the passed state and stop when
-    any of those is missing. """
-
-    def decorator(function):
-        @functools.wraps(function)
-        def wrapper(*args, **kwargs):
-            for key in required:
-                if key not in args[0]:
-                    raise KeyError('{0} not passed to {1}'.format(
-                        key, function.__name__))
-
-            return function(*args, **kwargs)
-
-        return wrapper
-
-    return decorator
-
-
- at require(['command',  # entry from compilation database
-          'directory',  # entry from compilation database
-          'file',  # entry from compilation database
-          'clang',  # clang executable name (and path)
-          'direct_args',  # arguments from command line
-          'force_debug',  # kill non debug macros
-          'output_dir',  # where generated report files shall go
-          'output_format',  # it's 'plist' or 'html' or both
-          'output_failures'])  # generate crash reports or not
-def run(opts):
-    """ Entry point to run (or not) static analyzer against a single entry
-    of the compilation database.
-
-    This complex task is decomposed into smaller methods which are calling
-    each other in chain. If the analyzis is not possibe the given method
-    just return and break the chain.
-
-    The passed parameter is a python dictionary. Each method first check
-    that the needed parameters received. (This is done by the 'require'
-    decorator. It's like an 'assert' to check the contract between the
-    caller and the called method.) """
-
-    try:
-        command = opts.pop('command')
-        command = command if isinstance(command, list) else decode(command)
-        logging.debug("Run analyzer against '%s'", command)
-        opts.update(classify_parameters(command))
-
-        return arch_check(opts)
-    except Exception:
-        logging.error("Problem occured during analyzis.", exc_info=1)
-        return None
-
-
- at require(['clang', 'directory', 'flags', 'file', 'output_dir', 'language',
-          'error_output', 'exit_code'])
-def report_failure(opts):
-    """ Create report when analyzer failed.
-
-    The major report is the preprocessor output. The output filename generated
-    randomly. The compiler output also captured into '.stderr.txt' file.
-    And some more execution context also saved into '.info.txt' file. """
-
-    def extension():
-        """ Generate preprocessor file extension. """
-
-        mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'}
-        return mapping.get(opts['language'], '.i')
-
-    def destination():
-        """ Creates failures directory if not exits yet. """
-
-        failures_dir = os.path.join(opts['output_dir'], 'failures')
-        if not os.path.isdir(failures_dir):
-            os.makedirs(failures_dir)
-        return failures_dir
-
-    # Classify error type: when Clang terminated by a signal it's a 'Crash'.
-    # (python subprocess Popen.returncode is negative when child terminated
-    # by signal.) Everything else is 'Other Error'.
-    error = 'crash' if opts['exit_code'] < 0 else 'other_error'
-    # Create preprocessor output file name. (This is blindly following the
-    # Perl implementation.)
-    (handle, name) = tempfile.mkstemp(suffix=extension(),
-                                      prefix='clang_' + error + '_',
-                                      dir=destination())
-    os.close(handle)
-    # Execute Clang again, but run the syntax check only.
-    cwd = opts['directory']
-    cmd = get_arguments(
-        [opts['clang'], '-fsyntax-only', '-E'
-         ] + opts['flags'] + [opts['file'], '-o', name], cwd)
-    run_command(cmd, cwd=cwd)
-    # write general information about the crash
-    with open(name + '.info.txt', 'w') as handle:
-        handle.write(opts['file'] + os.linesep)
-        handle.write(error.title().replace('_', ' ') + os.linesep)
-        handle.write(' '.join(cmd) + os.linesep)
-        handle.write(' '.join(os.uname()) + os.linesep)
-        handle.write(get_version(opts['clang']))
-        handle.close()
-    # write the captured output too
-    with open(name + '.stderr.txt', 'w') as handle:
-        handle.writelines(opts['error_output'])
-        handle.close()
-
-
- at require(['clang', 'directory', 'flags', 'direct_args', 'file', 'output_dir',
-          'output_format'])
-def run_analyzer(opts, continuation=report_failure):
-    """ It assembles the analysis command line and executes it. Capture the
-    output of the analysis and returns with it. If failure reports are
-    requested, it calls the continuation to generate it. """
-
-    def target():
-        """ Creates output file name for reports. """
-        if opts['output_format'] in {'plist', 'plist-html'}:
-            (handle, name) = tempfile.mkstemp(prefix='report-',
-                                              suffix='.plist',
-                                              dir=opts['output_dir'])
-            os.close(handle)
-            return name
-        return opts['output_dir']
-
-    try:
-        cwd = opts['directory']
-        cmd = get_arguments([opts['clang'], '--analyze'] +
-                            opts['direct_args'] + opts['flags'] +
-                            [opts['file'], '-o', target()],
-                            cwd)
-        output = run_command(cmd, cwd=cwd)
-        return {'error_output': output, 'exit_code': 0}
-    except subprocess.CalledProcessError as ex:
-        result = {'error_output': ex.output, 'exit_code': ex.returncode}
-        if opts.get('output_failures', False):
-            opts.update(result)
-            continuation(opts)
-        return result
-
-
- at require(['flags', 'force_debug'])
-def filter_debug_flags(opts, continuation=run_analyzer):
-    """ Filter out nondebug macros when requested. """
-
-    if opts.pop('force_debug'):
-        # lazy implementation just append an undefine macro at the end
-        opts.update({'flags': opts['flags'] + ['-UNDEBUG']})
-
-    return continuation(opts)
-
-
- at require(['language', 'compiler', 'file', 'flags'])
-def language_check(opts, continuation=filter_debug_flags):
-    """ Find out the language from command line parameters or file name
-    extension. The decision also influenced by the compiler invocation. """
-
-    accepted = frozenset({
-        'c', 'c++', 'objective-c', 'objective-c++', 'c-cpp-output',
-        'c++-cpp-output', 'objective-c-cpp-output'
-    })
-
-    # language can be given as a parameter...
-    language = opts.pop('language')
-    compiler = opts.pop('compiler')
-    # ... or find out from source file extension
-    if language is None and compiler is not None:
-        language = classify_source(opts['file'], compiler == 'c')
-
-    if language is None:
-        logging.debug('skip analysis, language not known')
-        return None
-    elif language not in accepted:
-        logging.debug('skip analysis, language not supported')
-        return None
-    else:
-        logging.debug('analysis, language: %s', language)
-        opts.update({'language': language,
-                     'flags': ['-x', language] + opts['flags']})
-        return continuation(opts)
-
-
- at require(['arch_list', 'flags'])
-def arch_check(opts, continuation=language_check):
-    """ Do run analyzer through one of the given architectures. """
-
-    disabled = frozenset({'ppc', 'ppc64'})
-
-    received_list = opts.pop('arch_list')
-    if received_list:
-        # filter out disabled architectures and -arch switches
-        filtered_list = [a for a in received_list if a not in disabled]
-        if filtered_list:
-            # There should be only one arch given (or the same multiple
-            # times). If there are multiple arch are given and are not
-            # the same, those should not change the pre-processing step.
-            # But that's the only pass we have before run the analyzer.
-            current = filtered_list.pop()
-            logging.debug('analysis, on arch: %s', current)
-
-            opts.update({'flags': ['-arch', current] + opts['flags']})
-            return continuation(opts)
-        else:
-            logging.debug('skip analysis, found not supported arch')
-            return None
-    else:
-        logging.debug('analysis, on default arch')
-        return continuation(opts)
-
-
-def classify_parameters(command):
-    """ Prepare compiler flags (filters some and add others) and take out
-    language (-x) and architecture (-arch) flags for future processing. """
-
-    result = {
-        'flags': [],  # the filtered compiler flags
-        'arch_list': [],  # list of architecture flags
-        'language': None,  # compilation language, None, if not specified
-        'compiler': compiler_language(command)  # 'c' or 'c++'
-    }
-
-    # iterate on the compile options
-    args = iter(command[1:])
-    for arg in args:
-        # take arch flags into a separate basket
-        if arg == '-arch':
-            result['arch_list'].append(next(args))
-        # take language
-        elif arg == '-x':
-            result['language'] = next(args)
-        # parameters which looks source file are not flags
-        elif re.match(r'^[^-].+', arg) and classify_source(arg):
-            pass
-        # ignore some flags
-        elif arg in IGNORED_FLAGS:
-            count = IGNORED_FLAGS[arg]
-            for _ in range(count):
-                next(args)
-        # we don't care about extra warnings, but we should suppress ones
-        # that we don't want to see.
-        elif re.match(r'^-W.+', arg) and not re.match(r'^-Wno-.+', arg):
-            pass
-        # and consider everything else as compilation flag.
-        else:
-            result['flags'].append(arg)
-
-    return result

Modified: cfe/trunk/tools/scan-build-py/tests/unit/__init__.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/tests/unit/__init__.py?rev=299759&r1=299758&r2=299759&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build-py/tests/unit/__init__.py (original)
+++ cfe/trunk/tools/scan-build-py/tests/unit/__init__.py Fri Apr  7 06:04:49 2017
@@ -7,7 +7,6 @@
 from . import test_libear
 from . import test_compilation
 from . import test_clang
-from . import test_runner
 from . import test_report
 from . import test_analyze
 from . import test_intercept
@@ -18,7 +17,6 @@ def load_tests(loader, suite, _):
     suite.addTests(loader.loadTestsFromModule(test_libear))
     suite.addTests(loader.loadTestsFromModule(test_compilation))
     suite.addTests(loader.loadTestsFromModule(test_clang))
-    suite.addTests(loader.loadTestsFromModule(test_runner))
     suite.addTests(loader.loadTestsFromModule(test_report))
     suite.addTests(loader.loadTestsFromModule(test_analyze))
     suite.addTests(loader.loadTestsFromModule(test_intercept))

Modified: cfe/trunk/tools/scan-build-py/tests/unit/test_analyze.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/tests/unit/test_analyze.py?rev=299759&r1=299758&r2=299759&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build-py/tests/unit/test_analyze.py (original)
+++ cfe/trunk/tools/scan-build-py/tests/unit/test_analyze.py Fri Apr  7 06:04:49 2017
@@ -7,6 +7,10 @@
 import libear
 import libscanbuild.analyze as sut
 import unittest
+import re
+import os
+import os.path
+
 
 class ReportDirectoryTest(unittest.TestCase):
 
@@ -20,3 +24,312 @@ class ReportDirectoryTest(unittest.TestC
              sut.report_directory(tmpdir, False) as report_dir3:
             self.assertLess(report_dir1, report_dir2)
             self.assertLess(report_dir2, report_dir3)
+
+
+class FilteringFlagsTest(unittest.TestCase):
+
+    def test_language_captured(self):
+        def test(flags):
+            cmd = ['clang', '-c', 'source.c'] + flags
+            opts = sut.classify_parameters(cmd)
+            return opts['language']
+
+        self.assertEqual(None, test([]))
+        self.assertEqual('c', test(['-x', 'c']))
+        self.assertEqual('cpp', test(['-x', 'cpp']))
+
+    def test_arch(self):
+        def test(flags):
+            cmd = ['clang', '-c', 'source.c'] + flags
+            opts = sut.classify_parameters(cmd)
+            return opts['arch_list']
+
+        self.assertEqual([], test([]))
+        self.assertEqual(['mips'], test(['-arch', 'mips']))
+        self.assertEqual(['mips', 'i386'],
+                         test(['-arch', 'mips', '-arch', 'i386']))
+
+    def assertFlagsChanged(self, expected, flags):
+        cmd = ['clang', '-c', 'source.c'] + flags
+        opts = sut.classify_parameters(cmd)
+        self.assertEqual(expected, opts['flags'])
+
+    def assertFlagsUnchanged(self, flags):
+        self.assertFlagsChanged(flags, flags)
+
+    def assertFlagsFiltered(self, flags):
+        self.assertFlagsChanged([], flags)
+
+    def test_optimalizations_pass(self):
+        self.assertFlagsUnchanged(['-O'])
+        self.assertFlagsUnchanged(['-O1'])
+        self.assertFlagsUnchanged(['-Os'])
+        self.assertFlagsUnchanged(['-O2'])
+        self.assertFlagsUnchanged(['-O3'])
+
+    def test_include_pass(self):
+        self.assertFlagsUnchanged([])
+        self.assertFlagsUnchanged(['-include', '/usr/local/include'])
+        self.assertFlagsUnchanged(['-I.'])
+        self.assertFlagsUnchanged(['-I', '.'])
+        self.assertFlagsUnchanged(['-I/usr/local/include'])
+        self.assertFlagsUnchanged(['-I', '/usr/local/include'])
+        self.assertFlagsUnchanged(['-I/opt', '-I', '/opt/otp/include'])
+        self.assertFlagsUnchanged(['-isystem', '/path'])
+        self.assertFlagsUnchanged(['-isystem=/path'])
+
+    def test_define_pass(self):
+        self.assertFlagsUnchanged(['-DNDEBUG'])
+        self.assertFlagsUnchanged(['-UNDEBUG'])
+        self.assertFlagsUnchanged(['-Dvar1=val1', '-Dvar2=val2'])
+        self.assertFlagsUnchanged(['-Dvar="val ues"'])
+
+    def test_output_filtered(self):
+        self.assertFlagsFiltered(['-o', 'source.o'])
+
+    def test_some_warning_filtered(self):
+        self.assertFlagsFiltered(['-Wall'])
+        self.assertFlagsFiltered(['-Wnoexcept'])
+        self.assertFlagsFiltered(['-Wreorder', '-Wunused', '-Wundef'])
+        self.assertFlagsUnchanged(['-Wno-reorder', '-Wno-unused'])
+
+    def test_compile_only_flags_pass(self):
+        self.assertFlagsUnchanged(['-std=C99'])
+        self.assertFlagsUnchanged(['-nostdinc'])
+        self.assertFlagsUnchanged(['-isystem', '/image/debian'])
+        self.assertFlagsUnchanged(['-iprefix', '/usr/local'])
+        self.assertFlagsUnchanged(['-iquote=me'])
+        self.assertFlagsUnchanged(['-iquote', 'me'])
+
+    def test_compile_and_link_flags_pass(self):
+        self.assertFlagsUnchanged(['-fsinged-char'])
+        self.assertFlagsUnchanged(['-fPIC'])
+        self.assertFlagsUnchanged(['-stdlib=libc++'])
+        self.assertFlagsUnchanged(['--sysroot', '/'])
+        self.assertFlagsUnchanged(['-isysroot', '/'])
+
+    def test_some_flags_filtered(self):
+        self.assertFlagsFiltered(['-g'])
+        self.assertFlagsFiltered(['-fsyntax-only'])
+        self.assertFlagsFiltered(['-save-temps'])
+        self.assertFlagsFiltered(['-init', 'my_init'])
+        self.assertFlagsFiltered(['-sectorder', 'a', 'b', 'c'])
+
+
+class Spy(object):
+    def __init__(self):
+        self.arg = None
+        self.success = 0
+
+    def call(self, params):
+        self.arg = params
+        return self.success
+
+
+class RunAnalyzerTest(unittest.TestCase):
+
+    @staticmethod
+    def run_analyzer(content, failures_report):
+        with libear.TemporaryDirectory() as tmpdir:
+            filename = os.path.join(tmpdir, 'test.cpp')
+            with open(filename, 'w') as handle:
+                handle.write(content)
+
+            opts = {
+                'clang': 'clang',
+                'directory': os.getcwd(),
+                'flags': [],
+                'direct_args': [],
+                'file': filename,
+                'output_dir': tmpdir,
+                'output_format': 'plist',
+                'output_failures': failures_report
+            }
+            spy = Spy()
+            result = sut.run_analyzer(opts, spy.call)
+            return (result, spy.arg)
+
+    def test_run_analyzer(self):
+        content = "int div(int n, int d) { return n / d; }"
+        (result, fwds) = RunAnalyzerTest.run_analyzer(content, False)
+        self.assertEqual(None, fwds)
+        self.assertEqual(0, result['exit_code'])
+
+    def test_run_analyzer_crash(self):
+        content = "int div(int n, int d) { return n / d }"
+        (result, fwds) = RunAnalyzerTest.run_analyzer(content, False)
+        self.assertEqual(None, fwds)
+        self.assertEqual(1, result['exit_code'])
+
+    def test_run_analyzer_crash_and_forwarded(self):
+        content = "int div(int n, int d) { return n / d }"
+        (_, fwds) = RunAnalyzerTest.run_analyzer(content, True)
+        self.assertEqual(1, fwds['exit_code'])
+        self.assertTrue(len(fwds['error_output']) > 0)
+
+
+class ReportFailureTest(unittest.TestCase):
+
+    def assertUnderFailures(self, path):
+        self.assertEqual('failures', os.path.basename(os.path.dirname(path)))
+
+    def test_report_failure_create_files(self):
+        with libear.TemporaryDirectory() as tmpdir:
+            # create input file
+            filename = os.path.join(tmpdir, 'test.c')
+            with open(filename, 'w') as handle:
+                handle.write('int main() { return 0')
+            uname_msg = ' '.join(os.uname()) + os.linesep
+            error_msg = 'this is my error output'
+            # execute test
+            opts = {
+                'clang': 'clang',
+                'directory': os.getcwd(),
+                'flags': [],
+                'file': filename,
+                'output_dir': tmpdir,
+                'language': 'c',
+                'error_type': 'other_error',
+                'error_output': error_msg,
+                'exit_code': 13
+            }
+            sut.report_failure(opts)
+            # verify the result
+            result = dict()
+            pp_file = None
+            for root, _, files in os.walk(tmpdir):
+                keys = [os.path.join(root, name) for name in files]
+                for key in keys:
+                    with open(key, 'r') as handle:
+                        result[key] = handle.readlines()
+                    if re.match(r'^(.*/)+clang(.*)\.i$', key):
+                        pp_file = key
+
+            # prepocessor file generated
+            self.assertUnderFailures(pp_file)
+            # info file generated and content dumped
+            info_file = pp_file + '.info.txt'
+            self.assertTrue(info_file in result)
+            self.assertEqual('Other Error\n', result[info_file][1])
+            self.assertEqual(uname_msg, result[info_file][3])
+            # error file generated and content dumped
+            error_file = pp_file + '.stderr.txt'
+            self.assertTrue(error_file in result)
+            self.assertEqual([error_msg], result[error_file])
+
+
+class AnalyzerTest(unittest.TestCase):
+
+    def test_nodebug_macros_appended(self):
+        def test(flags):
+            spy = Spy()
+            opts = {'flags': flags, 'force_debug': True}
+            self.assertEqual(spy.success,
+                             sut.filter_debug_flags(opts, spy.call))
+            return spy.arg['flags']
+
+        self.assertEqual(['-UNDEBUG'], test([]))
+        self.assertEqual(['-DNDEBUG', '-UNDEBUG'], test(['-DNDEBUG']))
+        self.assertEqual(['-DSomething', '-UNDEBUG'], test(['-DSomething']))
+
+    def test_set_language_fall_through(self):
+        def language(expected, input):
+            spy = Spy()
+            input.update({'compiler': 'c', 'file': 'test.c'})
+            self.assertEqual(spy.success, sut.language_check(input, spy.call))
+            self.assertEqual(expected, spy.arg['language'])
+
+        language('c',   {'language': 'c', 'flags': []})
+        language('c++', {'language': 'c++', 'flags': []})
+
+    def test_set_language_stops_on_not_supported(self):
+        spy = Spy()
+        input = {
+            'compiler': 'c',
+            'flags': [],
+            'file': 'test.java',
+            'language': 'java'
+        }
+        self.assertIsNone(sut.language_check(input, spy.call))
+        self.assertIsNone(spy.arg)
+
+    def test_set_language_sets_flags(self):
+        def flags(expected, input):
+            spy = Spy()
+            input.update({'compiler': 'c', 'file': 'test.c'})
+            self.assertEqual(spy.success, sut.language_check(input, spy.call))
+            self.assertEqual(expected, spy.arg['flags'])
+
+        flags(['-x', 'c'],   {'language': 'c', 'flags': []})
+        flags(['-x', 'c++'], {'language': 'c++', 'flags': []})
+
+    def test_set_language_from_filename(self):
+        def language(expected, input):
+            spy = Spy()
+            input.update({'language': None, 'flags': []})
+            self.assertEqual(spy.success, sut.language_check(input, spy.call))
+            self.assertEqual(expected, spy.arg['language'])
+
+        language('c',   {'file': 'file.c',   'compiler': 'c'})
+        language('c++', {'file': 'file.c',   'compiler': 'c++'})
+        language('c++', {'file': 'file.cxx', 'compiler': 'c'})
+        language('c++', {'file': 'file.cxx', 'compiler': 'c++'})
+        language('c++', {'file': 'file.cpp', 'compiler': 'c++'})
+        language('c-cpp-output',   {'file': 'file.i', 'compiler': 'c'})
+        language('c++-cpp-output', {'file': 'file.i', 'compiler': 'c++'})
+
+    def test_arch_loop_sets_flags(self):
+        def flags(archs):
+            spy = Spy()
+            input = {'flags': [], 'arch_list': archs}
+            sut.arch_check(input, spy.call)
+            return spy.arg['flags']
+
+        self.assertEqual([], flags([]))
+        self.assertEqual(['-arch', 'i386'], flags(['i386']))
+        self.assertEqual(['-arch', 'i386'], flags(['i386', 'ppc']))
+        self.assertEqual(['-arch', 'sparc'], flags(['i386', 'sparc']))
+
+    def test_arch_loop_stops_on_not_supported(self):
+        def stop(archs):
+            spy = Spy()
+            input = {'flags': [], 'arch_list': archs}
+            self.assertIsNone(sut.arch_check(input, spy.call))
+            self.assertIsNone(spy.arg)
+
+        stop(['ppc'])
+        stop(['ppc64'])
+
+
+ at sut.require([])
+def method_without_expecteds(opts):
+    return 0
+
+
+ at sut.require(['this', 'that'])
+def method_with_expecteds(opts):
+    return 0
+
+
+ at sut.require([])
+def method_exception_from_inside(opts):
+    raise Exception('here is one')
+
+
+class RequireDecoratorTest(unittest.TestCase):
+
+    def test_method_without_expecteds(self):
+        self.assertEqual(method_without_expecteds(dict()), 0)
+        self.assertEqual(method_without_expecteds({}), 0)
+        self.assertEqual(method_without_expecteds({'this': 2}), 0)
+        self.assertEqual(method_without_expecteds({'that': 3}), 0)
+
+    def test_method_with_expecteds(self):
+        self.assertRaises(KeyError, method_with_expecteds, dict())
+        self.assertRaises(KeyError, method_with_expecteds, {})
+        self.assertRaises(KeyError, method_with_expecteds, {'this': 2})
+        self.assertRaises(KeyError, method_with_expecteds, {'that': 3})
+        self.assertEqual(method_with_expecteds({'this': 0, 'that': 3}), 0)
+
+    def test_method_exception_not_caught(self):
+        self.assertRaises(Exception, method_exception_from_inside, dict())

Modified: cfe/trunk/tools/scan-build-py/tests/unit/test_report.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/tests/unit/test_report.py?rev=299759&r1=299758&r2=299759&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build-py/tests/unit/test_report.py (original)
+++ cfe/trunk/tools/scan-build-py/tests/unit/test_report.py Fri Apr  7 06:04:49 2017
@@ -75,7 +75,7 @@ class ParseFileTest(unittest.TestCase):
                          'file.i.stderr.txt')
 
     def test_parse_real_crash(self):
-        import libscanbuild.runner as sut2
+        import libscanbuild.analyze as sut2
         import re
         with libear.TemporaryDirectory() as tmpdir:
             filename = os.path.join(tmpdir, 'test.c')

Removed: cfe/trunk/tools/scan-build-py/tests/unit/test_runner.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/tests/unit/test_runner.py?rev=299758&view=auto
==============================================================================
--- cfe/trunk/tools/scan-build-py/tests/unit/test_runner.py (original)
+++ cfe/trunk/tools/scan-build-py/tests/unit/test_runner.py (removed)
@@ -1,321 +0,0 @@
-# -*- coding: utf-8 -*-
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-
-import libear
-import libscanbuild.runner as sut
-import unittest
-import re
-import os
-import os.path
-
-
-class FilteringFlagsTest(unittest.TestCase):
-
-    def test_language_captured(self):
-        def test(flags):
-            cmd = ['clang', '-c', 'source.c'] + flags
-            opts = sut.classify_parameters(cmd)
-            return opts['language']
-
-        self.assertEqual(None, test([]))
-        self.assertEqual('c', test(['-x', 'c']))
-        self.assertEqual('cpp', test(['-x', 'cpp']))
-
-    def test_arch(self):
-        def test(flags):
-            cmd = ['clang', '-c', 'source.c'] + flags
-            opts = sut.classify_parameters(cmd)
-            return opts['arch_list']
-
-        self.assertEqual([], test([]))
-        self.assertEqual(['mips'], test(['-arch', 'mips']))
-        self.assertEqual(['mips', 'i386'],
-                         test(['-arch', 'mips', '-arch', 'i386']))
-
-    def assertFlagsChanged(self, expected, flags):
-        cmd = ['clang', '-c', 'source.c'] + flags
-        opts = sut.classify_parameters(cmd)
-        self.assertEqual(expected, opts['flags'])
-
-    def assertFlagsUnchanged(self, flags):
-        self.assertFlagsChanged(flags, flags)
-
-    def assertFlagsFiltered(self, flags):
-        self.assertFlagsChanged([], flags)
-
-    def test_optimalizations_pass(self):
-        self.assertFlagsUnchanged(['-O'])
-        self.assertFlagsUnchanged(['-O1'])
-        self.assertFlagsUnchanged(['-Os'])
-        self.assertFlagsUnchanged(['-O2'])
-        self.assertFlagsUnchanged(['-O3'])
-
-    def test_include_pass(self):
-        self.assertFlagsUnchanged([])
-        self.assertFlagsUnchanged(['-include', '/usr/local/include'])
-        self.assertFlagsUnchanged(['-I.'])
-        self.assertFlagsUnchanged(['-I', '.'])
-        self.assertFlagsUnchanged(['-I/usr/local/include'])
-        self.assertFlagsUnchanged(['-I', '/usr/local/include'])
-        self.assertFlagsUnchanged(['-I/opt', '-I', '/opt/otp/include'])
-        self.assertFlagsUnchanged(['-isystem', '/path'])
-        self.assertFlagsUnchanged(['-isystem=/path'])
-
-    def test_define_pass(self):
-        self.assertFlagsUnchanged(['-DNDEBUG'])
-        self.assertFlagsUnchanged(['-UNDEBUG'])
-        self.assertFlagsUnchanged(['-Dvar1=val1', '-Dvar2=val2'])
-        self.assertFlagsUnchanged(['-Dvar="val ues"'])
-
-    def test_output_filtered(self):
-        self.assertFlagsFiltered(['-o', 'source.o'])
-
-    def test_some_warning_filtered(self):
-        self.assertFlagsFiltered(['-Wall'])
-        self.assertFlagsFiltered(['-Wnoexcept'])
-        self.assertFlagsFiltered(['-Wreorder', '-Wunused', '-Wundef'])
-        self.assertFlagsUnchanged(['-Wno-reorder', '-Wno-unused'])
-
-    def test_compile_only_flags_pass(self):
-        self.assertFlagsUnchanged(['-std=C99'])
-        self.assertFlagsUnchanged(['-nostdinc'])
-        self.assertFlagsUnchanged(['-isystem', '/image/debian'])
-        self.assertFlagsUnchanged(['-iprefix', '/usr/local'])
-        self.assertFlagsUnchanged(['-iquote=me'])
-        self.assertFlagsUnchanged(['-iquote', 'me'])
-
-    def test_compile_and_link_flags_pass(self):
-        self.assertFlagsUnchanged(['-fsinged-char'])
-        self.assertFlagsUnchanged(['-fPIC'])
-        self.assertFlagsUnchanged(['-stdlib=libc++'])
-        self.assertFlagsUnchanged(['--sysroot', '/'])
-        self.assertFlagsUnchanged(['-isysroot', '/'])
-
-    def test_some_flags_filtered(self):
-        self.assertFlagsFiltered(['-g'])
-        self.assertFlagsFiltered(['-fsyntax-only'])
-        self.assertFlagsFiltered(['-save-temps'])
-        self.assertFlagsFiltered(['-init', 'my_init'])
-        self.assertFlagsFiltered(['-sectorder', 'a', 'b', 'c'])
-
-
-class Spy(object):
-    def __init__(self):
-        self.arg = None
-        self.success = 0
-
-    def call(self, params):
-        self.arg = params
-        return self.success
-
-
-class RunAnalyzerTest(unittest.TestCase):
-
-    @staticmethod
-    def run_analyzer(content, failures_report):
-        with libear.TemporaryDirectory() as tmpdir:
-            filename = os.path.join(tmpdir, 'test.cpp')
-            with open(filename, 'w') as handle:
-                handle.write(content)
-
-            opts = {
-                'clang': 'clang',
-                'directory': os.getcwd(),
-                'flags': [],
-                'direct_args': [],
-                'file': filename,
-                'output_dir': tmpdir,
-                'output_format': 'plist',
-                'output_failures': failures_report
-            }
-            spy = Spy()
-            result = sut.run_analyzer(opts, spy.call)
-            return (result, spy.arg)
-
-    def test_run_analyzer(self):
-        content = "int div(int n, int d) { return n / d; }"
-        (result, fwds) = RunAnalyzerTest.run_analyzer(content, False)
-        self.assertEqual(None, fwds)
-        self.assertEqual(0, result['exit_code'])
-
-    def test_run_analyzer_crash(self):
-        content = "int div(int n, int d) { return n / d }"
-        (result, fwds) = RunAnalyzerTest.run_analyzer(content, False)
-        self.assertEqual(None, fwds)
-        self.assertEqual(1, result['exit_code'])
-
-    def test_run_analyzer_crash_and_forwarded(self):
-        content = "int div(int n, int d) { return n / d }"
-        (_, fwds) = RunAnalyzerTest.run_analyzer(content, True)
-        self.assertEqual(1, fwds['exit_code'])
-        self.assertTrue(len(fwds['error_output']) > 0)
-
-
-class ReportFailureTest(unittest.TestCase):
-
-    def assertUnderFailures(self, path):
-        self.assertEqual('failures', os.path.basename(os.path.dirname(path)))
-
-    def test_report_failure_create_files(self):
-        with libear.TemporaryDirectory() as tmpdir:
-            # create input file
-            filename = os.path.join(tmpdir, 'test.c')
-            with open(filename, 'w') as handle:
-                handle.write('int main() { return 0')
-            uname_msg = ' '.join(os.uname()) + os.linesep
-            error_msg = 'this is my error output'
-            # execute test
-            opts = {
-                'clang': 'clang',
-                'directory': os.getcwd(),
-                'flags': [],
-                'file': filename,
-                'output_dir': tmpdir,
-                'language': 'c',
-                'error_type': 'other_error',
-                'error_output': error_msg,
-                'exit_code': 13
-            }
-            sut.report_failure(opts)
-            # verify the result
-            result = dict()
-            pp_file = None
-            for root, _, files in os.walk(tmpdir):
-                keys = [os.path.join(root, name) for name in files]
-                for key in keys:
-                    with open(key, 'r') as handle:
-                        result[key] = handle.readlines()
-                    if re.match(r'^(.*/)+clang(.*)\.i$', key):
-                        pp_file = key
-
-            # prepocessor file generated
-            self.assertUnderFailures(pp_file)
-            # info file generated and content dumped
-            info_file = pp_file + '.info.txt'
-            self.assertTrue(info_file in result)
-            self.assertEqual('Other Error\n', result[info_file][1])
-            self.assertEqual(uname_msg, result[info_file][3])
-            # error file generated and content dumped
-            error_file = pp_file + '.stderr.txt'
-            self.assertTrue(error_file in result)
-            self.assertEqual([error_msg], result[error_file])
-
-
-class AnalyzerTest(unittest.TestCase):
-
-    def test_nodebug_macros_appended(self):
-        def test(flags):
-            spy = Spy()
-            opts = {'flags': flags, 'force_debug': True}
-            self.assertEqual(spy.success,
-                             sut.filter_debug_flags(opts, spy.call))
-            return spy.arg['flags']
-
-        self.assertEqual(['-UNDEBUG'], test([]))
-        self.assertEqual(['-DNDEBUG', '-UNDEBUG'], test(['-DNDEBUG']))
-        self.assertEqual(['-DSomething', '-UNDEBUG'], test(['-DSomething']))
-
-    def test_set_language_fall_through(self):
-        def language(expected, input):
-            spy = Spy()
-            input.update({'compiler': 'c', 'file': 'test.c'})
-            self.assertEqual(spy.success, sut.language_check(input, spy.call))
-            self.assertEqual(expected, spy.arg['language'])
-
-        language('c',   {'language': 'c', 'flags': []})
-        language('c++', {'language': 'c++', 'flags': []})
-
-    def test_set_language_stops_on_not_supported(self):
-        spy = Spy()
-        input = {
-            'compiler': 'c',
-            'flags': [],
-            'file': 'test.java',
-            'language': 'java'
-        }
-        self.assertIsNone(sut.language_check(input, spy.call))
-        self.assertIsNone(spy.arg)
-
-    def test_set_language_sets_flags(self):
-        def flags(expected, input):
-            spy = Spy()
-            input.update({'compiler': 'c', 'file': 'test.c'})
-            self.assertEqual(spy.success, sut.language_check(input, spy.call))
-            self.assertEqual(expected, spy.arg['flags'])
-
-        flags(['-x', 'c'],   {'language': 'c', 'flags': []})
-        flags(['-x', 'c++'], {'language': 'c++', 'flags': []})
-
-    def test_set_language_from_filename(self):
-        def language(expected, input):
-            spy = Spy()
-            input.update({'language': None, 'flags': []})
-            self.assertEqual(spy.success, sut.language_check(input, spy.call))
-            self.assertEqual(expected, spy.arg['language'])
-
-        language('c',   {'file': 'file.c',   'compiler': 'c'})
-        language('c++', {'file': 'file.c',   'compiler': 'c++'})
-        language('c++', {'file': 'file.cxx', 'compiler': 'c'})
-        language('c++', {'file': 'file.cxx', 'compiler': 'c++'})
-        language('c++', {'file': 'file.cpp', 'compiler': 'c++'})
-        language('c-cpp-output',   {'file': 'file.i', 'compiler': 'c'})
-        language('c++-cpp-output', {'file': 'file.i', 'compiler': 'c++'})
-
-    def test_arch_loop_sets_flags(self):
-        def flags(archs):
-            spy = Spy()
-            input = {'flags': [], 'arch_list': archs}
-            sut.arch_check(input, spy.call)
-            return spy.arg['flags']
-
-        self.assertEqual([], flags([]))
-        self.assertEqual(['-arch', 'i386'], flags(['i386']))
-        self.assertEqual(['-arch', 'i386'], flags(['i386', 'ppc']))
-        self.assertEqual(['-arch', 'sparc'], flags(['i386', 'sparc']))
-
-    def test_arch_loop_stops_on_not_supported(self):
-        def stop(archs):
-            spy = Spy()
-            input = {'flags': [], 'arch_list': archs}
-            self.assertIsNone(sut.arch_check(input, spy.call))
-            self.assertIsNone(spy.arg)
-
-        stop(['ppc'])
-        stop(['ppc64'])
-
-
- at sut.require([])
-def method_without_expecteds(opts):
-    return 0
-
-
- at sut.require(['this', 'that'])
-def method_with_expecteds(opts):
-    return 0
-
-
- at sut.require([])
-def method_exception_from_inside(opts):
-    raise Exception('here is one')
-
-
-class RequireDecoratorTest(unittest.TestCase):
-
-    def test_method_without_expecteds(self):
-        self.assertEqual(method_without_expecteds(dict()), 0)
-        self.assertEqual(method_without_expecteds({}), 0)
-        self.assertEqual(method_without_expecteds({'this': 2}), 0)
-        self.assertEqual(method_without_expecteds({'that': 3}), 0)
-
-    def test_method_with_expecteds(self):
-        self.assertRaises(KeyError, method_with_expecteds, dict())
-        self.assertRaises(KeyError, method_with_expecteds, {})
-        self.assertRaises(KeyError, method_with_expecteds, {'this': 2})
-        self.assertRaises(KeyError, method_with_expecteds, {'that': 3})
-        self.assertEqual(method_with_expecteds({'this': 0, 'that': 3}), 0)
-
-    def test_method_exception_not_caught(self):
-        self.assertRaises(Exception, method_exception_from_inside, dict())




More information about the cfe-commits mailing list