#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
#-----------------------------------------------------------------------------
# Modeling Framework: an Object-Relational Bridge for python
#
# Copyright (c) 2001-2004 Sbastien Bigaret <sbigaret@users.sourceforge.net>
# All rights reserved.
#
# This file is part of the Modeling Framework.
#
# This code is distributed under a "3-clause BSD"-style license;
# see the LICENSE file for details.
#-----------------------------------------------------------------------------
"""
Tests RelationshipManipulation mix-in class
The tests rely upon 7 classes based on the model 'model_testBothSidesRels'.
These classes were generated using the 'PyModelMason'. Then, the following
modifications were applied:
- methods 'addToToCs' and 'removeFromToCs' from class 'ClassA1' are removed,
so that the direct access to arrays can be tested additionnally,
- methods inverseForRelationship() are implemented in 'ClassA' and 'ClassB'
so that relationships 'toB' and 'toA' can be identified as reciprocical.
Note that 'test_01_addObjectToPropertyWithKey()' is also called by
'test_02_removeObjectFromPropertyWithKey()' (preparation of self's
variables). Hence, if the former fails, so does the latter.
CVS information
$Id: test_RelationshipManipulation.py 932 2004-07-20 06:21:57Z sbigaret $
"""
import unittest
if __name__ == "__main__":
import utils, sys
utils.fixpath()
from Modeling import ModelSet,Model
from Modeling.EntityClassDescription import EntityClassDescription
from Modeling.KeyValueCoding import KeyValueCoding
from Modeling.RelationshipManipulation import RelationshipManipulation
# load the model
# this is not done in setUp() since that method is triggered for each tests
# (this would slow down the tests dramatically)
from Modeling.Model import ModelError
if 'GlobalSetUp':
from os import getcwd,path
xmlmodelPath=path.join(getcwd(),'xmlmodels/model_testBothSidesRels.xml')
if not ModelSet.defaultModelSet().modelNamed('testBothSidesRels'):
ModelSet.defaultModelSet().addModelFromXML({'file': xmlmodelPath})
# Uncomment the following 5 lines to prepare the classes
# Remember to make the modifications described in module's docstring afterwards
#
#model=modelSet.modelNamed('testBothSidesRels')
#from Modeling.ModelMasons.PyModelMason import PyModelMason
#mm=PyModelMason(model, path.join(getcwd(),'testPackages'))
#mm.build()
#raise 'stop'
## Tests
from testPackages.testBothSidesRels.ClassA import ClassA
from testPackages.testBothSidesRels.ClassA1 import ClassA1
from testPackages.testBothSidesRels.ClassB import ClassB
from testPackages.testBothSidesRels.ClassC import ClassC
from testPackages.testBothSidesRels.ClassD import ClassD
from testPackages.testBothSidesRels.ClassE import ClassE
from testPackages.testBothSidesRels.ClassF import ClassF
class TestRelationshipManipulation(unittest.TestCase):
"Empty for now"
def test_00_imports(self):
"[RelationshipManipulation] import the test classes + classDescription()"
from testPackages.testBothSidesRels.ClassA import ClassA
a=ClassA()
self.assertEqual(a.classDescription().entityName(), 'A')
def test_01_addObjectToPropertyWithKey(self):
"[RelationshipManipulation] addObjectToPropertyWithKey"
self.a0=ClassA()
# toOne: reflexive
self.a1=ClassA()
self.a0.addObjectToPropertyWithKey(self.a1, 'toA')
self.failUnless(self.a0.getToA()==self.a1)
self.a2=ClassA()
self.a0.addObjectToPropertyWithKey(self.a2, 'toA')
self.failUnless(self.a0.getToA()==self.a2)
# toOne: standard
self.b1=ClassB()
self.a0.addObjectToPropertyWithKey(self.b1, 'toB')
self.failUnless(self.a0.getToB()==self.b1)
self.b2=ClassB()
self.a0.addObjectToPropertyWithKey(self.b2, 'toB')
self.failUnless(self.a0.getToB()==self.b2)
# toMany
self.c1=ClassC()
self.a0.addObjectToPropertyWithKey(self.c1, 'toCs')
self.failUnless(self.a0.getToCs()==(self.c1,))
self.c2=ClassC()
self.a0.addObjectToPropertyWithKey(self.c2, 'toCs')
self.failUnless(self.a0.getToCs()==(self.c1, self.c2,))
# toMany: direct access to array
self.aa1=ClassA1()
self.aa1.addObjectToPropertyWithKey(self.c1, 'toCs')
self.failUnless(self.aa1.getToCs()==(self.c1,))
self.aa1.addObjectToPropertyWithKey(self.c2, 'toCs')
self.failUnless(self.aa1.getToCs()==(self.c1, self.c2,))
def test_02_removeObjectFromPropertyWithKey(self):
"[RelationshipManipulation] removeObjectFromPropertyWithKey"
# ValueError for unknown values
self.test_01_addObjectToPropertyWithKey()
# Tests for raise conditions
self.failUnlessRaises(ValueError, self.a0.removeObjectFromPropertyWithKey,
ClassA(), 'toA')
self.failUnlessRaises(ValueError, self.a0.removeObjectFromPropertyWithKey,
ClassA(), 'toCs')
self.failUnlessRaises(ValueError, self.a0.removeObjectFromPropertyWithKey,
ClassA(), 'XYZ')
# toOne: reflexive
self.a0.removeObjectFromPropertyWithKey(self.a2, 'toA')
self.failUnless(not self.a0.getToA())
# toOne: standard
self.a0.removeObjectFromPropertyWithKey(self.b2, 'toB')
self.failIf(self.a0.getToB())
# toMany: standard
self.a0.removeObjectFromPropertyWithKey(self.c1, 'toCs')
self.failUnless(self.a0.getToCs()==(self.c2,))
# toMany: direct access to array
self.aa1.removeObjectFromPropertyWithKey(self.c2, 'toCs')
self.failUnless(self.aa1.getToCs()==(self.c1,))
def _define_vars(self):
self.a1=ClassA()
self.a2=ClassA()
self.c1=ClassC()
self.c2=ClassC()
self.b1=ClassB()
self.b2=ClassB()
self.d1=ClassD()
self.e1=ClassE()
self.f1=ClassF()
self.f2=ClassF()
def test_04_removeFromBothSideOfRelationshipWithKey(self):
"[RelationshipManipulation] removeFromBothSideOfRelationshipWithKey"
self._define_vars()
## a1 <-> b1
self.a1.setToB(self.b1); self.b1.setToA(self.a1)
self.a1.removeObjectFromBothSidesOfRelationshipWithKey(self.b1, 'toB')
self.failUnless(self.a1.getToB()==None)
self.failUnless(self.b1.getToA()==None)
# set on one side only
self.a1.setToB(self.b1)
self.a1.removeObjectFromBothSidesOfRelationshipWithKey(self.b1, 'toB')
## a1 <->> c1, c2
self.a1.addToToCs(self.c1); self.c1.setToA(self.a1)
self.a1.addToToCs(self.c2); self.c2.setToA(self.a1)
# from A
self.a1.removeObjectFromBothSidesOfRelationshipWithKey(self.c1, 'toCs')
self.failUnless(self.a1.getToCs()==(self.c2,))
self.failUnless(self.c1.getToA()==None)
# from C
self.c2.removeObjectFromBothSidesOfRelationshipWithKey(self.a1, 'toA')
self.failUnless(self.a1.getToCs()==())
self.failUnless(self.c2.getToA()==None)
# set on one side only
# ..1
self.a1.addToToCs(self.c1)
self.a1.addToToCs(self.c2)
self.a1.removeObjectFromBothSidesOfRelationshipWithKey(self.c2, 'toCs')
self.failUnless(self.a1.getToCs()==(self.c1,))
self.a1.removeObjectFromBothSidesOfRelationshipWithKey(self.c1, 'toCs')
## ..2
self.c1.setToA(self.a1)
self.c1.removeObjectFromBothSidesOfRelationshipWithKey(self.a1, 'toA')
self.failUnless(self.c1.getToA()==None)
## d1 ->> a1, a2
self.d1.addToToAs(self.a1)
self.d1.addToToAs(self.a2)
self.d1.removeObjectFromBothSidesOfRelationshipWithKey(self.a1, 'toAs')
self.failUnless(self.d1.getToAs()==(self.a2,))
## e1 -> a1
self.e1.setToA(self.a1)
self.e1.removeObjectFromBothSidesOfRelationshipWithKey(self.a1, 'toA')
self.failUnless(self.e1.getToA()==None)
## Raise condition
self.assertRaises(ValueError,
self.e1.removeObjectFromBothSidesOfRelationshipWithKey,
self.a1, 'toA')
## f1 <<->> a1, a2 /+/ f2 <<-->> a1
self.f1.addToToAs(self.a1); self.a1.addToToFs(self.f1)
self.f1.addToToAs(self.a2); self.a2.addToToFs(self.f1)
self.f2.addToToAs(self.a1); self.a1.addToToFs(self.f2)
self.f1.removeObjectFromBothSidesOfRelationshipWithKey(self.a1, 'toAs')
self.failUnless(self.f1.getToAs()==(self.a2,))
self.failUnless(self.a1.getToFs()==(self.f2,))
self.failUnless(self.f2.getToAs()==(self.a1,))
self.failUnless(self.a2.getToFs()==(self.f1,))
def test_05_addToBothSideOfRelationshipWithKey_one_to_many(self):
"[RelationshipManipulation] addToBothSideOfRelationshipWithKey/one-to-many"
self._define_vars()
# A <->> C
## from A
self.a1.addObjectToBothSidesOfRelationshipWithKey(self.c1, 'toCs')
self.failUnless(self.a1.getToCs()==(self.c1,))
self.failUnless(self.c1.getToA()==self.a1)
self.a1.addObjectToBothSidesOfRelationshipWithKey(self.c2, 'toCs')
a1_toCs=self.a1.getToCs()
self.failUnless(len(a1_toCs)==2 and \
self.c1 in a1_toCs and self.c2 in a1_toCs)
# from C
self.c1.addObjectToBothSidesOfRelationshipWithKey(self.a2, 'toA')
self.failUnless(self.c1.getToA()==self.a2, 'c1 -> a2')
self.failUnless(self.a2.getToCs()==(self.c1,), 'a2 ->> (c1,)')
self.failUnless(self.a1.getToCs()==(self.c2,), 'a1 disconnected from c1')
#self.failUnless(self.c1.getToA()==self.a)
def test_06_addToBothSideOfRelationshipWithKey_one_to_one(self):
"[RelationshipManipulation] addToBothSideOfRelationshipWithKey/one-to-one"
self._define_vars()
# A <-> B
# Note: A.toB and B.toA are NOT detected as reciprocical within the model
# (cf. test_Relationship), but they override 'inverseForRelationshipKey'
# for the framework to consider them as reciprocical
## from A
self.a1.addObjectToBothSidesOfRelationshipWithKey(self.b1, 'toB')
self.failUnless(self.a1.getToB()==self.b1)
self.failUnless(self.b1.getToA()==self.a1)
self.a1.addObjectToBothSidesOfRelationshipWithKey(self.b2, 'toB')
self.failUnless(self.a1.getToB()==self.b2)
self.failUnless(self.b1.getToA()==None)
self.failUnless(self.b2.getToA()==self.a1)
# from B
self.b1.addObjectToBothSidesOfRelationshipWithKey(self.a2, 'toA')
self.failUnless(self.b1.getToA()==self.a2, 'b1 -> a2')
self.failUnless(self.a2.getToB()==self.b1, 'a2 -> b1')
self.b1.addObjectToBothSidesOfRelationshipWithKey(self.a1, 'toA')
self.failUnless(self.b1.getToA()==self.a1, 'b1 -> a1')
self.failUnless(self.a1.getToB()==self.b1, 'a1 -> b1')
self.failUnless(self.b2.getToA()==None, 'b2 disconnected from a1')
def test_07_addToBothSideOfRelationshipWithKey_unidirectional(self):
"[RelationshipManipulation] addToBothSideOfRelationshipWithKey/unidirect."
self._define_vars()
# D -->> A
self.d1.addObjectToBothSidesOfRelationshipWithKey(self.a1, 'toAs')
self.failUnless(self.d1.getToAs()==(self.a1,))
self.d1.addObjectToBothSidesOfRelationshipWithKey(self.a2, 'toAs')
d1_toAs=self.d1.getToAs()
self.failUnless(len(d1_toAs)==2 and \
self.a1 in d1_toAs and self.a2 in d1_toAs)
# E --> A
self.e1.addObjectToBothSidesOfRelationshipWithKey(self.a1, 'toA')
self.failUnless(self.e1.getToA()==self.a1)
self.e1.addObjectToBothSidesOfRelationshipWithKey(self.a2, 'toA')
self.failUnless(self.e1.getToA()==self.a2)
def test_08_addToBothSideOfRelationshipWithKey_many_to_many(self):
"[RelationshipManipulation] addToBothSideOfRelationshipWithKey/n_to_n"
self._define_vars()
#TBD
class TestRelationshipManipulation_n_Inheritance(unittest.TestCase):
"Tests for RelationshipManipulation in an inheritance environment"
def test_01_addToBothSideOfRelationshipWithKey_one_to_many(self):
"[RelationshipManipulation/Inheritance] addObjToBothSide() one-to-many"
from StoreEmployees import Employee,Executive,SalesClerk,Address
emp=Employee.Employee()
a=Address.Address()
emp.addObjectToBothSidesOfRelationshipWithKey(a, 'toAddresses')
self.failUnless(a in emp.getToAddresses())
self.failUnless(emp == a.getToEmployee())
ex=Executive.Executive()
a=Address.Address()
ex.addObjectToBothSidesOfRelationshipWithKey(a, 'toAddresses')
self.failUnless(a in ex.getToAddresses())
self.failUnless(ex == a.getToEmployee())
sc=SalesClerk.SalesClerk()
a=Address.Address()
sc.addObjectToBothSidesOfRelationshipWithKey(a, 'toAddresses')
self.failUnless(a in sc.getToAddresses())
self.failUnless(sc == a.getToEmployee())
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestRelationshipManipulation, "test_"))
suite.addTest(unittest.makeSuite(TestRelationshipManipulation_n_Inheritance, "test_"))
return suite
if __name__ == "__main__":
errs = utils.run_suite(test_suite())
sys.exit(errs and 1 or 0)
|