<commit_before>#------------------------------------------------------------------------------
# Copyright (c) 2005-2013, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in /LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license.  The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#------------------------------------------------------------------------------
""" Trait assert mixin class to simplify test implementation for Trait
Classes.

"""

import contextlib
import threading
import sys
import warnings

from traits.api import (Any, Event, HasStrictTraits, Instance, Int, List,
        Property, Str)
from traits.util.async_trait_wait import wait_for_condition

# Compatibility layer for Python 2.6: try loading unittest2
from traits import _py2to3
if sys.version_info[:2] == (2, 6):
    import unittest2 as unittest
else:
    import unittest


class _AssertTraitChangesContext(object):
    """ A context manager used to implement the trait change assert methods.

    Attributes
    ----------
    obj : HasTraits
        The HasTraits class instance who's class trait will change.

    xname : str
        The extended trait name of trait changes to listen to.

    count : int, optional
        The expected number of times the event should be fired. When None
        (default value) there is no check for the number of times the
        change event was fired.

    events : list of tuples
        A list with tuple elements containing the arguments of an
        `on_trait_change` event signature (<object>, <name>, <old>, <new>).

    Raises
    ------
    AssertionError :
          When the desired number of trait changed did not take place or when
          `count = None` and no trait change took place.

    """

    def __init__(self, obj, xname, count, test_case):
        """ Initialize the trait change assertion context manager.

        Parameters
        ----------
        obj : HasTraits
            The HasTraits class instance who's class trait will change.

        xname : str
            The extended trait name of trait changes to listen to.

        count : int, optional
            The expected number of times the event should be fired. When None
            (default value) there is no check for the number of times the
            change event was fired.

        test_case : TestCase
            A unittest TestCase where to raise the failureException if
            necessary.

        Notes
        -----
        - Checking if the provided xname corresponds to valid traits in
          the class is not implemented yet.

        """
        self.obj = obj
        self.xname = xname
        self.count = count
        self.event = None
        self.events = []
        self.failureException = test_case.failureException

    def _listener(self, obj, name, old, new):
        """ Dummy trait listener.
        """
        self.event = (obj, name, old, new)
        self.events.append(self.event)

    def __enter__(self):
        """ Bind the trait listener.
        """
        self.obj.on_trait_change(self._listener, self.xname)
        return self

    def __exit__(self, exc_type, exc_value, tb):
        """ Remove the trait listener.
        """
        if exc_type is not None:
            return False

        self.obj.on_trait_change(self._listener, self.xname, remove=True)
        if self.count is not None and len(self.events) != self.count:
            msg = 'Change event for {0} was fired {1} times instead of {2}'
            items = self.xname, len(self.events), self.count
            raise self.failureException(msg.format(*items))
        elif self.count is None and not self.events:
            msg = 'A change event was not fired for: {0}'.format(self.xname)
            raise self.failureException(msg)
        return False


@contextlib.contextmanager
def reverse_assertion(context, msg):
    context.__enter__()
    try:
        yield context
    finally:
        try:
            context.__exit__(None, None, None)
        except AssertionError:
            pass
        else:
            raise context.failureException(msg)


class _TraitsChangeCollector(HasStrictTraits):
    """ Class allowing thread-safe recording of events.
    """
    # The object we're listening to.
    obj = Any

    # The (possibly extended) trait name.
    trait = Str

    # Read-only event count.
    event_count = Property(Int)

    # Event that's triggered when the event count is updated.
    event_count_updated = Event

    # Private list of events.
    events = List(Any)

    # Lock used to allow access to events by multiple threads
    # simultaneously.
    _lock = Instance(threading.Lock, ())

    def start_collecting(self):
        self.obj.on_trait_change(
            self._event_handler,
            self.trait,
        )

    def stop_collecting(self):
        self.obj.on_trait_change(
            self._event_handler,
            self.trait,
            remove=True,
        )

    def _event_handler(self, new):
        with self._lock:
            self.events.append(new)
        self.event_count_updated = True

    def _get_event_count(self):
        """ Traits property getter.

        Thread-safe access to event count.

        """
        with self._lock:
            return len(self.events)


class UnittestTools(object):
    """ Mixin class to augment the unittest.TestCase class with useful trait
    related assert methods.

    """

    def assertTraitChanges(self, obj, trait, count=None, callableObj=None,
                           *args, **kwargs):
        """Assert an object trait changes a given number of times.
<commit_msg>Fix irrelevant spacing change (thanks, emacs).<commit_after>#------------------------------------------------------------------------------
# Copyright (c) 2005-2013, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in /LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license.  The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#------------------------------------------------------------------------------
""" Trait assert mixin class to simplify test implementation for Trait
Classes.

