# Path: actors/actor.py
# class Actor(object):
#     """ The base class implemented by all actors.
# 
#     :ivar context: Provides contextual information about this actor and the
#         current message. Only valid within this actor.
#     :vartype context: :class:`ActorContext`
# 
#     """
# 
#     context = None
# 
#     supervisor_strategy = default_supervisor_strategy
#     """ Class method. Override to provide custom supervisor behaviour for this actor. """
# 
#     def receive(self, message):
#         """
#         Override to provide the actor behaviour.
# 
#         :param message: The current message.
#         """
# 
#     def pre_start(self):
#         """ Called asynchronous before processing any messages. """
# 
#     def post_stop(self):
#         """ Called asynchronous after the actor has stopped. """
# 
#     def pre_restart(self):
#         """ Called on the failed actor before it's disposed of. """
# 
#     def post_restart(self):
#         """ Called on the newly created actor. """
# 
#     @property
#     def sender(self):
#         """ Alias for :attr:`self.context.sender`. """
#         return self.context.sender
# 
#     @property
#     def ref(self):
#         """ Alias for :attr:`self.context.self_ref`. """
#         return self.context.self_ref
# 
# Path: actors/system.py
# class ActorSystem(actors.internal.factory.ActorFactory):
# 
#     def __init__(self, system_dispatcher=None):
#         """
#         The actor system is responsible for creating, configuring and stopping actors and
#         dispatchers.
# 
#         Normally, only one system per application should be created.
# 
#         :param system_dispatcher: Override the dispatcher used by the system. This also acts as the
#             default dispatcher for new actors.
#         :type system_dispatcher: :class:`Dispatcher`
#         """
#         self._system_dispatcher = Dispatcher(Executor()) \
#             if system_dispatcher is None else system_dispatcher
#         self._dead_letters = _DeadLetterRef()
# 
#         self._terminate_promise = Promise()
# 
#         class Guardian(Actor):
#             def __init__(me):
#                 me._logger = logging.getLogger(__name__)
# 
#             def receive(me, message):
#                 me._logger.warning("User receive called. This should not be happen.")
# 
#             def post_stop(me):
#                 self._terminate_promise.complete(None)
# 
#         self._guardian = InternalRef(actors.internal.cell.Cell(Guardian,
#             dispatcher=self._system_dispatcher, system=self, parent=None))
#         self._guardian.send_system_message(Start)
# 
#         actors.internal.factory.ActorFactory.__init__(self, self, self._guardian)
# 
#     def terminate(self):
#         self._guardian.send_system_message(Terminate)
#         self._terminate_promise.future.get()
# 
#     @property
#     def dead_letters(self):
#         return self._dead_letters
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         self.terminate()
# 
# Path: actors/utils/ask.py
# def ask(actor, message):
#     """
#     Send a message to `actor` and return a :class:`Future` holding a possible
#     reply.
# 
#     To receive a result, the actor MUST send a reply to `sender`.
# 
#     :param actor:
#     :type actor: :class:`ActorRef`.
# 
#     :param message:
#     :type message: :type: Any
# 
#     :return: A future holding the result.
#     """
#     sender = PromiseActorRef()
#     actor.tell(message, sender)
#     return sender.promise.future
# 
# Path: tests/mock_compat.py



import time
from actors.actor import Actor
from actors.system import ActorSystem
from actors.utils.ask import ask
from ..mock_compat import Mock
# See the License for the specific language governing permissions and
# limitations under the License.



def test_system():
    class Test(Actor):
        def receive(self, message):
            self.context.sender.tell(message)

    with ActorSystem() as system:
        actor = system.actor_of(Test)
        message = object()
        reply = ask(actor, message)
        assert reply.get(timeout=1) is message


def test_behaviour():
    with ActorSystem() as system:
        behaviour = Mock()
        actor = system.actor_of(behaviour=behaviour)
        message = object()
        actor.tell(message)
        time.sleep(1)
        behaviour.assert_called_once_with(message)


def test_self_stop():
    on_post_stop = Mock()


