Author Archives: Niklas - Page 13

My Kotlin features cheat sheet

Kotlin is a new and quite exciting language for both mobile and backend development. It has many nifty constructs. This is my Kotlin features sheet cheat that I will use whenever I need to switch from another language and to Kotlin. Maybe it can help you too 🙂

    // Let's start with a HelloWorld example
    println("Hello Kotlin!")

Variables

    // Immutable variables (only getters are provided)
    val readonly = 10

    // Mutable variables (getters and setters are provided)
    var mutable = "Hello"
    mutable = "Hello again"

    // Explicit typing
    val student: Student = Student
    val year: Int = 49

    // Implicit typing
    val student = Student
    val year = 42

    // Variable destruction
    val (model, color, price) = car
    println("I have a $color $model that set me back $price SEK")
    // Ex. "I have a red S60 that set me back 250 000 SEK"

String concatenation

    // 'In string' concatenation
    println("My daughter is $readonly years of age")
    // Ex. "My daughter is 10 yeas of age"

    // 'In string' concatenation with string functions
    println("In ten years my daughter will be ${readonly.plus(10)}")
    // Ex. "In ten years my daughter will be 20"

Switch statement

    // Kotlin switch
    var x = 23
    when (x) {
        in 1..10 -> println("x is between 1 and 10")
        !in 10..20 -> println("x is not between 1 and 10")
        else -> println("default branch")
    }

NULL

    // Mark variables that can be null
    val name: String  = "Niklas"
    var work: String? = "Goverment"

    name = null // NOT allowed     
    work = null // Allowed
    

Spread operator

    // Spread operator
    val subscriptions = arrayOf("subscription a", "subscription b")
    val hardware = arrayOf("iPhone 12", "iPhone X")
    val shoppingCart = arrayOf(*subscriptions, *hardware)
    // shoppingCart: 
    // ["subscription a", "subscription b", "iPhone 12", "iPhone X"]

Range

    // Range operator
    for (x in 1..10) {
        println(x)
    }
    // 12345678910

Pair

    // Pair object
    val hands = "Left" to "Right"
    println(hands.first)  // "Left"
    println(hands.second) // "Right"

Check variable type

val model = "Volvo"
val price = 123000.50
val cars: List<any> = listOf(model, price)

for(car in cars) {
  when (car) {
    is String -> {
      println("Model: $car")
    }
    is Double -> {
      println("Price: $car")
    }
    else -> {
      println("Not an attribute")
    }
  }
}

Short function syntax

fun sum(a: Int, b: Int) = a + b
println(sum(2, 4)) // 6

Default arguments

fun printWO(productId: Int, amount: Int = 1, by: String = "mail") {
  println("$amount of $productId by $by")
}

printWO(123456)             // "1 of 123456 by mail"
printWO(123456, 10)         // "10 of 123456 by mail"
printWO(123456, 10, "DHL")  // "10 of 123456 by DHL"

Data class

data class Phone(var model: Int, val color: String)

val phone = Phone(123456, "Purple")

println(phone)       // Phone(model=123456, color=Purple) - toString()
println(phone.model) // 123456 - Built in getters
phone.color = "Blue" // Built in setter
println(phone)       // Phone(model=123456, color=Blue)

val (model, color) = phone // Destructuring data classes

Singelton

object MySingletonClass {
  init {
    println("Hello World!")
  }
  var name = "I a Singelton"
  fun printName(){
    println(name)
  }
}

fun main() {     
    MySingletonClass.printName()  // "I a Singelton"
}

H2 Database: Missing UNIX_TIMESTAMP

So maybe you are running tests using an H2 database with your MySQL-based application, and you just got the message that the MySQL function UNIX_TIMESTAMP(value) is missing from the H2 database? No worries. With an H2 database, you can build your own UNIX_TIMESTAMP (or any other function you might need). I’m here going to show you one way to do it:

First, we need to create a class on the classpath of the application that connects to the H2 database, this is normally the application you are testing:

package h2;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class H2UserDefined {

    public static Long UNIX_TIMESTAMP(String d) throws ParseException {
        DateFormat dateFormat 
                          = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date dateresult = dateFormat.parse(d);
        return dateresult.getTime()/1000;
    }
}

Now we need to tell H2 that we have a new function to use. To do this we need some SQL to run against the H2 database:

CREATE ALIAS UNIX_TIMESTAMP FOR "h2.H2UserDefined.UNIX_TIMESTAMP";

Here we tell the H2 database that there is a new alias called UNIX_TIMESTAMP that can be used and that it is located in the package ‘h2’ with the path ‘H2UserDefines’ and a function name UNIX_TIMESTAMP. Quite simple 🙂

Tested on Play Framework 2.3.6, H2 v1.4

Vue testing with Jest: Mock window.location

The bottom line is that you can not mock window.location, BUT you can delete it and create your own to use in test. I will here show one example of how this can be achived:

describe('methodUnderTest', () => {
  // Save current windows.location
  const oldWindowLocation = window.location;
  // Some mocked value
  const mockedUrl = 'https://blog.niklasottosson.com';

  beforeEach(() => {
    // Remove windows.location so that we can create a new
    delete window.location;

    // Create a new mutable window.location
    window.location = Object.defineProperties(
      {},
       {   // copy all properties from the old window.location
        ...Object.getOwnPropertyDescriptors(oldWindowLocation),
        // Start mocking...
        assign: {
           configurable: true,
           value: jest.fn()
        },
        href: {
            configurable: true,
            value: mockedUrl
        }
     );
  });

  afterEach(() => {
    // Restore window.location
    window.location = oldWindowLocation;
  });

  // Start creating your tests...
  it('should...', () => {
    ...
  } 

Tested on OSX 10.15.7, Vue v2.6.12 and Jest v26.0.14