Does scalamock support mocking curried mehtod that has implicit and repeated parameters? - scalamock

I need to mock following method using scalamock, but I didn't manage to do it. It is curried, has implicit and repeated parameters in the same time.
Does scalamock library support mocking such combination?
def apply(key: String, args: Any*)(implicit lang: Lang): String

How about this?
"complicated paramter lists" should "be mockable" in {
trait Foo {
def apply(key: String, args: Any*)(implicit lang: String): String
}
val m = mock[Foo]
(m.apply(_: String, _: Seq[Any])(_: String)) expects(*, *, *) returning "Foo" once()
implicit val s = "foo"
m.apply("bar", 5, true, 42.0) should be ("Foo")
}

Related

Kotlin Generic problem, UNCHECKED_CAST , required:Nothing

#file:Suppress("UNCHECKED_CAST")
data class Element<T>(
val key: String,
val valueOne: T,
val valueTwo: T,
val comparator: Comparator<T>,
val comparatorValue: CompareResult
)
enum class CompareResult(
val value: Int
) {
LESS(-1),
EQUAL(0),
GREATER_THAN(1)
}
fun <T> matchesComparison(list:Collection<Element<T>>): Pair<Boolean, List<String>> {
val failedComparisons = mutableListOf<String>()
for (element in list) {
val compareValue = element.comparator.compare(element.valueOne, element.valueTwo)
if (element.comparatorValue.value != compareValue) {
failedComparisons.add(element.key)
}
}
return Pair(failedComparisons.isEmpty(), failedComparisons)
}
val stringComparator = Comparator.comparing(String::toString)
val intComparator = Comparator.comparing(Int::toInt)
val elementsToCompare = listOf(
Element("number", 1, 2, intComparator, CompareResult.LESS),
Element("first name", "a", "a", stringComparator, CompareResult.EQUAL),
Element("last name", "a", "b", stringComparator, CompareResult.EQUAL)
)
matchesComparison(elementsToCompare).second.joinToString(", ","Failed elements: \"","\"")
I often get faced with comparing two different object properties with the same values.
As an example object A has props number,firstname,lastname. What i want to do is create a list have and have a function which goes over these Elements and returns which props have failed the comparison. I've managed to use generics for both the object and the matchesComparison function which returns the failed comparisons. The problem begins when i want to pass this list which is of type Collection<Element<out Any>> to this function is i get a type missmatch. instead of using unchecked casts to force the Comparator to be of type Any i would like to do this
val stringComparator = Comparator.comparing(String::toString)
val intComparator = Comparator.comparing(Int::toInt)
The result value that of the script above should be Failed elements: "last name"
I tried changing the signature of the function to out any but then the comparator.compare method has both params as of type Nothing. I really want to avoid unsing unchecked casts.
matchesComparison() doesn't need to be generic in this case. It doesn't really care what is the type of the whole input collection, so we can simply use * here.
Then we have another problem. The compiler isn't smart enough to notice that while we perform operations on a single element, all its properties are of matching types. As a result, it doesn't allow to use element.comparator on element.valueOne and element.valueTwo. To fix this problem, we simply need to create a separate function which works on a single Element, so it understand the type for all properties is the same:
fun matchesComparison(list:Collection<Element<*>>): Pair<Boolean, List<String>> {
fun <T> Element<T>.matches() = comparatorValue.value == comparator.compare(valueOne, valueTwo)
val failedComparisons = mutableListOf<String>()
for (element in list) {
if (!element.matches()) {
failedComparisons.add(element.key)
}
}
return Pair(failedComparisons.isEmpty(), failedComparisons)
}
Also, I believe such matches() function should be actually a member function of Element. It seems strange that while Element is pretty independent and it contains everything that is needed to perform a comparison, it still requires to use external code for this. If it would have a matches() function then we wouldn't need to care about its T. matches() would work with any Element.

Return Type: Calling a function inside Vs outside `println()`

