# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Timeline is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Timeline. If not, see <http://www.gnu.org/licenses/>.
from unittest.mock import Mock
from timelinelib.canvas.data.memorydb.db import MemoryDB
from timelinelib.canvas.data.exceptions import TimelineIOError
from timelinelib.canvas.drawing.viewproperties import ViewProperties
from timelinelib.test.cases.unit import UnitTestCase
from timelinelib.test.utils import a_category_with
from timelinelib.test.utils import a_container
from timelinelib.test.utils import a_gregorian_era
from timelinelib.test.utils import a_gregorian_era_with
from timelinelib.test.utils import an_event_with
from timelinelib.test.utils import gregorian_period
from timelinelib.repositories.dbwrapper import category_tree
[docs]class describe_memory_db(UnitTestCase):
[docs] def testInitialState(self):
db = MemoryDB()
self.assertEqual(db.path, "")
self.assertEqual(db.displayed_period, None)
self.assertEqual(db.get_hidden_categories(), [])
self.assertEqual(db.is_read_only(), False)
self.assertEqual(db.search(""), [])
self.assertEqual(db.get_all_events(), [])
self.assertEqual(db.get_first_event(), None)
self.assertEqual(db.get_last_event(), None)
self.assertEqual(db.get_categories(), [])
[docs] 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)
tp = gregorian_period("23 Mar 2010", "24 Mar 2010")
vp.displayed_period = tp
# Save these properties and assert that the database fields are written
# correctly
self.db.save_view_properties(vp)
self.assertEqual(self.db.displayed_period, tp)
self.assertEqual(self.db.get_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.is_category_visible(self.c1))
self.assertTrue(new_vp.is_category_visible(self.c2))
self.assertEqual(new_vp.displayed_period, self.db.displayed_period)
# Assert save called: 2 save categories, 1 save view properties
self.assertEqual(self.save_callback_mock.call_count, 3)
[docs] def testSaveInvalidDisplayedPeriod(self):
# Assign a zero-period as displayed period
vp = ViewProperties()
tp = gregorian_period("23 Mar 2010", "23 Mar 2010")
vp.displayed_period = tp
# Assert error when trying to save
self.assertRaises(TimelineIOError, self.db.save_view_properties, vp)
[docs] def testGetSetDisplayedPeriod(self):
tp = gregorian_period("23 Mar 2010", "24 Mar 2010")
self.db.set_displayed_period(tp)
# Assert that we get back the same period
self.assertEqual(self.db.get_displayed_period(), tp)
# Assert that the period is correctly loaded into ViewProperties
vp = ViewProperties()
self.db.load_view_properties(vp)
self.assertEqual(vp.displayed_period, tp)
[docs] 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.assertEqual(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.is_category_visible(self.c1))
self.assertTrue(vp.is_category_visible(self.c2))
[docs] 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 save called: 1 save category
self.assertEqual(self.save_callback_mock.call_count, 1)
[docs] def testSaveExistingCategory(self):
self.db.save_category(self.c1)
id_before = self.c1.get_id()
self.c1.set_name("new name")
self.db.save_category(self.c1)
self.assertEqual(id_before, self.c1.get_id())
self.assertEqual(self.db.get_categories(), [self.c1])
self.assertEqual(self.db_listener.call_count, 2) # 2 save
# Assert save called: 2 save category
self.assertEqual(self.save_callback_mock.call_count, 2)
[docs] 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 save not called
self.assertEqual(self.save_callback_mock.call_count, 0)
[docs] def testSaveCategoryWithUnknownParent(self):
self.c1.set_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)
[docs] def testSaveCategoryWithParentChange(self):
# Start with this hierarchy:
# c1
# c11
# c111
# c12
c1 = a_category_with(name="c1", parent=None)
c11 = a_category_with(name="c11", parent=c1)
c111 = a_category_with(name="c111", parent=c11)
c12 = a_category_with(name="c12", 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.set_parent(c12)
self.db.save_category(c11)
self.assertEqual(c1._get_parent(), None)
self.assertEqual(c12._get_parent(), c1)
self.assertEqual(c11._get_parent(), c12)
self.assertEqual(c111._get_parent(), c11)
# Changing c11's parent to c111 should raise exception since that would
# create a circular parent link.
c11.set_parent(c111)
self.assertRaises(TimelineIOError, self.db.save_category, c11)
[docs] 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.assertEqual(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.assertEqual(len(categories), 1)
self.assertTrue(self.c2 in categories)
self.assertFalse(self.c1.has_id())
self.assertFalse(self.c1 in self.db.get_hidden_categories())
# Remove second (by id)
self.db.delete_category(self.c2.get_id())
categories = self.db.get_categories()
self.assertEqual(len(categories), 0)
# Check events
self.assertEqual(self.db_listener.call_count, 4) # 2 save, 2 delete
# Assert save called: 2 save category, 1 save view
# properties, 2 delete categories
self.assertEqual(self.save_callback_mock.call_count, 5)
[docs] 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 save not called
self.assertEqual(self.save_callback_mock.call_count, 0)
[docs] def testDeleteCategoryWithParent(self):
# Create hierarchy:
# c1
# c11
# c12
# c121
c1 = a_category_with(name="c1", parent=None)
c11 = a_category_with(name="c11", parent=c1)
c12 = a_category_with(name="c12", parent=c1)
c121 = a_category_with(name="c121", 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.assertEqual(c121.reload().parent, c1)
# Delete c1 should cause c11, and c121 to be parentless
self.db.delete_category(c1)
self.assertEqual(c11.reload().parent, None)
self.assertEqual(c121.reload().parent, None)
[docs] def testDeleteCategoryWithEvent(self):
# Create hierarchy:
# c1
# c11
c1 = a_category_with(name="c1", parent=None)
c11 = a_category_with(name="c11", 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.assertEqual(self.e1.reload().category, c1)
# Delete c1 should cause e1 to have no category
self.db.delete_category(c1)
self.assertEqual(self.e1.reload().category, None)
[docs] def testSaveEventUnknownCategory(self):
# A new
self.e1.set_category(self.c1)
self.assertRaises(TimelineIOError, self.db.save_event, self.e1)
# An existing
self.db.save_event(self.e2)
self.e2.set_category(self.c1)
self.assertRaises(TimelineIOError, self.db.save_event, self.e2)
# Assert save not called
self.assertEqual(self.save_callback_mock.call_count, 1)
[docs] def testSaveNewEvent(self):
self.db.save_event(self.e1)
tp = gregorian_period("12 Feb 2010", "14 Feb 2010")
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 save called: 1 save event
self.assertEqual(self.save_callback_mock.call_count, 1)
[docs] def testSaveExistingEvent(self):
self.db.save_event(self.e1)
id_before = self.e1.get_id()
self.e1.set_text("new text")
self.db.save_event(self.e1)
tp = gregorian_period("12 Feb 2010", "14 Feb 2010")
self.assertEqual(id_before, self.e1.get_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 save called: 2 save event
self.assertEqual(self.save_callback_mock.call_count, 2)
[docs] 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 save not called
self.assertEqual(self.save_callback_mock.call_count, 0)
[docs] def testDeleteExistingEvent(self):
tp = gregorian_period("12 Feb 2010", "15 Feb 2010")
self.db.save_event(self.e1)
self.db.save_event(self.e2)
# Assert both in db
self.assertEqual(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.assertEqual(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.get_id())
self.assertEqual(len(self.db.get_events(tp)), 0)
# Check events
self.assertEqual(self.db_listener.call_count, 4) # 2 save, 2 delete
# Assert save called: 2 save event, 2 delete event
self.assertEqual(self.save_callback_mock.call_count, 4)
[docs] 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.e2)
# Assert save not called
self.assertEqual(self.save_callback_mock.call_count, 0)
[docs] def testEventShouldNotBeFuzzyByDefault(self):
self.assertFalse(self.e1.get_fuzzy())
[docs] def testEventShouldNotBeLockedByDefault(self):
self.assertFalse(self.e1.get_locked())
[docs] def setUp(self):
self.save_callback_mock = Mock()
self.db = MemoryDB()
self.db.register_save_callback(self.save_callback_mock)
self.db_listener = Mock()
self.c1 = a_category_with(name="work")
self.c2 = a_category_with(name="private")
self.e1 = an_event_with(text="holiday", time="13 Feb 2010")
self.e2 = an_event_with(text="work starts", time="13 Feb 2010")
self.e3 = an_event_with(text="period", time="13 Feb 2010")
self.db.register(self.db_listener)
[docs]class describe_querying(UnitTestCase):
[docs] def test_can_get_first_event(self):
aug_event = an_event_with(time="30 Aug 2010")
jan_event = an_event_with(time="1 Jan 2010")
self.db.save_event(aug_event)
self.db.save_event(jan_event)
self.assertEqual(self.db.get_first_event(), jan_event)
[docs] def test_can_get_last_event(self):
jan_event = an_event_with(time="1 Jan 2010")
aug_event = an_event_with(time="30 Aug 2010")
self.db.save_event(aug_event)
self.db.save_event(jan_event)
self.assertEqual(self.db.get_last_event(), aug_event)
[docs] def test_can_get_subevents(self):
self.db.save_events(
a_container(name="con", category=None, sub_events=[
("sub1", None),
])
)
all_events = self.db.get_all_events()
containers = [e.text for e in all_events if e.is_container()]
subevents = [e.text for e in all_events if e.is_subevent()]
self.assertEqual((containers, subevents), (["con"], ["sub1"]))
[docs] def setUp(self):
self.db = MemoryDB()
[docs]class describe_searching(UnitTestCase):
[docs] def test_find_events_with_matching_text(self):
holiday_event = an_event_with(text="holiday in the alps")
football_event = an_event_with(text="football training")
self.db.save_event(holiday_event)
self.db.save_event(football_event)
self.assertEqual(self.db.search("holiday"), [holiday_event])
[docs] def setUp(self):
self.db = MemoryDB()
[docs]class describe_undo(UnitTestCase):
[docs] def test_undo_enabled(self):
self.assertFalse(self.db.undo_enabled())
self.db.save_event(an_event_with())
self.assertTrue(self.db.undo_enabled())
[docs] def test_redo_enabled(self):
self.assertFalse(self.db.redo_enabled())
self.db.save_event(an_event_with())
self.db.undo()
self.assertTrue(self.db.redo_enabled())
[docs] def test_can_not_undo_non_modified_timeline(self):
self.db.undo()
self.assertFalse(self.db_changed_listener.called)
[docs] def test_can_undo_added_event(self):
self.db.save_event(an_event_with(text="football"))
self.assertHasEvents(["football"])
self.db.undo()
self.assertHasEvents([])
[docs] def test_can_redo_undo(self):
self.db.save_event(an_event_with(text="football"))
self.assertHasEvents(["football"])
self.db.undo()
self.assertHasEvents([])
self.db.redo()
self.assertHasEvents(["football"])
[docs] def assertHasEvents(self, event_texts):
actual_event_texts = [e.get_text() for e in self.db.get_all_events()]
self.assertEqual(actual_event_texts, event_texts)
[docs] def setUp(self):
self.db_changed_listener = Mock()
self.db = MemoryDB()
self.db.listen_for_any(self.db_changed_listener)
[docs]class describe_importing(UnitTestCase):
[docs] def test_importing_empty_db_does_nothing(self):
self.base_db.import_db(self.import_db)
self.assertEqual(self.base_db.get_categories(), [])
self.assertEqual(self.base_db.get_all_events(), [])
[docs] def test_events_are_imported(self):
self.import_db.save_event(an_event_with(text="dentist"))
self.import_db.save_event(an_event_with(text="golf"))
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"dentist ()",
"golf ()",
])
[docs] def test_subevents_are_imported(self):
category = self.import_db.new_category(name="cat").save()
container = self.import_db.new_container(text="cont").save()
self.import_db.new_subevent(text="sub1", container=container).save()
self.import_db.new_subevent(text="sub2", category=category, container=container).save()
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"cont () [sub1 (), sub2 (cat)]",
])
[docs] def test_events_are_imported_into_existing_categories(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_event(an_event_with(
text="dentist",
category=self.import_db.get_category_by_name("work")))
self.base_db.save_category(a_category_with(name="work"))
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"dentist (work)",
])
self.assertCategoryTreeIs([
("work", [])
])
[docs] def test_new_categories_are_created_if_they_do_not_exist(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_event(an_event_with(
text="dentist",
category=self.import_db.get_category_by_name("work")))
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"dentist (work)",
])
self.assertCategoryTreeIs([
("work", [])
])
[docs] def test_new_categories_preserve_parent(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_category(a_category_with(
name="paper work",
parent=self.import_db.get_category_by_name("work")))
self.import_db.save_event(an_event_with(
text="write article",
category=self.import_db.get_category_by_name("paper work")))
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"write article (paper work)",
])
self.assertCategoryTreeIs([
("work", [
("paper work", []),
])
])
[docs] def test_new_categories_are_attached_to_existing_ones(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_category(a_category_with(
name="paper work",
parent=self.import_db.get_category_by_name("work")))
self.import_db.save_event(an_event_with(
text="write article",
category=self.import_db.get_category_by_name("paper work")))
self.base_db.save_category(a_category_with(name="work"))
self.base_db.import_db(self.import_db)
self.assertEventListIs([
"write article (paper work)",
])
self.assertCategoryTreeIs([
("work", [
("paper work", []),
])
])
[docs] def test_categories_without_events_are_not_imported(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_category(a_category_with(
name="paper work",
parent=self.import_db.get_category_by_name("work")))
self.base_db.import_db(self.import_db)
self.assertCategoryTreeIs([])
[docs] def test_save_is_only_called_once(self):
self.import_db.save_category(a_category_with(name="work"))
self.import_db.save_category(a_category_with(name="private"))
self.base_db.import_db(self.import_db)
self.assertEqual(self.base_db_save_callback.call_count, 1)
[docs] def test_fails_if_type_type_missmatch(self):
self.import_db.set_time_type(Mock())
self.assertRaises(Exception, self.base_db.import_db, self.import_db)
[docs] def assertCategoryTreeIs(self, expected_tree):
tree = category_tree(self.base_db.get_categories())
self.assertEqual(replace_category_with_name(tree), expected_tree)
[docs] def assertEventListIs(self, expected_list):
def format_event(event):
parts = []
parts.append("%s" % event.get_text())
parts.append("(%s)" % category_name(event))
if event.is_container():
parts.append("[%s]" % ", ".join(
format_event(subevent)
for subevent
in event.subevents
))
return " ".join(parts)
def category_name(event):
if event.get_category():
return event.get_category().get_name()
else:
return ""
actual_list = [
format_event(event)
for event
in self.base_db.get_all_events()
if not event.is_subevent()
]
self.assertEqual(sorted(actual_list), expected_list)
[docs] def setUp(self):
self.base_db_save_callback = Mock()
self.base_db = MemoryDB()
self.base_db.register_save_callback(self.base_db_save_callback)
self.import_db_save_callback = Mock()
self.import_db = MemoryDB()
self.import_db.register_save_callback(self.import_db_save_callback)
[docs]class describe_moving_events(UnitTestCase):
[docs] def test_place_after(self):
self.db.place_event_after_event(self.e1, self.e2)
self.assertEventOrderIs([
self.e2,
self.e1,
self.e3,
])
[docs] def test_place_after_to_end(self):
self.db.place_event_after_event(self.e1, self.e3)
self.assertEventOrderIs([
self.e2,
self.e3,
self.e1,
])
[docs] def test_place_after_when_already_after(self):
self.db.place_event_after_event(self.e3, self.e1)
self.assertEventOrderIs([
self.e1,
self.e2,
self.e3,
])
[docs] def test_place_after_when_same(self):
self.db.place_event_after_event(self.e2, self.e2)
self.assertEventOrderIs([
self.e1,
self.e2,
self.e3,
])
[docs] def test_place_before(self):
self.db.place_event_before_event(self.e2, self.e1)
self.assertEventOrderIs([
self.e2,
self.e1,
self.e3,
])
[docs] def test_place_before_to_beginning(self):
self.db.place_event_before_event(self.e3, self.e1)
self.assertEventOrderIs([
self.e3,
self.e1,
self.e2,
])
[docs] def test_place_before_when_already_before(self):
self.db.place_event_before_event(self.e1, self.e3)
self.assertEventOrderIs([
self.e1,
self.e2,
self.e3,
])
[docs] def test_place_before_when_same(self):
self.db.place_event_before_event(self.e2, self.e2)
self.assertEventOrderIs([
self.e1,
self.e2,
self.e3,
])
[docs] def assertEventOrderIs(self, expected_events):
# Check both get_all_events and get_events to ensure they are sorted
all_event_texts = [
event.text for event in self.db.get_all_events()
]
whole_period_event_texts = [
event.text for event in self.db.get_events(self.whole_period)
]
expected_event_texts = [
event.text for event in expected_events
]
self.assertEqual(all_event_texts, whole_period_event_texts)
self.assertEqual(whole_period_event_texts, expected_event_texts)
[docs] def setUp(self):
self.db = MemoryDB()
self.e1 = an_event_with(text="e1")
self.e2 = an_event_with(text="e2")
self.e3 = an_event_with(text="e3")
self.whole_period = self.e1.time_period # All events have same period
self.db.save_event(self.e1)
self.db.save_event(self.e2)
self.db.save_event(self.e3)
self.assertEventOrderIs([
self.e1,
self.e2,
self.e3,
])
[docs]class describe_query(UnitTestCase):
[docs] def test_get_container(self):
container = self.db.find_event_with_id(self.container.id)
# Check that it loads the container
self.assertEqual(container.text, "container")
# Check that it loads all subevents
self.assertEqual(
[subevent.text for subevent in container.subevents],
["sub1", "sub2"]
)
# Check that the subevents refer to the same container
for subevent in container.subevents:
self.assertEqual(id(subevent.container), id(container))
[docs] def test_get_subevent(self):
sub1, sub2 = self.db.find_event_with_ids([self.sub1.id, self.sub2.id])
# Check that it loads the subevents
self.assertEqual(sub1.text, "sub1")
self.assertEqual(sub2.text, "sub2")
# Check that it loads the same container
self.assertTrue(sub1.container is sub2.container)
self.assertEqual(sub1.container.text, "container")
# Check that it loads the same category
self.assertTrue(sub1.category is sub2.category)
self.assertEqual(sub1.category.name, "category")
# Check that the subevents are referred to by the container
self.assertEqual(
[id(subevent) for subevent in sub1.container.subevents],
[id(sub1), id(sub2)]
)
[docs] def setUp(self):
self.db = MemoryDB()
self.container = self.db.new_container(
text="container"
).save()
self.category = self.db.new_category(
name="category"
).save()
self.sub1 = self.db.new_subevent(
text="sub1",
category=self.category,
container=self.container
).save()
self.sub2 = self.db.new_subevent(
text="sub2",
category=self.category,
container=self.container
).save()
[docs]class describe_eras(UnitTestCase):
[docs] def test_save(self):
self.assertEqual(len(self.db.get_all_eras()), 0)
self.db.save_era(a_gregorian_era())
self.assertEqual(len(self.db.get_all_eras()), 1)
[docs] def test_delete(self):
self.db.save_era(a_gregorian_era())
all_eras = self.db.get_all_eras()
self.assertEqual(len(all_eras), 1)
self.db.delete_era(all_eras[0])
self.assertEqual(len(self.db.get_all_eras()), 0)
[docs] def test_retains_ends_today(self):
self.db.save_era(a_gregorian_era_with(ends_today=True))
self.assertEqual(self.db.get_all_eras()[0].ends_today(), True)
[docs] def setUp(self):
self.db = MemoryDB()
[docs]def replace_category_with_name(tree):
return [(category.get_name(), replace_category_with_name(child_tree))
for (category, child_tree) in tree]