Skip to content

Commit 2ffa34f

Browse files
committed
⚡ ⚡ Improved performance by a significant margin.
✅ Updated tests.
1 parent c81e869 commit 2ffa34f

8 files changed

+110
-134
lines changed

annotations.go

-6
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,6 @@ func mapIfLineContainsOASTag(lineText string, o *OAS) {
144144
}
145145
}
146146

147-
// Begin of oasAnnotations section.
148-
// This section is used mostly to abstract upon the []string,
149-
// so that future implementations are less susceptible to breaking changes.
150-
151147
type oasAnnotations []string
152148

153149
func (oa oasAnnotations) getHandlerFuncName() string {
@@ -161,5 +157,3 @@ func (oa oasAnnotations) getRoute() string {
161157
func (oa oasAnnotations) getHTTPMethod() string {
162158
return oa[4]
163159
}
164-
165-
// End of oasAnnotations section.

annotations_test.go

+71-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ package docs
22

33
import (
44
"errors"
5+
"math/rand"
6+
"os"
57
"path/filepath"
8+
"reflect"
9+
"runtime"
610
"testing"
11+
"testing/quick"
712
)
813

914
const (
@@ -13,7 +18,7 @@ const (
1318
func TestUnitMapAnnotationsInPath(t *testing.T) {
1419
t.Parallel()
1520

16-
o := prepForInitCallStack(t, false)
21+
o := prepForInitCallStack(t)
1722

1823
_ = o.MapAnnotationsInPath(examplesDir)
1924
}
@@ -61,7 +66,7 @@ func TestUnitScanForChangesInPathErrWalk(t *testing.T) {
6166
t.Error("expected an error, got none")
6267
}
6368

64-
o := prepForInitCallStack(t, false)
69+
o := prepForInitCallStack(t)
6570
errConfig := configAnnotation{
6671
getWD: wdErr,
6772
}
@@ -80,3 +85,67 @@ func TestUnitScanForChangesInPathErrWalk(t *testing.T) {
8085
t.Error("expected an error, got none")
8186
}
8287
}
88+
89+
type triggerNil struct {
90+
trigger bool
91+
}
92+
93+
func TestQuickUnitGetWD(t *testing.T) {
94+
t.Parallel()
95+
96+
config := quick.Config{
97+
Values: func(values []reflect.Value, rand *rand.Rand) {
98+
ca := configAnnotation{}
99+
rndNm := rand.Int()
100+
tn := triggerNil{trigger: false}
101+
if rndNm%2 == 0 {
102+
tn.trigger = true
103+
ca.getWD = func() (dir string, err error) {
104+
return "", nil
105+
}
106+
} else {
107+
ca.getWD = os.Getwd
108+
}
109+
110+
values[0] = reflect.ValueOf(ca)
111+
values[1] = reflect.ValueOf(tn)
112+
},
113+
}
114+
115+
gwdFetcher := func(ca configAnnotation, tn triggerNil) bool {
116+
got := ca.getCurrentDirFetcher()
117+
118+
return reflect.TypeOf(got) == reflect.TypeOf(ca.getWD)
119+
}
120+
121+
if err := quick.Check(gwdFetcher, &config); err != nil {
122+
t.Errorf("Check failed: %#v", err)
123+
}
124+
}
125+
126+
func TestUnitGWD(t *testing.T) {
127+
t.Parallel()
128+
129+
ca := configAnnotation{
130+
getWD: func() (dir string, err error) {
131+
return "", nil
132+
},
133+
}
134+
135+
got := ca.getCurrentDirFetcher()
136+
if reflect.TypeOf(got) != reflect.TypeOf(ca.getWD) {
137+
t.Error("functions differ")
138+
}
139+
140+
caNil := configAnnotation{}.getCurrentDirFetcher()
141+
142+
if gFnName(t, caNil) != gFnName(t, os.Getwd) {
143+
t.Error("functions differ")
144+
}
145+
}
146+
147+
func gFnName(t *testing.T, i interface{}) string {
148+
t.Helper()
149+
150+
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
151+
}

build.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ func getPathFromFirstElement(cbs []ConfigBuilder) string {
3636
//
3737
// Returns an error if there is any.
3838
func (o *OAS) BuildDocs(conf ...ConfigBuilder) error {
39-
err := o.initCallStackForRoutes()
40-
if err != nil {
41-
return fmt.Errorf("failed initiating call stack for registered routes: %w", err)
42-
}
39+
o.initCallStackForRoutes()
4340

4441
yml, err := marshalToYAML(o)
4542
if err != nil {

build_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "testing"
55
func TestUnitBuild(t *testing.T) {
66
t.Parallel()
77

8-
oasPrep := prepForInitCallStack(t, false)
8+
oasPrep := prepForInitCallStack(t)
99

1010
setInfoForTest(t, &oasPrep.Info)
1111
setPathForTest(t, &oasPrep.Paths[0])

caller.go

+9-24
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,27 @@
11
package docs
22

33
import (
4-
"fmt"
54
"reflect"
65
)
76

8-
func (o *OAS) Call(name string, params ...interface{}) (result []reflect.Value, err error) {
9-
f := reflect.ValueOf(o.RegisteredRoutes[name])
10-
paramNum := len(params)
11-
fnParamNum := f.Type().NumIn()
7+
// routePostfix will get exported by v1.3.
8+
const routePostfix = "Route"
129

13-
if paramNum != fnParamNum {
14-
return result, fmt.Errorf(
15-
"param number differs -> expected %d, got %d",
16-
paramNum, fnParamNum,
17-
)
18-
}
10+
func (o *OAS) Call(name string, params ...interface{}) (result []reflect.Value) {
11+
f := reflect.ValueOf(o.RegisteredRoutes[name])
1912

20-
in := make([]reflect.Value, paramNum)
13+
in := make([]reflect.Value, len(params))
2114
for k, param := range params {
2215
in[k] = reflect.ValueOf(param)
2316
}
2417

2518
result = f.Call(in)
2619

27-
return result, nil
20+
return result
2821
}
2922

30-
// should this be flexible for change?
31-
const routePostfix = "Route"
32-
33-
func (o *OAS) initCallStackForRoutes() error {
34-
for oasPathIndex, oasPath := range o.Paths { //nolint:gocritic //fixme: troubleshoot if this will be an issue.
35-
_, err := o.Call(oasPath.HandlerFuncName+routePostfix, oasPathIndex, o)
36-
if err != nil {
37-
return fmt.Errorf(" :%w", err)
38-
}
23+
func (o *OAS) initCallStackForRoutes() {
24+
for oasPathIndex := range o.Paths {
25+
o.Call(o.Paths[oasPathIndex].HandlerFuncName+routePostfix, oasPathIndex, o)
3926
}
40-
41-
return nil
4227
}

caller_test.go

+15-82
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,10 @@ import (
99

1010
const testingPostfix = "Testing"
1111

12-
func TestQuickUnitCallerErr(t *testing.T) {
13-
t.Parallel()
14-
15-
config := quick.Config{
16-
Values: func(args []reflect.Value, rand *rand.Rand) {
17-
rr := make(RegRoutes)
18-
count := rand.Intn(550-1) + 1
19-
paths := getPaths(t, count, RandomString(t, count))
20-
21-
for _, p := range paths {
22-
rr[p.Route+testingPostfix] = getPaths
23-
}
24-
25-
oas := OAS{
26-
Paths: getPaths(t, count, RandomString(t, count)),
27-
RegisteredRoutes: rr,
28-
}
29-
30-
var routes []interface{}
31-
for _, r := range rr {
32-
routes = append(routes, r)
33-
}
34-
35-
args[0] = reflect.ValueOf(oas)
36-
args[1] = reflect.ValueOf(routes)
37-
},
38-
}
39-
40-
callerWrongParamNumber := func(oas OAS, routes []interface{}) bool {
41-
oas.AttachRoutes(routes)
42-
43-
for oasPathIndex := range oas.Paths {
44-
_, err := oas.Call("getPaths", oasPathIndex, oas)
45-
if err == nil {
46-
t.Errorf("failing (OAS).Call() with err : %s", err)
47-
48-
return false
49-
}
50-
}
51-
52-
return true
53-
}
54-
55-
if err := quick.Check(callerWrongParamNumber, &config); err != nil {
56-
t.Errorf("Check failed: %#v", err)
57-
}
58-
}
59-
6012
func TestQuickUnitCaller(t *testing.T) {
6113
t.Parallel()
6214

63-
successParamNumber := func(name string, oas *OAS) {}
15+
successParamNumber := func(i int, oas *OAS) {}
6416
config := quick.Config{
6517
Values: func(args []reflect.Value, rand *rand.Rand) {
6618
rr := make(RegRoutes)
@@ -81,10 +33,11 @@ func TestQuickUnitCaller(t *testing.T) {
8133
}
8234

8335
callerCorrectParamNumber := func(oas OAS) bool {
84-
for _, oasPath := range oas.Paths {
85-
_, err := oas.Call(oasPath.Route+testingPostfix, oasPath.Route, &oas)
86-
if err != nil {
87-
t.Errorf("failed executing (OAS).Call() with err : %s", err)
36+
for i, oasPath := range oas.Paths {
37+
res := oas.Call(oasPath.Route+testingPostfix, i, &oas)
38+
39+
if len(res) > 0 {
40+
t.Error("failed executing (OAS).Call() with")
8841

8942
return false
9043
}
@@ -101,7 +54,7 @@ func TestQuickUnitCaller(t *testing.T) {
10154
func TestUnitCaller(t *testing.T) {
10255
t.Parallel()
10356

104-
successParamNumber := func(name string, oas *OAS) {}
57+
successParamNumber := func(i int, oas *OAS) {}
10558
routeName := "testRouteTesting"
10659
rr := make(RegRoutes)
10760
rr[routeName] = successParamNumber
@@ -110,45 +63,24 @@ func TestUnitCaller(t *testing.T) {
11063
RegisteredRoutes: rr,
11164
}
11265

113-
_, err := o.Call(routeName, routeName, &o)
114-
if err != nil {
115-
t.Errorf("failed executing (OAS).Call() with err : %s", err)
116-
}
66+
_ = o.Call(routeName, 0, &o)
11767
}
11868

11969
func TestUnitInitCallStack(t *testing.T) {
12070
t.Parallel()
12171

122-
o := prepForInitCallStack(t, false)
72+
o := prepForInitCallStack(t)
12373

124-
err := o.initCallStackForRoutes()
125-
if err != nil {
126-
t.Errorf("failed executing (OAS).initCallStackForRoutes() with err : %s", err)
127-
}
74+
o.initCallStackForRoutes()
12875
}
12976

130-
func TestUnitInitCallStackErr(t *testing.T) {
131-
t.Parallel()
132-
133-
o := prepForInitCallStack(t, true)
134-
135-
err := o.initCallStackForRoutes()
136-
if err == nil {
137-
t.Errorf("failed executing (OAS).initCallStackForRoutes() with err : %s", err)
138-
}
139-
}
140-
141-
func prepForInitCallStack(t *testing.T, triggerErr bool) OAS {
77+
func prepForInitCallStack(t *testing.T) OAS {
14278
t.Helper()
14379

14480
routeName := "testRoute" + routePostfix
14581
rr := make(RegRoutes)
14682

147-
if !triggerErr {
148-
rr[routeName] = getSuccessParamNumber
149-
} else {
150-
rr[routeName] = getFailureParamNumber
151-
}
83+
rr[routeName] = getSuccessParamNumber
15284

15385
path := Path{
15486
HandlerFuncName: "testRoute",
@@ -161,5 +93,6 @@ func prepForInitCallStack(t *testing.T, triggerErr bool) OAS {
16193
return o
16294
}
16395

164-
func getSuccessParamNumber(_ int, _ *OAS) {}
165-
func getFailureParamNumber(t *testing.T, _ int, _ *OAS) { t.Helper() }
96+
func getSuccessParamNumber(_ int, _ *OAS) {}
97+
98+
// func getFailureParamNumber(t *testing.T, _ int, _ *OAS) { t.Helper() }

routing.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ type (
1111
RouteFn func(index int, oas *OAS)
1212

1313
// RegRoutes represent a map of RouteFn's.
14-
// TODO: Will this get Deprecated?
14+
//
15+
// Note: Considering to un-export it.
1516
RegRoutes map[string]RouteFn
1617
)
1718

0 commit comments

Comments
 (0)