@Test
  public void replaceLobWithTable() throws StructureGraphComparisonException {
    ISqlSchemaFrontend frontend1 = new H2SchemaFrontend(DATABASE_FILE_PATH);
    ISqlSchemaFrontend frontend2 = new H2SchemaFrontend(REPLACE_LOB_WITH_TABLE_DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema1 = frontend1.createSqlSchema();
    DirectedGraph<IStructureElement, DefaultEdge> schema2 = frontend2.createSqlSchema();
    SqlSchemaComparer comparer = new SqlSchemaComparer(schema1, schema2);
    SqlSchemaComparisonResult result = comparer.comparisonResult;

    assertEquals(
        29,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema1.vertexSet()).size());
    assertEquals(
        33,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema2.vertexSet()).size());

    for (Entry<ISqlElement, SchemaModification> entry : result.getModifications().entrySet()) {
      if (entry.getValue() == SchemaModification.CREATE_TABLE) {
        assertEquals(REPLACE_LOB_WITH_TABLE, entry.getKey().getName());
      }

      if (entry.getValue() == SchemaModification.DELETE_COLUMN) {
        assertEquals(REPLACE_LOB_WITH_COLUMN, entry.getKey().getName());
      }
    }
  }
  @Test
  public void replaceColumnDetectedCorrectly() throws StructureGraphComparisonException {
    ISqlSchemaFrontend frontend1 = new H2SchemaFrontend(DATABASE_FILE_PATH);
    ISqlSchemaFrontend frontend2 = new H2SchemaFrontend(REPLACE_COLUMN_DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema1 = frontend1.createSqlSchema();
    DirectedGraph<IStructureElement, DefaultEdge> schema2 = frontend2.createSqlSchema();
    SqlSchemaComparer comparer = new SqlSchemaComparer(schema1, schema2);
    SqlSchemaComparisonResult result = comparer.comparisonResult;

    assertEquals(
        29,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema1.vertexSet()).size());
    assertEquals(
        29,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema2.vertexSet()).size());

    Entry<ISqlElement, SchemaModification> renameColumnEntry =
        TestHelper.getModificationOfType(result, SchemaModification.RENAME_COLUMN);
    Entry<ISqlElement, SchemaModification> replaceColumnTypeEntry =
        TestHelper.getModificationOfType(result, SchemaModification.CHANGE_COLUMN_TYPE);

    assertNotNull(renameColumnEntry);
    assertEquals(REPLACE_COLUMN_NAME, renameColumnEntry.getKey().getName());
    assertNotNull(replaceColumnTypeEntry);
    assertEquals(
        REPLACE_COLUMN_TYPE, ((ColumnTypeVertex) replaceColumnTypeEntry.getKey()).getColumnType());
  }
  @Test
  public void databaseConnectionEstablishedCorrectly() {
    ISqlSchemaFrontend frontend = new H2SchemaFrontend(DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema = frontend.createSqlSchema();
    Set<ISqlElement> tables =
        SqlElementFactory.getSqlElementsOfType(SqlTableVertex.class, schema.vertexSet());
    Set<ISqlElement> columns =
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema.vertexSet());
    ArrayList<ISqlElement> mandatoryColumns = new ArrayList<>();
    int tableCount = tables.size();
    int columnCount = columns.size();

    for (ISqlElement column : columns) {
      if (column.isMandatory() && !isPrimaryKey(schema, column)) {
        mandatoryColumns.add(column);
      }
    }

    assertNotNull(schema);
    assertEquals(7, tableCount);
    assertEquals(29, columnCount);
    assertEquals(
        7,
        TestHelper.getColumnWithConstraint(schema, IColumnConstraint.ConstraintType.PRIMARY_KEY)
            .size());
    assertEquals(1, mandatoryColumns.size());
    assertEquals("[Column] DEPARTMENTS.NAME", mandatoryColumns.get(0).toString());
  }
  @Test
  public void tableHasColumnRelationsEstablishedCorrectly() {
    ISqlSchemaFrontend frontend = new H2SchemaFrontend(DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema = frontend.createSqlSchema();
    int tableHasColumnEdges = 0;

    for (DefaultEdge edge : schema.edgeSet())
      if (edge instanceof TableHasColumnEdge) tableHasColumnEdges++;

    assertEquals(29, tableHasColumnEdges);
  }
  @Test
  public void foreignKeysEstablishedCorrectly() {
    ISqlSchemaFrontend frontend = new H2SchemaFrontend(DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema = frontend.createSqlSchema();
    int foreignKeyEdges = 0;

    for (DefaultEdge edge : schema.edgeSet())
      if (edge instanceof ForeignKeyRelationEdge) foreignKeyEdges++;

    assertEquals(7, foreignKeyEdges);
  }
  @Test
  public void droppedColumnDetectedCorrectly() throws StructureGraphComparisonException {
    ISqlSchemaFrontend frontend1 = new H2SchemaFrontend(DATABASE_FILE_PATH);
    ISqlSchemaFrontend frontend2 = new H2SchemaFrontend(DROPPED_COLUMN_DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema1 = frontend1.createSqlSchema();
    DirectedGraph<IStructureElement, DefaultEdge> schema2 = frontend2.createSqlSchema();
    SqlSchemaComparer comparer = new SqlSchemaComparer(schema1, schema2);
    SqlSchemaComparisonResult result = comparer.comparisonResult;

    assertEquals(
        29,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema1.vertexSet()).size());
    assertEquals(
        28,
        SqlElementFactory.getSqlElementsOfType(SqlColumnVertex.class, schema2.vertexSet()).size());

    Entry<ISqlElement, SchemaModification> entry =
        TestHelper.getModificationOfType(result, SchemaModification.DELETE_COLUMN);

    assertNotNull(entry);
    assertEquals(DROPPED_COLUMN_NAME, entry.getKey().getName());
  }
  @Test
  public void droppedTableDetectedCorrectly() throws StructureGraphComparisonException {
    ISqlSchemaFrontend frontend1 = new H2SchemaFrontend(DATABASE_FILE_PATH);
    ISqlSchemaFrontend frontend2 = new H2SchemaFrontend(DROPPED_TABLE_DATABASE_FILE_PATH);
    DirectedGraph<IStructureElement, DefaultEdge> schema1 = frontend1.createSqlSchema();
    DirectedGraph<IStructureElement, DefaultEdge> schema2 = frontend2.createSqlSchema();
    SqlSchemaComparer comparer = new SqlSchemaComparer(schema1, schema2);
    SqlSchemaComparisonResult result = comparer.comparisonResult;

    assertEquals(
        7,
        SqlElementFactory.getSqlElementsOfType(SqlTableVertex.class, schema1.vertexSet()).size());
    assertEquals(
        6,
        SqlElementFactory.getSqlElementsOfType(SqlTableVertex.class, schema2.vertexSet()).size());

    for (Entry<ISqlElement, SchemaModification> entry : result.getModifications().entrySet()) {
      if (entry.getValue() == SchemaModification.DELETE_TABLE) {
        assertEquals(SchemaModification.DELETE_TABLE, entry.getValue());
        assertEquals(DROPPED_TABLE_NAME, entry.getKey().getName());
      }
    }
  }
  @Test(expected = IllegalArgumentException.class)
  public void throwsInvalidArgumentExceptionOnInvalidFilePath() {
    ISqlSchemaFrontend frontend = new H2SchemaFrontend("dadidadam");

    frontend.createSqlSchema();
  }
  @Test(expected = InvalidPathException.class)
  public void throwsInvalidFilePathExceptionForNull() {
    ISqlSchemaFrontend frontend = new H2SchemaFrontend(null);

    frontend.createSqlSchema();
  }