@@ -244,6 +244,74 @@ describe("World", () => {
244244 expect ( world . exists ( b ) ) . toBe ( false ) ;
245245 } ) ;
246246
247+ it ( "should prevent archetype fragmentation with dontFragment relations" , ( ) => {
248+ const world = new World ( ) ;
249+ const entity1 = world . new ( ) ;
250+ const entity2 = world . new ( ) ;
251+ const target1 = world . new ( ) ;
252+ const target2 = world . new ( ) ;
253+
254+ // Create Follows component with dontFragment option
255+ const Follows = component < { strength : number } > ( { dontFragment : true } ) ;
256+
257+ const followsTarget1 = relation ( Follows , target1 ) ;
258+ const followsTarget2 = relation ( Follows , target2 ) ;
259+
260+ // Add different relations to different entities
261+ world . set ( entity1 , followsTarget1 , { strength : 1 } ) ;
262+ world . set ( entity2 , followsTarget2 , { strength : 2 } ) ;
263+ world . sync ( ) ;
264+
265+ // Both entities should exist and have their relations
266+ expect ( world . has ( entity1 , followsTarget1 ) ) . toBe ( true ) ;
267+ expect ( world . has ( entity2 , followsTarget2 ) ) . toBe ( true ) ;
268+
269+ // They should be in the same archetype despite having different relation targets
270+ // (this is the key behavior of dontFragment)
271+ const archetype1 = ( world as any ) . entityToArchetype . get ( entity1 ) ;
272+ const archetype2 = ( world as any ) . entityToArchetype . get ( entity2 ) ;
273+ expect ( archetype1 ) . toBe ( archetype2 ) ;
274+
275+ // Verify the wildcard marker is present
276+ const wildcardMarker = relation ( Follows , "*" ) ;
277+ expect ( archetype1 . componentTypes ) . toContain ( wildcardMarker ) ;
278+ } ) ;
279+
280+ it ( "should support cascadeDelete and dontFragment simultaneously" , ( ) => {
281+ const world = new World ( ) ;
282+ const parent = world . new ( ) ;
283+ const child1 = world . new ( ) ;
284+ const child2 = world . new ( ) ;
285+
286+ // Create ChildOf component with both cascadeDelete and dontFragment options
287+ const ChildOf = component < { priority : number } > ( { cascadeDelete : true , dontFragment : true } ) ;
288+
289+ const childOfParent1 = relation ( ChildOf , parent ) ;
290+ const childOfParent2 = relation ( ChildOf , parent ) ;
291+
292+ // Add relations to children
293+ world . set ( child1 , childOfParent1 , { priority : 1 } ) ;
294+ world . set ( child2 , childOfParent2 , { priority : 2 } ) ;
295+ world . sync ( ) ;
296+
297+ // Verify relations exist
298+ expect ( world . has ( child1 , childOfParent1 ) ) . toBe ( true ) ;
299+ expect ( world . has ( child2 , childOfParent2 ) ) . toBe ( true ) ;
300+
301+ // Both children should be in the same archetype (dontFragment behavior)
302+ const archetype1 = ( world as any ) . entityToArchetype . get ( child1 ) ;
303+ const archetype2 = ( world as any ) . entityToArchetype . get ( child2 ) ;
304+ expect ( archetype1 ) . toBe ( archetype2 ) ;
305+
306+ // Delete parent - should cascade delete both children (cascadeDelete behavior)
307+ world . delete ( parent ) ;
308+ world . sync ( ) ;
309+
310+ expect ( world . exists ( parent ) ) . toBe ( false ) ;
311+ expect ( world . exists ( child1 ) ) . toBe ( false ) ;
312+ expect ( world . exists ( child2 ) ) . toBe ( false ) ;
313+ } ) ;
314+
247315 it ( "should handle multiple components" , ( ) => {
248316 const world = new World ( ) ;
249317 const entity = world . new ( ) ;
0 commit comments