github.com/jmigpin/editor@v1.6.0/core/lsproto/all_test.go (about)

     1  package lsproto
     2  
     3  //godebug:annotatepackage
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"log"
    10  	"os"
    11  	"path/filepath"
    12  	"strconv"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/jmigpin/editor/util/iout"
    17  	"github.com/jmigpin/editor/util/iout/iorw"
    18  	"github.com/jmigpin/editor/util/parseutil"
    19  	"github.com/jmigpin/editor/util/testutil"
    20  )
    21  
    22  func TestScripts(t *testing.T) {
    23  	log.SetFlags(0)
    24  	//log.SetPrefix("lsptester: ")
    25  
    26  	scr := testutil.NewScript(os.Args)
    27  	//scr.Work = true
    28  	scr.ScriptsDir = "testdata"
    29  
    30  	man := (*Manager)(nil)
    31  	scr.ScriptStart = func(t *testing.T) error {
    32  		man = newTestManager(t)
    33  		return nil
    34  	}
    35  	scr.ScriptStop = func(t *testing.T) error {
    36  		return man.Close()
    37  	}
    38  
    39  	scr.Cmds = []*testutil.ScriptCmd{
    40  		&testutil.ScriptCmd{"lspSourceCursor", func(t *testing.T, args []string) error {
    41  			return lspSourceCursor(t, args, man)
    42  		}},
    43  		&testutil.ScriptCmd{"lspDefinition", func(t *testing.T, args []string) error {
    44  			return lspDefinition(t, args, man)
    45  		}},
    46  		&testutil.ScriptCmd{"lspCompletion", func(t *testing.T, args []string) error {
    47  			return lspCompletion(t, args, man)
    48  		}},
    49  		&testutil.ScriptCmd{"lspRename", func(t *testing.T, args []string) error {
    50  			return lspRename(t, args, man)
    51  		}},
    52  		&testutil.ScriptCmd{"lspReferences", func(t *testing.T, args []string) error {
    53  			return lspReferences(t, args, man)
    54  		}},
    55  		&testutil.ScriptCmd{"lspCallHierarchy", func(t *testing.T, args []string) error {
    56  			return lspCallHierarchy(t, args, man)
    57  		}},
    58  	}
    59  
    60  	scr.Run(t)
    61  }
    62  
    63  //----------
    64  
    65  func lspSourceCursor(t *testing.T, args []string, man *Manager) error {
    66  	args = args[1:] // remove cmd string
    67  	if len(args) != 3 {
    68  		return fmt.Errorf("sourcecursor: expecting 3 args: %v", args)
    69  	}
    70  
    71  	template := args[0]
    72  	filename := args[1]
    73  	mark := args[2]
    74  
    75  	mark2, err := strconv.ParseInt(mark, 10, 32)
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	// read template
    81  	b, err := os.ReadFile(template)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	offset, src := sourceCursor(t, string(b), int(mark2))
    86  
    87  	// write filename
    88  	if err := os.WriteFile(filename, []byte(src), 0o644); err != nil {
    89  		return err
    90  	}
    91  
    92  	fmt.Printf("%d", offset)
    93  
    94  	return nil
    95  }
    96  
    97  //----------
    98  
    99  func lspDefinition(t *testing.T, args []string, man *Manager) error {
   100  	args = args[1:] // remove cmd string
   101  	if len(args) != 2 {
   102  		return fmt.Errorf("rename: expecting 2 args: %v", args)
   103  	}
   104  
   105  	filename := args[0]
   106  	offset := args[1]
   107  
   108  	// read offset (allow offset from env var)
   109  	offset2, err := getIntArgPossiblyFromEnv(offset)
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	// read filename
   115  	b, err := os.ReadFile(filename)
   116  	if err != nil {
   117  		return err
   118  	}
   119  	rd := iorw.NewStringReaderAt(string(b))
   120  
   121  	// full filename
   122  	filename2, err := filepath.Abs(filename)
   123  	if err != nil {
   124  		return err
   125  	}
   126  
   127  	ctx := context.Background()
   128  	f, rang, err := man.TextDocumentDefinition(ctx, filename2, rd, offset2)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	fmt.Printf("%v %v", f, rang)
   133  	return nil
   134  }
   135  
   136  //----------
   137  
   138  func lspCompletion(t *testing.T, args []string, man *Manager) error {
   139  	args = args[1:] // remove cmd string
   140  	if len(args) != 2 {
   141  		return fmt.Errorf("rename: expecting 2 args: %v", args)
   142  	}
   143  
   144  	filename := args[0]
   145  	offset := args[1]
   146  
   147  	// read offset (allow offset from env var)
   148  	offset2, err := getIntArgPossiblyFromEnv(offset)
   149  	if err != nil {
   150  		return err
   151  	}
   152  
   153  	// read filename
   154  	b, err := os.ReadFile(filename)
   155  	if err != nil {
   156  		return err
   157  	}
   158  	rd := iorw.NewStringReaderAt(string(b))
   159  
   160  	// full filename
   161  	filename2, err := filepath.Abs(filename)
   162  	if err != nil {
   163  		return err
   164  	}
   165  
   166  	ctx := context.Background()
   167  	clist, err := man.TextDocumentCompletion(ctx, filename2, rd, offset2)
   168  	if err != nil {
   169  		return err
   170  	}
   171  	w := CompletionListToString(clist)
   172  	fmt.Printf("%v", w)
   173  	return nil
   174  }
   175  
   176  //----------
   177  
   178  func lspRename(t *testing.T, args []string, man *Manager) error {
   179  	args = args[1:] // remove cmd string
   180  	if len(args) != 3 {
   181  		return fmt.Errorf("rename: expecting 3 args: %v", args)
   182  	}
   183  
   184  	filename := args[0]
   185  	offset := args[1]
   186  	newName := args[2]
   187  
   188  	// read offset (allow offset from env var)
   189  	offset2, err := getIntArgPossiblyFromEnv(offset)
   190  	if err != nil {
   191  		return err
   192  	}
   193  
   194  	// read filename
   195  	b, err := os.ReadFile(filename)
   196  	if err != nil {
   197  		return err
   198  	}
   199  	rd := iorw.NewStringReaderAt(string(b))
   200  
   201  	// full filename
   202  	filename2, err := filepath.Abs(filename)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	ctx := context.Background()
   208  	wecs, err := man.TextDocumentRenameAndPatch(ctx, filename2, rd, offset2, newName, nil)
   209  	if err != nil {
   210  		return err
   211  	}
   212  	for _, wec := range wecs {
   213  		b, err := ioutil.ReadFile(wec.Filename)
   214  		if err != nil {
   215  			return err
   216  		}
   217  		fmt.Printf("filename: %v\n", wec.Filename)
   218  		fmt.Printf("%s\n", b)
   219  	}
   220  
   221  	return nil
   222  }
   223  
   224  //----------
   225  
   226  func lspReferences(t *testing.T, args []string, man *Manager) error {
   227  	args = args[1:] // remove cmd string
   228  	if len(args) != 2 {
   229  		return fmt.Errorf("rename: expecting 2 args: %v", args)
   230  	}
   231  
   232  	filename := args[0]
   233  	offset := args[1]
   234  
   235  	// read offset (allow offset from env var)
   236  	offset2, err := getIntArgPossiblyFromEnv(offset)
   237  	if err != nil {
   238  		return err
   239  	}
   240  
   241  	// read filename
   242  	b, err := os.ReadFile(filename)
   243  	if err != nil {
   244  		return err
   245  	}
   246  	rd := iorw.NewStringReaderAt(string(b))
   247  
   248  	// full filename
   249  	filename2, err := filepath.Abs(filename)
   250  	if err != nil {
   251  		return err
   252  	}
   253  
   254  	ctx := context.Background()
   255  	locs, err := man.TextDocumentReferences(ctx, filename2, rd, offset2)
   256  	if err != nil {
   257  		return err
   258  	}
   259  
   260  	str, err := LocationsToString(locs, "")
   261  	if err != nil {
   262  		return err
   263  	}
   264  	fmt.Printf("%v", str)
   265  
   266  	return nil
   267  }
   268  
   269  //----------
   270  
   271  func lspCallHierarchy(t *testing.T, args []string, man *Manager) error {
   272  	args = args[1:] // remove cmd string
   273  	if len(args) != 2 {
   274  		return fmt.Errorf("rename: expecting 2 args: %v", args)
   275  	}
   276  
   277  	filename := args[0]
   278  	offset := args[1]
   279  
   280  	// read offset (allow offset from env var)
   281  	offset2, err := getIntArgPossiblyFromEnv(offset)
   282  	if err != nil {
   283  		return err
   284  	}
   285  
   286  	// read filename
   287  	b, err := os.ReadFile(filename)
   288  	if err != nil {
   289  		return err
   290  	}
   291  	rd := iorw.NewStringReaderAt(string(b))
   292  
   293  	// full filename
   294  	filename2, err := filepath.Abs(filename)
   295  	if err != nil {
   296  		return err
   297  	}
   298  
   299  	ctx := context.Background()
   300  	mcalls, err := man.CallHierarchyCalls(ctx, filename2, rd, offset2, IncomingChct)
   301  	if err != nil {
   302  		return err
   303  	}
   304  	str, err := ManagerCallHierarchyCallsToString(mcalls, IncomingChct, "")
   305  	if err != nil {
   306  		t.Fatal(err)
   307  	}
   308  	fmt.Printf("result: %v", str)
   309  
   310  	return nil
   311  }
   312  
   313  //----------
   314  //----------
   315  //----------
   316  
   317  func newTestManager(t *testing.T) *Manager {
   318  	t.Helper()
   319  
   320  	msgFn := func(s string) {
   321  		t.Helper()
   322  		// can't use t.Log if already out of the test
   323  		logPrintf("manager async msg: %v", s)
   324  	}
   325  	w := iout.FnWriter(func(p []byte) (int, error) {
   326  		msgFn(string(p))
   327  		return len(p), nil
   328  	})
   329  
   330  	man := NewManager(msgFn)
   331  	man.serverWrapW = w
   332  
   333  	// lang registrations
   334  	u := []string{
   335  		// WARNING: can't use stdio with stderr to be able to run scripts collectlog (use tcp if available)
   336  
   337  		//GoplsRegistration(logTestVerbose(), false, false),
   338  		GoplsRegistration(logTestVerbose(), true, false),
   339  
   340  		//cLangRegistration(logTestVerbose()),
   341  		cLangRegistration(false),
   342  
   343  		pylspRegistration(false, true),
   344  	}
   345  	for _, s := range u {
   346  		reg, err := NewRegistration(s)
   347  		if err != nil {
   348  			panic(err)
   349  		}
   350  		if err := man.Register(reg); err != nil {
   351  			panic(err)
   352  		}
   353  	}
   354  
   355  	return man
   356  }
   357  
   358  //----------
   359  
   360  func getIntArgPossiblyFromEnv(val string) (int, error) {
   361  	// read offset (allow offset from env var)
   362  	envValue := os.Getenv(val)
   363  	if envValue != "" {
   364  		val = strings.TrimSpace(envValue)
   365  	}
   366  
   367  	u, err := strconv.ParseInt(val, 10, 32)
   368  	return int(u), err
   369  }
   370  
   371  //----------
   372  
   373  func sourceCursor(t *testing.T, src string, nth int) (int, string) {
   374  	src2, index, err := testutil.SourceCursor("●", src, nth)
   375  	if err != nil {
   376  		t.Fatal(err)
   377  	}
   378  	return index, src2
   379  }
   380  
   381  func readBytesOffset(t *testing.T, filename string, line, col int) (iorw.ReadWriterAt, int) {
   382  	b, err := ioutil.ReadFile(filename)
   383  	if err != nil {
   384  		t.Fatal(err)
   385  	}
   386  	rw := iorw.NewBytesReadWriterAt(b)
   387  	offset, err := parseutil.LineColumnIndex(rw, line, col)
   388  	if err != nil {
   389  		t.Fatal(err)
   390  	}
   391  	return rw, offset
   392  }