Showing posts with label kotlin. Show all posts
Showing posts with label kotlin. Show all posts

Last Updated: September 20, 2020

Nesting test cases with kotlin

Description: As features and requirements grows in our application, code and test cases grows hand in hand. It becomes very difficult to track the test cases with lots of them in single class. 

Consider a sample unit test class in Kotlin with bunch of test cases in single class

class ClientTest {

@Test
fun create(){
assert(true)
}
@Test
fun delete(){
assert(true)
}

@Test
fun connected(){
assert(true)
}

@Test
fun disconnected() {
assert(true)
}
}
fig.1

                                                        fig. 1

Well nothing wrong with test cases. 

Just imagine if you have 100+ tests within fig.1

By looking at fig.2 results it becomes difficult to figure out,

1. What exactly does these tests do ? or 

2. What's the logical connection within unit tests? etc 

That's where nesting comes useful for developers.

Consider a nesting sample with Kotlin

class ClientTest {

@Nested
inner class Operations{
@Test
fun create(){
assert(true)
}
@Test
fun delete(){
assert(true)
}
}

@Nested
inner class Client {
@Test
fun connected(){
assert(true)
}

@Test
fun disconnected(){
assert(true)
}
}
}

                                                   fig. 3

                                                     
                                                    fig. 4

We can now clearly make some distinction that, class in connecting to a client and doing some operations. (fig. 3 and fig. 4)

Although nesting is just a logical separation of test cases, it's very handy for developers in large scale projects.

For more updates follow us on -  Twitter

#codingIsAnArt #coderconsole


Last Updated: October 30, 2019

Things every android developer should know - part 5

Description: Hello coders! In this post I'm gonna show some interesting tips and tricks you can start using in your android project.

Also check out Part 1,Part 2Part 3 and Part 4

So let's get started.

1. How to remove boiler plate code of  Parcelable interface?

Let's consider this class with Parcelable Interface implementation. This class contains overriden methods which are boiler plate at larger extends

class User(val id: String, val name: String, val age: Long, val address: String, val isPrime: Boolean, val contact: String) : Parcelable {
    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString(),
            parcel.readLong(),
            parcel.readString(),
            parcel.readByte() != 0.toByte(),
            parcel.readString())

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(id)
        parcel.writeString(name)
        parcel.writeLong(age)
        parcel.writeString(address)
        parcel.writeByte(if (isPrime) 1 else 0)
        parcel.writeString(contact)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator {
        override fun createFromParcel(parcel: Parcel): User {
            return User(parcel)
        }

        override fun newArray(size: Int): Array {
            return arrayOfNulls(size)
        }
    }

}

So here comes @Parcelize annotation into picture. Lets modify our User class using @Parcelize
@Parcelize
class User(val id: String, val name: String, val age: Long, val address: String, 
           val isPrime: Boolean, val contact: String) : Parcelable

@Parcelize is the part of androidExtensions we have to enable it by adding below snippets within module's build.gradle section.
android {
    ...
    androidExtensions {
        experimental true
    }
    ...
}

2. Using Plurals

Although plurals where introduced long time back, but have seen developers adding logics for plural strings. Let's take an example of adding plural, when any post is liked.
    <plurals> name="like_count">
        <item quantity="one">%d second ago</item>
        <item quantity="other">%d seconds ago</item>
    </plurals>


Access within the code
mContext.resources.getQuantityString(R.plurals.like_count, 1, 2)

#Output:
2 second ago

#Note: First argument matches the plural and second is the argument for %d 

3. How to Change Default layout of activity?


Its interesting because it will help to add some constant template(toolbar in all the activity etc ) which we normally add after the activity is created, henceforth saving time. Simply Go to File -> New -> Edit File Templates


Edit Templates
Edit Templates

Change Default Tag of any layout.xml
Changing Root Tag for layouts

In the above example we can simply replace  ROOT_TAG with <LinearLayout> and next time when we create new layout it will start with <LinearLayout>


Bingo we're done.

For more updates follow us on -  Twitter

#codingIsAnArt
#coderconsole

Last Updated: September 19, 2018

Kotlin Reified Type

Description: In this post I'm gonna explain what is koltin reified types? with sample examples and explanation about its need and requirement in our application