I'm new to Kotlin.
I was experimenting with Anonymous functions a little bit until facing different outputs for the same concept using different approaches.
First: Creating my Anonymous function:
var greetingFunction = { playerName: String , numBuildings: Int ->
val currentYear = 2022
println("Adding $numBuildings houses")
"Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
}
Second: Creating a function that takes another function as a parameter:
private fun runSimulation(playerName: String, greetingFunc: (String, Int) -> String){
val numOfBuildings = (1..3).shuffled().last()
println(greetingFunc(playerName, numOfBuildings))
}
A- Regular call for Anonymous function:
println(runSimulation("Ahmed", greetingFunction))
Output:
Adding 3 houses
Welcome to SimVillage, Ahmed! (Copyright 2022)
B- Shorthand call for Anonymous function:
println(runSimulation("Different") { playerName: String , numBuildings: Int ->
val currentYear = 2022
println("Adding $numBuildings houses")
"Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
})
Output:
Adding 2 houses
Welcome to SimVillage, Different! (Copyright 2022)
kotlin.Unit
I tried to remove the println() and calling the runSimulation function directly and the output was:
Output:
Adding 2 houses
Welcome to SimVillage, Different! (Copyright 2022)
What I really want to know is: how in the first place did I get that "kotlin.Unit" print using the Shorthand Syntax?
Kotlin will automatically infer the type of lambda expressions. Since the last line of greetingFunction is a String
var greetingFunction = { playerName: String , numBuildings: Int ->
val currentYear = 2022
println("Adding $numBuildings houses")
// the last line is a string -> Kotlin will infer that the return type is a String
"Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
}
the inferred type is
var greetingFunction: (String, String) -> String
Return types for block-body functions are not inferred.
If a function does not return a useful value, its return type is Unit. The function
private fun runSimulation(playerName: String, greetingFunc: (String, Int) -> String) {
val numOfBuildings = (1..3).shuffled().last()
println(greetingFunc(playerName, numOfBuildings))
}
will therefore return Unit, so
println(runSimulation("foo") { _, _ -> "bar" })
will print the returned value of runSimulation(), and Unit.toString() is kotlin.Unit
Since runSimulation() will also print to stdout, this is effectively the same as running
println(println("bar"))
First the 'inner' println() will output bar, and then the 'outer' println() will print kotlin.Unit.
bar
kotlin.Unit

Can I specify an object with #SerializedName in its params as a #Field in a url-encoded POST request?

Take the following JSON i want to send to an API:
{
"param1": "1",
"param2": "2",
"param3": {
"param3-1": "3-1",
"param3-2": "3-2"
}
}
And my object for param3 is:
data class param3Object(
#SerializedName("param3-1") param3_1: String,
#SerializedName("param3-2") param3_2: String
)
Is it possible to pass the above object into an API request #Field attribute:
#FormUrlEncoded
#POST("api/something")
fun doSomething(
#Field("param1") param1: String,
#Field("param2") param2: String,
#Field("param3") param3: param3Object
): Call<MyResponse>
so that it represents the JSON at the top of this post? Or do I need to individually pass parameters as #Field? I'm trying to think of ways not to waste time boilerplating.
You should rather use it as REQUEST BODY
#POST("api/something")
fun createUser(#Body data: Data) : Call<MyResponse>
and define model
data class Data(
#SerializedName("param1") val param1: String,
#SerializedName("param2") val param2: String,
#SerializedName("param3") val param3: SubData
)
data class SubData(
#SerializedName("param3-1") val param3_1: String,
#SerializedName("param3-2") val param3_2: String
)
EDIT
If you really want send this as formUrlEncoded, then probably simple solution is to change parameter3 to string, and serialize data before put it to method, or even better change everything to single parameter and serialize whole object

How to get String description/value?

In Kotlin, how to get the raw value of the String?
For example,
val value: String = "Adrian"
Expected result:
"Cannot find value: Adrian"
I am coming from Swift and I know in swift it works like this
let value: String = "Adrian"
print("Cannot find \(string.description): \(value)")
Another example in Swift,
let a: String = "b"
print("\(a.description) = \(a)"
///prints "a = b"
Im guessing a String extension is needed given I read the Kotlin String documentation and seems none of the choices provides the expected result.
A simple problem but I really can't solve it:(
This might help you. For this you have to use Kotlin reflection:
Example:
data class Person(val name:String)
fun main(){
val person = Person("Birju")
val prop = person::name
println("Property Name: ${prop.name}")
println("Property Value: ${prop.get()}")
}
How about
println("value :$value")
You don't need concatination operator(+) to concat strings in kotlin

Python vars() in Kotlin

This python code
class Test:
def __init__(self):
self.one = "python"
self.two = "is"
self.three = "fun!"
t=Test()
print(vars(t))
prints a collection of fields and their values:
{'one': 'python', 'two': 'is', 'three': 'fun!'}
How can I do the same in Kotlin?
If you are using the Koltin data class you can just print the class
class Test(val one: String, val two: String, val three: String)
fun main(args: Array<String>) {
val test = Test("Kotlin", "is", "fun")
println(test)
}
which will produce: Test(one=Kotlin, two=is, three=fun)
Kotlin data classes also provide a componentN() function. Look here for some informations about data classes in Kotlin
For regular classes you can try the approach of this answer