@@ -534,4 +534,91 @@ describe('ObjectKernel', () => {
534534 } ) . rejects . toThrow ( 'not running' ) ;
535535 } ) ;
536536 } ) ;
537+
538+ describe ( 'Service Replacement' , ( ) => {
539+ it ( 'should replace an existing service via replaceService' , async ( ) => {
540+ const originalService = { value : 'original' } ;
541+ const replacementService = { value : 'replaced' } ;
542+
543+ const plugin : Plugin = {
544+ name : 'register-plugin' ,
545+ version : '1.0.0' ,
546+ init : async ( ctx ) => {
547+ ctx . registerService ( 'metadata' , originalService ) ;
548+ } ,
549+ } ;
550+
551+ const optimizationPlugin : Plugin = {
552+ name : 'optimization-plugin' ,
553+ version : '1.0.0' ,
554+ dependencies : [ 'register-plugin' ] ,
555+ init : async ( ctx ) => {
556+ const existing = ctx . getService ( 'metadata' ) ;
557+ expect ( existing ) . toBe ( originalService ) ;
558+ ctx . replaceService ( 'metadata' , replacementService ) ;
559+ } ,
560+ } ;
561+
562+ await kernel . use ( plugin ) ;
563+ await kernel . use ( optimizationPlugin ) ;
564+ await kernel . bootstrap ( ) ;
565+
566+ const result = kernel . getService ( 'metadata' ) ;
567+ expect ( result ) . toBe ( replacementService ) ;
568+
569+ await kernel . shutdown ( ) ;
570+ } ) ;
571+
572+ it ( 'should throw when replacing a non-existent service' , async ( ) => {
573+ const plugin : Plugin = {
574+ name : 'bad-replace-plugin' ,
575+ version : '1.0.0' ,
576+ init : async ( ctx ) => {
577+ expect ( ( ) => {
578+ ctx . replaceService ( 'nonexistent' , { value : 'test' } ) ;
579+ } ) . toThrow ( "Service 'nonexistent' not found" ) ;
580+ } ,
581+ } ;
582+
583+ await kernel . use ( plugin ) ;
584+ await kernel . bootstrap ( ) ;
585+ await kernel . shutdown ( ) ;
586+ } ) ;
587+
588+ it ( 'should allow decorator pattern via replaceService' , async ( ) => {
589+ const original = {
590+ getData : ( ) => 'raw-data' ,
591+ } ;
592+
593+ const plugin : Plugin = {
594+ name : 'data-plugin' ,
595+ version : '1.0.0' ,
596+ init : async ( ctx ) => {
597+ ctx . registerService ( 'data' , original ) ;
598+ } ,
599+ } ;
600+
601+ const wrapperPlugin : Plugin = {
602+ name : 'wrapper-plugin' ,
603+ version : '1.0.0' ,
604+ dependencies : [ 'data-plugin' ] ,
605+ init : async ( ctx ) => {
606+ const existing = ctx . getService < typeof original > ( 'data' ) ;
607+ const decorated = {
608+ getData : ( ) => `cached(${ existing . getData ( ) } )` ,
609+ } ;
610+ ctx . replaceService ( 'data' , decorated ) ;
611+ } ,
612+ } ;
613+
614+ await kernel . use ( plugin ) ;
615+ await kernel . use ( wrapperPlugin ) ;
616+ await kernel . bootstrap ( ) ;
617+
618+ const result = kernel . getService < typeof original > ( 'data' ) ;
619+ expect ( result . getData ( ) ) . toBe ( 'cached(raw-data)' ) ;
620+
621+ await kernel . shutdown ( ) ;
622+ } ) ;
623+ } ) ;
537624} ) ;
0 commit comments