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  }