gitstack

grindlemire/go-tui code browser

3.2 KB Go 133 lines 2026-03-01 · af637c7 raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package lsp

import (
	"bytes"
	"encoding/json"
	"testing"
)

func newTestServer() *Server {
	return NewServer(bytes.NewReader(nil), &bytes.Buffer{})
}

func TestHandleInitialize_ReturnsCapabilities(t *testing.T) {
	s := newTestServer()

	params, _ := json.Marshal(InitializeParams{
		RootURI: "file:///tmp/test",
	})

	result, lspErr := s.handleInitialize(params)
	if lspErr != nil {
		t.Fatalf("handleInitialize returned error: %v", lspErr)
	}

	initResult, ok := result.(InitializeResult)
	if !ok {
		t.Fatalf("expected InitializeResult, got %T", result)
	}

	caps := initResult.Capabilities

	if caps.TextDocumentSync == nil {
		t.Fatal("TextDocumentSync should be set")
	}
	if !caps.TextDocumentSync.OpenClose {
		t.Error("TextDocumentSync.OpenClose should be true")
	}
	if caps.TextDocumentSync.Change != TextDocumentSyncKindFull {
		t.Errorf("TextDocumentSync.Change = %d, want %d", caps.TextDocumentSync.Change, TextDocumentSyncKindFull)
	}
	if caps.CompletionProvider == nil {
		t.Error("CompletionProvider should be set")
	}

	type tc struct {
		got  bool
		want bool
	}

	tests := map[string]tc{
		"HoverProvider":              {got: caps.HoverProvider, want: true},
		"DefinitionProvider":         {got: caps.DefinitionProvider, want: true},
		"ReferencesProvider":         {got: caps.ReferencesProvider, want: true},
		"DocumentSymbolProvider":     {got: caps.DocumentSymbolProvider, want: true},
		"WorkspaceSymbolProvider":    {got: caps.WorkspaceSymbolProvider, want: true},
		"DocumentFormattingProvider": {got: caps.DocumentFormattingProvider, want: true},
	}

	for name, tt := range tests {
		t.Run(name, func(t *testing.T) {
			if tt.got != tt.want {
				t.Errorf("%s = %v, want %v", name, tt.got, tt.want)
			}
		})
	}

	if caps.SemanticTokensProvider == nil {
		t.Error("SemanticTokensProvider should be set")
	}
}

func TestHandleInitialize_SetsRootURI(t *testing.T) {
	s := newTestServer()

	params, _ := json.Marshal(InitializeParams{
		RootURI: "file:///workspace/myproject",
	})

	_, lspErr := s.handleInitialize(params)
	if lspErr != nil {
		t.Fatalf("handleInitialize returned error: %v", lspErr)
	}

	if s.rootURI != "file:///workspace/myproject" {
		t.Errorf("rootURI = %q, want %q", s.rootURI, "file:///workspace/myproject")
	}
}

func TestHandleInitialize_InvalidParams(t *testing.T) {
	s := newTestServer()

	_, lspErr := s.handleInitialize([]byte(`{invalid json`))
	if lspErr == nil {
		t.Fatal("expected error for invalid params")
	}
	if lspErr.Code != CodeInvalidParams {
		t.Errorf("error code = %d, want %d", lspErr.Code, CodeInvalidParams)
	}
}

func TestHandleShutdown(t *testing.T) {
	s := newTestServer()

	if s.shutdown {
		t.Fatal("server should not be shut down initially")
	}

	_, lspErr := s.handleShutdown()
	if lspErr != nil {
		t.Fatalf("handleShutdown returned error: %v", lspErr)
	}

	if !s.shutdown {
		t.Error("server should be shut down after handleShutdown")
	}
}

func TestHandleInitialized(t *testing.T) {
	s := newTestServer()

	if s.initialized {
		t.Fatal("server should not be initialized initially")
	}

	_, lspErr := s.handleInitialized()
	if lspErr != nil {
		t.Fatalf("handleInitialized returned error: %v", lspErr)
	}

	if !s.initialized {
		t.Error("server should be initialized after handleInitialized")
	}
}