středa 21. září 2022

Download Maven artifact with version range

Download Maven artifact with version range

Download Maven artifact with version range

The task is simple - download maven artifact using version range - e.g. [2, 3)
This can be useful for example in CI jobs.

Suprisingly I don’t have trivial solution.

One possible solution

Is described in my repository:
https://github.com/bugs84/download-maven-dependency-with-version-range

You have to create dummy file. pom.xml (which is in repository)
and then run command. e.g.

mvn dependency:copy-dependencies -DoutputDirectory=./downloaded-dependencies -Ddep.group="org.apache.logging.log4j" -Ddep.artifact="log4j-api" -Ddep.version="[2.17.1,)"

pondělí 1. listopadu 2021

Git How to add Branch name into commit message

Git - add Branch name into commit message.

Git - How to add Branch name into commit message.

Why

Because search something in git history can be very frustrating, because git branches are just “floating labels, which will simply move elsewhere or dissapear”.

How

Using git hook

Into file .git\hooks\prepare-commit-msg add this:

#!/bin/sh  
#  
# Automatically adds branch name and branch description to every commit message.  
#  
NAME=$(git branch | grep '*' | sed 's/* //')  
DESCRIPTION=$(git config branch."$NAME".description)  
TEXT=$(cat "$1" | sed '/^#.*/d')  
  
if [ -n "$TEXT" ]  
then  
  printf "$(cat "$1" | sed '/^#.*/d')\nBranch: $NAME" > "$1"  
  if [ -n "$DESCRIPTION" ]  
    then  
  echo "" >> "$1"  
  echo $DESCRIPTION >> "$1"  
  fi  
else  
  echo "Aborting commit due to empty commit message."  
  exit 1  
fi

And that’s it. Your commits will contain a branch name.

Sharing git hooks with others

Sharing git hooks inside a project is not supported by git. There are a few workarounds, but none of them is perfect.