# Path: actors/actor.py
# class Actor(object):
#     """ The base class implemented by all actors.
# 
#     :ivar context: Provides contextual information about this actor and the
#         current message. Only valid within this actor.
#     :vartype context: :class:`ActorContext`
# 
#     """
# 
#     context = None
# 
#     supervisor_strategy = default_supervisor_strategy
#     """ Class method. Override to provide custom supervisor behaviour for this actor. """
# 
#     def receive(self, message):
#         """
#         Override to provide the actor behaviour.
# 
#         :param message: The current message.
#         """
# 
#     def pre_start(self):
#         """ Called asynchronous before processing any messages. """
# 
#     def post_stop(self):
#         """ Called asynchronous after the actor has stopped. """
# 
#     def pre_restart(self):
#         """ Called on the failed actor before it's disposed of. """
# 
#     def post_restart(self):
#         """ Called on the newly created actor. """
# 
#     @property
#     def sender(self):
#         """ Alias for :attr:`self.context.sender`. """
#         return self.context.sender
# 
#     @property
#     def ref(self):
#         """ Alias for :attr:`self.context.self_ref`. """
#         return self.context.self_ref
# 
# Path: actors/system.py
# class ActorSystem(actors.internal.factory.ActorFactory):
# 
#     def __init__(self, system_dispatcher=None):
#         """
#         The actor system is responsible for creating, configuring and stopping actors and
#         dispatchers.
# 
#         Normally, only one system per application should be created.
# 
#         :param system_dispatcher: Override the dispatcher used by the system. This also acts as the
#             default dispatcher for new actors.
#         :type system_dispatcher: :class:`Dispatcher`
#         """
#         self._system_dispatcher = Dispatcher(Executor()) \
#             if system_dispatcher is None else system_dispatcher
#         self._dead_letters = _DeadLetterRef()
# 
#         self._terminate_promise = Promise()
# 
#         class Guardian(Actor):
#             def __init__(me):
#                 me._logger = logging.getLogger(__name__)
# 
#             def receive(me, message):
#                 me._logger.warning("User receive called. This should not be happen.")
# 
#             def post_stop(me):
#                 self._terminate_promise.complete(None)
# 
#         self._guardian = InternalRef(actors.internal.cell.Cell(Guardian,
#             dispatcher=self._system_dispatcher, system=self, parent=None))
#         self._guardian.send_system_message(Start)
# 
#         actors.internal.factory.ActorFactory.__init__(self, self, self._guardian)
# 
#     def terminate(self):
#         self._guardian.send_system_message(Terminate)
#         self._terminate_promise.future.get()
# 
#     @property
#     def dead_letters(self):
#         return self._dead_letters
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         self.terminate()
# 
# Path: actors/utils/ask.py
# def ask(actor, message):
#     """
#     Send a message to `actor` and return a :class:`Future` holding a possible
#     reply.
# 
#     To receive a result, the actor MUST send a reply to `sender`.
# 
#     :param actor:
#     :type actor: :class:`ActorRef`.
# 
#     :param message:
#     :type message: :type: Any
# 
#     :return: A future holding the result.
#     """
#     sender = PromiseActorRef()
#     actor.tell(message, sender)
#     return sender.promise.future
# 
# Path: tests/mock_compat.py



# Path: tests/integration/test_system.py
import time
from actors.actor import Actor
from actors.system import ActorSystem
from actors.utils.ask import ask
from ..mock_compat import Mock

# See the License for the specific language governing permissions and
# limitations under the License.



def test_system():
    class Test(Actor):
        def receive(self, message):
            self.context.sender.tell(message)

    with ActorSystem() as system:
        actor = system.actor_of(Test)
        message = object()
        reply = ask(actor, message)
        assert reply.get(timeout=1) is message


def test_behaviour():
    with ActorSystem() as system:
        behaviour = Mock()
        actor = system.actor_of(behaviour=behaviour)
        message = object()
        actor.tell(message)
        time.sleep(1)
        behaviour.assert_called_once_with(message)


def test_self_stop():
    on_post_stop = Mock()


    class Test(Actor):