Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 1df903b

Browse files
authored
Merge pull request #98 from hatstand/master
Support slices in SetArg()
2 parents 45f67fc + 73cae96 commit 1df903b

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

gomock/call.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ func (c *Call) Times(n int) *Call {
118118
}
119119

120120
// SetArg declares an action that will set the nth argument's value,
121-
// indirected through a pointer.
121+
// indirected through a pointer. Or, in the case of a slice, SetArg
122+
// will copy value's elements into the nth argument.
122123
func (c *Call) SetArg(n int, value interface{}) *Call {
123124
if c.setArgs == nil {
124125
c.setArgs = make(map[int]reflect.Value)
@@ -142,8 +143,10 @@ func (c *Call) SetArg(n int, value interface{}) *Call {
142143
}
143144
case reflect.Interface:
144145
// nothing to do
146+
case reflect.Slice:
147+
// nothing to do
145148
default:
146-
c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v [%s]",
149+
c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v",
147150
n, at, c.origin)
148151
}
149152
c.setArgs[n] = reflect.ValueOf(value)
@@ -243,7 +246,12 @@ func (c *Call) call(args []interface{}) (rets []interface{}, action func()) {
243246
action = func() { c.doFunc.Call(doArgs) }
244247
}
245248
for n, v := range c.setArgs {
246-
reflect.ValueOf(args[n]).Elem().Set(v)
249+
switch reflect.TypeOf(args[n]).Kind() {
250+
case reflect.Slice:
251+
setSlice(args[n], v)
252+
default:
253+
reflect.ValueOf(args[n]).Elem().Set(v)
254+
}
247255
}
248256

249257
rets = c.rets
@@ -265,3 +273,10 @@ func InOrder(calls ...*Call) {
265273
calls[i].After(calls[i-1])
266274
}
267275
}
276+
277+
func setSlice(arg interface{}, v reflect.Value) {
278+
va := reflect.ValueOf(arg)
279+
for i := 0; i < v.Len(); i++ {
280+
va.Index(i).Set(v.Index(i))
281+
}
282+
}

gomock/call_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package gomock
22

3-
import "testing"
3+
import (
4+
"reflect"
5+
"testing"
6+
)
47

58
type mockTestReporter struct {
69
errorCalls int
@@ -45,3 +48,32 @@ func TestCall_After(t *testing.T) {
4548
}
4649
})
4750
}
51+
52+
func TestCall_SetArg(t *testing.T) {
53+
t.Run("SetArgSlice", func(t *testing.T) {
54+
c := &Call{
55+
methodType: reflect.TypeOf(func([]byte) {}),
56+
}
57+
c.SetArg(0, []byte{1, 2, 3})
58+
59+
in := []byte{4, 5, 6}
60+
c.call([]interface{}{in})
61+
62+
if in[0] != 1 || in[1] != 2 || in[2] != 3 {
63+
t.Error("Expected SetArg() to modify input slice argument")
64+
}
65+
})
66+
67+
t.Run("SetArgPointer", func(t *testing.T) {
68+
c := &Call{
69+
methodType: reflect.TypeOf(func(*int) {}),
70+
}
71+
c.SetArg(0, 42)
72+
73+
in := 43
74+
c.call([]interface{}{&in})
75+
if in != 42 {
76+
t.Error("Expected SetArg() to modify value pointed to by argument")
77+
}
78+
})
79+
}

0 commit comments

Comments
 (0)