# Path: pyrseas/testutils.py
# class DatabaseToMapTestCase(PyrseasTestCase):
#     """Base class for "database to map" test cases"""
# 
#     superuser = False
# 
#     def to_map(self, stmts, config={}, schemas=[], tables=[], no_owner=True,
#                no_privs=True, superuser=False, multiple_files=False):
#         """Execute statements and return a database map.
# 
#         :param stmts: list of SQL statements to execute
#         :param config: dictionary of configuration information
#         :param schemas: list of schemas to map
#         :param tables: list of tables to map
#         :param no_owner: exclude object owner information
#         :param no_privs: exclude privilege information
#         :param superuser: must be superuser to run
#         :param multiple_files: emulate --multiple_files option
#         :return: possibly trimmed map of database
#         """
#         if (self.superuser or superuser) and not self.db.is_superuser():
#             self.skipTest("Must be a superuser to run this test")
#         for stmt in stmts:
#             self.db.execute(stmt)
#         self.db.conn.commit()
#         if multiple_files:
#             self.cfg.merge({'files': {'metadata_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['metadata'])}})
#         if 'datacopy' in config:
#             self.cfg.merge({'files': {'data_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['data'])}})
#         self.config_options(schemas=schemas, tables=tables, no_owner=no_owner,
#                             no_privs=no_privs, multiple_files=multiple_files)
#         self.cfg.merge(config)
#         return self.database().to_map()
# 
#     def yaml_load(self, filename, subdir=None):
#         """Read a file in the metadata_path and process it with YAML load
# 
#         :param filename: name of the file
#         :param subdir: name of a subdirectory where the file is located
#         :return: YAML dictionary
#         """
#         with open(os.path.join(self.cfg['files']['metadata_path'],
#                                subdir or '', filename), 'r') as f:
#             inmap = f.read()
#         return yaml.safe_load(inmap)
# 
#     def remove_tempfiles(self):
#         remove_temp_files(TEST_DIR)
# 
#     @staticmethod
#     def sort_privileges(data):
#         try:
#             sorted_privlist = []
#             for sortedItem in sorted([list(i.keys())[0]
#                                       for i in data['privileges']]):
#                 sorted_privlist.append(
#                     [item for item in data['privileges']
#                      if list(item.keys())[0] == sortedItem][0])
#             data['privileges'] = sorted_privlist
#         finally:
#             return data
# 
# Path: pyrseas/testutils.py
# class InputMapToSqlTestCase(PyrseasTestCase):
#     """Base class for "input map to SQL" test cases"""
# 
#     superuser = False
# 
#     def to_sql(self, inmap, stmts=None, config={}, superuser=False, schemas=[],
#                revert=False, quote_reserved=False):
#         """Execute statements and compare database to input map.
# 
#         :param inmap: dictionary defining target database
#         :param stmts: list of SQL database setup statements
#         :param config: dictionary of configuration information
#         :param superuser: indicates test requires superuser privilege
#         :param schemas: list of schemas to diff
#         :param revert: generate statements to back out changes
#         :param quote_reserved: fetch reserved words
#         :return: list of SQL statements
#         """
#         if (self.superuser or superuser) and not self.db.is_superuser():
#             self.skipTest("Must be a superuser to run this test")
#         if stmts:
#             for stmt in stmts:
#                 self.db.execute(stmt)
#             self.db.conn.commit()
# 
#         if 'datacopy' in config:
#             self.cfg.merge({'files': {'data_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['data'])}})
#         self.config_options(schemas=schemas, revert=revert),
#         self.cfg.merge(config)
#         return self.database().diff_map(inmap, quote_reserved=quote_reserved)
# 
#     def std_map(self, plpgsql_installed=False):
#         "Return a standard schema map for the default database"
#         base = {'schema sd': {
#                 'owner': self.db.user,
#                 'privileges': []}}
#         base.update({'extension plpgsql': {
#             'schema': 'pg_catalog', 'owner': PG_OWNER,
#             'description': "PL/pgSQL procedural language"}})
#         return base
# 
# def fix_indent(stmt):
#     "Fix specifications which are in a new line with indentation"
#     return stmt.replace('   ', ' ').replace('  ', ' ').replace('\n ', ' '). \
#         replace('( ', '(')


import pytest
from pyrseas.testutils import DatabaseToMapTestCase
from pyrseas.testutils import InputMapToSqlTestCase, fix_indent

class ExtensionToSqlTestCase(InputMapToSqlTestCase):
    """Test SQL generation for input extensions"""

    def test_create_extension_simple(self):
        "Create a extension that didn't exist"
        inmap = self.std_map()
        inmap.update({'extension pg_trgm': {'schema': 'sd'}})
        sql = self.to_sql(inmap)
        assert fix_indent(sql[0]) == CREATE_STMT + " SCHEMA sd"

    def test_bad_extension_map(self):
        "Error creating a extension with a bad map"
        inmap = self.std_map()
        inmap.update({'pg_trgm': {'schema': 'sd'}})
        with pytest.raises(KeyError):
            self.to_sql(inmap)

    def test_drop_extension(self):
        "Drop an existing extension"
        sql = self.to_sql(self.std_map(), [CREATE_STMT], superuser=True)
        assert sql == ["DROP EXTENSION pg_trgm"]

    def test_create_extension_schema(self):
        "Create a extension in a given schema"
        inmap = self.std_map()
        inmap.update({'schema s1': {},
                      'extension pg_trgm': {'schema': 's1', 'version': '1.0'}})
        sql = self.to_sql(inmap)
        assert sql[0] == 'CREATE SCHEMA s1'

