def test_can_add_up_durations(self): first = self.change(timedelta(hours=0), 10) second = self.change(timedelta(hours=10), 10) aggregated = self.aggregate([first, second], interval=timedelta(hours=1)) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, 10), aggregated[0]) self.assert_equals(burndown_entry(second.when, 20), aggregated[1])
def test_continues_straight_line_if_two_values_are_closer_together_than_the_interval_are_given(self): until = now() first = burndown_entry(until - timedelta(minutes=10), 10) second = burndown_entry(until - timedelta(minutes=5), 5) extrapolation = self.generator.calculate([first, second], until) self.assert_length(2, extrapolation) self.assert_equals([burndown_entry(second.when, 5), burndown_entry(until, 0)], extrapolation)
def test_does_not_discard_start_or_end_value_even_if_interval_is_bigger_than_their_distance(self): first = self.change(timedelta(hours=0), 10) second = self.change(timedelta(hours=1), 10) aggregated = self.aggregate([first, second]) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, 10), aggregated[0]) self.assert_equals(burndown_entry(second.when, 20), aggregated[1])
def test_just_transforms_to_changes_if_no_aggregation_is_neccessary(self): first = self.change(timedelta(hours=0), 0) second = self.change(timedelta(hours=10), 6) aggregated = self.aggregate([first, second], interval=timedelta(hours=1)) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, first.delta()), aggregated[0]) self.assert_equals(burndown_entry(second.when, first.delta() + second.delta()), aggregated[1])
def test_can_extend_series_till_specified_time(self): first = self.change(timedelta(hours=-10), 10) end = now() aggregated = self.aggregate([first], extend_until=end) self.assert_equals([ burndown_entry(first.when, first.delta()), burndown_entry(end, first.delta()) ], aggregated)
def test_can_aggregate_multiple_changes_in_interval(self): first = self.change(timedelta(hours=0), 10) second = self.change(timedelta(hours=1), 10) third = self.change(timedelta(hours=2), 10) aggregated = self.aggregate([first, second, third]) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, 10), aggregated[0]) self.assert_equals(burndown_entry(third.when, 30), aggregated[1])
def test_does_not_discard_start_or_end_value_even_if_interval_is_bigger_than_their_distance( self): first = self.change(timedelta(hours=0), 10) second = self.change(timedelta(hours=1), 10) aggregated = self.aggregate([first, second]) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, 10), aggregated[0]) self.assert_equals(burndown_entry(second.when, 20), aggregated[1])
def test_continues_straight_line_if_two_values_are_closer_together_than_the_interval_are_given( self): until = now() first = burndown_entry(until - timedelta(minutes=10), 10) second = burndown_entry(until - timedelta(minutes=5), 5) extrapolation = self.generator.calculate([first, second], until) self.assert_length(2, extrapolation) self.assert_equals( [burndown_entry(second.when, 5), burndown_entry(until, 0)], extrapolation)
def test_takes_average_of_three_days_ago_to_compute_interval(self): until = now() values = [ burndown_entry(until - timedelta(days=9), 40), # five per day burndown_entry(until - timedelta(days=5), 10), burndown_entry(until - timedelta(days=4), 15), ] generator = BurndownTrendLineGenerator(reference_interval=timedelta(days=3)) extrapolation = generator.calculate(values, until) self.assert_length(2, extrapolation) self.assert_equals([burndown_entry(values[-1].when, 15), burndown_entry(until, 15 - 4*5)], extrapolation)
def test_just_transforms_to_changes_if_no_aggregation_is_neccessary(self): first = self.change(timedelta(hours=0), 0) second = self.change(timedelta(hours=10), 6) aggregated = self.aggregate([first, second], interval=timedelta(hours=1)) self.assert_length(2, aggregated) self.assert_equals(burndown_entry(first.when, first.delta()), aggregated[0]) self.assert_equals( burndown_entry(second.when, first.delta() + second.delta()), aggregated[1])
def test_takes_average_of_three_days_ago_to_compute_interval(self): until = now() values = [ burndown_entry(until - timedelta(days=9), 40), # five per day burndown_entry(until - timedelta(days=5), 10), burndown_entry(until - timedelta(days=4), 15), ] generator = BurndownTrendLineGenerator(reference_interval=timedelta( days=3)) extrapolation = generator.calculate(values, until) self.assert_length(2, extrapolation) self.assert_equals([ burndown_entry(values[-1].when, 15), burndown_entry(until, 15 - 4 * 5) ], extrapolation)
def test_can_aggregate_one_change(self): first = self.change(timedelta(hours=0), 10) self.assert_equals([burndown_entry(first.when, first.delta())], self.aggregate([first]))
def test_can_extend_series_till_specified_time(self): first = self.change(timedelta(hours=-10), 10) end = now() aggregated = self.aggregate([first], extend_until=end) self.assert_equals([burndown_entry(first.when, first.delta()), burndown_entry(end, first.delta())], aggregated)
def test_generate_no_trendline_from_one_input(self): burndown_values = [burndown_entry(now(), 0)] self.assert_is_empty(self.generator.calculate(burndown_values, now()))