Something went wrong. Try again.
A Thrift language server, formatter, and linter.
lsp linter helix vim vscode thrift
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123package analyzers
import ( "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"
"github.com/karitham/thrift-ls/analyzertest" "github.com/karitham/thrift-ls/sema")
// addIncludeFixes returns the fixes the fixer offers for the undefined-type// diagnostics the analysis produced for file.func addIncludeFixes(t *testing.T, files map[string]string, file string) []sema.Fix { t.Helper()
view := analyzertest.View(t, files) u := analyzertest.URI(file) report := analyzertest.RunOnView(t, sema.EachFile(&SemanticAnalysis{}), view, u) diags := report[u]
f := analyzertest.File(t, view, file)
var got []sema.Fix for _, d := range diags { if d.Code == sema.CodeUndefinedType { got = append(got, AddIncludeFixer{}.Fix(t.Context(), f, d)...) } }
return got}
func Test_AddIncludeFixer(t *testing.T) { t.Run("adds the include defining the missing type", func(t *testing.T) { content := "struct S {\n 1: User u,\n}\n"
fixes := addIncludeFixes(t, map[string]string{ "shared.thrift": "struct User {\n 1: i32 id,\n}\n", "user.thrift": content, }, "user.thrift") require.Len(t, fixes, 1) assert.Equal(t, `Add include "shared.thrift"`, fixes[0].Title) assert.Equal(t, "include \"shared.thrift\"\n", fixes[0].Edits[0].NewText)
out, applied, _, err := sema.Apply([]byte(content), fixes) require.NoError(t, err) require.Len(t, applied, 1) assert.Equal(t, "include \"shared.thrift\"\nstruct S {\n 1: User u,\n}\n", string(out)) })
t.Run("inserts after existing includes", func(t *testing.T) { content := "include \"base.thrift\"\n\nstruct S {\n 1: User u,\n}\n"
fixes := addIncludeFixes(t, map[string]string{ "shared.thrift": "struct User {\n 1: i32 id,\n}\n", "user.thrift": content, }, "user.thrift") require.Len(t, fixes, 1)
out, applied, _, err := sema.Apply([]byte(content), fixes) require.NoError(t, err) require.Len(t, applied, 1) assert.Equal(t, "include \"base.thrift\"\ninclude \"shared.thrift\"\n\nstruct S {\n 1: User u,\n}\n", string(out)) })
t.Run("a type defined nowhere offers no fix", func(t *testing.T) { assert.Empty(t, addIncludeFixes(t, map[string]string{ "user.thrift": "struct S {\n 1: Ghost u,\n}\n", }, "user.thrift")) })
t.Run("a type defined in the same file offers no fix", func(t *testing.T) { assert.Empty(t, addIncludeFixes(t, map[string]string{ "user.thrift": "struct User {}\nstruct S {\n 1: User u,\n}\n", }, "user.thrift")) })}
// Test_UnusedIncludeCheck_InlineFix pins the inline quickfix: the unused// include line is deleted whole, trailing newline included.func Test_UnusedIncludeCheck_InlineFix(t *testing.T) { content := "include \"shared.thrift\"\nstruct S { 1: i32 a }\n"
report := analyzertest.Run(t, sema.EachFile(&UnusedIncludeCheck{}), map[string]string{ "user.thrift": content, }, "user.thrift") diags := report[analyzertest.URI("user.thrift")] require.Len(t, diags, 1) require.Len(t, diags[0].Fixes, 1)
fix := diags[0].Fixes[0] assert.Equal(t, `Remove unused include "shared.thrift"`, fix.Title)
out, applied, _, err := sema.Apply([]byte(content), diags[0].Fixes) require.NoError(t, err) require.Len(t, applied, 1) assert.Equal(t, "struct S { 1: i32 a }\n", string(out))}
// TestFixAllEnumValues drives the whole fix loop over a file with implicit// enum members: every member ends up with the value the compiler would// auto-increment, and the fixed file passes the check on the next pass.func TestFixAllEnumValues(t *testing.T) { t.Parallel()
files := map[string]string{ "user.thrift": "enum Color {\n RED,\n GREEN = 2,\n BLUE,\n}\n", }
res := analyzertest.RunFixAll(t, DefaultPipeline(sema.Config{}), files, "user.thrift")
require.Equal(t, 2, res.Applied) require.Empty(t, res.Skipped)
// Every implicit member gains its auto-incremented value. require.Equal(t, "enum Color {\n RED = 0,\n GREEN = 2,\n BLUE = 3,\n}\n", files["user.thrift"])
// The fixed file passes the check on the next pass. require.Empty(t, res.Remaining[analyzertest.URI("user.thrift")])}