diff --git a/pkg/analyzer/completion_item.go b/pkg/analyzer/completion_item.go index 9e67aae0..f7702006 100644 --- a/pkg/analyzer/completion_item.go +++ b/pkg/analyzer/completion_item.go @@ -54,3 +54,8 @@ type MarkdownString struct { // Value is string contents Value string `json:"value"` } + +// NewMarkdownString returns markdown string +func NewMarkdownString(val string) MarkdownString { + return MarkdownString{Value: val} +} diff --git a/pkg/analyzer/package_test.go b/pkg/analyzer/package_test.go index e4c54259..5bbd4999 100644 --- a/pkg/analyzer/package_test.go +++ b/pkg/analyzer/package_test.go @@ -2,6 +2,7 @@ package analyzer import ( "github.com/stretchr/testify/require" + "github.com/x1unix/go-playground/pkg/testutil" "testing" ) @@ -83,5 +84,10 @@ func TestPackage_HasChildren(t *testing.T) { } func TestPackage_AllSymbols(t *testing.T) { - + SetRoot("testdata") + SetLogger(testutil.GetLogger(t).Desugar()) + want := examplePackageSummary + pkg := Package{Path: "example"} + require.NoError(t, pkg.Analyze()) + require.Equal(t, want, pkg.PackageSummary) } diff --git a/pkg/analyzer/scanner_test.go b/pkg/analyzer/scanner_test.go new file mode 100644 index 00000000..e282b27b --- /dev/null +++ b/pkg/analyzer/scanner_test.go @@ -0,0 +1,86 @@ +package analyzer + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "github.com/x1unix/go-playground/pkg/testutil" +) + +// should be in sync with "testdata/src" !!! +var examplePackageSummary = PackageSummary{ + Functions: newSymbolIndex([]*CompletionItem{ + { + Label: "SomeFunc", + Kind: Function, + Detail: "func(val string) string", + InsertText: "SomeFunc()", + Documentation: NewMarkdownString( + "SomeFunc is test function sample\nwith doc that contains code sample:" + + "\n\n```\n\ta := \"foo\"\n\tfmt.PrintLn(a)\n\n```\nend\n\n", + ), + }, + { + Label: "ChanArrFunc", + Kind: Function, + Detail: "func(items ...string) chan string", + InsertText: "ChanArrFunc()", + Documentation: NewMarkdownString("ChanArrFunc is stub\n\n"), + }, + { + Label: "SomeFunc2", + Kind: Function, + Detail: "func(m map[string]interface{}, v *int) []interface{}", + InsertText: "SomeFunc2()", + Documentation: NewMarkdownString("SomeFunc2 is func stub\n\n"), + }, + { + Label: "IfaceFunc", + Kind: Function, + Detail: "func() Action", + InsertText: "IfaceFunc()", + Documentation: NewMarkdownString("IfaceFunc is stub with unterminated code block\n```\n\t2 + 2\n\n```\n"), + }, + { + Label: "FuncReturnFuncAndIface", + Kind: Function, + Detail: "func() (func() (string, error), interface{\nf func()\n})", + InsertText: "FuncReturnFuncAndIface()", + Documentation: NewMarkdownString("FuncReturnFuncAndIface is stub\n\n"), + }, + }), + Values: newSymbolIndex([]*CompletionItem{ + { + Label: "SomeConst", + Kind: Constant, + Detail: "SomeConst", + Documentation: "", + InsertText: "SomeConst", + }, + { + Label: "SomeVar", + Kind: Variable, + Detail: "SomeVar", + Documentation: "SomeVar is public var example\n", + InsertText: "SomeVar", + }, + { + Label: "AnonIfaceVar", + Kind: Variable, + Detail: "AnonIfaceVar", + Documentation: "AnonIfaceVar is var with anonymous interface sample\n", + InsertText: "AnonIfaceVar", + }, + }), +} + +func TestPackageScanner_Scan(t *testing.T) { + want := examplePackageSummary + tempRoot := testutil.TestdataPath("src") + SetLogger(testutil.GetLogger(t).Desugar()) + s := NewPackageScanner("example", filepath.Join(tempRoot, "example"), false) + got, err := s.Scan() + require.NoError(t, err) + require.Equal(t, want, got) +} diff --git a/pkg/analyzer/testdata/src/example/example.go b/pkg/analyzer/testdata/src/example/example.go new file mode 100644 index 00000000..f88a7947 --- /dev/null +++ b/pkg/analyzer/testdata/src/example/example.go @@ -0,0 +1,79 @@ +// Package example is Go package sample for scanner tests +// +// See: pkg/analyzer/scanner_test.go +package example + +// SomeConst is const example +const SomeConst = 32 + +var ( + // SomeVar is public var example + SomeVar = "someVar" + + // AnonIfaceVar is var with anonymous interface sample + AnonIfaceVar interface { + // Foo does something + Foo() + } +) + +var privateVar = "privateVar" + +// SomeType is public struct example +type SomeType struct{} + +// Any is type sample +type Any interface{} + +// Action is interface sample +type Action interface { + // Do is interface method sample + Do() error +} + +// Method is struct method sample +func (st SomeType) Method() {} + +// SomeInterface is interface example +type SomeInterface interface{} + +// privateType is private type example +type privateType struct { + foo int +} + +// SomeFunc is test function sample +// with doc that contains code sample: +// +// a := "foo" +// fmt.PrintLn(a) +// +// end +func SomeFunc(val string) string { + return "foo" + val +} + +// ChanArrFunc is stub +func ChanArrFunc(items ...string) chan string { + ch := make(chan string, len(items)) + for _, i := range items { + ch <- i + } + return ch +} + +// SomeFunc2 is func stub +func SomeFunc2(m map[string]interface{}, v *int) []interface{} { + return []interface{}{m, v} +} + +// IfaceFunc is stub with unterminated code block +// 2 + 2 +func IfaceFunc() Action { + return nil +} + +// FuncReturnFuncAndIface is stub +func FuncReturnFuncAndIface() (func() (string, error), interface{ f() }) { + return nil, nil +}