Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dev.appoutlet.some.android.resolver

import android.os.Bundle
import dev.appoutlet.some.core.Resolver
import dev.appoutlet.some.core.ResolverChain
import kotlin.random.Random
import kotlin.reflect.KType
import kotlin.reflect.typeOf

private const val MIN_STRING_LENGTH = 1
private const val MAX_STRING_LENGTH = 10

/**
* Resolves [Bundle] types by creating a new [Bundle] and populating it with
* one entry for each supported primitive value type.
*
* Generated bundles always contain one [String], [Int], [Long], [Float],
* [Double], and [Boolean] entry with random values.
*
* @param random Random source used when generating values.
*/
class BundleResolver(
private val random: Random
) : Resolver {
override fun canResolve(type: KType): Boolean = type == typeOf<Bundle>()

override fun resolve(type: KType, chain: ResolverChain): Any {
return Bundle().apply {
putString("string", generateString())
putInt("int", random.nextInt())
putLong("long", random.nextLong())
putFloat("float", random.nextFloat())
putDouble("double", random.nextDouble())
putBoolean("boolean", random.nextBoolean())
}
}

private fun generateString(): String {
val length = random.nextInt(MIN_STRING_LENGTH, MAX_STRING_LENGTH + 1)
return List(length) { ('a'..'z').random(random) }.joinToString("")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package dev.appoutlet.some.android.resolver

import android.os.Bundle
import dev.appoutlet.some.config.NullableStrategy
import dev.appoutlet.some.core.ResolverChain
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import kotlin.random.Random
import kotlin.reflect.typeOf

@RunWith(RobolectricTestRunner::class)
class BundleResolverTest {
@Test
fun `BundleResolver canResolve detects Bundle type`() {
val resolver = BundleResolver(Random.Default)
assertTrue(resolver.canResolve(typeOf<Bundle>()))
}

@Test
fun `BundleResolver rejects non-Bundle types`() {
val resolver = BundleResolver(Random.Default)
assertFalse(resolver.canResolve(typeOf<String>()))
assertFalse(resolver.canResolve(typeOf<Int>()))
}

@Test
fun `BundleResolver generates non-null Bundle`() {
val resolver = BundleResolver(Random.Default)
val result = resolver.resolve(typeOf<Bundle>(), testChain)
assertNotNull(result)
assertTrue(result is Bundle)
}

@Test
fun `BundleResolver generates one entry for each supported type`() {
val resolver = BundleResolver(Random.Default)

repeat(20) {
val result = resolver.resolve(typeOf<Bundle>(), testChain) as Bundle

assertEquals(6, result.size())
assertEquals(setOf("string", "int", "long", "float", "double", "boolean"), result.keySet())
assertNotNull(result.getString("string"))
assertTrue(result.getString("string")!!.isNotEmpty())
assertTrue(result.getValue("string") is String)
assertTrue(result.getValue("int") is Int)
assertTrue(result.getValue("long") is Long)
assertTrue(result.getValue("float") is Float)
assertTrue(result.getValue("double") is Double)
assertTrue(result.getValue("boolean") is Boolean)
}
}

@Suppress("DEPRECATION")
private fun Bundle.getValue(key: String): Any? = get(key)

companion object {
private val testChain = ResolverChain(emptyList(), NullableStrategy.NullOnCircularReference)
}
}
17 changes: 9 additions & 8 deletions docs/android/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@ All shared types from [Supported Types](../supported-types.md) are available her

Today, the Android module adds these Android-specific types:

| Type | Usage | Notes |
|------|-------|-------|
| `android.net.Uri` | `some<Uri>()` | See [Uri](uri.md) and [Uri Strategy](uri.md#uri-strategy) |
| `android.graphics.Rect` | `some<Rect>()` | Random integer bounds with `left < right` and `top < bottom` |
| `android.graphics.RectF` | `some<RectF>()` | Random float bounds with `left < right` and `top < bottom` |
| `android.graphics.Point` | `some<Point>()` | Random integer `x` and `y` |
| Type | Usage | Notes |
|------|------------------|-------|
| `android.net.Uri` | `some<Uri>()` | See [Uri](uri.md) and [Uri Strategy](uri.md#uri-strategy) |
| `android.graphics.Rect` | `some<Rect>()` | Random integer bounds with `left < right` and `top < bottom` |
| `android.graphics.RectF` | `some<RectF>()` | Random float bounds with `left < right` and `top < bottom` |
| `android.graphics.Point` | `some<Point>()` | Random integer `x` and `y` |
| `android.graphics.PointF` | `some<PointF>()` | Random float `x` and `y` |
| `android.util.Size` | `some<Size>()` | Random positive integer `width` and `height` |
| `android.util.SizeF` | `some<SizeF>()` | Random positive float `width` and `height` |
| `android.util.Size` | `some<Size>()` | Random positive integer `width` and `height` |
| `android.util.SizeF` | `some<SizeF>()` | Random positive float `width` and `height` |
| `android.os.Bundle` | `some<Bundle>()` | One random value each for `String`, `Int`, `Long`, `Float`, `Double`, and `Boolean` |

## Platform constraints

Expand Down