main
  1using System;
  2using System.Timers;
  3using developwithpassion.bdd.contexts;
  4using Gorilla.Commons.Testing;
  5using MoMoney.Service.Infrastructure.Threading;
  6using Rhino.Mocks;
  7
  8namespace momoney.service.infrastructure.threading
  9{
 10    [Concern(typeof (IntervalTimer))]
 11    public abstract class behaves_like_an_interval_timer : concerns_for<ITimer, IntervalTimer>
 12    {
 13        context c = () => { factory = the_dependency<ITimerFactory>(); };
 14
 15        protected static ITimerFactory factory;
 16    }
 17
 18    [Concern(typeof (IntervalTimer))]
 19    public class when_starting_a_timer_for_a_new_client : behaves_like_an_interval_timer
 20    {
 21        static ITimerClient client;
 22        static Timer timer;
 23
 24        it should_create_a_new_timer = () => factory.was_told_to(f => f.create_for(new TimeSpan(0, 10, 0)));
 25
 26        it should_start_the_timer = () => timer.was_told_to(t => t.Start());
 27
 28        context c = () =>
 29        {
 30            client = an<ITimerClient>();
 31            timer = dependency<Timer>();
 32
 33            factory.is_told_to(f => f.create_for(new TimeSpan(0, 10, 0))).it_will_return(timer);
 34        };
 35
 36        because b = () => sut.start_notifying(client, new TimeSpan(0, 10, 0));
 37    }
 38
 39    [Concern(typeof (IntervalTimer))]
 40    public class when_starting_a_timer_for_an_existing_client : behaves_like_an_interval_timer
 41    {
 42        it should_stop_the_previously_started_timer = () =>
 43        {
 44            first_timer.was_told_to(t => t.Stop());
 45            first_timer.was_told_to(t => t.Dispose());
 46        };
 47
 48        it should_start_a_new_timer = () => second_timer.was_told_to(t => t.Start());
 49
 50        context c = () =>
 51        {
 52            client = an<ITimerClient>();
 53            first_timer = dependency<Timer>();
 54            second_timer = dependency<Timer>();
 55
 56            factory.is_told_to(f => f.create_for(new TimeSpan(0, 1, 1))).it_will_return(first_timer);
 57            factory.is_told_to(f => f.create_for(new TimeSpan(0, 2, 2))).it_will_return(second_timer);
 58        };
 59
 60        because b = () =>
 61        {
 62            sut.start_notifying(client, new TimeSpan(0, 1, 1));
 63            sut.start_notifying(client, new TimeSpan(0, 2, 2));
 64        };
 65
 66        static ITimerClient client;
 67        static Timer first_timer;
 68        static Timer second_timer;
 69    }
 70
 71    [Concern(typeof (IntervalTimer))]
 72    public class when_a_timer_elapses : behaves_like_an_interval_timer
 73    {
 74        it should_notify_the_timer_client = () => client.was_told_to(c => c.notify());
 75
 76        static ITimerClient client;
 77        static Timer timer;
 78
 79        context c = () =>
 80        {
 81            client = an<ITimerClient>();
 82            timer = dependency<Timer>();
 83            factory.is_told_to(f => f.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(timer);
 84        };
 85
 86        because b = () =>
 87        {
 88            sut.start_notifying(client, new TimeSpan(0, 10, 0));
 89            timer.Raise(t => t.Elapsed += null, timer, null);
 90        };
 91    }
 92
 93    [Concern(typeof (IntervalTimer))]
 94    public class when_stopping_notifications_for_an_existing_timer_client : behaves_like_an_interval_timer
 95    {
 96        static ITimerClient client;
 97        static Timer timer;
 98
 99        it should_stop_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Stop());
100
101        it should_dispose_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Dispose());
102
103        context c = () =>
104        {
105            client = an<ITimerClient>();
106            timer = dependency<Timer>();
107
108            when_the(factory).is_told_to(t => t.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(
109                timer);
110        };
111
112        because b = () =>
113        {
114            sut.start_notifying(client, new TimeSpan(0, 0, 1));
115            sut.stop_notifying(client);
116        };
117    }
118
119    [Concern(typeof (IntervalTimer))]
120    public class when_attempting_to_stop_notification_for_a_client_that_doesnt_have_a_timer_started_for_it :
121        behaves_like_an_interval_timer
122    {
123        it should_not_blow_up = () => { };
124
125        context c = () => { client = an<ITimerClient>(); };
126
127        because b = () => sut.stop_notifying(client);
128
129        static ITimerClient client;
130    }
131}