diff --git a/pom.xml b/pom.xml index 23d6477249..ada5446016 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT pom Spring Data MongoDB @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATABUILD-369-SNAPSHOT diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml index 4a49168713..72cf07e714 100644 --- a/spring-data-mongodb-cross-store/pom.xml +++ b/spring-data-mongodb-cross-store/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-mongodb-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT ../pom.xml @@ -48,7 +48,7 @@ org.springframework.data spring-data-mongodb - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index 750ed23aa8..54b1c2bd59 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml index 50d0a6454a..b4692cd9a5 100644 --- a/spring-data-mongodb-log4j/pom.xml +++ b/spring-data-mongodb-log4j/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 99ef83a54b..d77efc652c 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,13 +11,14 @@ org.springframework.data spring-data-mongodb-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.DATAMONGO-1689-SNAPSHOT ../pom.xml 1.3 1.5 + 1.1.2-5 @@ -230,12 +231,108 @@ spring-webmvc test + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin} + true + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin} + true + + + org.jetbrains.kotlin + kotlin-test + ${kotlin} + test + + + com.nhaarman + mockito-kotlin + 1.5.0 + test + + + org.jetbrains.kotlin + kotlin-stdlib + + + org.jetbrains.kotlin + kotlin-reflect + + + org.mockito + mockito-core + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin} + + 1.8 + + + + compile + compile + compile + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + + + + test-compile + test-compile + test-compile + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + java-compile + compile + compile + + + java-test-compile + test-compile + testCompile + + + + com.mysema.maven apt-maven-plugin diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensions.kt new file mode 100644 index 0000000000..5b43222c42 --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensions.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import kotlin.reflect.KClass + +/** + * Extension for [ExecutableAggregationOperation.aggregateAndReturn] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ExecutableAggregationOperation.aggregateAndReturn(entityClass: KClass): ExecutableAggregationOperation.AggregationOperation = + aggregateAndReturn(entityClass.java) + +/** + * Extension for [ExecutableAggregationOperation.aggregateAndReturn] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ExecutableAggregationOperation.aggregateAndReturn(): ExecutableAggregationOperation.AggregationOperation = + aggregateAndReturn(T::class.java) \ No newline at end of file diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensions.kt new file mode 100644 index 0000000000..be445235e1 --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensions.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import kotlin.reflect.KClass + +/** + * Extension for [ExecutableFindOperation.query] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ExecutableFindOperation.query(entityClass: KClass): ExecutableFindOperation.FindOperation = + query(entityClass.java) + +/** + * Extension for [ExecutableFindOperation.query] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ExecutableFindOperation.query(): ExecutableFindOperation.FindOperation = + query(T::class.java) + + +/** + * Extension for [ExecutableFindOperation.FindOperationWithProjection.as] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ExecutableFindOperation.FindOperationWithProjection.asType(resultType: KClass): ExecutableFindOperation.FindOperationWithQuery = + `as`(resultType.java) + +/** + * Extension for [ExecutableFindOperation.FindOperationWithProjection.as] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ExecutableFindOperation.FindOperationWithProjection.asType(): ExecutableFindOperation.FindOperationWithQuery = + `as`(T::class.java) + + diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensions.kt new file mode 100644 index 0000000000..1b0f80fcc0 --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensions.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import kotlin.reflect.KClass + +/** + * Extension for [ExecutableInsertOperation.insert] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ExecutableInsertOperation.insert(entityClass: KClass): ExecutableInsertOperation.InsertOperation = + insert(entityClass.java) + +/** + * Extension for [ExecutableInsertOperation.insert] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ExecutableInsertOperation.insert(): ExecutableInsertOperation.InsertOperation = + insert(T::class.java) \ No newline at end of file diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensions.kt new file mode 100644 index 0000000000..5c84e67d64 --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensions.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import kotlin.reflect.KClass + +/** + * Extension for [ExecutableRemoveOperation.remove] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ExecutableRemoveOperation.remove(entityClass: KClass): ExecutableRemoveOperation.RemoveOperation = + remove(entityClass.java) + +/** + * Extension for [ExecutableRemoveOperation.remove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ExecutableRemoveOperation.remove(): ExecutableRemoveOperation.RemoveOperation = + remove(T::class.java) \ No newline at end of file diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensions.kt new file mode 100644 index 0000000000..7956df812b --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensions.kt @@ -0,0 +1,466 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import com.mongodb.client.MongoCollection +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.UpdateResult +import org.bson.Document +import org.springframework.data.geo.GeoResults +import org.springframework.data.mongodb.core.BulkOperations.BulkMode +import org.springframework.data.mongodb.core.aggregation.Aggregation +import org.springframework.data.mongodb.core.aggregation.AggregationResults +import org.springframework.data.mongodb.core.mapreduce.GroupBy +import org.springframework.data.mongodb.core.mapreduce.GroupByResults +import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions +import org.springframework.data.mongodb.core.mapreduce.MapReduceResults +import org.springframework.data.mongodb.core.query.Criteria +import org.springframework.data.mongodb.core.query.NearQuery +import org.springframework.data.mongodb.core.query.Query +import org.springframework.data.mongodb.core.query.Update +import org.springframework.data.util.CloseableIterator +import kotlin.reflect.KClass + +/** + * Extension for [MongoOperations.getCollectionName] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.getCollectionName(entityClass: KClass): String = + getCollectionName(entityClass.java) + +/** + * Extension for [MongoOperations.getCollectionName] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.getCollectionName(): String = + getCollectionName(T::class.java) + +/** + * Extension for [MongoOperations.execute] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.execute(action: CollectionCallback): T = + execute(T::class.java, action) + +/** + * Extension for [MongoOperations.stream] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.stream(query: Query): CloseableIterator = + stream(query, T::class.java) + +/** + * Extension for [MongoOperations.stream] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.stream(query: Query, collectionName: String? = null): CloseableIterator = + if (collectionName != null) stream(query, T::class.java, collectionName) + else stream(query, T::class.java) + +/** + * Extension for [MongoOperations.createCollection] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.createCollection(entityClass: KClass, collectionOptions: CollectionOptions? = null): MongoCollection = + if (collectionOptions != null) createCollection(entityClass.java, collectionOptions) + else createCollection(entityClass.java) + +/** + * Extension for [MongoOperations.createCollection] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.createCollection( + collectionOptions: CollectionOptions? = null): MongoCollection = + if (collectionOptions != null) createCollection(T::class.java, collectionOptions) + else createCollection(T::class.java) + +/** + * Extension for [MongoOperations.collectionExists] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.collectionExists(entityClass: KClass): Boolean = + collectionExists(entityClass.java) + +/** + * Extension for [MongoOperations.collectionExists] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.collectionExists(): Boolean = + collectionExists(T::class.java) + +/** + * Extension for [MongoOperations.dropCollection] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.dropCollection(entityClass: KClass) { + dropCollection(entityClass.java) +} + +/** + * Extension for [MongoOperations.dropCollection] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.dropCollection() { + dropCollection(T::class.java) +} + +/** + * Extension for [MongoOperations.indexOps] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.indexOps(entityClass: KClass): IndexOperations = + indexOps(entityClass.java) + +/** + * Extension for [MongoOperations.indexOps] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.indexOps(): IndexOperations = + indexOps(T::class.java) + +/** + * Extension for [MongoOperations.bulkOps] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.bulkOps(bulkMode: BulkMode, entityClass: KClass, collectionName: String? = null): BulkOperations = + if (collectionName != null) bulkOps(bulkMode, entityClass.java, collectionName) + else bulkOps(bulkMode, entityClass.java) + +/** + * Extension for [MongoOperations.bulkOps] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.bulkOps(bulkMode: BulkMode, collectionName: String? = null): BulkOperations = + if (collectionName != null) bulkOps(bulkMode, T::class.java, collectionName) + else bulkOps(bulkMode, T::class.java) + +/** + * Extension for [MongoOperations.findAll] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findAll(collectionName: String? = null): List = + if (collectionName != null) findAll(T::class.java, collectionName) else findAll(T::class.java) + +/** + * Extension for [MongoOperations.group] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.group(inputCollectionName: String, groupBy: GroupBy): GroupByResults = + group(inputCollectionName, groupBy, T::class.java) + +/** + * Extension for [MongoOperations.group] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.group(criteria: Criteria, inputCollectionName: String, groupBy: GroupBy): GroupByResults = + group(criteria, inputCollectionName, groupBy, T::class.java) + +/** + * Extension for [MongoOperations.aggregate] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.aggregate(aggregation: Aggregation, inputType: KClass<*>): AggregationResults = + aggregate(aggregation, inputType.java, O::class.java) + +/** + * Extension for [MongoOperations.aggregate] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.aggregate(aggregation: Aggregation, collectionName: String): AggregationResults = + aggregate(aggregation, collectionName, O::class.java) + +/** + * Extension for [MongoOperations.aggregateStream] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.aggregateStream(aggregation: Aggregation, inputType: KClass<*>): CloseableIterator = + aggregateStream(aggregation, inputType.java, O::class.java) + +/** + * Extension for [MongoOperations.aggregateStream] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.aggregateStream(aggregation: Aggregation, collectionName: String): CloseableIterator = + aggregateStream(aggregation, collectionName, O::class.java) + +/** + * Extension for [MongoOperations.mapReduce] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.mapReduce(collectionName: String, mapFunction: String, reduceFunction: String, options: MapReduceOptions? = null): MapReduceResults = + if (options != null) mapReduce(collectionName, mapFunction, reduceFunction, options, T::class.java) + else mapReduce(collectionName, mapFunction, reduceFunction, T::class.java) + +/** + * Extension for [MongoOperations.mapReduce] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 52.0 + */ +inline fun MongoOperations.mapReduce(query: Query, collectionName: String, mapFunction: String, reduceFunction: String, options: MapReduceOptions? = null): MapReduceResults = + if (options != null) mapReduce(query, collectionName, mapFunction, reduceFunction, options, T::class.java) + else mapReduce(query, collectionName, mapFunction, reduceFunction, T::class.java) + +/** + * Extension for [MongoOperations.geoNear] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.geoNear(near: NearQuery, collectionName: String? = null): GeoResults = + if (collectionName != null) geoNear(near, T::class.java, collectionName) + else geoNear(near, T::class.java) + +/** + * Extension for [MongoOperations.findOne] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findOne(query: Query, collectionName: String? = null): T = + if (collectionName != null) findOne(query, T::class.java, collectionName) else findOne(query, T::class.java) + +/** + * Extension for [MongoOperations.exists] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.exists(query: Query, entityClass: KClass, collectionName: String? = null): Boolean = + if (collectionName != null) exists(query, entityClass.java, collectionName) + else exists(query, entityClass.java) + +/** + * Extension for [MongoOperations.exists] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.exists(query: Query, collectionName: String? = null): Boolean = + if (collectionName != null) exists(query, T::class.java, collectionName) + else exists(query, T::class.java) + +/** + * Extension for [MongoOperations.find] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.find(query: Query, collectionName: String? = null): List = + if (collectionName != null) find(query, T::class.java, collectionName) + else find(query, T::class.java) + +/** + * Extension for [MongoOperations.findById] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findById(id: Any, collectionName: String? = null): T = + if (collectionName != null) findById(id, T::class.java, collectionName) + else findById(id, T::class.java) + +/** + * Extension for [MongoOperations.findAndModify] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findAndModify(query: Query, update: Update, options: FindAndModifyOptions, collectionName: String? = null): T = + if (collectionName != null) findAndModify(query, update, options, T::class.java, collectionName) + else findAndModify(query, update, options, T::class.java) + +/** + * Extension for [MongoOperations.findAndRemove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findAndRemove(query: Query, collectionName: String? = null): T = + if (collectionName != null) findAndRemove(query, T::class.java, collectionName) + else findAndRemove(query, T::class.java) + +/** + * Extension for [MongoOperations.count] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.count(query: Query = Query(), entityClass: KClass, collectionName: String? = null): Long = + if (collectionName != null) count(query, entityClass.java, collectionName) + else count(query, entityClass.java) + +/** + * Extension for [MongoOperations.count] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.count(query: Query = Query(), collectionName: String? = null): Long = + if (collectionName != null) count(query, T::class.java, collectionName) else count(query, T::class.java) + +/** + * Extension for [MongoOperations.insert] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.insert(batchToSave: Collection, entityClass: KClass) { + insert(batchToSave, entityClass.java) +} + +/** + * Extension for [MongoOperations.upsert] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.upsert(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): UpdateResult = + if (collectionName != null) upsert(query, update, entityClass.java, collectionName) + else upsert(query, update, entityClass.java) + +/** + * Extension for [MongoOperations.upsert] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.upsert(query: Query, update: Update, collectionName: String? = null): UpdateResult = + if (collectionName != null) upsert(query, update, T::class.java, collectionName) + else upsert(query, update, T::class.java) + +/** + * Extension for [MongoOperations.updateFirst] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.updateFirst(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): UpdateResult = + if (collectionName != null) updateFirst(query, update, entityClass.java, collectionName) + else updateFirst(query, update, entityClass.java) + +/** + * Extension for [MongoOperations.updateFirst] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.updateFirst(query: Query, update: Update, collectionName: String? = null): UpdateResult = + if (collectionName != null) updateFirst(query, update, T::class.java, collectionName) + else updateFirst(query, update, T::class.java) + + +/** + * Extension for [MongoOperations.updateMulti] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.updateMulti(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): UpdateResult = + if (collectionName != null) updateMulti(query, update, entityClass.java, collectionName) + else updateMulti(query, update, entityClass.java) + +/** + * Extension for [MongoOperations.updateMulti] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.updateMulti(query: Query, update: Update, collectionName: String? = null): UpdateResult = + if (collectionName != null) updateMulti(query, update, T::class.java, collectionName) + else updateMulti(query, update, T::class.java) + +/** + * Extension for [MongoOperations.remove] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun MongoOperations.remove(query: Query, entityClass: KClass, collectionName: String? = null): DeleteResult = + if (collectionName != null) remove(query, entityClass.java, collectionName) + else remove(query, entityClass.java) + +/** + * Extension for [MongoOperations.remove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun MongoOperations.remove(query: Query, collectionName: String? = null): DeleteResult = + if (collectionName != null) remove(query, T::class.java, collectionName) + else remove(query, T::class.java) + +/** + * Extension for [MongoOperations.findAllAndRemove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun MongoOperations.findAllAndRemove(query: Query): List = + findAllAndRemove(query, T::class.java) diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensions.kt new file mode 100644 index 0000000000..5e92c8db49 --- /dev/null +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensions.kt @@ -0,0 +1,334 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.UpdateResult +import com.mongodb.reactivestreams.client.MongoCollection +import org.bson.Document +import org.springframework.data.geo.GeoResult +import org.springframework.data.mongodb.core.query.NearQuery +import org.springframework.data.mongodb.core.query.Query +import org.springframework.data.mongodb.core.query.Update +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import kotlin.reflect.KClass + +/** + * Extension for [ReactiveMongoOperations.indexOps] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.indexOps(entityClass: KClass): ReactiveIndexOperations = + indexOps(entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.indexOps] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.indexOps(): ReactiveIndexOperations = + indexOps(T::class.java) + +/** + * Extension for [ReactiveMongoOperations.execute] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.execute(action: ReactiveCollectionCallback): Flux = + execute(T::class.java, action) + +/** + * Extension for [ReactiveMongoOperations.createCollection] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.createCollection(entityClass: KClass, collectionOptions: CollectionOptions? = null): Mono> = + if (collectionOptions != null) createCollection(entityClass.java, collectionOptions) else createCollection(entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.createCollection] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.createCollection(collectionOptions: CollectionOptions? = null): Mono> = + if (collectionOptions != null) createCollection(T::class.java, collectionOptions) else createCollection(T::class.java) + +/** + * Extension for [ReactiveMongoOperations.collectionExists] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.collectionExists(entityClass: KClass): Mono = + collectionExists(entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.collectionExists] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.collectionExists(): Mono = + collectionExists(T::class.java) + +/** + * Extension for [ReactiveMongoOperations.dropCollection] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.dropCollection(entityClass: KClass): Mono = + dropCollection(entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.dropCollection] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.dropCollection(): Mono = + dropCollection(T::class.java) + + +/** + * Extension for [ReactiveMongoOperations.findAll] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.findAll(collectionName: String? = null): Flux = + if (collectionName != null) findAll(T::class.java, collectionName) else findAll(T::class.java) + +/** + * Extension for [ReactiveMongoOperations.findOne] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.findOne(query: Query, collectionName: String? = null): Mono = + if (collectionName != null) findOne(query, T::class.java, collectionName) else findOne(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.exists] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.exists(query: Query, entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) exists(query, entityClass.java, collectionName) else exists(query, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.exists] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.exists(query: Query, collectionName: String? = null): Mono = + if (collectionName != null) exists(query, T::class.java, collectionName) else exists(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.find] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.find(query: Query, collectionName: String? = null): Flux = + if (collectionName != null) find(query, T::class.java, collectionName) else find(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.findById] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.findById(id: Any, collectionName: String? = null): Mono = + if (collectionName != null) findById(id, T::class.java, collectionName) else findById(id, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.geoNear] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.geoNear(near: NearQuery, collectionName: String? = null): Flux> = + if (collectionName != null) geoNear(near, T::class.java, collectionName) else geoNear(near, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.findAndModify] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.findAndModify(query: Query, update: Update, options: FindAndModifyOptions, collectionName: String? = null): Mono = + if (collectionName != null) findAndModify(query, update, options, T::class.java, collectionName) else findAndModify(query, update, options, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.findAndRemove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.findAndRemove(query: Query, collectionName: String? = null): Mono = + if (collectionName != null) findAndRemove(query, T::class.java, collectionName) + else findAndRemove(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.count] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.count(query: Query = Query(), entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) count(query, entityClass.java, collectionName) + else count(query, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.count] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.count(query: Query = Query(), collectionName: String? = null): Mono = + if (collectionName != null) count(query, T::class.java, collectionName) + else count(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.insert] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.insert(batchToSave: Collection, entityClass: KClass): Flux = + insert(batchToSave, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.insertAll] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.insertAll(batchToSave: Mono>, entityClass: KClass): Flux = + insertAll(batchToSave, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.upsert] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.upsert(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) upsert(query, update, entityClass.java, collectionName) else upsert(query, update, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.upsert] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.upsert(query: Query, update: Update, collectionName: String? = null): Mono = + if (collectionName != null) upsert(query, update, T::class.java, collectionName) + else upsert(query, update, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.updateFirst] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.updateFirst(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) updateFirst(query, update, entityClass.java, collectionName) + else updateFirst(query, update, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.updateFirst] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.updateFirst(query: Query, update: Update, collectionName: String? = null): Mono = + if (collectionName != null) updateFirst(query, update, T::class.java, collectionName) + else updateFirst(query, update, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.updateMulti] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.updateMulti(query: Query, update: Update, entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) updateMulti(query, update, entityClass.java, collectionName) + else updateMulti(query, update, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.updateMulti] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.updateMulti(query: Query, update: Update, collectionName: String? = null): Mono = + if (collectionName != null) updateMulti(query, update, T::class.java, collectionName) + else updateMulti(query, update, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.remove] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +fun ReactiveMongoOperations.remove(query: Query, entityClass: KClass, collectionName: String? = null): Mono = + if (collectionName != null) remove(query, entityClass.java, collectionName) + else remove(query, entityClass.java) + +/** + * Extension for [ReactiveMongoOperations.remove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.remove(query: Query, collectionName: String? = null): Mono = + if (collectionName != null) remove(query, T::class.java, collectionName) + else remove(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.findAllAndRemove] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveMongoOperations.findAllAndRemove(query: Query): Flux = + findAllAndRemove(query, T::class.java) + +/** + * Extension for [ReactiveMongoOperations.tail] leveraging reified type parameters. + * + * @author Sebastien Deleuze + * @since 2.0 + */ +inline fun ReactiveMongoOperations.tail(query: Query, collectionName: String? = null): Flux = + if (collectionName != null) tail(query, T::class.java, collectionName) else tail(query, T::class.java) diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensionsTests.kt new file mode 100644 index 0000000000..2f49a75998 --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableAggregationOperationExtensionsTests.kt @@ -0,0 +1,32 @@ +package org.springframework.data.mongodb.core + +import example.first.First +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableAggregationOperationExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operation: ExecutableAggregationOperation + + @Test // DATAMONGO-1689 + fun `aggregateAndReturn(KClass) extension should call its Java counterpart`() { + operation.aggregateAndReturn(First::class) + Mockito.verify(operation, Mockito.times(1)).aggregateAndReturn(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `aggregateAndReturn() with reified type parameter extension should call its Java counterpart`() { + operation.aggregateAndReturn() + Mockito.verify(operation, Mockito.times(1)).aggregateAndReturn(First::class.java) + } + +} diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensionsTests.kt new file mode 100644 index 0000000000..20aa74484d --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableFindOperationExtensionsTests.kt @@ -0,0 +1,47 @@ +package org.springframework.data.mongodb.core + +import example.first.First +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableFindOperationExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operation: ExecutableFindOperation + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operationWithProjection: ExecutableFindOperation.FindOperationWithProjection + + @Test // DATAMONGO-1689 + fun `ExecutableFindOperation#query(KClass) extension should call its Java counterpart`() { + operation.query(First::class) + Mockito.verify(operation, Mockito.times(1)).query(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `ExecutableFindOperation#query() with reified type parameter extension should call its Java counterpart`() { + operation.query() + Mockito.verify(operation, Mockito.times(1)).query(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `ExecutableFindOperation#FindOperationWithProjection#asType(KClass) extension should call its Java counterpart`() { + operationWithProjection.asType(First::class) + Mockito.verify(operationWithProjection, Mockito.times(1)).`as`(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `ExecutableFindOperation#FindOperationWithProjection#asType() with reified type parameter extension should call its Java counterpart`() { + operationWithProjection.asType() + Mockito.verify(operationWithProjection, Mockito.times(1)).`as`(First::class.java) + } + +} diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensionsTests.kt new file mode 100644 index 0000000000..800c8dd82f --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableInsertOperationExtensionsTests.kt @@ -0,0 +1,32 @@ +package org.springframework.data.mongodb.core + +import example.first.First +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableInsertOperationExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operation: ExecutableInsertOperation + + @Test // DATAMONGO-1689 + fun `insert(KClass) extension should call its Java counterpart`() { + operation.insert(First::class) + Mockito.verify(operation, Mockito.times(1)).insert(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `insert() with reified type parameter extension should call its Java counterpart`() { + operation.insert() + Mockito.verify(operation, Mockito.times(1)).insert(First::class.java) + } + +} diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensionsTests.kt new file mode 100644 index 0000000000..126ff42e8b --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ExecutableRemoveOperationExtensionsTests.kt @@ -0,0 +1,32 @@ +package org.springframework.data.mongodb.core + +import example.first.First +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableRemoveOperationExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operation: ExecutableRemoveOperation + + @Test // DATAMONGO-1689 + fun `remove(KClass) extension should call its Java counterpart`() { + operation.remove(First::class) + Mockito.verify(operation, Mockito.times(1)).remove(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `remove() with reified type parameter extension should call its Java counterpart`() { + operation.remove() + Mockito.verify(operation, Mockito.times(1)).remove(First::class.java) + } + +} diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensionsTests.kt new file mode 100644 index 0000000000..ec3ee3ac4b --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/MongoOperationsExtensionsTests.kt @@ -0,0 +1,680 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import com.nhaarman.mockito_kotlin.mock +import example.first.First +import example.second.Second +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.mongodb.core.BulkOperations.BulkMode +import org.springframework.data.mongodb.core.aggregation.Aggregation +import org.springframework.data.mongodb.core.mapreduce.GroupBy +import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions +import org.springframework.data.mongodb.core.query.Criteria +import org.springframework.data.mongodb.core.query.NearQuery +import org.springframework.data.mongodb.core.query.Query +import org.springframework.data.mongodb.core.query.Update + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class MongoOperationsExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: MongoOperations + + @Test // DATAMONGO-1689 + fun `getCollectionName(KClass) extension should call its Java counterpart`() { + + operations.getCollectionName(First::class) + verify(operations, times(1)).getCollectionName(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `getCollectionName() with reified type parameter extension should call its Java counterpart`() { + + operations.getCollectionName() + verify(operations, times(1)).getCollectionName(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `execute(CollectionCallback) with reified type parameter extension should call its Java counterpart`() { + + val collectionCallback = mock>() + operations.execute(collectionCallback) + verify(operations, times(1)).execute(First::class.java, collectionCallback) + } + + @Test // DATAMONGO-1689 + fun `stream(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + operations.stream(query) + verify(operations, times(1)).stream(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `stream(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + operations.stream(query, collectionName) + verify(operations, times(1)).stream(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `createCollection(KClass) extension should call its Java counterpart`() { + + operations.createCollection(First::class) + verify(operations, times(1)).createCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `createCollection(KClass, CollectionOptions) extension should call its Java counterpart`() { + + val collectionOptions = mock() + operations.createCollection(First::class, collectionOptions) + verify(operations, times(1)).createCollection(First::class.java, collectionOptions) + } + + @Test // DATAMONGO-1689 + fun `createCollection() with reified type parameter extension should call its Java counterpart`() { + + operations.createCollection() + verify(operations, times(1)).createCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `createCollection(CollectionOptions) with reified type parameter extension should call its Java counterpart`() { + + val collectionOptions = mock() + operations.createCollection(collectionOptions) + verify(operations, times(1)).createCollection(First::class.java, collectionOptions) + } + + + @Test // DATAMONGO-1689 + fun `collectionExists(KClass) extension should call its Java counterpart`() { + + operations.collectionExists(First::class) + verify(operations, times(1)).collectionExists(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `collectionExists() with reified type parameter extension should call its Java counterpart`() { + + operations.collectionExists() + verify(operations, times(1)).collectionExists(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `dropCollection(KClass) extension should call its Java counterpart`() { + + operations.dropCollection(First::class) + verify(operations, times(1)).dropCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `dropCollection() with reified type parameter extension should call its Java counterpart`() { + + operations.dropCollection() + verify(operations, times(1)).dropCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `indexOps(KClass) extension should call its Java counterpart`() { + + operations.indexOps(First::class) + verify(operations, times(1)).indexOps(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `indexOps() with reified type parameter extension should call its Java counterpart`() { + + operations.indexOps() + verify(operations, times(1)).indexOps(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `bulkOps(BulkMode, KClass) extension should call its Java counterpart`() { + + val bulkMode = BulkMode.ORDERED + + operations.bulkOps(bulkMode, First::class) + verify(operations, times(1)).bulkOps(bulkMode, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `bulkOps(BulkMode, KClass, String) extension should call its Java counterpart`() { + + val bulkMode = BulkMode.ORDERED + val collectionName = "foo" + + operations.bulkOps(bulkMode, First::class, collectionName) + verify(operations, times(1)).bulkOps(bulkMode, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `bulkOps(BulkMode) with reified type parameter extension should call its Java counterpart`() { + + val bulkMode = BulkMode.ORDERED + + operations.bulkOps(bulkMode) + verify(operations, times(1)).bulkOps(bulkMode, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `bulkOps(BulkMode, String) with reified type parameter extension should call its Java counterpart`() { + + val bulkMode = BulkMode.ORDERED + val collectionName = "foo" + + operations.bulkOps(bulkMode, collectionName) + verify(operations, times(1)).bulkOps(bulkMode, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAll() with reified type parameter extension should call its Java counterpart`() { + + operations.findAll() + verify(operations, times(1)).findAll(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAll(String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + + operations.findAll(collectionName) + verify(operations, times(1)).findAll(First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `group(String, GroupBy) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val groupBy = mock() + + operations.group(collectionName, groupBy) + verify(operations, times(1)).group(collectionName, groupBy, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `group(Criteria, String, GroupBy) with reified type parameter extension should call its Java counterpart`() { + + val criteria = mock() + val collectionName = "foo" + val groupBy = mock() + + operations.group(criteria, collectionName, groupBy) + verify(operations, times(1)).group(criteria, collectionName, groupBy, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `aggregate(Aggregation, KClass) with reified type parameter extension should call its Java counterpart`() { + + val aggregation = mock() + + operations.aggregate(aggregation, Second::class) + verify(operations, times(1)).aggregate(aggregation, Second::class.java, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `aggregate(Aggregation, String) with reified type parameter extension should call its Java counterpart`() { + + val aggregation = mock() + val collectionName = "foo" + + operations.aggregate(aggregation, collectionName) + verify(operations, times(1)).aggregate(aggregation, collectionName, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `aggregateStream(Aggregation, KClass) with reified type parameter extension should call its Java counterpart`() { + + val aggregation = mock() + + operations.aggregateStream(aggregation, Second::class) + verify(operations, times(1)).aggregateStream(aggregation, Second::class.java, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `aggregateStream(Aggregation, String) with reified type parameter extension should call its Java counterpart`() { + + val aggregation = mock() + val collectionName = "foo" + + operations.aggregateStream(aggregation, collectionName) + verify(operations, times(1)).aggregateStream(aggregation, collectionName, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `mapReduce(String, String, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val mapFunction = "bar" + val reduceFunction = "baz" + + operations.mapReduce(collectionName, mapFunction, reduceFunction) + verify(operations, times(1)).mapReduce(collectionName, mapFunction, reduceFunction, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `mapReduce(String, String, String, MapReduceOptions) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val mapFunction = "bar" + val reduceFunction = "baz" + val options = mock() + + operations.mapReduce(collectionName, mapFunction, reduceFunction, options) + verify(operations, times(1)).mapReduce(collectionName, mapFunction, reduceFunction, options, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `mapReduce(Query, String, String, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + val mapFunction = "bar" + val reduceFunction = "baz" + + operations.mapReduce(query, collectionName, mapFunction, reduceFunction) + verify(operations, times(1)).mapReduce(query, collectionName, mapFunction, reduceFunction, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `mapReduce(Query, String, String, String, MapReduceOptions) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + val mapFunction = "bar" + val reduceFunction = "baz" + val options = mock() + + operations.mapReduce(query, collectionName, mapFunction, reduceFunction, options) + verify(operations, times(1)).mapReduce(query, collectionName, mapFunction, reduceFunction, options, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `geoNear(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = NearQuery.near(0.0, 0.0) + + operations.geoNear(query) + verify(operations, times(1)).geoNear(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `geoNear(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = NearQuery.near(0.0, 0.0) + + operations.geoNear(query, collectionName) + verify(operations, times(1)).geoNear(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findOne(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findOne(query) + verify(operations, times(1)).findOne(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findOne(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + + operations.findOne(query, collectionName) + verify(operations, times(1)).findOne(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `exists(Query, KClass) extension should call its Java counterpart`() { + + val query = mock() + + operations.exists(query, First::class) + verify(operations, times(1)).exists(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.exists(query) + verify(operations, times(1)).exists(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `find(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.find(query) + verify(operations, times(1)).find(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `find(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + + operations.find(query, collectionName) + verify(operations, times(1)).find(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findById(Any) with reified type parameter extension should call its Java counterpart`() { + + val id = 1L + + operations.findById(id) + verify(operations, times(1)).findById(id, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findById(Any, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val id = 1L + + operations.findById(id, collectionName) + verify(operations, times(1)).findById(id, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAndModify(Query, Update, FindAndModifyOptions) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val options = mock() + + operations.findAndModify(query, update, options) + verify(operations, times(1)).findAndModify(query, update, options, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAndModify(Query, Update, FindAndModifyOptions, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + val update = mock() + val options = mock() + + operations.findAndModify(query, update, options, collectionName) + verify(operations, times(1)).findAndModify(query, update, options, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAndRemove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findAndRemove(query) + verify(operations, times(1)).findAndRemove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAndRemove(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.findAndRemove(query, collectionName) + verify(operations, times(1)).findAndRemove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `count() with reified type parameter extension should call its Java counterpart`() { + + operations.count() + verify(operations, times(1)).count(any(), eq(First::class.java)) + } + + @Test // DATAMONGO-1689 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.count(query) + verify(operations, times(1)).count(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `count(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.count(query, collectionName) + verify(operations, times(1)).count(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `count(Query, KClass) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.count(query, First::class) + verify(operations, times(1)).count(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `count(Query, KClass, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.count(query, First::class, collectionName) + verify(operations, times(1)).count(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `insert(Collection, KClass) extension should call its Java counterpart`() { + + val collection = listOf(First(), First()) + + operations.insert(collection, First::class) + verify(operations, times(1)).insert(collection, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.upsert(query, update, First::class) + verify(operations, times(1)).upsert(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.upsert(query, update, First::class, collectionName) + verify(operations, times(1)).upsert(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.upsert(query, update) + verify(operations, times(1)).upsert(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.upsert(query, update, collectionName) + verify(operations, times(1)).upsert(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateFirst(query, update, First::class) + verify(operations, times(1)).updateFirst(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateFirst(query, update, First::class, collectionName) + verify(operations, times(1)).updateFirst(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateFirst(query, update) + verify(operations, times(1)).updateFirst(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateFirst(query, update, collectionName) + verify(operations, times(1)).updateFirst(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateMulti(query, update, First::class) + verify(operations, times(1)).updateMulti(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateMulti(query, update, First::class, collectionName) + verify(operations, times(1)).updateMulti(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateMulti(query, update) + verify(operations, times(1)).updateMulti(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateMulti(query, update, collectionName) + verify(operations, times(1)).updateMulti(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, KClass) extension should call its Java counterpart`() { + + val query = mock() + + operations.remove(query, First::class) + verify(operations, times(1)).remove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.remove(query, First::class, collectionName) + verify(operations, times(1)).remove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `remove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.remove(query) + verify(operations, times(1)).remove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.remove(query, collectionName) + verify(operations, times(1)).remove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAllAndRemove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findAllAndRemove(query) + verify(operations, times(1)).findAllAndRemove(query, First::class.java) + } +} diff --git a/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensionsTests.kt b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensionsTests.kt new file mode 100644 index 0000000000..e41af8fc0b --- /dev/null +++ b/spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/ReactiveMongoOperationsExtensionsTests.kt @@ -0,0 +1,529 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core + +import com.nhaarman.mockito_kotlin.mock +import example.first.First +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.mongodb.core.query.NearQuery +import org.springframework.data.mongodb.core.query.Query +import org.springframework.data.mongodb.core.query.Update +import reactor.core.publisher.Mono + +/** + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveMongoOperationsExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveMongoOperations + + @Test // DATAMONGO-1689 + fun `indexOps(KClass) extension should call its Java counterpart`() { + + operations.indexOps(First::class) + verify(operations, times(1)).indexOps(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `indexOps() with reified type parameter extension should call its Java counterpart`() { + + operations.indexOps() + verify(operations, times(1)).indexOps(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `execute(ReactiveCollectionCallback) with reified type parameter extension should call its Java counterpart`() { + + val collectionCallback = mock>() + + operations.execute(collectionCallback) + verify(operations, times(1)).execute(First::class.java, collectionCallback) + } + + @Test // DATAMONGO-1689 + fun `createCollection(KClass) extension should call its Java counterpart`() { + + operations.createCollection(First::class) + verify(operations, times(1)).createCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `createCollection(KClass, CollectionOptions) extension should call its Java counterpart`() { + + val collectionOptions = mock() + + operations.createCollection(First::class, collectionOptions) + verify(operations, times(1)).createCollection(First::class.java, collectionOptions) + } + + @Test // DATAMONGO-1689 + fun `createCollection() with reified type parameter extension should call its Java counterpart`() { + + operations.createCollection() + verify(operations, times(1)).createCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `createCollection(CollectionOptions) with reified type parameter extension should call its Java counterpart`() { + + val collectionOptions = mock() + + operations.createCollection(collectionOptions) + verify(operations, times(1)).createCollection(First::class.java, collectionOptions) + } + + @Test // DATAMONGO-1689 + fun `collectionExists(KClass) extension should call its Java counterpart`() { + + operations.collectionExists(First::class) + verify(operations, times(1)).collectionExists(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `collectionExists() with reified type parameter extension should call its Java counterpart`() { + + operations.collectionExists() + verify(operations, times(1)).collectionExists(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `dropCollection(KClass) extension should call its Java counterpart`() { + + operations.dropCollection(First::class) + verify(operations, times(1)).dropCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `dropCollection() with reified type parameter extension should call its Java counterpart`() { + + operations.dropCollection() + verify(operations, times(1)).dropCollection(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAll() with reified type parameter extension should call its Java counterpart`() { + + operations.findAll() + verify(operations, times(1)).findAll(First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAll(String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + + operations.findAll(collectionName) + verify(operations, times(1)).findAll(First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findOne(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findOne(query) + verify(operations, times(1)).findOne(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findOne(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + + operations.findOne(query, collectionName) + verify(operations, times(1)).findOne(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `exists(Query, KClass) extension should call its Java counterpart`() { + + val query = mock() + + operations.exists(query, First::class) + verify(operations, times(1)).exists(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.exists(query) + verify(operations, times(1)).exists(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `find(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.find(query) + verify(operations, times(1)).find(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `find(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + + operations.find(query, collectionName) + verify(operations, times(1)).find(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findById(Any) with reified type parameter extension should call its Java counterpart`() { + + val id = 1L + + operations.findById(id) + verify(operations, times(1)).findById(id, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findById(Any, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val id = 1L + + operations.findById(id, collectionName) + verify(operations, times(1)).findById(id, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `geoNear(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = NearQuery.near(0.0, 0.0) + + operations.geoNear(query) + verify(operations, times(1)).geoNear(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `geoNear(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = NearQuery.near(0.0, 0.0) + + operations.geoNear(query, collectionName) + verify(operations, times(1)).geoNear(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAndModify(Query, Update, FindAndModifyOptions) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val options = mock() + + operations.findAndModify(query, update, options) + verify(operations, times(1)).findAndModify(query, update, options, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAndModify(Query, Update, FindAndModifyOptions, String) with reified type parameter extension should call its Java counterpart`() { + + val collectionName = "foo" + val query = mock() + val update = mock() + val options = mock() + + operations.findAndModify(query, update, options, collectionName) + verify(operations, times(1)).findAndModify(query, update, options, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAndRemove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findAndRemove(query) + verify(operations, times(1)).findAndRemove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `findAndRemove(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.findAndRemove(query, collectionName) + verify(operations, times(1)).findAndRemove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `count() with reified type parameter extension should call its Java counterpart`() { + + operations.count() + verify(operations, times(1)).count(any(), eq(First::class.java)) + } + + @Test // DATAMONGO-1689 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.count(query) + verify(operations, times(1)).count(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `count(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.count(query, collectionName) + verify(operations, times(1)).count(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `count(Query, KClass) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.count(query, First::class) + verify(operations, times(1)).count(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `count(Query, KClass, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.count(query, First::class, collectionName) + verify(operations, times(1)).count(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `insert(Collection, KClass) extension should call its Java counterpart`() { + + val collection = listOf(First(), First()) + + operations.insert(collection, First::class) + verify(operations, times(1)).insert(collection, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `insertAll(Mono, KClass) extension should call its Java counterpart`() { + + val collection = Mono.just(listOf(First(), First())) + + operations.insertAll(collection, First::class) + verify(operations, times(1)).insertAll(collection, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.upsert(query, update, First::class) + verify(operations, times(1)).upsert(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.upsert(query, update, First::class, collectionName) + verify(operations, times(1)).upsert(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.upsert(query, update) + verify(operations, times(1)).upsert(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `upsert(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.upsert(query, update, collectionName) + verify(operations, times(1)).upsert(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateFirst(query, update, First::class) + verify(operations, times(1)).updateFirst(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateFirst(query, update, First::class, collectionName) + verify(operations, times(1)).updateFirst(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateFirst(query, update) + verify(operations, times(1)).updateFirst(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateFirst(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateFirst(query, update, collectionName) + verify(operations, times(1)).updateFirst(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, KClass) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateMulti(query, update, First::class) + verify(operations, times(1)).updateMulti(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateMulti(query, update, First::class, collectionName) + verify(operations, times(1)).updateMulti(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + + operations.updateMulti(query, update) + verify(operations, times(1)).updateMulti(query, update, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `updateMulti(Query, Update, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val update = mock() + val collectionName = "foo" + + operations.updateMulti(query, update, collectionName) + verify(operations, times(1)).updateMulti(query, update, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, KClass) extension should call its Java counterpart`() { + + val query = mock() + + operations.remove(query, First::class) + verify(operations, times(1)).remove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, KClass, String) extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.remove(query, First::class, collectionName) + verify(operations, times(1)).remove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `remove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.remove(query) + verify(operations, times(1)).remove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `remove(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.remove(query, collectionName) + verify(operations, times(1)).remove(query, First::class.java, collectionName) + } + + @Test // DATAMONGO-1689 + fun `findAllAndRemove(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.findAllAndRemove(query) + verify(operations, times(1)).findAllAndRemove(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `tail(Query) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + + operations.tail(query) + verify(operations, times(1)).tail(query, First::class.java) + } + + @Test // DATAMONGO-1689 + fun `tail(Query, String) with reified type parameter extension should call its Java counterpart`() { + + val query = mock() + val collectionName = "foo" + + operations.tail(query, collectionName) + verify(operations, times(1)).tail(query, First::class.java, collectionName) + } +}