Skip to content

Commit 0acf5a5

Browse files
fercarcedopocmo
authored andcommitted
Issue mozilla-mobile#466: Fretboard: Move JSONExtensions into support-ktx
Closes mozilla-mobile#466: Fretboard: Move JSONExtensions into support-ktx
1 parent 5a999c4 commit 0acf5a5

File tree

9 files changed

+234
-52
lines changed

9 files changed

+234
-52
lines changed

components/service/fretboard/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ android {
2222
}
2323

2424
dependencies {
25+
implementation project(':support-ktx')
2526
implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.dependencies['kotlin']}"
2627
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${rootProject.ext.dependencies['coroutines']}"
2728

components/service/fretboard/src/main/java/mozilla/components/service/fretboard/JSONExperimentParser.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
package mozilla.components.service.fretboard
66

7+
import mozilla.components.support.ktx.kotlin.putIfNotNull
8+
import mozilla.components.support.ktx.kotlin.toJsonArray
9+
import mozilla.components.support.ktx.kotlin.toList
10+
import mozilla.components.support.ktx.kotlin.tryGetInt
11+
import mozilla.components.support.ktx.kotlin.tryGetLong
12+
import mozilla.components.support.ktx.kotlin.tryGetString
713
import org.json.JSONArray
814
import org.json.JSONObject
915

