Infer Kotlin null-safety from type variables
This commit removes the constraint from type variables in PropertyResolver, JdbcOperations and RestOperations Kotlin extensions in order to get null-safety inferred from the type declared by the user. Closes gh-22687
This commit is contained in:
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.jdbc.core
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import java.sql.*
|
||||
|
||||
@@ -30,91 +32,96 @@ import java.sql.*
|
||||
*/
|
||||
class JdbcOperationsExtensionsTests {
|
||||
|
||||
val template = mockk<JdbcTemplate>(relaxed = true)
|
||||
val template = mockk<JdbcTemplate>()
|
||||
|
||||
val sql = "select age from customer where id = 3"
|
||||
|
||||
@Test
|
||||
fun `queryForObject with reified type parameters`() {
|
||||
val sql = "select age from customer where id = 3"
|
||||
template.queryForObject<Int>(sql)
|
||||
verify { template.queryForObject(sql, Integer::class.java) }
|
||||
every { template.queryForObject(sql, any<Class<Int>>()) } returns 2
|
||||
assertEquals(2, template.queryForObject<Int>(sql))
|
||||
verify { template.queryForObject(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with RowMapper-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
template.queryForObject(sql, 3) { rs: ResultSet, _: Int -> rs.getInt(1) }
|
||||
every { template.queryForObject(sql, any<RowMapper<Int>>(), any<Int>()) } returns 2
|
||||
assertEquals(2, template.queryForObject(sql, 3) { rs: ResultSet, _: Int -> rs.getInt(1) })
|
||||
verify { template.queryForObject(eq(sql), any<RowMapper<Int>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Test // gh-22682
|
||||
fun `queryForObject with nullable RowMapper-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
template.queryForObject(sql, 3) { _, _ -> null as Int? }
|
||||
every { template.queryForObject(sql, any<RowMapper<Int>>(), 3) } returns null
|
||||
assertNull(template.queryForObject(sql, 3) { _, _ -> null as Int? })
|
||||
verify { template.queryForObject(eq(sql), any<RowMapper<Int?>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with reified type parameters and argTypes`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
val args = arrayOf(3)
|
||||
val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber)
|
||||
template.queryForObject<Int>(sql, args, argTypes)
|
||||
verify { template.queryForObject(sql, args, argTypes, Integer::class.java) }
|
||||
every { template.queryForObject(sql, args, argTypes, any<Class<Int>>()) } returns 2
|
||||
assertEquals(2, template.queryForObject<Int>(sql, args, argTypes))
|
||||
verify { template.queryForObject(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with reified type parameters and args`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
val args = arrayOf(3)
|
||||
template.queryForObject<Int>(sql, args)
|
||||
verify { template.queryForObject(sql, args, Integer::class.java) }
|
||||
every { template.queryForObject(sql, args, any<Class<Int>>()) } returns 2
|
||||
assertEquals(2, template.queryForObject<Int>(sql, args))
|
||||
verify { template.queryForObject(sql, args, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters`() {
|
||||
val sql = "select age from customer where id = 3"
|
||||
template.queryForList<Int>(sql)
|
||||
verify { template.queryForList(sql, Integer::class.java) }
|
||||
val list = listOf(1, 2, 3)
|
||||
every { template.queryForList(sql, any<Class<Int>>()) } returns list
|
||||
assertEquals(list, template.queryForList<Int>(sql))
|
||||
verify { template.queryForList(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters and argTypes`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
val list = listOf(1, 2, 3)
|
||||
val args = arrayOf(3)
|
||||
val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber)
|
||||
template.queryForList<Int>(sql, args, argTypes)
|
||||
verify { template.queryForList(sql, args, argTypes, Integer::class.java) }
|
||||
every { template.queryForList(sql, args, argTypes, any<Class<Int>>()) } returns list
|
||||
assertEquals(list, template.queryForList<Int>(sql, args, argTypes))
|
||||
verify { template.queryForList(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters and args`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
val list = listOf(1, 2, 3)
|
||||
val args = arrayOf(3)
|
||||
every { template.queryForList(sql, args, any<Class<Int>>()) } returns list
|
||||
template.queryForList<Int>(sql, args)
|
||||
verify { template.queryForList(sql, args, Integer::class.java) }
|
||||
verify { template.queryForList(sql, args, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `query with ResultSetExtractor-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
template.query<Int>(sql, 3) { rs ->
|
||||
every { template.query(eq(sql), any<ResultSetExtractor<Int>>(), eq(3)) } returns 2
|
||||
assertEquals(2, template.query<Int>(sql, 3) { rs ->
|
||||
rs.next()
|
||||
rs.getInt(1)
|
||||
}
|
||||
})
|
||||
verify { template.query(eq(sql), any<ResultSetExtractor<Int>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Test // gh-22682
|
||||
fun `query with nullable ResultSetExtractor-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
template.query<Int?>(sql, 3) { _ -> null }
|
||||
every { template.query(eq(sql), any<ResultSetExtractor<Int?>>(), eq(3)) } returns null
|
||||
assertNull(template.query<Int?>(sql, 3) { _ -> null })
|
||||
verify { template.query(eq(sql), any<ResultSetExtractor<Int?>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
@Test
|
||||
fun `query with RowCallbackHandler-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
every { template.query(sql, ofType<RowCallbackHandler>(), 3) } returns Unit
|
||||
template.query(sql, 3) { rs ->
|
||||
assertEquals(22, rs.getInt(1))
|
||||
}
|
||||
@@ -123,10 +130,11 @@ class JdbcOperationsExtensionsTests {
|
||||
|
||||
@Test
|
||||
fun `query with RowMapper-like function`() {
|
||||
val sql = "select age from customer where id = ?"
|
||||
template.query(sql, 3) { rs, _ ->
|
||||
val list = listOf(1, 2, 3)
|
||||
every { template.query(sql, ofType<RowMapper<*>>(), 3) } returns list
|
||||
assertEquals(list, template.query(sql, 3) { rs, _ ->
|
||||
rs.getInt(1)
|
||||
}
|
||||
})
|
||||
verify { template.query(sql, ofType<RowMapper<*>>(), 3) }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user