"""

import contextlib
import threading
import sys
import warnings

from traits.api import (Any, Event, HasStrictTraits, Instance, Int, List,
        Property, Str)
from traits.util.async_trait_wait import wait_for_condition

# Compatibility layer for Python 2.6: try loading unittest2
from traits import _py2to3
if sys.version_info[:2] == (2, 6):
    import unittest2 as unittest
else:
    import unittest


class _AssertTraitChangesContext(object):
    """ A context manager used to implement the trait change assert methods.

    Attributes
    ----------
    obj : HasTraits
        The HasTraits class instance who's class trait will change.

    xname : str
        The extended trait name of trait changes to listen to.

    count : int, optional
        The expected number of times the event should be fired. When None
        (default value) there is no check for the number of times the
        change event was fired.

    events : list of tuples
        A list with tuple elements containing the arguments of an
        `on_trait_change` event signature (<object>, <name>, <old>, <new>).

    Raises
    ------
    AssertionError :
          When the desired number of trait changed did not take place or when
          `count = None` and no trait change took place.

    """

    def __init__(self, obj, xname, count, test_case):
        """ Initialize the trait change assertion context manager.

        Parameters
        ----------
        obj : HasTraits
            The HasTraits class instance who's class trait will change.

        xname : str
            The extended trait name of trait changes to listen to.

        count : int, optional
            The expected number of times the event should be fired. When None
            (default value) there is no check for the number of times the
            change event was fired.

        test_case : TestCase
            A unittest TestCase where to raise the failureException if
            necessary.

        Notes
        -----
        - Checking if the provided xname corresponds to valid traits in
          the class is not implemented yet.

        """
        self.obj = obj
        self.xname = xname
        self.count = count
        self.event = None
        self.events = []
        self.failureException = test_case.failureException

    def _listener(self, obj, name, old, new):
        """ Dummy trait listener.
        """
        self.event = (obj, name, old, new)
        self.events.append(self.event)

    def __enter__(self):
        """ Bind the trait listener.
        """
        self.obj.on_trait_change(self._listener, self.xname)
        return self

    def __exit__(self, exc_type, exc_value, tb):
        """ Remove the trait listener.
        """
        if exc_type is not None:
            return False

        self.obj.on_trait_change(self._listener, self.xname, remove=True)
        if self.count is not None and len(self.events) != self.count:
            msg = 'Change event for {0} was fired {1} times instead of {2}'
            items = self.xname, len(self.events), self.count
            raise self.failureException(msg.format(*items))
        elif self.count is None and not self.events:
            msg = 'A change event was not fired for: {0}'.format(self.xname)
            raise self.failureException(msg)
        return False


@contextlib.contextmanager
def reverse_assertion(context, msg):
    context.__enter__()
    try:
        yield context
    finally:
        try:
            context.__exit__(None, None, None)
        except AssertionError:
            pass
        else:
            raise context.failureException(msg)


class _TraitsChangeCollector(HasStrictTraits):
    """ Class allowing thread-safe recording of events.
    """
    # The object we're listening to.
    obj = Any

    # The (possibly extended) trait name.
    trait = Str

    # Read-only event count.
    event_count = Property(Int)

    # Event that's triggered when the event count is updated.
    event_count_updated = Event

    # Private list of events.
    events = List(Any)

    # Lock used to allow access to events by multiple threads
    # simultaneously.
    _lock = Instance(threading.Lock, ())

    def start_collecting(self):
        self.obj.on_trait_change(
            self._event_handler,
            self.trait,
        )

    def stop_collecting(self):
        self.obj.on_trait_change(
            self._event_handler,
            self.trait,
            remove=True,
        )

    def _event_handler(self, new):
        with self._lock:
            self.events.append(new)
        self.event_count_updated = True

    def _get_event_count(self):
        """ Traits property getter.

        Thread-safe access to event count.

        """
        with self._lock:
            return len(self.events)


class UnittestTools(object):
    """ Mixin class to augment the unittest.TestCase class with useful trait
    related assert methods.

    """

    def assertTraitChanges(self, obj, trait, count=None, callableObj=None,
                           *args, **kwargs):
        """ Assert an object trait changes a given number of times.

{'fraction_non_alphanumeric': 0.10335386721423682, 'fraction_numerical': 0.003593429158110883, 'mean_word_length': 2.050365344467641, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3496625', 'n_tokens_mistral': 3074, 'n_tokens_neox': 2977, 'n_words': 1127}