Skip to content

Commit cb4a27b

Browse files
committed
SerializationTestData.kt: re-written to use Arb
1 parent 7c1c1ee commit cb4a27b

File tree

1 file changed

+127
-192
lines changed

1 file changed

+127
-192
lines changed

firebase-dataconnect/src/test/kotlin/com/google/firebase/dataconnect/SerializationTestData.kt

Lines changed: 127 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,15 @@
1616

1717
package com.google.firebase.dataconnect
1818

19-
import kotlin.math.PI
20-
import kotlin.math.abs
19+
import io.kotest.property.Arb
20+
import io.kotest.property.arbitrary.*
21+
import io.kotest.property.arbitrary.arbitrary
22+
import io.kotest.property.arbitrary.boolean
23+
import io.kotest.property.arbitrary.byte
24+
import io.kotest.property.arbitrary.char
25+
import io.kotest.property.arbitrary.int
26+
import io.kotest.property.arbitrary.orNull
27+
import io.kotest.property.arbitrary.string
2128
import kotlinx.serialization.Serializable
2229

2330
object SerializationTestData {
@@ -26,56 +33,39 @@ object SerializationTestData {
2633
A,
2734
B,
2835
C,
29-
D,
36+
D
3037
}
3138

3239
@Serializable @JvmInline value class TestStringValueClass(val a: String)
3340

3441
@Serializable @JvmInline value class TestIntValueClass(val a: Int)
3542

36-
@Serializable
37-
data class TestData1(val s: String, val i: Int) {
38-
companion object {
39-
fun newInstance(seed: String = "abcdef01234567890"): TestData1 =
40-
seed.run { TestData1(s = seededString("s"), i = seededInt("i")) }
41-
}
42-
}
43+
@Serializable data class TestData1(val s: String, val i: Int)
4344

44-
@Serializable
45-
data class TestData2(val td: TestData1, val ntd: TestData1?, val noll: TestData1?) {
46-
companion object {
47-
fun newInstance(seed: String = "abcdef01234567890"): TestData2 =
48-
TestData2(
49-
td = TestData1.newInstance(seed + "td"),
50-
ntd = TestData1.newInstance(seed + "ntd"),
51-
noll = null
52-
)
53-
}
54-
}
45+
fun Arb.Companion.serializationTestData1(
46+
s: Arb<String> = Arb.string(),
47+
i: Arb<Int> = Arb.int()
48+
): Arb<TestData1> = arbitrary { TestData1(s.bind(), i.bind()) }
49+
50+
@Serializable data class TestData2(val td: TestData1, val ntd: TestData1?)
51+
52+
fun Arb.Companion.serializationTestData2(
53+
testData1: Arb<TestData1> = Arb.serializationTestData1()
54+
): Arb<TestData2> = arbitrary { TestData2(testData1.bind(), testData1.orNull(0.33).bind()) }
5555

5656
@Serializable
5757
data class AllTheTypes(
5858
val boolean: Boolean,
5959
val byte: Byte,
6060
val char: Char,
6161
val double: Double,
62-
val doubleMinValue: Double,
63-
val doubleMaxValue: Double,
64-
val doubleNegativeInfinity: Double,
65-
val doublePositiveInfinity: Double,
66-
val doubleNaN: Double,
6762
val enum: TestEnum,
6863
val float: Float,
69-
val floatMinValue: Float,
70-
val floatMaxValue: Float,
71-
val floatNegativeInfinity: Float,
72-
val floatPositiveInfinity: Float,
73-
val floatNaN: Float,
7464
val inlineString: TestStringValueClass,
7565
val inlineInt: TestIntValueClass,
7666
val int: Int,
7767
val long: Long,
78-
val noll: Unit?,
68+
val unit: Unit,
7969
val short: Short,
8070
val string: String,
8171
val testData: TestData2,
@@ -92,19 +82,6 @@ object SerializationTestData {
9282
val shortList: List<Short>,
9383
val stringList: List<String>,
9484
val testDataList: List<TestData2>,
95-
val booleanNull: Boolean?,
96-
val byteNull: Byte?,
97-
val charNull: Char?,
98-
val doubleNull: Double?,
99-
val enumNull: TestEnum?,
100-
val floatNull: Float?,
101-
val inlineStringNull: TestStringValueClass?,
102-
val inlineIntNull: TestIntValueClass?,
103-
val intNull: Int?,
104-
val longNull: Long?,
105-
val shortNull: Short?,
106-
val stringNull: String?,
107-
val testDataNull: TestData2?,
10885
val booleanNullable: Boolean?,
10986
val byteNullable: Byte?,
11087
val charNullable: Char?,
@@ -132,157 +109,115 @@ object SerializationTestData {
132109
val stringNullableList: List<String?>,
133110
val testDataNullableList: List<TestData2?>,
134111
val nested: AllTheTypes?,
135-
val unit: Unit,
136-
val nullUnit: Unit?,
137112
val nullableUnit: Unit?,
138113
val listOfUnit: List<Unit>,
139114
val listOfNullableUnit: List<Unit?>,
140-
) {
141-
companion object {
115+
)
142116

143-
fun newInstance(seed: String = "abcdef01234567890", nesting: Int = 1): AllTheTypes =
144-
seed.run {
145-
AllTheTypes(
146-
boolean = seededBoolean("plain"),
147-
byte = seededByte("plain"),
148-
char = seededChar("plain"),
149-
double = seededDouble("plain"),
150-
doubleMinValue = Double.MIN_VALUE,
151-
doubleMaxValue = Double.MAX_VALUE,
152-
doubleNegativeInfinity = Double.POSITIVE_INFINITY,
153-
doublePositiveInfinity = Double.NEGATIVE_INFINITY,
154-
doubleNaN = Double.NaN,
155-
enum = seededEnum("plain"),
156-
float = seededFloat("plain"),
157-
floatMinValue = Float.MIN_VALUE,
158-
floatMaxValue = Float.MAX_VALUE,
159-
floatNegativeInfinity = Float.POSITIVE_INFINITY,
160-
floatPositiveInfinity = Float.NEGATIVE_INFINITY,
161-
floatNaN = Float.NaN,
162-
inlineString = TestStringValueClass(seededString("value")),
163-
inlineInt = TestIntValueClass(seededInt("value")),
164-
int = seededInt("plain"),
165-
long = seededLong("plain"),
166-
noll = null,
167-
short = seededShort("plain"),
168-
string = seededString("plain"),
169-
testData = TestData2.newInstance(seededString("plain")),
170-
booleanList = listOf(seededBoolean("list0"), seededBoolean("list1")),
171-
byteList = listOf(seededByte("list0"), seededByte("list1")),
172-
charList = listOf(seededChar("list0"), seededChar("list1")),
173-
doubleList = listOf(seededDouble("list0"), seededDouble("list1")),
174-
enumList = listOf(seededEnum("list0"), seededEnum("list1")),
175-
floatList = listOf(seededFloat("list0"), seededFloat("list1")),
176-
inlineStringList =
177-
listOf(
178-
TestStringValueClass(seededString("list0")),
179-
TestStringValueClass(seededString("list1"))
180-
),
181-
inlineIntList =
182-
listOf(TestIntValueClass(seededInt("list0")), TestIntValueClass(seededInt("list1"))),
183-
intList = listOf(seededInt("list0"), seededInt("list1")),
184-
longList = listOf(seededLong("list0"), seededLong("list1")),
185-
shortList = listOf(seededShort("list0"), seededShort("list1")),
186-
stringList = listOf(seededString("list0"), seededString("list1")),
187-
testDataList =
188-
listOf(
189-
TestData2.newInstance(seededString("list0")),
190-
TestData2.newInstance(seededString("list1"))
191-
),
192-
booleanNull = null,
193-
byteNull = null,
194-
charNull = null,
195-
doubleNull = null,
196-
enumNull = null,
197-
floatNull = null,
198-
inlineStringNull = null,
199-
inlineIntNull = null,
200-
intNull = null,
201-
longNull = null,
202-
shortNull = null,
203-
stringNull = null,
204-
testDataNull = null,
205-
booleanNullable = seededBoolean("nullable"),
206-
byteNullable = seededByte("nullable"),
207-
charNullable = seededChar("nullable"),
208-
doubleNullable = seededDouble("nullable"),
209-
enumNullable = seededEnum("nullable"),
210-
floatNullable = seededFloat("nullable"),
211-
inlineStringNullable = TestStringValueClass(seededString("nullable")),
212-
inlineIntNullable = TestIntValueClass(seededInt("nullable")),
213-
intNullable = seededInt("nullable"),
214-
longNullable = seededLong("nullable"),
215-
shortNullable = seededShort("nullable"),
216-
stringNullable = seededString("nullable"),
217-
testDataNullable = TestData2.newInstance(seededString("nullable")),
218-
booleanNullableList = listOf(seededBoolean("nlist0"), seededBoolean("nlist1"), null),
219-
byteNullableList = listOf(seededByte("nlist0"), seededByte("nlist1"), null),
220-
charNullableList = listOf(seededChar("nlist0"), seededChar("nlist1"), null),
221-
doubleNullableList = listOf(seededDouble("nlist0"), seededDouble("nlist1"), null),
222-
enumNullableList = listOf(seededEnum("nlist0"), seededEnum("nlist1"), null),
223-
floatNullableList = listOf(seededFloat("nlist0"), seededFloat("nlist1"), null),
224-
inlineStringNullableList =
225-
listOf(
226-
TestStringValueClass(seededString("nlist0")),
227-
TestStringValueClass(seededString("nlist1")),
228-
null
229-
),
230-
inlineIntNullableList =
231-
listOf(
232-
TestIntValueClass(seededInt("nlist0")),
233-
TestIntValueClass(seededInt("nlist1")),
234-
null
235-
),
236-
intNullableList = listOf(seededInt("nlist0"), seededInt("nlist1"), null),
237-
longNullableList = listOf(seededLong("nlist0"), seededLong("nlist1"), null),
238-
shortNullableList = listOf(seededShort("nlist0"), seededShort("nlist1"), null),
239-
stringNullableList = listOf(seededString("nlist0"), seededString("nlist1"), null),
240-
testDataNullableList =
241-
listOf(
242-
TestData2.newInstance(seededString("nlist0")),
243-
TestData2.newInstance(seededString("nlist1"))
244-
),
245-
nested = if (nesting <= 0) null else newInstance("${seed}nest${nesting}", nesting - 1),
246-
unit = Unit,
247-
nullUnit = null,
248-
nullableUnit = Unit,
249-
listOfUnit = listOf(Unit, Unit),
250-
listOfNullableUnit = listOf(Unit, null, Unit, null),
117+
fun Arb.Companion.serializationTestDataAllTypes(
118+
boolean: Arb<Boolean> = Arb.boolean(),
119+
byte: Arb<Byte> = Arb.byte(),
120+
char: Arb<Char> = Arb.char(),
121+
short: Arb<Short> = Arb.short(),
122+
int: Arb<Int> = Arb.int(),
123+
long: Arb<Long> = Arb.long(),
124+
float: Arb<Float> = Arb.float(),
125+
double: Arb<Double> = Arb.double(),
126+
string: Arb<String> = Arb.string(),
127+
enum: Arb<TestEnum> = Arb.enum<TestEnum>(),
128+
testData2: Arb<TestData2> = Arb.serializationTestData2(),
129+
listSize: Arb<IntRange> = Arb.intRange(0..20),
130+
): Arb<AllTheTypes> = arbitrary {
131+
val inlineString: Arb<TestStringValueClass> = arbitrary { TestStringValueClass(string.bind()) }
132+
val inlineInt: Arb<TestIntValueClass> = arbitrary { TestIntValueClass(int.bind()) }
133+
val nullProbability = 0.33
134+
135+
AllTheTypes(
136+
boolean = boolean.bind(),
137+
byte = byte.bind(),
138+
char = char.bind(),
139+
double = double.bind(),
140+
enum = enum.bind(),
141+
float = float.bind(),
142+
inlineString = inlineString.bind(),
143+
inlineInt = inlineInt.bind(),
144+
int = int.bind(),
145+
long = long.bind(),
146+
unit = Unit,
147+
short = short.bind(),
148+
string = string.bind(),
149+
testData = testData2.bind(),
150+
booleanList = Arb.list(boolean, listSize).bind(),
151+
byteList = Arb.list(byte, listSize).bind(),
152+
charList = Arb.list(char, listSize).bind(),
153+
doubleList = Arb.list(double, listSize).bind(),
154+
enumList = Arb.list(enum, listSize).bind(),
155+
floatList = Arb.list(float, listSize).bind(),
156+
inlineStringList = Arb.list(inlineString, listSize).bind(),
157+
inlineIntList = Arb.list(inlineInt, listSize).bind(),
158+
intList = Arb.list(int, listSize).bind(),
159+
longList = Arb.list(long, listSize).bind(),
160+
shortList = Arb.list(short, listSize).bind(),
161+
stringList = Arb.list(string, listSize).bind(),
162+
testDataList = Arb.list(testData2, listSize).bind(),
163+
booleanNullable = boolean.orNull(nullProbability).bind(),
164+
byteNullable = byte.orNull(nullProbability).bind(),
165+
charNullable = char.orNull(nullProbability).bind(),
166+
doubleNullable = double.orNull(nullProbability).bind(),
167+
enumNullable = enum.orNull(nullProbability).bind(),
168+
floatNullable = float.orNull(nullProbability).bind(),
169+
inlineStringNullable = inlineString.orNull(nullProbability).bind(),
170+
inlineIntNullable = inlineInt.orNull(nullProbability).bind(),
171+
intNullable = int.orNull(nullProbability).bind(),
172+
longNullable = long.orNull(nullProbability).bind(),
173+
shortNullable = short.orNull(nullProbability).bind(),
174+
stringNullable = string.orNull(nullProbability).bind(),
175+
testDataNullable = testData2.orNull(nullProbability).bind(),
176+
booleanNullableList = Arb.list(boolean.orNull(nullProbability), listSize).bind(),
177+
byteNullableList = Arb.list(byte.orNull(nullProbability), listSize).bind(),
178+
charNullableList = Arb.list(char.orNull(nullProbability), listSize).bind(),
179+
doubleNullableList = Arb.list(double.orNull(nullProbability), listSize).bind(),
180+
enumNullableList = Arb.list(enum.orNull(nullProbability), listSize).bind(),
181+
floatNullableList = Arb.list(float.orNull(nullProbability), listSize).bind(),
182+
inlineStringNullableList = Arb.list(inlineString.orNull(nullProbability), listSize).bind(),
183+
inlineIntNullableList = Arb.list(inlineInt.orNull(nullProbability), listSize).bind(),
184+
intNullableList = Arb.list(int.orNull(nullProbability), listSize).bind(),
185+
longNullableList = Arb.list(long.orNull(nullProbability), listSize).bind(),
186+
shortNullableList = Arb.list(short.orNull(nullProbability), listSize).bind(),
187+
stringNullableList = Arb.list(string.orNull(nullProbability), listSize).bind(),
188+
testDataNullableList = Arb.list(testData2.orNull(nullProbability), listSize).bind(),
189+
nested =
190+
Arb.serializationTestDataAllTypes(
191+
boolean = boolean,
192+
byte = byte,
193+
char = char,
194+
short = short,
195+
int = int,
196+
long = long,
197+
float = float,
198+
double = double,
199+
string = string,
200+
enum = enum,
201+
testData2 = testData2,
202+
listSize = listSize,
251203
)
252-
}
253-
}
204+
.orNull(nullProbability = 0.15)
205+
.bind(),
206+
nullableUnit = Arb.constant(Unit).orNull(nullProbability).bind(),
207+
listOfUnit = Arb.list(Arb.constant(Unit), listSize).bind(),
208+
listOfNullableUnit = Arb.list(Arb.constant(Unit).orNull(nullProbability), listSize).bind(),
209+
)
254210
}
255-
}
256211

257-
/**
258-
* Creates and returns a new instance with the exact same property values but with all lists of
259-
* [Unit] to be empty. This may be useful if testing an encoder/decoder that does not support
260-
* [kotlinx.serialization.descriptors.StructureKind.OBJECT] in lists.
261-
*/
262-
fun SerializationTestData.AllTheTypes.withEmptyUnitLists(): SerializationTestData.AllTheTypes =
263-
copy(
264-
listOfUnit = emptyList(),
265-
listOfNullableUnit = emptyList(),
266-
nested = nested?.withEmptyUnitLists()
267-
)
268-
269-
private fun String.seededBoolean(id: String): Boolean = seededInt(id) % 2 == 0
270-
271-
private fun String.seededByte(id: String): Byte = seededInt(id).toByte()
272-
273-
private fun String.seededChar(id: String): Char = get(abs(id.hashCode()) % length)
274-
275-
private fun String.seededDouble(id: String): Double = seededLong(id).toDouble() / PI
276-
277-
private fun String.seededEnum(id: String): SerializationTestData.TestEnum =
278-
SerializationTestData.TestEnum.values().let { it[abs(seededInt(id)) % it.size] }
279-
280-
private fun String.seededFloat(id: String): Float = (seededInt(id).toFloat() / PI.toFloat())
281-
282-
private fun String.seededInt(id: String): Int = (hashCode() * id.hashCode())
283-
284-
private fun String.seededLong(id: String): Long = (hashCode().toLong() * id.hashCode().toLong())
285-
286-
private fun String.seededShort(id: String): Short = seededInt(id).toShort()
287-
288-
private fun String.seededString(id: String): String = "${this}_${id}"
212+
/**
213+
* Creates and returns a new instance with the exact same property values but with all lists of
214+
* [Unit] to be empty. This may be useful if testing an encoder/decoder that does not support
215+
* [kotlinx.serialization.descriptors.StructureKind.OBJECT] in lists.
216+
*/
217+
fun AllTheTypes.withEmptyUnitLists(): SerializationTestData.AllTheTypes =
218+
copy(
219+
listOfUnit = emptyList(),
220+
listOfNullableUnit = emptyList(),
221+
nested = nested?.withEmptyUnitLists()
222+
)
223+
}

0 commit comments

Comments
 (0)