Source code for unit.canvas.data.eras

# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Timeline is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Timeline.  If not, see <http://www.gnu.org/licenses/>.


from unittest.mock import Mock

from timelinelib.canvas.data import Eras
from timelinelib.test.cases.unit import UnitTestCase
from timelinelib.test.utils import a_gregorian_era_with
from timelinelib.test.utils import human_time_to_gregorian


[docs]class ErasTestCase(UnitTestCase):
[docs] def test_default_has_an_empty_list(self): self.assertEqual([], self.eras.get_all())
[docs] def setUp(self): UnitTestCase.setUp(self) self.color1 = (128, 255, 255) self.color2 = (255, 0, 255) self.color3 = (255, 128, 255) self.Dec_1_2015 = human_time_to_gregorian("1 Dec 2015") self.db = Mock() self.eras = Eras(self.db)
[docs]class describe_overlapping_eras(ErasTestCase): """ All Eras are sorted by start_time. That is... Era(n).start_time <= Era(n+1).start_time. Two adjacent Eras are overlapping if.. Era(n+1).start_time < Era(n).end_time There are 6 different overlapping situations to handle: 1. o---(e1)---o o---(e2)---o 2. o---(e1)---o o---(e2)-------o Total ecplise.... 3. o---(e1)-------o o---(e2)----o 4. o---(e1)----o o---(e2)----o 5. o------(e1)----o o---(e2)----o 6. o------(e1)----o o---(e2)---o """
[docs] def test_eras_are_returned_sorted_when_list_is_unsorted(self): self.given_two_overlapping_eras_type_1() self.assertEqual(self.era1, self.eras.get_all()[0])
[docs] def test_eras_can_detect_overlapping_type1(self): self.given_two_overlapping_eras_type_1() eras = self.eras.get_all() self.assertEqual(1, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_detect_overlapping_type2(self): self.given_two_overlapping_eras_type_2() eras = self.eras.get_all() self.assertEqual(eras[0], self.era1) self.assertEqual(2, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_detect_overlapping_type3(self): self.given_two_overlapping_eras_type_3() eras = self.eras.get_all() self.assertEqual(eras[0], self.era1) self.assertEqual(3, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_detect_overlapping_type4(self): self.given_two_overlapping_eras_type_4() eras = self.eras.get_all() self.assertEqual(eras[0], self.era1) self.assertEqual(4, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_detect_overlapping_type5(self): self.given_two_overlapping_eras_type_5() eras = self.eras.get_all() self.assertEqual(eras[0], self.era1) self.assertEqual(5, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_detect_overlapping_type6(self): self.given_two_overlapping_eras_type_6() eras = self.eras.get_all() self.assertEqual(eras[0], self.era1) self.assertEqual(6, eras[0].overlapping(eras[1]))
[docs] def test_eras_can_return_a_list_with_added_overlapping_type1_eras(self): self.given_two_overlapping_eras_type_1() periods = self.eras.get_all_periods() self.assertEqual(3, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015"), human_time_to_gregorian("15 Dec 2015"), human_time_to_gregorian("1 Jan 2016")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.color1, self.mix_colors(self.color1, self.color2), self.color2], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_added_overlapping_type2_eras(self): self.given_two_overlapping_eras_type_2() periods = self.eras.get_all_periods() self.assertEqual(2, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015"), human_time_to_gregorian("1 Jan 2016")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.mix_colors(self.color1, self.color2), self.color2], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_added_overlapping_type3_eras(self): self.given_two_overlapping_eras_type_3() periods = self.eras.get_all_periods() self.assertEqual(2, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015"), human_time_to_gregorian("15 Dec 2015")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.mix_colors(self.color1, self.color2), self.color1], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_added_overlapping_type4_eras(self): self.given_two_overlapping_eras_type_4() periods = self.eras.get_all_periods() self.assertEqual(1, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.mix_colors(self.color1, self.color2)], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_added_overlapping_type5_eras(self): self.given_two_overlapping_eras_type_5() periods = self.eras.get_all_periods() self.assertEqual(2, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015"), human_time_to_gregorian("15 Dec 2015")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.color1, self.mix_colors(self.color1, self.color2)], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_added_overlapping_type6_eras(self): self.given_two_overlapping_eras_type_6() periods = self.eras.get_all_periods() self.assertEqual(3, len(periods)) self.assertEqual([human_time_to_gregorian("1 Dec 2015"), human_time_to_gregorian("15 Dec 2015"), human_time_to_gregorian("15 Jan 2016")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.color1, self.mix_colors(self.color1, self.color2), self.color1], [e.color for e in periods])
[docs] def test_eras_can_return_a_list_with_3_overlapping_eras(self): """ o-------(e1)-------o o-----(e2)----------o o--------(e3)------o """ self.given_three_overlapping_eras() periods = self.eras.get_all_periods() self.assertEqual(5, len(periods)) self.assertEqual([human_time_to_gregorian("1 Jan 2016"), human_time_to_gregorian("15 Jan 2016"), human_time_to_gregorian("1 Feb 2016"), human_time_to_gregorian("30 Mar 2016"), human_time_to_gregorian("15 Apr 2016")], [e.get_time_period().start_time for e in periods]) self.assertEqual([self.color1, self.mix_colors(self.color1, self.color3), self.mix_3colors(self.color3, self.color1, self.color2), self.mix_colors(self.color2, self.color3), self.color2], [e.color for e in periods])
[docs] def test_eras_with_no_duration_are_excluded(self): self.given_two_eras_with_no_duration() result = self.eras.get_all_periods() self.assertEqual([], result)
[docs] def mix_colors(self, c0, c1): return ( (c0[0] + c1[0]) // 2, (c0[1] + c1[1]) // 2, (c0[2] + c1[2]) // 2 )
[docs] def mix_3colors(self, c1, c2, c3): return self.mix_colors(self.mix_colors(c1, c2), c3)
[docs] def given_two_overlapping_eras_type_1(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="15 Dec 2015", end="1 Feb 2016", color=self.color2) self.eras = Eras(self.db, eras=[ self.era2, self.era1, ])
[docs] def given_two_overlapping_eras_type_2(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="1 Dec 2015", end="1 Feb 2016", color=self.color2) self.eras = Eras(self.db, eras=[ self.era1, self.era2, ])
[docs] def given_two_overlapping_eras_type_3(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="1 Dec 2015", end="15 Dec 2015", color=self.color2) self.eras = Eras(self.db, eras=[ self.era1, self.era2, ])
[docs] def given_two_overlapping_eras_type_4(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color2) self.eras = Eras(self.db, eras=[ self.era1, self.era2, ])
[docs] def given_two_overlapping_eras_type_5(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="1 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="15 Dec 2015", end="1 Jan 2016", color=self.color2) self.eras = Eras(self.db, eras=[ self.era2, self.era1, ])
[docs] def given_two_overlapping_eras_type_6(self): self.era1 = a_gregorian_era_with(start="1 Dec 2015", end="30 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="15 Dec 2015", end="15 Jan 2016", color=self.color2) self.eras = Eras(self.db, eras=[ self.era2, self.era1, ])
[docs] def given_two_eras_with_no_duration(self): self.era1 = a_gregorian_era_with(start="30 Jan 2016", end="30 Jan 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="1 Dec 2015", end="1 Dec 2015", color=self.color2) self.eras = Eras(self.db, eras=[ self.era2, self.era1, ])
[docs] def given_three_overlapping_eras(self): self.era1 = a_gregorian_era_with(start="1 Jan 2016", end="30 Mar 2016", color=self.color1) self.era2 = a_gregorian_era_with(start="1 Feb 2016", end="30 Apr 2016", color=self.color2) self.era3 = a_gregorian_era_with(start="15 Jan 2016", end="15 Apr 2016", color=self.color3) self.eras = Eras(self.db, eras=[ self.era1, self.era2, self.era3, ])