public void TestDelayedRemoval()
        {
            using (ProgressTracker tracker = new ProgressTracker()) {
                Mock <IProgressTrackerSubscriber> mockedSubscriber = mockSubscriber(tracker);

                TestTransaction test1 = new TestTransaction();
                TestTransaction test2 = new TestTransaction();

                // Step 1
                {
                    mockedSubscriber.Expects.One.Method(
                        m => m.IdleStateChanged(null, null)
                        ).WithAnyArguments();

                    // This is optional. The tracker's progress is currently 0, so there's no need
                    // to send out superfluous progress reports.
                    mockedSubscriber.Expects.Between(0, 2).Method(m => m.ProgressChanged(null, null)).With(
                        new NMock.Matchers.TypeMatcher(typeof(ProgressTracker)),
                        new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.0f))
                        );

                    tracker.Track(test1);
                    tracker.Track(test2);
                }

                // Step 2
                {
                    mockedSubscriber.Expects.One.Method(m => m.ProgressChanged(null, null)).With(
                        new NMock.Matchers.TypeMatcher(typeof(ProgressTracker)),
                        new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.25f))
                        );

                    // Total progress should be 0.25 after this call (two transactions, one with
                    // 0% progress and one with 50% progress)
                    test1.ChangeProgress(0.5f);
                }

                // Step 3
                {
                    mockedSubscriber.Expects.One.Method(m => m.ProgressChanged(null, null)).With(
                        new NMock.Matchers.TypeMatcher(typeof(ProgressTracker)),
                        new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.75f))
                        );

                    // Total progress should be 0.75 after this call (one transaction at 100%,
                    // the other one at 50%). If the second transaction would be removed by the tracker,
                    // (which would be inappropriate!) the progress would falsely jump to 0.5 instead.
                    test2.End();
                }

                // Step 4
                {
                    mockedSubscriber.Expects.One.Method(m => m.ProgressChanged(null, null)).With(
                        new NMock.Matchers.TypeMatcher(typeof(ProgressTracker)),
                        new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(1.0f))
                        );

                    mockedSubscriber.Expects.One.Method(
                        m => m.IdleStateChanged(null, null)
                        ).WithAnyArguments();

                    test1.End();
                }
            }

            this.mockery.VerifyAllExpectationsHaveBeenMet();
        }
 public void TestMultiTrackedTransaction() {
   using(ProgressTracker tracker = new ProgressTracker()) {
     TestTransaction test = new TestTransaction();
     tracker.Track(test);
     tracker.Track(test);
     tracker.Track(test);
     tracker.Untrack(test);
     tracker.Untrack(test);
     tracker.Untrack(test);
   }
 }
    /// <summary>Mocks a subscriber for the events of a tracker</summary>
    /// <param name="tracker">Tracker to mock an event subscriber for</param>
    /// <returns>The mocked event subscriber</returns>
    private IProgressTrackerSubscriber mockSubscriber(ProgressTracker tracker) {
      IProgressTrackerSubscriber mockedSubscriber =
        this.mockery.NewMock<IProgressTrackerSubscriber>();

      tracker.AsyncIdleStateChanged +=
        new EventHandler<IdleStateEventArgs>(mockedSubscriber.IdleStateChanged);

      tracker.AsyncProgressChanged +=
        new EventHandler<ProgressReportEventArgs>(mockedSubscriber.ProgressChanged);

      return mockedSubscriber;
    }
    public void TestThrowOnUntrackNonTrackedTransaction() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        TestTransaction test1 = new TestTransaction();

        Assert.Throws<ArgumentException>(
          delegate() { tracker.Untrack(test1); }
        );
      }
    }
 public void TestProgressReportDuringUnsubscribe() {
   using(ProgressTracker tracker = new ProgressTracker()) {
     EvilTransaction evil = new EvilTransaction();
     tracker.Track(evil);
     tracker.Untrack(evil);
   }
 }
    public void TestIdleWithAutoRemoval() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        TestTransaction test1 = new TestTransaction();

        Assert.IsTrue(tracker.Idle);

        tracker.Track(test1);

        Assert.IsFalse(tracker.Idle);

        test1.End();

        Assert.IsTrue(tracker.Idle);
      }
    }
    public void TestProgressWithUntrack() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        TestTransaction test1 = new TestTransaction();
        TestTransaction test2 = new TestTransaction();
        tracker.Track(test1);
        tracker.Track(test2);

        Assert.AreEqual(0.0f, tracker.Progress);

        test1.ChangeProgress(0.5f);

        Assert.AreEqual(0.25f, tracker.Progress);

        tracker.Untrack(test2);

        Assert.AreEqual(0.5f, tracker.Progress);
      }
    }
    public void TestProvokedDeadlock() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        TestTransaction test1 = new TestTransaction();
        tracker.Track(test1);

        tracker.AsyncIdleStateChanged +=
          (EventHandler<IdleStateEventArgs>)delegate(object sender, IdleStateEventArgs arguments) {
          tracker.Track(Transaction.EndedDummy);
        };

        test1.End();
      }
    }
    public void TestEndedTransaction() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        IProgressTrackerSubscriber mockedSubscriber = mockSubscriber(tracker);

        TestTransaction test1 = new TestTransaction();

        // Step 1
        {
          Expect.Once.On(mockedSubscriber).
            Method("IdleStateChanged").
            WithAnyArguments();

          Expect.Between(0, 1).On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
                new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
                new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.0f))
              }
            );

          tracker.Track(test1);
        }

        // Step 2
        {
          Expect.Once.On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
                new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
                new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.5f))
              }
            );

          tracker.Track(Transaction.EndedDummy);
        }

        // Step 3
        {
          Expect.Once.On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
                new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
                new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(1.0f))
              }
            );

          Expect.Once.On(mockedSubscriber).
            Method("IdleStateChanged").
            WithAnyArguments();

          test1.End();
        }
      }

      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    public void TestSoleEndedTransaction() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        IProgressTrackerSubscriber mockedSubscriber = mockSubscriber(tracker);

        Expect.Never.On(mockedSubscriber).Method("IdleStateChanged").WithAnyArguments();
        Expect.Never.On(mockedSubscriber).Method("ProgressChanged").WithAnyArguments();

        tracker.Track(Transaction.EndedDummy);
      }

      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    public void TestDelayedRemoval() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        IProgressTrackerSubscriber mockedSubscriber = mockSubscriber(tracker);

        TestTransaction test1 = new TestTransaction();
        TestTransaction test2 = new TestTransaction();

        // Step 1
        {
          Expect.Once.On(mockedSubscriber).
            Method("IdleStateChanged").
            WithAnyArguments();

          // This is optional. The tracker's progress is currently 0, so there's no need
          // to send out superfluous progress reports.
          Expect.Between(0, 2).On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.0f))
            }
            );

          tracker.Track(test1);
          tracker.Track(test2);
        }

        // Step 2
        {
          Expect.Once.On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.25f))
            }
            );

          // Total progress should be 0.25 after this call (two transactions, one with
          // 0% progress and one with 50% progress)
          test1.ChangeProgress(0.5f);
        }

        // Step 3
        {
          Expect.Once.On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.75f))
            }
            );

          // Total progress should be 0.75 after this call (one transaction at 100%,
          // the other one at 50%). If the second transaction would be removed by the tracker,
          // (which would be inappropriate!) the progress would falsely jump to 0.5 instead.
          test2.End();
        }

        // Step 4
        {
          Expect.Once.On(mockedSubscriber).
            Method("ProgressChanged").
            With(
              new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(1.0f))
            }
            );

          Expect.Once.On(mockedSubscriber).
            Method("IdleStateChanged").
            WithAnyArguments();

          test1.End();
        }
      }

      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    public void TestSummedProgress() {
      using(ProgressTracker tracker = new ProgressTracker()) {
        IProgressTrackerSubscriber mockedSubscriber = mockSubscriber(tracker);

        TestTransaction test1 = new TestTransaction();
        TestTransaction test2 = new TestTransaction();

        // Step 1
        {
          Expect.Once.On(mockedSubscriber).Method("IdleStateChanged").WithAnyArguments();

          // Since the progress is already at 0, these redundant reports are optional
          Expect.Between(0, 2).On(mockedSubscriber).Method("ProgressChanged").With(
            new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.0f))
            }
          );

          tracker.Track(test1);
          tracker.Track(test2);
        }

        // Step 2
        {
          Expect.Once.On(mockedSubscriber).Method("ProgressChanged").With(
            new Matcher[] {
              new NMock2.Matchers.TypeMatcher(typeof(ProgressTracker)),
              new ProgressReportEventArgsMatcher(new ProgressReportEventArgs(0.25f))
            }
          );

          test1.ChangeProgress(0.5f);
        }
      }

      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }