Example #1
0
 def __init__(self, path, load=True, import_timeline=False, timetype=None):
     MemoryDB.__init__(self)
     self.path = path
     self.time_type = self._select_timetype(timetype)
     if load == True:
         self._load()
         self._fill_containers()
Example #2
0
 def testSaveNonExistingEvent(self):
     other_db = MemoryDB()
     other_db.save_event(self.e1)
     # It has id but is not in this db
     self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
     # Assert virtual _save method not called
     self.assertEquals(self.db._save.call_count, 0)
 def testSaveNonExistingEvent(self):
     other_db = MemoryDB()
     other_db.save_event(self.e1)
     # It has id but is not in this db
     self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
     # Assert virtual _save method not called
     self.assertEquals(self.db._save.call_count, 0)
Example #4
0
class ContainerEditorTestCase(unittest.TestCase):

    def setUp(self):
        self.view = Mock(ContainerEditorDialog)
        self.event_repository = Mock(EventRepository)
        self.db = MemoryDB()
        start = self.time("2000-01-03 10:01:01")
        end   = self.time("2000-01-03 10:01:01")
        self.container = Container(self.db.get_time_type(), start, end, "Container1")

    def testConstructionWithoutContainer(self):
        self.given_editor_without_container()
        self.view.set_name.assert_called_with("")
        self.view.set_category.assert_called_with(None)

    def testConstructionWithContainer(self):
        self.given_editor_with_container()
        self.view.set_name.assert_called_with("Container1")
        self.view.set_category.assert_called_with(None)

    def testContainerCreated(self):
        self.given_editor_without_container()
        self.editor.save()
        self.view.get_name.assert_called()
        self.view.get_category.assert_called()
        self.assertFalse(self.editor.container == None)

    def given_editor_without_container(self):
        self.editor = ContainerEditor(self.view, self.db, None)

    def given_editor_with_container(self):
        self.editor = ContainerEditor(self.view, self.db, self.container)

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)
Example #5
0
 def setUp(self):
     self.view = Mock(ContainerEditorDialog)
     self.event_repository = Mock(EventRepository)
     self.db = MemoryDB()
     start = self.time("2000-01-03 10:01:01")
     end   = self.time("2000-01-03 10:01:01")
     self.container = Container(self.db.get_time_type(), start, end, "Container1")
Example #6
0
 def testDeleteNonExistingEvent(self):
     self.assertRaises(TimelineIOError, self.db.delete_event, self.e1)
     self.assertRaises(TimelineIOError, self.db.delete_event, 5)
     other_db = MemoryDB()
     other_db.save_event(self.e2)
     self.assertRaises(TimelineIOError, self.db.delete_event, self.c2)
     # Assert virtual _save method not called
     self.assertEquals(self.db._save.call_count, 0)
 def testDeleteNonExistingEvent(self):
     self.assertRaises(TimelineIOError, self.db.delete_event, self.e1)
     self.assertRaises(TimelineIOError, self.db.delete_event, 5)
     other_db = MemoryDB()
     other_db.save_event(self.e2)
     self.assertRaises(TimelineIOError, self.db.delete_event, self.c2)
     # Assert virtual _save method not called
     self.assertEquals(self.db._save.call_count, 0)
Example #8
0
 def __init__(self):
     self.db = MemoryDB()
     from timelinelib.time.gregoriantime import GregorianTimeType
     self.db.time_type = GregorianTimeType()
     now = gregorian.from_time(self.db.time_type.now())
     self.start = self.get_time(now.year, now.month, 1)
     self.end = self.start + self.get_days_delta(30)
     self.db._set_displayed_period(TimePeriod(self.db.get_time_type(),
                                              self.start, self.end))
     self.last_cat = None
 def setUp(self):
     self.db = MemoryDB()
     self.db._save = Mock()
     self.db_listener = Mock()
     self.c1 = Category("work", (255, 0, 0), None, True)
     self.c2 = Category("private", (0, 255, 0), None, True)
     self.e1 = Event(self.db.get_time_type(), datetime(2010, 2, 13),
                     datetime(2010, 2, 13), "holiday")
     self.e2 = Event(self.db.get_time_type(), datetime(2010, 2, 14),
                     datetime(2010, 2, 14), "work starts")
     self.e3 = Event(self.db.get_time_type(), datetime(2010, 2, 15),
                     datetime(2010, 2, 16), "period")
     self.db.register(self.db_listener)
Example #10
0
class ContainerSubeventSpec(unittest.TestCase):

    def testSubeventPropertiesDefaultsToFalse(self):
        self.given_default_subevent()
        self.assertEqual(-1, self.subevent.cid())
        self.assertEqual(False, self.subevent.fuzzy)
        self.assertEqual(False, self.subevent.locked)
        self.assertEqual(False, self.subevent.ends_today)
        self.assertEqual(False, self.subevent.is_container())
        self.assertEqual(True, self.subevent.is_subevent())

    def testSubeventPropertyCidCanBeSetAtConstruction(self):
        self.given_subevent_with_cid()
        self.assertEqual(99, self.subevent.cid())

    def given_default_subevent(self):
        self.subevent = Subevent(self.db.get_time_type(), self.time("2000-01-01 10:01:01"),
                                 self.time("2000-01-03 10:01:01"), "evt")

    def given_subevent_with_cid(self):
        self.subevent = Subevent(self.db.get_time_type(), self.time("2000-01-01 10:01:01"),
                                 self.time("2000-01-03 10:01:01"), "evt", cid=99)

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #11
0
 def setUp(self):
     self.db = MemoryDB()
     self.view = Mock(DrawingAreaPanel)
     self.width = 10
     self.middle_x = self.width / 2
     self.view.GetSizeTuple.return_value = (self.width, 10)
     self.status_bar_adapter = Mock(StatusBarAdapter)
     self.config = Mock(Config)
     self.mock_drawer = MockDrawer()
     self.divider_line_slider = Mock()
     self.divider_line_slider.GetValue.return_value = 50
     self.fn_handle_db_error = Mock()
     self.controller = DrawingArea(self.view, self.status_bar_adapter,
                                   self.config, self.mock_drawer,
                                   self.divider_line_slider,
                                   self.fn_handle_db_error)
Example #12
0
class ContainerConstructorSpec(unittest.TestCase):

    def testContainerPropertiesDefaultsToFalse(self):
        self.given_default_container()
        self.assertEqual(-1, self.container.cid())
        self.assertEqual(False, self.container.fuzzy)
        self.assertEqual(False, self.container.locked)
        self.assertEqual(False, self.container.ends_today)
        self.assertEqual(True, self.container.is_container())
        self.assertEqual(False, self.container.is_subevent())
        self.assertEqual(None, self.container.category)

    def testContainerPropertyCidCanBeSetAtConstruction(self):
        self.given_container_with_cid()
        self.assertEqual(99, self.container.cid())

    def given_default_container(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now, "container")

    def given_container_with_cid(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now, "evt", cid=99)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
class ContainerConstructorSpec(unittest.TestCase):
    def testContainerPropertiesDefaultsToFalse(self):
        self.given_default_container()
        self.assertEqual(-1, self.container.cid())
        self.assertEqual(False, self.container.fuzzy)
        self.assertEqual(False, self.container.locked)
        self.assertEqual(False, self.container.ends_today)
        self.assertEqual(True, self.container.is_container())
        self.assertEqual(False, self.container.is_subevent())
        self.assertEqual(None, self.container.category)

    def testContainerPropertyCidCanBeSetAtConstruction(self):
        self.given_container_with_cid()
        self.assertEqual(99, self.container.cid())

    def given_default_container(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now,
                                   "container")

    def given_container_with_cid(self):
        self.container = Container(self.db.get_time_type(),
                                   self.now,
                                   self.now,
                                   "evt",
                                   cid=99)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #14
0
class EventSpec(unittest.TestCase):
    def testEventPropertyEndsTodayCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", ends_today=True)
        self.assertEqual(True, self.event.ends_today)

    def testEventPropertyFuzzyCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", fuzzy=True)
        self.assertEqual(True, self.event.fuzzy)

    def testEventPropertyLockedCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", locked=True)
        self.assertEqual(True, self.event.locked)

    def testEventPropertyEndsTodayCantBeSetOnLockedEvent(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", locked=True)
        self.event.update(self.now, self.now, "evt", ends_today=True)
        self.assertEqual(False, self.event.ends_today)

    def testEventPropertyEndsTodayCantBeUnsetOnLockedEvent(self):
        self.given_default_point_event()
        self.event.update(self.now,
                          self.now,
                          "evt",
                          locked=True,
                          ends_today=True)
        self.assertEqual(True, self.event.ends_today)
        self.event.update(self.now, self.now, "evt", ends_today=False)
        self.assertEqual(True, self.event.ends_today)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def given_point_event(self):
        self.event = Event(self.db.get_time_type(),
                           self.time("2000-01-01 10:01:01"),
                           self.time("2000-01-01 10:01:01"), "evt")
 def testInitialState(self):
     db = MemoryDB()
     self.assertEquals(db.path, "")
     self.assertEquals(db.displayed_period, None)
     self.assertEquals(db.hidden_categories, [])
     self.assertEquals(db.is_read_only(), False)
     self.assertEquals(db.supported_event_data(),
                       ["description", "icon", "alert", "hyperlink"])
     self.assertEquals(db.search(""), [])
     self.assertEquals(db.get_all_events(), [])
     self.assertEquals(db.get_first_event(), None)
     self.assertEquals(db.get_last_event(), None)
     self.assertEquals(db.get_categories(), [])
Example #16
0
 def testInitialState(self):
     db = MemoryDB()
     self.assertEquals(db.path, "")
     self.assertEquals(db.displayed_period, None)
     self.assertEquals(db.hidden_categories, [])
     self.assertEquals(db.is_read_only(), False)
     self.assertEquals(db.supported_event_data(), ["description", "icon", "alert", "hyperlink"])
     self.assertEquals(db.search(""), [])
     self.assertEquals(db.get_all_events(), [])
     self.assertEquals(db.get_first_event(), None)
     self.assertEquals(db.get_last_event(), None)
     self.assertEquals(db.get_categories(), [])
Example #17
0
class EventSpec(unittest.TestCase):

    def testEventPropertyEndsTodayCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", ends_today=True)
        self.assertEqual(True, self.event.ends_today)

    def testEventPropertyFuzzyCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", fuzzy=True)
        self.assertEqual(True, self.event.fuzzy)

    def testEventPropertyLockedCanBeUpdated(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", locked=True)
        self.assertEqual(True, self.event.locked)

    def testEventPropertyEndsTodayCantBeSetOnLockedEvent(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", locked=True)
        self.event.update(self.now, self.now, "evt", ends_today=True)
        self.assertEqual(False, self.event.ends_today)

    def testEventPropertyEndsTodayCantBeUnsetOnLockedEvent(self):
        self.given_default_point_event()
        self.event.update(self.now, self.now, "evt", locked=True, ends_today=True)
        self.assertEqual(True, self.event.ends_today)
        self.event.update(self.now, self.now, "evt", ends_today=False)
        self.assertEqual(True, self.event.ends_today)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def given_point_event(self):
        self.event = Event(self.db.get_time_type(), self.time("2000-01-01 10:01:01"),
                           self.time("2000-01-01 10:01:01"), "evt")
 def setUp(self):
     self.app = wx.App()  # a stored app is needed to create fonts
     self.drawer = DefaultDrawingAlgorithm()
     self.dc = Mock(wx.DC)
     self.dc.GetSizeTuple.return_value = IMAGE_SIZE
     self.dc.GetTextExtent.return_value = TEXT_SIZE
     self.timeline = MemoryDB()
     self.view_properties = ViewProperties()
     self.view_properties.displayed_period = TimePeriod(
         PyTimeType(), datetime.datetime(2010, 1, 1),
         datetime.datetime(2011, 1, 1))
Example #19
0
class EventFunctionsSpec(unittest.TestCase):

    def test_zero_time_span(self):
        self.given_default_point_event()
        self.assertEqual(self.event.time_type.get_zero_delta(), self.event.time_span())

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #20
0
class EventFunctionsSpec(unittest.TestCase):
    def test_zero_time_span(self):
        self.given_default_point_event()
        self.assertEqual(self.event.time_type.get_zero_delta(),
                         self.event.time_span())

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #21
0
 def setUp(self):
     self.db = MemoryDB()
     self.db._save = Mock()
     self.db_listener = Mock()
     self.c1 = Category("work", (255, 0, 0), None, True)
     self.c2 = Category("private", (0, 255, 0), None, True)
     self.e1 = Event(self.db.get_time_type(), datetime(2010, 2, 13), datetime(2010, 2, 13),
                     "holiday")
     self.e2 = Event(self.db.get_time_type(), datetime(2010, 2, 14), datetime(2010, 2, 14),
                     "work starts")
     self.e3 = Event(self.db.get_time_type(), datetime(2010, 2, 15), datetime(2010, 2, 16),
                     "period")
     self.db.register(self.db_listener)
Example #22
0
class EventCosntructorSpec(unittest.TestCase):
    def testEventPropertiesDefaultsToFalse(self):
        self.given_default_point_event()
        self.assertEqual(False, self.event.fuzzy)
        self.assertEqual(False, self.event.locked)
        self.assertEqual(False, self.event.ends_today)
        self.assertEqual(False, self.event.is_container())
        self.assertEqual(False, self.event.is_subevent())

    def testEventPropertyFuzzyCanBeSetAtConstruction(self):
        self.given_fuzzy_point_event()
        self.assertEqual(True, self.event.fuzzy)

    def testEventPropertyLockedCanBeSetAtConstruction(self):
        self.given_locked_point_event()
        self.assertEqual(True, self.event.locked)

    def testEventPropertyEndsTodayCanBeSetAtConstruction(self):
        self.given_point_event_wich_ends_today()
        self.assertEqual(True, self.event.ends_today)

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def given_point_event_wich_ends_today(self):
        self.event = Event(self.db.get_time_type(),
                           self.now,
                           self.now,
                           "evt",
                           ends_today=True)

    def given_fuzzy_point_event(self):
        self.event = Event(self.db.get_time_type(),
                           self.now,
                           self.now,
                           "evt",
                           fuzzy=True)

    def given_locked_point_event(self):
        self.event = Event(self.db.get_time_type(),
                           self.now,
                           self.now,
                           "evt",
                           locked=True)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
class ContainerSpec(unittest.TestCase):
    def testContainerCanHaveSubevents(self):
        self.given_period_subevent()
        self.given_default_container()
        self.container.register_subevent(self.event)
        self.assertEqual(1, len(self.container.events))

    def testSubeventsCanBeUnregistered(self):
        self.given_period_subevent()
        self.given_default_container()
        self.container.register_subevent(self.event)
        self.assertEqual(1, len(self.container.events))
        self.container.unregister_subevent(self.event)
        self.assertEqual(0, len(self.container.events))

    def testNameCanBeUpdated(self):
        self.given_default_container()
        new_name = "new text"
        self.container.update_properties(new_name)
        self.assertEqual(new_name, self.container.text)

    def testNameAndCategoryCanBeUpdated(self):
        self.given_default_container()
        new_name = "new text"
        new_category = Category("cat", (255, 0, 0), (255, 0, 0), True)
        self.container.update_properties(new_name, new_category)
        self.assertEqual(new_category, self.container.category)

    def testCidCanBeChanged(self):
        self.given_default_container()
        self.container.set_cid(99)
        self.assertEqual(99, self.container.cid())

    def given_default_container(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now,
                                   "container")

    def given_period_subevent(self):
        self.event = Subevent(self.db.get_time_type(),
                              self.time("2000-01-01 10:01:01"),
                              self.time("2000-01-03 10:01:01"), "evt")

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #24
0
class ContainerSpec(unittest.TestCase):

    def testContainerCanHaveSubevents(self):
        self.given_period_subevent()
        self.given_default_container()
        self.container.register_subevent(self.event)
        self.assertEqual(1, len(self.container.events))

    def testSubeventsCanBeUnregistered(self):
        self.given_period_subevent()
        self.given_default_container()
        self.container.register_subevent(self.event)
        self.assertEqual(1, len(self.container.events))
        self.container.unregister_subevent(self.event)
        self.assertEqual(0, len(self.container.events))

    def testNameCanBeUpdated(self):
        self.given_default_container()
        new_name = "new text"
        self.container.update_properties(new_name)
        self.assertEqual(new_name, self.container.text)

    def testNameAndCategoryCanBeUpdated(self):
        self.given_default_container()
        new_name = "new text"
        new_category = Category("cat", (255,0,0), (255,0,0), True)
        self.container.update_properties(new_name, new_category)
        self.assertEqual(new_category, self.container.category)

    def testCidCanBeChanged(self):
        self.given_default_container()
        self.container.set_cid(99)
        self.assertEqual(99, self.container.cid())

    def given_default_container(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now, "container")

    def given_period_subevent(self):
        self.event = Subevent(self.db.get_time_type(), self.time("2000-01-01 10:01:01"),
                              self.time("2000-01-03 10:01:01"), "evt")

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #25
0
 def setUp(self):
     self.db = MemoryDB()
     self.view = Mock(DrawingAreaPanel)
     self.width = 10
     self.middle_x = self.width / 2
     self.view.GetSizeTuple.return_value = (self.width, 10)
     self.status_bar_adapter = Mock(StatusBarAdapter)
     self.config = Mock(Config)
     self.mock_drawer = MockDrawer()
     self.divider_line_slider = Mock()
     self.divider_line_slider.GetValue.return_value = 50
     self.fn_handle_db_error = Mock()
     self.controller = DrawingArea(
         self.view,
         self.status_bar_adapter,
         self.config,
         self.mock_drawer,
         self.divider_line_slider,
         self.fn_handle_db_error)
Example #26
0
class SubeventSpec(unittest.TestCase):

    def testSubeventCanChangeContainer(self):
        self.given_default_subevent()
        self.given_container_with_cid()
        self.subevent.register_container(self.container)
        self.assertEqual(99, self.subevent.cid())
        self.assertEqual(self.container, self.subevent.container)

    def given_default_subevent(self):
        self.subevent = Subevent(self.db.get_time_type(), self.time("2000-01-01 10:01:01"),
                                 self.time("2000-01-03 10:01:01"), "evt")

    def given_container_with_cid(self):
        self.container = Container(self.db.get_time_type(), self.now, self.now, "evt", cid=99)


    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
Example #27
0
class EventCosntructorSpec(unittest.TestCase):

    def testEventPropertiesDefaultsToFalse(self):
        self.given_default_point_event()
        self.assertEqual(False, self.event.fuzzy)
        self.assertEqual(False, self.event.locked)
        self.assertEqual(False, self.event.ends_today)
        self.assertEqual(False, self.event.is_container())
        self.assertEqual(False, self.event.is_subevent())

    def testEventPropertyFuzzyCanBeSetAtConstruction(self):
        self.given_fuzzy_point_event()
        self.assertEqual(True, self.event.fuzzy)

    def testEventPropertyLockedCanBeSetAtConstruction(self):
        self.given_locked_point_event()
        self.assertEqual(True, self.event.locked)

    def testEventPropertyEndsTodayCanBeSetAtConstruction(self):
        self.given_point_event_wich_ends_today()
        self.assertEqual(True, self.event.ends_today)

    def given_default_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt")

    def given_point_event_wich_ends_today(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt", ends_today=True)

    def given_fuzzy_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt", fuzzy=True)

    def given_locked_point_event(self):
        self.event = Event(self.db.get_time_type(), self.now, self.now, "evt", locked=True)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
 def setUp(self):
     self.db = MemoryDB()
     self.now = self.db.get_time_type().now()
     self.time_type = self.db.get_time_type()
Example #29
0
 def __init__(self, path):
     MemoryDB.__init__(self)
     self._load(path)
Example #30
0
 def setUp(self):
     self.timeline = MemoryDB()
Example #31
0
class TimelineViewSpec(unittest.TestCase):
    def test_initializes_displayed_period_from_db(self):
        self.init_view_with_db_with_period("1 Aug 2010", "2 Aug 2010")
        self.assert_displays_period("1 Aug 2010", "2 Aug 2010")

    def test_scrolls_timeline_when_dragging_mouse(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(10, "2 Aug 2010")
        self.init_view_with_db_with_period("11 Aug 2010", "31 Aug 2010")
        self.simulate_mouse_down_move_up((0, ANY_Y), (10, ANY_Y))
        self.assert_displays_period("10 Aug 2010", "30 Aug 2010")

    def test_zooms_timeline_when_shift_dragging_mouse(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y),
                                         shift_down=True)
        self.assert_displays_period("1 Aug 2010", "3 Aug 2010")

    def test_displays_zoom_intstructions_in_status_bar(self):
        self.init_view_with_db()
        self.controller.left_mouse_down(0, 0, ctrl_down=False, shift_down=True)
        self.assert_displays_status_text(_("Select region to zoom into"))

    def test_displays_period_to_short_message_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2010 00:00")
        self.given_time_at_x_is(1, "1 Aug 2010 00:01")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_displays_status_text(_("Region too short"))

    def test_displays_nothing_if_period_ok_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(1, "2 Aug 2010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_displays_status_text("")

    def test_displays_period_to_long_message_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2000")
        self.given_time_at_x_is(200, "1 Aug 4000")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(200)
        self.assert_displays_status_text(_("Region too long"))

    def test_removes_zoom_instructions_when_zoom_done(self):
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y),
                                         shift_down=True)
        self.assert_displays_status_text("")

    def test_hightlights_selected_region_while_zooming(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_highlights_region(("1 Jan 2010", "1 Jan 2011"))

    def test_highlights_last_valid_region_while_zooming(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.given_time_at_x_is(2000, "1 Jan 4010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.move_mouse_to_x(2000)
        self.assert_highlights_region(("1 Jan 2010", "1 Jan 2011"))

    def test_highlights_no_region_when_zooming_is_completed(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y),
                                         shift_down=True)
        self.assert_highlights_region(None)

    def test_zooms_to_last_valid_selection(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.given_time_at_x_is(2000, "1 Jan 4010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.move_mouse_to_x(2000)
        self.release_mouse()
        self.assert_displays_period("1 Jan 2010", "1 Jan 2011")

    def test_centers_displayed_period_around_middle_click_position(self):
        self.given_time_at_x_is(150, "15 Aug 2010")
        self.init_view_with_db_with_period("1 Aug 2010", "11 Aug 2010")
        self.controller.middle_mouse_clicked(150)
        self.assert_displays_period("10 Aug 2010", "20 Aug 2010")

    def test_zooms_timeline_by_10_percent_on_each_side_when_scrolling_while_holding_down_ctrl(
            self):
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.controller.mouse_wheel_moved(1,
                                          ctrl_down=True,
                                          shift_down=False,
                                          x=self.middle_x)
        self.assert_displays_period("3 Aug 2010", "19 Aug 2010")

    def test_displays_balloon_for_event_with_description(self):
        event = self.given_event_with(description="any description",
                                      pos=(40, 60),
                                      size=(20, 10))
        self.init_view_with_db()
        self.controller.mouse_moved(50, 65)
        self.fire_balloon_show_timer()
        self.assert_balloon_drawn_for_event(event)

    def test_hides_balloon_when_leaving_event(self):
        event = self.given_event_with(description="any description",
                                      pos=(40, 60),
                                      size=(20, 10))
        self.init_view_with_db()
        self.controller.mouse_moved(50, 65)
        self.fire_balloon_show_timer()
        self.assert_balloon_drawn_for_event(event)
        self.controller.mouse_moved(0, ANY_Y)
        self.fire_balloon_hide_timer()
        self.assert_balloon_drawn_for_event(None)

    def test_creates_event_when_ctrl_dragging_mouse(self):
        self.given_time_at_x_is(10, "1 Aug 2010")
        self.given_time_at_x_is(30, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((10, ANY_Y), (30, ANY_Y),
                                         ctrl_down=True)
        self.assert_created_event_with_period("1 Aug 2010", "3 Aug 2010")
        self.assert_timeline_redrawn()

    def test_displays_event_info_in_status_bar_when_hovering_event(self):
        event = self.given_event_with(text="Period event",
                                      pos=(40, 60),
                                      size=(20, 10))
        self.init_view_with_db()
        self.simulate_mouse_move(50, 65)
        self.assertTrue("Period event" in self.get_status_text())

    def test_removes_event_info_from_status_bar_when_un_hovering_event(self):
        self.init_view_with_db()
        self.simulate_mouse_move(0, ANY_Y)
        self.assertEquals("", self.get_status_text())

    def test_displays_hidden_event_count_in_status_bar(self):
        self.mock_drawer.hidden_event_count = 3
        self.init_view_with_db()
        self.assertTrue("3" in self.get_hidden_event_count_text())

    def test_displays_error_in_status_bar_when_scrolling_too_far_left(self):
        def navigate(time_period):
            raise TimeOutOfRangeLeftError()

        self.init_view_with_db()
        self.controller.navigate_timeline(navigate)
        self.assert_displays_status_text(_("Can't scroll more to the left"))

    def test_displays_error_in_status_bar_when_scrolling_too_far_right(self):
        def navigate(time_period):
            raise TimeOutOfRangeRightError()

        self.init_view_with_db()
        self.controller.navigate_timeline(navigate)
        self.assert_displays_status_text(_("Can't scroll more to the right"))

    def test_creates_event_when_double_clicking_surface(self):
        self.given_time_at_x_is(30, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_double_click(30, ANY_Y)
        self.assert_created_event_with_period("3 Aug 2010", "3 Aug 2010")
        self.assert_timeline_redrawn()

    def test_edits_event_when_double_clicking_it(self):
        event = self.given_event_with(pos=(40, 60), size=(20, 10))
        self.init_view_with_db()
        self.simulate_mouse_double_click(50, 65)
        self.view.open_event_editor_for.assert_called_with(event)
        self.assert_timeline_redrawn()

    def test_selects_and_deselects_event_when_clicking_on_it(self):
        event = self.given_event_with(pos=(30, 60), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(40, 65)
        self.assert_is_selected(event)
        self.simulate_mouse_click(40, 65)
        self.assert_is_not_selected(event)

    def test_deselects_event_when_clicking_outside_of_it(self):
        event = self.given_event_with(pos=(30, 60), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.assert_is_selected(event)
        self.simulate_mouse_click(0, ANY_Y)
        self.assert_is_not_selected(event)

    def test_selects_multiple_events_when_clicked_if_ctrl_is_pressed(self):
        period_event = self.given_event_with(pos=(30, 60), size=(50, 10))
        point_event = self.given_event_with(pos=(130, 30), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.simulate_mouse_click(140, 35, ctrl_down=True)
        self.assert_is_selected(period_event)
        self.assert_is_selected(point_event)

    def test_displays_move_cursor_when_hovering_move_icon_on_event(self):
        event = self.given_event_with(pos=(0, 60), size=(30, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(10, 65)
        self.simulate_mouse_move(10, 65)
        self.assertTrue(self.view.set_move_cursor.called)

    def test_displays_resize_cursor_when_hovering_resize_icons_on_event(self):
        event = self.given_event_with(pos=(30, 60), size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.simulate_mouse_move(31, 65)
        self.simulate_mouse_move(89, 65)
        self.assertEquals(2, self.view.set_size_cursor.call_count)

    def test_resizes_event_when_dragging_right_drag_icon_on_event(self):
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.given_time_at_x_is(89, "4 Aug 2010")
        self.given_time_at_x_is(109, "11 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((89, 60), (109, 60))
        self.assert_event_has_period(event, "4 Aug 2010", "11 Aug 2010")
        self.assert_timeline_redrawn()

    def test_resizes_event_when_dragging_left_drag_icon_on_event(self):
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.given_time_at_x_is(31, "4 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((31, 60), (20, 60))
        self.assert_event_has_period(event, "3 Aug 2010", "10 Aug 2010")
        self.assert_timeline_redrawn()

    def test_snaps_event_edge_when_resizing_event(self):
        self.given_time_at_x_is(89, "10 Aug 2010")
        self.given_time_at_x_is(120, "13 Aug 2010")
        self.mock_drawer.setup_snap("13 Aug 2010", "27 Aug 2010")
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((89, 60), (120, 60))
        self.assert_event_has_period(event, "4 Aug 2010", "27 Aug 2010")
        self.assert_timeline_redrawn()

    def test_snaps_event_when_moving_event(self):
        self.given_time_at_x_is(31, "4 Aug 2010")
        self.given_time_at_x_is(10, "2 Aug 2010")
        self.mock_drawer.setup_snap("2 Aug 2010", "28 Jul 2010")
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(55, 60)
        self.simulate_mouse_down_move_up((31, 60), (10, 60))
        self.assert_event_has_period(event, "28 Jul 2010", "10 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_timeline_by_10_percent_when_moving_event(self):
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.simulate_mouse_click(50, 60)
        self.controller.left_mouse_down(65,
                                        60,
                                        ctrl_down=False,
                                        shift_down=False)
        self.controller.mouse_moved(199, 60)
        self.assertTrue(self.view.start_dragscroll_timer.called)
        self.controller.dragscroll_timer_fired()
        self.controller.left_mouse_up()
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_timeline_by_10_percent_when_resizing_event(self):
        event = self.given_event_with(start="4 Aug 2010",
                                      end="10 Aug 2010",
                                      pos=(30, 55),
                                      size=(60, 10))
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.simulate_mouse_click(50, 60)
        self.controller.left_mouse_down(89,
                                        60,
                                        ctrl_down=False,
                                        shift_down=False)
        self.controller.mouse_moved(199, 60)
        self.assertTrue(self.view.start_dragscroll_timer.called)
        self.controller.dragscroll_timer_fired()
        self.controller.left_mouse_up()
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_with_10_percent_when_using_mouse_wheel(self):
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.controller.mouse_wheel_moved(-1,
                                          ctrl_down=False,
                                          shift_down=False,
                                          x=self.middle_x)
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()
        self.controller.mouse_wheel_moved(1,
                                          ctrl_down=False,
                                          shift_down=False,
                                          x=self.middle_x)
        self.assert_displays_period("1 Aug 2010", "21 Aug 2010")
        self.assert_timeline_redrawn()

    def test_deletes_selected_events_when_pressing_del_and_answering_yes_in_dialog(
            self):
        period_event = self.given_event_with(start="4 Aug 2010",
                                             end="10 Aug 2010",
                                             pos=(30, 60 - 5),
                                             size=(60, 10))
        point_event = self.given_event_with(start="15 Aug 2010",
                                            end="15 Aug 2010",
                                            pos=(130, 30 - 5),
                                            size=(50, 10))
        self.init_view_with_db()
        self.view.ask_question.return_value = wx.YES
        self.simulate_mouse_click(50, 60)
        self.controller.key_down(wx.WXK_DELETE, False)
        self.assertEquals([point_event], self.db.get_all_events())

    def test_deletes_no_selected_events_when_pressing_del_and_answering_no_in_dialog(
            self):
        period_event = self.given_event_with(start="4 Aug 2010",
                                             end="10 Aug 2010",
                                             pos=(30, 60 - 5),
                                             size=(60, 10))
        point_event = self.given_event_with(start="15 Aug 2010",
                                            end="15 Aug 2010",
                                            pos=(130, 30 - 5),
                                            size=(50, 10))
        self.init_view_with_db()
        self.view.ask_question.return_value = wx.NO
        self.simulate_mouse_click(50, 60)
        self.controller.key_down(wx.WXK_DELETE, False)
        self.assertTrue(period_event in self.db.get_all_events())
        self.assertTrue(point_event in self.db.get_all_events())

    def test_shift_scroll_changes_divider_line_value_and_redraws(self):
        self.init_view_with_db()
        self.controller.mouse_wheel_moved(1,
                                          ctrl_down=False,
                                          shift_down=True,
                                          x=self.middle_x)
        self.assertTrue(self.divider_line_slider.SetValue.called)
        self.assert_timeline_redrawn()

    def test_disables_view_if_no_timeline_set(self):
        self.controller.set_timeline(None)
        self.view.Disable.assert_called_with()

    def setUp(self):
        self.db = MemoryDB()
        self.view = Mock(DrawingAreaPanel)
        self.width = 10
        self.middle_x = self.width / 2
        self.view.GetSizeTuple.return_value = (self.width, 10)
        self.status_bar_adapter = Mock(StatusBarAdapter)
        self.config = Mock(Config)
        self.mock_drawer = MockDrawer()
        self.divider_line_slider = Mock()
        self.divider_line_slider.GetValue.return_value = 50
        self.fn_handle_db_error = Mock()
        self.controller = DrawingArea(self.view, self.status_bar_adapter,
                                      self.config, self.mock_drawer,
                                      self.divider_line_slider,
                                      self.fn_handle_db_error)

    def given_event_with(self,
                         start="4 Aug 2010",
                         end="10 Aug 2010",
                         text="Text",
                         description=None,
                         pos=(0, 0),
                         size=(0, 0)):
        event = Event(self.db.get_time_type(), human_time_to_py(start),
                      human_time_to_py(end), text)
        if description is not None:
            event.set_data("description", description)
        self.db.save_event(event)
        self.mock_drawer.events_and_rects.append(
            (event, wx.Rect(pos[0], pos[1], size[0], size[1])))
        return event

    def given_time_at_x_is(self, x, time):
        self.mock_drawer.setup_get_time_call(x, human_time_to_py(time))

    def init_view_with_db_with_period(self, start, end):
        self.db._set_displayed_period(py_period(start, end))
        self.init_view_with_db()

    def init_view_with_db(self):
        self.controller.set_timeline(self.db)

    def fire_balloon_show_timer(self):
        self.assertTrue(self.view.start_balloon_show_timer.called)
        self.controller.balloon_show_timer_fired()

    def fire_balloon_hide_timer(self):
        self.assertTrue(self.view.start_balloon_hide_timer.called)
        self.controller.balloon_hide_timer_fired()

    def start_shift_drag_at_x(self, x):
        ctrl_down = False
        shift_down = True
        self.controller.left_mouse_down(x, ANY_Y, ctrl_down, shift_down)

    def simulate_mouse_double_click(self, x, y):
        self.simulate_mouse_click(x, y)
        self.controller.left_mouse_dclick(x, y, ctrl_down=False)

    def simulate_mouse_click(self, x, y, ctrl_down=False):
        self.controller.left_mouse_down(x,
                                        y,
                                        ctrl_down=ctrl_down,
                                        shift_down=False)
        self.controller.left_mouse_up()

    def simulate_mouse_down_move_up(self,
                                    from_,
                                    to,
                                    ctrl_down=False,
                                    shift_down=False):
        x1, y1 = from_
        x2, y2 = to
        self.controller.left_mouse_down(x1, y1, ctrl_down, shift_down)
        self.controller.mouse_moved(x2, y2)
        self.controller.config.use_inertial_scrolling = False
        self.controller.left_mouse_up()

    def simulate_mouse_move(self, x, y):
        self.controller.mouse_moved(x, y)

    def move_mouse_to_x(self, x):
        self.controller.mouse_moved(x, ANY_Y)

    def release_mouse(self):
        self.controller.left_mouse_up()

    def get_status_text(self):
        self.assertTrue(self.status_bar_adapter.set_text.called)
        text = self.status_bar_adapter.set_text.call_args[0][0]
        return text

    def get_hidden_event_count_text(self):
        self.assertTrue(
            self.status_bar_adapter.set_hidden_event_count_text.called)
        text = self.status_bar_adapter.set_hidden_event_count_text.call_args[
            0][0]
        return text

    def assert_event_has_period(self, event, start, end):
        self.assertEquals(py_period(start, end), event.time_period)

    def assert_balloon_drawn_for_event(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(event, view_properties.hovered_event)

    def assert_highlights_region(self, start_end):
        if start_end is not None:
            start_end = (human_time_to_py(start_end[0]),
                         human_time_to_py(start_end[1]))
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(start_end, view_properties.period_selection)

    def assert_displays_period(self, start, end):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(py_period(start, end),
                          view_properties.displayed_period)

    def assert_timeline_redrawn(self):
        self.assertTrue(self.view.redraw_surface.called)

    def assert_created_event_with_period(self, start, end):
        self.view.open_create_event_editor.assert_called_with(
            human_time_to_py(start), human_time_to_py(end))

    def assert_is_selected(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertTrue(view_properties.is_selected(event))

    def assert_is_not_selected(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertFalse(view_properties.is_selected(event))

    def assert_displays_status_text(self, text):
        self.assertEquals(text, self.get_status_text())

    def get_view_properties_used_when_drawing(self):
        self.assertTrue(self.view.redraw_surface.called)
        draw_fn = self.view.redraw_surface.call_args[0][0]
        draw_fn(Mock())
        return self.mock_drawer.draw_view_properties
Example #32
0
 def setUp(self):
     self.backend = MemoryDB()
Example #33
0
File: dir.py Project: sk/gnumed
 def __init__(self, path):
     MemoryDB.__init__(self)
     self._load(path)
Example #34
0
class TutorialTimelineCreator(object):

    def __init__(self):
        self.db = MemoryDB()
        from timelinelib.time.gregoriantime import GregorianTimeType
        self.db.time_type = GregorianTimeType()
        now = gregorian.from_time(self.db.time_type.now())
        self.start = self.get_time(now.year, now.month, 1)
        self.end = self.start + self.get_days_delta(30)
        self.db._set_displayed_period(TimePeriod(self.db.get_time_type(),
                                                 self.start, self.end))
        self.last_cat = None

    def add_category(self, name, color, font_color, make_last_added_parent=False):
        if make_last_added_parent:
            parent = self.last_cat
        else:
            parent = None
        self.prev_cat = self.last_cat 
        self.last_cat = Category(name, color, font_color, True, parent)
        self.db.save_category(self.last_cat)

    def add_event(self, text, description, start_add, end_add=None):
        start, end = self.calc_start_end(start_add, end_add)
        evt = Event(self.db.get_time_type(), start, end, text, self.last_cat)
        if description:
            evt.set_data("description", description)
        self.db.save_event(evt)

    def add_container(self, text, description, start_add, end_add=None):
        start, end = self.calc_start_end(start_add, end_add)
        container = Container(self.db.get_time_type(), start, end, text, self.prev_cat)
        self.db.save_event(container)
        return container

    def add_subevent(self, container, text, description, start_add, end_add=None):
        start, end = self.calc_start_end(start_add, end_add)
        evt = Subevent(self.db.get_time_type(), start, end, text, self.last_cat)
        if description:
            evt.set_data("description", description)
        self.db.save_event(evt)
        container.register_subevent(evt)
        
    def calc_start_end(self, start_add, end_add=None):
        start = self.start + start_add
        end = start
        if end_add is not None:
            end = self.start + end_add
        return (start, end)
    
    def get_db(self):
        return self.db

    def get_days_delta(self, days):
        if self.db.get_time_type().get_name() == u"gregoriantime":
            return delta_from_days(days)

    def get_time(self, year, month, day):
        if self.db.get_time_type().get_name() == u"gregoriantime":
            return Gregorian(year, month, day, 0, 0, 0).to_time()
Example #35
0
class TimelineViewSpec(unittest.TestCase):

    def test_initializes_displayed_period_from_db(self):
        self.init_view_with_db_with_period("1 Aug 2010", "2 Aug 2010")
        self.assert_displays_period("1 Aug 2010", "2 Aug 2010")

    def test_scrolls_timeline_when_dragging_mouse(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(10, "2 Aug 2010")
        self.init_view_with_db_with_period("11 Aug 2010", "31 Aug 2010")
        self.simulate_mouse_down_move_up((0, ANY_Y), (10, ANY_Y))
        self.assert_displays_period("10 Aug 2010", "30 Aug 2010")

    def test_zooms_timeline_when_shift_dragging_mouse(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y), shift_down=True)
        self.assert_displays_period("1 Aug 2010", "3 Aug 2010")

    def test_displays_zoom_intstructions_in_status_bar(self):
        self.init_view_with_db()
        self.controller.left_mouse_down(0, 0, ctrl_down=False, shift_down=True)
        self.assert_displays_status_text(_("Select region to zoom into"))

    def test_displays_period_to_short_message_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2010 00:00")
        self.given_time_at_x_is(1, "1 Aug 2010 00:01")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_displays_status_text(_("Region too short"))

    def test_displays_nothing_if_period_ok_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(1, "2 Aug 2010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_displays_status_text("")

    def test_displays_period_to_long_message_when_zooming(self):
        self.given_time_at_x_is(0, "1 Aug 2000")
        self.given_time_at_x_is(200, "1 Aug 4000")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(200)
        self.assert_displays_status_text(_("Region too long"))

    def test_removes_zoom_instructions_when_zoom_done(self):
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y), shift_down=True)
        self.assert_displays_status_text("")

    def test_hightlights_selected_region_while_zooming(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.assert_highlights_region(("1 Jan 2010", "1 Jan 2011"))

    def test_highlights_last_valid_region_while_zooming(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.given_time_at_x_is(2000, "1 Jan 4010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.move_mouse_to_x(2000)
        self.assert_highlights_region(("1 Jan 2010", "1 Jan 2011"))

    def test_highlights_no_region_when_zooming_is_completed(self):
        self.given_time_at_x_is(0, "1 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((0, ANY_Y), (20, ANY_Y), shift_down=True)
        self.assert_highlights_region(None)

    def test_zooms_to_last_valid_selection(self):
        self.given_time_at_x_is(0, "1 Jan 2010")
        self.given_time_at_x_is(1, "1 Jan 2011")
        self.given_time_at_x_is(2000, "1 Jan 4010")
        self.init_view_with_db()
        self.start_shift_drag_at_x(0)
        self.move_mouse_to_x(1)
        self.move_mouse_to_x(2000)
        self.release_mouse()
        self.assert_displays_period("1 Jan 2010", "1 Jan 2011")

    def test_centers_displayed_period_around_middle_click_position(self):
        self.given_time_at_x_is(150, "15 Aug 2010")
        self.init_view_with_db_with_period("1 Aug 2010", "11 Aug 2010")
        self.controller.middle_mouse_clicked(150)
        self.assert_displays_period("10 Aug 2010", "20 Aug 2010")

    def test_zooms_timeline_by_10_percent_on_each_side_when_scrolling_while_holding_down_ctrl(self):
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.controller.mouse_wheel_moved(
            1, ctrl_down=True, shift_down=False, x=self.middle_x)
        self.assert_displays_period("3 Aug 2010", "19 Aug 2010")

    def test_displays_balloon_for_event_with_description(self):
        event = self.given_event_with(description="any description", pos=(40, 60), size=(20, 10))
        self.init_view_with_db()
        self.controller.mouse_moved(50, 65)
        self.fire_balloon_show_timer()
        self.assert_balloon_drawn_for_event(event)

    def test_hides_balloon_when_leaving_event(self):
        event = self.given_event_with(description="any description", pos=(40, 60), size=(20, 10))
        self.init_view_with_db()
        self.controller.mouse_moved(50, 65)
        self.fire_balloon_show_timer()
        self.assert_balloon_drawn_for_event(event)
        self.controller.mouse_moved(0, ANY_Y)
        self.fire_balloon_hide_timer()
        self.assert_balloon_drawn_for_event(None)

    def test_creates_event_when_ctrl_dragging_mouse(self):
        self.given_time_at_x_is(10, "1 Aug 2010")
        self.given_time_at_x_is(30, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_down_move_up((10, ANY_Y), (30, ANY_Y), ctrl_down=True)
        self.assert_created_event_with_period("1 Aug 2010", "3 Aug 2010")
        self.assert_timeline_redrawn()

    def test_displays_event_info_in_status_bar_when_hovering_event(self):
        event = self.given_event_with(text="Period event", pos=(40, 60), size=(20, 10))
        self.init_view_with_db()
        self.simulate_mouse_move(50, 65)
        self.assertTrue("Period event" in self.get_status_text())

    def test_removes_event_info_from_status_bar_when_un_hovering_event(self):
        self.init_view_with_db()
        self.simulate_mouse_move(0, ANY_Y)
        self.assertEquals("", self.get_status_text())

    def test_displays_hidden_event_count_in_status_bar(self):
        self.mock_drawer.hidden_event_count = 3
        self.init_view_with_db()
        self.assertTrue("3" in self.get_hidden_event_count_text())

    def test_displays_error_in_status_bar_when_scrolling_too_far_left(self):
        def navigate(time_period):
            raise TimeOutOfRangeLeftError()
        self.init_view_with_db()
        self.controller.navigate_timeline(navigate)
        self.assert_displays_status_text(_("Can't scroll more to the left"))

    def test_displays_error_in_status_bar_when_scrolling_too_far_right(self):
        def navigate(time_period):
            raise TimeOutOfRangeRightError()
        self.init_view_with_db()
        self.controller.navigate_timeline(navigate)
        self.assert_displays_status_text(_("Can't scroll more to the right"))

    def test_creates_event_when_double_clicking_surface(self):
        self.given_time_at_x_is(30, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_double_click(30, ANY_Y)
        self.assert_created_event_with_period("3 Aug 2010", "3 Aug 2010")
        self.assert_timeline_redrawn()

    def test_edits_event_when_double_clicking_it(self):
        event = self.given_event_with(pos=(40, 60), size=(20, 10))
        self.init_view_with_db()
        self.simulate_mouse_double_click(50, 65)
        self.view.open_event_editor_for.assert_called_with(event)
        self.assert_timeline_redrawn()

    def test_selects_and_deselects_event_when_clicking_on_it(self):
        event = self.given_event_with(pos=(30, 60), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(40, 65)
        self.assert_is_selected(event)
        self.simulate_mouse_click(40, 65)
        self.assert_is_not_selected(event)

    def test_deselects_event_when_clicking_outside_of_it(self):
        event = self.given_event_with(pos=(30, 60), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.assert_is_selected(event)
        self.simulate_mouse_click(0, ANY_Y)
        self.assert_is_not_selected(event)

    def test_selects_multiple_events_when_clicked_if_ctrl_is_pressed(self):
        period_event = self.given_event_with(pos=(30, 60), size=(50, 10))
        point_event = self.given_event_with(pos=(130, 30), size=(50, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.simulate_mouse_click(140, 35, ctrl_down=True)
        self.assert_is_selected(period_event)
        self.assert_is_selected(point_event)

    def test_displays_move_cursor_when_hovering_move_icon_on_event(self):
        event = self.given_event_with(pos=(0, 60), size=(30, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(10, 65)
        self.simulate_mouse_move(10, 65)
        self.assertTrue(self.view.set_move_cursor.called)

    def test_displays_resize_cursor_when_hovering_resize_icons_on_event(self):
        event = self.given_event_with(pos=(30, 60), size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 65)
        self.simulate_mouse_move(31, 65)
        self.simulate_mouse_move(89, 65)
        self.assertEquals(2, self.view.set_size_cursor.call_count)

    def test_resizes_event_when_dragging_right_drag_icon_on_event(self):
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.given_time_at_x_is(89, "4 Aug 2010")
        self.given_time_at_x_is(109, "11 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((89, 60), (109, 60))
        self.assert_event_has_period(event, "4 Aug 2010", "11 Aug 2010")
        self.assert_timeline_redrawn()

    def test_resizes_event_when_dragging_left_drag_icon_on_event(self):
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.given_time_at_x_is(31, "4 Aug 2010")
        self.given_time_at_x_is(20, "3 Aug 2010")
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((31, 60), (20, 60))
        self.assert_event_has_period(event, "3 Aug 2010", "10 Aug 2010")
        self.assert_timeline_redrawn()

    def test_snaps_event_edge_when_resizing_event(self):
        self.given_time_at_x_is(89, "10 Aug 2010")
        self.given_time_at_x_is(120, "13 Aug 2010")
        self.mock_drawer.setup_snap("13 Aug 2010", "27 Aug 2010")
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(50, 60)
        self.simulate_mouse_down_move_up((89, 60), (120, 60))
        self.assert_event_has_period(event, "4 Aug 2010", "27 Aug 2010")
        self.assert_timeline_redrawn()

    def test_snaps_event_when_moving_event(self):
        self.given_time_at_x_is(31, "4 Aug 2010")
        self.given_time_at_x_is(10, "2 Aug 2010")
        self.mock_drawer.setup_snap("2 Aug 2010", "28 Jul 2010")
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.init_view_with_db()
        self.simulate_mouse_click(55, 60)
        self.simulate_mouse_down_move_up((31, 60), (10, 60))
        self.assert_event_has_period(event, "28 Jul 2010", "10 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_timeline_by_10_percent_when_moving_event(self):
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.simulate_mouse_click(50, 60)
        self.controller.left_mouse_down(65, 60, ctrl_down=False, shift_down=False)
        self.controller.mouse_moved(199, 60)
        self.assertTrue(self.view.start_dragscroll_timer.called)
        self.controller.dragscroll_timer_fired()
        self.controller.left_mouse_up()
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_timeline_by_10_percent_when_resizing_event(self):
        event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 55), size=(60, 10))
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.simulate_mouse_click(50, 60)
        self.controller.left_mouse_down(89, 60, ctrl_down=False, shift_down=False)
        self.controller.mouse_moved(199, 60)
        self.assertTrue(self.view.start_dragscroll_timer.called)
        self.controller.dragscroll_timer_fired()
        self.controller.left_mouse_up()
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()

    def test_scrolls_with_10_percent_when_using_mouse_wheel(self):
        self.init_view_with_db_with_period("1 Aug 2010", "21 Aug 2010")
        self.controller.mouse_wheel_moved(
            -1, ctrl_down=False, shift_down=False, x=self.middle_x)
        self.assert_displays_period("3 Aug 2010", "23 Aug 2010")
        self.assert_timeline_redrawn()
        self.controller.mouse_wheel_moved(
            1, ctrl_down=False, shift_down=False, x=self.middle_x)
        self.assert_displays_period("1 Aug 2010", "21 Aug 2010")
        self.assert_timeline_redrawn()

    def test_deletes_selected_events_when_pressing_del_and_answering_yes_in_dialog(self):
        period_event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 60-5), size=(60, 10))
        point_event = self.given_event_with(start="15 Aug 2010", end="15 Aug 2010", pos=(130, 30-5), size=(50, 10))
        self.init_view_with_db()
        self.view.ask_question.return_value = wx.YES
        self.simulate_mouse_click(50, 60)
        self.controller.key_down(wx.WXK_DELETE, False)
        self.assertEquals([point_event], self.db.get_all_events())

    def test_deletes_no_selected_events_when_pressing_del_and_answering_no_in_dialog(self):
        period_event = self.given_event_with(start="4 Aug 2010", end="10 Aug 2010", pos=(30, 60-5), size=(60, 10))
        point_event = self.given_event_with(start="15 Aug 2010", end="15 Aug 2010", pos=(130, 30-5), size=(50, 10))
        self.init_view_with_db()
        self.view.ask_question.return_value = wx.NO
        self.simulate_mouse_click(50, 60)
        self.controller.key_down(wx.WXK_DELETE, False)
        self.assertTrue(period_event in self.db.get_all_events())
        self.assertTrue(point_event in self.db.get_all_events())

    def test_shift_scroll_changes_divider_line_value_and_redraws(self):
        self.init_view_with_db()
        self.controller.mouse_wheel_moved(
            1, ctrl_down=False, shift_down=True, x=self.middle_x)
        self.assertTrue(self.divider_line_slider.SetValue.called)
        self.assert_timeline_redrawn()

    def test_disables_view_if_no_timeline_set(self):
        self.controller.set_timeline(None)
        self.view.Disable.assert_called_with()

    def setUp(self):
        self.db = MemoryDB()
        self.view = Mock(DrawingAreaPanel)
        self.width = 10
        self.middle_x = self.width / 2
        self.view.GetSizeTuple.return_value = (self.width, 10)
        self.status_bar_adapter = Mock(StatusBarAdapter)
        self.config = Mock(Config)
        self.mock_drawer = MockDrawer()
        self.divider_line_slider = Mock()
        self.divider_line_slider.GetValue.return_value = 50
        self.fn_handle_db_error = Mock()
        self.controller = DrawingArea(
            self.view,
            self.status_bar_adapter,
            self.config,
            self.mock_drawer,
            self.divider_line_slider,
            self.fn_handle_db_error)

    def given_event_with(self, start="4 Aug 2010", end="10 Aug 2010",
                         text="Text", description=None,
                         pos=(0, 0), size=(0, 0)):
        event = Event(self.db.get_time_type(), human_time_to_py(start), human_time_to_py(end), text)
        if description is not None:
            event.set_data("description", description)
        self.db.save_event(event)
        self.mock_drawer.events_and_rects.append((event, wx.Rect(pos[0], pos[1], size[0], size[1])))
        return event

    def given_time_at_x_is(self, x, time):
        self.mock_drawer.setup_get_time_call(x, human_time_to_py(time))

    def init_view_with_db_with_period(self, start, end):
        self.db._set_displayed_period(py_period(start, end))
        self.init_view_with_db()

    def init_view_with_db(self):
        self.controller.set_timeline(self.db)

    def fire_balloon_show_timer(self):
        self.assertTrue(self.view.start_balloon_show_timer.called)
        self.controller.balloon_show_timer_fired()

    def fire_balloon_hide_timer(self):
        self.assertTrue(self.view.start_balloon_hide_timer.called)
        self.controller.balloon_hide_timer_fired()

    def start_shift_drag_at_x(self, x):
        ctrl_down = False
        shift_down = True
        self.controller.left_mouse_down(x, ANY_Y, ctrl_down, shift_down)

    def simulate_mouse_double_click(self, x, y):
        self.simulate_mouse_click(x, y)
        self.controller.left_mouse_dclick(x, y, ctrl_down=False)

    def simulate_mouse_click(self, x, y, ctrl_down=False):
        self.controller.left_mouse_down(x, y, ctrl_down=ctrl_down, shift_down=False)
        self.controller.left_mouse_up()

    def simulate_mouse_down_move_up(self, from_, to, ctrl_down=False, shift_down=False):
        x1, y1 = from_
        x2, y2 = to
        self.controller.left_mouse_down(x1, y1, ctrl_down, shift_down)
        self.controller.mouse_moved(x2, y2)
        self.controller.config.use_inertial_scrolling = False
        self.controller.left_mouse_up()

    def simulate_mouse_move(self, x, y):
        self.controller.mouse_moved(x, y)

    def move_mouse_to_x(self, x):
        self.controller.mouse_moved(x, ANY_Y)

    def release_mouse(self):
        self.controller.left_mouse_up()

    def get_status_text(self):
        self.assertTrue(self.status_bar_adapter.set_text.called)
        text = self.status_bar_adapter.set_text.call_args[0][0]
        return text

    def get_hidden_event_count_text(self):
        self.assertTrue(self.status_bar_adapter.set_hidden_event_count_text.called)
        text = self.status_bar_adapter.set_hidden_event_count_text.call_args[0][0]
        return text

    def assert_event_has_period(self, event, start, end):
        self.assertEquals(py_period(start, end), event.time_period)

    def assert_balloon_drawn_for_event(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(event, view_properties.hovered_event)

    def assert_highlights_region(self, start_end):
        if start_end is not None:
            start_end = (human_time_to_py(start_end[0]), human_time_to_py(start_end[1]))
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(start_end, view_properties.period_selection)

    def assert_displays_period(self, start, end):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertEquals(
            py_period(start, end), view_properties.displayed_period)

    def assert_timeline_redrawn(self):
        self.assertTrue(self.view.redraw_surface.called)

    def assert_created_event_with_period(self, start, end):
        self.view.open_create_event_editor.assert_called_with(
            human_time_to_py(start), human_time_to_py(end))

    def assert_is_selected(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertTrue(view_properties.is_selected(event))

    def assert_is_not_selected(self, event):
        view_properties = self.get_view_properties_used_when_drawing()
        self.assertFalse(view_properties.is_selected(event))

    def assert_displays_status_text(self, text):
        self.assertEquals(text, self.get_status_text())

    def get_view_properties_used_when_drawing(self):
        self.assertTrue(self.view.redraw_surface.called)
        draw_fn = self.view.redraw_surface.call_args[0][0]
        draw_fn(Mock())
        return self.mock_drawer.draw_view_properties
Example #36
0
 def setUp(self):
     self.db = MemoryDB()
     self.now = self.db.get_time_type().now()
Example #37
0
class SceneSpec(unittest.TestCase):

    def test_has_no_hidden_events_when_all_events_belong_to_visible_categories(self):
        self.given_displayed_period("1 Jan 2010", "10 Jan 2010")
        self.given_visible_event_at("5 Jan 2010")
        self.when_scene_is_created()
        self.assertEquals(0, self.scene.get_hidden_event_count())

    def test_has_hidden_events_for_all_events_belonging_to_hidden_categories(self):
        self.given_displayed_period("1 Jan 2010", "10 Jan 2010")
        self.given_visible_event_at("5 Jan 2010")
        self.given_hidden_event_at("5 Jan 2010")
        self.when_scene_is_created()
        self.assertEquals(1, self.scene.get_hidden_event_count())

    def test_considers_events_outside_screen_hidden(self):
        self.given_displayed_period("1 Jan 2010", "10 Jan 2010")
        self.given_number_of_events_stackable_is(5)
        for i in range(6):
            self.given_visible_event_at("5 Jan 2010")
        self.when_scene_is_created()
        self.assertEquals(1, self.scene.get_hidden_event_count())

    def test_point_events_on_same_date_has_different_y_positions(self):
        self.given_displayed_period("1 Jan 2010", "10 Jan 2010")
        self.given_visible_event_at("5 Jan 2010")
        self.given_visible_event_at("5 Jan 2010")
        self.when_scene_is_created()
        self.assertTrue(self.scene.event_data[0][1].Y >
                        self.scene.event_data[1][1].Y)

    def test_point_events_on_different_dates_has_same_y_positions(self):
        self.given_displayed_period("1 Jan 2010", "10 Jan 2010")
        self.given_visible_event_at("2 Jan 2010")
        self.given_visible_event_at("9 Jan 2010")
        self.when_scene_is_created()
        self.assertEqual(self.scene.event_data[0][1].Y,
                         self.scene.event_data[1][1].Y)

    def test_period_events_with_same_period_has_different_y_positions(self):
        self.given_displayed_period("1 Jan 2010", "12 Jan 2010")
        self.given_visible_event_at("2 Jan 2010", "10 Jan 2010")
        self.given_visible_event_at("2 Jan 2010", "10 Jan 2010")
        self.when_scene_is_created()
        self.assertTrue(self.scene.event_data[0][1].Y <
                        self.scene.event_data[1][1].Y)

    def test_period_events_with_different_periods_has_same_y_positions(self):
        self.given_displayed_period("1 Jan 2010", "12 Jan 2010")
        self.given_visible_event_at("2 Jan 2010", "3 Jan 2010")
        self.given_visible_event_at("8 Jan 2010", "10 Jan 2010")
        self.when_scene_is_created()
        self.assertEqual(self.scene.event_data[0][1].Y,
                         self.scene.event_data[1][1].Y)

    def test_scene_must_be_created_at_last_century(self):
        self.given_displayed_period("1 Jan 9890", "1 Jan 9990")
        try:
            self.when_scene_is_created()
            self.assertTrue(self.scene != None)
        except:
            self.assertTrue(False)
        
    def setUp(self):
        self.db = MemoryDB()
        self.view_properties = ViewProperties()
        self.given_number_of_events_stackable_is(5)

    def get_text_size_fn(self, text):
        return (len(text), self.event_height)

    def given_number_of_events_stackable_is(self, number):
        self.event_height = 10
        self.size = (100, 2 * self.event_height * number)
        self.view_properties.divider_position = 0.5
        self.outer_padding = 0
        self.inner_padding = 0
        self.baseline_padding = 0

    def given_displayed_period(self, start, end):
        self.view_properties.displayed_period = py_period(start, end)

    def given_visible_event_at(self, start_time, end_time=None):
        self.given_event_at(start_time, end_time, visible=True)

    def given_hidden_event_at(self, time):
        self.given_event_at(time, visible=False)

    def given_event_at(self, start_time, end_time=None, visible=True):
        category = Category("category", (0, 0, 0), None, visible)
        if end_time is None:
            end_time = start_time
        event = Event(self.db.get_time_type(), human_time_to_py(start_time),
                      human_time_to_py(end_time), "event-text", category)
        self.db.save_category(category)
        self.db.save_event(event)
        self.view_properties.set_category_visible(category, visible)

    def when_scene_is_created(self):
        self.scene = TimelineScene(
            self.size, self.db, self.view_properties, self.get_text_size_fn,
            None)
        self.scene.set_outer_padding(self.outer_padding)
        self.scene.set_inner_padding(self.inner_padding)
        self.scene.set_baseline_padding(self.baseline_padding)
        self.scene.create()
class MemoryDBSpec(unittest.TestCase):
    def testInitialState(self):
        db = MemoryDB()
        self.assertEquals(db.path, "")
        self.assertEquals(db.displayed_period, None)
        self.assertEquals(db.hidden_categories, [])
        self.assertEquals(db.is_read_only(), False)
        self.assertEquals(db.supported_event_data(),
                          ["description", "icon", "alert", "hyperlink"])
        self.assertEquals(db.search(""), [])
        self.assertEquals(db.get_all_events(), [])
        self.assertEquals(db.get_first_event(), None)
        self.assertEquals(db.get_last_event(), None)
        self.assertEquals(db.get_categories(), [])

    def testLoadSaveViewProperties(self):
        # Make sure the database contains categories
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        # Set up a view properties object that simulates having selected a
        # specific period and hidden one category
        vp = ViewProperties()
        vp.set_category_visible(self.c1, False)
        start = datetime(2010, 3, 23)
        end = datetime(2010, 3, 24)
        tp = TimePeriod(self.db.get_time_type(), start, end)
        vp.displayed_period = tp
        # Save these properties and assert that the database fields are written
        # correctly
        self.db.save_view_properties(vp)
        self.assertEquals(self.db.displayed_period, tp)
        self.assertEquals(self.db.hidden_categories, [self.c1])
        # Load view properties from db simulating that this db was just loaded
        # into memory and the view is being configured
        new_vp = ViewProperties()
        self.db.load_view_properties(new_vp)
        self.assertFalse(new_vp.category_visible(self.c1))
        self.assertTrue(new_vp.category_visible(self.c2))
        self.assertEquals(new_vp.displayed_period, self.db.displayed_period)
        # Assert virtual _save method called: 2 save categories, 1 save view
        # properties
        self.assertEquals(self.db._save.call_count, 3)

    def testSaveInvalidDisplayedPeriod(self):
        # Assign a zero-period as displayed period
        vp = ViewProperties()
        start = datetime(2010, 3, 23)
        end = datetime(2010, 3, 23)
        tp = TimePeriod(PyTimeType(), start, end)
        vp.displayed_period = tp
        # Assert error when trying to save
        self.assertRaises(TimelineIOError, self.db.save_view_properties, vp)

    def testGetSetDisplayedPeriod(self):
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 3, 23),
                        datetime(2010, 3, 24))
        self.db._set_displayed_period(tp)
        # Assert that we get back the same period
        self.assertEquals(self.db._get_displayed_period(), tp)
        # Assert that the period is correctly loaded into ViewProperties
        vp = ViewProperties()
        self.db.load_view_properties(vp)
        self.assertEquals(vp.displayed_period, tp)

    def testGetSetHiddenCategories(self):
        # Assert that we cannot include categories not in the db
        self.assertRaises(ValueError, self.db._set_hidden_categories,
                          [self.c1])
        self.db._set_hidden_categories([])
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        self.db._set_hidden_categories([self.c1])
        # Assert that the returned list is the same
        self.assertEquals(self.db._get_hidden_categories(), [self.c1])
        # Assert that category visibility information is correctly written to
        # ViewProperties
        vp = ViewProperties()
        self.db.load_view_properties(vp)
        self.assertFalse(vp.category_visible(self.c1))
        self.assertTrue(vp.category_visible(self.c2))

    def testSaveNewCategory(self):
        self.db.save_category(self.c1)
        self.assertTrue(self.c1.has_id())
        self.assertEqual(self.db.get_categories(), [self.c1])
        self.assertEqual(self.db_listener.call_count, 1)
        # Assert virtual _save method called: 1 save category
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveExistingCategory(self):
        self.db.save_category(self.c1)
        id_before = self.c1.id
        self.c1.name = "new name"
        self.db.save_category(self.c1)
        self.assertEqual(id_before, self.c1.id)
        self.assertEqual(self.db.get_categories(), [self.c1])
        self.assertEqual(self.db_listener.call_count, 2)  # 2 save
        # Assert virtual _save method called: 2 save category
        self.assertEquals(self.db._save.call_count, 2)

    def testSaveNonExistingCategory(self):
        other_db = MemoryDB()
        other_db.save_category(self.c1)
        # It has id but is not in this db
        self.assertRaises(TimelineIOError, self.db.save_category, self.c1)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testSaveCategoryWithUnknownParent(self):
        self.c1.parent = self.c2
        # c2 not in db so we should get exception
        self.assertRaises(TimelineIOError, self.db.save_category, self.c1)
        # But after c2 is added everything is fine
        self.db.save_category(self.c2)
        self.db.save_category(self.c1)

    def testSaveCategoryWithParentChange(self):
        # Start with this hierarchy:
        # c1
        #   c11
        #     c111
        #   c12
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        c111 = Category("c111", (255, 0, 0), None, True, parent=c11)
        c12 = Category("c12", (255, 0, 0), None, True, parent=c1)
        self.db.save_category(c1)
        self.db.save_category(c11)
        self.db.save_category(c111)
        self.db.save_category(c12)
        # Changing c11's parent to c12 should create the following tree:
        # c1
        #   c12
        #     c11
        #       c111
        c11.parent = c12
        self.db.save_category(c11)
        self.assertEquals(c1.parent, None)
        self.assertEquals(c12.parent, c1)
        self.assertEquals(c11.parent, c12)
        self.assertEquals(c111.parent, c11)
        # Changing c11's parent to c111 should raise exception since that would
        # create a circular parent link.
        c11.parent = c111
        self.assertRaises(TimelineIOError, self.db.save_category, c11)

    def testDeleteExistingCategory(self):
        # Add two categories to the db
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        # Make category 1 hidden
        vp = ViewProperties()
        vp.set_category_visible(self.c1, False)
        self.db.save_view_properties(vp)
        # Assert both categories in db
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 2)
        self.assertTrue(self.c1 in categories)
        self.assertTrue(self.c2 in categories)
        # Remove first (by category)
        self.db.delete_category(self.c1)
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 1)
        self.assertTrue(self.c2 in categories)
        self.assertFalse(self.c1.has_id())
        self.assertFalse(self.c1 in self.db.hidden_categories)
        # Remove second (by id)
        self.db.delete_category(self.c2.id)
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 0)
        self.assertFalse(self.c2.has_id())
        # Check events
        self.assertEqual(self.db_listener.call_count, 4)  # 2 save, 2 delete
        # Assert virtual _save method called: 2 save category, 1 save view
        # properties, 2 delete categories
        self.assertEquals(self.db._save.call_count, 5)

    def testDeleteNonExistingCategory(self):
        self.assertRaises(TimelineIOError, self.db.delete_category, self.c1)
        self.assertRaises(TimelineIOError, self.db.delete_category, 5)
        other_db = MemoryDB()
        other_db.save_category(self.c2)
        self.assertRaises(TimelineIOError, self.db.delete_category, self.c2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDeleteCategoryWithParent(self):
        # Create hierarchy:
        # c1
        #   c11
        #   c12
        #     c121
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        c12 = Category("c12", (255, 0, 0), None, True, parent=c1)
        c121 = Category("c121", (255, 0, 0), None, True, parent=c12)
        self.db.save_category(c1)
        self.db.save_category(c11)
        self.db.save_category(c12)
        self.db.save_category(c121)
        # Delete c12 should cause c121 to get c1 as parent
        self.db.delete_category(c12)
        self.assertEquals(c121.parent, c1)
        # Delete c1 should cause c11, and c121 to be parentless
        self.db.delete_category(c1)
        self.assertEquals(c11.parent, None)
        self.assertEquals(c121.parent, None)

    def testDelteCategoryWithEvent(self):
        # Create hierarchy:
        # c1
        #   c11
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        self.db.save_category(c1)
        self.db.save_category(c11)
        # Create event belonging to c11
        self.e1.category = c11
        self.db.save_event(self.e1)
        # Delete c11 should cause e1 to get c1 as category
        self.db.delete_category(c11)
        self.assertEquals(self.e1.category, c1)
        # Delete c1 should cause e1 to have no category
        self.db.delete_category(c1)
        self.assertEquals(self.e1.category, None)

    def testSaveEventUnknownCategory(self):
        # A new
        self.e1.category = self.c1
        self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
        # An existing
        self.db.save_event(self.e2)
        self.e2.category = self.c1
        self.assertRaises(TimelineIOError, self.db.save_event, self.e2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveNewEvent(self):
        self.db.save_event(self.e1)
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 14))
        self.assertTrue(self.e1.has_id())
        self.assertEqual(self.db.get_events(tp), [self.e1])
        self.assertEqual(self.db.get_all_events(), [self.e1])
        self.assertEqual(self.db_listener.call_count, 1)  # 1 save
        # Assert virtual _save method called: 1 save event
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveExistingEvent(self):
        self.db.save_event(self.e1)
        id_before = self.e1.id
        self.e1.text = "new text"
        self.db.save_event(self.e1)
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 14))
        self.assertEqual(id_before, self.e1.id)
        self.assertEqual(self.db.get_events(tp), [self.e1])
        self.assertEqual(self.db.get_all_events(), [self.e1])
        self.assertEqual(self.db_listener.call_count, 2)  # 1 save
        # Assert virtual _save method called: 2 save event
        self.assertEquals(self.db._save.call_count, 2)

    def testSaveNonExistingEvent(self):
        other_db = MemoryDB()
        other_db.save_event(self.e1)
        # It has id but is not in this db
        self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDeleteExistingEvent(self):
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 15))
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        # Assert both in db
        self.assertEquals(len(self.db.get_events(tp)), 2)
        self.assertTrue(self.e1 in self.db.get_events(tp))
        self.assertTrue(self.e2 in self.db.get_events(tp))
        # Delete first (by event)
        self.db.delete_event(self.e1)
        self.assertFalse(self.e1.has_id())
        self.assertEquals(len(self.db.get_events(tp)), 1)
        self.assertTrue(self.e2 in self.db.get_events(tp))
        # Delete second (by id)
        self.db.delete_event(self.e2.id)
        self.assertFalse(self.e2.has_id())
        self.assertEquals(len(self.db.get_events(tp)), 0)
        # Check events
        self.assertEqual(self.db_listener.call_count, 4)  # 2 save, 2 delete
        # Assert virtual _save method called: 2 save event, 2 delete event
        self.assertEquals(self.db._save.call_count, 4)

    def testDeleteNonExistingEvent(self):
        self.assertRaises(TimelineIOError, self.db.delete_event, self.e1)
        self.assertRaises(TimelineIOError, self.db.delete_event, 5)
        other_db = MemoryDB()
        other_db.save_event(self.e2)
        self.assertRaises(TimelineIOError, self.db.delete_event, self.c2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDisableEnableSave(self):
        self.db.save_category(self.c1)
        # Assert virtual _save method called: save enabled by default
        self.assertEquals(self.db._save.call_count, 1)
        self.db.disable_save()
        self.db.save_category(self.c1)
        self.assertEquals(self.db._save.call_count, 1)  # still 1
        self.db.enable_save()
        self.assertEquals(self.db._save.call_count, 2)
        # Now do the same thing but tell enable not to call save
        self.db.disable_save()
        self.db.save_category(self.c1)
        self.db.enable_save(False)
        self.assertEquals(self.db._save.call_count, 2)
        # Enabling when enabled should not have any effect
        self.db.enable_save()
        self.assertEquals(self.db._save.call_count, 2)

    def testMoveEventForward(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_after_event(self.e1, self.e2)
        self.assertTrue(self.db.events[0] == self.e2)
        self.assertTrue(self.db.events[1] == self.e1)
        self.assertTrue(self.db.events[2] == self.e3)

    def testMoveEventToEnd(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_after_event(self.e1, self.e3)
        self.assertTrue(self.db.events[0] == self.e2)
        self.assertTrue(self.db.events[1] == self.e3)
        self.assertTrue(self.db.events[2] == self.e1)

    def testMoveEventBackward(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e2, self.e1)
        self.assertTrue(self.db.events[0] == self.e2)
        self.assertTrue(self.db.events[1] == self.e1)
        self.assertTrue(self.db.events[2] == self.e3)

    def testMoveEventToBeginning(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e3, self.e1)
        self.assertTrue(self.db.events[0] == self.e3)
        self.assertTrue(self.db.events[1] == self.e1)
        self.assertTrue(self.db.events[2] == self.e2)

    def testMoveEventToOriginalPlace(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e2, self.e2)
        self.assertTrue(self.db.events[0] == self.e1)
        self.assertTrue(self.db.events[1] == self.e2)
        self.assertTrue(self.db.events[2] == self.e3)

    def testEventShouldNotBeFuzzyByDefault(self):
        self.assertFalse(self.e1.fuzzy)

    def testEventShouldNotBeLockedByDefault(self):
        self.assertFalse(self.e1.locked)

    def setUp(self):
        self.db = MemoryDB()
        self.db._save = Mock()
        self.db_listener = Mock()
        self.c1 = Category("work", (255, 0, 0), None, True)
        self.c2 = Category("private", (0, 255, 0), None, True)
        self.e1 = Event(self.db.get_time_type(), datetime(2010, 2, 13),
                        datetime(2010, 2, 13), "holiday")
        self.e2 = Event(self.db.get_time_type(), datetime(2010, 2, 14),
                        datetime(2010, 2, 14), "work starts")
        self.e3 = Event(self.db.get_time_type(), datetime(2010, 2, 15),
                        datetime(2010, 2, 16), "period")
        self.db.register(self.db_listener)
class DefaultContainerStartegySpec(unittest.TestCase):

    def test_construction(self):
        self.given_strategy_with_container()
        self.assertEqual(self.container, self.strategy.container)

    def test_first_registered_event_decides_container_period(self):
        self.given_strategy_with_container()
        self.given_subevent1()
        self.strategy.register_subevent(self.subevent1)
        self.assert_equal_start(self.container, self.subevent1)
        self.assert_equal_end(self.container, self.subevent1)

    def test_second_registered_event_expands_container_period(self):
        # Container event:   +-------+
        # New sub-event:                 +-------+
        self.given_container_with_two_events_with_nonoverlapping_periods()
        self.assert_equal_start(self.container, self.subevent1)
        self.assert_equal_end(self.container, self.subevent2)

    def test_removing_one_event_contracts_container_period(self):
        # Container event:   +-------+
        # New sub-event:                 +-------+
        self.given_container_with_two_events_with_nonoverlapping_periods()
        self.strategy.unregister_subevent(self.subevent1)
        self.assert_equal_start(self.container, self.subevent2)
        self.assert_equal_end(self.container, self.subevent2)

    def test_updating_subevent_expands_container_period(self):
        # Container event:   +-------+
        # New sub-event:                 +-------+
        self.given_container_with_two_events_with_nonoverlapping_periods()
        self.subevent2.time_period.end_time = self.time("2000-05-01 10:01:01")
        self.strategy.update(self.subevent2)
        self.assert_equal_start(self.container, self.subevent1)
        self.assert_equal_end(self.container, self.subevent2)

    def test_adding_partial_overlapping_event_moves_overlapped_event_backwards(self):
        # Container event:   +-------+
        # New sub-event:          +-------+
        self.given_container_with_two_events_with_overlapping_periods()
        self.assert_start_equals_end(self.subevent2, self.subevent1)

    def test_adding_partial_overlapping_event_moves_overlapped_event_forward(self):
        # Container event:        +-------+
        # New sub-event:     +-------+
        self.given_container_with_two_events_with_overlapping_periods_reversed_order()
        self.assert_start_equals_end(self.subevent2, self.subevent1)

    def test_adding_event_with_same_period_moves_overlapped_event_forward(self):
        # Container event:   +-------+
        # New sub-event:     +-------+
        self.given_container_with_two_events_with_same_periods()
        self.assert_start_equals_end(self.subevent1, self.subevent2)

    def test_adding_event_with_same_start_moves_overlapped_event_forward(self):
        # Container event:   +-------+
        # New sub-event:     +---+
        self.given_container_with_two_events_with_same_start_time()
        self.assert_start_equals_end(self.subevent1, self.subevent2)

    def test_overlapping_nonperiod_event_at_begining_moves_nonperiod_event_backwards(self):
        # Container event:    +
        # New sub-event:     +----------+
        self.given_strategy_with_container()
        self.given_event_overlapping_point_event()
        self.assert_start_equals_start(self.subevent1, self.subevent2)

    def test_overlapping_nonperiod_event_at_end_moves_nonperiod_event_forward(self):
        # Container event:             +
        # New sub-event:     +----------+
        self.given_strategy_with_container()
        self.given_event_overlapping_point_event2()
        self.assert_start_equals_end(self.subevent1, self.subevent2)

    def given_container_with_two_events_with_nonoverlapping_periods(self):
        self.given_strategy_with_container()
        self.given_two_events_with_nonoverlapping_periods()
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_container_with_two_events_with_overlapping_periods(self):
        self.given_strategy_with_container()
        self.given_two_overlapping_events()
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_container_with_two_events_with_overlapping_periods_reversed_order(self):
        self.given_strategy_with_container()
        self.given_two_overlapping_events()
        self.strategy.register_subevent(self.subevent2)
        self.strategy.register_subevent(self.subevent1)

    def given_container_with_two_events_with_same_periods(self):
        self.given_strategy_with_container()
        self.given_two_events_with_same_period()
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_container_with_two_events_with_same_start_time(self):
        self.given_strategy_with_container()
        self.given_two_events_with_same_start_time()
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_strategy_with_container(self):
        self.container = Container(self.db.get_time_type(),
                                   self.time("2000-01-01 10:01:01"),
                                   self.time("2000-01-01 10:01:01"), "Container1")
        self.strategy = DefaultContainerStrategy(self.container)

    def given_event_overlapping_point_event(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-05-01 10:02:01"),
                                  self.time("2000-05-01 10:02:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-05-01 10:01:01"),
                                  self.time("2000-07-01 10:01:01"), "Container1")
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_event_overlapping_point_event2(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-07-01 10:00:01"),
                                  self.time("2000-07-01 10:00:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-05-01 10:01:01"),
                                  self.time("2000-07-01 10:01:01"), "Container1")
        self.strategy.register_subevent(self.subevent1)
        self.strategy.register_subevent(self.subevent2)

    def given_two_overlapping_events(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-06-01 10:01:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-05-01 10:01:01"),
                                  self.time("2000-07-01 10:01:01"), "Container1")

    def given_two_events_with_same_period(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-06-01 10:01:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-06-01 10:01:01"), "Container1")

    def given_two_events_with_same_start_time(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-06-01 10:01:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-04-01 10:01:01"), "Container1")

    def given_two_events_with_nonoverlapping_periods(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-01-01 10:01:01"),
                                  self.time("2000-02-01 10:01:01"), "Container1")
        self.subevent2 = Subevent(self.db.get_time_type(),
                                  self.time("2000-03-01 10:01:01"),
                                  self.time("2000-04-01 10:01:01"), "Container1")

    def given_subevent1(self):
        self.subevent1 = Subevent(self.db.get_time_type(),
                                  self.time("2000-01-01 10:01:01"),
                                  self.time("2000-02-01 10:01:01"), "Container1")

    def assert_equal_start(self, obj1, obj2):
        self.assertEqual(obj1.time_period.start_time, obj2.time_period.start_time)

    def assert_equal_end(self, obj1, obj2):
        self.assertEqual(obj1.time_period.end_time, obj2.time_period.end_time)

    def assert_start_equals_end(self, obj1, obj2):
        self.assertEqual(obj1.time_period.start_time, obj2.time_period.end_time)

    def assert_start_equals_start(self, obj1, obj2):
        self.assertEqual(obj1.time_period.start_time, obj2.time_period.start_time)

    def time(self, tm):
        return self.db.get_time_type().parse_time(tm)

    def setUp(self):
        self.db = MemoryDB()
        self.now = self.db.get_time_type().now()
        self.time_type = self.db.get_time_type()
Example #40
0
class MemoryDBSpec(unittest.TestCase):

    def testInitialState(self):
        db = MemoryDB()
        self.assertEquals(db.path, "")
        self.assertEquals(db.displayed_period, None)
        self.assertEquals(db.hidden_categories, [])
        self.assertEquals(db.is_read_only(), False)
        self.assertEquals(db.supported_event_data(), ["description", "icon", "alert", "hyperlink"])
        self.assertEquals(db.search(""), [])
        self.assertEquals(db.get_all_events(), [])
        self.assertEquals(db.get_first_event(), None)
        self.assertEquals(db.get_last_event(), None)
        self.assertEquals(db.get_categories(), [])

    def testLoadSaveViewProperties(self):
        # Make sure the database contains categories
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        # Set up a view properties object that simulates having selected a
        # specific period and hidden one category
        vp = ViewProperties()
        vp.set_category_visible(self.c1, False)
        start = datetime(2010, 3, 23)
        end = datetime(2010, 3, 24)
        tp = TimePeriod(self.db.get_time_type(), start, end)
        vp.displayed_period = tp
        # Save these properties and assert that the database fields are written
        # correctly
        self.db.save_view_properties(vp)
        self.assertEquals(self.db.displayed_period, tp)
        self.assertEquals(self.db.hidden_categories, [self.c1])
        # Load view properties from db simulating that this db was just loaded
        # into memory and the view is being configured
        new_vp = ViewProperties()
        self.db.load_view_properties(new_vp)
        self.assertFalse(new_vp.category_visible(self.c1))
        self.assertTrue(new_vp.category_visible(self.c2))
        self.assertEquals(new_vp.displayed_period, self.db.displayed_period)
        # Assert virtual _save method called: 2 save categories, 1 save view
        # properties
        self.assertEquals(self.db._save.call_count, 3)

    def testSaveInvalidDisplayedPeriod(self):
        # Assign a zero-period as displayed period
        vp = ViewProperties()
        start = datetime(2010, 3, 23)
        end = datetime(2010, 3, 23)
        tp = TimePeriod(PyTimeType(), start, end)
        vp.displayed_period = tp
        # Assert error when trying to save
        self.assertRaises(TimelineIOError, self.db.save_view_properties, vp)

    def testGetSetDisplayedPeriod(self):
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 3, 23),
                        datetime(2010, 3, 24))
        self.db._set_displayed_period(tp)
        # Assert that we get back the same period
        self.assertEquals(self.db._get_displayed_period(), tp)
        # Assert that the period is correctly loaded into ViewProperties
        vp = ViewProperties()
        self.db.load_view_properties(vp)
        self.assertEquals(vp.displayed_period, tp)

    def testGetSetHiddenCategories(self):
        # Assert that we cannot include categories not in the db
        self.assertRaises(ValueError, self.db._set_hidden_categories, [self.c1])
        self.db._set_hidden_categories([])
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        self.db._set_hidden_categories([self.c1])
        # Assert that the returned list is the same
        self.assertEquals(self.db._get_hidden_categories(), [self.c1])
        # Assert that category visibility information is correctly written to
        # ViewProperties
        vp = ViewProperties()
        self.db.load_view_properties(vp)
        self.assertFalse(vp.category_visible(self.c1))
        self.assertTrue(vp.category_visible(self.c2))

    def testSaveNewCategory(self):
        self.db.save_category(self.c1)
        self.assertTrue(self.c1.has_id())
        self.assertEqual(self.db.get_categories(), [self.c1])
        self.assertEqual(self.db_listener.call_count, 1)
        # Assert virtual _save method called: 1 save category
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveExistingCategory(self):
        self.db.save_category(self.c1)
        id_before = self.c1.id
        self.c1.name = "new name"
        self.db.save_category(self.c1)
        self.assertEqual(id_before, self.c1.id)
        self.assertEqual(self.db.get_categories(), [self.c1])
        self.assertEqual(self.db_listener.call_count, 2) # 2 save
        # Assert virtual _save method called: 2 save category
        self.assertEquals(self.db._save.call_count, 2)

    def testSaveNonExistingCategory(self):
        other_db = MemoryDB()
        other_db.save_category(self.c1)
        # It has id but is not in this db
        self.assertRaises(TimelineIOError, self.db.save_category, self.c1)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testSaveCategoryWithUnknownParent(self):
        self.c1.parent = self.c2
        # c2 not in db so we should get exception
        self.assertRaises(TimelineIOError, self.db.save_category, self.c1)
        # But after c2 is added everything is fine
        self.db.save_category(self.c2)
        self.db.save_category(self.c1)

    def testSaveCategoryWithParentChange(self):
        # Start with this hierarchy:
        # c1
        #   c11
        #     c111
        #   c12
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        c111 = Category("c111", (255, 0, 0), None, True, parent=c11)
        c12 = Category("c12", (255, 0, 0), None, True, parent=c1)
        self.db.save_category(c1)
        self.db.save_category(c11)
        self.db.save_category(c111)
        self.db.save_category(c12)
        # Changing c11's parent to c12 should create the following tree:
        # c1
        #   c12
        #     c11
        #       c111
        c11.parent = c12
        self.db.save_category(c11)
        self.assertEquals(c1.parent, None)
        self.assertEquals(c12.parent, c1)
        self.assertEquals(c11.parent, c12)
        self.assertEquals(c111.parent, c11)
        # Changing c11's parent to c111 should raise exception since that would
        # create a circular parent link.
        c11.parent = c111
        self.assertRaises(TimelineIOError, self.db.save_category, c11)

    def testDeleteExistingCategory(self):
        # Add two categories to the db
        self.db.save_category(self.c1)
        self.db.save_category(self.c2)
        # Make category 1 hidden
        vp = ViewProperties()
        vp.set_category_visible(self.c1, False)
        self.db.save_view_properties(vp)
        # Assert both categories in db
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 2)
        self.assertTrue(self.c1 in categories)
        self.assertTrue(self.c2 in categories)
        # Remove first (by category)
        self.db.delete_category(self.c1)
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 1)
        self.assertTrue(self.c2 in categories)
        self.assertFalse(self.c1.has_id())
        self.assertFalse(self.c1 in self.db.hidden_categories)
        # Remove second (by id)
        self.db.delete_category(self.c2.id)
        categories = self.db.get_categories()
        self.assertEquals(len(categories), 0)
        self.assertFalse(self.c2.has_id())
        # Check events
        self.assertEqual(self.db_listener.call_count, 4) # 2 save, 2 delete
        # Assert virtual _save method called: 2 save category, 1 save view
        # properties, 2 delete categories
        self.assertEquals(self.db._save.call_count, 5)

    def testDeleteNonExistingCategory(self):
        self.assertRaises(TimelineIOError, self.db.delete_category, self.c1)
        self.assertRaises(TimelineIOError, self.db.delete_category, 5)
        other_db = MemoryDB()
        other_db.save_category(self.c2)
        self.assertRaises(TimelineIOError, self.db.delete_category, self.c2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDeleteCategoryWithParent(self):
        # Create hierarchy:
        # c1
        #   c11
        #   c12
        #     c121
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        c12 = Category("c12", (255, 0, 0), None, True, parent=c1)
        c121 = Category("c121", (255, 0, 0), None, True, parent=c12)
        self.db.save_category(c1)
        self.db.save_category(c11)
        self.db.save_category(c12)
        self.db.save_category(c121)
        # Delete c12 should cause c121 to get c1 as parent
        self.db.delete_category(c12)
        self.assertEquals(c121.parent, c1)
        # Delete c1 should cause c11, and c121 to be parentless
        self.db.delete_category(c1)
        self.assertEquals(c11.parent, None)
        self.assertEquals(c121.parent, None)

    def testDelteCategoryWithEvent(self):
        # Create hierarchy:
        # c1
        #   c11
        c1 = Category("c1", (255, 0, 0), None, True, parent=None)
        c11 = Category("c11", (255, 0, 0), None, True, parent=c1)
        self.db.save_category(c1)
        self.db.save_category(c11)
        # Create event belonging to c11
        self.e1.category = c11
        self.db.save_event(self.e1)
        # Delete c11 should cause e1 to get c1 as category
        self.db.delete_category(c11)
        self.assertEquals(self.e1.category, c1)
        # Delete c1 should cause e1 to have no category
        self.db.delete_category(c1)
        self.assertEquals(self.e1.category, None)

    def testSaveEventUnknownCategory(self):
        # A new
        self.e1.category = self.c1
        self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
        # An existing
        self.db.save_event(self.e2)
        self.e2.category = self.c1
        self.assertRaises(TimelineIOError, self.db.save_event, self.e2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveNewEvent(self):
        self.db.save_event(self.e1)
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 14))
        self.assertTrue(self.e1.has_id())
        self.assertEqual(self.db.get_events(tp), [self.e1])
        self.assertEqual(self.db.get_all_events(), [self.e1])
        self.assertEqual(self.db_listener.call_count, 1) # 1 save
        # Assert virtual _save method called: 1 save event
        self.assertEquals(self.db._save.call_count, 1)

    def testSaveExistingEvent(self):
        self.db.save_event(self.e1)
        id_before = self.e1.id
        self.e1.text = "new text"
        self.db.save_event(self.e1)
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 14))
        self.assertEqual(id_before, self.e1.id)
        self.assertEqual(self.db.get_events(tp), [self.e1])
        self.assertEqual(self.db.get_all_events(), [self.e1])
        self.assertEqual(self.db_listener.call_count, 2) # 1 save
        # Assert virtual _save method called: 2 save event
        self.assertEquals(self.db._save.call_count, 2)

    def testSaveNonExistingEvent(self):
        other_db = MemoryDB()
        other_db.save_event(self.e1)
        # It has id but is not in this db
        self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDeleteExistingEvent(self):
        tp = TimePeriod(self.db.get_time_type(), datetime(2010, 2, 12),
                        datetime(2010, 2, 15))
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        # Assert both in db
        self.assertEquals(len(self.db.get_events(tp)), 2)
        self.assertTrue(self.e1 in self.db.get_events(tp))
        self.assertTrue(self.e2 in self.db.get_events(tp))
        # Delete first (by event)
        self.db.delete_event(self.e1)
        self.assertFalse(self.e1.has_id())
        self.assertEquals(len(self.db.get_events(tp)), 1)
        self.assertTrue(self.e2 in self.db.get_events(tp))
        # Delete second (by id)
        self.db.delete_event(self.e2.id)
        self.assertFalse(self.e2.has_id())
        self.assertEquals(len(self.db.get_events(tp)), 0)
        # Check events
        self.assertEqual(self.db_listener.call_count, 4) # 2 save, 2 delete
        # Assert virtual _save method called: 2 save event, 2 delete event
        self.assertEquals(self.db._save.call_count, 4)

    def testDeleteNonExistingEvent(self):
        self.assertRaises(TimelineIOError, self.db.delete_event, self.e1)
        self.assertRaises(TimelineIOError, self.db.delete_event, 5)
        other_db = MemoryDB()
        other_db.save_event(self.e2)
        self.assertRaises(TimelineIOError, self.db.delete_event, self.c2)
        # Assert virtual _save method not called
        self.assertEquals(self.db._save.call_count, 0)

    def testDisableEnableSave(self):
        self.db.save_category(self.c1)
        # Assert virtual _save method called: save enabled by default
        self.assertEquals(self.db._save.call_count, 1)
        self.db.disable_save()
        self.db.save_category(self.c1)
        self.assertEquals(self.db._save.call_count, 1) # still 1
        self.db.enable_save()
        self.assertEquals(self.db._save.call_count, 2)
        # Now do the same thing but tell enable not to call save
        self.db.disable_save()
        self.db.save_category(self.c1)
        self.db.enable_save(False)
        self.assertEquals(self.db._save.call_count, 2)
        # Enabling when enabled should not have any effect
        self.db.enable_save()
        self.assertEquals(self.db._save.call_count, 2)

    def testMoveEventForward(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_after_event(self.e1, self.e2)
        self.assertTrue(self.db.events[0] == self.e2 )
        self.assertTrue(self.db.events[1] == self.e1 )
        self.assertTrue(self.db.events[2] == self.e3 )

    def testMoveEventToEnd(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_after_event(self.e1, self.e3)
        self.assertTrue(self.db.events[0] == self.e2 )
        self.assertTrue(self.db.events[1] == self.e3 )
        self.assertTrue(self.db.events[2] == self.e1 )

    def testMoveEventBackward(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e2, self.e1)
        self.assertTrue(self.db.events[0] == self.e2 )
        self.assertTrue(self.db.events[1] == self.e1 )
        self.assertTrue(self.db.events[2] == self.e3 )

    def testMoveEventToBeginning(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e3, self.e1)
        self.assertTrue(self.db.events[0] == self.e3 )
        self.assertTrue(self.db.events[1] == self.e1 )
        self.assertTrue(self.db.events[2] == self.e2 )

    def testMoveEventToOriginalPlace(self):
        self.db.save_event(self.e1)
        self.db.save_event(self.e2)
        self.db.save_event(self.e3)
        self.db.place_event_before_event(self.e2, self.e2)
        self.assertTrue(self.db.events[0] == self.e1 )
        self.assertTrue(self.db.events[1] == self.e2 )
        self.assertTrue(self.db.events[2] == self.e3 )

    def testEventShouldNotBeFuzzyByDefault(self):
        self.assertFalse(self.e1.fuzzy)

    def testEventShouldNotBeLockedByDefault(self):
        self.assertFalse(self.e1.locked)

    def setUp(self):
        self.db = MemoryDB()
        self.db._save = Mock()
        self.db_listener = Mock()
        self.c1 = Category("work", (255, 0, 0), None, True)
        self.c2 = Category("private", (0, 255, 0), None, True)
        self.e1 = Event(self.db.get_time_type(), datetime(2010, 2, 13), datetime(2010, 2, 13),
                        "holiday")
        self.e2 = Event(self.db.get_time_type(), datetime(2010, 2, 14), datetime(2010, 2, 14),
                        "work starts")
        self.e3 = Event(self.db.get_time_type(), datetime(2010, 2, 15), datetime(2010, 2, 16),
                        "period")
        self.db.register(self.db_listener)
Example #41
0
 def setUp(self):
     self.db = MemoryDB()
     self.view_properties = ViewProperties()
     self.given_number_of_events_stackable_is(5)
 def setUp(self):
     self.view = Mock(EventEditorDialog)
     self.event_repository = Mock(EventRepository)
     self.timeline = MemoryDB()