github.com/mithrandie/csvq@v1.18.1/lib/terminal/terminal_test.go (about)

     1  package terminal
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/mithrandie/csvq/lib/excmd"
     9  	"github.com/mithrandie/csvq/lib/parser"
    10  	"github.com/mithrandie/csvq/lib/query"
    11  	"github.com/mithrandie/csvq/lib/value"
    12  )
    13  
    14  var promptLoadConfigTests = []struct {
    15  	Prompt                   string
    16  	ContinuousPrompt         string
    17  	ExpectSequence           []PromptElement
    18  	ExpectContinuousSequence []PromptElement
    19  	Error                    string
    20  }{
    21  	{
    22  		Prompt:                   "TEST P > ",
    23  		ContinuousPrompt:         "TEST C > ",
    24  		ExpectSequence:           []PromptElement{{Text: "TEST P > ", Type: excmd.FixedString}},
    25  		ExpectContinuousSequence: []PromptElement{{Text: "TEST C > ", Type: excmd.FixedString}},
    26  	},
    27  	{
    28  		Prompt:                   "TEST P @ > ",
    29  		ContinuousPrompt:         "TEST C > ",
    30  		ExpectSequence:           nil,
    31  		ExpectContinuousSequence: nil,
    32  		Error:                    "prompt: invalid variable symbol",
    33  	},
    34  	{
    35  		Prompt:                   "TEST P > ",
    36  		ContinuousPrompt:         "TEST C @ > ",
    37  		ExpectSequence:           nil,
    38  		ExpectContinuousSequence: nil,
    39  		Error:                    "prompt: invalid variable symbol",
    40  	},
    41  }
    42  
    43  func TestPrompt_LoadConfig(t *testing.T) {
    44  	prompt := NewPrompt(query.NewReferenceScope(TestTx))
    45  
    46  	for _, v := range promptLoadConfigTests {
    47  		TestTx.Environment.InteractiveShell.Prompt = v.Prompt
    48  		TestTx.Environment.InteractiveShell.ContinuousPrompt = v.ContinuousPrompt
    49  
    50  		err := prompt.LoadConfig()
    51  		if err != nil {
    52  			if len(v.Error) < 1 {
    53  				t.Errorf("unexpected error %q for %s, %s", err, v.Prompt, v.ContinuousPrompt)
    54  			} else if err.Error() != v.Error {
    55  				t.Errorf("error %q, want error %q for %s, %s", err.Error(), v.Error, v.Prompt, v.ContinuousPrompt)
    56  			}
    57  		} else if 0 < len(v.Error) {
    58  			t.Errorf("no error, want error %q for %s, %s", v.Error, v.Prompt, v.ContinuousPrompt)
    59  		}
    60  
    61  		if !reflect.DeepEqual(prompt.sequence, v.ExpectSequence) {
    62  			t.Errorf("sequence = %v, want %v for %s, %s", prompt.sequence, v.ExpectSequence, v.Prompt, v.ContinuousPrompt)
    63  		}
    64  		if !reflect.DeepEqual(prompt.continuousSequence, v.ExpectContinuousSequence) {
    65  			t.Errorf("continuous sequence = %v, want %v for %s, %s", prompt.continuousSequence, v.ExpectContinuousSequence, v.Prompt, v.ContinuousPrompt)
    66  		}
    67  	}
    68  }
    69  
    70  var promptRenderPromptTests = []struct {
    71  	Sequence []PromptElement
    72  	UseColor bool
    73  	Expect   string
    74  	Error    string
    75  }{
    76  	{
    77  		Sequence: nil,
    78  		UseColor: false,
    79  		Expect:   DefaultPrompt,
    80  	},
    81  	{
    82  		Sequence: []PromptElement{
    83  			{Text: "\033[32mstr\033[0m", Type: excmd.FixedString},
    84  		},
    85  		UseColor: true,
    86  		Expect:   "\033[32mstr\033[0m",
    87  	},
    88  	{
    89  		Sequence: []PromptElement{
    90  			{Text: "str", Type: excmd.FixedString},
    91  		},
    92  		UseColor: true,
    93  		Expect:   "\033[34mstr\033[0m",
    94  	},
    95  	{
    96  		Sequence: []PromptElement{
    97  			{Text: "\033[32mstr\033[0m", Type: excmd.FixedString},
    98  		},
    99  		UseColor: false,
   100  		Expect:   "str",
   101  	},
   102  }
   103  
   104  func TestPrompt_RenderPrompt(t *testing.T) {
   105  	defer func() {
   106  		TestTx.UseColor(false)
   107  		initFlag(TestTx.Flags)
   108  	}()
   109  
   110  	prompt := NewPrompt(query.NewReferenceScope(TestTx))
   111  
   112  	for _, v := range promptRenderPromptTests {
   113  		TestTx.UseColor(v.UseColor)
   114  		prompt.sequence = v.Sequence
   115  		result, err := prompt.RenderPrompt(context.Background())
   116  
   117  		if err != nil {
   118  			if len(v.Error) < 1 {
   119  				t.Errorf("unexpected error %q for %v", err, v.Sequence)
   120  			} else if err.Error() != v.Error {
   121  				t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Sequence)
   122  			}
   123  			continue
   124  		}
   125  		if 0 < len(v.Error) {
   126  			t.Errorf("no error, want error %q for %v", v.Error, v.Sequence)
   127  			continue
   128  		}
   129  
   130  		if result != v.Expect {
   131  			t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Sequence)
   132  		}
   133  	}
   134  }
   135  
   136  var promptRenderContinuousPromptTests = []struct {
   137  	Sequence []PromptElement
   138  	UseColor bool
   139  	Expect   string
   140  	Error    string
   141  }{
   142  	{
   143  		Sequence: nil,
   144  		UseColor: false,
   145  		Expect:   DefaultContinuousPrompt,
   146  	},
   147  	{
   148  		Sequence: []PromptElement{
   149  			{Text: "\033[32mstr\033[0m", Type: excmd.FixedString},
   150  		},
   151  		UseColor: true,
   152  		Expect:   "\033[32mstr\033[0m",
   153  	},
   154  	{
   155  		Sequence: []PromptElement{
   156  			{Text: "str", Type: excmd.FixedString},
   157  		},
   158  		UseColor: true,
   159  		Expect:   "\033[34mstr\033[0m",
   160  	},
   161  	{
   162  		Sequence: []PromptElement{
   163  			{Text: "\033[32mstr\033[0m", Type: excmd.FixedString},
   164  		},
   165  		UseColor: false,
   166  		Expect:   "str",
   167  	},
   168  }
   169  
   170  func TestPrompt_RenderContinuousPrompt(t *testing.T) {
   171  	defer func() {
   172  		TestTx.UseColor(false)
   173  		initFlag(TestTx.Flags)
   174  	}()
   175  
   176  	prompt := NewPrompt(query.NewReferenceScope(TestTx))
   177  
   178  	for _, v := range promptRenderContinuousPromptTests {
   179  		TestTx.UseColor(v.UseColor)
   180  		prompt.continuousSequence = v.Sequence
   181  		result, err := prompt.RenderContinuousPrompt(context.Background())
   182  
   183  		if err != nil {
   184  			if len(v.Error) < 1 {
   185  				t.Errorf("unexpected error %q for %v", err, v.Sequence)
   186  			} else if err.Error() != v.Error {
   187  				t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Sequence)
   188  			}
   189  			continue
   190  		}
   191  		if 0 < len(v.Error) {
   192  			t.Errorf("no error, want error %q for %v", v.Error, v.Sequence)
   193  			continue
   194  		}
   195  
   196  		if result != v.Expect {
   197  			t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Sequence)
   198  		}
   199  	}
   200  }
   201  
   202  var promptRenderTests = []struct {
   203  	Input  []PromptElement
   204  	Expect string
   205  	Error  string
   206  }{
   207  	{
   208  		Input:  nil,
   209  		Expect: "",
   210  	},
   211  	{
   212  		Input: []PromptElement{
   213  			{Text: "str", Type: excmd.FixedString},
   214  			{Text: "var", Type: excmd.Variable},
   215  			{Text: "CSVQ_TEST_ENV", Type: excmd.EnvironmentVariable},
   216  			{Text: "VERSION", Type: excmd.RuntimeInformation},
   217  			{Text: "@var", Type: excmd.CsvqExpression},
   218  		},
   219  		Expect: "strabcfoov1.0.0abc",
   220  	},
   221  	{
   222  		Input: []PromptElement{
   223  			{Text: "notexist", Type: excmd.Variable},
   224  		},
   225  		Error: "prompt: variable @notexist is undeclared",
   226  	},
   227  	{
   228  		Input: []PromptElement{
   229  			{Text: "NOTEXIST", Type: excmd.RuntimeInformation},
   230  		},
   231  		Error: "prompt: @#NOTEXIST is an unknown runtime information",
   232  	},
   233  	{
   234  		Input: []PromptElement{
   235  			{Text: "invalid invalid", Type: excmd.CsvqExpression},
   236  		},
   237  		Error: "prompt: syntax error: unexpected token \"invalid\"",
   238  	},
   239  	{
   240  		Input: []PromptElement{
   241  			{Text: "", Type: excmd.CsvqExpression},
   242  		},
   243  		Expect: "",
   244  	},
   245  	{
   246  		Input: []PromptElement{
   247  			{Text: "print 1;", Type: excmd.CsvqExpression},
   248  		},
   249  		Error: "prompt: print 1;: cannot evaluate as a value",
   250  	},
   251  	{
   252  		Input: []PromptElement{
   253  			{Text: "1;2", Type: excmd.CsvqExpression},
   254  		},
   255  		Error: "prompt: 1;2: cannot evaluate as a value",
   256  	},
   257  	{
   258  		Input: []PromptElement{
   259  			{Text: "@notexist", Type: excmd.CsvqExpression},
   260  		},
   261  		Error: "prompt: variable @notexist is undeclared",
   262  	},
   263  }
   264  
   265  func TestPrompt_Render(t *testing.T) {
   266  	scope := query.NewReferenceScope(TestTx)
   267  	_ = scope.DeclareVariableDirectly(parser.Variable{Name: "var"}, value.NewString("abc"))
   268  	prompt := NewPrompt(scope)
   269  
   270  	for _, v := range promptRenderTests {
   271  		result, err := prompt.Render(context.Background(), v.Input)
   272  
   273  		if err != nil {
   274  			if len(v.Error) < 1 {
   275  				t.Errorf("unexpected error %q for %v", err, v.Input)
   276  			} else if err.Error() != v.Error {
   277  				t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Input)
   278  			}
   279  			continue
   280  		}
   281  		if 0 < len(v.Error) {
   282  			t.Errorf("no error, want error %q for %v", v.Error, v.Input)
   283  			continue
   284  		}
   285  
   286  		if result != v.Expect {
   287  			t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Input)
   288  		}
   289  	}
   290  }
   291  
   292  var promptStripEscapeSequenceTests = []struct {
   293  	Input  string
   294  	Expect string
   295  }{
   296  	{
   297  		Input:  "\u001b[34;1m/path/to/working/directory \u001b[33;1m(Uncommitted:2)\u001b[34;1m >\u001b[0m ",
   298  		Expect: "/path/to/working/directory (Uncommitted:2) > ",
   299  	},
   300  }
   301  
   302  func TestPrompt_StripEscapeSequence(t *testing.T) {
   303  	prompt := NewPrompt(query.NewReferenceScope(TestTx))
   304  
   305  	for _, v := range promptStripEscapeSequenceTests {
   306  		result := prompt.StripEscapeSequence(v.Input)
   307  
   308  		if result != v.Expect {
   309  			t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Input)
   310  		}
   311  	}
   312  }