github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/write_test.go (about)

     1  package readline
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/lmorg/murex/test/count"
     8  	"github.com/lmorg/murex/utils/json"
     9  	"github.com/mattn/go-runewidth"
    10  )
    11  
    12  func TestLineWrap(t *testing.T) {
    13  	type TestLineWrapT struct {
    14  		Prompt    string
    15  		Line      string
    16  		TermWidth int
    17  		Expected  []string
    18  	}
    19  
    20  	tests := []TestLineWrapT{
    21  		{
    22  			Prompt:    "foobar",
    23  			Line:      "1234567890",
    24  			TermWidth: 80,
    25  			Expected:  []string{"1234567890"},
    26  		},
    27  		{
    28  			Prompt:    "foobar",
    29  			Line:      "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
    30  			TermWidth: 86,
    31  			Expected:  []string{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"},
    32  		},
    33  		{
    34  			Prompt:    "foobar",
    35  			Line:      "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
    36  			TermWidth: 87,
    37  			Expected:  []string{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"},
    38  		},
    39  		{
    40  			Prompt:    "foobar",
    41  			Line:      "123456789012345678901234567890",
    42  			TermWidth: 20,
    43  			Expected:  []string{"12345678901234", "      56789012345678", "      90"},
    44  		},
    45  		{
    46  			Prompt:    "foobar",
    47  			Line:      "1234567890",
    48  			TermWidth: 4,
    49  			Expected:  []string{"1234", "5678", "90"},
    50  		},
    51  		{
    52  			Prompt:    "foobar",
    53  			Line:      "1234567890",
    54  			TermWidth: 5,
    55  			Expected:  []string{"12345", "67890"},
    56  		},
    57  		{
    58  			Prompt:    "foobar",
    59  			Line:      "1234567890",
    60  			TermWidth: 6,
    61  			Expected:  []string{"123456", "7890"},
    62  		},
    63  		{
    64  			Prompt:    "foobar",
    65  			Line:      "1234567890",
    66  			TermWidth: 7,
    67  			Expected:  []string{"1", "      2", "      3", "      4", "      5", "      6", "      7", "      8", "      9", "      0"},
    68  		},
    69  		{
    70  			Prompt:    "foobar",
    71  			Line:      "1234567890",
    72  			TermWidth: 8,
    73  			Expected:  []string{"12", "      34", "      56", "      78", "      90"},
    74  		},
    75  		{
    76  			Prompt:    "foobar",
    77  			Line:      "使用再生纸",
    78  			TermWidth: 8,
    79  			Expected:  []string{"使", "      用", "      再", "      生", "      纸"},
    80  		},
    81  		{
    82  			Prompt:    "foobar",
    83  			Line:      "使用再生纸",
    84  			TermWidth: 9,
    85  			Expected:  []string{"使", "      用", "      再", "      生", "      纸"},
    86  		},
    87  	}
    88  
    89  	count.Tests(t, len(tests))
    90  	for i, test := range tests {
    91  		rl := NewInstance()
    92  		rl.SetPrompt(test.Prompt)
    93  		rl.line.Set(rl,[]rune(test.Line))
    94  
    95  		wrap := lineWrap(rl, test.TermWidth)
    96  		if len(wrap) != len(test.Expected) {
    97  			t.Error("Slice lens do not match:")
    98  			t.Logf("  Test:         %d (%s)", i, t.Name())
    99  			t.Logf("  Prompt:      '%s'", test.Prompt)
   100  			t.Logf("  Line:        '%s'", test.Line)
   101  			t.Logf("  Width:        %d", test.TermWidth)
   102  			t.Logf("  len(exp):     %d", len(test.Expected))
   103  			t.Logf("  len(act):     %d", len(wrap))
   104  			t.Logf("  Slice exp:   '%s'", fmt.Sprint(test.Expected))
   105  			t.Logf("  Slice act:   '%s'", fmt.Sprint(wrap))
   106  			t.Logf("  Slice json e: %s", json.LazyLogging(test.Expected))
   107  			t.Logf("  Slice json a: %s", json.LazyLogging(wrap))
   108  			t.Logf("  rl.promptLen: %d'", rl.promptLen)
   109  			t.Logf("  rl.line:     '%s'", rl.line.String())
   110  			continue
   111  		}
   112  
   113  		for j := range wrap {
   114  			if wrap[j] != test.Expected[j] {
   115  				t.Error("Slice element does not match:")
   116  				t.Logf("  Test:      %d (%s)", i, t.Name())
   117  				t.Logf("  Prompt:   '%s'", test.Prompt)
   118  				t.Logf("  Line:     '%s'", test.Line)
   119  				t.Logf("  Width:     %d", test.TermWidth)
   120  				t.Logf("  Expected:  %s", test.Expected[j])
   121  				t.Logf("  Actual:    %s", wrap[j])
   122  				t.Logf("  len(exp):  %d", len(test.Expected))
   123  				t.Logf("  len(act):  %d", len(wrap))
   124  				t.Logf("  Slice exp:'%s'", fmt.Sprint(test.Expected))
   125  				t.Logf("  Slice act:'%s'", fmt.Sprint(wrap))
   126  				t.Logf("  Slice j e: %s", json.LazyLogging(test.Expected))
   127  				t.Logf("  Slice j a: %s", json.LazyLogging(wrap))
   128  			}
   129  		}
   130  	}
   131  }
   132  
   133  func TestLineWrapCell(t *testing.T) {
   134  	type ExpectedT struct {
   135  		X, Y int
   136  	}
   137  
   138  	type TestLineWrapPosT struct {
   139  		Prompt    string
   140  		Line      string
   141  		TermWidth int
   142  		Expected  ExpectedT
   143  	}
   144  
   145  	tests := []TestLineWrapPosT{
   146  		{
   147  			Prompt:    "12345",
   148  			Line:      "",
   149  			TermWidth: 10,
   150  			Expected:  ExpectedT{5 + 0, 0},
   151  		},
   152  		/////
   153  		{
   154  			Prompt:    "12345",
   155  			Line:      "123",
   156  			TermWidth: 10,
   157  			Expected:  ExpectedT{5 + 3, 0},
   158  		},
   159  		{
   160  			Prompt:    "12345",
   161  			Line:      "1234",
   162  			TermWidth: 10,
   163  			Expected:  ExpectedT{5 + 4, 0},
   164  		},
   165  		{
   166  			Prompt:    "12345",
   167  			Line:      "12345",
   168  			TermWidth: 10,
   169  			Expected:  ExpectedT{10, 0},
   170  		},
   171  		{
   172  			Prompt:    "12345",
   173  			Line:      "123456",
   174  			TermWidth: 10,
   175  			Expected:  ExpectedT{5 + 1, 1},
   176  		},
   177  		{
   178  			Prompt:    "foobar",
   179  			Line:      "1234567890",
   180  			TermWidth: 80,
   181  			Expected:  ExpectedT{6 + 10, 0},
   182  		},
   183  		{
   184  			Prompt:    "foobar",
   185  			Line:      "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
   186  			TermWidth: 85,
   187  			Expected:  ExpectedT{6 + 1, 1},
   188  		},
   189  		{
   190  			Prompt:    "foobar",
   191  			Line:      "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
   192  			TermWidth: 86,
   193  			Expected:  ExpectedT{86, 0},
   194  		},
   195  		{
   196  			Prompt:    "foobar",
   197  			Line:      "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
   198  			TermWidth: 87,
   199  			Expected:  ExpectedT{86, 0},
   200  		},
   201  		{
   202  			Prompt:    "foobar",
   203  			Line:      "123456789012345678901234567890",
   204  			TermWidth: 20,
   205  			//Expected:  []string{"12345678901234", "56789012345678", "90"},
   206  			Expected: ExpectedT{6 + 2, 2},
   207  		},
   208  		{ // 10
   209  			Prompt:    "foobar",
   210  			Line:      "1234567890",
   211  			TermWidth: 4,
   212  			//Expected:  []string{"1234", "5678", "90"},
   213  			Expected: ExpectedT{0 + 2, 2},
   214  		},
   215  		{
   216  			Prompt:    "foobar",
   217  			Line:      "1234567890",
   218  			TermWidth: 5,
   219  			//Expected:  []string{"12345", "67890"},
   220  			Expected: ExpectedT{5, 1},
   221  		},
   222  		{
   223  			Prompt:    "foobar",
   224  			Line:      "1234567890",
   225  			TermWidth: 6,
   226  			//Expected:  []string{"123456", "7890"},
   227  			Expected: ExpectedT{0 + 4, 1},
   228  		},
   229  		{
   230  			Prompt:    "foobar",
   231  			Line:      "1234567890",
   232  			TermWidth: 7,
   233  			//Expected:  []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"},
   234  			Expected: ExpectedT{7, 9},
   235  		},
   236  		{
   237  			Prompt:    "foobar",
   238  			Line:      "1234567890",
   239  			TermWidth: 8,
   240  			//Expected:  []string{"12", "34", "56", "78", "90"},
   241  			Expected: ExpectedT{6 + 2, 4},
   242  		},
   243  		/////
   244  		{
   245  			Prompt:    "foobar",
   246  			Line:      "使用再生纸",
   247  			TermWidth: 8,
   248  			//Expected:  []string{"12", "34", "56", "78", "90"},
   249  			Expected: ExpectedT{6 + 2, 4},
   250  		},
   251  		{
   252  			Prompt:    "foo",
   253  			Line:      "使用 再生纸",
   254  			TermWidth: 8,
   255  			//Expected:  []string{"12", "34", "56", "78", "90"},
   256  			Expected: ExpectedT{X: 5, Y: 2},
   257  		},
   258  		{
   259  			Prompt:    "foo",
   260  			Line:      "使用 再生纸 使用 再生",
   261  			TermWidth: 8,
   262  			//Expected:  []string{"12", "34", "56", "78", "90"},
   263  			Expected: ExpectedT{X: 5, Y: 4},
   264  		},
   265  		{
   266  			Prompt:    "使用",
   267  			Line:      "使用再生纸使用再生",
   268  			TermWidth: 8,
   269  			//Expected:  []string{"12", "34", "56", "78", "90"},
   270  			Expected: ExpectedT{X: 6, Y: 4},
   271  		},
   272  	}
   273  
   274  	count.Tests(t, len(tests))
   275  	for i, test := range tests {
   276  		promptLen := runewidth.StringWidth(test.Prompt)
   277  		x, y := lineWrapCell(promptLen, []rune(test.Line), test.TermWidth)
   278  
   279  		if (test.Expected.X != x) || (test.Expected.Y != y) {
   280  			t.Error("X or Y does not match:")
   281  			t.Logf("  Test:      %d (%s)", i, t.Name())
   282  			t.Logf("  Prompt:   '%s'", test.Prompt)
   283  			t.Logf("  Prompt len %d", promptLen)
   284  			t.Logf("  Line:     '%s'", test.Line)
   285  			t.Logf("  Width:     %d", test.TermWidth)
   286  			t.Logf("  Expected X:%d", test.Expected.X)
   287  			t.Logf("  Actual   X:%d", x)
   288  			t.Logf("  Expected Y:%d", test.Expected.Y)
   289  			t.Logf("  Actual   Y:%d", y)
   290  		}
   291  
   292  	}
   293  }