@@ -749,6 +749,53 @@ func TestEndToEndSuccess(t *testing.T) {
749749 assert .ElementsMatch (t , actualStrs , expectedStrs , "list of strings provided must match" )
750750 })
751751
752+ t .Run ("multiple As with Group and Name" , func (t * testing.T ) {
753+ c := digtest .New (t )
754+ expectedNames := []string {"inst1" , "inst2" }
755+ expectedStrs := []string {"foo" , "bar" }
756+ for i , s := range expectedStrs {
757+ s := s
758+ c .RequireProvide (func () * bytes.Buffer {
759+ return bytes .NewBufferString (s )
760+ }, dig .Group ("buffs" ), dig .Name (expectedNames [i ]),
761+ dig .As (new (io.Reader ), new (io.Writer )))
762+ }
763+
764+ type in struct {
765+ dig.In
766+
767+ Reader1 io.Reader `name:"inst1"`
768+ Reader2 io.Reader `name:"inst2"`
769+ Readers []io.Reader `group:"buffs"`
770+ Writers []io.Writer `group:"buffs"`
771+ }
772+
773+ var actualStrs []string
774+ var actualStrsName []string
775+
776+ c .RequireInvoke (func (got in ) {
777+ require .Len (t , got .Readers , 2 )
778+ buf := make ([]byte , 3 )
779+ for i , r := range got .Readers {
780+ _ , err := r .Read (buf )
781+ require .NoError (t , err )
782+ actualStrs = append (actualStrs , string (buf ))
783+ // put the text back
784+ got .Writers [i ].Write (buf )
785+ }
786+ _ , err := got .Reader1 .Read (buf )
787+ require .NoError (t , err )
788+ actualStrsName = append (actualStrsName , string (buf ))
789+ _ , err = got .Reader2 .Read (buf )
790+ require .NoError (t , err )
791+ actualStrsName = append (actualStrsName , string (buf ))
792+ require .Len (t , got .Writers , 2 )
793+ })
794+
795+ assert .ElementsMatch (t , actualStrs , expectedStrs , "list of strings provided must match" )
796+ assert .ElementsMatch (t , actualStrsName , expectedStrs , "names: list of strings provided must match" )
797+ })
798+
752799 t .Run ("As same interface" , func (t * testing.T ) {
753800 c := digtest .New (t )
754801 c .RequireProvide (func () io.Reader {
@@ -1098,6 +1145,48 @@ func TestGroups(t *testing.T) {
10981145 })
10991146 })
11001147
1148+ t .Run ("values are provided; coexist with name" , func (t * testing.T ) {
1149+ c := digtest .New (t , dig .SetRand (rand .New (rand .NewSource (0 ))))
1150+
1151+ type out struct {
1152+ dig.Out
1153+
1154+ Value int `group:"val"`
1155+ }
1156+
1157+ type out2 struct {
1158+ dig.Out
1159+
1160+ Value int `name:"inst1" group:"val"`
1161+ }
1162+
1163+ provide := func (i int ) {
1164+ c .RequireProvide (func () out {
1165+ return out {Value : i }
1166+ })
1167+ }
1168+
1169+ provide (1 )
1170+ provide (2 )
1171+ provide (3 )
1172+
1173+ c .RequireProvide (func () out2 {
1174+ return out2 {Value : 4 }
1175+ })
1176+
1177+ type in struct {
1178+ dig.In
1179+
1180+ SingleValue int `name:"inst1"`
1181+ Values []int `group:"val"`
1182+ }
1183+
1184+ c .RequireInvoke (func (i in ) {
1185+ assert .Equal (t , []int {1 , 2 , 3 , 4 }, i .Values )
1186+ assert .Equal (t , 4 , i .SingleValue )
1187+ })
1188+ })
1189+
11011190 t .Run ("groups are provided via option" , func (t * testing.T ) {
11021191 c := digtest .New (t , dig .SetRand (rand .New (rand .NewSource (0 ))))
11031192
@@ -1122,6 +1211,36 @@ func TestGroups(t *testing.T) {
11221211 })
11231212 })
11241213
1214+ t .Run ("groups are provided via option; coexist with name" , func (t * testing.T ) {
1215+ c := digtest .New (t , dig .SetRand (rand .New (rand .NewSource (0 ))))
1216+
1217+ provide := func (i int ) {
1218+ c .RequireProvide (func () int {
1219+ return i
1220+ }, dig .Group ("val" ))
1221+ }
1222+
1223+ provide (1 )
1224+ provide (2 )
1225+ provide (3 )
1226+
1227+ c .RequireProvide (func () int {
1228+ return 4
1229+ }, dig .Group ("val" ), dig .Name ("inst1" ))
1230+
1231+ type in struct {
1232+ dig.In
1233+
1234+ SingleValue int `name:"inst1"`
1235+ Values []int `group:"val"`
1236+ }
1237+
1238+ c .RequireInvoke (func (i in ) {
1239+ assert .Equal (t , []int {1 , 2 , 3 , 4 }, i .Values )
1240+ assert .Equal (t , 4 , i .SingleValue )
1241+ })
1242+ })
1243+
11251244 t .Run ("different types may be grouped" , func (t * testing.T ) {
11261245 c := digtest .New (t , dig .SetRand (rand .New (rand .NewSource (0 ))))
11271246
@@ -1998,21 +2117,6 @@ func TestAsExpectingOriginalType(t *testing.T) {
19982117 })
19992118}
20002119
2001- func TestProvideIncompatibleOptions (t * testing.T ) {
2002- t .Parallel ()
2003-
2004- t .Run ("group and name" , func (t * testing.T ) {
2005- c := digtest .New (t )
2006- err := c .Provide (func () io.Reader {
2007- t .Fatal ("this function must not be called" )
2008- return nil
2009- }, dig .Group ("foo" ), dig .Name ("bar" ))
2010- require .Error (t , err )
2011- assert .Contains (t , err .Error (), "cannot use named values with value groups: " +
2012- `name:"bar" provided with group:"foo"` )
2013- })
2014- }
2015-
20162120type testStruct struct {}
20172121
20182122func (testStruct ) TestMethod (x int ) float64 { return float64 (x ) }
@@ -2559,6 +2663,60 @@ func testProvideFailures(t *testing.T, dryRun bool) {
25592663 )
25602664 })
25612665
2666+ t .Run ("provide multiple instances with the same name and same group" , func (t * testing.T ) {
2667+ c := digtest .New (t , dig .DryRun (dryRun ))
2668+ type A struct {}
2669+ type ret1 struct {
2670+ dig.Out
2671+ * A `name:"foo" group:"foos"`
2672+ }
2673+ type ret2 struct {
2674+ dig.Out
2675+ * A `name:"foo" group:"foos"`
2676+ }
2677+ c .RequireProvide (func () ret1 {
2678+ return ret1 {A : & A {}}
2679+ })
2680+
2681+ err := c .Provide (func () ret2 {
2682+ return ret2 {A : & A {}}
2683+ })
2684+ require .Error (t , err , "expected error on the second provide" )
2685+ dig .AssertErrorMatches (t , err ,
2686+ `cannot provide function "go.uber.org/dig_test".testProvideFailures\S+` ,
2687+ `dig_test.go:\d+` , // file:line
2688+ `cannot provide \*dig_test.A\[name="foo"\] from \[0\].A:` ,
2689+ `already provided by "go.uber.org/dig_test".testProvideFailures\S+` ,
2690+ )
2691+ })
2692+
2693+ t .Run ("provide multiple instances with the same name but different group" , func (t * testing.T ) {
2694+ c := digtest .New (t , dig .DryRun (dryRun ))
2695+ type A struct {}
2696+ type ret1 struct {
2697+ dig.Out
2698+ * A `name:"foo" group:"foos"`
2699+ }
2700+ type ret2 struct {
2701+ dig.Out
2702+ * A `name:"foo" group:"foosss"`
2703+ }
2704+ c .RequireProvide (func () ret1 {
2705+ return ret1 {A : & A {}}
2706+ })
2707+
2708+ err := c .Provide (func () ret2 {
2709+ return ret2 {A : & A {}}
2710+ })
2711+ require .Error (t , err , "expected error on the second provide" )
2712+ dig .AssertErrorMatches (t , err ,
2713+ `cannot provide function "go.uber.org/dig_test".testProvideFailures\S+` ,
2714+ `dig_test.go:\d+` , // file:line
2715+ `cannot provide \*dig_test.A\[name="foo"\] from \[0\].A:` ,
2716+ `already provided by "go.uber.org/dig_test".testProvideFailures\S+` ,
2717+ )
2718+ })
2719+
25622720 t .Run ("out with unexported field should error" , func (t * testing.T ) {
25632721 c := digtest .New (t , dig .DryRun (dryRun ))
25642722
0 commit comments