from piper.db.db_sqlalchemy import SQLAlchemyDB

import mock
import pytest


class SQLAlchemyDBBase(object):
    def setup_method(self, method):
        self.cli = SQLAlchemyDB()
        self.ns = mock.Mock()
        self.config = mock.Mock()


class TestSQLAlchemyDBSetup(SQLAlchemyDBBase):
    @mock.patch('piper.db.db_sqlalchemy.create_engine')
    @mock.patch('piper.db.db_sqlalchemy.Session')
    def test_setup(self, se, ce):
        config = mock.Mock()
        self.cli.setup(config)

        assert self.cli.config is config
        ce.assert_called_once_with(config.db.host)
        se.configure.assert_called_once_with(bind=ce.return_value)


class TestSQLAlchemyDBInit(SQLAlchemyDBBase):
    def test_no_db(self):
        self.config.db.host = None

        with pytest.raises(AssertionError):
            self.cli.init(self.ns, self.config)

    def test_calls(self):
        self.cli.handle_sqlite = mock.Mock()
        self.cli.create_tables = mock.Mock()

        self.cli.init(self.ns, self.config)

        self.cli.handle_sqlite.assert_called_once_with(self.config.db.host)
        self.cli.create_tables.assert_called_once_with(
            self.config.db.host,
            echo=self.ns.verbose,
        )


class TestSQLAlchemyDBHandleSqlite(SQLAlchemyDBBase):
    @mock.patch('piper.utils.mkdir')
    @mock.patch('os.path.dirname')
    @mock.patch('os.path.exists')
    def test_sqlite_handling_creates_dir(self, exists, dirname, mkdir):
        self.config.db.host = 'sqlite:///amaranthine.db'
        exists.return_value = False

        self.cli.handle_sqlite(self.ns.host)
        mkdir.assert_called_once_with(dirname.return_value)


class TestSQLAlchemyDBCreateTables(SQLAlchemyDBBase):
    def setup_method(self, method):
        super(TestSQLAlchemyDBCreateTables, self).setup_method(method)
        self.cli.tables = (mock.Mock(), mock.Mock())

        for x, table in enumerate(self.cli.tables):
            table.__tablename__ = x

    @mock.patch('piper.db.db_sqlalchemy.Session')
    @mock.patch('piper.db.db_sqlalchemy.create_engine')
    def test_creation(self, ce, se):
        eng = ce.return_value
        host = self.config.host

        self.cli.create_tables(host)

        ce.assert_called_once_with(host, echo=False)
        se.configure.assert_called_once_with(bind=eng)

        for table in self.cli.tables:
            assert table.metadata.bind is eng
            table.metadata.create_all.assert_called_once_with()

@@ -151,19 +151,18 @@
    self.
-cli
+db
  = SQLAl
@@ -466,19 +466,18 @@
    self.
-cli
+db
 .setup(c
@@ -504,19 +504,18 @@
 rt self.
-cli
+db
 .config 
@@ -805,35 +805,34 @@
            self.
-cli
+db
 .init(self.ns, s
@@ -875,35 +875,34 @@
 ):%0A        self.
-cli
+db
 .handle_sqlite =
@@ -919,35 +919,34 @@
 ()%0A        self.
-cli
+db
 .create_tables =
@@ -972,19 +972,18 @@
    self.
-cli
+db
 .init(se
@@ -1008,35 +1008,34 @@
 )%0A%0A        self.
-cli
+db
 .handle_sqlite.a
@@ -1083,35 +1083,34 @@
 t)%0A        self.
-cli
+db
 .create_tables.a
@@ -1551,19 +1551,18 @@
    self.
-cli
+db
 .handle_
@@ -1814,27 +1814,26 @@
        self.
-cli
+db
 .tables = (m
@@ -1893,27 +1893,26 @@
 merate(self.
-cli
+db
 .tables):%0A  
@@ -2165,19 +2165,18 @@
    self.
-cli
+db
 .create_
@@ -2328,11 +2328,10 @@
 elf.
-cli
+db
 .tab

Refactor leftover refactoring