| // Copyright 2019 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | package cache | 
 |  | 
 | import ( | 
 | 	"encoding/json" | 
 | 	"strings" | 
 | 	"testing" | 
 |  | 
 | 	"github.com/google/go-cmp/cmp" | 
 | 	"golang.org/x/tools/go/packages" | 
 | 	"golang.org/x/tools/gopls/internal/protocol" | 
 | ) | 
 |  | 
 | func TestParseErrorMessage(t *testing.T) { | 
 | 	tests := []struct { | 
 | 		name             string | 
 | 		in               string | 
 | 		expectedFileName string | 
 | 		expectedLine     int // (missing => 1) | 
 | 		expectedColumn   int // (missing => 1) | 
 | 	}{ | 
 | 		{ | 
 | 			name:             "from go list output", | 
 | 			in:               "\nattributes.go:13:1: expected 'package', found 'type'", | 
 | 			expectedFileName: "attributes.go", | 
 | 			expectedLine:     13, | 
 | 			expectedColumn:   1, | 
 | 		}, | 
 | 		{ | 
 | 			name:             "windows driver letter", | 
 | 			in:               "C:\\foo\\bar.go:13: message", | 
 | 			expectedFileName: "bar.go", | 
 | 			expectedLine:     13, | 
 | 			expectedColumn:   1, | 
 | 		}, | 
 | 	} | 
 |  | 
 | 	for _, tt := range tests { | 
 | 		t.Run(tt.name, func(t *testing.T) { | 
 | 			fn, line, col8 := parseGoListError(packages.Error{Msg: tt.in}, ".") | 
 |  | 
 | 			if !strings.HasSuffix(fn, tt.expectedFileName) { | 
 | 				t.Errorf("expected filename with suffix %v but got %v", tt.expectedFileName, fn) | 
 | 			} | 
 | 			if line != tt.expectedLine { | 
 | 				t.Errorf("expected line %v but got %v", tt.expectedLine, line) | 
 | 			} | 
 | 			if col8 != tt.expectedColumn { | 
 | 				t.Errorf("expected col %v but got %v", tt.expectedLine, col8) | 
 | 			} | 
 | 		}) | 
 | 	} | 
 | } | 
 |  | 
 | func TestDiagnosticEncoding(t *testing.T) { | 
 | 	diags := []*Diagnostic{ | 
 | 		{}, // empty | 
 | 		{ | 
 | 			URI: "file///foo", | 
 | 			Range: protocol.Range{ | 
 | 				Start: protocol.Position{Line: 4, Character: 2}, | 
 | 				End:   protocol.Position{Line: 6, Character: 7}, | 
 | 			}, | 
 | 			Severity: protocol.SeverityWarning, | 
 | 			Code:     "red", | 
 | 			CodeHref: "https://go.dev", | 
 | 			Source:   "test", | 
 | 			Message:  "something bad happened", | 
 | 			Tags:     []protocol.DiagnosticTag{81}, | 
 | 			Related: []protocol.DiagnosticRelatedInformation{ | 
 | 				{ | 
 | 					Location: protocol.Location{ | 
 | 						URI: "file:///other", | 
 | 						Range: protocol.Range{ | 
 | 							Start: protocol.Position{Line: 3, Character: 6}, | 
 | 							End:   protocol.Position{Line: 4, Character: 9}, | 
 | 						}, | 
 | 					}, | 
 | 					Message: "psst, over here", | 
 | 				}, | 
 | 			}, | 
 |  | 
 | 			// Fields below are used internally to generate quick fixes. They aren't | 
 | 			// part of the LSP spec and don't leave the server. | 
 | 			SuggestedFixes: []SuggestedFix{ | 
 | 				{ | 
 | 					Title: "fix it!", | 
 | 					Edits: map[protocol.DocumentURI][]protocol.TextEdit{ | 
 | 						"file:///foo": {{ | 
 | 							Range: protocol.Range{ | 
 | 								Start: protocol.Position{Line: 4, Character: 2}, | 
 | 								End:   protocol.Position{Line: 6, Character: 7}, | 
 | 							}, | 
 | 							NewText: "abc", | 
 | 						}}, | 
 | 						"file:///other": {{ | 
 | 							Range: protocol.Range{ | 
 | 								Start: protocol.Position{Line: 4, Character: 2}, | 
 | 								End:   protocol.Position{Line: 6, Character: 7}, | 
 | 							}, | 
 | 							NewText: "!@#!", | 
 | 						}}, | 
 | 					}, | 
 | 					Command: &protocol.Command{ | 
 | 						Title:     "run a command", | 
 | 						Command:   "gopls.fix", | 
 | 						Arguments: []json.RawMessage{json.RawMessage(`{"a":1}`)}, | 
 | 					}, | 
 | 					ActionKind: protocol.QuickFix, | 
 | 				}, | 
 | 			}, | 
 | 		}, | 
 | 		{ | 
 | 			URI: "file//bar", | 
 | 			// other fields tested above | 
 | 		}, | 
 | 	} | 
 |  | 
 | 	data := encodeDiagnostics(diags) | 
 | 	diags2 := decodeDiagnostics(data) | 
 |  | 
 | 	if diff := cmp.Diff(diags, diags2); diff != "" { | 
 | 		t.Errorf("decoded diagnostics do not match (-original +decoded):\n%s", diff) | 
 | 	} | 
 | } |