from Ft.Rdf import Statement, Container
from Ft.Rdf import Model, RDF_MS_BASE, RdfException

import os, pprint

DATABASE_NAME = os.environ.get('RDF_TEST_DB','test')

def init(tester):
    tester.startTest("Init Driver")
    driver = tester.test_data['driver']
    
    if driver.ExistsDb(DATABASE_NAME):
        driver.DestroyDb(DATABASE_NAME)
    driver.CreateDb(DATABASE_NAME)
    tester.testDone()


def test_add(tester):

    tester.startTest('add')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)

    s = Statement.Statement('Book','Author','Mike Olson','http://foo.com')
    m.add(s)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

def test_remove(tester):
        
    tester.startTest('remove')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)

    s = Statement.Statement('Book','Author','Mike Olson','http://foo.com')
    m.add(s)
    m.remove(s)
    tester.compare(0,len(m.statements()))
    db.rollback()
    tester.testDone()


def test_remove_pattern(tester):

    tester.startTest('remove pattern subject')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern('S1',None,None)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern subject (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern('s1',None,None,subjectFlags=Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern subject (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern('.1',None,None,subjectFlags=Model.REGEX)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern subject (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern("s['1']",None,None,subjectFlags=Model.REGEX|Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern predicate')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,'P1',None)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern predicate (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,'p1',None,predicateFlags=Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern predicate (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,'.1',None,predicateFlags=Model.REGEX)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern predicate (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,"p['1','3']",None,predicateFlags=Model.REGEX|Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern object')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,'O1')
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern object (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,'o1',objectFlags=Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern object (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O1','U2','SU2')
    m.add(s)
    m.removePattern(None, None, 'OBJ.*', objectFlags=Model.REGEX)
    tester.compare(1, len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern object (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None, None, 'o(BjEcT)?2',objectFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    
    tester.startTest('remove pattern statement uri')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,None,statementUri='U1')
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern statement uri (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,None,statementUri='u1',statementUriFlags=Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern statement URI (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','URI1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add(s)
    m.removePattern(None, None, None, 'U.+1', statementUriFlags=Model.REGEX)
    tester.compare(1, len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern statement URI (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','URI1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add(s)
    m.removePattern(None, None, None, 'u.+1', statementUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern source uri')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,None,sourceUri='SU1')
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern source uri (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    m.removePattern(None,None,None,sourceUri='su1',sourceUriFlags=Model.IGNORE_CASE)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


    tester.startTest('remove pattern source URI (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU1')
    m.add(s)
    m.removePattern(None, None, None, None, 'S[^U]+.*1',
                    sourceUriFlags=Model.REGEX)
    tester.compare(1, len(m.statements()))
    db.rollback()
    tester.testDone()

    tester.startTest('remove pattern source URI (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SOUCEURI1')
    m.add(s)
    m.removePattern(None, None, None, None, 'source[^U]*1',
                    sourceUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(m.statements()))
    db.rollback()
    tester.testDone()


def test_contains(tester):

    tester.startTest('contains')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.contains(s))
    s = Statement.Statement('S1','P1','O1')
    tester.compare(1,m.contains(s))
    s = Statement.Statement('S2','P2','O2')
    tester.compare(0,m.contains(s))
    db.rollback()
    tester.testDone()


def test_contains_pattern(tester):

    tester.startTest('contains subject pattern')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern('S1',None,None))
    tester.compare(0,m.containsPattern('S2',None,None))
    db.rollback()
    tester.testDone()


    tester.startTest('contains subject pattern (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern('s1',None,None,subjectFlags=Model.IGNORE_CASE))
    tester.compare(0,m.containsPattern('s2',None,None,subjectFlags=Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()

    tester.startTest('contains subject pattern (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    tester.compare(1, m.containsPattern('.1', None, None,
                                        subjectFlags=Model.REGEX))
    db.rollback()
    tester.testDone()

    tester.startTest('contains subject pattern (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    tester.compare(1, m.containsPattern("s['1']", None, None,
                                        subjectFlags=Model.REGEX|Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()


    tester.startTest('contains predicate pattern')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,'P1',None))
    tester.compare(0,m.containsPattern(None,'P2',None))
    db.rollback()
    tester.testDone()

    tester.startTest('contains predicate pattern (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,'p1',None,predicateFlags=Model.IGNORE_CASE))
    tester.compare(0,m.containsPattern(None,'p2',None,predicateFlags=Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()

    tester.startTest('contains predicate (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    rt = m.containsPattern(None,'.1',None,predicateFlags=Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains predicate (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    rt = m.containsPattern(None,"p['1','3']",None,
                           predicateFlags=Model.REGEX|Model.IGNORE_CASE)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains object pattern')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,'O1'))
    tester.compare(0,m.containsPattern(None,None,'O2'))
    db.rollback()
    tester.testDone()

    tester.startTest('contains object pattern (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,'o1',objectFlags=Model.IGNORE_CASE))
    tester.compare(0,m.containsPattern(None,None,'o2',objectFlags=Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()

    tester.startTest('contains object (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O1','U2','SU2')
    m.add(s)
    rt = m.containsPattern(None, None, 'OBJ.*', objectFlags=Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains object (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    rt = m.containsPattern(None, None, 'o(BjEcT)?2',
                           objectFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains statement URI pattern')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,None,statementUri='U1'))
    tester.compare(0,m.containsPattern(None,None,None,statementUri='U2'))
    db.rollback()
    tester.testDone()


    tester.startTest('contains statement URI pattern (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,None,statementUri='u1',statementUriFlags=Model.IGNORE_CASE))
    tester.compare(0,m.containsPattern(None,None,None,statementUri='u2',statementUriFlags=Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()

    tester.startTest('contains statement URI (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','URI1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add(s)
    rt = m.containsPattern(None, None, None, 'U.+1',
                           statementUriFlags=Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains statement URI (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','URI1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add(s)
    rt = m.containsPattern(None, None, None, 'u.+1',
                           statementUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()

    tester.startTest('contains source URI pattern')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,None,sourceUri='SU1'))
    tester.compare(0,m.containsPattern(None,None,None,sourceUri='SU2'))
    db.rollback()
    tester.testDone()


    tester.startTest('contains source URI pattern (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.containsPattern(None,None,None,sourceUri='Su1',sourceUriFlags=Model.IGNORE_CASE))
    tester.compare(0,m.containsPattern(None,None,None,sourceUri='su2',sourceUriFlags=Model.IGNORE_CASE))
    db.rollback()
    tester.testDone()


    tester.startTest('contains source URI (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU1')
    m.add(s)
    rt = m.containsPattern(None, None, None, None, 'S[^U]+.*1',
                           sourceUriFlags=Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()


    tester.startTest('contains source URI (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SOUCEURI1')
    m.add(s)
    rt = m.containsPattern(None, None, None, None, 'source[^U]*1',
                           sourceUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1, rt)
    db.rollback()
    tester.testDone()


def test_statements(tester):

    tester.startTest('statements')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,len(m.statements()))
    s = m.statements()[0]
    tester.compare('S1',s.subject)
    tester.compare('P1',s.predicate)
    tester.compare('O1',s.object)
    tester.compare('U1',s.uri)
    tester.compare('SU1',s.sourceUri)
    db.rollback()
    tester.testDone()

def test_size(tester):

    tester.startTest('size')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    tester.compare(0,m.size())
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    tester.compare(1,m.size())
    db.rollback()
    tester.testDone()

def test_complete(tester):
    tester.startTest('complete subject')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete('S1',None,None)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete subject (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete('s1',None,None,subjectFlags=Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete subject (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add([s1, s2])
    res = m.complete('.1', None, None, subjectFlags=Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete subject (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add([s1, s2])
    res = m.complete("s['1']", None, None,
                     subjectFlags=Model.REGEX|Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()


    tester.startTest('complete predicate')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,'P1',None)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete predicate (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,'p1',None,predicateFlags=Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete predicate (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add([s1, s2])
    res = m.complete(None, '.1', None, predicateFlags=Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete predicate (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add([s1, s2])
    res = m.complete(None, "p['1','3']", None,
                     predicateFlags=Model.REGEX|Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()


    tester.startTest('complete object')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,'O1')
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()


    tester.startTest('complete object (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,'o1',objectFlags=Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete object (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    s2 = Statement.Statement('S2','P2','O1','U2','SU2')
    m.add([s1, s2])
    res = m.complete(None, None, 'OBJ.*', objectFlags=Model.REGEX)
    tester.compare(1, len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('OBJECT1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete object (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','OBJECT1','U1','SU1')
    m.add(s)
    s = Statement.Statement('S2','P2','O2','U2','SU2')
    m.add(s)
    res = m.complete(None, None, 'o(BjEcT)?2',
                     objectFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S2',res[0].subject)
    tester.compare('P2',res[0].predicate)
    tester.compare('O2',res[0].object)
    tester.compare('U2',res[0].uri)
    tester.compare('SU2',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete uri')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,None,statementUri='U1')
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete uri (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,None,statementUri='u1',statementUriFlags=Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete uri (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','URI1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add([s1, s2])
    res = m.complete(None, None, None, 'U.+1',
                     statementUriFlags=Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('URI1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete uri (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','URI1','SU1')
    s2 = Statement.Statement('S2','P2','O2','U1','SU2')
    m.add([s1, s2])
    res = m.complete(None, None, None, 'u.+1',
                     statementUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('URI1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete source uri')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,None,sourceUri='SU1')
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()


    tester.startTest('complete source uri (ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1','P1','O1','U1','SU1')
    m.add(s)
    res = m.complete(None,None,None,sourceUri='SU1',sourceUriFlags=Model.IGNORE_CASE)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SU1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete source URI (regex)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    s2 = Statement.Statement('S2','P2','O2','U2','SU1')
    m.add([s1, s2])
    res = m.complete(None, None, None, None, 'S[^U]+.*1',
                     sourceUriFlags=Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SOURCE1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

    tester.startTest('complete source URI (regex & ignore-case)')
    db = tester.test_data['driver'].GetDb(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s1 = Statement.Statement('S1','P1','O1','U1','SOURCE1')
    s2 = Statement.Statement('S2','P2','O2','U2','SOUCEURI1')
    m.add([s1, s2])
    res = m.complete(None, None, None, None, 'source[^U]*1',
                     sourceUriFlags=Model.IGNORE_CASE+Model.REGEX)
    tester.compare(1,len(res))
    tester.compare('S1',res[0].subject)
    tester.compare('P1',res[0].predicate)
    tester.compare('O1',res[0].object)
    tester.compare('U1',res[0].uri)
    tester.compare('SOURCE1',res[0].sourceUri)
    db.rollback()
    tester.testDone()

def test_containers(tester):

    tester.startGroup("Containers")

    driver = tester.test_data['driver']

    tester.startTest("Add Bag")
    db = driver.DbAdapter(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    b = Container.Bag("Test URI",['B1','B2','B3'])
    uri = m.addContainer(b)
    tester.compare(4,len(m.complete(uri,None,None)))
    tester.compare(3,len(m.complete(None,None,None,sourceUri=uri)))
    tester.testDone()

    tester.startTest("Extract Bag")
    b = m.extractContainer(uri)
    tester.compare(uri,b.uri)
    tester.compare('Bag',b.className)
    tester.compare(3,len(b))
    tester.compareIn(b,'B1')
    tester.compareIn(b,'B2')
    tester.compareIn(b,'B3')
    db.rollback()
    tester.testDone()


    tester.startTest("Add Seq")
    db = driver.DbAdapter(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Container.Sequence("Test URI",['S1','S2','S3'])
    uri = m.addContainer(s)
    tester.compare(4,len(m.complete(uri,None,None)))
    tester.compare(3,len(m.complete(None,None,None,sourceUri=uri)))
    tester.testDone()

    tester.startTest("Extract Seq")
    s = m.extractContainer(uri)
    tester.compare(uri,s.uri)
    tester.compare('Seq',s.className)
    tester.compare(3,len(s))
    tester.compareIn(s,'S1')
    tester.compareIn(s,'S2')
    tester.compareIn(s,'S3')
    db.rollback()
    tester.testDone()

    tester.startTest("Add Alt")
    db = driver.DbAdapter(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    a = Container.Alternative(None,['A1','A2','A3'])
    uri = m.addContainer(a)
    tester.compare(4,len(m.complete(uri,None,None)))
    tester.compare(3,len(m.complete(None,None,None,sourceUri=uri)))
    tester.testDone()

    tester.startTest("Extract Alt")
    a = m.extractContainer(uri)
    tester.compare(uri,a.uri)
    tester.compare('Alt',a.className)
    tester.compare(3,len(a))
    tester.compareIn(a,'A1')
    tester.compareIn(a,'A2')
    tester.compareIn(a,'A3')
    db.rollback()
    tester.testDone()
    tester.groupDone()


def test_exceptions(tester):

    tester.startGroup("Exceptions")

    driver = tester.test_data['driver']

    tester.startTest("Invalid Container Type")
    db = driver.DbAdapter(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    s = Statement.Statement('S1',RDF_MS_BASE+'type','Foo')
    m.add(s)
    tester.testException(m.extractContainer,('S1',),RdfException,{'errorCode':RdfException.INVALID_CONTAINER_TYPE})
    db.rollback()
    tester.testDone()


    tester.startTest("Invalid Flag")
    db = driver.DbAdapter(DATABASE_NAME)
    db.begin()
    m = Model.Model(db)
    try:
        m.complete(None,None,None,foo=1)
    except RdfException, e:
        if e.errorCode == RdfException.INVALID_FLAG:
            pass
        else:
            tester.error("Wrong Error Code: %s" % e.errorCode)
    else:
        tester.error("No Exception Raised")
    db.rollback()
    tester.testDone()

    tester.startTest("Invalid Statement Subject")
    tester.testException(Statement.Statement,(None,'',''),ValueError)
    tester.testDone()
    tester.startTest("Invalid Statement Predicate")
    tester.testException(Statement.Statement,('',None,''),ValueError)
    tester.testDone()
    tester.startTest("Invalid Statement Object")
    tester.testException(Statement.Statement,('','',None),ValueError)
    tester.testDone()

    tester.startTest("Invalid Statement URI")
    tester.testException(Statement.Statement,('','','',None),ValueError)
    tester.testDone()

    tester.startTest("Invalid Statement souce URI")
    tester.testException(Statement.Statement,('','','','',3),ValueError)
    tester.testDone()

    tester.startTest("REGEX Exceptions")
    tester.warning("Not tested, skipped")
    tester.testDone()


    tester.groupDone()

def Test(tester):

    tester.startGroup('Interface')
    init(tester)
    test_add(tester)
    test_remove(tester)
    test_contains(tester)
    test_remove_pattern(tester)
    test_contains_pattern(tester)
    test_statements(tester)
    test_size(tester)
    test_complete(tester)
    tester.groupDone()
    
    test_containers(tester)
    test_exceptions(tester)
