blob: 7b0bf0a0629cd870b824b191d4ee7909715db743 [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 langserver
import (
"testing"
"github.com/sourcegraph/go-lsp"
"fidl-lsp/analysis"
)
func TestHover(t *testing.T) {
var elementCount uint = 10
cases := []struct {
symName string
symType analysis.Type
hoverText []lsp.MarkedString
}{
{
symName: "fuchsia.test",
symType: analysis.Type{
IsLib: true,
},
hoverText: []lsp.MarkedString{newFIDLString("library fuchsia.test")},
},
{
symName: "array_value",
symType: analysis.Type{
Kind: analysis.ArrayType,
Array: &analysis.ArrayTypeInfo{
ElementType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint32,
},
},
ElementCount: 10,
},
},
hoverText: []lsp.MarkedString{newFIDLString("array<uint32>:10")},
},
{
symName: "vector_without_size_constraint",
symType: analysis.Type{
Kind: analysis.VectorType,
Vector: &analysis.VectorTypeInfo{
ElementType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint32,
},
},
},
},
hoverText: []lsp.MarkedString{newFIDLString("vector<uint32>")},
},
{
symName: "nullable_vector_with_size_constraint",
symType: analysis.Type{
Kind: analysis.VectorType,
Vector: &analysis.VectorTypeInfo{
ElementType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint32,
},
},
ElementCount: &elementCount,
Nullable: true,
},
},
hoverText: []lsp.MarkedString{newFIDLString("vector<uint32>:10?")},
},
{
symName: "nullable_string_without_size_constraint",
symType: analysis.Type{
Kind: analysis.StringType,
String: &analysis.StringTypeInfo{
Nullable: true,
},
},
hoverText: []lsp.MarkedString{newFIDLString("string?")},
},
{
symName: "string_with_size_constraint",
symType: analysis.Type{
Kind: analysis.StringType,
String: &analysis.StringTypeInfo{
ElementCount: &elementCount,
},
},
hoverText: []lsp.MarkedString{newFIDLString("string:10")},
},
{
symName: "handle",
symType: analysis.Type{
Kind: analysis.HandleType,
Handle: &analysis.HandleTypeInfo{
Subtype: analysis.Vmo,
Nullable: true,
},
},
hoverText: []lsp.MarkedString{newFIDLString("handle<vmo>?")},
},
{
symName: "request",
symType: analysis.Type{
Kind: analysis.RequestType,
Request: &analysis.RequestTypeInfo{
Subtype: "File",
},
},
hoverText: []lsp.MarkedString{newFIDLString("request<File>")},
},
{
symName: "primitive_bool",
symType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Bool,
},
},
hoverText: []lsp.MarkedString{newFIDLString("bool")},
},
{
symName: "primitive_uint64",
symType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint64,
},
},
hoverText: []lsp.MarkedString{newFIDLString("uint64")},
},
{
symName: "bits_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyBits",
Kind: analysis.BitsKind,
Bits: &analysis.BitsTypeInfo{
Type: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint32,
},
},
},
},
},
hoverText: []lsp.MarkedString{newFIDLString("bits fuchsia.test/MyBits: uint32")},
},
{
symName: "enum_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyEnum",
Kind: analysis.EnumKind,
Enum: &analysis.EnumTypeInfo{
Type: "string",
},
},
},
hoverText: []lsp.MarkedString{newFIDLString("enum fuchsia.test/MyEnum: string")},
},
{
symName: "const_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyConst",
Kind: analysis.ConstKind,
Const: &analysis.ConstTypeInfo{
Type: analysis.Type{
Kind: analysis.StringType,
String: &analysis.StringTypeInfo{},
},
Value: "hello, world!",
},
},
},
hoverText: []lsp.MarkedString{newFIDLString("const string fuchsia.test/MyConst = `hello, world!`")},
},
{
symName: "protocol_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyProtocol",
Kind: analysis.ProtocolKind,
},
},
hoverText: []lsp.MarkedString{newFIDLString("protocol fuchsia.test/MyProtocol")},
},
{
symName: "service_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyService",
Kind: analysis.ServiceKind,
},
},
hoverText: []lsp.MarkedString{newFIDLString("service fuchsia.test/MyService")},
},
{
symName: "struct_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyStruct",
Kind: analysis.StructKind,
},
},
hoverText: []lsp.MarkedString{newFIDLString("struct fuchsia.test/MyStruct")},
},
{
symName: "table_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyTable",
Kind: analysis.TableKind,
},
},
hoverText: []lsp.MarkedString{newFIDLString("table fuchsia.test/MyTable")},
},
{
symName: "union_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyUnion",
Kind: analysis.UnionKind,
},
},
hoverText: []lsp.MarkedString{newFIDLString("union fuchsia.test/MyUnion")},
},
{
symName: "type_alias_decl",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/AliasToVectorOfBools",
Kind: analysis.TypeAliasKind,
TypeAlias: &analysis.TypeAliasTypeInfo{
Type: analysis.Type{
Kind: analysis.VectorType,
Vector: &analysis.VectorTypeInfo{
ElementType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Bool,
},
},
},
},
},
},
},
hoverText: []lsp.MarkedString{newFIDLString("fuchsia.test/AliasToVectorOfBools: alias to vector<bool>")},
},
{
symName: "nullable_struct_param",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: false,
Identifier: "fuchsia.test/MyStruct",
Nullable: true,
},
},
hoverText: []lsp.MarkedString{newFIDLString("fuchsia.test/MyStruct?")},
},
{
symName: "type_with_attributes",
symType: analysis.Type{
Kind: analysis.IdentifierType,
Identifier: &analysis.IdentifierTypeInfo{
IsDecl: true,
Name: "fuchsia.test/MyProtocol",
Kind: analysis.ProtocolKind,
},
Attrs: []analysis.Attribute{
{
Name: "Doc",
Value: "Example doc comments on MyProtocol",
},
{Name: "Transitional"},
{
Name: "OtherAttribute",
Value: "AttributeValue",
},
},
},
hoverText: []lsp.MarkedString{
lsp.RawMarkedString(`Example doc comments on MyProtocol`),
newFIDLString(`[Transitional, OtherAttribute = "AttributeValue"]`),
newFIDLString(`protocol fuchsia.test/MyProtocol`),
},
},
}
for _, ex := range cases {
hoverText, err := symbolTypeToMarkedStrings(ex.symName, ex.symType)
if err != nil {
t.Errorf("could not get hover text for symbol `%s`: %s", ex.symName, err)
continue
}
if len(hoverText) != len(ex.hoverText) {
t.Errorf(
"incorrect number of marked strings for symbol `%s`: expected %d, got %d",
ex.symName,
len(ex.hoverText),
len(hoverText),
)
continue
}
for i, expMarkedString := range ex.hoverText {
if hoverText[i] != expMarkedString {
t.Errorf(
"incorrect hoverText for symbol `%s`: expected %v, got %v",
ex.symName,
expMarkedString,
hoverText[i],
)
}
}
}
}
func TestHoverInvalidType(t *testing.T) {
_, err := symbolTypeToMarkedStrings(
"invalid_type",
analysis.Type{
Kind: analysis.PrimitiveType,
Array: &analysis.ArrayTypeInfo{
ElementType: analysis.Type{
Kind: analysis.PrimitiveType,
Primitive: &analysis.PrimitiveTypeInfo{
Subtype: analysis.Uint64,
},
},
ElementCount: 255,
},
},
)
if err == nil {
t.Errorf("expect error for hover text on invalid type")
}
}