If you are new to Koltin I recommend Switch from Java to Kotlin

So let's get started.



Why we need to know reified types?

Consider an below example in 'Java' which takes JSON and convert that into equivalent model class using Gson library (you can use any other parsing library like Jackson etc).

public T createModelFromClass(String jsonString) {
    return new Gson().fromJson(jsonString, T.class);
}

Now, if you try this way it will show an error saying "Cannot select from type variable". Because of "type erasure" in java generics which erased the type at run time.
Let's fix this!
public T createModelFromClass(String jsonString, Class<T> classT) {
    return new Gson().fromJson(jsonString, classT);
}

Consider the same example in kotlin

fun <T> createModelFromClass(jsonString: String): T {
    return Gson().fromJson(jsonString, T::class.java)
}
Now, if you try this way it will show an error saying ' Cannot use 'T' as reified type parameter. Use a class instead.

Because like in java the Generics 'T' get erased at run time.

Let's fix this!

fun <T: Any> createModelFromClass(jsonString: String, tClass: KClass<T>): T {
    return Gson().fromJson(jsonString, tClass.java)
}

Here comes the need!

In java and koltin example above, we need to pass the 'Class' so that the bytecode of the class could be generated at runtime.

Introducing reified type!
Reified in combination with inline function generates the bytecode of the class at runtime. So the overhead of passing <KClass> would be avoided within function.

How to use reified type?

Let's modify the above example of koltin using reified type




inline fun <reified T : Any> createModelFromClass(jsonString: String): T {
    return Gson().fromJson(jsonString, T::class.java)
}

Note: This functions with reified type are not callable from Java code.

Sample within the activity

class MainActivity : AppCompatActivity() {

    val USER_JSON = "{\"id\": 1000,\n" +
            " \"name\": \"nitesh tiwari\",\n" +
            " \"email\": \"[email protected]\"\n" +
            "}"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val userModel = createModelFromClass<User>(USER_JSON)
        Log.d("Reified", "\nName: " + userModel.name + "\nId:" + userModel.id + "\nEmail:" + userModel.email)
    }


    data class User(var id: Int, var name: String?, var email: String?)

    inline fun <reified T : Any> createModelFromClass(jsonString: String): T {
        return Gson().fromJson(jsonString, T::class.java)
    }
}


Output:

Name: nitesh tiwari
Id:1000
Email:[email protected]


Bingo! We are done. We have just avoided the overhead of passing the 'KClass' in method constructor to generate its byte code at runtime.


Last Updated: April 09, 2018

Koltin Extension functions and Operator Overloading examples

Description: In this post I'm gonna explain you guys how 'Kotlin' gives us the power to play around with our code using 'Extension function' and 'Operator Overloading'.

Note: If you are new to Kotlin. I strongly recommend Switch from Java to Kotlin and Kotlinlang

So lets get started.



1. Kotlin Extension functions:

Why Extensions?
Extension empower as to extend the functionality of the existing classes without overriding the whole structure. Its fun !!!

Syntax:
fun <InheritingClassName>.<functionName>()

e.g : fun String.firstCharacterUpperCase(): String


Example 1:

Consider a requirement about making the first character 'CAPITAL' for logged in user in your app.

Using Extension:

fun String.firstCharacterUpperCase(): String {
    return if (this[0].isLowerCase())
        this[0].toUpperCase().plus(this.substring(1, this.length))
    else        this 
}

Explanation: This extension function return a String by making the first character in 'CAPITAL'

Note: 'this' means the inherited class. In our example its 'String'

So simply call:
fun printName(){
    val name = "nitesh tiwari".firstCharacterUpperCase()
    println("Name: $name")
}

//OutPut:
//Name: Nitesh tiwari


Example 2: 

Consider a requirement of getting a list on odd and even indexes respectively.

Using Extension:
fun <T> ArrayList<T>.oddEvenArrayItems(oddOrEven: Int): ArrayList<T> {
    val list = arrayListOf<T>()
    forEachIndexed { index, genericObject ->
        if (index % 2 == oddOrEven)
            list.add(genericObject)
    }
    return list
}

Explanation: This extension function returns generic ArrayList<T> whose index can we either odd or even based on input params.

