
from Ft.Ods import Database
from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods.MetaData import Scope

def test_primitive_type(tester,db,klass,attrName,value):

    tester.startTest("Set %s on %s" % (attrName,klass.__name__))
    tx = db.new()
    tx.begin()
    i = klass(db,None)
    setattr(i,attrName,value)
    tx.commit()

    tx = db.new()
    tx.begin()

    rid = i._4ods_getId()

    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid)
    tester.compare(value,getattr(i,attrName))
    tx.abort()
    tester.testDone()
    return

def test_primitive_collection(tester,db,klass,attrName,value):

    tester.startTest("Add %s on %s" % (attrName,klass.__name__))
    tx = db.new()
    tx.begin()
    i = klass(db,None)
    col = getattr(i,attrName)
    col.insert_element(value)
    tx.commit()

    tx = db.new()
    tx.begin()

    rid = i._4ods_getId()

    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid)
    tester.testResults(1,value in getattr(i,attrName),done=0,msg='Wrong value for %s on %s' % (attrName,klass.__name__))
    tx.abort()
    tester.testDone()
    return


def test_form_drop(tester,db,klass,attrName,valueKlass,**args):

    accessListFunction = args.get('accessListFunction')
    nSided = args.get('nSided')

    tester.startTest("Form %s on %s with %s" % (attrName,klass.__name__,valueKlass.__name__))
    tx = db.new()
    tx.begin()
    t = valueKlass(db,None)
    i = klass(db,None)
    func = getattr(i,'form_%s' % attrName)
    apply(func,(t,))
    if nSided:
        tester.testResults(1,t in getattr(i,attrName),done=0,msg='New Value not in %s on %s before commit' % (attrName,klass.__name__))
    else:
        tester.testResults(t,getattr(i,attrName),done=0,msg='Wrong Value before commit of %s on %s' % (attrName,klass.__name__))
    if accessListFunction:
        func = getattr(i,accessListFunction)
        tester.testResults(1,t in func(),done=0,msg='New Value not in %s on %s before commit' % (accessListFunction,klass.__name__))
        
    tx.commit()

    rid = i._4ods_getId()
    rid1 = t._4ods_getId()

    tester.testDone()

    tester.startTest("Drop %s on %s" % (attrName,klass.__name__))
    tx = db.new()
    tx.begin()
    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid)
    t = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid1)
    if nSided:
        tester.testResults(1,t in getattr(i,attrName),done=0,msg='New Value not in %s on %s after commit' % (attrName,klass.__name__))
    else:
        tester.testResults(t,getattr(i,attrName),done=0,msg='Wrong Value after commit of %s on %s' % (attrName,klass.__name__))

    if accessListFunction:
        func = getattr(i,accessListFunction)
        tester.testResults(1,t in func(),done=0,msg='New Value not in %s on %s after commit' % (accessListFunction,klass.__name__))


    func = getattr(i,'drop_%s' % attrName)
    apply(func,(t,))
    if nSided:
        tester.testResults(0,t in getattr(i,attrName),done=0,msg='New Value still in %s on %s after drop' % (attrName,klass.__name__))
    else:
        tester.testResults(None,getattr(i,attrName),done=0,msg='Wrong Value after drop of %s on %s' % (attrName,klass.__name__))

    if accessListFunction:
        func = getattr(i,accessListFunction)
        tester.testResults(0,t in func(),done=0,msg='New Value still in %s on %s after drop' % (accessListFunction,klass.__name__))


    tx.abort()

    tester.testDone()




def test_create(tester,db,klass,funcName,args,testValues,testListValues=None):

    testListValues = testListValues or {}

    tester.startTest("%s on %s" % (funcName,klass.__name__))
    i = klass(db,None)
    func = getattr(i,funcName)
    o = apply(func,args)
    for attrName,value in testValues.items():
        tester.testResults(value,getattr(o,attrName),done=0,msg="Wrong Value of %s from %s on %s" % (attrName,funcName,klass.__name__))
    for attrName,value in testListValues.items():
        tester.testResults(1, value in getattr(o,attrName),done=0,msg="No Value added to %s from %s on %s" % (attrName,funcName,klass.__name__))
    tester.testDone()
    

