diff --git a/pyvows/runner/gevent.py b/pyvows/runner/gevent.py index 4314225..93c8aa4 100644 --- a/pyvows/runner/gevent.py +++ b/pyvows/runner/gevent.py @@ -127,7 +127,8 @@ def _run_setup_and_topic(ctx_obj, index): # Find & run topic function if not hasattr(ctx_obj, 'topic'): # ctx_obj has no topic - return ctx_obj._get_first_available_topic(index) + ctx_obj.topic_value = ctx_obj._get_first_available_topic(index) + return ctx_obj.topic_value try: topic_func = ctx_obj.topic @@ -139,11 +140,20 @@ def _run_setup_and_topic(ctx_obj, index): return None topic = topic_func(*topic_list) + + # setup generated topics if needed + is_generator = inspect.isgenerator(topic) + if is_generator: + ctx_obj.generated_topic = True + topic = ctx_obj.topic_value = list(topic) + else: + ctx_obj.topic_value = topic + ctx_result['topic_elapsed'] = elapsed(start_time) return topic except SkipTest: raise - except Exception: + except: raise VowsTopicError('topic', sys.exc_info()) def _run_tests(topic): @@ -186,19 +196,7 @@ def _run_vows_and_subcontexts(topic, index=-1, enumerated=False): ) teardown_blockers.append(subctx_greenlet) - # setup generated topics if needed - is_generator = inspect.isgenerator(topic) - if is_generator: - try: - ctx_obj.generated_topic = True - topic = ctx_obj.topic_value = list(topic) - except Exception: - # Actually getting the values from the generator may raise exception - raise VowsTopicError('topic', sys.exc_info()) - else: - ctx_obj.topic_value = topic - - if is_generator: + if ctx_obj.generated_topic and not ctx_result['error']: for index, topic_value in enumerate(topic): _run_vows_and_subcontexts(topic_value, index=index, enumerated=True) else: diff --git a/tests/errors_in_topic_vows.py b/tests/errors_in_topic_vows.py index 9256852..d77a6d8 100755 --- a/tests/errors_in_topic_vows.py +++ b/tests/errors_in_topic_vows.py @@ -11,6 +11,7 @@ from pyvows import Vows, expect from pyvows.runner import VowsRunner, SkipTest from pyvows.runner.executionplan import ExecutionPlanner +from pyvows.runner.abc import VowsTopicError # These tests demonstrate what happens when the topic function raises @@ -97,6 +98,19 @@ def topic(self): def results_are_not_successful(self, topic): expect(topic.successful).to_equal(False) + class WhenGeneratedTopicRaisesAnUnexpectedException(Vows.Context): + def topic(self): + dummySuite = {'dummySuite': set([WhenGeneratedTopicRaisesAnException])} + execution_plan = ExecutionPlanner(dummySuite, set(), set()).plan() + runner = VowsRunner(dummySuite, Vows.Context, None, None, execution_plan, False) + return runner.run() + + def results_are_not_successful(self, results): + expect(results.successful).to_equal(False) + + def the_tests_are_still_reported(self, results): + expect(results.contexts[0]['tests']).to_length(1) + class WhenTopicRaisesAnException(Vows.Context): functionsCalled = 0 @@ -139,3 +153,12 @@ def topic(self): class WhenTeardownRaisesException(Vows.Context): def teardown(self): raise Exception('omg') + + +class WhenGeneratedTopicRaisesAnException(Vows.Context): + def topic(self): + for i in xrange(1): + yield 1/i + + def one_vow(self): + raise Exception('This should not run')