@@ -20,7 +26,7 @@ class JSONExperimentParser {
2026
fun fromJson(jsonObject: JSONObject): Experiment {
2127
val bucketsObject: JSONObject? = jsonObject.optJSONObject(BUCKETS_KEY)
2228
val matchObject: JSONObject? = jsonObject.optJSONObject(MATCH_KEY)
23-
val regions: List<String>? = matchObject?.optJSONArray(REGIONS_KEY)?.toList()
29+
val regions: List<String>? = matchObject?.optJSONArray(REGIONS_KEY).toList()
2430
val matcher = if (matchObject != null) {
2531
Experiment.Matcher(
2632
matchObject.tryGetString(LANG_KEY),

components/service/fretboard/src/main/java/mozilla/components/service/fretboard/JSONExtensions.kt

Lines changed: 0 additions & 50 deletions
This file was deleted.

components/support/ktx/src/main/java/mozilla/components/support/ktx/kotlin/JSONArray.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,16 @@ fun JSONArray.asSequence(): Sequence<Any> {
2424
}
2525
}
2626
}
27+
28+
/**
29+
* Convenience method to convert a JSONArray into a List
30+
*
31+
* @return list with the JSONArray values, or an empty list if the JSONArray was null
32+
*/
33+
@Suppress("UNCHECKED_CAST")
34+
fun <T> JSONArray?.toList(): List<T> {
35+
if (this != null) {
36+
return asSequence().map { it as T }.toList()
37+
}
38+
return listOf()
39+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package mozilla.components.support.ktx.kotlin
6+
7+
import org.json.JSONObject
8+
import java.util.TreeMap
9+
10+
/**
11+
* Returns the value mapped by {@code key} if it exists, and
12+
* if the value returned is not null. If it's null, it returns null
13+
*/
14+
fun JSONObject.tryGetString(key: String): String? {
15+
if (!isNull(key)) {
16+
return getString(key)
17+
}
18+
return null
19+
}
20+
21+
/**
22+
* Returns the value mapped by {@code key} if it exists, and
23+
* if the value returned is not null. If it's null, it returns null
24+
*/
25+
fun JSONObject.tryGetInt(key: String): Int? {
26+
if (!isNull(key)) {
27+
return getInt(key)
28+
}
29+
return null
30+
}
31+
32+
/**
33+
* Returns the value mapped by {@code key} if it exists, and
34+
* if the value returned is not null. If it's null, it returns null
35+
*/
36+
fun JSONObject.tryGetLong(key: String): Long? {
37+
if (!isNull(key)) {
38+
return getLong(key)
39+
}
40+
return null
41+
}
42+
43+
/**
44+
* Puts the specified value under the key if it's not null
45+
*/
46+
fun JSONObject.putIfNotNull(key: String, value: Any?) {
47+
if (value != null) {
48+
put(key, value)
49+
}
50+
}
51+
52+
/**
53+
* Sorts the keys of a JSONObject (and all of its child JSONObjects) alphabetically
54+
*/
55+
fun JSONObject.sortKeys(): JSONObject {
56+
val map = TreeMap<String, Any>()
57+
for (key in this.keys()) {
58+
map[key] = this[key]
59+
}
60+
val jsonObject = JSONObject()
61+
for (key in map.keys) {
62+
if (map[key] is JSONObject) {
63+
map[key] = (map[key] as JSONObject).sortKeys()
64+
}
65+
jsonObject.put(key, map[key])
66+
}
67+
return jsonObject
68+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package mozilla.components.support.ktx.kotlin
6+
7+
import org.json.JSONArray
8+
9+
/**
10+
* Converts the list into a JSON array
11+
*/
12+
fun <T> List<T>.toJsonArray(): JSONArray {
13+
return fold(JSONArray()) { jsonArray, element -> jsonArray.put(element) }
14+
}

components/support/ktx/src/test/java/mozilla/components/support/ktx/kotlin/JSONArrayTest.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package mozilla.components.support.ktx.kotlin
66

77
import junit.framework.Assert.assertEquals
8+
import junit.framework.Assert.assertTrue
89
import org.json.JSONArray
910
import org.junit.Test
1011
import org.junit.runner.RunWith
@@ -23,4 +24,29 @@ class JSONArrayTest {
2324

2425
assertEquals(6, sum)
2526
}
26-
}
27+
28+
@Test
29+
fun testToListNull() {
30+
val jsonArray: JSONArray? = null
31+
val list = jsonArray.toList<Any>()
32+
assertEquals(0, list.size)
33+
}
34+
35+
@Test
36+
fun testToListEmpty() {
37+
val jsonArray = JSONArray()
38+
val list = jsonArray.toList<Any>()
39+
assertEquals(0, list.size)
40+
}
41+
42+
@Test
43+
fun testToListNotEmpty() {
44+
val jsonArray = JSONArray()
45+
jsonArray.put("value")
46+
jsonArray.put("another-value")
47+
val list = jsonArray.toList<String>()
48+
assertEquals(2, list.size)
49+
assertTrue(list.contains("value"))
50+
assertTrue(list.contains("another-value"))
51+
}
52+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package mozilla.components.support.ktx.kotlin
2+
3+
import org.json.JSONArray
4+
import org.json.JSONObject
5+
import org.junit.Assert.assertEquals
6+
import org.junit.Assert.assertNull
7+
import org.junit.Test
8+
import org.junit.runner.RunWith
9+
import org.robolectric.RobolectricTestRunner
10+
11+
@RunWith(RobolectricTestRunner::class)
12+
class JSONObjectTest {
13+
@Test
14+
fun testSortKeys() {
15+
val jsonObject = JSONObject()
16+
jsonObject.put("second-key", "second-value")
17+
jsonObject.put("third-key", JSONArray().apply {
18+
put(1)
19+
put(2)
20+
put(3)
21+
})
22+
jsonObject.put("first-key", JSONObject().apply {
23+
put("one-key", "one-value")
24+
put("a-key", "a-value")
25+
put("second-key", "second")
26+
})
27+
assertEquals("""{"first-key":{"a-key":"a-value","one-key":"one-value","second-key":"second"},"second-key":"second-value","third-key":[1,2,3]}""", jsonObject.sortKeys().toString())
28+
}
29+
30+
@Test
31+
fun testPutIfNotNull() {
32+
val jsonObject = JSONObject()
33+
assertEquals(0, jsonObject.length())
34+
jsonObject.putIfNotNull("key", null)
35+
assertEquals(0, jsonObject.length())
36+
jsonObject.putIfNotNull("key", "value")
37+
assertEquals(1, jsonObject.length())
38+
assertEquals("value", jsonObject["key"])
39+
}
40+
41+
@Test
42+
fun testTryGetStringNull() {
43+
val jsonObject = JSONObject("""{"key":null}""")
44+
assertNull(jsonObject.tryGetString("key"))
45+
assertNull(jsonObject.tryGetString("another-key"))
46+
}
47+
48+
@Test
49+
fun testTryGetStringNotNull() {
50+
val jsonObject = JSONObject("""{"key":"value"}""")
51+
assertEquals("value", jsonObject.tryGetString("key"))
52+
}
53+
54+
@Test
55+
fun testTryGetLongNull() {
56+
val jsonObject = JSONObject("""{"key":null}""")
57+
assertNull(jsonObject.tryGetLong("key"))
58+
assertNull(jsonObject.tryGetLong("another-key"))
59+
}
60+
61+
@Test
62+
fun testTryGetLongNotNull() {
63+
val jsonObject = JSONObject("""{"key":218728173837192717}""")
64+
assertEquals(218728173837192717, jsonObject.tryGetLong("key"))
65+
}
66+
67+
@Test
68+
fun testTryGetIntNull() {
69+
val jsonObject = JSONObject("""{"key":null}""")
70+
assertNull(jsonObject.tryGetInt("key"))
71+
assertNull(jsonObject.tryGetInt("another-key"))
72+
}
73+
74+
@Test
75+
fun testTryGetIntNotNull() {
76+
val jsonObject = JSONObject("""{"key":3}""")
77+
assertEquals(3, jsonObject.tryGetInt("key"))
78+
}
79+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package mozilla.components.support.ktx.kotlin
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
import org.junit.runner.RunWith
6+
import org.robolectric.RobolectricTestRunner
7+
8+
@RunWith(RobolectricTestRunner::class)
9+
class ListTest {
10+
@Test
11+
fun testToJsonArrayEmptyList() {
12+
val jsonArray = listOf<String>().toJsonArray()
13+
assertEquals(0, jsonArray.length())
14+
}
15+
16+
@Test
17+
fun testToJsonArrayNotEmptyList() {
18+
val list = listOf(1, 2, 3)
19+
val jsonArray = list.toJsonArray()
20+
assertEquals(3, jsonArray.length())
21+
assertEquals(1, jsonArray[0])
22+
assertEquals(2, jsonArray[1])
23+
assertEquals(3, jsonArray[2])
24+
}
25+
}

0 commit comments

Comments
 (0)