# -*- coding: utf-8 -*-

import sys
from datetime import datetime, timedelta
import inspect

from mamba import error


class Example(object):

    def __init__(self, test, parent=None):
        self.test = test
        self.parent = parent
        self._error = None
        self._elapsed_time = timedelta(0)

    def run(self, reporter):
        self._begin = datetime.utcnow()
        reporter.example_started(self)
        try:
            self._run_inner_test(reporter)
        except Exception as exception:
            self._elapsed_time = datetime.utcnow() - self._begin
            self._set_failed()
            reporter.example_failed(self)

    def _run_inner_test(self, reporter):
        self.run_hook('before_each')
        self.test()
        self.run_hook('after_each')
        self._elapsed_time = datetime.utcnow() - self._begin
        reporter.example_passed(self)

    def _set_failed(self):
        type_, value, traceback = sys.exc_info()
        self.error = error.Error(value, traceback)

    def run_hook(self, hook):
        for parent in self._parents:
            parent.run_hook(hook)

    @property
    def _parents(self):
        parents = []
        parent = self.parent
        while parent:
            parents.append(parent)
            parent = parent.parent

        return reversed(parents)

    @property
    def elapsed_time(self):
        return self._elapsed_time

    @property
    def name(self):
        return self.test.__name__

    @property
    def source_line(self):
        return inspect.getsourcelines(self.test)[1]

    @property
    def failed(self):
        return self.error is not None

    @property
    def error(self):
        return self._error

    @error.setter
    def error(self, value):
        self._error = value

    @property
    def depth(self):
        if self.parent is None:
            return 0

        return self.parent.depth + 1


class PendingExample(Example):

    def run(self, reporter):
        reporter.example_pending(self)

@@ -350,71 +350,22 @@
 lf._
-begin = datetime.utcnow()%0A        reporter.example_started(self
+start(reporter
 )%0A  
@@ -479,90 +479,146 @@
 lf._
-elapsed_time = datetime.utcnow() - self._begin%0A            self._set_failed()%0A    
+set_failed()%0A        finally:%0A            self._finish(reporter)%0A%0A    def _start(self, reporter):%0A        self._begin = datetime.utcnow()%0A
     
@@ -638,20 +638,21 @@
 example_
-fail
+start
 ed(self)
@@ -791,105 +791,108 @@
 h')%0A
+%0A
     
-    self._elapsed_time = datetime.utcnow() - self._begin%0A        reporter.example_passed(self
+def run_hook(self, hook):%0A        for parent in self._parents:%0A            parent.run_hook(hook
 )%0A%0A 
@@ -1030,99 +1030,217 @@
 def 
-run_hook(self, hook):%0A        for parent in self._parents:%0A            parent.run_hook(hook
+_finish(self, reporter):%0A        self._elapsed_time = datetime.utcnow() - self._begin%0A        if not self.error:%0A            reporter.example_passed(self)%0A        else:%0A            reporter.example_failed(self
 )%0A%0A 

Refactor spec execution for stop the timer in one place