github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwedit/all_test.go (about) 1 package rwedit 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/jmigpin/editor/util/iout/iorw" 8 ) 9 10 func TestAll1(t *testing.T) { 11 type state struct { 12 s string 13 ci int // cursor index 14 si int // selected index 15 son bool // selection on 16 } 17 type test struct { 18 st state 19 est state // expected state 20 f func(*Ctx) error 21 } 22 23 var testEntry func(*test) 24 25 var testFns = []func(){ 26 func() { 27 testEntry(&test{ 28 st: state{s: "123\nabc\n", ci: 0}, 29 est: state{s: "123\n123\nabc\n", si: 4, ci: 7, son: true}, 30 f: DuplicateLines, 31 }) 32 }, 33 func() { 34 testEntry(&test{ 35 st: state{s: "123", ci: 0}, 36 est: state{s: "123\n123", si: 4, ci: 7, son: true}, 37 f: DuplicateLines, 38 }) 39 }, 40 func() { 41 testEntry(&test{ 42 st: state{s: " 123", ci: 4}, 43 est: state{s: " 1\n 23", ci: 8}, 44 f: func(ctx *Ctx) error { return AutoIndent(ctx) }, 45 }) 46 }, 47 func() { 48 testEntry(&test{ 49 st: state{s: " 123", ci: 4, si: 5, son: true}, 50 est: state{s: " 1\n 3", ci: 8, son: false}, 51 f: AutoIndent, 52 }) 53 }, 54 func() { 55 testEntry(&test{ 56 st: state{s: "0123\n abc", ci: 10}, 57 est: state{s: "0123\n ab\n c", ci: 14, son: false}, 58 f: AutoIndent, 59 }) 60 }, 61 func() { 62 testEntry(&test{ 63 st: state{s: "0123\n abc", ci: 6}, 64 est: state{s: "0123\n \n abc", ci: 8, son: false}, 65 f: AutoIndent, 66 }) 67 }, 68 func() { 69 testEntry(&test{ 70 st: state{s: "123", ci: 2}, 71 est: state{s: "13", ci: 1}, 72 f: Backspace, 73 }) 74 }, 75 func() { 76 testEntry(&test{ 77 st: state{s: "01234", ci: 2, si: 4, son: true}, 78 est: state{s: "014", ci: 2}, 79 f: Backspace, 80 }) 81 }, 82 func() { 83 testEntry(&test{ 84 st: state{s: "01234"}, 85 est: state{s: "//01234", ci: 2}, 86 f: Comment, 87 }) 88 }, 89 func() { 90 testEntry(&test{ 91 st: state{s: "0123\n abc\n efg\n", si: 9, ci: 14, son: true}, 92 est: state{s: "0123\n // abc\n //efg\n", si: 5, ci: 19, son: true}, 93 f: Comment, 94 }) 95 }, 96 func() { 97 testEntry(&test{ 98 st: state{s: "0123\n // abc\n //efg\n", si: 5, ci: 19, son: true}, 99 est: state{s: "0123\n abc\n efg\n", si: 5, ci: 15, son: true}, 100 f: Uncomment, 101 }) 102 }, 103 func() { 104 testEntry(&test{ 105 st: state{s: "01234", ci: 2, si: 4, son: true}, 106 est: state{s: "014", ci: 2}, 107 f: Cut, 108 }) 109 }, 110 func() { 111 testEntry(&test{ 112 st: state{s: "01234", ci: 2, si: 4, son: true}, 113 est: state{s: "014", ci: 2}, 114 f: Delete, 115 }) 116 }, 117 func() { 118 testEntry(&test{ 119 st: state{s: "01234", ci: 2}, 120 est: state{s: "0134", ci: 2}, 121 f: Delete, 122 }) 123 }, 124 func() { 125 testEntry(&test{ 126 st: state{s: "0123\nabc", ci: 7}, 127 est: state{s: "0123\nabc", ci: 5}, 128 f: func(ctx *Ctx) error { 129 return StartOfLine(ctx, false) 130 }, 131 }) 132 }, 133 func() { 134 testEntry(&test{ 135 st: state{s: "0123\nabc"}, 136 est: state{s: "0123\nabc", ci: 4}, 137 f: func(ctx *Ctx) error { 138 return EndOfLine(ctx, false) 139 }, 140 }) 141 }, 142 func() { 143 testEntry(&test{ 144 st: state{s: "0123\nabc", ci: 6}, 145 est: state{s: "0123\nabc", si: 6, ci: 8, son: true}, 146 f: func(ctx *Ctx) error { 147 return EndOfLine(ctx, true) 148 }, 149 }) 150 }, 151 func() { 152 testEntry(&test{ 153 st: state{s: "012"}, 154 est: state{s: "012", ci: 3}, 155 f: func(ctx *Ctx) error { 156 return EndOfLine(ctx, false) 157 }, 158 }) 159 }, 160 func() { 161 testEntry(&test{ 162 st: state{s: "012\nabc", ci: 7}, 163 est: state{s: "012\nabc", ci: 0}, 164 f: func(ctx *Ctx) error { 165 StartOfString(ctx, false) 166 return nil 167 }, 168 }) 169 }, 170 func() { 171 testEntry(&test{ 172 st: state{s: "012\nabc"}, 173 est: state{s: "012\nabc", ci: 7}, 174 f: func(ctx *Ctx) error { 175 EndOfString(ctx, false) 176 return nil 177 }, 178 }) 179 }, 180 func() { 181 testEntry(&test{ 182 st: state{s: "01234\nabc"}, 183 est: state{s: "01234\nabc", si: 6, ci: 8, son: true}, 184 f: func(ctx *Ctx) error { 185 cctx := context.Background() 186 opt := &iorw.IndexOpt{} 187 _, err := Find(cctx, ctx, "ab", false, opt) 188 return err 189 }, 190 }) 191 }, 192 func() { 193 testEntry(&test{ 194 st: state{s: "01234\nabc", ci: 7}, 195 est: state{s: "01234\nabc", si: 6, ci: 8, son: true}, 196 f: func(ctx *Ctx) error { 197 cctx := context.Background() 198 opt := &iorw.IndexOpt{} 199 _, err := Find(cctx, ctx, "ab", false, opt) 200 return err 201 }, 202 }) 203 }, 204 func() { 205 testEntry(&test{ 206 st: state{s: "0123", ci: 2}, 207 est: state{s: "01ab23", ci: 4}, 208 f: func(ctx *Ctx) error { 209 return InsertString(ctx, "ab") 210 }, 211 }) 212 }, 213 func() { 214 testEntry(&test{ 215 st: state{s: "0123", ci: 2}, 216 est: state{s: "0123", ci: 1}, 217 f: func(ctx *Ctx) error { 218 return MoveCursorLeft(ctx, false) 219 }, 220 }) 221 }, 222 func() { 223 testEntry(&test{ 224 st: state{s: "0123", ci: 2}, 225 est: state{s: "0123", ci: 3}, 226 f: func(ctx *Ctx) error { 227 return MoveCursorRight(ctx, false) 228 }, 229 }) 230 }, 231 func() { 232 testEntry(&test{ 233 st: state{s: " 0123 ", ci: 3}, 234 est: state{s: " 0123 ", ci: 5}, 235 f: func(ctx *Ctx) error { 236 return MoveCursorJumpRight(ctx, false) 237 }, 238 }) 239 }, 240 func() { 241 testEntry(&test{ 242 st: state{s: "0123\nabcd", ci: 5}, 243 est: state{s: "abcd\n0123", ci: 0}, 244 f: MoveLineUp, 245 }) 246 }, 247 func() { 248 testEntry(&test{ 249 st: state{s: "0123\nabcd\n", ci: 5}, 250 est: state{s: "abcd\n0123\n", ci: 0}, 251 f: MoveLineUp, 252 }) 253 }, 254 func() { 255 testEntry(&test{ 256 st: state{s: "01\nab\nzy", si: 4, ci: 7, son: true}, 257 est: state{s: "ab\nzy\n01", si: 0, ci: 5, son: true}, 258 f: MoveLineUp, 259 }) 260 }, 261 func() { 262 testEntry(&test{ 263 st: state{s: "01\nab\nzy"}, 264 est: state{s: "ab\n01\nzy", ci: 3}, 265 f: MoveLineDown, 266 }) 267 }, 268 func() { 269 testEntry(&test{ 270 st: state{s: "01\nab\nzy\n", si: 0, ci: 4, son: true}, 271 est: state{s: "zy\n01\nab\n", si: 3, ci: 8, son: true}, 272 f: MoveLineDown, 273 }) 274 }, 275 func() { 276 testEntry(&test{ 277 st: state{s: "01\nab\nzy", ci: 4}, 278 est: state{s: "01\nzy\nab", ci: 7}, 279 f: MoveLineDown, 280 }) 281 }, 282 func() { 283 testEntry(&test{ 284 st: state{s: "01\nab\n", ci: 4}, 285 est: state{s: "01\n\nab", ci: 5}, 286 f: MoveLineDown, 287 }) 288 }, 289 func() { 290 testEntry(&test{ 291 st: state{s: "aaa\nbbb\n", ci: 4, si: 5, son: true}, 292 est: state{s: "aaa\n\nbbb", ci: 8, si: 5, son: true}, 293 f: MoveLineDown, 294 }) 295 }, 296 func() { 297 testEntry(&test{ 298 st: state{s: "aaa\nbbb\n\n", ci: 4, si: 6, son: true}, 299 est: state{s: "aaa\n\n", ci: 4}, 300 f: RemoveLines, 301 }) 302 }, 303 func() { 304 testEntry(&test{ 305 st: state{s: "0123401234", ci: 4}, 306 est: state{s: "0404", ci: 1}, 307 f: func(ctx *Ctx) error { 308 _, err := Replace(ctx, "123", "") 309 return err 310 }, 311 }) 312 }, 313 func() { 314 testEntry(&test{ 315 st: state{s: "012 -- abc", ci: 4}, 316 est: state{s: "012 -- abc", si: 4, ci: 5, son: true}, 317 f: SelectWord, 318 }) 319 }, 320 func() { 321 testEntry(&test{ 322 st: state{s: "--abc--", ci: 3}, 323 est: state{s: "--abc--", si: 2, ci: 5, son: true}, 324 f: SelectWord, 325 }) 326 }, 327 func() { 328 testEntry(&test{ 329 st: state{s: "--abc--", ci: 5}, 330 est: state{s: "--abc--", si: 5, ci: 6, son: true}, 331 f: SelectWord, 332 }) 333 }, 334 func() { 335 testEntry(&test{ 336 st: state{s: "abc\n 0123", ci: 10}, 337 est: state{s: "abc\n 0123", ci: 7}, 338 f: func(ctx *Ctx) error { 339 return StartOfLine(ctx, false) 340 }, 341 }) 342 }, 343 func() { 344 testEntry(&test{ 345 st: state{s: "0123", ci: 0}, 346 est: state{s: "\t0123", ci: 1}, 347 f: TabRight, 348 }) 349 }, 350 func() { 351 testEntry(&test{ 352 st: state{s: "0123\nabc\n", si: 2, ci: 6, son: true}, 353 est: state{s: "\t0123\n\tabc\n", si: 0, ci: 10, son: true}, 354 f: TabRight, 355 }) 356 }, 357 func() { 358 testEntry(&test{ 359 st: state{s: "\t0123\n\tabc\n", si: 2, ci: 8, son: true}, 360 est: state{s: "0123\nabc\n", si: 0, ci: 8, son: true}, 361 f: TabLeft, 362 }) 363 }, 364 func() { 365 testEntry(&test{ 366 st: state{s: "\t0123\n\tabc\n", ci: 4}, 367 est: state{s: "\t0123\n\tabc\n", si: 0, ci: 11, son: true}, 368 f: SelectAll, 369 }) 370 }, 371 func() { 372 testEntry(&test{ 373 st: state{s: "\t0123\n\tabc\n", ci: 8}, 374 est: state{s: "\t0123\n\tabc\n", ci: 11, si: 6, son: true}, 375 f: SelectLine, 376 }) 377 }, 378 } 379 380 // TODO: movecursorup/movecursordown 381 // TODO: copy 382 // TODO: paste 383 384 testEntry = func(w *test) { 385 t.Helper() 386 387 // init 388 ctx := NewCtx() 389 ctx.Fns = EmptyCtxFns() 390 ctx.Fns.LineCommentStr = func() string { return "//" } 391 ctx.RW = iorw.NewBytesReadWriterAt([]byte(w.st.s)) 392 393 if w.st.son { 394 ctx.C.SetSelection(w.st.si, w.st.ci) 395 } else { 396 ctx.C.SetIndex(w.st.ci) 397 } 398 399 // func error 400 if err := w.f(ctx); err != nil { 401 t.Fatal(err) 402 } 403 // content 404 b, err := iorw.ReadFastFull(ctx.RW) 405 if err != nil { 406 t.Fatal(err) 407 } 408 // state 409 est := state{ 410 s: string(b), 411 ci: ctx.C.Index(), 412 si: ctx.C.SelectionIndex(), 413 son: ctx.C.HaveSelection(), 414 } 415 if est != w.est { 416 t.Fatalf("expected:\n%v\ngot:\n%v\n", w.est, est) 417 } 418 } 419 420 // run tests 421 for _, fn := range testFns { 422 fn() 423 } 424 }