Skip to content

Commit bf7b4a2

Browse files
stainless-botStainless Bot
authored andcommitted
feat(client): add QueryParams class
chore: unknown commit message
1 parent 339e93c commit bf7b4a2

File tree

2 files changed

+298
-0
lines changed

2 files changed

+298
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.openai.core.http
2+
3+
import com.openai.core.toImmutable
4+
5+
class QueryParams
6+
private constructor(
7+
private val map: Map<String, List<String>>,
8+
@get:JvmName("size") val size: Int
9+
) {
10+
11+
fun isEmpty(): Boolean = map.isEmpty()
12+
13+
fun keys(): Set<String> = map.keys
14+
15+
fun values(key: String): List<String> = map[key].orEmpty()
16+
17+
fun toBuilder(): Builder = Builder().putAll(map)
18+
19+
companion object {
20+
21+
@JvmStatic fun builder() = Builder()
22+
}
23+
24+
class Builder {
25+
26+
private val map: MutableMap<String, MutableList<String>> = mutableMapOf()
27+
private var size: Int = 0
28+
29+
fun put(key: String, value: String) = apply {
30+
map.getOrPut(key) { mutableListOf() }.add(value)
31+
size++
32+
}
33+
34+
fun put(key: String, values: Iterable<String>) = apply { values.forEach { put(key, it) } }
35+
36+
fun putAll(queryParams: Map<String, Iterable<String>>) = apply {
37+
queryParams.forEach(::put)
38+
}
39+
40+
fun putAll(queryParams: QueryParams) = apply {
41+
queryParams.keys().forEach { put(it, queryParams.values(it)) }
42+
}
43+
44+
fun replace(key: String, value: String) = apply {
45+
remove(key)
46+
put(key, value)
47+
}
48+
49+
fun replace(key: String, values: Iterable<String>) = apply {
50+
remove(key)
51+
put(key, values)
52+
}
53+
54+
fun replaceAll(queryParams: Map<String, Iterable<String>>) = apply {
55+
queryParams.forEach(::replace)
56+
}
57+
58+
fun replaceAll(queryParams: QueryParams) = apply {
59+
queryParams.keys().forEach { replace(it, queryParams.values(it)) }
60+
}
61+
62+
fun remove(key: String) = apply { size -= map.remove(key).orEmpty().size }
63+
64+
fun removeAll(keys: Set<String>) = apply { keys.forEach(::remove) }
65+
66+
fun clear() = apply {
67+
map.clear()
68+
size = 0
69+
}
70+
71+
fun build() =
72+
QueryParams(map.mapValues { (_, values) -> values.toImmutable() }.toImmutable(), size)
73+
}
74+
75+
override fun hashCode(): Int = map.hashCode()
76+
77+
override fun equals(other: Any?): Boolean {
78+
if (this === other) {
79+
return true
80+
}
81+
82+
return other is QueryParams && map == other.map
83+
}
84+
85+
override fun toString(): String = "QueryParams{map=$map}"
86+
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package com.openai.core.http
2+
3+
import org.assertj.core.api.Assertions.assertThat
4+
import org.assertj.core.api.Assertions.catchThrowable
5+
import org.assertj.core.api.Assumptions.assumeThat
6+
import org.junit.jupiter.params.ParameterizedTest
7+
import org.junit.jupiter.params.provider.EnumSource
8+
9+
internal class QueryParamsTest {
10+
11+
enum class TestCase(
12+
val queryParams: QueryParams,
13+
val expectedMap: Map<String, List<String>>,
14+
val expectedSize: Int
15+
) {
16+
EMPTY(QueryParams.builder().build(), expectedMap = mapOf(), expectedSize = 0),
17+
PUT_ONE(
18+
QueryParams.builder().put("key", "value").build(),
19+
expectedMap = mapOf("key" to listOf("value")),
20+
expectedSize = 1
21+
),
22+
PUT_MULTIPLE(
23+
QueryParams.builder().put("key", listOf("value1", "value2")).build(),
24+
expectedMap = mapOf("key" to listOf("value1", "value2")),
25+
expectedSize = 2
26+
),
27+
MULTIPLE_PUT(
28+
QueryParams.builder().put("key1", "value").put("key2", "value").build(),
29+
expectedMap = mapOf("key1" to listOf("value"), "key2" to listOf("value")),
30+
expectedSize = 2
31+
),
32+
MULTIPLE_PUT_SAME_NAME(
33+
QueryParams.builder().put("key", "value1").put("key", "value2").build(),
34+
expectedMap = mapOf("key" to listOf("value1", "value2")),
35+
expectedSize = 2
36+
),
37+
MULTIPLE_PUT_MULTIPLE(
38+
QueryParams.builder()
39+
.put("key", listOf("value1", "value2"))
40+
.put("key", listOf("value1", "value2"))
41+
.build(),
42+
expectedMap = mapOf("key" to listOf("value1", "value2", "value1", "value2")),
43+
expectedSize = 4
44+
),
45+
PUT_ALL_MAP(
46+
QueryParams.builder()
47+
.putAll(
48+
mapOf(
49+
"key1" to listOf("value1", "value2"),
50+
"key2" to listOf("value1", "value2")
51+
)
52+
)
53+
.build(),
54+
expectedMap =
55+
mapOf("key1" to listOf("value1", "value2"), "key2" to listOf("value1", "value2")),
56+
expectedSize = 4
57+
),
58+
PUT_ALL_HEADERS(
59+
QueryParams.builder().putAll(QueryParams.builder().put("key", "value").build()).build(),
60+
expectedMap = mapOf("key" to listOf("value")),
61+
expectedSize = 1
62+
),
63+
REMOVE_ABSENT(
64+
QueryParams.builder().remove("key").build(),
65+
expectedMap = mapOf(),
66+
expectedSize = 0
67+
),
68+
REMOVE_PRESENT_ONE(
69+
QueryParams.builder().put("key", "value").remove("key").build(),
70+
expectedMap = mapOf(),
71+
expectedSize = 0
72+
),
73+
REMOVE_PRESENT_MULTIPLE(
74+
QueryParams.builder().put("key", listOf("value1", "value2")).remove("key").build(),
75+
expectedMap = mapOf(),
76+
expectedSize = 0
77+
),
78+
REMOVE_ALL(
79+
QueryParams.builder()
80+
.put("key1", "value")
81+
.put("key3", "value")
82+
.removeAll(setOf("key1", "key2", "key3"))
83+
.build(),
84+
expectedMap = mapOf(),
85+
expectedSize = 0
86+
),
87+
CLEAR(
88+
QueryParams.builder().put("key1", "value").put("key2", "value").clear().build(),
89+
expectedMap = mapOf(),
90+
expectedSize = 0
91+
),
92+
REPLACE_ONE_ABSENT(
93+
QueryParams.builder().replace("key", "value").build(),
94+
expectedMap = mapOf("key" to listOf("value")),
95+
expectedSize = 1
96+
),
97+
REPLACE_ONE_PRESENT_ONE(
98+
QueryParams.builder().put("key", "value1").replace("key", "value2").build(),
99+
expectedMap = mapOf("key" to listOf("value2")),
100+
expectedSize = 1
101+
),
102+
REPLACE_ONE_PRESENT_MULTIPLE(
103+
QueryParams.builder()
104+
.put("key", listOf("value1", "value2"))
105+
.replace("key", "value3")
106+
.build(),
107+
expectedMap = mapOf("key" to listOf("value3")),
108+
expectedSize = 1
109+
),
110+
REPLACE_MULTIPLE_ABSENT(
111+
QueryParams.builder().replace("key", listOf("value1", "value2")).build(),
112+
expectedMap = mapOf("key" to listOf("value1", "value2")),
113+
expectedSize = 2
114+
),
115+
REPLACE_MULTIPLE_PRESENT_ONE(
116+
QueryParams.builder()
117+
.put("key", "value1")
118+
.replace("key", listOf("value2", "value3"))
119+
.build(),
120+
expectedMap = mapOf("key" to listOf("value2", "value3")),
121+
expectedSize = 2
122+
),
123+
REPLACE_MULTIPLE_PRESENT_MULTIPLE(
124+
QueryParams.builder()
125+
.put("key", listOf("value1", "value2"))
126+
.replace("key", listOf("value3", "value4"))
127+
.build(),
128+
expectedMap = mapOf("key" to listOf("value3", "value4")),
129+
expectedSize = 2
130+
),
131+
REPLACE_ALL_MAP(
132+
QueryParams.builder()
133+
.put("key1", "value1")
134+
.put("key2", "value1")
135+
.put("key3", "value1")
136+
.replaceAll(mapOf("key1" to listOf("value2"), "key3" to listOf("value2")))
137+
.build(),
138+
expectedMap =
139+
mapOf(
140+
"key1" to listOf("value2"),
141+
"key2" to listOf("value1"),
142+
"key3" to listOf("value2")
143+
),
144+
expectedSize = 3
145+
),
146+
REPLACE_ALL_HEADERS(
147+
QueryParams.builder()
148+
.put("key1", "value1")
149+
.put("key2", "value1")
150+
.put("key3", "value1")
151+
.replaceAll(
152+
QueryParams.builder().put("key1", "value2").put("key3", "value2").build()
153+
)
154+
.build(),
155+
expectedMap =
156+
mapOf(
157+
"key1" to listOf("value2"),
158+
"key2" to listOf("value1"),
159+
"key3" to listOf("value2")
160+
),
161+
expectedSize = 3
162+
)
163+
}
164+
165+
@ParameterizedTest
166+
@EnumSource
167+
fun keysAndValues(testCase: TestCase) {
168+
val map = mutableMapOf<String, List<String>>()
169+
val queryParams = testCase.queryParams
170+
queryParams.keys().forEach { key -> map[key] = queryParams.values(key) }
171+
172+
assertThat(map).isEqualTo(testCase.expectedMap)
173+
}
174+
175+
@ParameterizedTest
176+
@EnumSource
177+
fun size(testCase: TestCase) {
178+
val size = testCase.queryParams.size
179+
180+
assertThat(size).isEqualTo(testCase.expectedSize)
181+
}
182+
183+
@ParameterizedTest
184+
@EnumSource
185+
fun keysAreImmutable(testCase: TestCase) {
186+
val queryParams = testCase.queryParams
187+
val queryParamKeysCopy = queryParams.keys().toSet()
188+
189+
val throwable = catchThrowable {
190+
(queryParams.keys() as MutableSet<String>).add("another key")
191+
}
192+
193+
assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java)
194+
assertThat(queryParams.keys()).isEqualTo(queryParamKeysCopy)
195+
}
196+
197+
@ParameterizedTest
198+
@EnumSource
199+
fun valuesAreImmutable(testCase: TestCase) {
200+
val queryParams = testCase.queryParams
201+
assumeThat(queryParams.size).isNotEqualTo(0)
202+
val key = queryParams.keys().first()
203+
val queryParamValuesCopy = queryParams.values(key).toList()
204+
205+
val throwable = catchThrowable {
206+
(queryParams.values(key) as MutableList<String>).add("another value")
207+
}
208+
209+
assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java)
210+
assertThat(queryParams.values(key)).isEqualTo(queryParamValuesCopy)
211+
}
212+
}

0 commit comments

Comments
 (0)