def test_add_remove(tester,db,klass,name,origArgs,**args):


    argFactory = args.get('argFactory',{})
    argListFactory = args.get('argListFactory',{})
    argResolve = args.get('argResolve',{})
    testValues = args.get('testValues',{})
    testListValues = args.get('testListValues',{})
    testResolve = args.get('testResolve')
    testIn = args.get('testIn')

    tester.startTest("Add %s on %s" % (name,klass.__name__))
    tx=db.new()
    tx.begin()
    i = klass(db,None)

    createdValues = {}

    arguments = []
    for a in origArgs:
        if argFactory.has_key(a):
            nv = argFactory[a](db,None)
            arguments.append(nv)
            createdValues[a] = nv
        elif argListFactory.has_key(a):
            nv = argListFactory[a](db,None)
            arguments.append([nv])
            createdValues[a] = nv
        elif argResolve.has_key(a):
            nv = db.schema().resolve(argResolve[a])
            arguments.append(nv)
            createdValues[a] = nv
        else:
            arguments.append(a)

    for key,value in testValues.items():
        if createdValues.has_key(value):
            testValues[key] = createdValues[value]
        elif argFactory.has_key(value):
            testValues[key] = argFactory[value]()
        elif argResolve.has_key(value):
            testValue[key] = db.schema().resolve(argResolve[value])
        
    for key,value in testListValues.items():
        if createdValues.has_key(value):
            testListValues[key] = createdValues[value]
        elif argFactory.has_key(value):
            testListValues[key] = argFactory[value]()
        elif argResolve.has_key(value):
            testListValue[key] = db.schema().resolve(argResolve[value])
        

    func = getattr(i,'add_%s' % name)
    res = apply(func,arguments)

    for attrName,value in testValues.items():
        tester.testResults(value,getattr(res,attrName),done=0,msg='Wrong Value of %s on %s after add of %s' % (attrName,klass.__name__,name))
    for attrName,value in testListValues.items():
        tester.testResults(1,value in getattr(res,attrName),done=0,msg='No Value added to %s on %s after add of %s' % (attrName,klass.__name__,name))

    if testResolve:
        try:
            i.resolve(testResolve)
        except Scope.Scope.NameNotFound:
            tester.error('Name %s not found on %s after add of %s' % (testResolve,klass.__name__,name))

    if testIn:
        tester.testResults(1,res in getattr(i,testIn),done=0,msg='No Value added to %s on %s after add of %s' % (testIn,klass.__name__,name))
        

    tx.commit()
    tester.testDone()

    rid = i._4ods_getId()
    rid1 = res._4ods_getId()

    tester.startTest("Remove %s from %s"%(name,klass.__name__))
    tx=db.new()
    tx.begin()
    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid)
    res = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid1)


    if testResolve:
        try:
            i.resolve(testResolve)
        except Scope.Scope.NameNotFound:
            tester.error('Name %s not found on %s after commit of %s' % (testResolve,klass.__name__,name))

    if testIn:
        tester.testResults(1,res in getattr(i,testIn),done=0,msg='No Value %s on %s after commit of %s' % (testIn,klass.__name__,name))

    func = getattr(i,'remove_%s' % name)
    apply(func,(res,))


    if testResolve:
        try:
            i.resolve(testResolve)
        except Scope.Scope.NameNotFound:
            pass
        else:
            tester.error('Name %s still on %s after remove of %s' % (testResolve,klass.__name__,name))

    if testIn:
        tester.testResults(0,res in getattr(i,testIn),done=0,msg='Value %s on %s after drop of %s' % (testIn,klass.__name__,name))

    tx.abort()
    tester.testDone()

