Skip to content

Commit 410a522

Browse files
VEN-4 Add system parsing, support different types of return values, w… (#944)
* VEN-4 Add system parsing, support different types of return values, write new test cases
1 parent 74a2ad2 commit 410a522

File tree

7 files changed

+189
-73
lines changed

7 files changed

+189
-73
lines changed

test-crawler/collector/collector.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ type FunctionAnnotation struct {
3737
Public bool
3838
}
3939

40+
type SystemMethods struct {
41+
System string `yaml:"system"`
42+
Methods []FunctionAnnotation `yaml:"methods"`
43+
}
44+
4045
func GetTestFiles(root string, ignore []string) (files []TestFile, err error) {
4146
fileArray, err := listTestFiles(root, ignore)
4247
if err != nil {
@@ -89,3 +94,35 @@ func listTestFiles(root string, ignore []string) (files []string, err error) {
8994

9095
return nil, nil
9196
}
97+
98+
// listGoFilesInFolder returns list of all .go files, excluding _test.go
99+
// Root folder will represent a system for which the methods will be crawled.
100+
func ListGoFilesInFolder(root string, ignore []string) (system string, files []string, err error) {
101+
err = filepath.Walk(root,
102+
func(path string, info os.FileInfo, err error) error {
103+
if err != nil {
104+
return err
105+
}
106+
107+
// If it's directory, get the name of system.
108+
if root == path && info.IsDir() {
109+
system = info.Name()
110+
}
111+
112+
if strings.HasSuffix(path, ".go") && !strings.Contains(path, "_test") {
113+
files = append(files, path)
114+
}
115+
116+
return nil
117+
})
118+
119+
if err != nil {
120+
return "", nil, err
121+
}
122+
123+
if len(files) != 0 {
124+
return system, files, nil
125+
}
126+
127+
return "", nil, nil
128+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package collector
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"strings"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestListGoFilesInFolder(t *testing.T) {
13+
t.Run("Read golang files from temporary directory", func(t *testing.T) {
14+
tempDir := t.TempDir()
15+
err := ioutil.WriteFile(fmt.Sprintf("%s/a.go", tempDir), []byte("package main func main(){a:=1}"), 0644)
16+
assert.NoError(t, err)
17+
err = ioutil.WriteFile(fmt.Sprintf("%s/b.go", tempDir), []byte("package main func main(){b:=2}"), 0644)
18+
assert.NoError(t, err)
19+
20+
system, files, err := ListGoFilesInFolder(tempDir, nil)
21+
assert.NoError(t, err)
22+
splitedFolderName := strings.Split(tempDir, "/")
23+
systemName := splitedFolderName[len(splitedFolderName)-1]
24+
assert.Equal(t, system, systemName)
25+
assert.Equal(t, 2, len(files))
26+
})
27+
28+
t.Run("Read golang files excluding everything else", func(t *testing.T) {
29+
tempDir := t.TempDir()
30+
err := ioutil.WriteFile(fmt.Sprintf("%s/a.go", tempDir), []byte("package main func main(){a:=1}"), 0644)
31+
err = ioutil.WriteFile(fmt.Sprintf("%s/b.go", tempDir), []byte("package main func main(){b:=2}"), 0644)
32+
err = ioutil.WriteFile(fmt.Sprintf("%s/b_test.go", tempDir), []byte("package main_test"), 0644)
33+
err = ioutil.WriteFile(fmt.Sprintf("%s/.env", tempDir), []byte("PORT=8080"), 0644)
34+
assert.NoError(t, err)
35+
36+
system, files, err := ListGoFilesInFolder(tempDir, nil)
37+
assert.NoError(t, err)
38+
splitedFolderName := strings.Split(tempDir, "/")
39+
systemName := splitedFolderName[len(splitedFolderName)-1]
40+
assert.Equal(t, system, systemName)
41+
assert.Equal(t, 2, len(files))
42+
})
43+
}

test-crawler/crawler_test.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@ package main
22

33
import (
44
"context"
5+
"io/ioutil"
56
"testing"
7+
c "testsuites/collector"
68

79
"github.com/stretchr/testify/assert"
10+
y "gopkg.in/yaml.v2"
811
)
912

10-
func TestExtractPublicMethodsFromFile(t *testing.T) {
11-
fnsAnn, err := extractPublicMethodsFromFile(context.Background(), "./mocks/event.go")
13+
func TestCrawlSingleFileForFunctions(t *testing.T) {
14+
ctx := context.Background()
15+
fnsAnn, err := crawlSingleFileForFunctions(ctx, "./mocks/event.go")
1216
if err != nil {
1317
t.Errorf("got error: %v", err.Error())
1418
}
1519

16-
if len(fnsAnn) != 2 {
20+
if len(fnsAnn) != 4 {
1721
t.Errorf("got %q, expected %q methods", len(fnsAnn), 2)
1822
}
1923

@@ -24,4 +28,52 @@ func TestExtractPublicMethodsFromFile(t *testing.T) {
2428
assert.Equal(t, "HelloEventWithParameter", fnsAnn[1].Name)
2529
assert.Equal(t, "(param string)", fnsAnn[1].InputParams)
2630
assert.Equal(t, "(string, error)", fnsAnn[1].ReturnValues)
31+
32+
assert.Equal(t, "FunctionWithoutParameters", fnsAnn[2].Name)
33+
assert.Equal(t, "()", fnsAnn[2].InputParams)
34+
assert.Equal(t, "", fnsAnn[2].ReturnValues)
35+
36+
assert.Equal(t, "FunctionWithPointerReturnValue", fnsAnn[3].Name)
37+
assert.Equal(t, "()", fnsAnn[3].InputParams)
38+
assert.Equal(t, "*Event", fnsAnn[3].ReturnValues)
39+
}
40+
41+
func TestMakeYAML(t *testing.T) {
42+
43+
yaml := []c.FunctionAnnotation{
44+
{
45+
ID: 1,
46+
Name: "SomeName",
47+
InputParams: "(ctx context.Context, param Parameters)",
48+
ReturnValues: "error",
49+
Description: "",
50+
Public: true,
51+
},
52+
{
53+
ID: 2,
54+
Name: "SomeName2",
55+
InputParams: "(ctx context.Context, param2 Parameters2)",
56+
ReturnValues: "error",
57+
Description: "",
58+
Public: true,
59+
},
60+
}
61+
62+
yamlData, err := y.Marshal(&yaml)
63+
if err != nil {
64+
t.Errorf("got error: %v", err.Error())
65+
}
66+
fileName := "test.yaml"
67+
err = ioutil.WriteFile(fileName, yamlData, 0644)
68+
if err != nil {
69+
panic("Unable to write data into the file")
70+
}
71+
72+
bytes, err := ioutil.ReadFile(fileName)
73+
if err != nil {
74+
t.Errorf("got error: %v", err.Error())
75+
}
76+
77+
assert.Equal(t, yamlData, bytes)
78+
2779
}

test-crawler/extractor/extractor.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const (
2828
CALL_EXPRESSION NodeType = "call_expression"
2929
IDENTIFIER NodeType = "identifier"
3030
METHOD_DECLARATION NodeType = "method_declaration"
31+
POINTER_TYPE NodeType = "pointer_type"
32+
TYPE_IDENTIFIER NodeType = "type_identifier"
3133
)
3234

3335
type Metadata struct {
@@ -262,8 +264,19 @@ func getFunctionNodes(content string, treeCursor *sitter.TreeCursor, parser *a.P
262264
funcName = content[child.Child(2).StartByte():child.Child(2).EndByte()]
263265
params := ""
264266
returnValues := ""
265-
if child.Child(1).Type() == string(PARAMETER_LIST) {
267+
if child.Child(3).Type() == string(PARAMETER_LIST) {
266268
params = content[child.Child(3).StartByte():child.Child(3).EndByte()]
269+
}
270+
returnValueType := child.Child(4).Type()
271+
/* Return value can be in one of these 3 forms
272+
- (type1, type2) -> PARAMETER_LIST
273+
- *type1 -> POINTER_TYPE
274+
- type1 -> TYPE_IDENTIFIER
275+
that's why we need to check all of these conditions.
276+
*/
277+
if returnValueType == string(PARAMETER_LIST) ||
278+
returnValueType == string(POINTER_TYPE) ||
279+
returnValueType == string(TYPE_IDENTIFIER) {
267280
returnValues = content[child.Child(4).StartByte():child.Child(4).EndByte()]
268281
}
269282
funcAnnoPair = append(funcAnnoPair, FunctionAnnotationNode{

test-crawler/main.go

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,45 @@ func crawlRepoBehaviorsAndSaveToJSON(config Config) {
8383

8484
// crawlSingleFileForMethods accepts path of single go file,
8585
// and prints extracted methods out of it.
86-
func crawlSingleFileForMethods(path string) {
87-
fns, err := extractPublicMethodsFromFile(context.Background(), path)
86+
func crawlSingleFileForFunctions(ctx context.Context, path string) ([]c.FunctionAnnotation, error) {
87+
fns, err := ex.GetExportedFunctions(ctx, path)
8888
if err != nil {
89-
fmt.Print(err)
90-
os.Exit(1)
91-
}
92-
for _, fn := range fns {
93-
fmt.Printf(
94-
"ID %d : name %s : public %v : params: %s : return values : %s\n",
95-
fn.ID,
96-
fn.Name,
97-
fn.Public,
98-
fn.InputParams,
99-
fn.ReturnValues,
100-
)
89+
return nil, fmt.Errorf("error extracting public methods from file: %w", err)
10190
}
91+
92+
return fns, nil
10293
}
10394

104-
func extractPublicMethodsFromFile(ctx context.Context, filePath string) ([]c.FunctionAnnotation, error) {
105-
return ex.GetExportedFunctions(ctx, filePath)
95+
// crawlFolderForSystemMethods accepts folder, which represents a system that will be crawled for
96+
// all of his methods.
97+
// ex: "../repo-to-crawl/venus-gateway/proofevent"
98+
func crawlFolderForSystemMethods(system string) (*c.SystemMethods, error) {
99+
system, files, err := c.ListGoFilesInFolder(system, nil)
100+
if err != nil {
101+
return nil, err
102+
}
103+
104+
systemFunctions := c.SystemMethods{
105+
System: system,
106+
Methods: make([]c.FunctionAnnotation, 0),
107+
}
108+
109+
ctx := context.Background()
110+
for _, file := range files {
111+
fns, err := crawlSingleFileForFunctions(ctx, file)
112+
if err != nil {
113+
return nil, fmt.Errorf("can not crawl file: %s, err: %w", file, err)
114+
}
115+
systemFunctions.Methods = append(systemFunctions.Methods, fns...)
116+
}
117+
118+
return &systemFunctions, nil
106119
}
107120

108121
// makeYAML will make yaml file from public methods.
109122
func makeYAML(ctx context.Context, filePath string) error {
110123

111-
publicMethods, err := extractPublicMethodsFromFile(ctx, filePath)
124+
publicMethods, err := crawlSingleFileForFunctions(ctx, filePath)
112125
if err != nil {
113126
fmt.Print(err)
114127
os.Exit(1)

test-crawler/make_yaml_test.go

Lines changed: 0 additions & 52 deletions
This file was deleted.

test-crawler/mocks/event.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,13 @@ func (e *Event) HelloEventWithParameter(param string) (string, error) {
2929

3030
return fmt.Sprintf("HelloEventWithParameter: %v", param), nil
3131
}
32+
33+
// FunctionWithoutParameters...
34+
func (e *Event) FunctionWithoutParameters() {
35+
36+
}
37+
38+
// FunctionWithPointerReturnValue returns a simple pointer value.
39+
func (e *Event) FunctionWithPointerReturnValue() *Event {
40+
return &Event{}
41+
}

0 commit comments

Comments
 (0)