@@ -94,7 +94,7 @@ void testSerializeDeserializeWithComplexRouteKeys() throws IOException {
9494    void  testDeserializeWithWrongVersion () {
9595        final  DemultiplexingSinkStateSerializer <String > serializer  =
9696                new  DemultiplexingSinkStateSerializer <>();
97-         final  byte [] serialized  = new  byte [] {1 , 2 , 3 , 4 };  // Some dummy data 
97+         final  byte [] serialized  = new  byte [] {1 , 2 , 3 , 4 };
9898
9999        assertThatThrownBy (() -> serializer .deserialize (999 , serialized ))
100100                .isInstanceOf (IOException .class )
@@ -109,6 +109,158 @@ void testGetVersion() {
109109        assertThat (serializer .getVersion ()).isEqualTo (1 );
110110    }
111111
112+     @ Test 
113+     void  testSetRouteStateWithNullState () {
114+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
115+ 
116+         // Add a route first 
117+         state .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
118+         assertThat (state .getRoutes ()).containsExactly ("route1" );
119+ 
120+         // Setting null state should remove the route 
121+         state .setRouteState ("route1" , null );
122+         assertThat (state .getRoutes ()).isEmpty ();
123+         assertThat (state .getRouteState ("route1" )).isNull ();
124+     }
125+ 
126+     @ Test 
127+     void  testSetRouteStateWithNullStateOnNonExistentRoute () {
128+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
129+ 
130+         // Setting null state on non-existent route should be no-op 
131+         state .setRouteState ("nonExistent" , null );
132+         assertThat (state .getRoutes ()).isEmpty ();
133+     }
134+ 
135+     @ Test 
136+     void  testEqualsWithSameInstance () {
137+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
138+         state .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
139+ 
140+         assertThat (state .equals (state )).isTrue ();
141+     }
142+ 
143+     @ Test 
144+     void  testEqualsWithNull () {
145+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
146+ 
147+         assertThat (state .equals (null )).isFalse ();
148+     }
149+ 
150+     @ Test 
151+     void  testEqualsWithDifferentClass () {
152+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
153+ 
154+         assertThat (state .equals ("not a state" )).isFalse ();
155+     }
156+ 
157+     @ Test 
158+     void  testEqualsWithDifferentRouteSizes () {
159+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
160+         state1 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
161+ 
162+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
163+         state2 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
164+         state2 .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
165+ 
166+         assertThat (state1 .equals (state2 )).isFalse ();
167+         assertThat (state2 .equals (state1 )).isFalse ();
168+     }
169+ 
170+     @ Test 
171+     void  testEqualsWithSameRoutesButDifferentStates () {
172+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
173+         state1 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
174+ 
175+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
176+         state2 .setRouteState ("route1" , new  byte [] {4 , 5 , 6 });
177+ 
178+         assertThat (state1 .equals (state2 )).isFalse ();
179+     }
180+ 
181+     @ Test 
182+     void  testEqualsWithSameRoutesAndStates () {
183+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
184+         state1 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
185+         state1 .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
186+ 
187+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
188+         state2 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
189+         state2 .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
190+ 
191+         assertThat (state1 .equals (state2 )).isTrue ();
192+         assertThat (state2 .equals (state1 )).isTrue ();
193+     }
194+ 
195+     @ Test 
196+     void  testHashCodeConsistency () {
197+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
198+         state1 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
199+         state1 .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
200+ 
201+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
202+         state2 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
203+         state2 .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
204+ 
205+         // Equal objects must have equal hash codes 
206+         assertThat (state1 .equals (state2 )).isTrue ();
207+         assertThat (state1 .hashCode ()).isEqualTo (state2 .hashCode ());
208+     }
209+ 
210+     @ Test 
211+     void  testHashCodeWithEmptyState () {
212+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
213+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
214+ 
215+         assertThat (state1 .hashCode ()).isEqualTo (state2 .hashCode ());
216+     }
217+ 
218+     @ Test 
219+     void  testHashCodeWithDifferentStates () {
220+         DemultiplexingSinkState <String > state1  = new  DemultiplexingSinkState <>();
221+         state1 .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
222+ 
223+         DemultiplexingSinkState <String > state2  = new  DemultiplexingSinkState <>();
224+         state2 .setRouteState ("route1" , new  byte [] {4 , 5 , 6 });
225+ 
226+         // Different objects should typically have different hash codes 
227+         assertThat (state1 .hashCode ()).isNotEqualTo (state2 .hashCode ());
228+     }
229+ 
230+     @ Test 
231+     void  testToStringWithEmptyState () {
232+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
233+ 
234+         String  toString  = state .toString ();
235+         assertThat (toString ).contains ("DemultiplexingSinkState" );
236+         assertThat (toString ).contains ("routeCount=0" );
237+         assertThat (toString ).contains ("routes=[]" );
238+     }
239+ 
240+     @ Test 
241+     void  testToStringWithSingleRoute () {
242+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
243+         state .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
244+ 
245+         String  toString  = state .toString ();
246+         assertThat (toString ).contains ("DemultiplexingSinkState" );
247+         assertThat (toString ).contains ("routeCount=1" );
248+         assertThat (toString ).contains ("route1" );
249+     }
250+ 
251+     @ Test 
252+     void  testToStringWithMultipleRoutes () {
253+         DemultiplexingSinkState <String > state  = new  DemultiplexingSinkState <>();
254+         state .setRouteState ("route1" , new  byte [] {1 , 2 , 3 });
255+         state .setRouteState ("route2" , new  byte [] {4 , 5 , 6 });
256+ 
257+         String  toString  = state .toString ();
258+         assertThat (toString ).contains ("DemultiplexingSinkState" );
259+         assertThat (toString ).contains ("routeCount=2" );
260+         assertThat (toString ).contains ("route1" );
261+         assertThat (toString ).contains ("route2" );
262+     }
263+ 
112264    /** A complex route key for testing serialization. */ 
113265    private  static  class  ComplexRouteKey  implements  java .io .Serializable  {
114266        private  static  final  long  serialVersionUID  = 1L ;
0 commit comments