kittenipc/kitcom/internal/tsgo/project/untitled_test.go
2025-10-15 10:12:44 +03:00

162 lines
5.3 KiB
Go

package project_test
import (
"context"
"strings"
"testing"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/bundled"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ls"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/lsp/lsproto"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/projecttestutil"
"gotest.tools/v3/assert"
)
func TestUntitledReferences(t *testing.T) {
t.Parallel()
if !bundled.Embedded {
t.Skip("bundled files are not embedded")
}
// First test the URI conversion functions to understand the issue
untitledURI := lsproto.DocumentUri("untitled:Untitled-2")
convertedFileName := untitledURI.FileName()
t.Logf("URI '%s' converts to filename '%s'", untitledURI, convertedFileName)
backToURI := ls.FileNameToDocumentURI(convertedFileName)
t.Logf("Filename '%s' converts back to URI '%s'", convertedFileName, backToURI)
if string(backToURI) != string(untitledURI) {
t.Errorf("Round-trip conversion failed: '%s' -> '%s' -> '%s'", untitledURI, convertedFileName, backToURI)
}
// Create a test case that simulates how untitled files should work
testContent := `let x = 42;
x
x++;`
// Use the converted filename that DocumentURIToFileName would produce
untitledFileName := convertedFileName // "^/untitled/ts-nul-authority/Untitled-2"
t.Logf("Would use untitled filename: %s", untitledFileName)
// Set up the file system with an untitled file -
// But use a regular file first to see the current behavior
files := map[string]any{
"/Untitled-2.ts": testContent,
}
session, _ := projecttestutil.Setup(files)
ctx := projecttestutil.WithRequestID(context.Background())
session.DidOpenFile(ctx, "file:///Untitled-2.ts", 1, testContent, lsproto.LanguageKindTypeScript)
// Get language service
languageService, err := session.GetLanguageService(ctx, "file:///Untitled-2.ts")
assert.NilError(t, err)
// Test the filename that the source file reports
program := languageService.GetProgram()
sourceFile := program.GetSourceFile("/Untitled-2.ts")
t.Logf("SourceFile.FileName() returns: '%s'", sourceFile.FileName())
// Call ProvideReferences using the LSP method
uri := lsproto.DocumentUri("file:///Untitled-2.ts")
lspPosition := lsproto.Position{Line: 2, Character: 0} // Line 3, character 1 (0-indexed)
refParams := &lsproto.ReferenceParams{
TextDocument: lsproto.TextDocumentIdentifier{Uri: uri},
Position: lspPosition,
Context: &lsproto.ReferenceContext{IncludeDeclaration: true},
}
resp, err := languageService.ProvideReferences(ctx, refParams)
assert.NilError(t, err)
refs := *resp.Locations
// Log the results
t.Logf("Input file URI: %s", uri)
t.Logf("Number of references found: %d", len(refs))
for i, ref := range refs {
t.Logf("Reference %d: URI=%s, Range=%+v", i+1, ref.Uri, ref.Range)
}
// We expect to find 3 references
assert.Assert(t, len(refs) == 3, "Expected 3 references, got %d", len(refs))
// Also test definition using ProvideDefinition
definition, err := languageService.ProvideDefinition(ctx, uri, lspPosition)
assert.NilError(t, err)
if definition.Locations != nil {
t.Logf("Definition found: %d locations", len(*definition.Locations))
for i, loc := range *definition.Locations {
t.Logf("Definition %d: URI=%s, Range=%+v", i+1, loc.Uri, loc.Range)
}
}
}
func TestUntitledFileInInferredProject(t *testing.T) {
t.Parallel()
if !bundled.Embedded {
t.Skip("bundled files are not embedded")
}
// Test that untitled files are properly handled in inferred projects
testContent := `let x = 42;
x
x++;`
session, _ := projecttestutil.Setup(map[string]any{})
ctx := projecttestutil.WithRequestID(context.Background())
// Open untitled files - these should create an inferred project
session.DidOpenFile(ctx, "untitled:Untitled-1", 1, "x\n\n", lsproto.LanguageKindTypeScript)
session.DidOpenFile(ctx, "untitled:Untitled-2", 1, testContent, lsproto.LanguageKindTypeScript)
snapshot, release := session.Snapshot()
defer release()
// Should have an inferred project
assert.Assert(t, snapshot.ProjectCollection.InferredProject() != nil)
// Get language service for the untitled file
languageService, err := session.GetLanguageService(ctx, "untitled:Untitled-2")
assert.NilError(t, err)
program := languageService.GetProgram()
untitledFileName := lsproto.DocumentUri("untitled:Untitled-2").FileName()
sourceFile := program.GetSourceFile(untitledFileName)
assert.Assert(t, sourceFile != nil)
assert.Equal(t, sourceFile.Text(), testContent)
// Test references on 'x' at position 13 (line 3, after "let x = 42;\n\n")
uri := lsproto.DocumentUri("untitled:Untitled-2")
lspPosition := lsproto.Position{Line: 2, Character: 0} // Line 3, character 1 (0-indexed)
refParams := &lsproto.ReferenceParams{
TextDocument: lsproto.TextDocumentIdentifier{Uri: uri},
Position: lspPosition,
Context: &lsproto.ReferenceContext{IncludeDeclaration: true},
}
resp, err := languageService.ProvideReferences(ctx, refParams)
assert.NilError(t, err)
refs := *resp.Locations
t.Logf("Number of references found: %d", len(refs))
for i, ref := range refs {
t.Logf("Reference %d: URI=%s, Range=%+v", i+1, ref.Uri, ref.Range)
// All URIs should be untitled: URIs, not file: URIs
assert.Assert(t, strings.HasPrefix(string(ref.Uri), "untitled:"),
"Expected untitled: URI, got %s", ref.Uri)
}
// We expect to find 4 references
assert.Assert(t, len(refs) == 4, "Expected 4 references, got %d", len(refs))
}