Skip to content

Commit

Permalink
feat: support sequence return
Browse files Browse the repository at this point in the history
Change-Id: I95036796bdffd559cb713ec3485fa6f064eaf1fa
  • Loading branch information
Sychorius committed May 22, 2023
1 parent b073d52 commit feab767
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
11 changes: 10 additions & 1 deletion mock_condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,18 @@ func (m *mockCondition) SetReturn(results ...interface{}) {
}

func (m *mockCondition) SetReturnForce(results ...interface{}) {
tool.CheckReturnType(m.builder.target, results...)
getResult := func() []interface{} { return results }
if len(results) == 1 {
seq, ok := results[0].(SequenceOpt)
if ok {
getResult = seq.GetNext
}
}

targetType := reflect.TypeOf(m.builder.target)
m.hook = reflect.MakeFunc(targetType, func(args []reflect.Value) []reflect.Value {
results := getResult()
tool.CheckReturnType(m.builder.target, results...)
valueResults := make([]reflect.Value, 0)
for i, result := range results {
rValue := reflect.Zero(targetType.Out(i))
Expand Down
63 changes: 63 additions & 0 deletions mock_sequence.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package mockey

import "github.com/bytedance/mockey/internal/tool"

type SequenceOpt interface {
// make sure it is mockey private interface
Private
// GetNext is used by mockey, don't use it if you don't know what it does
GetNext() []interface{}
Times(int) SequenceOpt
Then(...interface{}) SequenceOpt
}

type sequence struct {
MockeyPrivate // make sure it does implements mockey SequenceOpt
values [][]interface{}
cur int
}

func (s *sequence) GetNext() []interface{} {
v := s.values[s.cur]
s.cur++
if s.cur >= len(s.values) {
s.cur = 0
}
return v
}

func (s *sequence) Then(value ...interface{}) SequenceOpt {
s.values = append(s.values, value)
return s
}

func (s *sequence) Times(t int) SequenceOpt {
tool.Assert(t > 0, "return times should more than 0")
for i := 1; i < t; i++ { // repeat last return value t-1 times
s.values = append(s.values, s.values[len(s.values)-1])
}
return s
}

func Sequence(value ...interface{}) SequenceOpt {
return &sequence{
values: [][]interface{}{value},
cur: 0,
}
}
63 changes: 63 additions & 0 deletions mock_sequence_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package mockey

import (
"fmt"
"testing"

"github.com/smartystreets/goconvey/convey"
)

func TestSequenceOpt(t *testing.T) {
PatchConvey("test sequenceOpt", t, func() {
fn := func() (string, int) {
fmt.Println("original fn")
return "fn: not here", -1
}

tests := []struct {
Value1 string
Value2 int
Times int
}{
{"Alice", 2, 3},
{"Bob", 3, 1},
{"Tom", 4, 1},
{"Jerry", 5, 2},
}

seq := Sequence("Admin", 1)
for _, r := range tests {
seq.Then(r.Value1, r.Value2).Times(r.Times)
}
Mock(fn).Return(seq).Build()

for repeat := 3; repeat != 0; repeat-- {
v1, v2 := fn()
convey.So(v1, convey.ShouldEqual, "Admin")
convey.So(v2, convey.ShouldEqual, 1)
for _, r := range tests {
for rIndex := 0; rIndex < r.Times; rIndex++ {
v1, v2 := fn()
convey.So(v1, convey.ShouldEqual, r.Value1)
convey.So(v2, convey.ShouldEqual, r.Value2)
}
}
}
})
}
11 changes: 11 additions & 0 deletions private.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mockey

// make sure private

type Private interface {
private()
}

type MockeyPrivate struct{}

func (*MockeyPrivate) private() {}

0 comments on commit feab767

Please sign in to comment.