KtLint configuration - kotlin

We have started using KtLint to clean up out Kotlen code however we would like to customize some of the default standards.
One common convention we have is to format long declarations like this:
Class NameOfTheClass(var parameterOne: Int,
var parameterTwo: Int,
var parameterThree: Int) : DerivedFromClass {
.
.
.
}
Whereas KtLink enforces the style as:
Class NameOfTheClass(
var parameterOne: Int,
var parameterTwo: Int,
var parameterThree: Int
) : DerivedFromClass {
.
.
.
}
While I acknowledge that both styles are perfectly valid our preference is for the first style (which we have traditionally used) and my question is how to customize KtLint to accept such formatting.
While I have searched for ways to customize KtLint's rules I found the documentation to be lacking. Can anyone point me to a resource that explains such things?

Related

Extracting Nested POJO Object with Rest-Assured

I'm writing some tests using rest-assured and its Kotlin extensions to test some simple Spring MVC endpoints. I'm trying to understand how to extract values.
One endpoint returns a BookDetailsView POJO, the other returns a Page<BookDetailsView> (where Page is an interface provided by Spring for doing paging).
BookDetailsView is a really simple Kotlin data class with a single field:
data class BookDetailsView(val id: UUID)
For the single object endpoint, I have:
#Test
fun `single object`() {
val details = BookDetailsView(UUID.randomUUID())
whenever(bookDetailsService.getBookDetails(details.id)).thenReturn(details)
val result: BookDetailsView = Given {
mockMvc(mockMvc)
} When {
get("/book_details/${details.id}")
} Then {
statusCode(HttpStatus.SC_OK)
} Extract {
`as`(BookDetailsView::class.java)
}
assertEquals(details.id, result.id)
}
This works as expected, but trying to apply the same technique for the Page<BookDetailsView> runs afoul of all sorts of parsing challenges since Page is an interface, and even trying to use PageImpl isn't entirely straightforward. In the end, I don't even really care about the Page object, I just care about the nested list of POJOs inside it.
I've tried various permutations like the code below to just grab the bit I care about:
#Test
fun `extract nested`() {
val page = PageImpl(listOf(
BookDetailsView(UUID.randomUUID())
))
whenever(bookDetailsService.getBookDetailsPaged(any())).thenReturn(page)
val response = Given {
mockMvc(mockMvc)
} When {
get("/book_details")
} Then {
statusCode(HttpStatus.SC_OK)
body("content.size()", `is`(1))
body("content[0].id", equalTo(page.first().id.toString()))
} Extract {
path<List<BookDetailsView>>("content")
}
println(response[0].javaClass)
}
The final println spits out class java.util.LinkedHashMap. If instead I try to actually use the object, I get class java.util.LinkedHashMap cannot be cast to class BookDetailsView. There are lots of questions and answers related to this, and I understand it's ultimately an issue of the underlying JSON parser not knowing what to do, but I'm not clear on:
Why does the "simple" case parse without issue?
Shouldn't the type param passed to the path() function tell it what type to use?
What needs configuring to make the second case work, OR
Is there some other approach for grabbing a nested object that would make more sense?
Digging a bit into the code, it appears that the two cases may actually be using different json parsers/configurations (the former seems to stick to rest-assured JSON parsing, while the latter ends up in JsonPath's?)
I don't know kotlin but here is the thing:
path() doesn't know the Element in your List, so it'll be LinkedHashMap by default instead of BookDetailsView.class
to overcome it, you can provide TypeReference for this.
java example
List<BookDetailsView> response = ....then()
.extract().jsonPath()
.getObject("content", new TypeRef<List<BookDetailsView>>() {});
kotlin example
#Test
fun `extract nested`() {
var response = RestAssured.given().get("http://localhost:8000/req1")
.then()
.extract()
.jsonPath()
.getObject("content", object : TypeRef<List<BookDetailsView?>?>() {});
println(response)
//[{id=1}, {id=2}]
}

Micronaut declarative client with base url per environment

I'd like to be able to use Micronaut's declarative client to hit an a different endpoint based on whether I'm in a local development environment vs a production environment.
I'm setting my client's base uri in application.dev.yml:
myserviceclient:
baseUri: http://localhost:1080/endpoint
Reading the docs from Micronaut, they have the developer jumping through quite a few hoops to get a dynamic value piped into the actual client. They're actually quite confusing. So I've created a configuration like this:
#ConfigurationProperties(PREFIX)
class MyServiceClientConfig {
companion object {
const val PREFIX = "myserviceclient"
const val BASE_URL = "http://localhost:1080/endpoint"
}
var baseUri: String? = null
fun toMap(): MutableMap<String, Any> {
val m = HashMap<String, Any>()
if (baseUri != null) {
m["baseUri"] = baseUri!!
}
return m
}
}
But as you can see, that's not actually reading any values from application.yml, it's simply setting a const value as a static on the class. I'd like that BASE_URL value to be dynamic based on which environment I'm in.
To use this class, I've created a declarative client like this:
#Client(MyServiceClientConfig.BASE_URL)
interface MyServiceClient {
#Post("/user/kfc")
#Produces("application/json")
fun sendUserKfc(transactionDto: TransactionDto)
}
The docs show an example where they're interpolating values from the config map that's built like this:
#Get("/api/\${bintray.apiversion}/repos/\${bintray.organization}/\${bintray.repository}/packages")
But how would I make this work in the #Client() annotation?
Nowhere in that example do they show how bintray is getting defined/injected/etc. This appears to be the same syntax that's used with the #Value() annotation. I've tried using that as well, but every value I try to use ends up being null.
This is very frustrating, but I'm sure I'm missing a key piece that will make this all work.
I'm setting my client's base uri in application.dev.yml
You probably want application-dev.yml.
But how would I make this work in the #Client() annotation?
You can put a config key in the #Client value using something like #Client("${myserviceclient.baseUri}").
If you want the url somewhere in your code use this:
#Value("${micronaut.http.services.occupancy.urls}")
private String occupancyUrl;

Kotlin Builder vs Constructor

I'm pretty new to Kotlin, and I've come across both of these representations:
Car(name = "CarName")
and
car {
name = "CarName"
}
Is there any guidelines about when which one should be used? The docs don't seem to be too clear on this.
The second snippet is an example of how you could build a DSL for your domain. For simple cases like this, it is a bit overkill to create a DSL, but when your objects get larger it might be cleaner to design a DSL.
In fact, using the DSL style to create simple instances might even be confusing.
For example, the documentation on DSLs shows the following code:
fun result(args: Array<String>) =
html {
head {
title {+"XML encoding with Kotlin"}
}
body {
h1 {+"XML encoding with Kotlin"}
p {+"this format can be used as an alternative markup to XML"}
// an element with attributes and text content
a(href = "http://kotlinlang.org") {+"Kotlin"}
// mixed content
p {
+"This is some"
b {+"mixed"}
+"text. For more see the"
a(href = "http://kotlinlang.org") {+"Kotlin"}
+"project"
}
p {+"some text"}
// content generated by
p {
for (arg in args)
+arg
}
}
}
This is an excellent example of when you could use a DSL: The syntax enables a clean structure of how you create your models. Anko for another provides a DSL to defines UI's.

Accessing Resources IDs using Kotlin & Anko

I am new to Android/Kotlin/Anko and I have a question regarding the way to access color (and probably other) resources from within Anko.
I know that there are helpers like textResource where you simply pass the R.string.my_color to simplify the process of setting resource strings but how about accessing colors using the Resources instance from the View class ?
Let’s say you have a subclass of Button and want to change the text color. If you use the textResource it will change the text string not the color, and if you use textColor then you must specify the real resource ID by using resources.getColor(R.color.my_color, null) which wouldn't be so annoying if you didn't have to pass the optional theme parameter (null here)
Is creating an extension on Resources useful here ?
fun Int.fromResources(resources: Resources): Int {
return resources.getColor(this, null)
}
What is the recommended way ?
EDIT
I changed the textColor value extension to do just that, which I found the cleanest thing to do except I have no idea if this is really Android friendly
var android.widget.TextView.textColor: Int
get() = throw AnkoException("'android.widget.TextView.textColor' property does not have a getter")
set(v) = setTextColor(resources.getColor(v, null))
I think you can use a property extension like this one instead of the one you suggested:
var TextView.textColorRes: Int
get() = throw PropertyWithoutGetterException("textColorRes")
set(#ColorRes v) = setTextColor(resources.getColor(v, null))
Or use ContextCompat as suggested by Damian Petla:
var TextView.textColorRes: Int
get() = throw PropertyWithoutGetterException("textColorRes")
set(#ColorRes v) = setTextColor(ContextCompat.getColor(context, v))
You should keep Anko's textColor:
Allows you to set a color directly without taking it from XML, if needed at some point
Prevents you from importing the wrong textColor (Anko's one or yours), same property names with different behaviour is not a good idea.

Like swagger/swashbuckle but for node.js?

Is there any tool for node express where you can automatically generate swagger documentation for an existing project? Similar to swashbuckle?
I've been looking into this as well, the project which will help you is swagger-node-express. swagger-ui, should come as a dependency of swagger-node-express. Swagger-node-express wraps express and exposes it as a new interface meaning there will be code changes you to make it work. This is what a route would look like (taken from their docs)
var findById = {
'spec': {
"description" : "Operations about pets",
"path" : "/pet.{format}/{petId}",
"notes" : "Returns a pet based on ID",
"summary" : "Find pet by ID",
"method": "GET",
"parameters" : [swagger.pathParam("petId", "ID of pet that needs to be fetched", "string")],
"type" : "Pet",
"errorResponses" : [swagger.errors.invalid('id'), swagger.errors.notFound('pet')],
"nickname" : "getPetById"
},
'action': function (req,res) {
if (!req.params.petId) {
throw swagger.errors.invalid('id');
}
var id = parseInt(req.params.petId);
var pet = petData.getPetById(id);
if (pet) {
res.send(JSON.stringify(pet));
} else {
throw swagger.errors.notFound('pet');
}
}
};
Where the type "Pet" is still for you to define, I wont rewrite their docs here.
This will then produce a file which swagger-ui can use to give you a self contained self documenting system. The documentation for swagger-node-express is more than good enough to get it setup (dont forget to set swagger path, I did).
swagger.configureSwaggerPaths("", "/docs", "");
Having shown you the tools that in theory offer what your asking for, let me explain why I've come to conclusion that I'm not going to use them.
A lot of code change needed - is it really less work than creating
your own swagger.yml file? I dont think so.
Hand creating a swagger.yml file is much less likely to brake your project.
Whilst swagger-node-express hasnt been depricated it's github repo doesnt exist anymore, its been wrapped into swagger-node, but that project doesnt really mention it
I'd be wary of any tool that means I need to wrap express - it's not something I'd look to do.
TL;DR:
It's possible with a lot of code change - probably not what your after though.