Skip to content

Commit

Permalink
Add unit tests (#16)
Browse files Browse the repository at this point in the history
* Add unit tests

* Speedup build

* Add name for test report

* Rename parameter

* Add initial test

* Upgrade dependencies

* Add tests with custom row mappers

* Upgrade codeql

* Add tests with specified type

* Enable info output for sonar

* Add unit tests for simple result set

* Exclude integration tests also for sonar build

* Add changelog entry

* Describe how to view test coverage

* Add unit tests

* Add test for setting prepared stmt parameters

* Rename extractor

* Prepare release 0.6.1

---------

Co-authored-by: kaklakariada <[email protected]>
  • Loading branch information
kaklakariada and kaklakariada authored Jan 14, 2024
1 parent ca8f168 commit 1f112d8
Show file tree
Hide file tree
Showing 27 changed files with 600 additions and 137 deletions.
14 changes: 11 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ jobs:
run: echo 'testcontainers.reuse.enable=true' > "$HOME/.testcontainers.properties"

- name: Build with Java ${{ matrix.java }}
run: ./gradlew clean build --info -PjavaVersion=${{matrix.java}} -Dsonar.gradle.skipCompile=true
run: |
./gradlew clean build --info \
--exclude-task integrationTest \
-PjavaVersion=${{matrix.java}} \
-Dsonar.gradle.skipCompile=true
- name: Publish Test Report
- name: Publish Test Report for Java ${{ matrix.java }}
uses: scacap/action-surefire-report@v1
if: ${{ always() && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }}
with:
Expand All @@ -55,7 +59,11 @@ jobs:

- name: Sonar analysis
if: ${{ env.DEFAULT_JAVA == matrix.java && env.SONAR_TOKEN != null }}
run: ./gradlew sonar -Dsonar.token=$SONAR_TOKEN -Dsonar.gradle.skipCompile=true
run: |
./gradlew sonar --info \
--exclude-task integrationTest \
-Dsonar.token=$SONAR_TOKEN \
-Dsonar.gradle.skipCompile=true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ jobs:
with:
fetch-depth: 2

- name: Set up JDK 11
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 11
java-version: 17
cache: 'gradle'

- uses: gradle/wrapper-validation-action@v1

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: java

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.7.0] - unreleased

## [0.6.1] - 2024-01-14

