github.com/tiagovtristao/plz@v13.4.0+incompatible/tools/build_langserver/langserver/workspace_store_test.go (about)

     1  package langserver
     2  
     3  import (
     4  	"context"
     5  	"github.com/thought-machine/please/src/core"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/thought-machine/please/tools/build_langserver/lsp"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  var ws = newWorkspaceStore(lsp.DocumentURI(core.RepoRoot))
    15  
    16  func TestWorkspaceStore_Store(t *testing.T) {
    17  	ctx := context.Background()
    18  	content, err := ReadFile(ctx, completionURI)
    19  	assert.Equal(t, nil, err)
    20  	assert.Equal(t, 0, len(ws.documents))
    21  
    22  	text := strings.Join(content, "\n")
    23  	ws.Store(completionURI, text, 1)
    24  	assert.Equal(t, 1, len(ws.documents))
    25  	assert.Equal(t, "name = \"langserver_test\"\n", ws.documents[completionURI].text[0])
    26  }
    27  
    28  func TestWorkspaceStore_TrackEdit(t *testing.T) {
    29  	// Test Add Character
    30  	change := lsp.TextDocumentContentChangeEvent{
    31  		Range: &lsp.Range{
    32  			Start: lsp.Position{Line: 4, Character: 7},
    33  			End:   lsp.Position{Line: 4, Character: 7},
    34  		},
    35  		RangeLength: 1,
    36  		Text:        "s",
    37  	}
    38  
    39  	err := ws.TrackEdit(completionURI, []lsp.TextDocumentContentChangeEvent{change}, 33)
    40  	assert.Equal(t, nil, err)
    41  	assert.Equal(t, "    srcs\n", ws.documents[completionURI].textInEdit[4])
    42  
    43  	// Test Remove line
    44  	change = lsp.TextDocumentContentChangeEvent{
    45  		Range: &lsp.Range{
    46  			Start: lsp.Position{Line: 9, Character: 0},
    47  			End:   lsp.Position{Line: 10, Character: 12},
    48  		},
    49  		RangeLength: 0,
    50  		Text:        "",
    51  	}
    52  
    53  	err = ws.TrackEdit(completionURI, []lsp.TextDocumentContentChangeEvent{change}, 34)
    54  	assert.Equal(t, nil, err)
    55  	expected := []string{
    56  		"go_test(\n",
    57  		"    name = \"\",\n",
    58  		"    srcs =[],\n",
    59  		"    \"//src\"\n",
    60  		")\n",
    61  		"",
    62  	}
    63  	assert.Equal(t, expected, ws.documents[completionURI].textInEdit[6:])
    64  	assert.Equal(t, 34, ws.documents[completionURI].version)
    65  }
    66  
    67  func TestWorkspaceStore_applyChangeAddChar(t *testing.T) {
    68  	text := []string{
    69  		"     \"//src/cli\",\n",
    70  		" name = \"please\",\n",
    71  		"\"//src/quer\"\n",
    72  		"\"//src\"\n",
    73  		"",
    74  	}
    75  
    76  	// add one character
    77  	change := lsp.TextDocumentContentChangeEvent{
    78  		Range: &lsp.Range{
    79  			Start: lsp.Position{Line: 2, Character: 11},
    80  			End:   lsp.Position{Line: 2, Character: 11},
    81  		},
    82  		RangeLength: 0,
    83  		Text:        "y",
    84  	}
    85  	// Copy the text slice so it doesn't modify original
    86  	inText := append([]string{}, text...)
    87  
    88  	outText, err := ws.applyChange(inText, change)
    89  	assert.Equal(t, nil, err)
    90  	expected := []string{
    91  		"     \"//src/cli\",\n",
    92  		" name = \"please\",\n",
    93  		"\"//src/query\"\n",
    94  		"\"//src\"\n",
    95  		"",
    96  	}
    97  	assert.Equal(t, expected, outText)
    98  
    99  	// add a whole line
   100  	change = lsp.TextDocumentContentChangeEvent{
   101  		Range: &lsp.Range{
   102  			Start: lsp.Position{Line: 1, Character: 0},
   103  			End:   lsp.Position{Line: 1, Character: 0},
   104  		},
   105  		RangeLength: 0,
   106  		Text:        "        \"//third_party/go:jsonrpc2\",\n",
   107  	}
   108  	// Copy the text slice so it doesn't modify original
   109  	inText = append([]string{}, text...)
   110  
   111  	outText, err = ws.applyChange(inText, change)
   112  	assert.Equal(t, nil, err)
   113  	expected = []string{
   114  		"     \"//src/cli\",\n",
   115  		"        \"//third_party/go:jsonrpc2\",\n",
   116  		" name = \"please\",\n",
   117  		"\"//src/quer\"\n",
   118  		"\"//src\"\n",
   119  		"",
   120  	}
   121  	assert.Equal(t, expected, outText)
   122  
   123  	// apply changes with empty content
   124  	change = lsp.TextDocumentContentChangeEvent{
   125  		Range: &lsp.Range{
   126  			Start: lsp.Position{Line: 0, Character: 0},
   127  			End:   lsp.Position{Line: 0, Character: 0},
   128  		},
   129  		RangeLength: 0,
   130  		Text:        "yh",
   131  	}
   132  	outText, err = ws.applyChange([]string{""}, change)
   133  	assert.Equal(t, nil, err)
   134  	assert.Equal(t, "yh", outText[0])
   135  	assert.Equal(t, 1, len(outText))
   136  }
   137  
   138  func TestWorkspaceStore_applyChangeDelete(t *testing.T) {
   139  	text := []string{
   140  		"     \"//src/cli\",\n",
   141  		" name = \"please\",\n",
   142  		"\"//src/quer\"\n",
   143  		"\"//src\"\n",
   144  		"",
   145  	}
   146  
   147  	// delete one character
   148  	change := lsp.TextDocumentContentChangeEvent{
   149  		Range: &lsp.Range{
   150  			Start: lsp.Position{Line: 2, Character: 10},
   151  			End:   lsp.Position{Line: 2, Character: 11},
   152  		},
   153  		RangeLength: 0,
   154  		Text:        "",
   155  	}
   156  	// Copy the text slice so it doesn't modify original
   157  	inText := append([]string{}, text...)
   158  
   159  	outText, err := ws.applyChange(inText, change)
   160  	assert.Equal(t, nil, err)
   161  	expected := []string{
   162  		"     \"//src/cli\",\n",
   163  		" name = \"please\",\n",
   164  		"\"//src/que\"\n",
   165  		"\"//src\"\n",
   166  		"",
   167  	}
   168  	assert.Equal(t, expected, outText)
   169  
   170  	// delete more than one char
   171  	change = lsp.TextDocumentContentChangeEvent{
   172  		Range: &lsp.Range{
   173  			Start: lsp.Position{Line: 2, Character: 6},
   174  			End:   lsp.Position{Line: 2, Character: 11},
   175  		},
   176  		RangeLength: 0,
   177  		Text:        "",
   178  	}
   179  
   180  	inText = append([]string{}, text...)
   181  	outText, err = ws.applyChange(inText, change)
   182  	expected = []string{
   183  		"     \"//src/cli\",\n",
   184  		" name = \"please\",\n",
   185  		"\"//src\"\n",
   186  		"\"//src\"\n",
   187  		"",
   188  	}
   189  	assert.Equal(t, expected, outText)
   190  
   191  	// delete the whole line content
   192  	change = lsp.TextDocumentContentChangeEvent{
   193  		Range: &lsp.Range{
   194  			Start: lsp.Position{Line: 2, Character: 0},
   195  			End:   lsp.Position{Line: 2, Character: 12},
   196  		},
   197  		RangeLength: 0,
   198  		Text:        "",
   199  	}
   200  
   201  	inText = append([]string{}, text...)
   202  	outText, err = ws.applyChange(inText, change)
   203  	expected = []string{
   204  		"     \"//src/cli\",\n",
   205  		" name = \"please\",\n",
   206  		"\n",
   207  		"\"//src\"\n",
   208  		"",
   209  	}
   210  	assert.Equal(t, expected, outText)
   211  
   212  	// delete single line content
   213  	change = lsp.TextDocumentContentChangeEvent{
   214  		Range: &lsp.Range{
   215  			Start: lsp.Position{Line: 0, Character: 0},
   216  			End:   lsp.Position{Line: 0, Character: 5},
   217  		},
   218  		RangeLength: 0,
   219  		Text:        "",
   220  	}
   221  
   222  	outText, err = ws.applyChange([]string{"hello"}, change)
   223  	assert.Equal(t, nil, err)
   224  	assert.Equal(t, 1, len(outText))
   225  	assert.Equal(t, "", outText[0])
   226  }
   227  
   228  func TestWorkspaceStore_applyChangeDeleteCrossLine(t *testing.T) {
   229  	text := []string{
   230  		"     \"//src/cli\",\n",
   231  		" name = \"please\",\n",
   232  		"\"//src/quer\"\n",
   233  		"\"//blah\"\n",
   234  		"",
   235  	}
   236  
   237  	// delete the whole line including newline char
   238  	change := lsp.TextDocumentContentChangeEvent{
   239  		Range: &lsp.Range{
   240  			Start: lsp.Position{Line: 3, Character: 0},
   241  			End:   lsp.Position{Line: 4, Character: 0},
   242  		},
   243  		RangeLength: 0,
   244  		Text:        "",
   245  	}
   246  
   247  	inText := append([]string{}, text...)
   248  	outText, err := ws.applyChange(inText, change)
   249  	assert.Equal(t, nil, err)
   250  	expected := []string{
   251  		"     \"//src/cli\",\n",
   252  		" name = \"please\",\n",
   253  		"\"//src/quer\"\n",
   254  		"",
   255  	}
   256  	assert.Equal(t, expected, outText)
   257  
   258  	// Intellij's weird range for deleting the whole line...
   259  	change = lsp.TextDocumentContentChangeEvent{
   260  		Range: &lsp.Range{
   261  			Start: lsp.Position{Line: 3, Character: 0},
   262  			End:   lsp.Position{Line: 4, Character: 8},
   263  		},
   264  		RangeLength: 0,
   265  		Text:        "",
   266  	}
   267  
   268  	inText = append([]string{}, text...)
   269  	outText, err = ws.applyChange(inText, change)
   270  	assert.Equal(t, nil, err)
   271  	expected = []string{
   272  		"     \"//src/cli\",\n",
   273  		" name = \"please\",\n",
   274  		"\"//src/quer\"\n",
   275  		"",
   276  	}
   277  	assert.Equal(t, expected, outText)
   278  
   279  	// and we hope this does not interfere with the same thing
   280  	// if we delete two lines but leave one of the line breaks
   281  	change = lsp.TextDocumentContentChangeEvent{
   282  		Range: &lsp.Range{
   283  			Start: lsp.Position{Line: 2, Character: 0},
   284  			End:   lsp.Position{Line: 3, Character: 12},
   285  		},
   286  		RangeLength: 0,
   287  		Text:        "",
   288  	}
   289  
   290  	inText = []string{
   291  		"     \"//src/cli\",\n",
   292  		" name = \"please\",\n",
   293  		"\"//src/quer\"\n",
   294  		"\"//src/quer\"\n",
   295  		"\"//blah\"\n",
   296  		"",
   297  	}
   298  	outText, err = ws.applyChange(inText, change)
   299  	assert.Equal(t, nil, err)
   300  	expected = []string{
   301  		"     \"//src/cli\",\n",
   302  		" name = \"please\",\n",
   303  		"\n",
   304  		"\"//blah\"\n",
   305  		"",
   306  	}
   307  	assert.Equal(t, expected, outText)
   308  
   309  	// delete some the previous line, but leaving parts of the next line
   310  	change = lsp.TextDocumentContentChangeEvent{
   311  		Range: &lsp.Range{
   312  			Start: lsp.Position{Line: 2, Character: 0},
   313  			End:   lsp.Position{Line: 3, Character: 5},
   314  		},
   315  		RangeLength: 0,
   316  		Text:        "",
   317  	}
   318  
   319  	inText = append([]string{}, text...)
   320  	outText, err = ws.applyChange(inText, change)
   321  	assert.Equal(t, nil, err)
   322  	expected = []string{
   323  		"     \"//src/cli\",\n",
   324  		" name = \"please\",\n",
   325  		"ah\"\n",
   326  		"",
   327  	}
   328  	assert.Equal(t, expected, outText)
   329  
   330  	change = lsp.TextDocumentContentChangeEvent{
   331  		Range: &lsp.Range{
   332  			Start: lsp.Position{Line: 1, Character: 17},
   333  			End:   lsp.Position{Line: 3, Character: 8},
   334  		},
   335  		RangeLength: 0,
   336  		Text:        "",
   337  	}
   338  
   339  	inText = append([]string{}, text...)
   340  	outText, err = ws.applyChange(inText, change)
   341  	assert.Equal(t, nil, err)
   342  	expected = []string{
   343  		"     \"//src/cli\",\n",
   344  		" name = \"please\",\n",
   345  		"",
   346  	}
   347  	assert.Equal(t, expected, outText)
   348  }
   349  
   350  func TestSplitLines(t *testing.T) {
   351  	content := "     \"//src/cli\",\n" +
   352  		" name = \"please\",\n" +
   353  		"\"//src/quer\"\n"
   354  
   355  	text := SplitLines(content, true)
   356  	expected := []string{
   357  		"     \"//src/cli\",\n",
   358  		" name = \"please\",\n",
   359  		"\"//src/quer\"\n",
   360  		"",
   361  	}
   362  
   363  	assert.Equal(t, expected, text)
   364  
   365  	// Test with empty content
   366  	content = ""
   367  	assert.Equal(t, []string{""}, SplitLines(content, true))
   368  }
   369  
   370  func TestJoinLines(t *testing.T) {
   371  	text := []string{
   372  		"     \"//src/cli\",\n",
   373  		" name = \"please\",\n",
   374  		"\"//src/quer\"\n",
   375  		"",
   376  	}
   377  	expected := "     \"//src/cli\",\n" +
   378  		" name = \"please\",\n" +
   379  		"\"//src/quer\"\n"
   380  	content := JoinLines(text, true)
   381  
   382  	assert.Equal(t, expected, content)
   383  
   384  	stmts, _ := analyzer.AspStatementFromFile(exampleBuildURI)
   385  	for _, stmt := range stmts {
   386  		t.Log(stmt)
   387  	}
   388  
   389  }