e.g.

  • add directory <your repo>/.githooks/ create file prepare-commit-msg there and commit it.
  • set property git config --local core.hooksPath=.githooks
  • somehow ensure, that everyone will execute git config --local core.hooksPath=.githooks on every clone of your repo :(

https://stackoverflow.com/questions/5894946/how-to-add-gits-branch-name-to-the-commit-message

https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/

sobota 1. února 2020

I invented Agile Testing

I invented Agile Testing.md

I invented Agile Testing

For a couple of last years, I saw issues in our processes and in the way we work. I managed to do some changes and change how people think about testing.

And do you know what I now found?

It is always the same. You invent something new and then you found, that somebody else already did the same thing. In my case, these principles have already its own (buzz)word called “Agile Testing”
https://reqtest.com/testing-blog/agile-testing-principles-methods-advantages/

These principles are very very similar to the thinks I discovered myself and I believe, that works best in most situations.

Maybe that the best name of the article should be “My way to Agile Testing”.

neděle 5. ledna 2020

Kotlin Extendable Tests

Kotlin Extendable Tests

Kotlin Extendable Tests

Imagine, that you have a lot of System/Functional tests. And a lot of these test have some common code. E.g. One code clean your system data. Another starts your testing HttpServer. etc.

This code often end up in some class, lets call it “TestBase”, and all tests inherit from this TestBase. As time goes on this class is bigger and bigger. And a lot of tests, which doesn’t need clean system data are doing so, because this code is part of TestBase.

Solution is split this TestBase somehow. But Splitting it can be quite tricky.

In Groovy(link) this can be easyli done by using Traits (link). And each functionality became own Trait and only tests which need this functionality will implement this trait.

In Kotlin we do not have traits, but it is possilbe to use Interfaces and Delegation to easily implement something with similar capabilities.

Example

You can easily write tests, which use your extensions.

import ... Extendable
import ... ExtendableImpl
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import java.net.HttpURLConnection
import java.net.URL

class ExtensionSampleTest : Extendable by ExtendableImpl() {
    // Here is used our extenssion, which start and stop http server
    val server = register(HttpServerExtension())

    @Test
    fun `test using extension`() {
        // given
        val con = URL("http://localhost:${server.port}/test").openConnection() as HttpURLConnection
        con.setRequestMethod("GET")

        // when
        val response = String(con.inputStream.readAllBytes())

        // then
        assertThat(response).isEqualTo("This is the response")
    }

}

Extension which starts http server. Can look like this:

import com.sun.net.httpserver.HttpServer
import ... Extension
import java.net.InetSocketAddress


class HttpServerExtension(val port: Int = 8000) : Extension {

    lateinit var server: HttpServer

    override fun extBeforeEach() {
        start()
    }

    override fun extAfterEach() {
        stop()
    }

    private fun start() {
        server = HttpServer.create(InetSocketAddress(port), 0).apply {
            createContext("/test") { t ->
                val response = "This is the response"
                t.sendResponseHeaders(200, response.length.toLong())
                t.responseBody.apply {
                    write(response.toByteArray())
                    close()
                }
            }
            start()
        }
    }

    private fun stop() {
        server.stop(1)
    }
    
}

Implementation of extessions for jUnit5

  
import org.junit.jupiter.api.*  
import org.junit.jupiter.api.TestInstance.Lifecycle  
  
/**  
 * Be Aware! Implementing this Interface make the test @TestInstance(Lifecycle.PER_CLASS)
 * It means one test instance is used to run all tests!
 */
@TestInstance(Lifecycle.PER_CLASS)  
interface Extendable {  
  
    val extensions: MutableList<Extension>  
  
    fun <T : Extension> register(extension: T): T {  
        extensions.add(extension)  
        return extension  
    }  
  
    @BeforeAll  
    fun extendableBeforeAll() {  
        extensions.forEach(Extension::extBeforeAll)  
    }  
  
    @BeforeEach  
    fun extendableBeforeEach() {  
        extensions.forEach(Extension::extBeforeEach)  
    }  
  
    @AfterEach  
    fun extendableAfterEach() {  
        extensions.asReversed().forEach(Extension::extAfterEach)  
    }  
  
    @AfterAll  
    fun extendableAfterAll() {  
        extensions.asReversed().forEach(Extension::extAfterAll)  
    }  
}  
  
open class ExtendableImpl : Extendable {  
    override val extensions = mutableListOf<Extension>()  
}  
  
interface Extension {  
    fun extBeforeAll() {}  
    fun extBeforeEach() {}  
    fun extAfterEach() {}  
    fun extAfterAll() {}  
}

úterý 1. ledna 2019

Kotlin - Use spaces in name of tests.md

Kotlin - Use spaces in name of tests.md

Kotlin - Use spaces in name of tests

Kotlin allow us to use any characters in method names (even with spaces). If we enclose it in backticks.:
fun `method - name`() {}

It can be very convenient for name of tests. And I think, that we should definitely make use of this opportunity.

Then we can have descriptive names of tests like for example
Spock
have.

Example

We can figure out a lot of example, but will show you just one :)

Consider this simple test:

@Test  
fun `multiplyExact of zero integer should return zero`() {  
    //when  
    val result = Math.multiplyExact(10, 0)  
      
    //then  
    assertThat(result).isEqualTo(0)  
}

It is easier to understand name of test above, than following one:

@Test  
fun multiplyExactOfZeroIntegerShouldReturnZero() { ... }

Where ends the name of method and where starts test description?

Experience

I have never found any problem with method named like this.
IDE (IntelliJ IDEA) have no problem with methods named like this.
And jUnitRunner have no difficulties with this methods as well.

So there is no excuse for writing less readable test names.

pondělí 17. prosince 2018

Equivalent closures in Groovy and Kotlin

Equivalent closures in Groovy and Kotlin.md

Equivalent closures in Groovy and Kotlin

Closures in Groovy and Kotlin are very similar, but have different names. Here is is list with few of them.

Project with samples is here:
https://github.com/bugs84/samples/tree/master/kotlin-groovy-closures

Groovy Kotlin
each forEach
collect map
findAll filter
find find
groupBy groupBy
eachWithIndex forEachIndexed
with run, let
with :-/ apply, also

Note: Not every think is absolutely same, but it’s at least quite similar.

