def test_creating_new_version_of_the_subdir(self): t1 = get_utc_now() subdir1_v1 = Directory.objects.current.get(name__startswith='subdir1') subdir1_v2 = subdir1_v1.clone() subdir1_v2.name = 'subdir1.v2' subdir1_v2.save() sleep(0.1) t2 = get_utc_now() # Count all Directory instance versions: # 3 initial versions + 2 subdirs added to parentdir (implies a clone) + 1 subdir1 that was explicitely cloned = 6 self.assertEqual(6, Directory.objects.all().count()) # at t1 there is no directory named 'subdir1.v2' parentdir_at_t1 = Directory.objects.as_of(t1).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.count()) for subdir in parentdir_at_t1.directory_set.all(): self.assertNotEqual('subdir1.v2', subdir.name) # at t2 there must be 2 directories and ... parentdir_at_t2 = Directory.objects.as_of(t2).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t2.directory_set.count()) # ... and one of then is named 'subdir1.v2' if six.PY2: matches = itertools.ifilter(lambda x: x.name == 'subdir1.v2', parentdir_at_t2.directory_set.all()) if six.PY3: matches = filter(lambda x: x.name == 'subdir1.v2', parentdir_at_t2.directory_set.all()) self.assertEqual(1, len(list(matches)))
def test_adding_more_subdir(self): t1 = get_utc_now() sleep(0.1) current_parentdir = Directory.objects.current.get( name__startswith='parent') self.assertEqual(2, current_parentdir.directory_set.all().count()) sleep(0.1) Directory.objects.create(name='subdir3.v1', parent=current_parentdir) t2 = get_utc_now() # there must not be 3 subdirectories in the parent directory, since current_parentdir holds the state # at t1 - prior to adding "subdir3" self.assertNotEqual(3, current_parentdir.directory_set.all().count()) # If we wanted this comparision to be equal, we'd need to removed the 'as_of' timestamp within 'current_parentdir' # Let's do that: current_parentdir.as_of = None self.assertEqual(3, current_parentdir.directory_set.all().count()) # there should be 2 directories in the parent directory at time t1 parentdir_at_t1 = Directory.objects.as_of(t1).filter( name='parent.v1').first() self.assertEqual(2, parentdir_at_t1.directory_set.all().count()) # there should be 3 directories in the parent directory at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).filter( name='parent.v1').first() self.assertEqual(3, parentdir_at_t2.directory_set.all().count())
def test_creating_new_version_of_parent_directory(self): t1 = get_utc_now() sleep(0.1) parentdir_v1 = Directory.objects.get(name__startswith='parent.v1') self.assertTrue(parentdir_v1.is_current) parentdir_v2 = parentdir_v1.clone() parentdir_v2.name = 'parent.v2' parentdir_v2.save() t2 = get_utc_now() # 1 parent dir, 2 subdirs, 2 new versions after linking then together # and 1 new version of the parent dir self.assertEqual(6, Directory.objects.all().count()) self.assertTrue(parentdir_v2.is_current) # We didn't change anything to the subdirs so there must be 2 subdirs in # the parent at time t1... parentdir_at_t1 = Directory.objects.as_of(t1).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.count()) # ... and at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t2.directory_set.count())
def test_removing_and_then_adding_again_same_player(self): t1 = get_utc_now() sleep(0.1) p1 = self.p1.clone() p1.team = None p1.name = 'p1.v2' p1.save() t2 = get_utc_now() sleep(0.1) p1 = p1.clone() p1.team = self.team p1.name = 'p1.v3' p1.save() t3 = get_utc_now() # there should be 2 players in the team if we put ourselves back at time t1 team_at_t1 = Team.objects.as_of(t1).first() self.assertEqual(2, team_at_t1.player_set.all().count()) # there should be 1 players in the team if we put ourselves back at time t2 team_at_t2 = Team.objects.as_of(t2).first() self.assertEqual(1, team_at_t2.player_set.all().count()) p1_at_t2 = Player.objects.as_of(t2).get(name__startswith='p1') self.assertIsNone(p1_at_t2.team) # there should be 2 players in the team if we put ourselves back at time t3 team_at_t3 = Team.objects.as_of(t3).first() self.assertEqual(2, team_at_t3.player_set.all().count())
def setUp(self): billy = Pupil.objects.create(name='Billy', phone_number='123') erika = Pupil.objects.create(name='Erika', phone_number='456') ms_sue = Teacher.objects.create(name='Ms. Sue', domain='English') ms_klishina = Teacher.objects.create(name='Ms. Klishina', domain='Russian') mr_kazmirek = Teacher.objects.create(name='Mr. Kazmirek', domain='Math') ms_mayer = Teacher.objects.create(name='Ms. Mayer', domain='Chemistry') self.t0 = get_utc_now() sleep(0.1) billy.language_teachers.add(ms_sue) erika.science_teachers.add(mr_kazmirek, ms_mayer) self.t1 = get_utc_now() sleep(0.1) billy.language_teachers.add(ms_klishina) billy.language_teachers.remove(ms_sue) self.t2 = get_utc_now() sleep(0.1) erika.science_teachers.remove(ms_mayer) self.t3 = get_utc_now()
def test_simple_filter_using_q_objects(self): """ This tests explicitely the filtering of a versioned object using Q objects. However, since this is done implicetly with every call to 'as_of', this test is redundant but is kept for explicit test coverage """ t1 = get_utc_now() sleep(0.1) p1 = Player.objects.current.get(name__startswith='p1') self.team.player_set.remove(p1) p1 = Player.objects.current.get(name__startswith='p1') p1.name = 'p1.v2' p1.save() t2 = get_utc_now() sleep(0.1) t1_players = list( Player.objects.as_of(t1).filter( Q(name__startswith='p1') | Q(name__startswith='p2')).values_list('name', flat=True)) self.assertEqual(2, len(t1_players)) self.assertListEqual(sorted(t1_players), sorted(['p1.v1', 'p2.v1']))
def test_creating_new_version_of_the_player(self): t1 = get_utc_now() sleep(0.1) p1 = self.p1.clone() p1.name = 'p1.v2' p1.save() sleep(0.1) t2 = get_utc_now() self.assertEqual(3, Player.objects.all().count()) # at t1 there is no player named 'p1.v2' team = Team.objects.as_of(t1).first() self.assertEqual(2, team.player_set.count()) for player in team.player_set.all(): self.assertNotEqual(u'p1.v2', six.u(str(player.name))) # at t2 there must be a 2 players and on of them is named 'p1.v2' team = Team.objects.as_of(t2).first() self.assertEqual(2, team.player_set.count()) if six.PY2: matches = itertools.ifilter(lambda x: x.name == 'p1.v2', team.player_set.all()) if six.PY3: matches = filter(lambda x: x.name == 'p1.v2', team.player_set.all()) self.assertEqual(1, len(list(matches)))
def test_creating_new_version_of_parent_directory(self): t1 = get_utc_now() sleep(0.1) parentdir_v1 = Directory.objects.get(name__startswith='parent.v1') self.assertTrue(parentdir_v1.is_current) parentdir_v2 = parentdir_v1.clone() parentdir_v2.name = 'parent.v2' parentdir_v2.save() t2 = get_utc_now() # 1 parent dir, 2 subdirs, 2 new versions after linking then together # and 1 new version of the parent dir self.assertEqual(6, Directory.objects.all().count()) self.assertTrue(parentdir_v2.is_current) # We didn't change anything to the subdirs so there must be 2 subdirs in # the parent at time t1... parentdir_at_t1 = Directory.objects.as_of(t1).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.count()) # ... and at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t2.directory_set.count())
def test_creating_new_version_of_the_team(self): t1 = get_utc_now() sleep(0.1) team = self.team.clone() team.name = 't.v2' team.save() t2 = get_utc_now() self.assertEqual(2, Team.objects.all().count()) team = Team.objects.current.first() # Either we can test the version_end_date... self.assertIsNone(team.version_end_date) # ...or the is_current property self.assertTrue(team.is_current) # We didn't change anything to the players so there must be 2 players in # the team at time t1... team_at_t1 = Team.objects.as_of(t1).first() self.assertEqual(2, team_at_t1.player_set.count()) # ... and at time t2 team_at_t2 = Team.objects.as_of(t2).first() self.assertEqual(2, team_at_t2.player_set.count())
def test_removing_and_then_adding_again_same_subdir(self): t1 = get_utc_now() sleep(0.1) subdir1_v1 = Directory.objects.current.get(name__startswith='subdir1') subdir1_v2 = subdir1_v1.clone() subdir1_v2.parent = None subdir1_v2.name = 'subdir1.v2' subdir1_v2.save() t2 = get_utc_now() sleep(0.1) current_parentdir = Directory.objects.current.get(name__startswith='parent') subdir1_v3 = subdir1_v2.clone() subdir1_v3.parent = current_parentdir subdir1_v3.name = 'subdir1.v3' subdir1_v3.save() t3 = get_utc_now() # there should be 2 directories in the parent directory at time t1 parentdir_at_t1 = Directory.objects.as_of(t1).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.all().count()) # there should be 1 directory in the parent directory at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).get(name__startswith='parent') self.assertEqual(1, parentdir_at_t2.directory_set.all().count()) # there should be 2 directories in the parent directory at time t3 parentdir_at_t3 = Directory.objects.as_of(t3).get(name__startswith='parent') self.assertEqual(2, parentdir_at_t3.directory_set.all().count())
def test_adding_more_subdir(self): t1 = get_utc_now() sleep(0.1) current_parentdir = Directory.objects.current.get(name__startswith='parent') self.assertEqual(2, current_parentdir.directory_set.all().count()) sleep(0.1) Directory.objects.create(name='subdir3.v1', parent=current_parentdir) t2 = get_utc_now() # there must not be 3 subdirectories in the parent directory, since current_parentdir holds the state # at t1 - prior to adding "subdir3" self.assertNotEqual(3, current_parentdir.directory_set.all().count()) # If we wanted this comparision to be equal, we'd need to removed the 'as_of' timestamp within 'current_parentdir' # Let's do that: current_parentdir.as_of = None self.assertEqual(3, current_parentdir.directory_set.all().count()) # there should be 2 directories in the parent directory at time t1 parentdir_at_t1 = Directory.objects.as_of(t1).filter(name='parent.v1').first() self.assertEqual(2, parentdir_at_t1.directory_set.all().count()) # there should be 3 directories in the parent directory at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).filter(name='parent.v1').first() self.assertEqual(3, parentdir_at_t2.directory_set.all().count())
def test_filtering_on_the_other_side_of_the_relation(self): t1 = get_utc_now() sleep(0.1) p2 = Player.objects.get(name='p2.v1') self.team.player_set.remove(p2) t2 = get_utc_now() sleep(0.1) p1 = Player.objects.get(name='p1.v1') self.team.player_set.remove(p1) t3 = get_utc_now() sleep(0.1) # Let's get those players back into the game! p1 = Player.objects.current.get(name='p1.v1') p2 = Player.objects.current.get(name='p2.v1') self.team.player_set.add(p1) self.team.player_set.add(p2) t4 = get_utc_now() self.assertEqual(1, Team.objects.all().count()) self.assertEqual(1, Team.objects.as_of(t1).all().count()) self.assertEqual(3, Player.objects.filter(name='p1.v1').all().count()) self.assertEqual(3, Player.objects.filter(name='p2.v1').all().count()) self.assertEqual(1, Player.objects.as_of(t1).filter(name='p1.v1').all().count()) self.assertEqual(1, Player.objects.as_of(t1).filter(name='p2.v1').all().count()) # at t1 there should be one team with two players p1 = Team.objects.as_of(t1).filter(player__name='p1.v1').propagate_querytime().first() self.assertIsNotNone(p1) p2 = Team.objects.as_of(t1).filter(player__name='p2.v1').propagate_querytime().first() self.assertIsNotNone(p2) # at t2 there should be one team with one single player called 'p1.v1' p1 = Team.objects.as_of(t2).filter(player__name='p1.v1').propagate_querytime().first() p2 = Team.objects.as_of(t2).filter(player__name='p2.v1').propagate_querytime().first() self.assertIsNotNone(p1) self.assertIsNone(p2) # at t3 there should be one team with no players p1 = Team.objects.as_of(t3).filter(player__name='p1.v1').propagate_querytime().first() p2 = Team.objects.as_of(t3).filter(player__name='p2.v1').propagate_querytime().first() self.assertIsNone(p1) self.assertIsNone(p2) # at t4 there should be one team with two players again! p1 = Team.objects.as_of(t4).filter(player__name='p1.v1').first() p2 = Team.objects.as_of(t4).filter(player__name='p2.v1').first() self.assertIsNotNone(p1) self.assertIsNotNone(p2)
def clone_shallow(self, forced_version_date=None): """ This behaves like clone(), but misses all the Many2Many-relation-handling. This is a performance optimization for cases in which we have to handle the Many2Many relations by hand anyways. """ if not self.pk: # NOQA raise ValueError('Instance must be saved before it can be cloned') if self.version_end_date: # NOQA raise ValueError( 'This is a historical item and can not be cloned.') if forced_version_date: # NOQA if not self.version_start_date <= forced_version_date <= get_utc_now( ): raise ValueError( 'The clone date must be between the version start date and now.' ) else: forced_version_date = get_utc_now() earlier_version = self later_version = copy.copy(earlier_version) later_version.version_end_date = None later_version.version_start_date = forced_version_date # set earlier_version's ID to a new UUID so the clone (later_version) can # get the old one -- this allows 'head' to always have the original # id allowing us to get at all historic foreign key relationships earlier_version.id = six.u(str(uuid.uuid4())) earlier_version.version_end_date = forced_version_date earlier_version.save() for field in earlier_version._meta.many_to_many: earlier_version.clone_relations_shallow(later_version, field.attname, forced_version_date) if hasattr(earlier_version._meta, 'many_to_many_related'): for rel in earlier_version._meta.many_to_many_related: earlier_version.clone_relations_shallow( later_version, rel.via_field_name, forced_version_date) later_version.save() return later_version
def test_adding_more_player_to_the_team(self): t1 = get_utc_now() sleep(0.1) self.assertEqual(2, self.team.player_set.all().count()) new_player = Player.objects.create(name='p3.v1', team=self.team) t2 = get_utc_now() # there should be 3 players now in the team self.assertEqual(3, self.team.player_set.all().count()) # there should be 2 players in the team at time t1 team_at_t1 = Team.objects.as_of(t1).first() self.assertEqual(2, team_at_t1.player_set.all().count()) # there should be 3 players in the team at time t2 team_at_t2 = Team.objects.as_of(t2).first() self.assertEqual(3, team_at_t2.player_set.all().count())
def clone_shallow(self, forced_version_date=None): """ This behaves like clone(), but misses all the Many2Many-relation-handling. This is a performance optimization for cases in which we have to handle the Many2Many relations by hand anyways. """ if not self.pk: # NOQA raise ValueError('Instance must be saved before it can be cloned') if self.version_end_date: # NOQA raise ValueError('This is a historical item and can not be cloned.') if forced_version_date: # NOQA if not self.version_start_date <= forced_version_date <= get_utc_now(): raise ValueError('The clone date must be between the version start date and now.') else: forced_version_date = get_utc_now() earlier_version = self later_version = copy.copy(earlier_version) later_version.version_end_date = None later_version.version_start_date = forced_version_date # set earlier_version's ID to a new UUID so the clone (later_version) can # get the old one -- this allows 'head' to always have the original # id allowing us to get at all historic foreign key relationships earlier_version.id = six.u(str(uuid.uuid4())) earlier_version.version_end_date = forced_version_date earlier_version.save() for field in earlier_version._meta.many_to_many: earlier_version.clone_relations_shallow(later_version, field.attname, forced_version_date) if hasattr(earlier_version._meta, 'many_to_many_related'): for rel in earlier_version._meta.many_to_many_related: earlier_version.clone_relations_shallow(later_version, rel.via_field_name, forced_version_date) later_version.save() return later_version
def setUp(self): c1 = C1(name='c1.v1') c2 = C2(name='c2.v1') c3 = C3(name='c3.v1') c1.save() c2.save() c3.save() c2.c3s.add(c3) c1.c2s.add(c2) self.t1 = get_utc_now() sleep(0.2) c3a = C3(name='c3a.v1') c3a.save() c2.c3s.add(c3a) sleep(0.2) self.t2 = get_utc_now()
def set_up_one_object_with_3_versions(): b = B.objects.create(name='v1') sleep(0.1) t1 = get_utc_now() b = b.clone() b.name = 'v2' b.save() sleep(0.1) t2 = get_utc_now() b = b.clone() b.name = 'v3' b.save() sleep(0.1) t3 = get_utc_now() return b, t1, t2, t3
def test_removing_and_then_adding_again_same_player_on_related_object( self): t1 = get_utc_now() sleep(0.1) self.team.player_set.remove(self.p1) # Remember: self.p1 was cloned while removing and is not current anymore!! # This property has to be documented, since it's critical for developers! # At this time, there is no mean to replace the contents of self.p1 within the # remove method p1 = Player.objects.current.get(name__startswith='p1') self.assertNotEqual(p1, self.p1) p1.name = 'p1.v2' p1.save() self.p1 = p1 t2 = get_utc_now() sleep(0.1) self.team.player_set.add(self.p1) # Same thing here! Don't rely on an added value! p1 = Player.objects.current.get(name__startswith='p1') p1.name = 'p1.v3' p1.save() t3 = get_utc_now() # there should be 2 players in the team if we put ourselves back at time t1 team_at_t1 = Team.objects.as_of(t1).first() self.assertEqual(2, team_at_t1.player_set.all().count()) # there should be 1 players in the team if we put ourselves back at time t2 team_at_t2 = Team.objects.as_of(t2).first() self.assertEqual(1, team_at_t2.player_set.all().count()) # there should be 2 players in the team if we put ourselves back at time t3 team_at_t3 = Team.objects.as_of(t3).first() self.assertEqual(2, team_at_t3.player_set.all().count())
def test_removing_and_then_adding_again_same_player_on_related_object(self): t1 = get_utc_now() sleep(0.1) self.team.player_set.remove(self.p1) # Remember: self.p1 was cloned while removing and is not current anymore!! # This property has to be documented, since it's critical for developers! # At this time, there is no mean to replace the contents of self.p1 within the # remove method p1 = Player.objects.current.get(name__startswith='p1') self.assertNotEqual(p1, self.p1) p1.name = 'p1.v2' p1.save() self.p1 = p1 t2 = get_utc_now() sleep(0.1) self.team.player_set.add(self.p1) # Same thing here! Don't rely on an added value! p1 = Player.objects.current.get(name__startswith='p1') p1.name = 'p1.v3' p1.save() t3 = get_utc_now() # there should be 2 players in the team if we put ourselves back at time t1 team_at_t1 = Team.objects.as_of(t1).first() self.assertEqual(2, team_at_t1.player_set.all().count()) # there should be 1 players in the team if we put ourselves back at time t2 team_at_t2 = Team.objects.as_of(t2).first() self.assertEqual(1, team_at_t2.player_set.all().count()) # there should be 2 players in the team if we put ourselves back at time t3 team_at_t3 = Team.objects.as_of(t3).first() self.assertEqual(2, team_at_t3.player_set.all().count())
def test_creating_new_version_of_the_subdir(self): t1 = get_utc_now() subdir1_v1 = Directory.objects.current.get(name__startswith='subdir1') subdir1_v2 = subdir1_v1.clone() subdir1_v2.name = 'subdir1.v2' subdir1_v2.save() sleep(0.1) t2 = get_utc_now() # Count all Directory instance versions: # 3 initial versions + 2 subdirs added to parentdir (implies a clone) + 1 subdir1 that was explicitely cloned = 6 self.assertEqual(6, Directory.objects.all().count()) # at t1 there is no directory named 'subdir1.v2' parentdir_at_t1 = Directory.objects.as_of(t1).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.count()) for subdir in parentdir_at_t1.directory_set.all(): self.assertNotEqual('subdir1.v2', subdir.name) # at t2 there must be 2 directories and ... parentdir_at_t2 = Directory.objects.as_of(t2).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t2.directory_set.count()) # ... and one of then is named 'subdir1.v2' if six.PY2: matches = itertools.ifilter(lambda x: x.name == 'subdir1.v2', parentdir_at_t2.directory_set.all()) if six.PY3: matches = filter(lambda x: x.name == 'subdir1.v2', parentdir_at_t2.directory_set.all()) self.assertEqual(1, len(list(matches)))
def test_simple_filter_using_q_objects(self): """ This tests explicitely the filtering of a versioned object using Q objects. However, since this is done implicetly with every call to 'as_of', this test is redundant but is kept for explicit test coverage """ t1 = get_utc_now() sleep(0.1) p1 = Player.objects.current.get(name__startswith='p1') self.team.player_set.remove(p1) p1 = Player.objects.current.get(name__startswith='p1') p1.name = 'p1.v2' p1.save() t2 = get_utc_now() sleep(0.1) t1_players = list( Player.objects.as_of(t1).filter(Q(name__startswith='p1') | Q(name__startswith='p2')).values_list('name', flat=True)) self.assertEqual(2, len(t1_players)) self.assertListEqual(sorted(t1_players), sorted(['p1.v1', 'p2.v1']))
def test_removing_and_then_adding_again_same_subdir(self): t1 = get_utc_now() sleep(0.1) subdir1_v1 = Directory.objects.current.get(name__startswith='subdir1') subdir1_v2 = subdir1_v1.clone() subdir1_v2.parent = None subdir1_v2.name = 'subdir1.v2' subdir1_v2.save() t2 = get_utc_now() sleep(0.1) current_parentdir = Directory.objects.current.get( name__startswith='parent') subdir1_v3 = subdir1_v2.clone() subdir1_v3.parent = current_parentdir subdir1_v3.name = 'subdir1.v3' subdir1_v3.save() t3 = get_utc_now() # there should be 2 directories in the parent directory at time t1 parentdir_at_t1 = Directory.objects.as_of(t1).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t1.directory_set.all().count()) # there should be 1 directory in the parent directory at time t2 parentdir_at_t2 = Directory.objects.as_of(t2).get( name__startswith='parent') self.assertEqual(1, parentdir_at_t2.directory_set.all().count()) # there should be 2 directories in the parent directory at time t3 parentdir_at_t3 = Directory.objects.as_of(t3).get( name__startswith='parent') self.assertEqual(2, parentdir_at_t3.directory_set.all().count())
def setUp(self): c1 = C1(name='c1.v1') c2 = C2(name='c2.v1') c3 = C3(name='c3.v1') c1.save() c2.save() c3.save() self.t0 = get_utc_now() sleep(0.1) c2.c3s.add(c3) c1.c2s.add(c2) self.t1 = get_utc_now() sleep(0.1) c3a = C3(name='c3a.v1') c3a.save() c2.c3s.add(c3a) sleep(0.1) self.t2 = get_utc_now()
def setUp(self): # -------------- t0: mr_biggs = Professor.objects.create(name='Mr. Biggs', address='123 Mainstreet, Somewhere', phone_number='123') ms_piggy = Professor.objects.create(name='Ms. Piggy', address='82 Leicester Street, London', phone_number='987') gym = Classroom.objects.create(name='Sports room', building='The big one over there') phylo = Classroom.objects.create(name='Philosophy lectures', building='The old one') annika = Student.objects.create(name='Annika') annika.professors.add(mr_biggs) annika.professors.add(ms_piggy) annika.classrooms.add(phylo) annika.classrooms.add(gym) benny = Student.objects.create(name='Benny') benny.professors.add(mr_biggs) benny.classrooms.add(gym) sophie = Student.objects.create(name='Sophie') # Sophie doesn't study at that school yet, but is already subscribed self.t0 = get_utc_now() sleep(0.1) # -------------- t1: # Mr. Biggs moves to Berne mr_biggs = mr_biggs.clone() mr_biggs.address = 'Thunplatz, Bern' mr_biggs.save() # Mr. Evans gets hired mr_evans = Professor.objects.create(name='Mr. Evans', address='lives in a camper', phone_number='456') # A lab gets built lab = Classroom.objects.create(name='Physics and stuff', building='The old one') self.t1 = get_utc_now() sleep(0.1) # -------------- t2: # Mr. Evans starts to teach sophie in the lab mr_evans.students.add(sophie) lab.students.add(sophie) self.t2 = get_utc_now() sleep(0.1) # -------------- t3: # Annika is joining Sophie annika.professors.add(mr_evans) annika.classrooms.add(lab) self.t3 = get_utc_now() sleep(0.1) # -------------- t4: # Benny cuts that sh*t benny.professors.remove(mr_biggs) self.t4 = get_utc_now()
def test_filtering_on_the_other_side_of_the_relation(self): t1 = get_utc_now() sleep(0.1) p2 = Player.objects.get(name='p2.v1') self.team.player_set.remove(p2) t2 = get_utc_now() sleep(0.1) p1 = Player.objects.get(name='p1.v1') self.team.player_set.remove(p1) t3 = get_utc_now() sleep(0.1) # Let's get those players back into the game! p1 = Player.objects.current.get(name='p1.v1') p2 = Player.objects.current.get(name='p2.v1') self.team.player_set.add(p1) self.team.player_set.add(p2) t4 = get_utc_now() self.assertEqual(1, Team.objects.all().count()) self.assertEqual(1, Team.objects.as_of(t1).all().count()) self.assertEqual(3, Player.objects.filter(name='p1.v1').all().count()) self.assertEqual(3, Player.objects.filter(name='p2.v1').all().count()) self.assertEqual( 1, Player.objects.as_of(t1).filter(name='p1.v1').all().count()) self.assertEqual( 1, Player.objects.as_of(t1).filter(name='p2.v1').all().count()) # at t1 there should be one team with two players p1 = Team.objects.as_of(t1).filter( player__name='p1.v1').propagate_querytime().first() self.assertIsNotNone(p1) p2 = Team.objects.as_of(t1).filter( player__name='p2.v1').propagate_querytime().first() self.assertIsNotNone(p2) # at t2 there should be one team with one single player called 'p1.v1' p1 = Team.objects.as_of(t2).filter( player__name='p1.v1').propagate_querytime().first() p2 = Team.objects.as_of(t2).filter( player__name='p2.v1').propagate_querytime().first() self.assertIsNotNone(p1) self.assertIsNone(p2) # at t3 there should be one team with no players p1 = Team.objects.as_of(t3).filter( player__name='p1.v1').propagate_querytime().first() p2 = Team.objects.as_of(t3).filter( player__name='p2.v1').propagate_querytime().first() self.assertIsNone(p1) self.assertIsNone(p2) # at t4 there should be one team with two players again! p1 = Team.objects.as_of(t4).filter(player__name='p1.v1').first() p2 = Team.objects.as_of(t4).filter(player__name='p2.v1').first() self.assertIsNotNone(p1) self.assertIsNotNone(p2)
def setUp(self): # -------------- t0: mr_biggs = Professor.objects.create( name='Mr. Biggs', address='123 Mainstreet, Somewhere', phone_number='123') ms_piggy = Professor.objects.create( name='Ms. Piggy', address='82 Leicester Street, London', phone_number='987') gym = Classroom.objects.create(name='Sports room', building='The big one over there') phylo = Classroom.objects.create(name='Philosophy lectures', building='The old one') annika = Student.objects.create(name='Annika') annika.professors.add(mr_biggs) annika.professors.add(ms_piggy) annika.classrooms.add(phylo) annika.classrooms.add(gym) benny = Student.objects.create(name='Benny') benny.professors.add(mr_biggs) benny.classrooms.add(gym) sophie = Student.objects.create(name='Sophie') # Sophie doesn't study at that school yet, but is already subscribed self.t0 = get_utc_now() sleep(0.1) # -------------- t1: # Mr. Biggs moves to Berne mr_biggs = mr_biggs.clone() mr_biggs.address = 'Thunplatz, Bern' mr_biggs.save() # Mr. Evans gets hired mr_evans = Professor.objects.create(name='Mr. Evans', address='lives in a camper', phone_number='456') # A lab gets built lab = Classroom.objects.create(name='Physics and stuff', building='The old one') self.t1 = get_utc_now() sleep(0.1) # -------------- t2: # Mr. Evans starts to teach sophie in the lab mr_evans.students.add(sophie) lab.students.add(sophie) self.t2 = get_utc_now() sleep(0.1) # -------------- t3: # Annika is joining Sophie annika.professors.add(mr_evans) annika.classrooms.add(lab) self.t3 = get_utc_now() sleep(0.1) # -------------- t4: # Benny cuts that sh*t benny.professors.remove(mr_biggs) self.t4 = get_utc_now()