func TestMockConstructor(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo string) int Bar(bar int) string } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo func newMockFoo() *mockFoo { m := &mockFoo{} m.FooCalled = make(chan bool, 300) m.FooInput.Foo = make(chan string, 300) m.FooOutput.Ret0 = make(chan int, 300) m.BarCalled = make(chan bool, 300) m.BarInput.Bar = make(chan int, 300) m.BarOutput.Ret0 = make(chan string, 300) return m }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Constructor(300)}, nil) expect(src).To.Equal(string(expected)) }
func TestMockSimpleMethod(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo() }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo() { m.FooCalled <- true }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) fields := method.Fields() expect(fields).To.Have.Len(1).Else.FailNow() expect(fields[0].Names[0].Name).To.Equal("FooCalled") ch, ok := fields[0].Type.(*ast.ChanType) expect(ok).To.Be.Ok().Else.FailNow() expect(ch.Dir).To.Equal(ast.SEND | ast.RECV) ident, ok := ch.Value.(*ast.Ident) expect(ident.Name).To.Equal("bool") }
func TestMockTypeDecl_DirectionalChansGetParens(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo chan<- int) <-chan int } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo chan (chan<- int) } FooOutput struct { Ret0 chan (<-chan int) } } `)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockTypeDecl_ParamsWithoutTypes(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo, bar string) } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo, Bar chan string } } `)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockConstructor_VariadicParams(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo ...int) } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo func newMockFoo() *mockFoo { m := &mockFoo{} m.FooCalled = make(chan bool, 200) m.FooInput.Foo = make(chan []int, 200) return m } `)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Constructor(200)}, nil) expect(src).To.Equal(string(expected)) }
func TestMockMethodUnnamedValues(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(int, string) (string, error) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(arg0 int, arg1 string) (string, error) { m.FooCalled <- true m.FooInput.Arg0 <- arg0 m.FooInput.Arg1 <- arg1 return <-m.FooOutput.Ret0, <-m.FooOutput.Ret1 }`)) expect(err).To.Be.Nil() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockMethodLocalTypeNesting(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(bar []Bar, bacon map[Foo]Bar) (baz []Baz, eggs map[Foo]Bar) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) method.PrependLocalPackage("foo") expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(bar []foo.Bar, bacon map[foo.Foo]foo.Bar) (baz []foo.Baz, eggs map[foo.Foo]foo.Bar) { m.FooCalled <- true m.FooInput.Bar <- bar m.FooInput.Bacon <- bacon return <-m.FooOutput.Baz, <-m.FooOutput.Eggs }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockMethodParams(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo, bar string, baz int) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(foo, bar string, baz int) { m.FooCalled <- true m.FooInput.Foo <- foo m.FooInput.Bar <- bar m.FooInput.Baz <- baz }`)) expect(err).To.Be.Nil() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockConstructor_DirectionalChansGetParens(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo chan<- int) <-chan int } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo func newMockFoo() *mockFoo { m := &mockFoo{} m.FooCalled = make(chan bool, 200) m.FooInput.Foo = make(chan (chan<- int), 200) m.FooOutput.Ret0 = make(chan (<-chan int), 200) return m } `)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Constructor(200)}, nil) expect(src).To.Equal(string(expected)) }
func TestMockTypeDecl_VariadicMethods(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo ...int) } `) m, err := mocks.For(spec) expect(err).To.Be.Nil() expect(m).Not.To.Be.Nil() expected, err := format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo chan []int } } `)) expect(err).To.Be.Nil() src := source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) }
func TestNewErrorsForNonInterfaceTypes(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, "type Foo func()") _, err := mocks.For(spec) expect(err).Not.To.Be.Nil().Else.FailNow() expect(err.Error()).To.Equal("TypeSpec.Type expected to be *ast.InterfaceType, was *ast.FuncType") }
func TestMockName(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, "type Foo interface{}") m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expect(m.Name()).To.Equal("mockFoo") }
func TestMockMethodParams(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo, bar string, baz int) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(foo, bar string, baz int) { m.FooCalled <- true m.FooInput.Foo <- foo m.FooInput.Bar <- bar m.FooInput.Baz <- baz }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) fields := method.Fields() expect(fields).To.Have.Len(2) expect(fields[0].Names[0].Name).To.Equal("FooCalled") ch, ok := fields[0].Type.(*ast.ChanType) expect(ok).To.Be.Ok().Else.FailNow() expect(ch.Dir).To.Equal(ast.SEND | ast.RECV) ident, ok := ch.Value.(*ast.Ident) expect(ident.Name).To.Equal("bool") expect(fields[1].Names[0].Name).To.Equal("FooInput") input, ok := fields[1].Type.(*ast.StructType) expect(ok).To.Be.Ok().Else.FailNow() expect(input.Fields.List).To.Have.Len(2).Else.FailNow() fooBar := input.Fields.List[0] expect(fooBar.Names).To.Have.Len(2).Else.FailNow() expect(fooBar.Names[0].Name).To.Equal("Foo") expect(fooBar.Names[1].Name).To.Equal("Bar") ch, ok = fooBar.Type.(*ast.ChanType) expect(ok).To.Be.Ok().Else.FailNow() expect(ch.Dir).To.Equal(ast.SEND | ast.RECV) ident, ok = ch.Value.(*ast.Ident) expect(ident.Name).To.Equal("string") baz := input.Fields.List[1] expect(baz.Names[0].Name).To.Equal("Baz") ch, ok = baz.Type.(*ast.ChanType) expect(ok).To.Be.Ok().Else.FailNow() expect(ch.Dir).To.Equal(ast.SEND | ast.RECV) ident, ok = ch.Value.(*ast.Ident) expect(ident.Name).To.Equal("int") }
func TestMockAst(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Bar(bar string) Baz() (baz int) }`) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() decls := m.Ast(300) expect(decls).To.Have.Len(4).Else.FailNow() expect(decls[0]).To.Equal(m.Decl()) expect(decls[1]).To.Equal(m.Constructor(300)) expect(m.Methods()).To.Have.Len(2).Else.FailNow() expect(decls[2]).To.Equal(m.Methods()[0].Ast()) expect(decls[3]).To.Equal(m.Methods()[1].Ast()) }
func TestMockMethodLocalTypes(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(bar bar.Bar, baz string) (Foo, error) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(bar bar.Bar, baz string) (Foo, error) { m.FooCalled <- true m.FooInput.Bar <- bar m.FooInput.Baz <- baz return <-m.FooOutput.Ret0, <-m.FooOutput.Ret1 }`)) expect(err).To.Be.Nil() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) method.PrependLocalPackage("foo") expected, err = format.Source([]byte(` package foo func (m *mockFoo) Foo(bar bar.Bar, baz string) (foo.Foo, error) { m.FooCalled <- true m.FooInput.Bar <- bar m.FooInput.Baz <- baz return <-m.FooOutput.Ret0, <-m.FooOutput.Ret1 }`)) expect(err).To.Be.Nil() src = source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockSimpleMethod(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo() }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo() { m.FooCalled <- true }`)) expect(err).To.Be.Nil() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockMethodReceiverNameConflicts(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(m string) }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo(m_ string) { m.FooCalled <- true m.FooInput.M <- m_ }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func TestMockMethodWithBlockingReturn(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo() }`) mock, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() mock.SetBlockingReturn(true) method := mocks.MethodFor(mock, "Foo", method(expect, spec)) expected, err := format.Source([]byte(` package foo func (m *mockFoo) Foo() () { m.FooCalled <- true <-m.FooOutput.BlockReturn }`)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{method.Ast()}, nil) expect(src).To.Equal(string(expected)) }
func mockFor(expect func(interface{}) *expect.Expect, spec *ast.TypeSpec) mocks.Mock { m, err := mocks.For(spec) expect(err).To.Be.Nil() return m }
func TestMockTypeDecl(t *testing.T) { expect := expect.New(t) spec := typeSpec(expect, ` type Foo interface { Foo(foo string) int Bar(bar int) Foo Baz() Bacon(func(Eggs) Eggs) func(Eggs) Eggs } `) m, err := mocks.For(spec) expect(err).To.Be.Nil().Else.FailNow() expected, err := format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo chan string } FooOutput struct { Ret0 chan int } BarCalled chan bool BarInput struct { Bar chan int } BarOutput struct { Ret0 chan Foo } BazCalled chan bool BaconCalled chan bool BaconInput struct { Arg0 chan func(Eggs) Eggs } BaconOutput struct { Ret0 chan func(Eggs) Eggs } } `)) expect(err).To.Be.Nil().Else.FailNow() src := source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) m.PrependLocalPackage("foo") expected, err = format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo chan string } FooOutput struct { Ret0 chan int } BarCalled chan bool BarInput struct { Bar chan int } BarOutput struct { Ret0 chan foo.Foo } BazCalled chan bool BaconCalled chan bool BaconInput struct { Arg0 chan func(foo.Eggs) foo.Eggs } BaconOutput struct { Ret0 chan func(foo.Eggs) foo.Eggs } } `)) expect(err).To.Be.Nil().Else.FailNow() src = source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) m.SetBlockingReturn(true) expected, err = format.Source([]byte(` package foo type mockFoo struct { FooCalled chan bool FooInput struct { Foo chan string } FooOutput struct { Ret0 chan int } BarCalled chan bool BarInput struct { Bar chan int } BarOutput struct { Ret0 chan foo.Foo } BazCalled chan bool BazOutput struct { BlockReturn chan bool } BaconCalled chan bool BaconInput struct { Arg0 chan func(foo.Eggs) foo.Eggs } BaconOutput struct { Ret0 chan func(foo.Eggs) foo.Eggs } } `)) expect(err).To.Be.Nil().Else.FailNow() src = source(expect, "foo", []ast.Decl{m.Decl()}, nil) expect(src).To.Equal(string(expected)) }