diff --git a/stateful/src/main/java/com/picsart/stateful/SavableProperty.kt b/stateful/src/main/java/com/picsart/stateful/SavableProperty.kt index 22e0448..515dba7 100644 --- a/stateful/src/main/java/com/picsart/stateful/SavableProperty.kt +++ b/stateful/src/main/java/com/picsart/stateful/SavableProperty.kt @@ -71,33 +71,13 @@ class SavableProperty( value = defaultValue return } - val nullableValue = when (value) { - is Boolean -> bundle.getBoolean(key) as T - is BooleanArray -> bundle.getBooleanArray(key) as T - is Bundle -> bundle.getBundle(key) as T - is Byte -> bundle.getByte(key) as T - is ByteArray -> bundle.getByteArray(key) as T - is Char -> bundle.getChar(key) as T - is CharArray -> bundle.getCharArray(key) as T - is Double -> bundle.getDouble(key) as T - is DoubleArray -> bundle.getDoubleArray(key) as T - is Float -> bundle.getFloat(key) as T - is FloatArray -> bundle.getFloatArray(key) as T - is Int -> bundle.getInt(key) as T - is IntArray -> bundle.getIntArray(key) as T - is Long -> bundle.getLong(key) as T - is LongArray -> bundle.getLongArray(key) as T - is Parcelable -> bundle.getParcelable(key) as T - is Short -> bundle.getShort(key) as T - is ShortArray -> bundle.getShortArray(key) as T - is String -> bundle.getString(key) as T - is Serializable -> bundle.getSerializable(key) as T - else -> { - val klass = bundle.getSerializable(classKey) as Class - Gson().fromJson(bundle.getString(key), klass) - } + + value = if (bundle.containsKey(classKey)) { + val klass = bundle.getSerializable(classKey) as Class + Gson().fromJson(bundle.getString(key), klass) + } else { + bundle.get(key) as T } - value = nullableValue } override fun getValue(thisRef: Any, property: KProperty<*>): T { diff --git a/stateful/src/test/java/com/picsart/stateful/SavablePropertyTest.kt b/stateful/src/test/java/com/picsart/stateful/SavablePropertyTest.kt index a5adb09..e83f04f 100644 --- a/stateful/src/test/java/com/picsart/stateful/SavablePropertyTest.kt +++ b/stateful/src/test/java/com/picsart/stateful/SavablePropertyTest.kt @@ -17,6 +17,8 @@ package com.picsart.stateful import android.os.Bundle +import android.os.Parcel +import android.os.Parcelable import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -26,7 +28,6 @@ import java.util.* import kotlin.math.abs import kotlin.reflect.KClass -//TODO implement tests for types Bundle, Parcelable, Serializable @RunWith(RobolectricTestRunner::class) @Config(manifest = Config.NONE) class SavablePropertyTest { @@ -92,7 +93,7 @@ class SavablePropertyTest { } @Test - fun enumTest() { + fun enumSerializableTest() { testProperty(Mode::class) } @@ -121,6 +122,20 @@ class SavablePropertyTest { testProperty(String::class) } + @Test + fun gsonTest() { + testProperty(DataClass::class) + } + + @Test + fun parcelableTest() { + testProperty(ParcelableClass::class) + } + + @Test + fun bundleTest() { + testProperty(Bundle::class) + } private fun testProperty(type: KClass) { var rand = generateRandomValueOfType(type) @@ -197,6 +212,12 @@ class SavablePropertyTest { ShortArray::class -> generateRandomArrayOfType(Short::class) as T String::class -> UUID.randomUUID().toString() as T Mode::class -> Mode.values()[Random().nextInt(Short.MAX_VALUE + 1) % 2] as T + DataClass::class -> DataClass(Random().nextInt(), Random().nextInt()) as T + ParcelableClass::class -> ParcelableClass(Random().nextInt(), Random().nextInt()) as T + Bundle::class -> Bundle().apply { + putString(UUID.randomUUID().toString(), UUID.randomUUID().toString() ) + putInt(UUID.randomUUID().toString(), Random().nextInt()) + } as T else -> { throw TypeNotPresentException("generateRandomValueOfType is not implemented for $type", null) } @@ -224,4 +245,33 @@ class SavablePropertyTest { enum class Mode { DEFAULT, OTHER +} + +data class DataClass(val field1: Int, val field2: Int) + +class ParcelableClass(val field1: Int, val field2: Int) : Parcelable { + + constructor(parcel: Parcel) : this( + parcel.readInt(), + parcel.readInt()) { + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeInt(field1) + parcel.writeInt(field2) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): ParcelableClass { + return ParcelableClass(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } } \ No newline at end of file diff --git a/stateful/src/test/java/com/picsart/stateful/StatefulImplTest.kt b/stateful/src/test/java/com/picsart/stateful/StatefulImplTest.kt index 66b42df..576c1a0 100644 --- a/stateful/src/test/java/com/picsart/stateful/StatefulImplTest.kt +++ b/stateful/src/test/java/com/picsart/stateful/StatefulImplTest.kt @@ -29,10 +29,28 @@ import org.robolectric.annotation.Config @Config(manifest = Config.NONE) class StatefulImplTest : Stateful by StatefulImpl() { + data class A(val a: Int) + + enum class B { + B_1, B_2 + } + private var testProperty by statefulProperty(3) private var testNullableProperty by statefulNullableProperty(null) + private var testNullableProperty1 by statefulNullableProperty(false) + + private var testNullableProperty2 by statefulNullableProperty(null) + + private var testNullableProperty3 by statefulNullableProperty(A(2)) + + private var testNullableProperty4 by statefulNullableProperty("1234") + + private var testNullableProperty5 by statefulNullableProperty(B.B_2) + + private var testNullableProperty6 by statefulNullableProperty(Bundle()) + private var testPropertyWithKey by statefulProperty(-78, "test property") private var liveData by statefulLiveDataProperty(MutableLiveData(), null, "test livedata property") @@ -53,9 +71,10 @@ class StatefulImplTest : Stateful by StatefulImpl() { liveData.observeForever(observer) liveData.apply { value = 90 } Assert.assertEquals(liveData.value, 90) + val bundle = Bundle() liveData.removeObserver(observer) - save(bundle) + saveInternal(bundle) isFirst = false observer = Observer { if (!isFirst) { @@ -65,10 +84,12 @@ class StatefulImplTest : Stateful by StatefulImpl() { Assert.assertEquals(128, it) } } + restore(bundle) liveData.observeForever(observer) liveData.apply { value = 128 } Assert.assertEquals(liveData.value, 128) liveData.removeObserver(observer) + isFirst = false observer = Observer { if (!isFirst) { @@ -89,7 +110,7 @@ class StatefulImplTest : Stateful by StatefulImpl() { testProperty = 9 Assert.assertEquals(9, testProperty) val bundle = Bundle() - save(bundle) + saveInternal(bundle) Assert.assertTrue(bundle.containsKey("testProperty")) Assert.assertEquals(9, bundle.get("testProperty")) testProperty = 67 @@ -107,16 +128,27 @@ class StatefulImplTest : Stateful by StatefulImpl() { testNullableProperty = null Assert.assertEquals(null, testNullableProperty) - val bundle = Bundle() - save(bundle) + var bundle = Bundle() + saveInternal(bundle) Assert.assertTrue(!bundle.containsKey("testNullableProperty")) Assert.assertEquals(null, bundle.get("testNullableProperty")) testNullableProperty = 67 Assert.assertEquals(67, testNullableProperty) - restore(null) restore(bundle) Assert.assertTrue(!bundle.containsKey("testNullableProperty")) Assert.assertEquals(null, testNullableProperty) + Assert.assertTrue(!bundle.containsKey("testNullableProperty")) + Assert.assertEquals(null, testNullableProperty) + + testNullableProperty = 67 + bundle = Bundle() + saveInternal(bundle) + testNullableProperty = null + Assert.assertTrue(bundle.containsKey("testNullableProperty")) + Assert.assertEquals(67, bundle.get("testNullableProperty")) + restore(bundle) + Assert.assertEquals(67, testNullableProperty) + } @Test @@ -125,7 +157,7 @@ class StatefulImplTest : Stateful by StatefulImpl() { testPropertyWithKey = 9 Assert.assertEquals(9, testPropertyWithKey) val bundle = Bundle() - save(bundle) + saveInternal(bundle) Assert.assertTrue(bundle.containsKey("test property")) Assert.assertEquals(9, bundle.get("test property")) testPropertyWithKey = 67 @@ -134,4 +166,17 @@ class StatefulImplTest : Stateful by StatefulImpl() { restore(bundle) Assert.assertEquals(9, testPropertyWithKey) } + + //in android, after save state properties are likely to be cleared (i.e. low memory) + private fun saveInternal(bundle: Bundle) { + save(bundle) + testNullableProperty = null + testNullableProperty1 = null + testNullableProperty2 = null + testNullableProperty3 = null + testNullableProperty4 = null + testNullableProperty5 = null + testNullableProperty6 = null + liveData.value = null + } } \ No newline at end of file