github.com/jd-ly/tools@v0.5.7/internal/lsp/fake/workdir_test.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fake
     6  
     7  import (
     8  	"context"
     9  	"io/ioutil"
    10  	"os"
    11  	"sort"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/jd-ly/tools/internal/lsp/protocol"
    16  )
    17  
    18  const data = `
    19  -- go.mod --
    20  go 1.12
    21  -- nested/README.md --
    22  Hello World!
    23  `
    24  
    25  func newWorkdir(t *testing.T) (*Workdir, <-chan []FileEvent, func()) {
    26  	t.Helper()
    27  
    28  	tmpdir, err := ioutil.TempDir("", "goplstest-workdir-")
    29  	if err != nil {
    30  		t.Fatal(err)
    31  	}
    32  	wd := NewWorkdir(tmpdir)
    33  	if err := wd.writeInitialFiles(data); err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	cleanup := func() {
    37  		if err := os.RemoveAll(tmpdir); err != nil {
    38  			t.Error(err)
    39  		}
    40  	}
    41  
    42  	fileEvents := make(chan []FileEvent)
    43  	watch := func(_ context.Context, events []FileEvent) {
    44  		fileEvents <- events
    45  	}
    46  	wd.AddWatcher(watch)
    47  	return wd, fileEvents, cleanup
    48  }
    49  
    50  func TestWorkdir_ReadFile(t *testing.T) {
    51  	wd, _, cleanup := newWorkdir(t)
    52  	defer cleanup()
    53  
    54  	got, err := wd.ReadFile("nested/README.md")
    55  	if err != nil {
    56  		t.Fatal(err)
    57  	}
    58  	want := "Hello World!\n"
    59  	if got != want {
    60  		t.Errorf("reading workdir file, got %q, want %q", got, want)
    61  	}
    62  }
    63  
    64  func TestWorkdir_WriteFile(t *testing.T) {
    65  	wd, events, cleanup := newWorkdir(t)
    66  	defer cleanup()
    67  	ctx := context.Background()
    68  
    69  	tests := []struct {
    70  		path     string
    71  		wantType protocol.FileChangeType
    72  	}{
    73  		{"data.txt", protocol.Created},
    74  		{"nested/README.md", protocol.Changed},
    75  	}
    76  
    77  	for _, test := range tests {
    78  		if err := wd.WriteFile(ctx, test.path, "42"); err != nil {
    79  			t.Fatal(err)
    80  		}
    81  		es := <-events
    82  		if got := len(es); got != 1 {
    83  			t.Fatalf("len(events) = %d, want 1", got)
    84  		}
    85  		if es[0].Path != test.path {
    86  			t.Errorf("event.Path = %q, want %q", es[0].Path, test.path)
    87  		}
    88  		if es[0].ProtocolEvent.Type != test.wantType {
    89  			t.Errorf("event type = %v, want %v", es[0].ProtocolEvent.Type, test.wantType)
    90  		}
    91  		got, err := wd.ReadFile(test.path)
    92  		if err != nil {
    93  			t.Fatal(err)
    94  		}
    95  		want := "42"
    96  		if got != want {
    97  			t.Errorf("ws.ReadFile(%q) = %q, want %q", test.path, got, want)
    98  		}
    99  	}
   100  }
   101  
   102  func TestWorkdir_ListFiles(t *testing.T) {
   103  	wd, _, cleanup := newWorkdir(t)
   104  	defer cleanup()
   105  
   106  	checkFiles := func(dir string, want []string) {
   107  		files, err := wd.ListFiles(dir)
   108  		if err != nil {
   109  			t.Fatal(err)
   110  		}
   111  		sort.Strings(want)
   112  		var got []string
   113  		for p := range files {
   114  			got = append(got, p)
   115  		}
   116  		sort.Strings(got)
   117  		if len(got) != len(want) {
   118  			t.Fatalf("ListFiles(): len = %d, want %d; got=%v; want=%v", len(got), len(want), got, want)
   119  		}
   120  		for i, f := range got {
   121  			if f != want[i] {
   122  				t.Errorf("ListFiles()[%d] = %s, want %s", i, f, want[i])
   123  			}
   124  		}
   125  	}
   126  
   127  	checkFiles(".", []string{"go.mod", "nested/README.md"})
   128  	checkFiles("nested", []string{"nested/README.md"})
   129  }
   130  
   131  func TestWorkdir_CheckForFileChanges(t *testing.T) {
   132  	t.Skip("broken on darwin-amd64-10_12")
   133  	wd, events, cleanup := newWorkdir(t)
   134  	defer cleanup()
   135  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
   136  	defer cancel()
   137  
   138  	checkChange := func(path string, typ protocol.FileChangeType) {
   139  		if err := wd.CheckForFileChanges(ctx); err != nil {
   140  			t.Fatal(err)
   141  		}
   142  		var gotEvt FileEvent
   143  		select {
   144  		case <-ctx.Done():
   145  			t.Fatal(ctx.Err())
   146  		case ev := <-events:
   147  			gotEvt = ev[0]
   148  		}
   149  		// Only check relative path and Type
   150  		if gotEvt.Path != path || gotEvt.ProtocolEvent.Type != typ {
   151  			t.Errorf("file events: got %v, want {Path: %s, Type: %v}", gotEvt, path, typ)
   152  		}
   153  	}
   154  	// Sleep some positive amount of time to ensure a distinct mtime.
   155  	time.Sleep(100 * time.Millisecond)
   156  	if err := WriteFileData("go.mod", []byte("module foo.test\n"), wd.RelativeTo); err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	checkChange("go.mod", protocol.Changed)
   160  	if err := WriteFileData("newFile", []byte("something"), wd.RelativeTo); err != nil {
   161  		t.Fatal(err)
   162  	}
   163  	checkChange("newFile", protocol.Created)
   164  	fp := wd.AbsPath("newFile")
   165  	if err := os.Remove(fp); err != nil {
   166  		t.Fatal(err)
   167  	}
   168  	checkChange("newFile", protocol.Deleted)
   169  }
   170  
   171  func TestSplitModuleVersionPath(t *testing.T) {
   172  	tests := []struct {
   173  		path                                string
   174  		wantModule, wantVersion, wantSuffix string
   175  	}{
   176  		{"foo.com@v1.2.3/bar", "foo.com", "v1.2.3", "bar"},
   177  		{"foo.com/module@v1.2.3/bar", "foo.com/module", "v1.2.3", "bar"},
   178  		{"foo.com@v1.2.3", "foo.com", "v1.2.3", ""},
   179  		{"std@v1.14.0", "std", "v1.14.0", ""},
   180  		{"another/module/path", "another/module/path", "", ""},
   181  	}
   182  
   183  	for _, test := range tests {
   184  		module, version, suffix := splitModuleVersionPath(test.path)
   185  		if module != test.wantModule || version != test.wantVersion || suffix != test.wantSuffix {
   186  			t.Errorf("splitModuleVersionPath(%q) =\n\t(%q, %q, %q)\nwant\n\t(%q, %q, %q)",
   187  				test.path, module, version, suffix, test.wantModule, test.wantVersion, test.wantSuffix)
   188  		}
   189  	}
   190  }