Skip to content

Commit

Permalink
Fix LSP formatting that broke in v0.26.0 (#1055)
Browse files Browse the repository at this point in the history
Fixes #1054

Signed-off-by: Anders Eknert <anders@styra.com>
  • Loading branch information
anderseknert authored Sep 5, 2024
1 parent bf6e879 commit 1cfdee9
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
7 changes: 6 additions & 1 deletion internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,12 @@ func (l *LanguageServer) handleTextDocumentFormatting(
f := &fixes.Fmt{OPAFmtOpts: opts}
p := uri.ToPath(l.clientIdentifier, params.TextDocument.URI)

fixResults, err := f.Fix(&fixes.FixCandidate{Filename: filepath.Base(p), Contents: []byte(oldContent)}, nil)
fixResults, err := f.Fix(
&fixes.FixCandidate{Filename: filepath.Base(p), Contents: []byte(oldContent)},
&fixes.RuntimeOptions{
BaseDir: l.workspacePath(),
},
)
if err != nil {
l.logError(fmt.Errorf("failed to format file: %w", err))

Expand Down
86 changes: 86 additions & 0 deletions internal/lsp/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package lsp
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -731,6 +732,91 @@ func TestProcessBuiltinUpdateExitsOnMissingFile(t *testing.T) {
}
}

func TestFormatting(t *testing.T) {
t.Parallel()

tempDir := t.TempDir()

// set up the server and client connections
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

ls := NewLanguageServer(&LanguageServerOptions{
ErrorLog: newTestLogger(t),
})
go ls.StartConfigWorker(ctx)

clientHandler := func(_ context.Context, _ *jsonrpc2.Conn, req *jsonrpc2.Request) (result any, err error) {
t.Fatalf("unexpected request: %v", req)

return struct{}{}, nil
}

connServer, connClient, cleanup := createConnections(ctx, ls.Handle, clientHandler)
defer cleanup()

ls.SetConn(connServer)

// 1. Client sends initialize request
request := types.InitializeParams{
RootURI: fileURIScheme + tempDir,
ClientInfo: types.Client{Name: "go test"},
}

var response types.InitializeResult

err := connClient.Call(ctx, "initialize", request, &response)
if err != nil {
t.Fatalf("failed to send initialize request: %s", err)
}

mainRegoURI := fileURIScheme + tempDir + mainRegoFileName

// Simple as possible — opa fmt should just remove a newline
content := `package main
`
ls.cache.SetFileContents(mainRegoURI, content)

bs, err := json.Marshal(&types.DocumentFormattingParams{
TextDocument: types.TextDocumentIdentifier{URI: mainRegoURI},
Options: types.FormattingOptions{},
})
if err != nil {
t.Fatalf("failed to marshal document formatting params: %v", err)
}

var msg json.RawMessage = bs

req := &jsonrpc2.Request{Params: &msg}

res, err := ls.handleTextDocumentFormatting(ctx, connClient, req)
if err != nil {
t.Fatalf("failed to format document: %s", err)
}

if edits, ok := res.([]types.TextEdit); ok {
if len(edits) != 1 {
t.Fatalf("expected 1 edit, got %d", len(edits))
}

expectRange := types.Range{
Start: types.Position{Line: 1, Character: 0},
End: types.Position{Line: 2, Character: 0},
}

if edits[0].Range != expectRange {
t.Fatalf("expected range to be %v, got %v", expectRange, edits[0].Range)
}

if edits[0].NewText != "" {
t.Fatalf("expected new text to be empty, got %s", edits[0].NewText)
}
} else {
t.Fatalf("expected edits to be []types.TextEdit, got %T", res)
}
}

// TestLanguageServerParentDirConfig tests that regal config is loaded as it is for the
// Regal CLI, and that config files in a parent directory are loaded correctly
// even when the workspace is a child directory.
Expand Down

0 comments on commit 1cfdee9

Please sign in to comment.