Something went wrong. Try again.
A Thrift language server, formatter, and linter.
lsp linter helix vim vscode thrift
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142package 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")
func Test_EnumValueCheck_Diagnostic(t *testing.T) { tests := []struct { name string content string want []analyzertest.Diag }{ { name: "explicit values only", content: `enum Color { RED = 0, GREEN = 2,}`, want: nil, }, { name: "implicit members auto-increment", content: `enum Color { RED, GREEN = 2, BLUE, ALPHA = 0x10, OMEGA,}`, want: []analyzertest.Diag{ { StartLine: 1 + 1, StartCol: 2 + 1, EndLine: 1 + 1, EndCol: 5 + 1, Severity: sema.SeverityWarning, Code: sema.CodeImplicitEnumValue, Message: "RED has no explicit value (implicitly 0)", }, { StartLine: 3 + 1, StartCol: 2 + 1, EndLine: 3 + 1, EndCol: 6 + 1, Severity: sema.SeverityWarning, Code: sema.CodeImplicitEnumValue, Message: "BLUE has no explicit value (implicitly 3)", }, { StartLine: 5 + 1, StartCol: 2 + 1, EndLine: 5 + 1, EndCol: 7 + 1, Severity: sema.SeverityWarning, Code: sema.CodeImplicitEnumValue, Message: "OMEGA has no explicit value (implicitly 17)", }, }, }, { name: "unparseable explicit value breaks the chain", content: `enum E { A = 08, B,}`, want: []analyzertest.Diag{ { StartLine: 2 + 1, StartCol: 2 + 1, EndLine: 2 + 1, EndCol: 3 + 1, Severity: sema.SeverityWarning, Code: sema.CodeImplicitEnumValue, Message: "B has no explicit value", }, }, }, }
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { report := analyzertest.Run(t, sema.EachFile(&EnumValueCheck{}), map[string]string{ "user.thrift": tt.content, }, "user.thrift")
assert.Equal(t, tt.want, analyzertest.Simplify(report[analyzertest.URI("user.thrift")])) }) }}
// Test_EnumValueCheck_InlineFix pins the inline quickfix: the member's name// is rewritten to carry the auto-incremented value the compiler resolves// for it.func Test_EnumValueCheck_InlineFix(t *testing.T) { content := "enum Color {\n RED,\n GREEN = 2,\n BLUE,\n}\n"
report := analyzertest.Run(t, sema.EachFile(&EnumValueCheck{}), map[string]string{ "user.thrift": content, }, "user.thrift") file := analyzertest.URI("user.thrift") diags := report[file] require.Len(t, diags, 2)
assert.Equal(t, "Add explicit value 0 to RED", diags[0].Fixes[0].Title)
out, applied, _, err := sema.Apply([]byte(content), diags[0].Fixes) require.NoError(t, err) require.Len(t, applied, 1) assert.Equal(t, "enum Color {\n RED = 0,\n GREEN = 2,\n BLUE,\n}\n", string(out))
assert.Equal(t, "Add explicit value 3 to BLUE", diags[1].Fixes[0].Title)
out, applied, _, err = sema.Apply([]byte(content), diags[1].Fixes) require.NoError(t, err) require.Len(t, applied, 1) assert.Equal(t, "enum Color {\n RED,\n GREEN = 2,\n BLUE = 3,\n}\n", string(out))}
// Test_EnumValueCheck_UnknownValueNoFix pins the Known=false boundary: a// member whose implicit value cannot be computed (it follows an// unparseable constant) offers no fix — writing one would put a wrong// value in the source. A fixable sibling still gets its fix.func Test_EnumValueCheck_UnknownValueNoFix(t *testing.T) { content := "enum E {\n A = 08,\n B,\n C,\n}\n"
report := analyzertest.Run(t, sema.EachFile(&EnumValueCheck{}), map[string]string{ "user.thrift": content, }, "user.thrift") diags := report[analyzertest.URI("user.thrift")] require.Len(t, diags, 2)
// B follows the broken constant: no computable value, no fix. assert.Equal(t, "B has no explicit value", diags[0].Message) assert.Empty(t, diags[0].Fixes)
// C's value is settled by the broken constant's absence: the chain // stays unknown, so no fix here either. assert.Equal(t, "C has no explicit value", diags[1].Message) assert.Empty(t, diags[1].Fixes)}