
import flask_sqlalchemy_testing
from flask_sqlalchemy_testing import FlaskDbTestCase

from app import db, ModelX, ModelY

def setUpModule():
    flask_sqlalchemy_testing.setUpModule()

    # You can issue module-wide setup operations here
    # (these will be rolled back after all tests in this module have run)
    db.session.add(ModelX(x=0))
    db.session.add(ModelY(y=0))
    db.session.commit()

from flask_sqlalchemy_testing import tearDownModule


class ModelXTestCase(FlaskDbTestCase):
    @classmethod
    def setUpClass(cls):
        super(ModelXTestCase, cls).setUpClass()

        # These will be rolled back after all the tests in this class
        db.session.add(ModelX(x=1))
        db.session.flush()


    def setUp(self):
        super(ModelXTestCase, self).setUp()

        # These will be rolled back after each test
        db.session.add(ModelX(x=2))
        db.session.flush()

    def test_model_x_instance_0_exists(self):
        """Model X instance 0 should exist"""
        self.assertIsNotNone(
            ModelX.query.filter_by(x=0).first())

    def test_model_x_instance_1_exists(self):
        """Model X instance 1 should exist"""
        self.assertIsNotNone(
            ModelX.query.filter_by(x=1).first())

    def test_model_x_instance_2_exists(self):
        """Model X instance 2 should exist"""
        self.assertIsNotNone(
            ModelX.query.filter_by(x=2).first())

    def test_model_y_instance_0_exists(self):
        """Model Y instance 0 should exist also in ModelXTestCase"""
        self.assertIsNotNone(
            ModelY.query.filter_by(y=0).first())

    def test_model_y_instance_1_exists_not(self):
        """Model Y instance 1 should not exist in ModelXTestCase"""
        self.assertIsNone(
            ModelY.query.filter_by(y=1).first())

    def test_model_y_instance_2_exists_not(self):
        """Model Y instance 2 should not exist in ModelXTestCase"""
        self.assertIsNone(
            ModelY.query.filter_by(y=2).first())

    def test_savepoint(self):
        """Test model states with savepoint"""
        from sqlalchemy import inspect
        modelx = ModelX(x=3)
        model_state = inspect(modelx)
        self.assertTrue(model_state.transient)

        savepoint = db.session.begin_nested()
        savepoint.session.add(modelx)
        self.assertTrue(model_state.pending)

        savepoint.commit()
        self.assertTrue(model_state.persistent)

class ModelYTestCase(FlaskDbTestCase):
    @classmethod
    def setUpClass(cls):
        super(ModelYTestCase, cls).setUpClass()

        db.session.add(ModelY(y=1))
        db.session.flush()


    def setUp(self):
        super(ModelYTestCase, self).setUp()

        db.session.add(ModelY(y=2))
        db.session.flush()

    def test_model_y_instance_0_exists(self):
        """Model Y instance 0 should exist"""
        self.assertIsNotNone(
            ModelY.query.filter_by(y=0).first())

    def test_model_y_instance_1_exists(self):
        """Model Y instance 1 should exist"""
        self.assertIsNotNone(
            ModelY.query.filter_by(y=1).first())
        self.assertTrue(
            db.session.query(ModelY).filter(ModelY.y==1).first()
            is not None)

    def test_model_y_instance_2_exists(self):
        """Model Y instance 2 should exist"""
        self.assertIsNotNone(
            ModelY.query.filter_by(y=1).first())

    def test_model_x_instance_0_exists(self):
        """Model X instance 0 should exist also in ModelYTestCase"""
        self.assertIsNotNone(
            ModelX.query.filter_by(x=0).first())

    def test_model_x_instance_1_exists_not(self):
        """Model X instance 1 should not exist in ModelYTestCase"""
        self.assertIsNone(
            ModelX.query.filter_by(x=1).first())

    def test_model_x_instance_2_exists_not(self):
        """Model X instance 2 should not exist in ModelYTestCase"""
        self.assertIsNone(
            ModelX.query.filter_by(x=2).first())


if __name__ == '__main__':
    #import logging
    #log = logging.getLogger(__name__)
    #logging.basicConfig(level=logging.INFO)
    #logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

    import unittest
    unittest.main(verbosity=2)


