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())
67 err = config.LoadAllPlugins()
69 screen.TermMessage(err)
75 err = config.InitColorscheme()
83 return nil, errors.New("No buffers opened")
89 err = config.RunPluginFn("init")
101 os.RemoveAll(tempDir)
106 e := screen.Screen.PollEvent()
114 func injectKey(key tcell.Key, r rune, mod tcell.ModMask) {
115 sim.InjectKey(key, r, mod)
119 func injectMouse(x, y int, buttons tcell.ButtonMask, mod tcell.ModMask) {
120 sim.InjectMouse(x, y, buttons, mod)
124 func injectString(str string) {
125 // the tcell simulation screen event channel can only handle
126 // 10 events at once, so we need to divide up the key events
127 // into chunks of 10 and handle the 10 events before sending
128 // another chunk of events
129 iters := len(str) / 10
130 extra := len(str) % 10
132 for i := 0; i < iters; i++ {
135 sim.InjectKeyBytes([]byte(str[s:e]))
136 for i := 0; i < 10; i++ {
141 sim.InjectKeyBytes([]byte(str[len(str)-extra:]))
142 for i := 0; i < extra; i++ {
147 func openFile(file string) {
148 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
149 injectString(fmt.Sprintf("open %s", file))
150 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
153 func createTestFile(name string, content string) (string, error) {
154 testf, err := ioutil.TempFile("", name)
159 if _, err := testf.Write([]byte(content)); err != nil {
162 if err := testf.Close(); err != nil {
166 return testf.Name(), nil
169 func TestMain(m *testing.M) {
171 sim, err = startup([]string{})
183 func TestSimpleEdit(t *testing.T) {
184 file, err := createTestFile("micro_simple_edit_test", "base content")
189 defer os.Remove(file)
193 var buf *buffer.Buffer
194 for _, b := range buffer.OpenBuffers {
201 t.Errorf("Could not find buffer %s", file)
205 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
206 injectKey(tcell.KeyUp, 0, tcell.ModNone)
207 injectString("first line")
209 // test both kinds of backspace
210 for i := 0; i < len("ne"); i++ {
211 injectKey(tcell.KeyBackspace, rune(tcell.KeyBackspace), tcell.ModNone)
213 for i := 0; i < len(" li"); i++ {
214 injectKey(tcell.KeyBackspace2, rune(tcell.KeyBackspace2), tcell.ModNone)
216 injectString("foobar")
218 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
220 data, err := ioutil.ReadFile(file)
226 assert.Equal(t, "firstfoobar\nbase content\n", string(data))
229 func TestMouse(t *testing.T) {
230 file, err := createTestFile("micro_mouse_test", "base content")
235 defer os.Remove(file)
241 // the selections need to happen at different locations to avoid a double click
242 injectMouse(3, 0, tcell.Button1, tcell.ModNone)
243 injectKey(tcell.KeyLeft, 0, tcell.ModNone)
244 injectMouse(0, 0, tcell.ButtonNone, tcell.ModNone)
245 injectString("secondline")
247 // secondlinebase content
248 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
252 injectMouse(2, 0, tcell.Button1, tcell.ModNone)
253 injectMouse(0, 0, tcell.ButtonNone, tcell.ModNone)
254 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
259 injectKey(tcell.KeyUp, 0, tcell.ModNone)
260 injectString("firstline")
265 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
267 data, err := ioutil.ReadFile(file)
273 assert.Equal(t, "firstline\nsecondline\nbase content\n", string(data))
276 var srTestStart = `foo
281 var srTest2 = `test_string
283 test_stringtest_stringtest_string
284 Ernleȝe test_string æðelen
286 var srTest3 = `test_foo
288 test_footest_stringtest_foo
289 Ernleȝe test_string æðelen
292 func TestSearchAndReplace(t *testing.T) {
293 file, err := createTestFile("micro_search_replace_test", srTestStart)
298 defer os.Remove(file)
302 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
303 injectString(fmt.Sprintf("replaceall %s %s", "foo", "test_string"))
304 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
306 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
308 data, err := ioutil.ReadFile(file)
314 assert.Equal(t, srTest2, string(data))
316 injectKey(tcell.KeyCtrlE, rune(tcell.KeyCtrlE), tcell.ModCtrl)
317 injectString(fmt.Sprintf("replace %s %s", "string", "foo"))
318 injectKey(tcell.KeyEnter, rune(tcell.KeyEnter), tcell.ModNone)
319 injectString("ynyny")
320 injectKey(tcell.KeyEscape, 0, tcell.ModNone)
322 injectKey(tcell.KeyCtrlS, rune(tcell.KeyCtrlS), tcell.ModCtrl)
324 data, err = ioutil.ReadFile(file)
330 assert.Equal(t, srTest3, string(data))
333 func TestMultiCursor(t *testing.T) {
337 func TestSettingsPersistence(t *testing.T) {
341 // more tests (rendering, tabs, plugins)?