# Path: pyrseas/testutils.py
# class DatabaseToMapTestCase(PyrseasTestCase):
#     """Base class for "database to map" test cases"""
# 
#     superuser = False
# 
#     def to_map(self, stmts, config={}, schemas=[], tables=[], no_owner=True,
#                no_privs=True, superuser=False, multiple_files=False):
#         """Execute statements and return a database map.
# 
#         :param stmts: list of SQL statements to execute
#         :param config: dictionary of configuration information
#         :param schemas: list of schemas to map
#         :param tables: list of tables to map
#         :param no_owner: exclude object owner information
#         :param no_privs: exclude privilege information
#         :param superuser: must be superuser to run
#         :param multiple_files: emulate --multiple_files option
#         :return: possibly trimmed map of database
#         """
#         if (self.superuser or superuser) and not self.db.is_superuser():
#             self.skipTest("Must be a superuser to run this test")
#         for stmt in stmts:
#             self.db.execute(stmt)
#         self.db.conn.commit()
#         if multiple_files:
#             self.cfg.merge({'files': {'metadata_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['metadata'])}})
#         if 'datacopy' in config:
#             self.cfg.merge({'files': {'data_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['data'])}})
#         self.config_options(schemas=schemas, tables=tables, no_owner=no_owner,
#                             no_privs=no_privs, multiple_files=multiple_files)
#         self.cfg.merge(config)
#         return self.database().to_map()
# 
#     def yaml_load(self, filename, subdir=None):
#         """Read a file in the metadata_path and process it with YAML load
# 
#         :param filename: name of the file
#         :param subdir: name of a subdirectory where the file is located
#         :return: YAML dictionary
#         """
#         with open(os.path.join(self.cfg['files']['metadata_path'],
#                                subdir or '', filename), 'r') as f:
#             inmap = f.read()
#         return yaml.safe_load(inmap)
# 
#     def remove_tempfiles(self):
#         remove_temp_files(TEST_DIR)
# 
#     @staticmethod
#     def sort_privileges(data):
#         try:
#             sorted_privlist = []
#             for sortedItem in sorted([list(i.keys())[0]
#                                       for i in data['privileges']]):
#                 sorted_privlist.append(
#                     [item for item in data['privileges']
#                      if list(item.keys())[0] == sortedItem][0])
#             data['privileges'] = sorted_privlist
#         finally:
#             return data
# 
# Path: pyrseas/testutils.py
# class InputMapToSqlTestCase(PyrseasTestCase):
#     """Base class for "input map to SQL" test cases"""
# 
#     superuser = False
# 
#     def to_sql(self, inmap, stmts=None, config={}, superuser=False, schemas=[],
#                revert=False, quote_reserved=False):
#         """Execute statements and compare database to input map.
# 
#         :param inmap: dictionary defining target database
#         :param stmts: list of SQL database setup statements
#         :param config: dictionary of configuration information
#         :param superuser: indicates test requires superuser privilege
#         :param schemas: list of schemas to diff
#         :param revert: generate statements to back out changes
#         :param quote_reserved: fetch reserved words
#         :return: list of SQL statements
#         """
#         if (self.superuser or superuser) and not self.db.is_superuser():
#             self.skipTest("Must be a superuser to run this test")
#         if stmts:
#             for stmt in stmts:
#                 self.db.execute(stmt)
#             self.db.conn.commit()
# 
#         if 'datacopy' in config:
#             self.cfg.merge({'files': {'data_path': os.path.join(
#                             TEST_DIR, self.cfg['repository']['data'])}})
#         self.config_options(schemas=schemas, revert=revert),
#         self.cfg.merge(config)
#         return self.database().diff_map(inmap, quote_reserved=quote_reserved)
# 
#     def std_map(self, plpgsql_installed=False):
#         "Return a standard schema map for the default database"
#         base = {'schema sd': {
#                 'owner': self.db.user,
#                 'privileges': []}}
#         base.update({'extension plpgsql': {
#             'schema': 'pg_catalog', 'owner': PG_OWNER,
#             'description': "PL/pgSQL procedural language"}})
#         return base
# 
# def fix_indent(stmt):
#     "Fix specifications which are in a new line with indentation"
#     return stmt.replace('   ', ' ').replace('  ', ' ').replace('\n ', ' '). \
#         replace('( ', '(')


# Path: tests/dbobject/test_extension.py
import pytest
from pyrseas.testutils import DatabaseToMapTestCase
from pyrseas.testutils import InputMapToSqlTestCase, fix_indent


class ExtensionToSqlTestCase(InputMapToSqlTestCase):
    """Test SQL generation for input extensions"""

    def test_create_extension_simple(self):
        "Create a extension that didn't exist"
        inmap = self.std_map()
        inmap.update({'extension pg_trgm': {'schema': 'sd'}})
        sql = self.to_sql(inmap)
        assert fix_indent(sql[0]) == CREATE_STMT + " SCHEMA sd"

    def test_bad_extension_map(self):
        "Error creating a extension with a bad map"
        inmap = self.std_map()
        inmap.update({'pg_trgm': {'schema': 'sd'}})
        with pytest.raises(KeyError):
            self.to_sql(inmap)

    def test_drop_extension(self):
        "Drop an existing extension"
        sql = self.to_sql(self.std_map(), [CREATE_STMT], superuser=True)
        assert sql == ["DROP EXTENSION pg_trgm"]

    def test_create_extension_schema(self):
        "Create a extension in a given schema"
        inmap = self.std_map()
        inmap.update({'schema s1': {},
                      'extension pg_trgm': {'schema': 's1', 'version': '1.0'}})
        sql = self.to_sql(inmap)
        assert sql[0] == 'CREATE SCHEMA s1'

        assert fix_indent(sql[1]) == \