diff --git a/mockk/common/src/main/kotlin/io/mockk/impl/recording/ChainedCallDetector.kt b/mockk/common/src/main/kotlin/io/mockk/impl/recording/ChainedCallDetector.kt index 04028886c..ec2aa4295 100644 --- a/mockk/common/src/main/kotlin/io/mockk/impl/recording/ChainedCallDetector.kt +++ b/mockk/common/src/main/kotlin/io/mockk/impl/recording/ChainedCallDetector.kt @@ -19,7 +19,7 @@ class ChainedCallDetector(safeToString: SafeToString) { fun detect( callRounds: List, callN: Int, - matchersList: SignatureMatchersList + matchersMap: SignatureMatchersMap ) { val callInAllRounds = callRounds.map { it.calls[callN] } val zeroCall = callInAllRounds[0] @@ -51,7 +51,7 @@ class ChainedCallDetector(safeToString: SafeToString) { log.trace { "Signature for $nArgument argument of ${zeroCall.method.toStr()}: $signature" } - val matcherBySignature = matchersList.remove(signature) + val matcherBySignature = matchersMap.remove(signature) return buildMatcher( nArgument == 0, @@ -84,7 +84,7 @@ class ChainedCallDetector(safeToString: SafeToString) { log.trace { "Signature for $nArgument/$nVarArg argument of ${zeroCall.method.toStr()}: $signature" } - val matcherBySignature = matchersList.remove(signature) + val matcherBySignature = matchersMap.remove(signature) varArgMatchers.add( buildMatcher( nArgument == 0 && nVarArg == 0, diff --git a/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatcherDetector.kt b/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatcherDetector.kt index c7f020733..9ac67158e 100644 --- a/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatcherDetector.kt +++ b/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatcherDetector.kt @@ -45,7 +45,7 @@ class SignatureMatcherDetector( } } - val matchersList = SignatureMatchersList() + val matchersMap = SignatureMatchersMap() val allCompositeMatchers = mutableListOf>>() fun gatherMatchers() { @@ -59,10 +59,10 @@ class SignatureMatcherDetector( }) } - matchersList.add(signature, matcher) + matchersMap.add(signature, matcher) } - log.trace { "Matcher list: $matchersList" } + log.trace { "Matcher list: $matchersMap" } } @Suppress("UNCHECKED_CAST") @@ -77,7 +77,7 @@ class SignatureMatcherDetector( log.trace { "Signature for $nOp operand of $matcher composite matcher: $signature" } - matchersList.remove(signature) + matchersMap.remove(signature) ?: ChainedCallDetector.eqOrNullMatcher(matcher.operandValues[nOp]) } as List>? } @@ -90,13 +90,13 @@ class SignatureMatcherDetector( repeat(nCalls) { callN -> val detector = chainedCallDetectorFactory() - detector.detect(callRounds, callN, matchersList) + detector.detect(callRounds, callN, matchersMap) calls.add(detector.call) } processCompositeMatchers() - if (matchersList.isNotEmpty()) { - throw MockKException("Failed matching mocking signature for\n${callRounds[0].calls.joinToString("\n")}\nleft matchers: $matchersList") + if (matchersMap.isNotEmpty()) { + throw MockKException("Failed matching mocking signature for\n${callRounds[0].calls.joinToString("\n")}\nleft matchers: $matchersMap") } } } diff --git a/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersList.kt b/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersList.kt deleted file mode 100644 index 0763ee83b..000000000 --- a/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersList.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.mockk.impl.recording - -import io.mockk.Matcher - -class SignatureMatchersList { - private var matchers = mutableListOf() - - fun add(signature: List, matcher: Matcher<*>) { - matchers.add(SignatureWithMatcher(signature, matcher)) - } - - fun remove(signature: List): Matcher<*>? { - val index = matchers.indexOfFirst { it.signature == signature } - return if (index > -1) matchers.removeAt(index).matcher else null - } - - fun isNotEmpty() = matchers.isNotEmpty() - - override fun toString(): String { - return matchers.map { it.matcher }.toString() - } - - private data class SignatureWithMatcher(val signature: List, val matcher: Matcher<*>) -} \ No newline at end of file diff --git a/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersMap.kt b/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersMap.kt new file mode 100644 index 000000000..b1c0e78b5 --- /dev/null +++ b/mockk/common/src/main/kotlin/io/mockk/impl/recording/SignatureMatchersMap.kt @@ -0,0 +1,31 @@ +package io.mockk.impl.recording + +import io.mockk.Matcher + +class SignatureMatchersMap { + private var matchers = mutableMapOf, List>>() + + fun add(signature: List, matcher: Matcher<*>) { + val signatureMatchers = matchers[signature] ?: emptyList() + matchers[signature] = signatureMatchers.plus(matcher) + } + + fun remove(signature: List): Matcher<*>? { + val signatureMatchers = (matchers[signature] ?: emptyList()).toMutableList() + val removedMatcher = if (signatureMatchers.size > 0) signatureMatchers.removeAt(0) else null + + if (signatureMatchers.isEmpty()) { + matchers.remove(signature) } + else { + matchers[signature] = signatureMatchers.toList() + } + + return removedMatcher + } + + fun isNotEmpty() = matchers.isNotEmpty() + + override fun toString(): String { + return matchers.flatMap { it.value }.toString() + } +} \ No newline at end of file diff --git a/mockk/common/src/test/kotlin/io/mockk/impl/recording/ChainedCallDetectorTest.kt b/mockk/common/src/test/kotlin/io/mockk/impl/recording/ChainedCallDetectorTest.kt index 44601d89c..9b4aac16f 100644 --- a/mockk/common/src/test/kotlin/io/mockk/impl/recording/ChainedCallDetectorTest.kt +++ b/mockk/common/src/test/kotlin/io/mockk/impl/recording/ChainedCallDetectorTest.kt @@ -30,16 +30,16 @@ class ChainedCallDetectorTest { every { call1.method.varArgsArg } returns -1 every { call2.method.varArgsArg } returns -1 - detector.detect(listOf(callRound1, callRound2), 0, SignatureMatchersList()) + detector.detect(listOf(callRound1, callRound2), 0, SignatureMatchersMap()) assertEquals("abc", detector.call.matcher.method.name) } @Test fun givenTwoCallsRoundsWithOneCallOneArgWhenDetectCallsHappenThenOneCallWithArgIsReturned() { - val matchersList = SignatureMatchersList() + val matchersMap = SignatureMatchersMap() - matchersList.add(listOf(signedMatcher1.signature, signedMatcher2.signature), signedMatcher1.matcher) + matchersMap.add(listOf(signedMatcher1.signature, signedMatcher2.signature), signedMatcher1.matcher) every { callRound1.calls } returns listOf(call1) every { callRound2.calls } returns listOf(call2) @@ -56,7 +56,7 @@ class ChainedCallDetectorTest { every { call1.method.varArgsArg } returns -1 every { call2.method.varArgsArg } returns -1 - detector.detect(listOf(callRound1, callRound2), 0, matchersList) + detector.detect(listOf(callRound1, callRound2), 0, matchersMap) assertEquals("abc", detector.call.matcher.method.name) assertEquals(listOf>(EqMatcher(5)), detector.call.matcher.args) diff --git a/mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersListTest.kt b/mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersMapTest.kt similarity index 87% rename from mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersListTest.kt rename to mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersMapTest.kt index fb1f4cf06..e6637ffbe 100644 --- a/mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersListTest.kt +++ b/mockk/common/src/test/kotlin/io/mockk/impl/recording/SignatureMatchersMapTest.kt @@ -8,12 +8,12 @@ import kotlin.test.assertFalse import kotlin.test.assertNull import kotlin.test.assertTrue -class SignatureMatchersListTest { +class SignatureMatchersMapTest { @Test fun shouldAddMatcherForSignature() { // given - val map = SignatureMatchersList() + val map = SignatureMatchersMap() val signedMatcher = mockk(relaxed = true) val signature = listOf(signedMatcher.signature) val matcher = signedMatcher.matcher @@ -29,7 +29,7 @@ class SignatureMatchersListTest { @Test fun shouldNotContainAnyMatchers() { // given - val map = SignatureMatchersList() + val map = SignatureMatchersMap() // when && then assertFalse { map.isNotEmpty() } @@ -38,7 +38,7 @@ class SignatureMatchersListTest { @Test fun shouldNotRemoveFromEmptyList() { // given - val map = SignatureMatchersList() + val map = SignatureMatchersMap() val signedMatcher = mockk(relaxed = true) val signature = listOf(signedMatcher.signature) @@ -53,7 +53,7 @@ class SignatureMatchersListTest { @Test fun shouldRemoveFromList() { // given - val map = SignatureMatchersList() + val map = SignatureMatchersMap() val signedMatcher1 = mockk(relaxed = true) val signedMatcher2 = mockk(relaxed = true) val signature1 = listOf(signedMatcher1.signature) @@ -76,7 +76,7 @@ class SignatureMatchersListTest { @Test fun shouldPrintListCorrectly() { // given - val list = SignatureMatchersList() + val list = SignatureMatchersMap() val signedMatcher = mockk(relaxed = true) val signature = listOf(signedMatcher.signature) val matcher = AllAnyMatcher() @@ -89,6 +89,6 @@ class SignatureMatchersListTest { val matchersAsString = list.toString() // then - assertEquals(matchersAsString, expectedMatchersListAsString) + assertEquals(expectedMatchersListAsString, matchersAsString) } } \ No newline at end of file