public async Task ShouldCaptureMultipleApplicationEventsWithStepNames()
        {
            var          sink      = new TestSink();
            const string operation = "multi test";

            using (var monitor = new MonitorBuilder(sink).Begin(User, operation))
            {
                monitor.Action(DoStuff, "do stuff");

                monitor.Function(ReturnStuff, "return stuff").Should().BeTrue();

                (await monitor.Function(ReturnStuffAsync, "return stuff async")).Should().BeTrue();

                await monitor.Complete();
            }

            sink.SentEvents.Count.Should().Be(3);
            sink.SentEvents[0].Operation.Should().Be(operation);
            sink.SentEvents[0].OperationStep.Should().Be("do stuff");
            sink.SentEvents[1].Operation.Should().Be(operation);
            sink.SentEvents[1].OperationStep.Should().Be("return stuff");
            sink.SentEvents[2].Operation.Should().Be(operation);
            sink.SentEvents[2].OperationStep.Should().Be("return stuff async");
        }
        public async Task ShouldCaptureSlowApplicationEvent()
        {
            var          sink      = new TestSink();
            const string operation = "slow test";

            using (var monitor = new MonitorBuilder(sink).Begin(User, operation, acceptableDurationMilliseconds: 1000))
            {
                var result = monitor.Function(() => ReturnStuff(2000));
                result.Should().BeTrue();

                await monitor.Complete();
            }

            sink.SentEvents.Count.Should().Be(1);
            var actual = sink.SentEvents.First();

            actual.User.Should().Be(User);
            actual.Operation.Should().Be(operation);
            actual.Outcome.Should().Be(Outcome.Slow);
        }
        public void ShouldCaptureApplicationEventAndMeasureDuration()
        {
            var          sink      = new TestSink();
            const string operation = "duration test";

            using (var monitor = new MonitorBuilder(sink).Begin(User, operation))
            {
                var result = monitor.Function(() => ReturnStuff(1000));
                result.Should().BeTrue();
            }

            sink.SentEvents.Count.Should().Be(1);
            var actual = sink.SentEvents.First();

            actual.User.Should().Be(User);
            actual.Operation.Should().Be(operation);
            actual.OperationStep.Should().BeNull();
            actual.Outcome.Should().Be(Outcome.Successful);
            sink.SentEvents.First().Duration.Should().BeGreaterOrEqualTo(1000.0);
        }
        public void ShouldCaptureApplicationEventForFunc()
        {
            Clock.Utc.Freeze();

            var          sink      = new TestSink();
            const string operation = "func test";

            using (var monitor = new MonitorBuilder(sink).Begin(User, operation))
            {
                var result = monitor.Function(ReturnStuff);
                result.Should().BeTrue();
            }

            sink.SentEvents.Count.Should().Be(1);
            sink.SentEvents.First().User.Should().Be(User);
            sink.SentEvents.First().Operation.Should().Be(operation);
            sink.SentEvents.First().OperationStep.Should().BeNull();
            sink.SentEvents.First().Outcome.Should().Be(Outcome.Successful);
            sink.SentEvents.First().Timestamp.Should().Be(Clock.Utc.Now);
            sink.SentEvents.First().Duration.Should().Be(0.0);
        }