test: replace handwritten clipboard and IME doubles with Mockery mocks
- commit
- 8b015e39a00264c7da62e176a50a0edf030c2596
- author
- brice · · 2026-10-01 17:53 UTC
- parent
- 2543591
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
9 files · +672 -82
this diff holds invisible characters (direction controls, zero-width characters). They are shown as <U+XXXX> markers, never applied.
M .mockery.yml +13 -0
| @@ -22,4 +22,17 @@ packages: | |||
| 22 | 22 | filename: '{{.InterfaceName}}_mock_test.go' | |
| 23 | 23 | interfaces: | |
| 24 | 24 | IME: | |
| 25 | + | configs: | |
| 26 | + | - {} | |
| 27 | + | # Also mocked next to the UI tests that drive the editors. | |
| 28 | + | - dir: internal/ui | |
| 29 | + | pkgname: ui | |
| 25 | 30 | Clipboard: | |
| 31 | + | configs: | |
| 32 | + | - {} | |
| 33 | + | - dir: internal/ui | |
| 34 | + | pkgname: ui | |
| 35 | + | AsyncClipboard: | |
| 36 | + | configs: | |
| 37 | + | - dir: internal/ui | |
| 38 | + | pkgname: ui | |
| @@ -22,4 +22,17 @@ packages: | |||||
| 22 | filename: '{{.InterfaceName}}_mock_test.go' | 22 | filename: '{{.InterfaceName}}_mock_test.go' | ||
| 23 | interfaces: | 23 | interfaces: | ||
| 24 | IME: | 24 | IME: | ||
| 25 | + | configs: | |||
| 26 | + | - {} | |||
| 27 | + | # Also mocked next to the UI tests that drive the editors. | |||
| 28 | + | - dir: internal/ui | |||
| 29 | + | pkgname: ui | |||
| 25 | Clipboard: | 30 | Clipboard: | ||
| 31 | + | configs: | |||
| 32 | + | - {} | |||
| 33 | + | - dir: internal/ui | |||
| 34 | + | pkgname: ui | |||
| 35 | + | AsyncClipboard: | |||
| 36 | + | configs: | |||
| 37 | + | - dir: internal/ui | |||
| 38 | + | pkgname: ui | |||
M internal/edit/edit_test.go +8 -10
| @@ -8,11 +8,6 @@ import ( | |||
| 8 | 8 | "github.com/stretchr/testify/mock" | |
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | - | type memoryClipboard struct{ data []byte } | |
| 12 | - | ||
| 13 | - | func (m *memoryClipboard) ReadText(limit int) ([]byte, error) { return m.data, nil } | |
| 14 | - | func (m *memoryClipboard) WriteText(v []byte) error { m.data = append([]byte(nil), v...); return nil } | |
| 15 | - | ||
| 16 | 11 | func TestGraphemesAndIME(t *testing.T) { | |
| 17 | 12 | s := State{} | |
| 18 | 13 | s.Sync("e\u0301👩<U+200D>💻a") | |
| @@ -53,22 +48,25 @@ func TestClipboardAndMask(t *testing.T) { | |||
| 53 | 48 | s := State{} | |
| 54 | 49 | s.Sync("s3crét") | |
| 55 | 50 | s.Select(0, len(s.Value)) | |
| 56 | - | c := &memoryClipboard{} | |
| 57 | - | if err := s.Copy(c, true); err != nil || len(c.data) != 0 { | |
| 51 | + | c := NewMockClipboard(t) // a masked copy must not write | |
| 52 | + | if err := s.Copy(c, true); err != nil { | |
| 58 | 53 | t.Fatal(err) | |
| 59 | 54 | } | |
| 60 | 55 | if s.Mask() != "••••••" { | |
| 61 | 56 | t.Fatal(s.Mask()) | |
| 62 | 57 | } | |
| 63 | - | c.data = []byte{0xff} | |
| 58 | + | read := func(data []byte) { | |
| 59 | + | c.EXPECT().ReadText(mock.Anything).Return(data, nil).Once() | |
| 60 | + | } | |
| 61 | + | read([]byte{0xff}) | |
| 64 | 62 | if changed, _ := s.Paste(c); changed { | |
| 65 | 63 | t.Fatal(s) | |
| 66 | 64 | } | |
| 67 | - | c.data = []byte(strings.Repeat("x", MaxClipboardBytes+1)) | |
| 65 | + | read([]byte(strings.Repeat("x", MaxClipboardBytes+1))) | |
| 68 | 66 | if changed, _ := s.Paste(c); changed { | |
| 69 | 67 | t.Fatal(s) | |
| 70 | 68 | } | |
| 71 | - | c.data = []byte("ok") | |
| 69 | + | read([]byte("ok")) | |
| 72 | 70 | if changed, _ := s.Paste(c); !changed || s.Value != "ok" { | |
| 73 | 71 | t.Fatal(s) | |
| 74 | 72 | } | |
| @@ -8,11 +8,6 @@ import ( | |||||
| 8 | "github.com/stretchr/testify/mock" | 8 | "github.com/stretchr/testify/mock" | ||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | - | type memoryClipboard struct{ data []byte } | |||
| 12 | - | ||||
| 13 | - | func (m *memoryClipboard) ReadText(limit int) ([]byte, error) { return m.data, nil } | |||
| 14 | - | func (m *memoryClipboard) WriteText(v []byte) error { m.data = append([]byte(nil), v...); return nil } | |||
| 15 | - | ||||
| 16 | func TestGraphemesAndIME(t *testing.T) { | 11 | func TestGraphemesAndIME(t *testing.T) { | ||
| 17 | s := State{} | 12 | s := State{} | ||
| 18 | s.Sync("e\u0301👩<U+200D>💻a") | 13 | s.Sync("e\u0301👩<U+200D>💻a") | ||
| @@ -53,22 +48,25 @@ func TestClipboardAndMask(t *testing.T) { | |||||
| 53 | s := State{} | 48 | s := State{} | ||
| 54 | s.Sync("s3crét") | 49 | s.Sync("s3crét") | ||
| 55 | s.Select(0, len(s.Value)) | 50 | s.Select(0, len(s.Value)) | ||
| 56 | - | c := &memoryClipboard{} | 51 | + | c := NewMockClipboard(t) // a masked copy must not write |
| 57 | - | if err := s.Copy(c, true); err != nil || len(c.data) != 0 { | 52 | + | if err := s.Copy(c, true); err != nil { |
| 58 | t.Fatal(err) | 53 | t.Fatal(err) | ||
| 59 | } | 54 | } | ||
| 60 | if s.Mask() != "••••••" { | 55 | if s.Mask() != "••••••" { | ||
| 61 | t.Fatal(s.Mask()) | 56 | t.Fatal(s.Mask()) | ||
| 62 | } | 57 | } | ||
| 63 | - | c.data = []byte{0xff} | 58 | + | read := func(data []byte) { |
| 59 | + | c.EXPECT().ReadText(mock.Anything).Return(data, nil).Once() | |||
| 60 | + | } | |||
| 61 | + | read([]byte{0xff}) | |||
| 64 | if changed, _ := s.Paste(c); changed { | 62 | if changed, _ := s.Paste(c); changed { | ||
| 65 | t.Fatal(s) | 63 | t.Fatal(s) | ||
| 66 | } | 64 | } | ||
| 67 | - | c.data = []byte(strings.Repeat("x", MaxClipboardBytes+1)) | 65 | + | read([]byte(strings.Repeat("x", MaxClipboardBytes+1))) |
| 68 | if changed, _ := s.Paste(c); changed { | 66 | if changed, _ := s.Paste(c); changed { | ||
| 69 | t.Fatal(s) | 67 | t.Fatal(s) | ||
| 70 | } | 68 | } | ||
| 71 | - | c.data = []byte("ok") | 69 | + | read([]byte("ok")) |
| 72 | if changed, _ := s.Paste(c); !changed || s.Value != "ok" { | 70 | if changed, _ := s.Paste(c); !changed || s.Value != "ok" { | ||
| 73 | t.Fatal(s) | 71 | t.Fatal(s) | ||
| 74 | } | 72 | } | ||
A internal/ui/AsyncClipboard_mock_test.go +161 -0
| @@ -0,0 +1,161 @@ | |||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |
| 2 | + | // github.com/vektra/mockery | |
| 3 | + | // template: testify | |
| 4 | + | ||
| 5 | + | package ui | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | "context" | |
| 9 | + | ||
| 10 | + | mock "github.com/stretchr/testify/mock" | |
| 11 | + | ) | |
| 12 | + | ||
| 13 | + | // NewMockAsyncClipboard creates a new instance of MockAsyncClipboard. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 14 | + | // The first argument is typically a *testing.T value. | |
| 15 | + | func NewMockAsyncClipboard(t interface { | |
| 16 | + | mock.TestingT | |
| 17 | + | Cleanup(func()) | |
| 18 | + | }) *MockAsyncClipboard { | |
| 19 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 20 | + | helper.Helper() | |
| 21 | + | } | |
| 22 | + | ||
| 23 | + | mock := &MockAsyncClipboard{} | |
| 24 | + | mock.Mock.Test(t) | |
| 25 | + | ||
| 26 | + | t.Cleanup(func() { | |
| 27 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 28 | + | helper.Helper() | |
| 29 | + | } | |
| 30 | + | mock.AssertExpectations(t) | |
| 31 | + | }) | |
| 32 | + | ||
| 33 | + | return mock | |
| 34 | + | } | |
| 35 | + | ||
| 36 | + | // MockAsyncClipboard is an autogenerated mock type for the AsyncClipboard type | |
| 37 | + | type MockAsyncClipboard struct { | |
| 38 | + | mock.Mock | |
| 39 | + | } | |
| 40 | + | ||
| 41 | + | type MockAsyncClipboard_Expecter struct { | |
| 42 | + | mock *mock.Mock | |
| 43 | + | } | |
| 44 | + | ||
| 45 | + | func (_m *MockAsyncClipboard) EXPECT() *MockAsyncClipboard_Expecter { | |
| 46 | + | return &MockAsyncClipboard_Expecter{mock: &_m.Mock} | |
| 47 | + | } | |
| 48 | + | ||
| 49 | + | // ReadTextAsync provides a mock function for the type MockAsyncClipboard | |
| 50 | + | func (_mock *MockAsyncClipboard) ReadTextAsync(ctx context.Context, limit int, deliver func([]byte, error)) error { | |
| 51 | + | ret := _mock.Called(ctx, limit, deliver) | |
| 52 | + | ||
| 53 | + | if len(ret) == 0 { | |
| 54 | + | panic("no return value specified for ReadTextAsync") | |
| 55 | + | } | |
| 56 | + | ||
| 57 | + | var r0 error | |
| 58 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, int, func([]byte, error)) error); ok { | |
| 59 | + | r0 = returnFunc(ctx, limit, deliver) | |
| 60 | + | } else { | |
| 61 | + | r0 = ret.Error(0) | |
| 62 | + | } | |
| 63 | + | return r0 | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | // MockAsyncClipboard_ReadTextAsync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadTextAsync' | |
| 67 | + | type MockAsyncClipboard_ReadTextAsync_Call struct { | |
| 68 | + | *mock.Call | |
| 69 | + | } | |
| 70 | + | ||
| 71 | + | // ReadTextAsync is a helper method to define mock.On call | |
| 72 | + | // - ctx context.Context | |
| 73 | + | // - limit int | |
| 74 | + | // - deliver func([]byte, error) | |
| 75 | + | func (_e *MockAsyncClipboard_Expecter) ReadTextAsync(ctx any, limit any, deliver any) *MockAsyncClipboard_ReadTextAsync_Call { | |
| 76 | + | return &MockAsyncClipboard_ReadTextAsync_Call{Call: _e.mock.On("ReadTextAsync", ctx, limit, deliver)} | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) Run(run func(ctx context.Context, limit int, deliver func([]byte, error))) *MockAsyncClipboard_ReadTextAsync_Call { | |
| 80 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 81 | + | var arg0 context.Context | |
| 82 | + | if args[0] != nil { | |
| 83 | + | arg0 = args[0].(context.Context) | |
| 84 | + | } | |
| 85 | + | var arg1 int | |
| 86 | + | if args[1] != nil { | |
| 87 | + | arg1 = args[1].(int) | |
| 88 | + | } | |
| 89 | + | var arg2 func([]byte, error) | |
| 90 | + | if args[2] != nil { | |
| 91 | + | arg2 = args[2].(func([]byte, error)) | |
| 92 | + | } | |
| 93 | + | run( | |
| 94 | + | arg0, | |
| 95 | + | arg1, | |
| 96 | + | arg2, | |
| 97 | + | ) | |
| 98 | + | }) | |
| 99 | + | return _c | |
| 100 | + | } | |
| 101 | + | ||
| 102 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) Return(err error) *MockAsyncClipboard_ReadTextAsync_Call { | |
| 103 | + | _c.Call.Return(err) | |
| 104 | + | return _c | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) RunAndReturn(run func(ctx context.Context, limit int, deliver func([]byte, error)) error) *MockAsyncClipboard_ReadTextAsync_Call { | |
| 108 | + | _c.Call.Return(run) | |
| 109 | + | return _c | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | // WriteText provides a mock function for the type MockAsyncClipboard | |
| 113 | + | func (_mock *MockAsyncClipboard) WriteText(bytes []byte) error { | |
| 114 | + | ret := _mock.Called(bytes) | |
| 115 | + | ||
| 116 | + | if len(ret) == 0 { | |
| 117 | + | panic("no return value specified for WriteText") | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | var r0 error | |
| 121 | + | if returnFunc, ok := ret.Get(0).(func([]byte) error); ok { | |
| 122 | + | r0 = returnFunc(bytes) | |
| 123 | + | } else { | |
| 124 | + | r0 = ret.Error(0) | |
| 125 | + | } | |
| 126 | + | return r0 | |
| 127 | + | } | |
| 128 | + | ||
| 129 | + | // MockAsyncClipboard_WriteText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteText' | |
| 130 | + | type MockAsyncClipboard_WriteText_Call struct { | |
| 131 | + | *mock.Call | |
| 132 | + | } | |
| 133 | + | ||
| 134 | + | // WriteText is a helper method to define mock.On call | |
| 135 | + | // - bytes []byte | |
| 136 | + | func (_e *MockAsyncClipboard_Expecter) WriteText(bytes any) *MockAsyncClipboard_WriteText_Call { | |
| 137 | + | return &MockAsyncClipboard_WriteText_Call{Call: _e.mock.On("WriteText", bytes)} | |
| 138 | + | } | |
| 139 | + | ||
| 140 | + | func (_c *MockAsyncClipboard_WriteText_Call) Run(run func(bytes []byte)) *MockAsyncClipboard_WriteText_Call { | |
| 141 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 142 | + | var arg0 []byte | |
| 143 | + | if args[0] != nil { | |
| 144 | + | arg0 = args[0].([]byte) | |
| 145 | + | } | |
| 146 | + | run( | |
| 147 | + | arg0, | |
| 148 | + | ) | |
| 149 | + | }) | |
| 150 | + | return _c | |
| 151 | + | } | |
| 152 | + | ||
| 153 | + | func (_c *MockAsyncClipboard_WriteText_Call) Return(err error) *MockAsyncClipboard_WriteText_Call { | |
| 154 | + | _c.Call.Return(err) | |
| 155 | + | return _c | |
| 156 | + | } | |
| 157 | + | ||
| 158 | + | func (_c *MockAsyncClipboard_WriteText_Call) RunAndReturn(run func(bytes []byte) error) *MockAsyncClipboard_WriteText_Call { | |
| 159 | + | _c.Call.Return(run) | |
| 160 | + | return _c | |
| 161 | + | } | |
| @@ -0,0 +1,161 @@ | |||||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |||
| 2 | + | // github.com/vektra/mockery | |||
| 3 | + | // template: testify | |||
| 4 | + | ||||
| 5 | + | package ui | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | "context" | |||
| 9 | + | ||||
| 10 | + | mock "github.com/stretchr/testify/mock" | |||
| 11 | + | ) | |||
| 12 | + | ||||
| 13 | + | // NewMockAsyncClipboard creates a new instance of MockAsyncClipboard. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |||
| 14 | + | // The first argument is typically a *testing.T value. | |||
| 15 | + | func NewMockAsyncClipboard(t interface { | |||
| 16 | + | mock.TestingT | |||
| 17 | + | Cleanup(func()) | |||
| 18 | + | }) *MockAsyncClipboard { | |||
| 19 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 20 | + | helper.Helper() | |||
| 21 | + | } | |||
| 22 | + | ||||
| 23 | + | mock := &MockAsyncClipboard{} | |||
| 24 | + | mock.Mock.Test(t) | |||
| 25 | + | ||||
| 26 | + | t.Cleanup(func() { | |||
| 27 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 28 | + | helper.Helper() | |||
| 29 | + | } | |||
| 30 | + | mock.AssertExpectations(t) | |||
| 31 | + | }) | |||
| 32 | + | ||||
| 33 | + | return mock | |||
| 34 | + | } | |||
| 35 | + | ||||
| 36 | + | // MockAsyncClipboard is an autogenerated mock type for the AsyncClipboard type | |||
| 37 | + | type MockAsyncClipboard struct { | |||
| 38 | + | mock.Mock | |||
| 39 | + | } | |||
| 40 | + | ||||
| 41 | + | type MockAsyncClipboard_Expecter struct { | |||
| 42 | + | mock *mock.Mock | |||
| 43 | + | } | |||
| 44 | + | ||||
| 45 | + | func (_m *MockAsyncClipboard) EXPECT() *MockAsyncClipboard_Expecter { | |||
| 46 | + | return &MockAsyncClipboard_Expecter{mock: &_m.Mock} | |||
| 47 | + | } | |||
| 48 | + | ||||
| 49 | + | // ReadTextAsync provides a mock function for the type MockAsyncClipboard | |||
| 50 | + | func (_mock *MockAsyncClipboard) ReadTextAsync(ctx context.Context, limit int, deliver func([]byte, error)) error { | |||
| 51 | + | ret := _mock.Called(ctx, limit, deliver) | |||
| 52 | + | ||||
| 53 | + | if len(ret) == 0 { | |||
| 54 | + | panic("no return value specified for ReadTextAsync") | |||
| 55 | + | } | |||
| 56 | + | ||||
| 57 | + | var r0 error | |||
| 58 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, int, func([]byte, error)) error); ok { | |||
| 59 | + | r0 = returnFunc(ctx, limit, deliver) | |||
| 60 | + | } else { | |||
| 61 | + | r0 = ret.Error(0) | |||
| 62 | + | } | |||
| 63 | + | return r0 | |||
| 64 | + | } | |||
| 65 | + | ||||
| 66 | + | // MockAsyncClipboard_ReadTextAsync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadTextAsync' | |||
| 67 | + | type MockAsyncClipboard_ReadTextAsync_Call struct { | |||
| 68 | + | *mock.Call | |||
| 69 | + | } | |||
| 70 | + | ||||
| 71 | + | // ReadTextAsync is a helper method to define mock.On call | |||
| 72 | + | // - ctx context.Context | |||
| 73 | + | // - limit int | |||
| 74 | + | // - deliver func([]byte, error) | |||
| 75 | + | func (_e *MockAsyncClipboard_Expecter) ReadTextAsync(ctx any, limit any, deliver any) *MockAsyncClipboard_ReadTextAsync_Call { | |||
| 76 | + | return &MockAsyncClipboard_ReadTextAsync_Call{Call: _e.mock.On("ReadTextAsync", ctx, limit, deliver)} | |||
| 77 | + | } | |||
| 78 | + | ||||
| 79 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) Run(run func(ctx context.Context, limit int, deliver func([]byte, error))) *MockAsyncClipboard_ReadTextAsync_Call { | |||
| 80 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 81 | + | var arg0 context.Context | |||
| 82 | + | if args[0] != nil { | |||
| 83 | + | arg0 = args[0].(context.Context) | |||
| 84 | + | } | |||
| 85 | + | var arg1 int | |||
| 86 | + | if args[1] != nil { | |||
| 87 | + | arg1 = args[1].(int) | |||
| 88 | + | } | |||
| 89 | + | var arg2 func([]byte, error) | |||
| 90 | + | if args[2] != nil { | |||
| 91 | + | arg2 = args[2].(func([]byte, error)) | |||
| 92 | + | } | |||
| 93 | + | run( | |||
| 94 | + | arg0, | |||
| 95 | + | arg1, | |||
| 96 | + | arg2, | |||
| 97 | + | ) | |||
| 98 | + | }) | |||
| 99 | + | return _c | |||
| 100 | + | } | |||
| 101 | + | ||||
| 102 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) Return(err error) *MockAsyncClipboard_ReadTextAsync_Call { | |||
| 103 | + | _c.Call.Return(err) | |||
| 104 | + | return _c | |||
| 105 | + | } | |||
| 106 | + | ||||
| 107 | + | func (_c *MockAsyncClipboard_ReadTextAsync_Call) RunAndReturn(run func(ctx context.Context, limit int, deliver func([]byte, error)) error) *MockAsyncClipboard_ReadTextAsync_Call { | |||
| 108 | + | _c.Call.Return(run) | |||
| 109 | + | return _c | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | // WriteText provides a mock function for the type MockAsyncClipboard | |||
| 113 | + | func (_mock *MockAsyncClipboard) WriteText(bytes []byte) error { | |||
| 114 | + | ret := _mock.Called(bytes) | |||
| 115 | + | ||||
| 116 | + | if len(ret) == 0 { | |||
| 117 | + | panic("no return value specified for WriteText") | |||
| 118 | + | } | |||
| 119 | + | ||||
| 120 | + | var r0 error | |||
| 121 | + | if returnFunc, ok := ret.Get(0).(func([]byte) error); ok { | |||
| 122 | + | r0 = returnFunc(bytes) | |||
| 123 | + | } else { | |||
| 124 | + | r0 = ret.Error(0) | |||
| 125 | + | } | |||
| 126 | + | return r0 | |||
| 127 | + | } | |||
| 128 | + | ||||
| 129 | + | // MockAsyncClipboard_WriteText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteText' | |||
| 130 | + | type MockAsyncClipboard_WriteText_Call struct { | |||
| 131 | + | *mock.Call | |||
| 132 | + | } | |||
| 133 | + | ||||
| 134 | + | // WriteText is a helper method to define mock.On call | |||
| 135 | + | // - bytes []byte | |||
| 136 | + | func (_e *MockAsyncClipboard_Expecter) WriteText(bytes any) *MockAsyncClipboard_WriteText_Call { | |||
| 137 | + | return &MockAsyncClipboard_WriteText_Call{Call: _e.mock.On("WriteText", bytes)} | |||
| 138 | + | } | |||
| 139 | + | ||||
| 140 | + | func (_c *MockAsyncClipboard_WriteText_Call) Run(run func(bytes []byte)) *MockAsyncClipboard_WriteText_Call { | |||
| 141 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 142 | + | var arg0 []byte | |||
| 143 | + | if args[0] != nil { | |||
| 144 | + | arg0 = args[0].([]byte) | |||
| 145 | + | } | |||
| 146 | + | run( | |||
| 147 | + | arg0, | |||
| 148 | + | ) | |||
| 149 | + | }) | |||
| 150 | + | return _c | |||
| 151 | + | } | |||
| 152 | + | ||||
| 153 | + | func (_c *MockAsyncClipboard_WriteText_Call) Return(err error) *MockAsyncClipboard_WriteText_Call { | |||
| 154 | + | _c.Call.Return(err) | |||
| 155 | + | return _c | |||
| 156 | + | } | |||
| 157 | + | ||||
| 158 | + | func (_c *MockAsyncClipboard_WriteText_Call) RunAndReturn(run func(bytes []byte) error) *MockAsyncClipboard_WriteText_Call { | |||
| 159 | + | _c.Call.Return(run) | |||
| 160 | + | return _c | |||
| 161 | + | } | |||
A internal/ui/Clipboard_mock_test.go +158 -0
| @@ -0,0 +1,158 @@ | |||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |
| 2 | + | // github.com/vektra/mockery | |
| 3 | + | // template: testify | |
| 4 | + | ||
| 5 | + | package ui | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | mock "github.com/stretchr/testify/mock" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | // NewMockClipboard creates a new instance of MockClipboard. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 12 | + | // The first argument is typically a *testing.T value. | |
| 13 | + | func NewMockClipboard(t interface { | |
| 14 | + | mock.TestingT | |
| 15 | + | Cleanup(func()) | |
| 16 | + | }) *MockClipboard { | |
| 17 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 18 | + | helper.Helper() | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | mock := &MockClipboard{} | |
| 22 | + | mock.Mock.Test(t) | |
| 23 | + | ||
| 24 | + | t.Cleanup(func() { | |
| 25 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 26 | + | helper.Helper() | |
| 27 | + | } | |
| 28 | + | mock.AssertExpectations(t) | |
| 29 | + | }) | |
| 30 | + | ||
| 31 | + | return mock | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | // MockClipboard is an autogenerated mock type for the Clipboard type | |
| 35 | + | type MockClipboard struct { | |
| 36 | + | mock.Mock | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | type MockClipboard_Expecter struct { | |
| 40 | + | mock *mock.Mock | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | func (_m *MockClipboard) EXPECT() *MockClipboard_Expecter { | |
| 44 | + | return &MockClipboard_Expecter{mock: &_m.Mock} | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | // ReadText provides a mock function for the type MockClipboard | |
| 48 | + | func (_mock *MockClipboard) ReadText(limit int) ([]byte, error) { | |
| 49 | + | ret := _mock.Called(limit) | |
| 50 | + | ||
| 51 | + | if len(ret) == 0 { | |
| 52 | + | panic("no return value specified for ReadText") | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | var r0 []byte | |
| 56 | + | var r1 error | |
| 57 | + | if returnFunc, ok := ret.Get(0).(func(int) ([]byte, error)); ok { | |
| 58 | + | return returnFunc(limit) | |
| 59 | + | } | |
| 60 | + | if returnFunc, ok := ret.Get(0).(func(int) []byte); ok { | |
| 61 | + | r0 = returnFunc(limit) | |
| 62 | + | } else { | |
| 63 | + | if ret.Get(0) != nil { | |
| 64 | + | r0 = ret.Get(0).([]byte) | |
| 65 | + | } | |
| 66 | + | } | |
| 67 | + | if returnFunc, ok := ret.Get(1).(func(int) error); ok { | |
| 68 | + | r1 = returnFunc(limit) | |
| 69 | + | } else { | |
| 70 | + | r1 = ret.Error(1) | |
| 71 | + | } | |
| 72 | + | return r0, r1 | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | // MockClipboard_ReadText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadText' | |
| 76 | + | type MockClipboard_ReadText_Call struct { | |
| 77 | + | *mock.Call | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | // ReadText is a helper method to define mock.On call | |
| 81 | + | // - limit int | |
| 82 | + | func (_e *MockClipboard_Expecter) ReadText(limit any) *MockClipboard_ReadText_Call { | |
| 83 | + | return &MockClipboard_ReadText_Call{Call: _e.mock.On("ReadText", limit)} | |
| 84 | + | } | |
| 85 | + | ||
| 86 | + | func (_c *MockClipboard_ReadText_Call) Run(run func(limit int)) *MockClipboard_ReadText_Call { | |
| 87 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 88 | + | var arg0 int | |
| 89 | + | if args[0] != nil { | |
| 90 | + | arg0 = args[0].(int) | |
| 91 | + | } | |
| 92 | + | run( | |
| 93 | + | arg0, | |
| 94 | + | ) | |
| 95 | + | }) | |
| 96 | + | return _c | |
| 97 | + | } | |
| 98 | + | ||
| 99 | + | func (_c *MockClipboard_ReadText_Call) Return(bytes []byte, err error) *MockClipboard_ReadText_Call { | |
| 100 | + | _c.Call.Return(bytes, err) | |
| 101 | + | return _c | |
| 102 | + | } | |
| 103 | + | ||
| 104 | + | func (_c *MockClipboard_ReadText_Call) RunAndReturn(run func(limit int) ([]byte, error)) *MockClipboard_ReadText_Call { | |
| 105 | + | _c.Call.Return(run) | |
| 106 | + | return _c | |
| 107 | + | } | |
| 108 | + | ||
| 109 | + | // WriteText provides a mock function for the type MockClipboard | |
| 110 | + | func (_mock *MockClipboard) WriteText(bytes []byte) error { | |
| 111 | + | ret := _mock.Called(bytes) | |
| 112 | + | ||
| 113 | + | if len(ret) == 0 { | |
| 114 | + | panic("no return value specified for WriteText") | |
| 115 | + | } | |
| 116 | + | ||
| 117 | + | var r0 error | |
| 118 | + | if returnFunc, ok := ret.Get(0).(func([]byte) error); ok { | |
| 119 | + | r0 = returnFunc(bytes) | |
| 120 | + | } else { | |
| 121 | + | r0 = ret.Error(0) | |
| 122 | + | } | |
| 123 | + | return r0 | |
| 124 | + | } | |
| 125 | + | ||
| 126 | + | // MockClipboard_WriteText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteText' | |
| 127 | + | type MockClipboard_WriteText_Call struct { | |
| 128 | + | *mock.Call | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | // WriteText is a helper method to define mock.On call | |
| 132 | + | // - bytes []byte | |
| 133 | + | func (_e *MockClipboard_Expecter) WriteText(bytes any) *MockClipboard_WriteText_Call { | |
| 134 | + | return &MockClipboard_WriteText_Call{Call: _e.mock.On("WriteText", bytes)} | |
| 135 | + | } | |
| 136 | + | ||
| 137 | + | func (_c *MockClipboard_WriteText_Call) Run(run func(bytes []byte)) *MockClipboard_WriteText_Call { | |
| 138 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 139 | + | var arg0 []byte | |
| 140 | + | if args[0] != nil { | |
| 141 | + | arg0 = args[0].([]byte) | |
| 142 | + | } | |
| 143 | + | run( | |
| 144 | + | arg0, | |
| 145 | + | ) | |
| 146 | + | }) | |
| 147 | + | return _c | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | func (_c *MockClipboard_WriteText_Call) Return(err error) *MockClipboard_WriteText_Call { | |
| 151 | + | _c.Call.Return(err) | |
| 152 | + | return _c | |
| 153 | + | } | |
| 154 | + | ||
| 155 | + | func (_c *MockClipboard_WriteText_Call) RunAndReturn(run func(bytes []byte) error) *MockClipboard_WriteText_Call { | |
| 156 | + | _c.Call.Return(run) | |
| 157 | + | return _c | |
| 158 | + | } | |
| @@ -0,0 +1,158 @@ | |||||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |||
| 2 | + | // github.com/vektra/mockery | |||
| 3 | + | // template: testify | |||
| 4 | + | ||||
| 5 | + | package ui | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | mock "github.com/stretchr/testify/mock" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | // NewMockClipboard creates a new instance of MockClipboard. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |||
| 12 | + | // The first argument is typically a *testing.T value. | |||
| 13 | + | func NewMockClipboard(t interface { | |||
| 14 | + | mock.TestingT | |||
| 15 | + | Cleanup(func()) | |||
| 16 | + | }) *MockClipboard { | |||
| 17 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 18 | + | helper.Helper() | |||
| 19 | + | } | |||
| 20 | + | ||||
| 21 | + | mock := &MockClipboard{} | |||
| 22 | + | mock.Mock.Test(t) | |||
| 23 | + | ||||
| 24 | + | t.Cleanup(func() { | |||
| 25 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 26 | + | helper.Helper() | |||
| 27 | + | } | |||
| 28 | + | mock.AssertExpectations(t) | |||
| 29 | + | }) | |||
| 30 | + | ||||
| 31 | + | return mock | |||
| 32 | + | } | |||
| 33 | + | ||||
| 34 | + | // MockClipboard is an autogenerated mock type for the Clipboard type | |||
| 35 | + | type MockClipboard struct { | |||
| 36 | + | mock.Mock | |||
| 37 | + | } | |||
| 38 | + | ||||
| 39 | + | type MockClipboard_Expecter struct { | |||
| 40 | + | mock *mock.Mock | |||
| 41 | + | } | |||
| 42 | + | ||||
| 43 | + | func (_m *MockClipboard) EXPECT() *MockClipboard_Expecter { | |||
| 44 | + | return &MockClipboard_Expecter{mock: &_m.Mock} | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | // ReadText provides a mock function for the type MockClipboard | |||
| 48 | + | func (_mock *MockClipboard) ReadText(limit int) ([]byte, error) { | |||
| 49 | + | ret := _mock.Called(limit) | |||
| 50 | + | ||||
| 51 | + | if len(ret) == 0 { | |||
| 52 | + | panic("no return value specified for ReadText") | |||
| 53 | + | } | |||
| 54 | + | ||||
| 55 | + | var r0 []byte | |||
| 56 | + | var r1 error | |||
| 57 | + | if returnFunc, ok := ret.Get(0).(func(int) ([]byte, error)); ok { | |||
| 58 | + | return returnFunc(limit) | |||
| 59 | + | } | |||
| 60 | + | if returnFunc, ok := ret.Get(0).(func(int) []byte); ok { | |||
| 61 | + | r0 = returnFunc(limit) | |||
| 62 | + | } else { | |||
| 63 | + | if ret.Get(0) != nil { | |||
| 64 | + | r0 = ret.Get(0).([]byte) | |||
| 65 | + | } | |||
| 66 | + | } | |||
| 67 | + | if returnFunc, ok := ret.Get(1).(func(int) error); ok { | |||
| 68 | + | r1 = returnFunc(limit) | |||
| 69 | + | } else { | |||
| 70 | + | r1 = ret.Error(1) | |||
| 71 | + | } | |||
| 72 | + | return r0, r1 | |||
| 73 | + | } | |||
| 74 | + | ||||
| 75 | + | // MockClipboard_ReadText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadText' | |||
| 76 | + | type MockClipboard_ReadText_Call struct { | |||
| 77 | + | *mock.Call | |||
| 78 | + | } | |||
| 79 | + | ||||
| 80 | + | // ReadText is a helper method to define mock.On call | |||
| 81 | + | // - limit int | |||
| 82 | + | func (_e *MockClipboard_Expecter) ReadText(limit any) *MockClipboard_ReadText_Call { | |||
| 83 | + | return &MockClipboard_ReadText_Call{Call: _e.mock.On("ReadText", limit)} | |||
| 84 | + | } | |||
| 85 | + | ||||
| 86 | + | func (_c *MockClipboard_ReadText_Call) Run(run func(limit int)) *MockClipboard_ReadText_Call { | |||
| 87 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 88 | + | var arg0 int | |||
| 89 | + | if args[0] != nil { | |||
| 90 | + | arg0 = args[0].(int) | |||
| 91 | + | } | |||
| 92 | + | run( | |||
| 93 | + | arg0, | |||
| 94 | + | ) | |||
| 95 | + | }) | |||
| 96 | + | return _c | |||
| 97 | + | } | |||
| 98 | + | ||||
| 99 | + | func (_c *MockClipboard_ReadText_Call) Return(bytes []byte, err error) *MockClipboard_ReadText_Call { | |||
| 100 | + | _c.Call.Return(bytes, err) | |||
| 101 | + | return _c | |||
| 102 | + | } | |||
| 103 | + | ||||
| 104 | + | func (_c *MockClipboard_ReadText_Call) RunAndReturn(run func(limit int) ([]byte, error)) *MockClipboard_ReadText_Call { | |||
| 105 | + | _c.Call.Return(run) | |||
| 106 | + | return _c | |||
| 107 | + | } | |||
| 108 | + | ||||
| 109 | + | // WriteText provides a mock function for the type MockClipboard | |||
| 110 | + | func (_mock *MockClipboard) WriteText(bytes []byte) error { | |||
| 111 | + | ret := _mock.Called(bytes) | |||
| 112 | + | ||||
| 113 | + | if len(ret) == 0 { | |||
| 114 | + | panic("no return value specified for WriteText") | |||
| 115 | + | } | |||
| 116 | + | ||||
| 117 | + | var r0 error | |||
| 118 | + | if returnFunc, ok := ret.Get(0).(func([]byte) error); ok { | |||
| 119 | + | r0 = returnFunc(bytes) | |||
| 120 | + | } else { | |||
| 121 | + | r0 = ret.Error(0) | |||
| 122 | + | } | |||
| 123 | + | return r0 | |||
| 124 | + | } | |||
| 125 | + | ||||
| 126 | + | // MockClipboard_WriteText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteText' | |||
| 127 | + | type MockClipboard_WriteText_Call struct { | |||
| 128 | + | *mock.Call | |||
| 129 | + | } | |||
| 130 | + | ||||
| 131 | + | // WriteText is a helper method to define mock.On call | |||
| 132 | + | // - bytes []byte | |||
| 133 | + | func (_e *MockClipboard_Expecter) WriteText(bytes any) *MockClipboard_WriteText_Call { | |||
| 134 | + | return &MockClipboard_WriteText_Call{Call: _e.mock.On("WriteText", bytes)} | |||
| 135 | + | } | |||
| 136 | + | ||||
| 137 | + | func (_c *MockClipboard_WriteText_Call) Run(run func(bytes []byte)) *MockClipboard_WriteText_Call { | |||
| 138 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 139 | + | var arg0 []byte | |||
| 140 | + | if args[0] != nil { | |||
| 141 | + | arg0 = args[0].([]byte) | |||
| 142 | + | } | |||
| 143 | + | run( | |||
| 144 | + | arg0, | |||
| 145 | + | ) | |||
| 146 | + | }) | |||
| 147 | + | return _c | |||
| 148 | + | } | |||
| 149 | + | ||||
| 150 | + | func (_c *MockClipboard_WriteText_Call) Return(err error) *MockClipboard_WriteText_Call { | |||
| 151 | + | _c.Call.Return(err) | |||
| 152 | + | return _c | |||
| 153 | + | } | |||
| 154 | + | ||||
| 155 | + | func (_c *MockClipboard_WriteText_Call) RunAndReturn(run func(bytes []byte) error) *MockClipboard_WriteText_Call { | |||
| 156 | + | _c.Call.Return(run) | |||
| 157 | + | return _c | |||
| 158 | + | } | |||
A internal/ui/IME_mock_test.go +267 -0
| @@ -0,0 +1,267 @@ | |||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |
| 2 | + | // github.com/vektra/mockery | |
| 3 | + | // template: testify | |
| 4 | + | ||
| 5 | + | package ui | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | mock "github.com/stretchr/testify/mock" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | // NewMockIME creates a new instance of MockIME. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 12 | + | // The first argument is typically a *testing.T value. | |
| 13 | + | func NewMockIME(t interface { | |
| 14 | + | mock.TestingT | |
| 15 | + | Cleanup(func()) | |
| 16 | + | }) *MockIME { | |
| 17 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 18 | + | helper.Helper() | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | mock := &MockIME{} | |
| 22 | + | mock.Mock.Test(t) | |
| 23 | + | ||
| 24 | + | t.Cleanup(func() { | |
| 25 | + | if helper, ok := t.(interface{ Helper() }); ok { | |
| 26 | + | helper.Helper() | |
| 27 | + | } | |
| 28 | + | mock.AssertExpectations(t) | |
| 29 | + | }) | |
| 30 | + | ||
| 31 | + | return mock | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | // MockIME is an autogenerated mock type for the IME type | |
| 35 | + | type MockIME struct { | |
| 36 | + | mock.Mock | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | type MockIME_Expecter struct { | |
| 40 | + | mock *mock.Mock | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | func (_m *MockIME) EXPECT() *MockIME_Expecter { | |
| 44 | + | return &MockIME_Expecter{mock: &_m.Mock} | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | // ContentType provides a mock function for the type MockIME | |
| 48 | + | func (_mock *MockIME) ContentType(password bool, multiline bool) { | |
| 49 | + | _mock.Called(password, multiline) | |
| 50 | + | return | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | // MockIME_ContentType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ContentType' | |
| 54 | + | type MockIME_ContentType_Call struct { | |
| 55 | + | *mock.Call | |
| 56 | + | } | |
| 57 | + | ||
| 58 | + | // ContentType is a helper method to define mock.On call | |
| 59 | + | // - password bool | |
| 60 | + | // - multiline bool | |
| 61 | + | func (_e *MockIME_Expecter) ContentType(password any, multiline any) *MockIME_ContentType_Call { | |
| 62 | + | return &MockIME_ContentType_Call{Call: _e.mock.On("ContentType", password, multiline)} | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | func (_c *MockIME_ContentType_Call) Run(run func(password bool, multiline bool)) *MockIME_ContentType_Call { | |
| 66 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 67 | + | var arg0 bool | |
| 68 | + | if args[0] != nil { | |
| 69 | + | arg0 = args[0].(bool) | |
| 70 | + | } | |
| 71 | + | var arg1 bool | |
| 72 | + | if args[1] != nil { | |
| 73 | + | arg1 = args[1].(bool) | |
| 74 | + | } | |
| 75 | + | run( | |
| 76 | + | arg0, | |
| 77 | + | arg1, | |
| 78 | + | ) | |
| 79 | + | }) | |
| 80 | + | return _c | |
| 81 | + | } | |
| 82 | + | ||
| 83 | + | func (_c *MockIME_ContentType_Call) Return() *MockIME_ContentType_Call { | |
| 84 | + | _c.Call.Return() | |
| 85 | + | return _c | |
| 86 | + | } | |
| 87 | + | ||
| 88 | + | func (_c *MockIME_ContentType_Call) RunAndReturn(run func(password bool, multiline bool)) *MockIME_ContentType_Call { | |
| 89 | + | _c.Run(run) | |
| 90 | + | return _c | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | // CursorRect provides a mock function for the type MockIME | |
| 94 | + | func (_mock *MockIME) CursorRect(x float64, y float64, w float64, h float64) { | |
| 95 | + | _mock.Called(x, y, w, h) | |
| 96 | + | return | |
| 97 | + | } | |
| 98 | + | ||
| 99 | + | // MockIME_CursorRect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CursorRect' | |
| 100 | + | type MockIME_CursorRect_Call struct { | |
| 101 | + | *mock.Call | |
| 102 | + | } | |
| 103 | + | ||
| 104 | + | // CursorRect is a helper method to define mock.On call | |
| 105 | + | // - x float64 | |
| 106 | + | // - y float64 | |
| 107 | + | // - w float64 | |
| 108 | + | // - h float64 | |
| 109 | + | func (_e *MockIME_Expecter) CursorRect(x any, y any, w any, h any) *MockIME_CursorRect_Call { | |
| 110 | + | return &MockIME_CursorRect_Call{Call: _e.mock.On("CursorRect", x, y, w, h)} | |
| 111 | + | } | |
| 112 | + | ||
| 113 | + | func (_c *MockIME_CursorRect_Call) Run(run func(x float64, y float64, w float64, h float64)) *MockIME_CursorRect_Call { | |
| 114 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 115 | + | var arg0 float64 | |
| 116 | + | if args[0] != nil { | |
| 117 | + | arg0 = args[0].(float64) | |
| 118 | + | } | |
| 119 | + | var arg1 float64 | |
| 120 | + | if args[1] != nil { | |
| 121 | + | arg1 = args[1].(float64) | |
| 122 | + | } | |
| 123 | + | var arg2 float64 | |
| 124 | + | if args[2] != nil { | |
| 125 | + | arg2 = args[2].(float64) | |
| 126 | + | } | |
| 127 | + | var arg3 float64 | |
| 128 | + | if args[3] != nil { | |
| 129 | + | arg3 = args[3].(float64) | |
| 130 | + | } | |
| 131 | + | run( | |
| 132 | + | arg0, | |
| 133 | + | arg1, | |
| 134 | + | arg2, | |
| 135 | + | arg3, | |
| 136 | + | ) | |
| 137 | + | }) | |
| 138 | + | return _c | |
| 139 | + | } | |
| 140 | + | ||
| 141 | + | func (_c *MockIME_CursorRect_Call) Return() *MockIME_CursorRect_Call { | |
| 142 | + | _c.Call.Return() | |
| 143 | + | return _c | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | func (_c *MockIME_CursorRect_Call) RunAndReturn(run func(x float64, y float64, w float64, h float64)) *MockIME_CursorRect_Call { | |
| 147 | + | _c.Run(run) | |
| 148 | + | return _c | |
| 149 | + | } | |
| 150 | + | ||
| 151 | + | // Disable provides a mock function for the type MockIME | |
| 152 | + | func (_mock *MockIME) Disable() { | |
| 153 | + | _mock.Called() | |
| 154 | + | return | |
| 155 | + | } | |
| 156 | + | ||
| 157 | + | // MockIME_Disable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Disable' | |
| 158 | + | type MockIME_Disable_Call struct { | |
| 159 | + | *mock.Call | |
| 160 | + | } | |
| 161 | + | ||
| 162 | + | // Disable is a helper method to define mock.On call | |
| 163 | + | func (_e *MockIME_Expecter) Disable() *MockIME_Disable_Call { | |
| 164 | + | return &MockIME_Disable_Call{Call: _e.mock.On("Disable")} | |
| 165 | + | } | |
| 166 | + | ||
| 167 | + | func (_c *MockIME_Disable_Call) Run(run func()) *MockIME_Disable_Call { | |
| 168 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 169 | + | run() | |
| 170 | + | }) | |
| 171 | + | return _c | |
| 172 | + | } | |
| 173 | + | ||
| 174 | + | func (_c *MockIME_Disable_Call) Return() *MockIME_Disable_Call { | |
| 175 | + | _c.Call.Return() | |
| 176 | + | return _c | |
| 177 | + | } | |
| 178 | + | ||
| 179 | + | func (_c *MockIME_Disable_Call) RunAndReturn(run func()) *MockIME_Disable_Call { | |
| 180 | + | _c.Run(run) | |
| 181 | + | return _c | |
| 182 | + | } | |
| 183 | + | ||
| 184 | + | // Enable provides a mock function for the type MockIME | |
| 185 | + | func (_mock *MockIME) Enable() { | |
| 186 | + | _mock.Called() | |
| 187 | + | return | |
| 188 | + | } | |
| 189 | + | ||
| 190 | + | // MockIME_Enable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Enable' | |
| 191 | + | type MockIME_Enable_Call struct { | |
| 192 | + | *mock.Call | |
| 193 | + | } | |
| 194 | + | ||
| 195 | + | // Enable is a helper method to define mock.On call | |
| 196 | + | func (_e *MockIME_Expecter) Enable() *MockIME_Enable_Call { | |
| 197 | + | return &MockIME_Enable_Call{Call: _e.mock.On("Enable")} | |
| 198 | + | } | |
| 199 | + | ||
| 200 | + | func (_c *MockIME_Enable_Call) Run(run func()) *MockIME_Enable_Call { | |
| 201 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 202 | + | run() | |
| 203 | + | }) | |
| 204 | + | return _c | |
| 205 | + | } | |
| 206 | + | ||
| 207 | + | func (_c *MockIME_Enable_Call) Return() *MockIME_Enable_Call { | |
| 208 | + | _c.Call.Return() | |
| 209 | + | return _c | |
| 210 | + | } | |
| 211 | + | ||
| 212 | + | func (_c *MockIME_Enable_Call) RunAndReturn(run func()) *MockIME_Enable_Call { | |
| 213 | + | _c.Run(run) | |
| 214 | + | return _c | |
| 215 | + | } | |
| 216 | + | ||
| 217 | + | // Surrounding provides a mock function for the type MockIME | |
| 218 | + | func (_mock *MockIME) Surrounding(text string, cursor int, anchor int) { | |
| 219 | + | _mock.Called(text, cursor, anchor) | |
| 220 | + | return | |
| 221 | + | } | |
| 222 | + | ||
| 223 | + | // MockIME_Surrounding_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Surrounding' | |
| 224 | + | type MockIME_Surrounding_Call struct { | |
| 225 | + | *mock.Call | |
| 226 | + | } | |
| 227 | + | ||
| 228 | + | // Surrounding is a helper method to define mock.On call | |
| 229 | + | // - text string | |
| 230 | + | // - cursor int | |
| 231 | + | // - anchor int | |
| 232 | + | func (_e *MockIME_Expecter) Surrounding(text any, cursor any, anchor any) *MockIME_Surrounding_Call { | |
| 233 | + | return &MockIME_Surrounding_Call{Call: _e.mock.On("Surrounding", text, cursor, anchor)} | |
| 234 | + | } | |
| 235 | + | ||
| 236 | + | func (_c *MockIME_Surrounding_Call) Run(run func(text string, cursor int, anchor int)) *MockIME_Surrounding_Call { | |
| 237 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 238 | + | var arg0 string | |
| 239 | + | if args[0] != nil { | |
| 240 | + | arg0 = args[0].(string) | |
| 241 | + | } | |
| 242 | + | var arg1 int | |
| 243 | + | if args[1] != nil { | |
| 244 | + | arg1 = args[1].(int) | |
| 245 | + | } | |
| 246 | + | var arg2 int | |
| 247 | + | if args[2] != nil { | |
| 248 | + | arg2 = args[2].(int) | |
| 249 | + | } | |
| 250 | + | run( | |
| 251 | + | arg0, | |
| 252 | + | arg1, | |
| 253 | + | arg2, | |
| 254 | + | ) | |
| 255 | + | }) | |
| 256 | + | return _c | |
| 257 | + | } | |
| 258 | + | ||
| 259 | + | func (_c *MockIME_Surrounding_Call) Return() *MockIME_Surrounding_Call { | |
| 260 | + | _c.Call.Return() | |
| 261 | + | return _c | |
| 262 | + | } | |
| 263 | + | ||
| 264 | + | func (_c *MockIME_Surrounding_Call) RunAndReturn(run func(text string, cursor int, anchor int)) *MockIME_Surrounding_Call { | |
| 265 | + | _c.Run(run) | |
| 266 | + | return _c | |
| 267 | + | } | |
| @@ -0,0 +1,267 @@ | |||||
| 1 | + | // Code generated by mockery; DO NOT EDIT. | |||
| 2 | + | // github.com/vektra/mockery | |||
| 3 | + | // template: testify | |||
| 4 | + | ||||
| 5 | + | package ui | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | mock "github.com/stretchr/testify/mock" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | // NewMockIME creates a new instance of MockIME. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |||
| 12 | + | // The first argument is typically a *testing.T value. | |||
| 13 | + | func NewMockIME(t interface { | |||
| 14 | + | mock.TestingT | |||
| 15 | + | Cleanup(func()) | |||
| 16 | + | }) *MockIME { | |||
| 17 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 18 | + | helper.Helper() | |||
| 19 | + | } | |||
| 20 | + | ||||
| 21 | + | mock := &MockIME{} | |||
| 22 | + | mock.Mock.Test(t) | |||
| 23 | + | ||||
| 24 | + | t.Cleanup(func() { | |||
| 25 | + | if helper, ok := t.(interface{ Helper() }); ok { | |||
| 26 | + | helper.Helper() | |||
| 27 | + | } | |||
| 28 | + | mock.AssertExpectations(t) | |||
| 29 | + | }) | |||
| 30 | + | ||||
| 31 | + | return mock | |||
| 32 | + | } | |||
| 33 | + | ||||
| 34 | + | // MockIME is an autogenerated mock type for the IME type | |||
| 35 | + | type MockIME struct { | |||
| 36 | + | mock.Mock | |||
| 37 | + | } | |||
| 38 | + | ||||
| 39 | + | type MockIME_Expecter struct { | |||
| 40 | + | mock *mock.Mock | |||
| 41 | + | } | |||
| 42 | + | ||||
| 43 | + | func (_m *MockIME) EXPECT() *MockIME_Expecter { | |||
| 44 | + | return &MockIME_Expecter{mock: &_m.Mock} | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | // ContentType provides a mock function for the type MockIME | |||
| 48 | + | func (_mock *MockIME) ContentType(password bool, multiline bool) { | |||
| 49 | + | _mock.Called(password, multiline) | |||
| 50 | + | return | |||
| 51 | + | } | |||
| 52 | + | ||||
| 53 | + | // MockIME_ContentType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ContentType' | |||
| 54 | + | type MockIME_ContentType_Call struct { | |||
| 55 | + | *mock.Call | |||
| 56 | + | } | |||
| 57 | + | ||||
| 58 | + | // ContentType is a helper method to define mock.On call | |||
| 59 | + | // - password bool | |||
| 60 | + | // - multiline bool | |||
| 61 | + | func (_e *MockIME_Expecter) ContentType(password any, multiline any) *MockIME_ContentType_Call { | |||
| 62 | + | return &MockIME_ContentType_Call{Call: _e.mock.On("ContentType", password, multiline)} | |||
| 63 | + | } | |||
| 64 | + | ||||
| 65 | + | func (_c *MockIME_ContentType_Call) Run(run func(password bool, multiline bool)) *MockIME_ContentType_Call { | |||
| 66 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 67 | + | var arg0 bool | |||
| 68 | + | if args[0] != nil { | |||
| 69 | + | arg0 = args[0].(bool) | |||
| 70 | + | } | |||
| 71 | + | var arg1 bool | |||
| 72 | + | if args[1] != nil { | |||
| 73 | + | arg1 = args[1].(bool) | |||
| 74 | + | } | |||
| 75 | + | run( | |||
| 76 | + | arg0, | |||
| 77 | + | arg1, | |||
| 78 | + | ) | |||
| 79 | + | }) | |||
| 80 | + | return _c | |||
| 81 | + | } | |||
| 82 | + | ||||
| 83 | + | func (_c *MockIME_ContentType_Call) Return() *MockIME_ContentType_Call { | |||
| 84 | + | _c.Call.Return() | |||
| 85 | + | return _c | |||
| 86 | + | } | |||
| 87 | + | ||||
| 88 | + | func (_c *MockIME_ContentType_Call) RunAndReturn(run func(password bool, multiline bool)) *MockIME_ContentType_Call { | |||
| 89 | + | _c.Run(run) | |||
| 90 | + | return _c | |||
| 91 | + | } | |||
| 92 | + | ||||
| 93 | + | // CursorRect provides a mock function for the type MockIME | |||
| 94 | + | func (_mock *MockIME) CursorRect(x float64, y float64, w float64, h float64) { | |||
| 95 | + | _mock.Called(x, y, w, h) | |||
| 96 | + | return | |||
| 97 | + | } | |||
| 98 | + | ||||
| 99 | + | // MockIME_CursorRect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CursorRect' | |||
| 100 | + | type MockIME_CursorRect_Call struct { | |||
| 101 | + | *mock.Call | |||
| 102 | + | } | |||
| 103 | + | ||||
| 104 | + | // CursorRect is a helper method to define mock.On call | |||
| 105 | + | // - x float64 | |||
| 106 | + | // - y float64 | |||
| 107 | + | // - w float64 | |||
| 108 | + | // - h float64 | |||
| 109 | + | func (_e *MockIME_Expecter) CursorRect(x any, y any, w any, h any) *MockIME_CursorRect_Call { | |||
| 110 | + | return &MockIME_CursorRect_Call{Call: _e.mock.On("CursorRect", x, y, w, h)} | |||
| 111 | + | } | |||
| 112 | + | ||||
| 113 | + | func (_c *MockIME_CursorRect_Call) Run(run func(x float64, y float64, w float64, h float64)) *MockIME_CursorRect_Call { | |||
| 114 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 115 | + | var arg0 float64 | |||
| 116 | + | if args[0] != nil { | |||
| 117 | + | arg0 = args[0].(float64) | |||
| 118 | + | } | |||
| 119 | + | var arg1 float64 | |||
| 120 | + | if args[1] != nil { | |||
| 121 | + | arg1 = args[1].(float64) | |||
| 122 | + | } | |||
| 123 | + | var arg2 float64 | |||
| 124 | + | if args[2] != nil { | |||
| 125 | + | arg2 = args[2].(float64) | |||
| 126 | + | } | |||
| 127 | + | var arg3 float64 | |||
| 128 | + | if args[3] != nil { | |||
| 129 | + | arg3 = args[3].(float64) | |||
| 130 | + | } | |||
| 131 | + | run( | |||
| 132 | + | arg0, | |||
| 133 | + | arg1, | |||
| 134 | + | arg2, | |||
| 135 | + | arg3, | |||
| 136 | + | ) | |||
| 137 | + | }) | |||
| 138 | + | return _c | |||
| 139 | + | } | |||
| 140 | + | ||||
| 141 | + | func (_c *MockIME_CursorRect_Call) Return() *MockIME_CursorRect_Call { | |||
| 142 | + | _c.Call.Return() | |||
| 143 | + | return _c | |||
| 144 | + | } | |||
| 145 | + | ||||
| 146 | + | func (_c *MockIME_CursorRect_Call) RunAndReturn(run func(x float64, y float64, w float64, h float64)) *MockIME_CursorRect_Call { | |||
| 147 | + | _c.Run(run) | |||
| 148 | + | return _c | |||
| 149 | + | } | |||
| 150 | + | ||||
| 151 | + | // Disable provides a mock function for the type MockIME | |||
| 152 | + | func (_mock *MockIME) Disable() { | |||
| 153 | + | _mock.Called() | |||
| 154 | + | return | |||
| 155 | + | } | |||
| 156 | + | ||||
| 157 | + | // MockIME_Disable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Disable' | |||
| 158 | + | type MockIME_Disable_Call struct { | |||
| 159 | + | *mock.Call | |||
| 160 | + | } | |||
| 161 | + | ||||
| 162 | + | // Disable is a helper method to define mock.On call | |||
| 163 | + | func (_e *MockIME_Expecter) Disable() *MockIME_Disable_Call { | |||
| 164 | + | return &MockIME_Disable_Call{Call: _e.mock.On("Disable")} | |||
| 165 | + | } | |||
| 166 | + | ||||
| 167 | + | func (_c *MockIME_Disable_Call) Run(run func()) *MockIME_Disable_Call { | |||
| 168 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 169 | + | run() | |||
| 170 | + | }) | |||
| 171 | + | return _c | |||
| 172 | + | } | |||
| 173 | + | ||||
| 174 | + | func (_c *MockIME_Disable_Call) Return() *MockIME_Disable_Call { | |||
| 175 | + | _c.Call.Return() | |||
| 176 | + | return _c | |||
| 177 | + | } | |||
| 178 | + | ||||
| 179 | + | func (_c *MockIME_Disable_Call) RunAndReturn(run func()) *MockIME_Disable_Call { | |||
| 180 | + | _c.Run(run) | |||
| 181 | + | return _c | |||
| 182 | + | } | |||
| 183 | + | ||||
| 184 | + | // Enable provides a mock function for the type MockIME | |||
| 185 | + | func (_mock *MockIME) Enable() { | |||
| 186 | + | _mock.Called() | |||
| 187 | + | return | |||
| 188 | + | } | |||
| 189 | + | ||||
| 190 | + | // MockIME_Enable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Enable' | |||
| 191 | + | type MockIME_Enable_Call struct { | |||
| 192 | + | *mock.Call | |||
| 193 | + | } | |||
| 194 | + | ||||
| 195 | + | // Enable is a helper method to define mock.On call | |||
| 196 | + | func (_e *MockIME_Expecter) Enable() *MockIME_Enable_Call { | |||
| 197 | + | return &MockIME_Enable_Call{Call: _e.mock.On("Enable")} | |||
| 198 | + | } | |||
| 199 | + | ||||
| 200 | + | func (_c *MockIME_Enable_Call) Run(run func()) *MockIME_Enable_Call { | |||
| 201 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 202 | + | run() | |||
| 203 | + | }) | |||
| 204 | + | return _c | |||
| 205 | + | } | |||
| 206 | + | ||||
| 207 | + | func (_c *MockIME_Enable_Call) Return() *MockIME_Enable_Call { | |||
| 208 | + | _c.Call.Return() | |||
| 209 | + | return _c | |||
| 210 | + | } | |||
| 211 | + | ||||
| 212 | + | func (_c *MockIME_Enable_Call) RunAndReturn(run func()) *MockIME_Enable_Call { | |||
| 213 | + | _c.Run(run) | |||
| 214 | + | return _c | |||
| 215 | + | } | |||
| 216 | + | ||||
| 217 | + | // Surrounding provides a mock function for the type MockIME | |||
| 218 | + | func (_mock *MockIME) Surrounding(text string, cursor int, anchor int) { | |||
| 219 | + | _mock.Called(text, cursor, anchor) | |||
| 220 | + | return | |||
| 221 | + | } | |||
| 222 | + | ||||
| 223 | + | // MockIME_Surrounding_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Surrounding' | |||
| 224 | + | type MockIME_Surrounding_Call struct { | |||
| 225 | + | *mock.Call | |||
| 226 | + | } | |||
| 227 | + | ||||
| 228 | + | // Surrounding is a helper method to define mock.On call | |||
| 229 | + | // - text string | |||
| 230 | + | // - cursor int | |||
| 231 | + | // - anchor int | |||
| 232 | + | func (_e *MockIME_Expecter) Surrounding(text any, cursor any, anchor any) *MockIME_Surrounding_Call { | |||
| 233 | + | return &MockIME_Surrounding_Call{Call: _e.mock.On("Surrounding", text, cursor, anchor)} | |||
| 234 | + | } | |||
| 235 | + | ||||
| 236 | + | func (_c *MockIME_Surrounding_Call) Run(run func(text string, cursor int, anchor int)) *MockIME_Surrounding_Call { | |||
| 237 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 238 | + | var arg0 string | |||
| 239 | + | if args[0] != nil { | |||
| 240 | + | arg0 = args[0].(string) | |||
| 241 | + | } | |||
| 242 | + | var arg1 int | |||
| 243 | + | if args[1] != nil { | |||
| 244 | + | arg1 = args[1].(int) | |||
| 245 | + | } | |||
| 246 | + | var arg2 int | |||
| 247 | + | if args[2] != nil { | |||
| 248 | + | arg2 = args[2].(int) | |||
| 249 | + | } | |||
| 250 | + | run( | |||
| 251 | + | arg0, | |||
| 252 | + | arg1, | |||
| 253 | + | arg2, | |||
| 254 | + | ) | |||
| 255 | + | }) | |||
| 256 | + | return _c | |||
| 257 | + | } | |||
| 258 | + | ||||
| 259 | + | func (_c *MockIME_Surrounding_Call) Return() *MockIME_Surrounding_Call { | |||
| 260 | + | _c.Call.Return() | |||
| 261 | + | return _c | |||
| 262 | + | } | |||
| 263 | + | ||||
| 264 | + | func (_c *MockIME_Surrounding_Call) RunAndReturn(run func(text string, cursor int, anchor int)) *MockIME_Surrounding_Call { | |||
| 265 | + | _c.Run(run) | |||
| 266 | + | return _c | |||
| 267 | + | } | |||
M internal/ui/controls_extra_test.go +1 -5
| @@ -6,10 +6,6 @@ import ( | |||
| 6 | 6 | "testing" | |
| 7 | 7 | ) | |
| 8 | 8 | ||
| 9 | - | type clip struct{ data []byte } | |
| 10 | - | ||
| 11 | - | func (c *clip) ReadText(limit int) ([]byte, error) { return c.data, nil } | |
| 12 | - | func (c *clip) WriteText(v []byte) error { c.data = append([]byte(nil), v...); return nil } | |
| 13 | 9 | func TestRadioSliderAndEditingIdentity(t *testing.T) { | |
| 14 | 10 | r := newRuntime() | |
| 15 | 11 | r.styles = css.Compile(css.UA(), css.Parse(`input,radio,slider {height:20px}`)) | |
| @@ -97,7 +93,7 @@ func TestEditFocusIMEAndClipboard(t *testing.T) { | |||
| 97 | 93 | var value string | |
| 98 | 94 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | |
| 99 | 95 | r.Build(view) | |
| 100 | - | r.clipboard = &clip{data: []byte("paste")} | |
| 96 | + | r.clipboard = NewMockClipboard(t) // no clipboard access expected | |
| 101 | 97 | r.route(key("Tab")) | |
| 102 | 98 | r.Build(view) | |
| 103 | 99 | r.route(platformInput{Kind: "key", Key: keyEvent{Name: "q", Text: "x", Pressed: true}}) | |
| @@ -6,10 +6,6 @@ import ( | |||||
| 6 | "testing" | 6 | "testing" | ||
| 7 | ) | 7 | ) | ||
| 8 | 8 | ||||
| 9 | - | type clip struct{ data []byte } | |||
| 10 | - | ||||
| 11 | - | func (c *clip) ReadText(limit int) ([]byte, error) { return c.data, nil } | |||
| 12 | - | func (c *clip) WriteText(v []byte) error { c.data = append([]byte(nil), v...); return nil } | |||
| 13 | func TestRadioSliderAndEditingIdentity(t *testing.T) { | 9 | func TestRadioSliderAndEditingIdentity(t *testing.T) { | ||
| 14 | r := newRuntime() | 10 | r := newRuntime() | ||
| 15 | r.styles = css.Compile(css.UA(), css.Parse(`input,radio,slider {height:20px}`)) | 11 | r.styles = css.Compile(css.UA(), css.Parse(`input,radio,slider {height:20px}`)) | ||
| @@ -97,7 +93,7 @@ func TestEditFocusIMEAndClipboard(t *testing.T) { | |||||
| 97 | var value string | 93 | var value string | ||
| 98 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | 94 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | ||
| 99 | r.Build(view) | 95 | r.Build(view) | ||
| 100 | - | r.clipboard = &clip{data: []byte("paste")} | 96 | + | r.clipboard = NewMockClipboard(t) // no clipboard access expected |
| 101 | r.route(key("Tab")) | 97 | r.route(key("Tab")) | ||
| 102 | r.Build(view) | 98 | r.Build(view) | ||
| 103 | r.route(platformInput{Kind: "key", Key: keyEvent{Name: "q", Text: "x", Pressed: true}}) | 99 | r.route(platformInput{Kind: "key", Key: keyEvent{Name: "q", Text: "x", Pressed: true}}) | ||
M internal/ui/ime_focus_test.go +43 -41
| @@ -3,60 +3,62 @@ package ui | |||
| 3 | 3 | import ( | |
| 4 | 4 | "reflect" | |
| 5 | 5 | "testing" | |
| 6 | - | ) | |
| 7 | - | ||
| 8 | - | type orderedIME struct { | |
| 9 | - | calls []string | |
| 10 | - | active bool | |
| 11 | - | } | |
| 12 | - | ||
| 13 | - | func (i *orderedIME) Enable() { | |
| 14 | - | if i.active { | |
| 15 | - | panic("IME enable before disable") | |
| 16 | - | } | |
| 17 | - | i.active = true | |
| 18 | - | i.calls = append(i.calls, "enable") | |
| 19 | - | } | |
| 20 | - | func (i *orderedIME) Disable() { | |
| 21 | - | if !i.active { | |
| 22 | - | panic("IME double disable") | |
| 23 | - | } | |
| 24 | - | i.active = false | |
| 25 | - | i.calls = append(i.calls, "disable") | |
| 26 | - | } | |
| 27 | - | func (i *orderedIME) Surrounding(string, int, int) {} | |
| 28 | - | func (i *orderedIME) CursorRect(float64, float64, float64, float64) {} | |
| 29 | - | func (i *orderedIME) ContentType(bool, bool) {} | |
| 30 | 6 | ||
| 31 | - | type recordingIME struct { | |
| 32 | - | surrounding []string | |
| 33 | - | password bool | |
| 34 | - | } | |
| 7 | + | "github.com/stretchr/testify/mock" | |
| 8 | + | ) | |
| 35 | 9 | ||
| 36 | - | func (i *recordingIME) Enable() {} | |
| 37 | - | func (i *recordingIME) Disable() {} | |
| 38 | - | func (i *recordingIME) Surrounding(text string, _, _ int) { | |
| 39 | - | i.surrounding = append(i.surrounding, text) | |
| 10 | + | // newOrderedIME returns an IME mock that records Enable and Disable in order | |
| 11 | + | // and fails on an enable before a disable or a double disable. | |
| 12 | + | func newOrderedIME(t *testing.T) (*MockIME, *[]string) { | |
| 13 | + | t.Helper() | |
| 14 | + | ime := NewMockIME(t) | |
| 15 | + | calls := new([]string) | |
| 16 | + | active := false | |
| 17 | + | ime.EXPECT().Enable().Run(func() { | |
| 18 | + | if active { | |
| 19 | + | t.Error("IME enable before disable") | |
| 20 | + | } | |
| 21 | + | active = true | |
| 22 | + | *calls = append(*calls, "enable") | |
| 23 | + | }).Maybe() | |
| 24 | + | ime.EXPECT().Disable().Run(func() { | |
| 25 | + | if !active { | |
| 26 | + | t.Error("IME double disable") | |
| 27 | + | } | |
| 28 | + | active = false | |
| 29 | + | *calls = append(*calls, "disable") | |
| 30 | + | }).Maybe() | |
| 31 | + | ime.EXPECT().Surrounding(mock.Anything, mock.Anything, mock.Anything).Maybe() | |
| 32 | + | ime.EXPECT().CursorRect(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe() | |
| 33 | + | ime.EXPECT().ContentType(mock.Anything, mock.Anything).Maybe() | |
| 34 | + | return ime, calls | |
| 40 | 35 | } | |
| 41 | - | func (i *recordingIME) CursorRect(float64, float64, float64, float64) {} | |
| 42 | - | func (i *recordingIME) ContentType(password, _ bool) { i.password = password } | |
| 43 | 36 | ||
| 44 | 37 | func TestPasswordEditorNeverSendsSecretToIME(t *testing.T) { | |
| 45 | 38 | r := newRuntime() | |
| 46 | - | ime := &recordingIME{} | |
| 39 | + | ime := NewMockIME(t) | |
| 40 | + | var surrounding []string | |
| 41 | + | password := false | |
| 42 | + | ime.EXPECT().Enable().Maybe() | |
| 43 | + | ime.EXPECT().Disable().Maybe() | |
| 44 | + | ime.EXPECT().CursorRect(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe() | |
| 45 | + | ime.EXPECT().Surrounding(mock.Anything, mock.Anything, mock.Anything).Run(func(text string, _, _ int) { | |
| 46 | + | surrounding = append(surrounding, text) | |
| 47 | + | }).Maybe() | |
| 48 | + | ime.EXPECT().ContentType(mock.Anything, mock.Anything).Run(func(p, _ bool) { password = p }).Maybe() | |
| 47 | 49 | r.ime = ime | |
| 48 | 50 | value := "hunter2" | |
| 49 | 51 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | |
| 50 | 52 | r.Build(view) | |
| 51 | 53 | r.route(key("Tab")) | |
| 52 | 54 | r.Build(view) | |
| 53 | - | if !ime.password { | |
| 55 | + | if !password { | |
| 54 | 56 | t.Fatal("password content type not sent") | |
| 55 | 57 | } | |
| 56 | - | if len(ime.surrounding) == 0 { | |
| 58 | + | if len(surrounding) == 0 { | |
| 57 | 59 | t.Fatal("no surrounding text update") | |
| 58 | 60 | } | |
| 59 | - | for _, s := range ime.surrounding { | |
| 61 | + | for _, s := range surrounding { | |
| 60 | 62 | if s != "" { | |
| 61 | 63 | t.Fatalf("surrounding text leaked %q", s) | |
| 62 | 64 | } | |
| @@ -65,7 +67,7 @@ func TestPasswordEditorNeverSendsSecretToIME(t *testing.T) { | |||
| 65 | 67 | ||
| 66 | 68 | func TestIMEFocusTransferDisablesBeforeEnable(t *testing.T) { | |
| 67 | 69 | r := newRuntime() | |
| 68 | - | ime := &orderedIME{} | |
| 70 | + | ime, calls := newOrderedIME(t) | |
| 69 | 71 | r.ime = ime | |
| 70 | 72 | a, b := "one", "two" | |
| 71 | 73 | view := func(f *Frame) { root := f.Root(); root.Input("a", &a, Key("a")); root.Textarea("b", &b, Key("b")) } | |
| @@ -76,8 +78,8 @@ func TestIMEFocusTransferDisablesBeforeEnable(t *testing.T) { | |||
| 76 | 78 | r.Build(view) | |
| 77 | 79 | r.route(key("Tab")) | |
| 78 | 80 | r.Build(view) | |
| 79 | - | if want := []string{"enable", "disable", "enable", "disable", "enable"}; !reflect.DeepEqual(ime.calls, want) { | |
| 80 | - | t.Fatalf("focus transition calls %v want %v", ime.calls, want) | |
| 81 | + | if want := []string{"enable", "disable", "enable", "disable", "enable"}; !reflect.DeepEqual(*calls, want) { | |
| 82 | + | t.Fatalf("focus transition calls %v want %v", *calls, want) | |
| 81 | 83 | } | |
| 82 | 84 | if !r.edits[idKey(r.Target(0))].IMEActive() || r.edits[idKey(r.Target(1))].IMEActive() { | |
| 83 | 85 | t.Fatal("wrong active editor") | |
| @@ -3,60 +3,62 @@ package ui | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "reflect" | 4 | "reflect" | ||
| 5 | "testing" | 5 | "testing" | ||
| 6 | - | ) | |||
| 7 | - | ||||
| 8 | - | type orderedIME struct { | |||
| 9 | - | calls []string | |||
| 10 | - | active bool | |||
| 11 | - | } | |||
| 12 | - | ||||
| 13 | - | func (i *orderedIME) Enable() { | |||
| 14 | - | if i.active { | |||
| 15 | - | panic("IME enable before disable") | |||
| 16 | - | } | |||
| 17 | - | i.active = true | |||
| 18 | - | i.calls = append(i.calls, "enable") | |||
| 19 | - | } | |||
| 20 | - | func (i *orderedIME) Disable() { | |||
| 21 | - | if !i.active { | |||
| 22 | - | panic("IME double disable") | |||
| 23 | - | } | |||
| 24 | - | i.active = false | |||
| 25 | - | i.calls = append(i.calls, "disable") | |||
| 26 | - | } | |||
| 27 | - | func (i *orderedIME) Surrounding(string, int, int) {} | |||
| 28 | - | func (i *orderedIME) CursorRect(float64, float64, float64, float64) {} | |||
| 29 | - | func (i *orderedIME) ContentType(bool, bool) {} | |||
| 30 | 6 | ||||
| 31 | - | type recordingIME struct { | 7 | + | "github.com/stretchr/testify/mock" |
| 32 | - | surrounding []string | 8 | + | ) |
| 33 | - | password bool | |||
| 34 | - | } | |||
| 35 | 9 | ||||
| 36 | - | func (i *recordingIME) Enable() {} | 10 | + | // newOrderedIME returns an IME mock that records Enable and Disable in order |
| 37 | - | func (i *recordingIME) Disable() {} | 11 | + | // and fails on an enable before a disable or a double disable. |
| 38 | - | func (i *recordingIME) Surrounding(text string, _, _ int) { | 12 | + | func newOrderedIME(t *testing.T) (*MockIME, *[]string) { |
| 39 | - | i.surrounding = append(i.surrounding, text) | 13 | + | t.Helper() |
| 14 | + | ime := NewMockIME(t) | |||
| 15 | + | calls := new([]string) | |||
| 16 | + | active := false | |||
| 17 | + | ime.EXPECT().Enable().Run(func() { | |||
| 18 | + | if active { | |||
| 19 | + | t.Error("IME enable before disable") | |||
| 20 | + | } | |||
| 21 | + | active = true | |||
| 22 | + | *calls = append(*calls, "enable") | |||
| 23 | + | }).Maybe() | |||
| 24 | + | ime.EXPECT().Disable().Run(func() { | |||
| 25 | + | if !active { | |||
| 26 | + | t.Error("IME double disable") | |||
| 27 | + | } | |||
| 28 | + | active = false | |||
| 29 | + | *calls = append(*calls, "disable") | |||
| 30 | + | }).Maybe() | |||
| 31 | + | ime.EXPECT().Surrounding(mock.Anything, mock.Anything, mock.Anything).Maybe() | |||
| 32 | + | ime.EXPECT().CursorRect(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe() | |||
| 33 | + | ime.EXPECT().ContentType(mock.Anything, mock.Anything).Maybe() | |||
| 34 | + | return ime, calls | |||
| 40 | } | 35 | } | ||
| 41 | - | func (i *recordingIME) CursorRect(float64, float64, float64, float64) {} | |||
| 42 | - | func (i *recordingIME) ContentType(password, _ bool) { i.password = password } | |||
| 43 | 36 | ||||
| 44 | func TestPasswordEditorNeverSendsSecretToIME(t *testing.T) { | 37 | func TestPasswordEditorNeverSendsSecretToIME(t *testing.T) { | ||
| 45 | r := newRuntime() | 38 | r := newRuntime() | ||
| 46 | - | ime := &recordingIME{} | 39 | + | ime := NewMockIME(t) |
| 40 | + | var surrounding []string | |||
| 41 | + | password := false | |||
| 42 | + | ime.EXPECT().Enable().Maybe() | |||
| 43 | + | ime.EXPECT().Disable().Maybe() | |||
| 44 | + | ime.EXPECT().CursorRect(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe() | |||
| 45 | + | ime.EXPECT().Surrounding(mock.Anything, mock.Anything, mock.Anything).Run(func(text string, _, _ int) { | |||
| 46 | + | surrounding = append(surrounding, text) | |||
| 47 | + | }).Maybe() | |||
| 48 | + | ime.EXPECT().ContentType(mock.Anything, mock.Anything).Run(func(p, _ bool) { password = p }).Maybe() | |||
| 47 | r.ime = ime | 49 | r.ime = ime | ||
| 48 | value := "hunter2" | 50 | value := "hunter2" | ||
| 49 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | 51 | view := func(f *Frame) { f.Root().Input("secret", &value, Key("secret"), Password(true)) } | ||
| 50 | r.Build(view) | 52 | r.Build(view) | ||
| 51 | r.route(key("Tab")) | 53 | r.route(key("Tab")) | ||
| 52 | r.Build(view) | 54 | r.Build(view) | ||
| 53 | - | if !ime.password { | 55 | + | if !password { |
| 54 | t.Fatal("password content type not sent") | 56 | t.Fatal("password content type not sent") | ||
| 55 | } | 57 | } | ||
| 56 | - | if len(ime.surrounding) == 0 { | 58 | + | if len(surrounding) == 0 { |
| 57 | t.Fatal("no surrounding text update") | 59 | t.Fatal("no surrounding text update") | ||
| 58 | } | 60 | } | ||
| 59 | - | for _, s := range ime.surrounding { | 61 | + | for _, s := range surrounding { |
| 60 | if s != "" { | 62 | if s != "" { | ||
| 61 | t.Fatalf("surrounding text leaked %q", s) | 63 | t.Fatalf("surrounding text leaked %q", s) | ||
| 62 | } | 64 | } | ||
| @@ -65,7 +67,7 @@ func TestPasswordEditorNeverSendsSecretToIME(t *testing.T) { | |||||
| 65 | 67 | ||||
| 66 | func TestIMEFocusTransferDisablesBeforeEnable(t *testing.T) { | 68 | func TestIMEFocusTransferDisablesBeforeEnable(t *testing.T) { | ||
| 67 | r := newRuntime() | 69 | r := newRuntime() | ||
| 68 | - | ime := &orderedIME{} | 70 | + | ime, calls := newOrderedIME(t) |
| 69 | r.ime = ime | 71 | r.ime = ime | ||
| 70 | a, b := "one", "two" | 72 | a, b := "one", "two" | ||
| 71 | view := func(f *Frame) { root := f.Root(); root.Input("a", &a, Key("a")); root.Textarea("b", &b, Key("b")) } | 73 | view := func(f *Frame) { root := f.Root(); root.Input("a", &a, Key("a")); root.Textarea("b", &b, Key("b")) } | ||
| @@ -76,8 +78,8 @@ func TestIMEFocusTransferDisablesBeforeEnable(t *testing.T) { | |||||
| 76 | r.Build(view) | 78 | r.Build(view) | ||
| 77 | r.route(key("Tab")) | 79 | r.route(key("Tab")) | ||
| 78 | r.Build(view) | 80 | r.Build(view) | ||
| 79 | - | if want := []string{"enable", "disable", "enable", "disable", "enable"}; !reflect.DeepEqual(ime.calls, want) { | 81 | + | if want := []string{"enable", "disable", "enable", "disable", "enable"}; !reflect.DeepEqual(*calls, want) { |
| 80 | - | t.Fatalf("focus transition calls %v want %v", ime.calls, want) | 82 | + | t.Fatalf("focus transition calls %v want %v", *calls, want) |
| 81 | } | 83 | } | ||
| 82 | if !r.edits[idKey(r.Target(0))].IMEActive() || r.edits[idKey(r.Target(1))].IMEActive() { | 84 | if !r.edits[idKey(r.Target(0))].IMEActive() || r.edits[idKey(r.Target(1))].IMEActive() { | ||
| 83 | t.Fatal("wrong active editor") | 85 | t.Fatal("wrong active editor") | ||
M internal/ui/ime_return_test.go +2 -2
| @@ -14,7 +14,7 @@ func typed(name, text string) platformInput { | |||
| 14 | 14 | // keys that still arrive on wl_keyboard were not consumed and must be typed. | |
| 15 | 15 | func TestKeyboardTextInsertedWhileIMEEnabled(t *testing.T) { | |
| 16 | 16 | r := newRuntime() | |
| 17 | - | ime := &orderedIME{} | |
| 17 | + | ime, calls := newOrderedIME(t) | |
| 18 | 18 | r.ime = ime | |
| 19 | 19 | value := "ab" | |
| 20 | 20 | view := func(f *Frame) { f.Root().Textarea("message", &value) } | |
| @@ -28,7 +28,7 @@ func TestKeyboardTextInsertedWhileIMEEnabled(t *testing.T) { | |||
| 28 | 28 | r.route(k) | |
| 29 | 29 | r.Build(view) | |
| 30 | 30 | } | |
| 31 | - | if value != "abca\n\n" || len(ime.calls) == 0 { | |
| 31 | + | if value != "abca\n\n" || len(*calls) == 0 { | |
| 32 | 32 | t.Fatalf("keyboard text lost while IME enabled: %q", value) | |
| 33 | 33 | } | |
| 34 | 34 | ||
| @@ -14,7 +14,7 @@ func typed(name, text string) platformInput { | |||||
| 14 | // keys that still arrive on wl_keyboard were not consumed and must be typed. | 14 | // keys that still arrive on wl_keyboard were not consumed and must be typed. | ||
| 15 | func TestKeyboardTextInsertedWhileIMEEnabled(t *testing.T) { | 15 | func TestKeyboardTextInsertedWhileIMEEnabled(t *testing.T) { | ||
| 16 | r := newRuntime() | 16 | r := newRuntime() | ||
| 17 | - | ime := &orderedIME{} | 17 | + | ime, calls := newOrderedIME(t) |
| 18 | r.ime = ime | 18 | r.ime = ime | ||
| 19 | value := "ab" | 19 | value := "ab" | ||
| 20 | view := func(f *Frame) { f.Root().Textarea("message", &value) } | 20 | view := func(f *Frame) { f.Root().Textarea("message", &value) } | ||
| @@ -28,7 +28,7 @@ func TestKeyboardTextInsertedWhileIMEEnabled(t *testing.T) { | |||||
| 28 | r.route(k) | 28 | r.route(k) | ||
| 29 | r.Build(view) | 29 | r.Build(view) | ||
| 30 | } | 30 | } | ||
| 31 | - | if value != "abca\n\n" || len(ime.calls) == 0 { | 31 | + | if value != "abca\n\n" || len(*calls) == 0 { |
| 32 | t.Fatalf("keyboard text lost while IME enabled: %q", value) | 32 | t.Fatalf("keyboard text lost while IME enabled: %q", value) | ||
| 33 | } | 33 | } | ||
| 34 | 34 | ||||
M internal/ui/paste_test.go +19 -24
| @@ -3,29 +3,24 @@ package ui | |||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | 5 | "errors" | |
| 6 | - | "github.com/bnema/nefergui/internal/edit" | |
| 7 | 6 | "testing" | |
| 8 | - | ) | |
| 9 | 7 | ||
| 10 | - | type asyncClip struct { | |
| 11 | - | contexts []context.Context | |
| 12 | - | callbacks []func([]byte, error) | |
| 13 | - | } | |
| 8 | + | "github.com/bnema/nefergui/internal/edit" | |
| 9 | + | "github.com/stretchr/testify/mock" | |
| 10 | + | ) | |
| 14 | 11 | ||
| 15 | - | func (*asyncClip) ReadText(int) ([]byte, error) { panic("sync clipboard read on loop") } | |
| 16 | - | func (*asyncClip) WriteText([]byte) error { return nil } | |
| 17 | - | func (c *asyncClip) ReadTextAsync(ctx context.Context, limit int, deliver func([]byte, error)) error { | |
| 18 | - | if limit != edit.MaxClipboardBytes { | |
| 19 | - | panic("wrong limit") | |
| 20 | - | } | |
| 21 | - | c.contexts = append(c.contexts, ctx) | |
| 22 | - | c.callbacks = append(c.callbacks, deliver) | |
| 23 | - | return nil | |
| 24 | - | } | |
| 25 | 12 | func TestAsyncPasteFrameAndCancellation(t *testing.T) { | |
| 26 | 13 | r := newRuntime() | |
| 27 | - | c := &asyncClip{} | |
| 28 | - | r.clipboard = c | |
| 14 | + | c := NewMockAsyncClipboard(t) // synchronous ReadText is not expected | |
| 15 | + | var contexts []context.Context | |
| 16 | + | var callbacks []func([]byte, error) | |
| 17 | + | c.EXPECT().ReadTextAsync(mock.Anything, edit.MaxClipboardBytes, mock.Anything). | |
| 18 | + | RunAndReturn(func(ctx context.Context, _ int, deliver func([]byte, error)) error { | |
| 19 | + | contexts = append(contexts, ctx) | |
| 20 | + | callbacks = append(callbacks, deliver) | |
| 21 | + | return nil | |
| 22 | + | }) | |
| 23 | + | r.clipboard = asyncClipboard{c} | |
| 29 | 24 | name := "" | |
| 30 | 25 | var changed bool | |
| 31 | 26 | var diagnostics []string | |
| @@ -45,28 +40,28 @@ func TestAsyncPasteFrameAndCancellation(t *testing.T) { | |||
| 45 | 40 | } | |
| 46 | 41 | paste() | |
| 47 | 42 | paste() | |
| 48 | - | if c.contexts[0].Err() != context.Canceled { | |
| 43 | + | if contexts[0].Err() != context.Canceled { | |
| 49 | 44 | t.Fatal("old read not cancelled") | |
| 50 | 45 | } | |
| 51 | - | c.callbacks[0]([]byte("old"), nil) | |
| 52 | - | c.callbacks[1]([]byte("Ada"), nil) | |
| 46 | + | callbacks[0]([]byte("old"), nil) | |
| 47 | + | callbacks[1]([]byte("Ada"), nil) | |
| 53 | 48 | if !r.Build(view) || !changed || name != "Ada" { | |
| 54 | 49 | t.Fatalf("paste: changed=%v value=%q", changed, name) | |
| 55 | 50 | } | |
| 56 | 51 | paste() | |
| 57 | - | c.callbacks[2]([]byte{0xff}, nil) | |
| 52 | + | callbacks[2]([]byte{0xff}, nil) | |
| 58 | 53 | r.Build(view) | |
| 59 | 54 | if name != "Ada" || changed { | |
| 60 | 55 | t.Fatal("invalid UTF-8 accepted") | |
| 61 | 56 | } | |
| 62 | 57 | paste() | |
| 63 | - | c.callbacks[3](make([]byte, edit.MaxClipboardBytes+1), nil) | |
| 58 | + | callbacks[3](make([]byte, edit.MaxClipboardBytes+1), nil) | |
| 64 | 59 | r.Build(view) | |
| 65 | 60 | if name != "Ada" || changed { | |
| 66 | 61 | t.Fatal("oversize accepted") | |
| 67 | 62 | } | |
| 68 | 63 | paste() | |
| 69 | - | c.callbacks[4](nil, errors.New("transfer failed")) | |
| 64 | + | callbacks[4](nil, errors.New("transfer failed")) | |
| 70 | 65 | r.Build(view) | |
| 71 | 66 | if debugDiagnostics && len(diagnostics) != 1 { | |
| 72 | 67 | t.Fatalf("missing error diagnostic: %v", diagnostics) | |
| @@ -3,29 +3,24 @@ package ui | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | "errors" | 5 | "errors" | ||
| 6 | - | "github.com/bnema/nefergui/internal/edit" | |||
| 7 | "testing" | 6 | "testing" | ||
| 8 | - | ) | |||
| 9 | 7 | ||||
| 10 | - | type asyncClip struct { | 8 | + | "github.com/bnema/nefergui/internal/edit" |
| 11 | - | contexts []context.Context | 9 | + | "github.com/stretchr/testify/mock" |
| 12 | - | callbacks []func([]byte, error) | 10 | + | ) |
| 13 | - | } | |||
| 14 | 11 | ||||
| 15 | - | func (*asyncClip) ReadText(int) ([]byte, error) { panic("sync clipboard read on loop") } | |||
| 16 | - | func (*asyncClip) WriteText([]byte) error { return nil } | |||
| 17 | - | func (c *asyncClip) ReadTextAsync(ctx context.Context, limit int, deliver func([]byte, error)) error { | |||
| 18 | - | if limit != edit.MaxClipboardBytes { | |||
| 19 | - | panic("wrong limit") | |||
| 20 | - | } | |||
| 21 | - | c.contexts = append(c.contexts, ctx) | |||
| 22 | - | c.callbacks = append(c.callbacks, deliver) | |||
| 23 | - | return nil | |||
| 24 | - | } | |||
| 25 | func TestAsyncPasteFrameAndCancellation(t *testing.T) { | 12 | func TestAsyncPasteFrameAndCancellation(t *testing.T) { | ||
| 26 | r := newRuntime() | 13 | r := newRuntime() | ||
| 27 | - | c := &asyncClip{} | 14 | + | c := NewMockAsyncClipboard(t) // synchronous ReadText is not expected |
| 28 | - | r.clipboard = c | 15 | + | var contexts []context.Context |
| 16 | + | var callbacks []func([]byte, error) | |||
| 17 | + | c.EXPECT().ReadTextAsync(mock.Anything, edit.MaxClipboardBytes, mock.Anything). | |||
| 18 | + | RunAndReturn(func(ctx context.Context, _ int, deliver func([]byte, error)) error { | |||
| 19 | + | contexts = append(contexts, ctx) | |||
| 20 | + | callbacks = append(callbacks, deliver) | |||
| 21 | + | return nil | |||
| 22 | + | }) | |||
| 23 | + | r.clipboard = asyncClipboard{c} | |||
| 29 | name := "" | 24 | name := "" | ||
| 30 | var changed bool | 25 | var changed bool | ||
| 31 | var diagnostics []string | 26 | var diagnostics []string | ||
| @@ -45,28 +40,28 @@ func TestAsyncPasteFrameAndCancellation(t *testing.T) { | |||||
| 45 | } | 40 | } | ||
| 46 | paste() | 41 | paste() | ||
| 47 | paste() | 42 | paste() | ||
| 48 | - | if c.contexts[0].Err() != context.Canceled { | 43 | + | if contexts[0].Err() != context.Canceled { |
| 49 | t.Fatal("old read not cancelled") | 44 | t.Fatal("old read not cancelled") | ||
| 50 | } | 45 | } | ||
| 51 | - | c.callbacks[0]([]byte("old"), nil) | 46 | + | callbacks[0]([]byte("old"), nil) |
| 52 | - | c.callbacks[1]([]byte("Ada"), nil) | 47 | + | callbacks[1]([]byte("Ada"), nil) |
| 53 | if !r.Build(view) || !changed || name != "Ada" { | 48 | if !r.Build(view) || !changed || name != "Ada" { | ||
| 54 | t.Fatalf("paste: changed=%v value=%q", changed, name) | 49 | t.Fatalf("paste: changed=%v value=%q", changed, name) | ||
| 55 | } | 50 | } | ||
| 56 | paste() | 51 | paste() | ||
| 57 | - | c.callbacks[2]([]byte{0xff}, nil) | 52 | + | callbacks[2]([]byte{0xff}, nil) |
| 58 | r.Build(view) | 53 | r.Build(view) | ||
| 59 | if name != "Ada" || changed { | 54 | if name != "Ada" || changed { | ||
| 60 | t.Fatal("invalid UTF-8 accepted") | 55 | t.Fatal("invalid UTF-8 accepted") | ||
| 61 | } | 56 | } | ||
| 62 | paste() | 57 | paste() | ||
| 63 | - | c.callbacks[3](make([]byte, edit.MaxClipboardBytes+1), nil) | 58 | + | callbacks[3](make([]byte, edit.MaxClipboardBytes+1), nil) |
| 64 | r.Build(view) | 59 | r.Build(view) | ||
| 65 | if name != "Ada" || changed { | 60 | if name != "Ada" || changed { | ||
| 66 | t.Fatal("oversize accepted") | 61 | t.Fatal("oversize accepted") | ||
| 67 | } | 62 | } | ||
| 68 | paste() | 63 | paste() | ||
| 69 | - | c.callbacks[4](nil, errors.New("transfer failed")) | 64 | + | callbacks[4](nil, errors.New("transfer failed")) |
| 70 | r.Build(view) | 65 | r.Build(view) | ||
| 71 | if debugDiagnostics && len(diagnostics) != 1 { | 66 | if debugDiagnostics && len(diagnostics) != 1 { | ||
| 72 | t.Fatalf("missing error diagnostic: %v", diagnostics) | 67 | t.Fatalf("missing error diagnostic: %v", diagnostics) | ||