So simply call:
fun printData(){
    val arrayList = arrayListOf<Int>(2,3,4,5,6,7,8,9,10, 11)
    val odd = arrayList.oddEvenArrayItems(1)
    val even = arrayList.oddEvenArrayItems(0)

    println("odd: $odd")
    println("even: $even")

    //OUTPUT
    //odd: [3, 5, 7, 9, 11]
    //even: [2, 4, 6, 8, 10]}

2. Operator Overloading:


Why Operator Overloading:
Operator overloading in Kotlin provide us the power to change the implementation of operators like plus(+),times(*),unaryplus(++),plusAssign(+=) and many many more on our 'Custom Objects'. Highly powerful !!!

Note: Operator names should be same.

Syntax:
operator fun <operatorName>()
e.g: operator fun plus()

Example 1: Consider a requirement where you want to add the price of the shopping cartItem together.

class CartItem(val price: Double, val name: String) {

    val itemName: String? = null
    operator fun plus(other: CartItem): Double =
        price + other.price
    
}

fun addPrice() {
    val cartItem1 = CartItem(10.6, "Bag")
    val cartItem2 = CartItem(20.4, "Shoes")

    val total: Double = cartItem1 + cartItem2
    println("Total Cost: $total")

    //OUTPUT:    //Total Cost: 31.0
}
Explanation: We have created a class 'CartItem' which contains the price of the shopping item and overridden the plus(+) operator for adding the prices together and returning the result. Looks simple right?.

Let's checkout one more example to understand operator overloading in combination of extension function


Example 2: Finding the item by productId in the List<CartItem>

class CartItem(val productId: Int, val price: Double, val name: String)

class Cart(val mList: List<CartItem>) {

    operator fun contains(id: Int): Boolean =
        mList.hasProductId(id)

    fun List<CartItem>.hasProductId(productId: Int): Boolean {
        forEachIndexed { _, cartItem ->
            if (productId == cartItem.productId)
                return true
        }
        return false
    }
}

fun checkProductId(){

    //Preparing CartItems
    val cartItem1 = CartItem(1001, 10.6, "Bag")
    val cartItem2 = CartItem(1002, 20.4, "Shoes")

    //Creating CartList
    val cartList = arrayListOf<CartItem>()
    cartList.add(cartItem1)
    cartList.add(cartItem2)

    //Creating Cart

   val cart = Cart(cartList)

    //Finding product
    println("Is 1001 present: " + cart.contains(1001))
    println("Is 1006 present: " + cart.contains(1006))
    
    //OUTPUT
    //Is 1001 present: true 
   //Is 1006 present: false
}

Explanation:
1. We have created a class 'Cart' which will be contain our listOf  'CartItem'.

2. Within our 'Cart' class we have overridden the 'contains' operator which will find whether the productId is within the 'Cart'

3. Finally, we have extension function(hasProductId) on List<CartItem> which returns a Boolean if the productId is present.

Example 3: Comparing two games together.

class GameItem(val scores: Double) {
    operator fun compareTo(item: GameItem): Int = this.scores.compareTo(item.scores)
}

fun compareGame() {

    val gameItem1 = GameItem(100.0)
    val gameItem2 = GameItem(2000.0)

    val result = gameItem1 > gameItem2

    println("Is game1 > game2 ? $result")
    
    //OUTPUT:    //Is game1 > game2 ? false}

Bingo we are done !!!

Let me know if you have any questions in comment box :-)

For more updates follow us on -  Twitter

#codingIsAnArt :-)

Last Updated: August 18, 2017

Switch from Java to Kotlin


Description: In this post I'm gonna show some of the basic syntax and semantics difference while we use "KOTLIN" in your android application w.r.t JAVA(Java v/s KOTLIN).


So let's get started.



1. Variable Declaration
Java:
String name="coderconsole";

Kotlin:
val  name:String="coderconsole"

2. Casting

Java:
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);

Kotlin:
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

3. Function Declaration

Java:

void methodDeclaration(){
    methodDeclaration("First Method ");
}

void methodDeclaration(String firstParam) {
    methodDeclaration(firstParam, "Second Method ");
}

void methodDeclaration(String firstParam, String secondParams) {
    System.out.println(firstParam + secondParams);
}


Kotlin:


fun methodDeclaration(){
    methodDeclaration("First Method ")
}

