public void AccountForEfficiencies_FixedEnd_MultipleDateIntervalEfficiencies_ReturnsCorrectAnswer()
        {
            //         +------------+
            //       |0|  |0|  |0|

            // Result:
            //   +------------------+
            //       |0|  |0|  |0|

            // Arrange
            var now = DateTime.Now;
            var dateInterval = new DateInterval(now, now.AddDays(5));

            var dateIntervalEfficiencies = new List<DateIntervalEfficiency>();
            var efficiency1 = new DateIntervalEfficiency(now.AddDays(1), now.AddDays(2), 0);
            var efficiency2 = new DateIntervalEfficiency(now.AddDays(3), now.AddDays(4), 0);
            var efficiency3 = new DateIntervalEfficiency(now.AddDays(5), now.AddDays(6), 0);

            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies, FixedEndPoint.Max);

            var correctDateInterval = new DateInterval(dateInterval.Max.Value.Add(-dateInterval.Duration).Add(-efficiency1.Duration).Add(-efficiency2.Duration).Add(-efficiency3.Duration), dateInterval.Max.Value);

            // Assert
            Assert.AreEqual(correctDateInterval, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap1()
        {
            // 300% has higher priority than 200%,
            // 50% and 200% have same priority so 50% takes precedence.

            // +--------------------------+            Duration: 60 mins
            // |-----------200%-----------|			   Duration: 50 mins
            // |--50%--|           |-500%-|			   Duration (1): 30 min, (2): 10min

            // Frist we must work out the calendar efficiencies:

            // |--50%--|                               Duration: 30 mins
            //         |---200%---|                    Duration: 20 mins
            //                    |-500%-|             Duration: 10 mins

            // 30 mins at 50%	   => 15   mins at 100%
            // 20 mins at 200%     => 40   mins at 100%
            // 10 mins at 500%     => 50   mins at 100%

            // Result:
            // 60 - 15 - 40 = 5 mins
            // 5 mins at 100% is equivalend to 5/5 = 1 min at 500%
            // Total duration is: 30 + 20 + 1 = 51 mins

            // Arrange
            DateTime end = start.AddMinutes(60);
            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(30)), 50);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(30), start.AddMinutes(50)), 200);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(50), start.AddMinutes(60)), 500, 1);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(51));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_FixedEnd_NoOverlap_ThreeIntervals4()
        {
            // NOTE: This test if with Max end point fixed
            //
            // +----------------------+         Duration: 70 mins
            // |----------|                     Duration: 30 mins at 30%
            //            |-----|               Duration: 15 mins at 200%
            //                  |-|             Duration: 5 mins at 50%

            // The first section is not affected by a calendar period (i.e. 70 - 30 - 15 - 5 = 20)
            // So only 70 - 20 = 50 mins are affected by calendar periods.
            // Details:
            // 30 mins at 30%   => 9 min at 100%
            // 15 mins at 200%  => 30 min at 100%
            // 5 mins at 50%    => 2.5 min at 100%
            // 50 - 9 - 30 - 2.5 = 8.5 mins

            // So the 50 mins affected by the calendar period will last 30 + 15 + 5 + 8.5 = 58.5 mins
            // Total duration 25 + 58.5 = 83.5 mins

            // Arrange
            DateTime end = start.AddMinutes(70);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(30)), 30);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(30), start.AddMinutes(45)), 200);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(45), start.AddMinutes(50)), 50);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies, FixedEndPoint.Max);

            // Assert
            var result = new DateInterval(end.AddMinutes(-83.5), end);
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_OneInterval()
        {
            // +--------------------------------+      Duration: 60 mins
            // |--------|                              Duration: 30 mins at 20%
            //
            // Result
            // |----------------|                      Duration: 75 mins

            // Arrange
            DateTime end = start.AddMinutes(60);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(30)), 20); // 30 mins at 20%
            dateIntervalEfficiencies.Add(efficiency1);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(75));  // Duration: 75 mins
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_OneZeroEfficiencyCalendarStartWithDateInterval_ReturnsCorrectDateInterval()
        {
            // +-----------+
            // |-----0-----|

            // Result:
            // +-----------------------+
            // |-----0-----|

            // Arrange
            var now = DateTime.Now;
            var dateInterval = new DateInterval(now, now.AddDays(1));

            var dateIntervalEfficiencies = new List<DateIntervalEfficiency>();
            var efficiency1 = new DateIntervalEfficiency( dateInterval, 0 );
            dateIntervalEfficiencies.Add(efficiency1);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            var correctDateInterval = new DateInterval( dateInterval.Min.Value, efficiency1.Max.Value.Add(dateInterval.Duration) );

            // Assert
            Assert.AreEqual(correctDateInterval, newDateInterval);
        }
        public void AccountForEfficiencies_FixedEnd_OneZeroEfficiencyCalendarStartsInAndEndsAfterDateInterval_ReturnsCorrectResult()
        {
            //      +-----------+
            //               |--0--|

            // Result:
            //  +---------------+
            //               |--0--|

            // Arrange
            var now = DateTime.Now;
            var dateInterval = new DateInterval(now, now.AddDays(4));

            var dateIntervalEfficiencies = new List<DateIntervalEfficiency>();
            var efficiency1 = new DateIntervalEfficiency(now.AddDays(3), now.AddDays(5), 0);
            dateIntervalEfficiencies.Add(efficiency1);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies, FixedEndPoint.Max);

            var correctDateInterval = new DateInterval(dateInterval.Min.Value.Add( - (dateInterval.Max.Value - efficiency1.Min.Value) ), dateInterval.Max.Value);

            // Assert
            Assert.AreEqual(correctDateInterval, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap2()
        {
            // +--------------------------+            Duration: 80 mins
            // |--------200%----|			           Duration: 50 mins, Priority
            //    |--50%--|                            Duration: 30 mins starts at 10
            //                     |-300%-|			   Duration: 20 mins finishes at 80 mins

            // Work out the calendar efficiences

            // |--|                                    Duration: 10 mins at 200%
            //    |--50%--|                            Duration: 30 mins
            //            |--200%-|                    Duration: 10 mins
            //                    |-100%-|             Duration: 10 mins
            //                           |-300%-|      Duration: 20 mins

            // 10 mins at 200% => 20 mins at 100%
            // 30 mins at 50%  => 15 mins at 100%
            // 10 mins at 200% => 20 mins at 100%
            // 10 mins at 100% => 10 mins at 100%
            // 20 mins at 300% => 60 mins at 100%

            // 80 - 20 - 15 - 20 - 10 = 15 mins
            // 15 mins at 100% => 5 mins at 300%
            // Total duration is: 10 + 30 + 10 + 10 + 5 = 65 mins

            // Arrange
            DateTime end = start.AddMinutes(80);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(50)), 200);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(10), start.AddMinutes(40)), 50);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(60), start.AddMinutes(80)), 300);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(65));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap6()
        {
            // +--------------------------+           Duration: 100 mins
            //   |------120%---------|				  Duration: 45 mins, starts at 10
            //     |----100%-------|                  Duration: 35 mins, starts at 15
            //         |-30%-|			      		  Duration: 25 mins, starts at 20

            // Work out the calendar efficiences:

            // Assumption all the calendar periods have the same efficiency. To the lowest efficiency takes precedence

            //|--|									  Duration: 10 mins
            //    |-|                                 Duration: 5 mins at 120%
            //      |-|                               Duration: 5 mins at 100%
            //        |-----|                         Duration: 25 mins at 30%
            //              |-|                       Duration: 5 mins at 100%
            //                |-|                     Duration: 5 mins at 120%
            //                  |-----|               Duration: 45 mins at 100% (which is the default value)

            // 10 mins at 100%	  => 10   mins at 100%
            // 5 mins at 120%	  => 6    mins at 100%
            // 5 mins at 100%     => 5    mins at 100%
            // 25 mins at 30%	  => 7.5  mins at 100%
            // 5 mins at 100%	  => 5    mins at 100%
            // 5 mins at 120%	  => 6    mins at 100%
            // 45 mins at 100%    => 45   mins at 100%

            // Result:
            // 100 - 10 - 6 - 5 - 7.5 - 5 - 6 - 45 = 15.5 mins
            // Total duration is: 10 + 5 + 5 + 25 + 5 + 5 + 45 + 15.5 = 115.5 mins

            // Arrange
            DateTime end = start.AddMinutes(100);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(10), start.AddMinutes(55)), 120);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(15), start.AddMinutes(50)), 100);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(20), start.AddMinutes(45)), 30);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(115.5));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap5()
        {
            //+--------------------------+            Duration: 100 mins
            //   |------120%---------|				  Duration: 45 mins, starts at 10 (PRIORITY)
            //     |----100%-------|                  Duration: 35 mins, starts at 15
            //         |-30%-|			      		  Duration: 25 mins, starts at 20

            // Work out the calendar efficiences:
            // If 120% is the priority then it takes precedence over the 100% and the 30% calendar period
            // Because 100% and 30% have the same priority, 30% takes precedence (lower efficiency)

            // |--|									Duration: 10 mins
            //    |---120%-----------|              Duration: 45 mins
            //                       |-100%-|		Duration: 45 mins

            // 10 mins at 100%	  => 10   mins at 100%
            // 45 mins at 120%	  => 54   mins at 100%
            // 45 mins at 100%    => 45   mins at 100%

            // Result:

            // 100 - 10 - 54 = 36 mins
            // Total duration is: 10 + 45 + 36 = 91

            // Arrange
            DateTime end = start.AddMinutes(100);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(10), start.AddMinutes(55)), 120, 1);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(15), start.AddMinutes(50)), 100);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(20), start.AddMinutes(45)), 30);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(91));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_ThreeIntervals2()
        {
            // +----------------------+                      Duration: 80 mins
            // |-------|                                     Duration: 20 mins at 10%
            //         |-------------|                       Duration: 50 mins at 60%
            //                       |------------|          Duration: 40 mins at 150%

            // Details:

            // 20 mins at 10%  => 2 min at 100%
            // 50 mins at 60%  => 30 min at 100%
            // 40 mins at 150% => 60 min at 100%
            //
            // 80 - 2 - 30 = 48min
            // 48 mins at 100% => 32 mins at 150%
            //
            // Final result: 20 + 50 + 32 = 102 mins

            // Arrange
            DateTime end = start.AddMinutes(80);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(20)), 10);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(20), start.AddMinutes(70)), 60);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(70), start.AddMinutes(110)), 150);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(102));  // Duration: 102 mins
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap3()
        {
            // +--------------------------+                Duration: 55 mins
            //    |------80%-------|			  	       Duration: 30 mins, starts at 15
            //                  |-200%-|	               Duration: 20 mins starts at 40

            //Work out the calendar efficiences
            // |--|                                         Duration: 15 mins at 100%
            //    |----80%-----|                            Duration: 30 mins
            //                 |--200%-|                    Duration: 15 mins

            // 15 mins at 100%     => 15 mins at 100%
            // 30 mins at 80%	   => 24 mins at 100%
            // 15 mins at 200%     => 30 mins at 100%

            // Result:

            // 55 - 15 - 24 = 16 mins
            // 16 min at 100% is equivalend to 8 mins at 200%
            // Total duration is: 15 + 30 + 8 = 53 min

            // Arrange
            DateTime end = start.AddMinutes(55);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(15), start.AddMinutes(45)), 80, 1);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(40), start.AddMinutes(60)), 200);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(53));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_ThreeIntervals()
        {
            // +------------------+                         Duration: 70 mins
            // |------------------|                         Duration: 60 mins at 10%
            //                    |---------|               Duration: 40 mins at 80%
            //                              |---------|     Duration: 80 mins at 200%
            //
            // Result
            // 60 mins at 10%  => 6 mins at 100%
            // 40 mins at 80%  => 32 mins at 100%
            // 80 mins at 200% => 160 mins at 100%
            //
            // 70 - 6 - 32 = 32 mins
            // 32 mins at 100% => 16 mins at 200%
            //
            // Total = 60 + 40 + 16 = 116 mins

            // Arrange
            DateTime end = start.AddMinutes(70);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(60)), 10);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(60), start.AddMinutes(100)), 80);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(100), start.AddMinutes(180)), 200);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(116));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_TwoIntervals2()
        {
            // +------------------+     Duration: 60 mins
            //           |--------|     Duration: 20 mins at 40%
            //     |-----|              Duration: 10 mins at 150%
            //
            // Result
            // 20 mins at 40%  => 8 mins at 100%
            // 10 mins at 150% => 1.5 mins at 100%
            // 60 - 8 - 1.5 = 50.5
            //
            // Total = 20 + 10 + 50.5 = 80.5 mins

            // Arrange
            DateTime end = start.AddMinutes(60);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(30), start.AddMinutes(50)), 40);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(50), start.AddMinutes(60)), 150);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(80.5));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_TwoIntervals()
        {
            // +------------------+      Duration: 60 mins
            // |--------|                Duration: 30 mins at 20%
            //          |---------|      Duration: 30 mins at 150%
            //
            // Result
            // 30 mins at 20%  => 6 mins at 100%
            // 30 mins at 150% => 45 mins at 100%
            // 60 - 6 - 45 = 9 mins
            //
            // Total = 30 + 30 + 9 = 69 mins

            // Arrange
            DateTime end = start.AddMinutes(60);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(30)), 20); // 30 mins at 20%
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(30), start.AddMinutes(60)), 150); // 30 mins at 20%
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(69));  // Duration: 69 mins
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_NoOverlap_ThreeIntervals3()
        {
            //         +----------------------+     Duration: 60 mins
            // |-------|                            Duration: 30 mins at 30% (outside)
            //         |-------|                    Duration: 25 mins at 200%
            //                 |---|                Duration: 15 mins at 50%

            // Details:
            // 30 mins at 30%   => 0 (outside)
            // 25 mins at 200%  => 50 min at 100%
            // 15 mins at 50%   => 7.5 min at 100%
            // 60 - 50 - 7.5 = 2.5 min
            //
            // Result: 25 + 15 + 2.5 = 42.5 mins.

            // Arrange
            DateTime end = start.AddMinutes(60);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(-30), start), 30);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start, start.AddMinutes(25)), 200);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(25), start.AddMinutes(40)), 50);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(42.5));  // Duration: 42.5 mins
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_Overlap4()
        {
            // +---------------------------------+       Duration: 90 mins
            //   |------90%----------|			   	     Duration: 40 mins, starts at 10
            //   |--30%--|                               Duration: 15 mins starts at 10
            //                          |-150%-|	     Duration: 10 mins finishes at 80 mins

            // Work out the calendar efficiences

            // |--|										   Duration: 10 mins at 100%
            //     |--30%--|                               Duration: 15 mins
            //             |-----90%----|                  Duration: 25 mins
            //                          |---|              Duration: 20 mins at 100%
            //                               |-150%-|      Duration: 10 mins
            //                                      |--|   Duration: 10 mins at 100%

            // 10 mins at 10%	   => 10   mins at 100%
            // 15 mins at 30%	   => 4.5  mins at 100%
            // 25 mins at 90%      => 22.5   mins at 100%
            // 20 mins at 100%	   => 20   mins at 100%
            // 10 mins at 150%     => 15   mins at 100%
            // 10 mins at 100%	   => 10   mins at 100%

            // Result:
            // 90 - 10 - 4.5 - 22.5 - 20 - 15 - 10 = 8 mins
            // Total duration is: 10 + 15 + 25 + 20 + 10 + 10 + 8 = 98 mins

            // Arrange
            DateTime end = start.AddMinutes(90);

            var dateInterval = new DateInterval(start, end);

            var efficiency1 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(10), start.AddMinutes(50)), 90);
            var efficiency2 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(10), start.AddMinutes(25)), 30, 1);
            var efficiency3 = new DateIntervalEfficiency(new DateInterval(start.AddMinutes(70), start.AddMinutes(80)), 150);
            dateIntervalEfficiencies.Add(efficiency1);
            dateIntervalEfficiencies.Add(efficiency2);
            dateIntervalEfficiencies.Add(efficiency3);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies);

            // Assert
            var result = new DateInterval(start, start.AddMinutes(98));
            Assert.AreEqual(result, newDateInterval);
        }
        public void AccountForEfficiencies_FixedEnd_OneEfficiencyCalendarStartAndEndWithDateInterval_ReturnsCorrectAnswer()
        {
            // +-----------+
            // |----200----|

            // Result:
            //       +-----+
            // |----200----|

            // Arrange
            var now = DateTime.Now;
            var dateInterval = new DateInterval(now, now.AddDays(1));

            var dateIntervalEfficiencies = new List<DateIntervalEfficiency>();
            var efficiency1 = new DateIntervalEfficiency(dateInterval.Min.Value, dateInterval.Max.Value, 200);
            dateIntervalEfficiencies.Add(efficiency1);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies, FixedEndPoint.Max);

            var correctDateInterval = new DateInterval(dateInterval.Min.Value.AddTicks(-dateInterval.Duration.Ticks / 2), dateInterval.Max.Value);

            // Assert
            Assert.AreEqual(correctDateInterval, newDateInterval);
        }
        public void AccountForEfficiencies_FixedEnd_OneZeroEfficiencyCalendarStartAndEndWithDateInterval_ReturnsDateIntervalOfSameDurationWhichStartsWhenTheEfficiencyFinishes()
        {
            // +-----------+
            // |-----0-----|

            // Result:
            // +-----------------------+
            //             |-----0-----|

            // Arrange
            var now = DateTime.Now;
            var dateInterval = new DateInterval(now, now.AddDays(1));

            var dateIntervalEfficiencies = new List<DateIntervalEfficiency>();
            var efficiency1 = new DateIntervalEfficiency( dateInterval.Min.Value, dateInterval.Max.Value, 0 );
            dateIntervalEfficiencies.Add(efficiency1);

            // Act
            var newDateInterval = dateInterval.AccountForEfficiencies(dateIntervalEfficiencies, FixedEndPoint.Max);

            var correctDateInterval = new DateInterval(dateInterval.Min.Value.Add( - efficiency1.Duration ), dateInterval.Max.Value);

            // Assert
            Assert.AreEqual(correctDateInterval, newDateInterval);
        }