Skip to content

Commit

Permalink
Merge pull request #30 from nhaarman/release-0.3.1
Browse files Browse the repository at this point in the history
Release 0.3.1
  • Loading branch information
nhaarman committed Mar 27, 2016
2 parents 48fc1aa + df0c3f6 commit 55e9a3c
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 14 deletions.
11 changes: 0 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,3 @@ install:

script:
- ./gradlew test

before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties.lock
- rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties
cache:
directories:
- $HOME/.gradle/caches
- $HOME/.gradle/daemon
- $HOME/.gradle/native
- $HOME/.gradle/wrapper
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package com.nhaarman.mockito_kotlin

import org.mockito.Answers
import org.mockito.internal.creation.MockSettingsImpl
import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor
import org.mockito.internal.util.MockUtil
import java.lang.reflect.Modifier
import java.lang.reflect.ParameterizedType
Expand All @@ -37,6 +38,7 @@ import kotlin.reflect.KType
import kotlin.reflect.defaultType
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaType
import kotlin.reflect.jvm.jvmName

/**
* A collection of functions that tries to create an instance of
Expand All @@ -54,16 +56,38 @@ fun <T : Any> createInstance(kClass: KClass<T>): T {
kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue()
kClass.isEnum() -> kClass.java.enumConstants.first()
kClass.isArray() -> kClass.toArrayInstance()
else -> kClass.constructors.sortedBy { it.parameters.size }.first().newInstance()
kClass.isClassObject() -> kClass.toClassObject()
else -> kClass.easiestConstructor().newInstance()
}
}

/**
* Tries to find the easiest constructor which it can instantiate.
*/
private fun <T : Any> KClass<T>.easiestConstructor(): KFunction<T> {
return constructors.firstOrDefault(
{
it.parameters.filter {
it.type.toString().toLowerCase().contains("array")
}.isEmpty()
},
{
constructors.sortedBy { it.parameters.size }.first()
}
)
}

private fun <T> Collection<T>.firstOrDefault(predicate: (T) -> Boolean, default: () -> T): T {
return firstOrNull(predicate) ?: default()
}

@Suppress("SENSELESS_COMPARISON")
private fun KClass<*>.hasObjectInstance() = objectInstance != null

private fun KClass<*>.isMockable() = !Modifier.isFinal(java.modifiers)
private fun KClass<*>.isEnum() = java.isEnum
private fun KClass<*>.isArray() = java.isArray
private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class")
private fun KClass<*>.isPrimitive() =
java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf(
"Boolean",
Expand Down Expand Up @@ -104,6 +128,11 @@ private fun <T : Any> KClass<T>.toArrayInstance(): T {
} as T
}

@Suppress("UNCHECKED_CAST")
private fun <T : Any> KClass<T>.toClassObject(): T {
return Class.forName("java.lang.Object") as T
}

private fun <T : Any> KFunction<T>.newInstance(): T {
isAccessible = true
return callBy(parameters.associate {
Expand Down Expand Up @@ -132,5 +161,7 @@ private fun <T : Any> KType.createNullableInstance(): T? {
private fun <T> Class<T>.uncheckedMock(): T {
val impl = MockSettingsImpl<T>().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<T>
val creationSettings = impl.confirm(this)
return MockUtil().createMock(creationSettings)
return MockUtil().createMock(creationSettings).apply {
(this as MockMethodInterceptor.MockAccess).mockitoInterceptor = null
}
}
5 changes: 4 additions & 1 deletion mockito-kotlin/src/test/kotlin/Classes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ interface Methods {
fun closedSet(s: Set<Closed>)
fun string(s: String)
fun closedVararg(vararg c: Closed)
fun throwableClass(t: ThrowableClass)

fun stringResult(): String
}
}

class ThrowableClass(cause: Throwable) : Throwable(cause)
35 changes: 35 additions & 0 deletions mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.nhaarman.expect.expect
import com.nhaarman.mockito_kotlin.createInstance
import org.junit.Test
import java.util.*
import kotlin.reflect.KClass

class CreateInstanceTest {

Expand Down Expand Up @@ -368,6 +370,39 @@ class CreateInstanceTest {
expect(result).toNotBeNull()
}

@Test
fun classObject() {
/* When */
val result = createInstance<Class<String>>()

/* Then */
expect(result).toNotBeNull()
}

@Test
fun kClassObject() {
/* When */
val result = createInstance<KClass<String>>()

/* Then */
expect(result).toNotBeNull()
}

@Test
fun uuid() {
/**
* The UUID class has a single-argument constructor that expects an array with some specific contents.
* We avoid these types of constructors by calling another constructor, if available.
* In this case, UUID(Long, Long).
*/

/* When */
val result = createInstance<UUID>()

/* Then */
expect(result).toBeEqualTo(UUID(0, 0))
}

private class PrivateClass private constructor(val data: String)

class ClosedClass
Expand Down
9 changes: 9 additions & 0 deletions mockito-kotlin/src/test/kotlin/MockitoTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import com.nhaarman.expect.expectErrorWithMessage
import com.nhaarman.mockito_kotlin.*
import org.junit.Test
import org.mockito.exceptions.base.MockitoAssertionError
import java.io.IOException

/*
* The MIT License
Expand Down Expand Up @@ -107,6 +108,14 @@ class MockitoTest {
}
}

@Test
fun anyThrowableWithSingleThrowableConstructor() {
mock<Methods>().apply {
throwableClass(ThrowableClass(IOException()))
verify(this).throwableClass(any())
}
}

@Test
fun listArgThat() {
mock<Methods>().apply {
Expand Down

0 comments on commit 55e9a3c

Please sign in to comment.