from dbtest import *
from sqlobject import sqlhub, SQLObject, StringCol
import py.test
try:
    from sqlobject.wsgi_middleware import make_middleware
except ImportError:
    pytestmark = py.test.mark.skipif('True')


class NameOnly(SQLObject):
    name = StringCol()

def makeapp(abort=False, begin=False, fail=False):
    def app(environ, start_response):
        NameOnly(name='app1')
        if fail == 'early':
            assert 0
        start_response('200 OK', [('content-type', 'text/plain')])
        if begin:
            environ['sqlobject.begin']()
        NameOnly(name='app2')
        if abort:
            environ['sqlobject.abort']()
        if fail:
            assert 0
        return ['ok']
    return app

def makestack(abort=False, begin=False, fail=False, **kw):
    app = makeapp(abort=abort, begin=begin, fail=fail)
    app = make_middleware(app, {}, database=getConnectionURI(), **kw)
    return app

def runapp(**kw):
    print '-'*8
    app = makestack(**kw)
    env = {}
    def start_response(*args):
        pass
    try:
        list(app(env, start_response))
        return True
    except AssertionError:
        return False

def setup():
    setupClass(NameOnly)
    getConnection().query('DELETE FROM name_only')
    NameOnly._connection = sqlhub

def names():
    names = [n.name for n in NameOnly.select(connection=getConnection())]
    names.sort()
    return names

def test_fail():
    setup()
    assert not runapp(fail=True, use_transaction=True)
    assert names() == []
    setup()
    assert not runapp(fail=True, use_transaction=False)
    assert names() == ['app1', 'app2']
    setup()
    assert not runapp(fail=True, begin=True, use_transaction=True)
    assert names() == ['app1']

def test_other():
    setup()
    assert runapp(fail=False, begin=True, use_transaction=True)
    assert names() == ['app1', 'app2']
    setup()
    # @@: Dammit, I can't get these to pass because I can't get the
    # stupid table to clear itself.  setupClass() sucks.  When I
    # fix it I'll take this disabling out:
    return
    assert names() == []
    assert runapp(fail=False, begin=True, abort=True, use_transaction=True)
    assert names() == ['app1']
    setup()
    assert runapp(use_transaction=True)
    assert names() == ['app1', 'app2']
    