each vs. forEach

def sum = 0
[1, 2, 3].each { sum += it }
assert sum == 6
var sum = 0  
listOf(1, 2, 3).forEach { sum += it }  
assertThat(sum).isEqualTo(6)

collect vs. map

List<String> result = [1, 2, 3].collect { "S-" + it }  
assert result == ["S-1", "S-2", "S-3"]
val result = listOf(1, 2, 3).map { "S-" + it }  
assertThat(result).isEqualTo(listOf("S-1", "S-2", "S-3"))

findAll vs. filter

assert [1, 2, 3, 4, 5].findAll { it < 3 } == [1, 2]
assertThat(
        listOf(1, 2, 3, 4, 5).filter { it < 3 }
).isEqualTo(
        listOf(1, 2)
)

find vs. find

assert [1, 2, 3, 4, 5].find { it < 3 } == 1
assertThat(  
        listOf(1, 2, 3, 4, 5).find { it < 3 }  
).isEqualTo(
        1
)

groupBy vs. groupBy

Map<Integer, List<Integer>> groupBy = [1, 2, 3, 4, 5, 6, 7].groupBy { it % 3 }  
assert groupBy == [  
        0: [3, 6],  
        1: [1, 4, 7],  
        2: [2, 5]  
]
val groupBy: Map<Int, List<Int>> = listOf(1, 2, 3, 4, 5, 6, 7).groupBy { it % 3 }  
assertThat(groupBy).isEqualTo(
    mapOf(  
        0 to listOf(3, 6),  
        1 to listOf(1, 4, 7),  
        2 to listOf(2, 5)  
    ))

eachWithIndex vs. forEachIndexed

def result = ""  
["A", "B"].eachWithIndex { entry, index ->  
    result += "$index:$entry, "  
}  
assert result == "0:A, 1:B, "
var result = ""  
listOf("A", "B").forEachIndexed { index, entry ->  
  result += "$index:$entry, "  
}  
assertThat(result).isEqualTo("0:A, 1:B, ")

Note: entry and index are in different order

with vs. run

assert "string".with {  
    length()  
} == 6
assertThat(  
    "string".run {  
        length  
    }  
).isEqualTo(6)

with/run can be used just for for creating an scope:

assert with {  
    "AAA"  
} == "AAA"
assertThat(  
        run {  
            "AAA"  
        }  
).isEqualTo("AAA")

In Groovy with works as Kotlin let as well. See next example:

with vs. let

assert "string".with {  
    it.length()  
} == 6
assertThat(  
        "string".let {  
            it.length  
        }  
).isEqualTo(6)

with vs. apply

assert "string".with {  
    println length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".apply {  
            println(length)  
        }
).isEqualTo("string")

with vs. also

assert "string".with {  
    println it.length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".also {  
            println(it.length)  
        }  
).isEqualTo("string")

středa 9. května 2018

Kotlin - Append to StringBuilder using "+" "plus" instead of append() method

Kotlin - Override plus operator for StringBuilder

Kotlin - Append to StringBuilder using “+” “plus” instead of append() method

In Kotlin you can easily override operator. I will show simple example how can this help you to write more readable code.

At first we will override “plus” operator on for StringBuilder class

operator fun StringBuilder.plus(str: String): StringBuilder {
    append(str)
    return this
}

If you define this function as private. It will be accessible only in file, where it is defined. Or public and then it can be used anywhere in project.

And from this code:

sb.append("function ").append(generatedClassName).append("() {").append("\n")
functions.forEach { function: Function ->
    sb.append(indent).append("this.").append(function.name).append(" = undefined;").append("\n")
}
sb.append("}").append("\n")
sb.append("var ").append(name).append(" = new ").append(generatedClassName).append("();").append("\n")

we can remove all ‘append’ words and we get this code:
=>

sb + "function " + generatedClassName + "() {" + "\n"
functions.forEach { function: Function ->
    sb + indent + "this." + function.name + " = undefined;" + "\n"
}
sb + "}" + "\n"
sb + "var " + name + " = new " + generatedClassName + "();" + "\n"

Very simple, code is shorter and more readable.