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, scope='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, scope='su1', scopeFlags=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',
                    scopeFlags=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', 'SOURCEURI1')
    m.add(s)
    m.removePattern(None, None, None, None, 'source[^U]*1',
                    scopeFlags=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, scope='SU1'))
    tester.compare(0, m.containsPattern(None,None,None, scope='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, scope='Su1', scopeFlags=Model.IGNORE_CASE))
    tester.compare(0, m.containsPattern(None,None,None, scope='su2', scopeFlags=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',
                           scopeFlags=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', 'SOURCEURI1')
    m.add(s)
    rt = m.containsPattern(None, None, None, None, 'source[^U]*1',
                           scopeFlags=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.scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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].scope)
    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, scope='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].scope)
    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, scope='SU1', scopeFlags=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].scope)
    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',
                     scopeFlags=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].scope)
    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', 'SOURCEURI1')
    m.add([s1, s2])
    res = m.complete(None, None, None, None, 'source[^U]*1',
                     scopeFlags=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].scope)
    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, scope=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, scope=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, scope=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, '', ''), TypeError)
    tester.testDone()
    tester.startTest("Invalid Statement Predicate")
    tester.testException(Statement.Statement, ('',None, ''), TypeError)
    tester.testDone()
    tester.startTest("Invalid Statement Object")
    tester.testException(Statement.Statement, ('', '',None), TypeError)
    tester.testDone()

    tester.startTest("Invalid Statement URI")
    tester.testException(Statement.Statement, ('', '', '', 0), TypeError)
    tester.testDone()

    tester.startTest("Invalid Statement source URI")
    tester.testException(Statement.Statement, ('', '', '', '', 3), TypeError)
    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)
