class ContextTimeController(Thread):
    """
    Executes a function in a new thread that uses a fake datetime.
    This allows a test to manipulate time as perceived by the target function.
    """
    """Initializer

    Behaves exactly like Thread.__init__ except that daemon defaults to
    True.

    target -- function to call in the thread
    parent_context -- inherit dependencies injected into this context
    """
    def __init__(self, target, *args, parent_context, **kwargs):
        super().__init__(target=target, **kwargs)
        self.exception_caught = None
        self.value_returned = None
        self.fake_datetime = FakeDatetime()
        self._context = parent_context.spawn()
        self._target = target

    """Advance the fake clock by the given interval

    Raises a RuntimeError if the thread has not been started.
    Keyword arguments can be anything accepted by datetime.timedelta.
    """

    def advance(self, **kwargs):
        if not self.ident:
            raise RuntimeError(
                "The thread must be started before advancing time")
        self.fake_datetime.advance(**kwargs)

    def run(self):
        self._context.inject(datetime, self.fake_datetime)
        self._context.attach_to_thread(self)
        try:
            self.value_returned = self._target()
        except Exception as e:
            self.exception_caught = e
Exemple #2
0
 def test_can_advance_by_arbitrary_days(self):
     fake = FakeDatetime()
     days = 8
     start = fake.now()
     fake.advance(days=days)
     expect(fake.now()).to(equal(start + timedelta(days=days)))
Exemple #3
0
 def test_can_advance_by_arbitrary_hours(self):
     fake = FakeDatetime()
     hours = 23
     start = fake.now()
     fake.advance(hours=hours)
     expect(fake.now()).to(equal(start + timedelta(hours=hours)))
Exemple #4
0
 def test_can_advance_by_arbitrary_minutes(self):
     fake = FakeDatetime()
     mins = 4
     start = fake.now()
     fake.advance(minutes=mins)
     expect(fake.now()).to(equal(start + timedelta(minutes=mins)))
Exemple #5
0
 def test_can_advance_by_arbitrary_sec(self):
     fake = FakeDatetime()
     sec = 235
     start = fake.now()
     fake.advance(seconds=sec)
     expect(fake.now()).to(equal(start + timedelta(seconds=sec)))
Exemple #6
0
 def test_can_advance_by_arbitrary_ms(self):
     fake = FakeDatetime()
     ms = 235
     start = fake.now()
     fake.advance(milliseconds=ms)
     expect(fake.now()).to(equal(start + timedelta(milliseconds=ms)))