fun methodDeclaration(name : String){
    methodDeclaration(name, "Second Method ")
}

fun methodDeclaration(first : String, second: String){
    println(first + second)
}


4. Static Functions and Variable

Java:

class DeviceUtils{
    static final String name = "coderconsole";

    public static String getAndroidId(Context context){
        return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }
}



Kotlin:


class DeviceUtils {

    companion object {
        val name: String = "coderconsole"
        @JvmStatic fun getAndroidId(context: Context): String = Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
   }

}



5. Ternary


Java:
String ternary(String name) {
    return name.equalsIgnoreCase("coderconsole") ? " Ternary success" : " Ternary failed";
}

Kotlin:
fun ternary(name: String): String {
    return if (name.equals("coderconsole"))"Ternary success" else "Ternary failed"
}

6. Operators(this operators are only useful in kotlin)

a) Null Type(?)- variable can be made null only using null type operator

   val array: String = null /** Null cannot be the value of not null type**/ 
   val array: String? = null  /** Bingo! Will work now **/

b) Safe Type:(?.) - Helpful when we donot know when the variable be null.So instead of throwing NPE it return the value as null.

//The below code will return "customerId" if present else return null even if the "customerObject" is null.
fun safeTypeDemo(customerObject: JSONObject?): String?{
         return customerObject?.optString("customerId")     
}

c) Elvis Operator(?:) - Helpful when we want to return some not-null values, if the first result is null.
Java:
int elvisDemo(JSONObject result){
      if (result != null)
        return result.optInt("marks");
     else  return -1;
   }

Kotlin: 
fun elvisDemo(marksObject: JSONObject?): Int {
         return marksObject?.optInt("marks")?:-1      
}
                                 (or)
fun elvisDemo(marksObject: JSONObject?): Int = marksObject?.optInt("marks")?:-1


d) !! operator - throws Null Pointer when asked explicitly
//The below code will throw NullPointerException if customerObject is null.
fun npeTypeDemoDemo(customerObject: JSONObject?): String{
         return customerObject!!.optString("customerId")     
}


7. Loops
a) for loop:
Java
void forLoopDemo(List mList) {
        for (String item : mList)Log.d("Loop", item);
    }

Kotlin
fun forLoopDemo(mList: List) {
       for (item in mList) Log.d("Loop", item)
    }

b) while/do-while: - there is no syntactical difference from Java.

8. Switch Case
Java
void switchCaseDemo(int type) {
    switch (type){
        case 0:
            Log.d("switch", "value - " + type);
            break;
        case 1:
            Log.d("switch", "value - " + type);
            break;
        default:
            Log.d("switch", "value default");
            break;

    }
}

Kotlin
fun switchCaseDemo(type: Int) {
    when (type) {
        0 -> Log.d("switch", "value - " + type)
        1 -> Log.d("switch", "value - " + type)
        else -> Log.d("switch", "value default")
    }
}


9. Extends/Implements

//This sample contains abstract class and an interface to printData.
public abstract class AbstractA {
    public void printAbstractData(String data){
        System.out.println(data);
    }
}
public interface InterfaceA {
    public void printData(String data);
}


public class ExtendsImpDemo extends AbstractA implements InterfaceA {
    @Override    public void printData(String data) {
        printAbstractData(data);
    }
}


Kotlin

abstract class AbstractA{
    public fun printAbstractData(data: String){
        println(data)
    }
}

interface InterfaceA{
    fun printData(data: String)
}

class ExtendsImpDemo : AbstractA(), InterfaceA {
    override fun printData(data: String) {
        printAbstractData(data)
    }
}


10. Iterating JSONArray

Java:
void arrayTest(JSONArray jsonArray) {
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject jsonObject = jsonArray.optJSONObject(i);
        Log.d("ArrayTest", jsonObject.optString("name"));
    }
}

Kotlin:
fun arrayTest(jsonArray: JSONArray){
    jsonArray.items<JSONObject>().forEachIndexed { i, jsonObject ->
        Log.d("ArrayTest", jsonObject.optString("name"))
    }
}

Kotlin is an awesome language and very fun to write code in it.
For further reference you can try https://try.kotlinlang.org

For more updates follow us on -  Twitter