10 "github.com/go-errors/errors"
11 "github.com/stretchr/testify/assert"
12 "github.com/zyedidia/micro/v2/internal/action"
13 "github.com/zyedidia/micro/v2/internal/buffer"
14 "github.com/zyedidia/micro/v2/internal/config"
15 "github.com/zyedidia/micro/v2/internal/screen"
16 "github.com/zyedidia/tcell/v2"
20 var sim tcell.SimulationScreen
23 screen.Events = make(chan tcell.Event, 8)
26 func startup(args []string) (tcell.SimulationScreen, error) {
29 tempDir, err = ioutil.TempDir("", "micro_test")
33 err = config.InitConfigDir(tempDir)
38 config.InitRuntimeFiles()
39 err = config.ReadSettings()
43 err = config.InitGlobalSettings()
48 s, err := screen.InitSimScreen()
54 if err := recover(); err != nil {
56 fmt.Println("Micro encountered an error:", err)
57 // backup all open buffers
58 for _, b := range buffer.OpenBuffers {
61 // Print the stack trace too
62 log.Fatalf(errors.Wrap(err, 2).ErrorStack())
66 err = config.LoadAllPlugins()
68 screen.TermMessage(err)
74 err = config.InitColorscheme()
82 return nil, errors.New("No buffers opened")
88 err = config.RunPluginFn("init")
100 os.RemoveAll(tempDir)
105 e := screen.Screen.PollEvent()
113 func injectKey(key tcell.Key, r rune, mod tcell.ModMask) {
114 sim.InjectKey(key, r, mod)
118 func injectMouse(x, y int, buttons tcell.ButtonMask, mod tcell.ModMask) {
119 sim.InjectMouse(x, y, buttons, mod)
123 func injectString(str string) {
124 // the tcell simulation screen event channel can only handle
125 // 10 events at once, so we need to divide up the key events
126 // into chunks of 10 and handle the 10 events before sending
127 // another chunk of events
128 iters := len(str) / 10
129 extra := len(str) % 10
131 for i := 0; i < iters; i++ {
134 sim.InjectKeyBytes([]byte(str[s:e]))
135 for i := 0; i < 10; i++ {
140 sim.InjectKeyBytes([]byte(str[len(str)-extra:]))
141 for i := 0; i < extra; i++ {
146 func openFile(file string) {
147 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
148 injectString(fmt.Sprintf("open %s", file))
149 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
152 func createTestFile(name string, content string) (string, error) {
153 testf, err := ioutil.TempFile("", name)
158 if _, err := testf.Write([]byte(content)); err != nil {
161 if err := testf.Close(); err != nil {
165 return testf.Name(), nil
168 func TestMain(m *testing.M) {
170 sim, err = startup([]string{})
181 func TestSimpleEdit(t *testing.T) {
182 file, err := createTestFile("micro_simple_edit_test", "base content")
187 defer os.Remove(file)
191 var buf *buffer.Buffer
192 for _, b := range buffer.OpenBuffers {
199 t.Errorf("Could not find buffer %s", file)
203 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
204 injectKey(tcell.KeyUp, 0, tcell.ModNone)
205 injectString("first line")
207 // test both kinds of backspace
208 for i := 0; i < len("ne"); i++ {
209 injectKey(tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone)
211 for i := 0; i < len(" li"); i++ {
212 injectKey(tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone)
214 injectString("foobar")
216 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
218 data, err := ioutil.ReadFile(file)
224 assert.Equal(t, "firstfoobar\nbase content\n", string(data))
227 func TestMouse(t *testing.T) {
228 file, err := createTestFile("micro_mouse_test", "base content")
233 defer os.Remove(file)
239 // the selections need to happen at different locations to avoid a double click
240 injectMouse(3, 0, tcell.Button1, tcell.ModNone)
241 injectKey(tcell.KeyLeft, 0, tcell.ModNone)
242 injectMouse(0, 0, tcell.ButtonNone, tcell.ModNone)
243 injectString("secondline")
245 // secondlinebase content
246 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
250 injectMouse(2, 0, tcell.Button1, tcell.ModNone)
251 injectMouse(0, 0, tcell.ButtonNone, tcell.ModNone)
252 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
257 injectKey(tcell.KeyUp, 0, tcell.ModNone)
258 injectString("firstline")
263 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
265 data, err := ioutil.ReadFile(file)
271 assert.Equal(t, "firstline\nsecondline\nbase content\n", string(data))
274 var srTestStart = `foo
279 var srTest2 = `test_string
281 test_stringtest_stringtest_string
282 Ernleȝe test_string æðelen
284 var srTest3 = `test_foo
286 test_footest_stringtest_foo
287 Ernleȝe test_string æðelen
290 func TestSearchAndReplace(t *testing.T) {
291 file, err := createTestFile("micro_search_replace_test", srTestStart)
296 defer os.Remove(file)
300 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
301 injectString(fmt.Sprintf("replaceall %s %s", "foo", "test_string"))
302 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
304 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
306 data, err := ioutil.ReadFile(file)
312 assert.Equal(t, srTest2, string(data))
314 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
315 injectString(fmt.Sprintf("replace %s %s", "string", "foo"))
316 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
317 injectString("ynyny")
318 injectKey(tcell.KeyEscape, 0, tcell.ModNone)
320 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
322 data, err = ioutil.ReadFile(file)
328 assert.Equal(t, srTest3, string(data))
331 func TestMultiCursor(t *testing.T) {
335 func TestSettingsPersistence(t *testing.T) {
339 // more tests (rendering, tabs, plugins)?