15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Copyright (C) 2010 Apple Inc. All rights reserved.
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# modification, are permitted provided that the following conditions
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# are met:
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 1.  Redistributions of source code must retain the above copyright
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#     notice, this list of conditions and the following disclaimer.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 2.  Redistributions in binary form must reproduce the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#     notice, this list of conditions and the following disclaimer in the
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#     documentation and/or other materials provided with the distribution.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import logging
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)_log = logging.getLogger(__name__)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def skip_if(klass, condition, message=None, logger=None):
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    """Makes all test_* methods in a given class no-ops if the given condition
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    is False. Backported from Python 3.1+'s unittest.skipIf decorator."""
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if not logger:
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logger = _log
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if not condition:
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return klass
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for name in dir(klass):
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        attr = getattr(klass, name)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if not callable(attr):
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if not name.startswith('test_'):
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setattr(klass, name, _skipped_method(attr, message, logger))
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    klass._printed_skipped_message = False
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return klass
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def _skipped_method(method, message, logger):
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    def _skip(*args):
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if method.im_class._printed_skipped_message:
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        method.im_class._printed_skipped_message = True
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logger.info('Skipping %s.%s: %s' % (method.__module__, method.im_class.__name__, message))
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return _skip
53