# Path: guild/actor.py
# class Actor(ActorMixin, _Thread):
#     daemon = True
# 
#     def __init__(self):
#         self.killflag = False
#         super(Actor, self).__init__()
# 
#     def run(self):
#         self.process_start()
#         self.process()
#         try:
#             gen = self.main
#         except AttributeError:
#             try:
#                 gen = self.gen_process
#             except AttributeError:
#                 gen = None
# 
#         if gen:
#             # NB next line looks at the code object, and checks a flag
#             if inspect.isgeneratorfunction(gen):
#                 g = gen()
#             else:
#                 function_name = gen.__self__.__class__.__name__ +"."+gen.__name__
#                 source_ref = "(%s, line: %d)" % (gen.__func__.__code__.co_filename, gen.__func__.__code__.co_firstlineno)
#                 warning = "Function %s %s must be a generator" % (function_name, source_ref)
#                 raise ValueError(warning)
#         else:
#             g = None
# 
#         while not self.killflag:
# 
#             while (self.F_inbound or self.inbound or self.core):
#                 self._actor_do_queued()
# 
#             if not self._actor_do_queued():
#                 if g is None:
#                     time.sleep(0.01)
#             if g:
#                 try:
#                     next(g)
#                 except StopIteration:
#                     # Print("Generator Exited")
#                     self.stop()
#                     g = None
#         self.onStop()
#         if g:
#             try:
#                 g.throw(StopIteration)
#             except StopIteration:
#                 pass
# 
#     def stop(self):
#         self.killflag = True
# 
# def actor_method(method):
#     return ("ACTORMETHOD", method)
# 
# def actor_function(timeout=None):
#     # Just used as "@actor_function -- ie the common case"
#     if callable(timeout):
#         return actor_function(None)(timeout)
# 
#     def dec(fn):
#         return ("ACTORFUNCTION", fn, timeout)
# 
#     return dec
# 
# class ActorNotStartedException(Exception): #NOTE: Overview documented
#     pass


from behave import given, when, then, step
from guild.actor import Actor, actor_method, actor_function, ActorNotStartedException
from hamcrest import *
import time
def step_impl(context):
    assert_that(False, equal_to(context.value.is_alive()))

@when(u'we do start it')
def step_impl(context):
    context.value.go()
    assert_that(True, equal_to(context.value.is_alive()))


@then(u'that combine actor function doesn\'t work')
def step_impl(context):
    assert_that(context.value.combine, raises(ActorNotStartedException))

@then(u'that fails actor function raises an exception in the caller thread')
def step_impl(context):
    assert_that(context.value.fails, raises(UserDefinedException))

@then(u'that increment actor method doesn\'t work')
def step_impl(context):
    context.value.increment()
    time.sleep(0.01) # Microsleep to allow context.value.increment a chance to run
    v = context.value.a, context.value.b, context.value.c
    assert_that(v, equal_to((6,5,4)))


@then(u'that combine actor function works as expected')
def step_impl(context):
    assert_that((6,5,4), equal_to(context.value.combine()))

@then(u'that increment actor method works asynchronously as expected')

# Path: guild/actor.py
# class Actor(ActorMixin, _Thread):
#     daemon = True
# 
#     def __init__(self):
#         self.killflag = False
#         super(Actor, self).__init__()
# 
#     def run(self):
#         self.process_start()
#         self.process()
#         try:
#             gen = self.main
#         except AttributeError:
#             try:
#                 gen = self.gen_process
#             except AttributeError:
#                 gen = None
# 
#         if gen:
#             # NB next line looks at the code object, and checks a flag
#             if inspect.isgeneratorfunction(gen):
#                 g = gen()
#             else:
#                 function_name = gen.__self__.__class__.__name__ +"."+gen.__name__
#                 source_ref = "(%s, line: %d)" % (gen.__func__.__code__.co_filename, gen.__func__.__code__.co_firstlineno)
#                 warning = "Function %s %s must be a generator" % (function_name, source_ref)
#                 raise ValueError(warning)
#         else:
#             g = None
# 
#         while not self.killflag:
# 
#             while (self.F_inbound or self.inbound or self.core):
#                 self._actor_do_queued()
# 
#             if not self._actor_do_queued():
#                 if g is None:
#                     time.sleep(0.01)
#             if g:
#                 try:
#                     next(g)
#                 except StopIteration:
#                     # Print("Generator Exited")
#                     self.stop()
#                     g = None
#         self.onStop()
#         if g:
#             try:
#                 g.throw(StopIteration)
#             except StopIteration:
#                 pass
# 
#     def stop(self):
#         self.killflag = True
# 
# def actor_method(method):
#     return ("ACTORMETHOD", method)
# 
# def actor_function(timeout=None):
#     # Just used as "@actor_function -- ie the common case"
#     if callable(timeout):
#         return actor_function(None)(timeout)
# 
#     def dec(fn):
#         return ("ACTORFUNCTION", fn, timeout)
# 
#     return dec
# 
# class ActorNotStartedException(Exception): #NOTE: Overview documented
#     pass


# Path: features/steps/actor_feature_steps.py
from behave import given, when, then, step
from guild.actor import Actor, actor_method, actor_function, ActorNotStartedException
from hamcrest import *
import time

def step_impl(context):
    assert_that(False, equal_to(context.value.is_alive()))

@when(u'we do start it')
def step_impl(context):
    context.value.go()
    assert_that(True, equal_to(context.value.is_alive()))


@then(u'that combine actor function doesn\'t work')
def step_impl(context):
    assert_that(context.value.combine, raises(ActorNotStartedException))

@then(u'that fails actor function raises an exception in the caller thread')
def step_impl(context):
    assert_that(context.value.fails, raises(UserDefinedException))

@then(u'that increment actor method doesn\'t work')
def step_impl(context):
    context.value.increment()
    time.sleep(0.01) # Microsleep to allow context.value.increment a chance to run
    v = context.value.a, context.value.b, context.value.c
    assert_that(v, equal_to((6,5,4)))


@then(u'that combine actor function works as expected')
def step_impl(context):
    assert_that((6,5,4), equal_to(context.value.combine()))

@then(u'that increment actor method works asynchronously as expected')

def step_impl(context):