@@ -391,134 +391,227 @@ func TestNewApp(t *testing.T) {
391391 })
392392}
393393
394- func TestPrivateProvide (t * testing.T ) {
394+ // TestPrivate tests Private when used with both fx.Provide and fx.Supply.
395+ func TestPrivate (t * testing.T ) {
395396 t .Parallel ()
396397
397- t . Run ( "CanUsePrivateAndNonPrivateFromOuterModule" , func ( t * testing. T ) {
398- t . Parallel ()
398+ testCases := [] struct {
399+ desc string
399400
400- app := fxtest .New (t ,
401- Module ("SubModule" , Invoke (func (a int , b string ) {})),
402- Provide (func () int { return 0 }, Private ),
403- Provide (func () string { return "" }),
404- )
405- app .RequireStart ().RequireStop ()
406- })
401+ // provide is either a Supply or Provide wrapper around the given int
402+ // that allows us to generalize these test cases for both APIs.
403+ provide func (int , bool ) Option
404+ }{
405+ {
406+ desc : "Provide" ,
407+ provide : func (i int , private bool ) Option {
408+ opts := []any {func () int { return i }}
409+ if private {
410+ opts = append (opts , Private )
411+ }
412+ return Provide (opts ... )
413+ },
414+ },
415+ {
416+ desc : "Supply" ,
417+ provide : func (i int , private bool ) Option {
418+ opts := []any {i }
419+ if private {
420+ opts = append (opts , Private )
421+ }
422+ return Supply (opts ... )
423+ },
424+ },
425+ }
407426
408- t .Run ("CantUsePrivateFromSubModule" , func (t * testing.T ) {
409- t .Parallel ()
427+ for _ , tt := range testCases {
428+ t .Run (tt .desc , func (t * testing.T ) {
429+ t .Parallel ()
410430
411- app := NewForTest (t ,
412- Module ("SubModule" , Provide (func () int { return 0 }, Private )),
413- Invoke (func (a int ) {}),
414- )
415- err := app .Err ()
416- require .Error (t , err )
417- assert .Contains (t , err .Error (), "missing dependencies for function" )
418- assert .Contains (t , err .Error (), "missing type: int" )
419- })
431+ t .Run ("CanUsePrivateFromParentModule" , func (t * testing.T ) {
432+ t .Parallel ()
433+
434+ var invoked bool
435+ app := fxtest .New (t ,
436+ Module ("SubModule" , Invoke (func (a int , b string ) {
437+ assert .Equal (t , 0 , a )
438+ invoked = true
439+ })),
440+ Provide (func () string { return "" }),
441+ tt .provide (0 , true /* private */ ),
442+ )
443+ app .RequireStart ().RequireStop ()
444+ assert .True (t , invoked )
445+ })
420446
421- t .Run ("DifferentModulesCanProvideSamePrivateType " , func (t * testing.T ) {
422- t .Parallel ()
447+ t .Run ("CannotUsePrivateFromSubModule " , func (t * testing.T ) {
448+ t .Parallel ()
423449
424- app := fxtest .New (t ,
425- Module ("SubModuleA" ,
426- Provide (func () int { return 1 }, Private ),
427- Invoke (func (s int ) {
428- assert .Equal (t , 1 , s )
429- }),
430- ),
431- Module ("SubModuleB" ,
432- Provide (func () int { return 2 }, Private ),
433- Invoke (func (s int ) {
434- assert .Equal (t , 2 , s )
435- }),
436- ),
437- Provide (func () int { return 3 }),
438- Invoke (func (s int ) {
439- assert .Equal (t , 3 , s )
440- }),
441- )
442- app .RequireStart ().RequireStop ()
443- })
450+ app := NewForTest (t ,
451+ Module ("SubModule" , tt .provide (0 , true /* private */ )),
452+ Invoke (func (a int ) {}),
453+ )
454+ err := app .Err ()
455+ require .Error (t , err )
456+ assert .Contains (t , err .Error (), "missing dependencies for function" )
457+ assert .Contains (t , err .Error (), "missing type: int" )
458+ })
459+
460+ t .Run ("MultipleModulesSameType" , func (t * testing.T ) {
461+ t .Parallel ()
462+
463+ var invoked int
464+ app := fxtest .New (t ,
465+ Module ("SubModuleA" ,
466+ tt .provide (1 , true /* private */ ),
467+ Invoke (func (s int ) {
468+ assert .Equal (t , 1 , s )
469+ invoked ++
470+ }),
471+ ),
472+ Module ("SubModuleB" ,
473+ tt .provide (2 , true /* private */ ),
474+ Invoke (func (s int ) {
475+ assert .Equal (t , 2 , s )
476+ invoked ++
477+ }),
478+ ),
479+ tt .provide (3 , false /* private */ ),
480+ Invoke (func (s int ) {
481+ assert .Equal (t , 3 , s )
482+ invoked ++
483+ }),
484+ )
485+ app .RequireStart ().RequireStop ()
486+ assert .Equal (t , 3 , invoked )
487+ })
488+ })
489+ }
444490}
445491
446492func TestPrivateProvideWithDecorators (t * testing.T ) {
447493 t .Parallel ()
448494
449- t . Run ( "DecoratedPublicOrPrivateTypeInSubModule" , func ( t * testing. T ) {
450- t . Parallel ()
495+ testCases := [] struct {
496+ desc string
451497
452- runApp := func (private bool ) {
453- provideOpts := []interface {}{func () int { return 0 }}
454- if private {
455- provideOpts = append (provideOpts , Private )
456- }
457- app := NewForTest (t ,
458- Module ("SubModule" ,
459- Provide (provideOpts ... ),
460- Decorate (func (a int ) int { return a + 2 }),
461- Invoke (func (a int ) { assert .Equal (t , 2 , a ) }),
462- ),
463- Invoke (func (a int ) { assert .Equal (t , 0 , a ) }),
464- )
465- err := app .Err ()
466- if private {
467- require .Error (t , err )
468- assert .Contains (t , err .Error (), "missing dependencies for function" )
469- assert .Contains (t , err .Error (), "missing type: int" )
470- } else {
471- require .NoError (t , err )
472- }
473- }
498+ // provide is either a Supply or Provide wrapper around the given int
499+ // that allows us to generalize these test cases for both APIs.
500+ provide func (int ) Option
501+ private bool
502+ }{
503+ {
504+ desc : "Private/Provide" ,
505+ provide : func (i int ) Option {
506+ return Provide (
507+ func () int { return i },
508+ Private ,
509+ )
510+ },
511+ private : true ,
512+ },
513+ {
514+ desc : "Private/Supply" ,
515+ provide : func (i int ) Option {
516+ return Supply (i , Private )
517+ },
518+ private : true ,
519+ },
520+ {
521+ desc : "Public/Provide" ,
522+ provide : func (i int ) Option {
523+ return Provide (func () int { return i })
524+ },
525+ private : false ,
526+ },
527+ {
528+ desc : "Public/Supply" ,
529+ provide : func (i int ) Option {
530+ return Supply (i )
531+ },
532+ private : false ,
533+ },
534+ }
474535
475- t . Run ( "Public" , func ( t * testing. T ) { runApp ( false ) })
476- t .Run ("Private" , func (t * testing.T ) { runApp ( true ) })
477- } )
536+ for _ , tt := range testCases {
537+ t .Run (tt . desc , func (t * testing.T ) {
538+ t . Parallel ( )
478539
479- t .Run ("DecoratedPublicOrPrivateTypeInOuterModule " , func (t * testing.T ) {
480- t .Parallel ()
540+ t .Run ("DecoratedTypeInSubModule " , func (t * testing.T ) {
541+ t .Parallel ()
481542
482- runApp := func (private bool ) {
483- provideOpts := []interface {}{func () int { return 0 }}
484- if private {
485- provideOpts = append (provideOpts , Private )
486- }
487- app := fxtest .New (t ,
488- Provide (provideOpts ... ),
489- Decorate (func (a int ) int { return a - 5 }),
490- Invoke (func (a int ) {
491- assert .Equal (t , - 5 , a )
492- }),
493- Module ("Child" ,
494- Decorate (func (a int ) int { return a + 10 }),
543+ var invoked bool
544+ app := NewForTest (t ,
545+ Module ("SubModule" ,
546+ tt .provide (0 ),
547+ Decorate (func (a int ) int { return a + 2 }),
548+ Invoke (func (a int ) { assert .Equal (t , 2 , a ) }),
549+ ),
495550 Invoke (func (a int ) {
496- assert .Equal (t , 5 , a )
551+ // Decoration is always "private",
552+ // so raw provided value is expected here
553+ // when the submodule provides it as public.
554+ assert .Equal (t , 0 , a )
555+ invoked = true
497556 }),
498- ),
499- )
500- app .RequireStart ().RequireStop ()
501- }
557+ )
558+ err := app .Err ()
559+ if tt .private {
560+ require .Error (t , err )
561+ assert .Contains (t , err .Error (), "missing dependencies for function" )
562+ assert .Contains (t , err .Error (), "missing type: int" )
563+ } else {
564+ require .NoError (t , err )
565+ assert .True (t , invoked )
566+ }
567+ })
502568
503- t .Run ("Public" , func (t * testing.T ) { runApp (false ) })
504- t .Run ("Private" , func (t * testing.T ) { runApp (true ) })
505- })
569+ t .Run ("DecoratedTypeInParentModule" , func (t * testing.T ) {
570+ t .Parallel ()
506571
507- t .Run ("CannotDecoratePrivateChildType" , func (t * testing.T ) {
508- t .Parallel ()
572+ var invoked int
573+ app := fxtest .New (t ,
574+ tt .provide (0 ),
575+ Decorate (func (a int ) int { return a - 5 }),
576+ Invoke (func (a int ) {
577+ assert .Equal (t , - 5 , a )
578+ invoked ++
579+ }),
580+ Module ("Child" ,
581+ Decorate (func (a int ) int { return a + 10 }),
582+ Invoke (func (a int ) {
583+ assert .Equal (t , 5 , a )
584+ invoked ++
585+ }),
586+ ),
587+ )
588+ app .RequireStart ().RequireStop ()
589+ assert .Equal (t , 2 , invoked )
590+ })
509591
510- app := NewForTest (t ,
511- Module ("Child" ,
512- Provide (func () int { return 0 }, Private ),
513- ),
514- Decorate (func (a int ) int { return a + 5 }),
515- Invoke (func (a int ) {}),
516- )
517- err := app .Err ()
518- require .Error (t , err )
519- assert .Contains (t , err .Error (), "missing dependencies for function" )
520- assert .Contains (t , err .Error (), "missing type: int" )
521- })
592+ t .Run ("ParentDecorateChildType" , func (t * testing.T ) {
593+ t .Parallel ()
594+
595+ var invoked bool
596+ app := NewForTest (t ,
597+ Module ("Child" , tt .provide (0 )),
598+ Decorate (func (a int ) int { return a + 5 }),
599+ Invoke (func (a int ) {
600+ invoked = true
601+ }),
602+ )
603+ err := app .Err ()
604+ if tt .private {
605+ require .Error (t , err )
606+ assert .Contains (t , err .Error (), "missing dependencies for function" )
607+ assert .Contains (t , err .Error (), "missing type: int" )
608+ } else {
609+ require .NoError (t , err )
610+ assert .True (t , invoked )
611+ }
612+ })
613+ })
614+ }
522615}
523616
524617func TestWithLoggerErrorUseDefault (t * testing.T ) {
0 commit comments