- [PR #16](https://github.com/itsallcode/simple-jdbc/pull/16): Improve test coverage

## [0.6.0] - 2023-12-16

- [PR #15](https://github.com/itsallcode/simple-jdbc/pull/15): Refactor row mapper, add DB dialect detection
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Add dependency to your gradle project:

```groovy
dependencies {
implementation 'org.itsallcode:simple-jdbc:0.6.0'
implementation 'org.itsallcode:simple-jdbc:0.6.1'
}
```

Expand Down Expand Up @@ -62,6 +62,15 @@ Install to local maven repository:
./gradlew clean publishToMavenLocal
```

### Test Coverage

To calculate and view test coverage:

```sh
./gradlew check jacocoTestReport
open build/reports/jacoco/test/html/index.html
```

### Publish to Maven Central

1. Add the following to your `~/.gradle/gradle.properties`:
Expand Down
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

group 'org.itsallcode'
version = '0.6.0'
version = '0.6.1'

dependencies {
}
Expand Down Expand Up @@ -89,6 +89,7 @@ tasks.named('check') {
jacocoTestReport {
reports {
xml.required = true
html.required = true
}
}

Expand Down
6 changes: 3 additions & 3 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ dependencyResolutionManagement {
}
versionCatalogs {
libs {
library('assertj', 'org.assertj:assertj-core:3.24.2')
library('assertj', 'org.assertj:assertj-core:3.25.1')
library('h2', 'com.h2database:h2:2.2.224')
library('junitPioneer', 'org.junit-pioneer:junit-pioneer:2.2.0')
library('equalsverifier', 'nl.jqno.equalsverifier:equalsverifier:3.15.4')
library('equalsverifier', 'nl.jqno.equalsverifier:equalsverifier:3.15.6')
library('tostringverifier', 'com.jparams:to-string-verifier:1.4.8')
library('hamcrest', 'org.hamcrest:hamcrest-all:1.3')
library('hamcrestResultSetMatcher', 'com.exasol:hamcrest-resultset-matcher:1.6.3')
library('mockito', 'org.mockito:mockito-core:5.8.0')
library('mockitoJunit', 'org.mockito:mockito-junit-jupiter:5.8.0')
library('slf4jLogger', 'org.slf4j:slf4j-jdk14:2.0.9')
library('slf4jLogger', 'org.slf4j:slf4j-jdk14:2.0.11')
library('exasolJdbc', 'com.exasol:exasol-jdbc:7.1.20')
library('exasolTestcontainers', 'com.exasol:exasol-testcontainers:7.0.0')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class ExasolTypeTest {

private static final ExasolContainer<?> container = new ExasolContainer<>("8.23.1")
private static final ExasolContainer<?> container = new ExasolContainer<>("8.24.0")
.withRequiredServices(ExasolService.JDBC).withReuse(true);

@BeforeAll
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/org/itsallcode/jdbc/SimpleConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import org.itsallcode.jdbc.dialect.DbDialect;
import org.itsallcode.jdbc.identifier.Identifier;
import org.itsallcode.jdbc.identifier.SimpleIdentifier;
import org.itsallcode.jdbc.resultset.*;
import org.itsallcode.jdbc.resultset.generic.Row;

Expand Down Expand Up @@ -114,7 +113,7 @@ private SimplePreparedStatement prepareStatement(final String sql) {
*/
public <T> void insert(final String table, final List<String> columnNames, final ParamConverter<T> rowMapper,
final Stream<T> rows) {
insert(SimpleIdentifier.of(table), columnNames.stream().map(SimpleIdentifier::of).toList(), rowMapper, rows);
insert(Identifier.simple(table), columnNames.stream().map(Identifier::simple).toList(), rowMapper, rows);
}

/**
Expand Down Expand Up @@ -168,7 +167,7 @@ public void close() {
try {
connection.close();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error closing connection", e);
throw new UncheckedSQLException("Error closing connection: " + e.getMessage(), e);
}
}
}
12 changes: 6 additions & 6 deletions src/main/java/org/itsallcode/jdbc/SimplePreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private ResultSet doExecute() {
try {
return statement.executeQuery();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error executing query '" + sql + "'", e);
throw new UncheckedSQLException("Error executing query '" + sql + "': " + e.getMessage(), e);
}
}

Expand All @@ -38,15 +38,15 @@ public void close() {
try {
statement.close();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error closing statement", e);
throw new UncheckedSQLException("Error closing statement: " + e.getMessage(), e);
}
}

void setValues(final PreparedStatementSetter preparedStatementSetter) {
try {
preparedStatementSetter.setValues(statement);
} catch (final SQLException e) {
throw new UncheckedSQLException("Error setting values for prepared statement", e);
throw new UncheckedSQLException("Error setting values for prepared statement: " + e.getMessage(), e);
}

}
Expand All @@ -55,23 +55,23 @@ void executeBatch() {
try {
statement.executeBatch();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error executing batch sql '" + sql + "'", e);
throw new UncheckedSQLException("Error executing batch sql '" + sql + "': " + e.getMessage(), e);
}
}

void addBatch() {
try {
this.statement.addBatch();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error adding batch", e);
throw new UncheckedSQLException("Error adding batch: " + e.getMessage(), e);
}
}

SimpleParameterMetaData getParameterMetadata() {
try {
return new SimpleParameterMetaData(statement.getParameterMetaData());
} catch (final SQLException e) {
throw new UncheckedSQLException("Error getting parameter metadata", e);
throw new UncheckedSQLException("Error getting parameter metadata: " + e.getMessage(), e);
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/org/itsallcode/jdbc/dialect/Extractors.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ static ColumnValueExtractor timestampToUTCInstant() {
return nonNull((resultSet, columnIndex) -> resultSet.getTimestamp(columnIndex, utcCalendar).toInstant());
}

public static ColumnValueExtractor timestampToInstant() {
return nonNull((resultSet, columnIndex) -> resultSet.getTimestamp(columnIndex).toInstant());
}

static ColumnValueExtractor dateToLocalDate() {
final Calendar utcCalendar = createUtcCalendar();
return nonNull((resultSet, columnIndex) -> resultSet.getDate(columnIndex, utcCalendar).toLocalDate());
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/itsallcode/jdbc/dialect/H2Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public H2Dialect() {
public ColumnValueExtractor createExtractor(final ColumnMetaData column) {
return switch (column.type().jdbcType()) {
case TIMESTAMP -> Extractors.timestampToUTCInstant();
case TIMESTAMP_WITH_TIMEZONE -> Extractors.timestampToInstant();
case CLOB -> Extractors.clobToString();
case BLOB -> Extractors.blobToBytes();
case TIME -> Extractors.forType(LocalTime.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package org.itsallcode.jdbc.identifier;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining;

import java.util.Arrays;
import java.util.List;

/**
* A qualified identifier, e.g. table name and schema name.
*/
public class QualifiedIdentifier implements Identifier {
private final Identifier[] id;

private QualifiedIdentifier(final Identifier... ids) {
this.id = ids;
}
record QualifiedIdentifier(List<Identifier> id) implements Identifier {

/**
* Create a new qualified identifier.
Expand All @@ -21,7 +17,7 @@ private QualifiedIdentifier(final Identifier... ids) {
* @return a new instance
*/
public static Identifier of(final Identifier... ids) {
return new QualifiedIdentifier(ids);
return new QualifiedIdentifier(asList(ids));
}

@Override
Expand All @@ -31,6 +27,6 @@ public String toString() {

@Override
public String quote() {
return Arrays.stream(id).map(Identifier::quote).collect(joining("."));
return id.stream().map(Identifier::quote).collect(joining("."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
/**
* An identifier consisting only of an ID.
*/
public class SimpleIdentifier implements Identifier {
private final String id;

private SimpleIdentifier(final String id) {
this.id = id;
}
record SimpleIdentifier(String id) implements Identifier {

/**
* Create a new simple identifier.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,31 @@ static ResultSetValueConverter create(final SimpleMetaData resultSetMetadata,
return new ResultSetValueConverter(convertersByIndex, columnIndexByLabel);
}

<T> T getObject(final ResultSet delegate, final int columnIndex, final Class<T> type) throws SQLException {
return getConverter(columnIndex).getObject(delegate, columnIndex, type);
<T> T getObject(final ResultSet resultSet, final int columnIndex, final Class<T> type) throws SQLException {
return getConverter(columnIndex).getObject(resultSet, columnIndex, type);
}

Object getObject(final ResultSet delegate, final int columnIndex) throws SQLException {
return getConverter(columnIndex).getObject(delegate, columnIndex);
Object getObject(final ResultSet resultSet, final int columnIndex) throws SQLException {
return getConverter(columnIndex).getObject(resultSet, columnIndex);
}

<T> T getObject(final ResultSet delegate, final String columnLabel, final Class<T> type)
<T> T getObject(final ResultSet resultSet, final String columnLabel, final Class<T> type)
throws SQLException {
final int columnIndex = getIndexForLabel(columnLabel);
return getConverter(columnIndex).getObject(delegate, columnIndex, type);
return getConverter(columnIndex).getObject(resultSet, columnIndex, type);
}

Object getObject(final ResultSet delegate, final String columnLabel)
Object getObject(final ResultSet resultSet, final String columnLabel)
throws SQLException {
final int columnIndex = getIndexForLabel(columnLabel);
return getConverter(columnIndex).getObject(delegate, columnIndex);
return getConverter(columnIndex).getObject(resultSet, columnIndex);
}

private int getIndexForLabel(final String columnLabel) {
final Integer index = columnIndexByLabel.get(columnLabel);
final Integer index = columnIndexByLabel.get(columnLabel.toUpperCase());
if (index == null) {
throw new IllegalStateException("No index found for column label '" + columnLabel + "'");
throw new IllegalStateException("No index found for column label '" + columnLabel
+ "'. Available column labels: " + columnIndexByLabel.keySet());
}
return index.intValue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ public void close() {
try {
resultSet.close();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error closing resultset", e);
throw new UncheckedSQLException("Error closing resultset: " + e.getMessage(), e);
}
}

private boolean next() {
try {
return resultSet.next();
} catch (final SQLException e) {
throw new UncheckedSQLException("Error getting next row", e);
throw new UncheckedSQLException("Error getting next row: " + e.getMessage(), e);
}
}

Expand Down Expand Up @@ -131,7 +131,9 @@ private T mapRow() {
try {
return rowMapper.mapRow(context, resultSet.resultSet, currentRowIndex);
} catch (final SQLException e) {
throw new UncheckedSQLException("Error mapping row " + currentRowIndex, e);
throw new UncheckedSQLException("Error mapping row " + currentRowIndex + ": " + e.getMessage(), e);
} catch (final RuntimeException e) {
throw new IllegalStateException("Error mapping row " + currentRowIndex + ": " + e.getMessage(), e);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/itsallcode/jdbc/H2TestFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static SimpleConnection createMemConnection() {
return createMemConnection(Context.builder().build());
}

public static SimpleConnection createMemConnection(final Context context) {
private static SimpleConnection createMemConnection(final Context context) {
return ConnectionFactory.create(context).create("jdbc:h2:mem:");
}
}
Loading

0 comments on commit 1f112d8

Please sign in to comment.