@@ -9,53 +9,47 @@ class EncodedFormatTest {
99 @Serializable
1010 data class Payload (val x : Int , val s : String )
1111
12- private val formatNoChecksum: StringFormat = EncodedFormat (Base62 , null )
13- private val formatWithChecksum: StringFormat = EncodedFormat (Base62 , Crc16 .asTransform())
12+ private val formatBare: StringFormat = EncodedFormat (Base62 , null )
13+ private val formatChecksum: StringFormat = EncodedFormat (Base62 , Crc16 .asTransform())
14+ private val formatCompact: StringFormat = EncodedFormat (Base62 , CompactZeros )
15+ private val formatCompactChecksum: StringFormat = EncodedFormat (Base62 , CompactZeros .then(Crc16 .asTransform()))
1416
1517 @Test
16- fun `roundtrip without checksum ` () {
18+ fun `roundtrip without transform ` () {
1719 val value = Payload (42 , " hello" )
18- val encoded =
19- formatNoChecksum.encodeToString(Payload .serializer(), value)
20- val decoded =
21- formatNoChecksum.decodeFromString(Payload .serializer(), encoded)
20+ val encoded = formatBare.encodeToString(Payload .serializer(), value)
21+ val decoded = formatBare.decodeFromString(Payload .serializer(), encoded)
2222 assertEquals(value, decoded)
2323 }
2424
2525 @Test
2626 fun `roundtrip with checksum` () {
2727 val value = Payload (- 5 , " world" )
28- val encoded =
29- formatWithChecksum.encodeToString(Payload .serializer(), value)
30- val decoded =
31- formatWithChecksum.decodeFromString(Payload .serializer(), encoded)
28+ val encoded = formatChecksum.encodeToString(Payload .serializer(), value)
29+ val decoded = formatChecksum.decodeFromString(Payload .serializer(), encoded)
3230 assertEquals(value, decoded)
3331 }
3432
3533 @Test
3634 fun `checksum mismatch throws` () {
3735 val value = Payload (7 , " x" )
38- val encoded =
39- formatWithChecksum.encodeToString(Payload .serializer(), value)
36+ val encoded = formatChecksum.encodeToString(Payload .serializer(), value)
4037 val tampered = encoded.dropLast(1 ) + when (encoded.last()) {
4138 ' A' -> ' B'
4239 else -> ' A'
4340 }
4441 assertFailsWith<IllegalArgumentException > {
45- formatWithChecksum .decodeFromString(Payload .serializer(), tampered)
42+ formatChecksum .decodeFromString(Payload .serializer(), tampered)
4643 }
4744 }
4845
4946 @Test
50- fun `compactZeros roundtrip without checksum ` () {
47+ fun `compactZeros roundtrip` () {
5148 val value = Payload (1 , " hi" )
52- val encoded =
53- formatNoChecksum.encodeToString(Payload .serializer(), value)
54- val decoded =
55- formatNoChecksum.decodeFromString(Payload .serializer(), encoded)
49+ val encoded = formatCompact.encodeToString(Payload .serializer(), value)
50+ val decoded = formatCompact.decodeFromString(Payload .serializer(), encoded)
5651 assertEquals(value, decoded)
57- val uncompressed = EncodedFormat (Base62 , compactZeros = false )
58- .encodeToString(Payload .serializer(), value)
52+ val uncompressed = formatBare.encodeToString(Payload .serializer(), value)
5953 assertTrue(
6054 encoded.length <= uncompressed.length,
6155 " compactZeros ($encoded ) should be <= uncompressed ($uncompressed )"
@@ -65,10 +59,8 @@ class EncodedFormatTest {
6559 @Test
6660 fun `compactZeros roundtrip with checksum` () {
6761 val value = Payload (0 , " zero" )
68- val encoded =
69- formatWithChecksum.encodeToString(Payload .serializer(), value)
70- val decoded =
71- formatWithChecksum.decodeFromString(Payload .serializer(), encoded)
62+ val encoded = formatCompactChecksum.encodeToString(Payload .serializer(), value)
63+ val decoded = formatCompactChecksum.decodeFromString(Payload .serializer(), encoded)
7264 assertEquals(value, decoded)
7365 }
7466
@@ -78,25 +70,32 @@ class EncodedFormatTest {
7870 data class Z (val a : Int , val b : Int )
7971
8072 val value = Z (0 , 0 )
81- val encoded = formatNoChecksum .encodeToString(Z .serializer(), value)
82- val decoded = formatNoChecksum .decodeFromString(Z .serializer(), encoded)
73+ val encoded = formatCompact .encodeToString(Z .serializer(), value)
74+ val decoded = formatCompact .decodeFromString(Z .serializer(), encoded)
8375 assertEquals(value, decoded)
8476 }
8577
8678 @Test
8779 fun `compactZeros checksum mismatch throws` () {
8880 val value = Payload (7 , " x" )
89- val encoded =
90- formatWithChecksum.encodeToString(Payload .serializer(), value)
81+ val encoded = formatCompactChecksum.encodeToString(Payload .serializer(), value)
9182 val tampered = encoded.dropLast(1 ) + when (encoded.last()) {
9283 ' A' -> ' B'
9384 else -> ' A'
9485 }
9586 assertFailsWith<IllegalArgumentException > {
96- formatWithChecksum .decodeFromString(Payload .serializer(), tampered)
87+ formatCompactChecksum .decodeFromString(Payload .serializer(), tampered)
9788 }
9889 }
9990
91+ @Test
92+ fun `compactZeros no overhead when no leading zeros` () {
93+ val value = Payload (- 1 , " a" )
94+ val compact = formatCompact.encodeToString(Payload .serializer(), value)
95+ val bare = formatBare.encodeToString(Payload .serializer(), value)
96+ assertEquals(bare, compact)
97+ }
98+
10099 @Test
101100 fun `builder configures custom properties successfully` () {
102101 val value = Payload (99 , " builder validation" )
@@ -110,14 +109,25 @@ class EncodedFormatTest {
110109 val encoded = customFormat.encodeToString(Payload .serializer(), value)
111110
112111 assertTrue(encoded.isNotEmpty())
113- val decoded =
114- customFormat.decodeFromString(Payload .serializer(), encoded)
112+ val decoded = customFormat.decodeFromString(Payload .serializer(), encoded)
115113 assertEquals(value, decoded)
116114
117- val tampered =
118- encoded.dropLast(1 ) + if (encoded.last() == ' u' ) " t" else " u"
115+ val tampered = encoded.dropLast(1 ) + if (encoded.last() == ' u' ) " t" else " u"
119116 assertFailsWith<IllegalArgumentException > {
120117 customFormat.decodeFromString(Payload .serializer(), tampered)
121118 }
122119 }
120+
121+ @Test
122+ fun `builder then composition roundtrip` () {
123+ val value = Payload (0 , " composed" )
124+
125+ val format = EncodedFormat {
126+ transform = CompactZeros .then(Crc16 .asTransform())
127+ }
128+
129+ val encoded = format.encodeToString(Payload .serializer(), value)
130+ val decoded = format.decodeFromString(Payload .serializer(), encoded)
131+ assertEquals(value, decoded)
132+ }
123133}
0 commit comments