In a previous blog we learned about setting default JVM options when we run Maven commands. We can also set default Maven options that we want to apply each time we run a Maven command. All options can be defined in the file maven.config
in a .mvn
directory in the root of our project. Each option must be defined on a new line. This directory and file can be added to our source control so that all users that have access to the repository will use the same Maven options.
Continue reading →
If we write specification where we need to use files and directories we can use the @TempDir
annotation on a File
or Path
instance variable. By using this annotation we make sure the file is created in the directory defined by the Java system property java.io.tmpdir
. We could overwrite the temporary root directory using Spock configuration if we want, but the default should be okay for most situations. The @TempDir
annotation can actually be used on any class that has a constructor with a File
or Path
argument. Since Spock 2.2 we can use the FileSystemFixture
class provided by Spock. With this class we have a nice DSL to create directory structures and files in a simple matter. We can use the Groovy extensions to File
and Path
to also immediately create contents for the files. If we want to use the extensions to Path
we must make sure we include org.apache.groovy:groovy-nio
as dependency to our test runtime classpath. The FileSystemFixture
class also has the method copyFromClasspath
that we can use to copy files and their content directory into our newly created directory structure.
Continue reading →
In order to add default JVM options to our Maven mvn
command we can define an environment variable MAVEN_OPTS
. But we can also create a file jvm.config
in the directory .mvn
in our project root directory. On each line we define a Java option we want to apply. We can specify JVM options, but also Java system properties we want to apply each time we run the mvn
command. This directory and file can be added to our source control so that all users that have access to the repository will use the same JVM options.
Continue reading →
A version catalog in Gradle is a central place in our project where we can define dependency references with their version or version rules. We can define a version catalog using an API in our build file, but we can also create an external file where we define our dependencies and version. In our dependencies
section we can refer to the names in the version catalog using a type-safe accessor (if we use Kotlin for writing our build script) with code completion in a supported IDE (IntelliJ IDEA). If we want to share a version catalog between projects we can publish a version catalog to a Maven repository with a groupId
, artifactId
and version
.
Continue reading →
Since Spock 2.1 we have 2 new operators we can use for assertions to check collections: =~
and ==~
. We can use these operators with implementations of the Iterable
interface when we want to check that a given collection has the same elements as an expected collection and we don’t care about the order of the elements. Without the new operators we would have to cast our collections to a Set
first and than use the ==
operator.
Continue reading →
The chunked
extension method is added to the Iterable
Java class and makes it possible to split an interable into fixed sized lists. We define the size of the lists as argument to the chunked
method. The return result is a list of lists. Each of the lists will have the number of elements we have specified as argument. The last list can have less elements if the total number of elements cannot be divided exactly by the size we specified as argument. We can specify a lambda transformation function as second argument. The lambda function has the new sublist as argument and we can write code to transform that sublist.
Continue reading →
The method partition
is available in Kotlin for arrays and iterable objects to split it into two lists. We pass a predicate lambda function to the partition
method. The predicate should return either true
or false
based on a condition for each element from the array or iterable. The return result is a Pair
instance where the first element is a List
object with all elements that returned true
from the predicate. The second element in the Pair
object contains all elements for which the predicate returned false
. As a String
can be seen as an iterable of characters we can also use partition
on a String
instance.
Continue reading →
Kotlin adds a lot of extension methods to the String
class. For example we can use the take
method to get a certain number of characters from the start of a string value. With the drop
method where we remove a given number of characters from the start of the string to get a new string. We can also take and drop a certain number of characters from the end of a string using the methods takeLast
and dropLast
.
Instead of using the number of characters we want to take or drop we can also use a condition defined with a predicate lambda function. We take or drop characters as long as the lambda returns true
. The names of the methods for taking characters are takeWhile
and takeLastWhile
and for dropping characters dropWhile
and dropLastWhile
.
Continue reading →
If we want to find the longest shared prefix or suffix for two string values we can use the String
extension methods commonPrefixWith
and commonSuffixWith
. The result is the prefix or suffix value that is common for both values. We can pass a second argument to the method to indicate if we want to ignore the casing of the letters. The default value for this argument is false
, so if we don’t set it explicitly the casing of the letters should also match.
Continue reading →
Kotlin gives us the associate
method for collection objects, like lists, iterables and arrays. With this method we can convert the items in the collection to a new Map
instance. The associate
method accepts a lambda function as argument and we must return a Pair
from the lambda. The first item of the pair will be the key and the second element is the value of the key/value pair in the resulting map.
If we want to use the elements in our collection as key, but want to transform the value we must use associateWith
. The lambda for this method must return the value part of our key/value pair. Alternatively if we only want to transform the key value we can use associateBy
with one lambda function. The lambda function must return the result for the key in the key/value pair of the map. The method associateBy
is overloaded where we can pass two lambda functions. The first lambda function is for transforming the key and the second lambda function is for transforming the value.
Continue reading →
Kotlin extends the String
class with a couple of padding methods. These methods allows us to define a fixed width a string value must occupy. If the string itself is less than the fixed width then the space is padded with spaces or any other character we define. We can pad to the left or the right of the string using the padStart
and padEnd
methods. When we don’t define an argument a space character is used for padding, but we can also add our own custom character as argument that will be used as padding character.
Continue reading →
Multiline strings are very useful. But sometimes we want use the multiline string without the leading spaces that are added because of code formatting. To remove leading spaces we can use the trimIndent
method. This method will find the least amount of leading spaces and removes that amount of spaces from each line. Also a first and last empty line are removed.
If we want a bit more control we can also add a character to the start of each line to show where the line starts. And then we use the method trimMargin
and all spaces before that character are removed. The default character is the pipe symbol, |
, but we can also define our own and pass it as argument to the trimMargin
method.
Continue reading →