Skip to content

Commit 3822c6a

Browse files
committed
Merge branch 'development' of github.com:gofr-dev/gofr into development
2 parents 3f6cf08 + 1d1d257 commit 3822c6a

File tree

7 files changed

+209
-84
lines changed

7 files changed

+209
-84
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ go 1.21
44

55
require (
66
github.com/DATA-DOG/go-sqlmock v1.5.2
7-
github.com/alicebob/miniredis/v2 v2.31.1
87
github.com/go-sql-driver/mysql v1.7.1
98
github.com/gorilla/mux v1.8.1
109
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
@@ -26,6 +25,7 @@ require (
2625

2726
require (
2827
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
28+
github.com/alicebob/miniredis/v2 v2.31.1 // indirect
2929
github.com/cespare/xxhash/v2 v2.2.0 // indirect
3030
github.com/davecgh/go-spew v1.1.1 // indirect
3131
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect

pkg/gofr/cmd_test.go

Lines changed: 161 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,205 @@
11
package gofr
22

33
import (
4+
"os"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
8+
9+
"gofr.dev/pkg/gofr/config"
10+
"gofr.dev/pkg/gofr/container"
11+
"gofr.dev/pkg/gofr/testutil"
712
)
813

9-
func Test_ErrCommandNotFound(t *testing.T) {
10-
err := ErrCommandNotFound{}
14+
func Test_Run_SuccessCallRegisteredArgument(t *testing.T) {
15+
os.Args = []string{"", "log"}
16+
17+
c := cmd{}
1118

12-
result := err.Error()
19+
c.addRoute("log", func(c *Context) (interface{}, error) {
20+
c.Logger.Info("handler called")
21+
22+
return nil, nil
23+
})
1324

14-
assert.Equal(t, "No Command Found!", result, "Test Failed \nMatch Error String")
25+
logs := testutil.StdoutOutputForFunc(func() {
26+
c.Run(container.NewContainer(config.NewEnvFile("")))
27+
})
28+
29+
assert.Contains(t, logs, "handler called")
1530
}
1631

17-
func Test_addRouteNotNilHandler(t *testing.T) {
18-
testHandler := func(c *Context) (interface{}, error) {
32+
func Test_Run_SuccessSkipEmptySpaceAndMatchCommandWithSpace(t *testing.T) {
33+
os.Args = []string{"", "", " ", "log"}
34+
35+
c := cmd{}
36+
37+
c.addRoute("log", func(c *Context) (interface{}, error) {
38+
c.Logger.Info("handler called")
39+
1940
return nil, nil
20-
}
41+
})
42+
43+
logs := testutil.StdoutOutputForFunc(func() {
44+
c.Run(container.NewContainer(config.NewEnvFile("")))
45+
})
46+
47+
assert.Contains(t, logs, "handler called")
48+
}
49+
50+
func Test_Run_SuccessCommandWithMultipleParameters(t *testing.T) {
51+
os.Args = []string{"", "log", "-param=value", "-b", "-c"}
52+
53+
c := cmd{}
2154

55+
c.addRoute("log", func(c *Context) (interface{}, error) {
56+
assert.Equal(t, c.Request.Param("param"), "value")
57+
assert.Equal(t, c.Request.Param("b"), "true")
58+
59+
c.Logger.Info("handler called")
60+
61+
return nil, nil
62+
})
63+
64+
logs := testutil.StdoutOutputForFunc(func() {
65+
c.Run(container.NewContainer(config.NewEnvFile("")))
66+
})
67+
68+
assert.Contains(t, logs, "handler called")
69+
}
70+
71+
func Test_Run_SuccessRouteWithSpecialCharacters(t *testing.T) {
2272
testCases := []struct {
23-
desc string
24-
pattern string
25-
handler func(c *Context) (interface{}, error)
73+
desc string
74+
args []string
2675
}{
27-
{"valid pattern and handler", "test", testHandler},
28-
{"empty pattern and valid handler", " ", testHandler},
76+
{"special character !", []string{"", "command-with-special-characters!"}},
77+
{"special character @", []string{"", "command-with-special-characters@"}},
78+
{"special character #", []string{"", "command-with-special-characters#"}},
79+
{"special character %", []string{"", "command-with-special-characters%"}},
80+
{"special character &", []string{"", "command-with-special-characters&"}},
81+
{"special character *", []string{"", "command-with-special-characters*"}},
2982
}
3083

3184
for i, tc := range testCases {
32-
cmd := &cmd{}
85+
os.Args = tc.args
86+
c := cmd{}
3387

34-
cmd.addRoute(tc.pattern, tc.handler)
88+
c.addRoute(tc.args[1], func(c *Context) (interface{}, error) {
89+
c.Logger.Info("handler called")
3590

36-
assert.Equal(t, tc.pattern, cmd.routes[0].pattern, "TEST[%d], Failed.\n%s", i, tc.desc)
37-
assert.NotNil(t, cmd.routes[0].handler, "TEST[%d], Failed.\n%s", i, tc.desc)
91+
return nil, nil
92+
})
93+
94+
logs := testutil.StdoutOutputForFunc(func() {
95+
c.Run(container.NewContainer(config.NewEnvFile("")))
96+
})
97+
98+
assert.Contains(t, logs, "handler called", "TEST[%d] Failed.\n %s", i, tc.desc)
99+
assert.NotContains(t, logs, "No Command Found!", "TEST[%d] Failed.\n %s", i, tc.desc)
38100
}
39101
}
40102

41-
func Test_addRouteNilHanlder(t *testing.T) {
103+
func Test_Run_ErrorRouteWithSpecialCharacters(t *testing.T) {
42104
testCases := []struct {
43-
desc string
44-
pattern string
45-
handler func(c *Context) (interface{}, error)
105+
desc string
106+
args []string
46107
}{
47-
{"valid pattern and nil handler", "test", nil},
48-
{"empty pattern and nil handler", " ", nil},
108+
{"special character $", []string{"", "command-with-special-characters$"}},
109+
{"special character ^", []string{"", "command-with-special-characters^"}},
49110
}
50111

51112
for i, tc := range testCases {
52-
cmd := &cmd{}
113+
os.Args = tc.args
114+
c := cmd{}
115+
116+
c.addRoute(tc.args[1], func(c *Context) (interface{}, error) {
117+
c.Logger.Info("handler called")
53118

54-
cmd.addRoute(tc.pattern, tc.handler)
119+
return nil, nil
120+
})
55121

56-
assert.Equal(t, tc.pattern, cmd.routes[0].pattern, "TEST[%d], Failed.\n%s", i, tc.desc)
57-
assert.Nil(t, cmd.routes[0].handler, "TEST[%d], Failed.\n%s", i, tc.desc)
122+
logs := testutil.StderrOutputForFunc(func() {
123+
c.Run(container.NewContainer(config.NewEnvFile("")))
124+
})
125+
126+
assert.NotContains(t, logs, "handler called", "TEST[%d] Failed.\n %s", i, tc.desc)
127+
assert.Contains(t, logs, "No Command Found!", "TEST[%d] Failed.\n %s", i, tc.desc)
58128
}
59129
}
60130

61-
func Test_handlerReturnsNilIfRouteHandlerIsNotNil(t *testing.T) {
62-
cmd := &cmd{
63-
routes: []route{
64-
{pattern: "pattern", handler: func(c *Context) (interface{}, error) {
65-
return nil, nil
66-
}},
67-
},
68-
}
69-
path := "pattern"
131+
func Test_Run_ErrorParamNotReadWithoutHyphen(t *testing.T) {
132+
os.Args = []string{"", "log", "hello=world"}
133+
134+
c := cmd{}
70135

71-
result := cmd.handler(path)
136+
c.addRoute("log", func(c *Context) (interface{}, error) {
137+
assert.Equal(t, c.Request.Param("hello"), "")
138+
c.Logger.Info("handler called")
72139

73-
assert.NotNil(t, result, "TEST, Failed.\n not nil handler")
140+
return nil, nil
141+
})
142+
143+
logs := testutil.StdoutOutputForFunc(func() {
144+
c.Run(container.NewContainer(config.NewEnvFile("")))
145+
})
146+
147+
assert.Contains(t, logs, "handler called")
74148
}
75149

76-
func Test_handlerReturnsNil(t *testing.T) {
77-
nonMatchingPattern := &cmd{
78-
routes: []route{
79-
{pattern: "pattern1", handler: func(c *Context) (interface{}, error) {
80-
return nil, nil
81-
}},
82-
{pattern: "pattern2", handler: func(c *Context) (interface{}, error) {
83-
return nil, nil
84-
}},
85-
},
86-
}
150+
func Test_Run_ErrorNotARegisteredCommand(t *testing.T) {
151+
os.Args = []string{"", "log"}
87152

88-
emptyRouteSlice := &cmd{routes: []route{}}
153+
c := cmd{}
89154

90-
nilHandler := &cmd{
91-
routes: []route{
92-
{pattern: "pattern", handler: nil},
93-
},
94-
}
155+
logs := testutil.StderrOutputForFunc(func() {
156+
c.Run(container.NewContainer(config.NewEnvFile("")))
157+
})
95158

96-
testCases := []struct {
97-
desc string
98-
cmd cmd
99-
pattern string
100-
}{
101-
{"pattern not matching with routes", *nonMatchingPattern, "non-matching-pattern"},
102-
{"routes slice in empty", *emptyRouteSlice, "pattern"},
103-
{"handler in nil", *nilHandler, "pattern"},
104-
}
159+
assert.Contains(t, logs, "No Command Found!")
160+
}
105161

106-
for i, tc := range testCases {
107-
r := tc.cmd.handler(tc.pattern)
162+
func Test_Run_ErrorWhenOnlyParamAreGiven(t *testing.T) {
163+
os.Args = []string{"", "-route"}
108164

109-
assert.Nil(t, r, "TEST[%d], Failed.\n%s", i, tc.desc)
110-
}
165+
c := cmd{}
166+
167+
c.addRoute("-route", func(c *Context) (interface{}, error) {
168+
c.Logger.Info("handler called of route -route")
169+
170+
return nil, nil
171+
})
172+
173+
logs := testutil.StderrOutputForFunc(func() {
174+
c.Run(container.NewContainer(config.NewEnvFile("")))
175+
})
176+
177+
assert.Contains(t, logs, "No Command Found!")
178+
assert.NotContains(t, logs, "handler called of route -route")
179+
}
180+
181+
func Test_Run_ErrorRouteRegisteredButNilHandler(t *testing.T) {
182+
os.Args = []string{"", "route"}
183+
184+
c := cmd{}
185+
186+
c.addRoute("route", nil)
187+
188+
logs := testutil.StderrOutputForFunc(func() {
189+
c.Run(container.NewContainer(config.NewEnvFile("")))
190+
})
191+
192+
assert.Contains(t, logs, "No Command Found!")
193+
}
194+
195+
func Test_Run_ErrorNoArgumentGiven(t *testing.T) {
196+
os.Args = []string{""}
197+
198+
c := cmd{}
199+
200+
logs := testutil.StderrOutputForFunc(func() {
201+
c.Run(container.NewContainer(config.NewEnvFile("")))
202+
})
203+
204+
assert.Contains(t, logs, "No Command Found!")
111205
}

pkg/gofr/container/container.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ type Container struct {
2626
func (c *Container) Health() interface{} {
2727
datasources := make(map[string]interface{})
2828

29-
datasources["sql"] = c.DB.HealthCheck()
29+
if c.DB != nil {
30+
datasources["sql"] = c.DB.HealthCheck()
31+
}
32+
33+
if c.Redis != nil {
34+
datasources["redis"] = c.Redis.HealthCheck()
35+
}
3036

3137
return datasources
3238
}
@@ -48,6 +54,7 @@ func NewContainer(conf config.Config) *Container {
4854
c.Redis, err = redis.NewClient(redis.Config{
4955
HostName: host,
5056
Port: port,
57+
Options: nil,
5158
}, c.Logger)
5259

5360
if err != nil {

pkg/gofr/datasource/health.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package datasource
22

3+
const (
4+
StatusUp = "UP"
5+
StatusDown = "DOWN"
6+
)
7+
38
type Health struct {
49
Status string `json:"status,omitempty"`
510
Details map[string]interface{} `json:"details,omitempty"`
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package redis
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"gofr.dev/pkg/gofr/datasource"
8+
)
9+
10+
func (r *Redis) HealthCheck() datasource.Health {
11+
h := datasource.Health{
12+
Details: make(map[string]interface{}),
13+
}
14+
15+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
16+
defer cancel()
17+
18+
info, err := r.InfoMap(ctx, "Stats").Result()
19+
if err != nil {
20+
h.Status = datasource.StatusDown
21+
h.Details["error"] = err.Error()
22+
23+
return h
24+
}
25+
26+
h.Status = datasource.StatusUp
27+
h.Details["stats"] = info
28+
29+
return h
30+
}

pkg/gofr/datasource/sql/health.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ func (d *DB) HealthCheck() datasource.Health {
1616
defer cancel()
1717

1818
err := d.PingContext(ctx)
19-
2019
if err != nil {
21-
h.Status = "DOWN"
20+
h.Status = datasource.StatusDown
21+
22+
return h
2223
}
2324

24-
h.Status = "UP"
25+
h.Status = datasource.StatusUp
2526
h.Details["stats"] = d.Stats()
2627

2728
return h

pkg/gofr/handler_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,6 @@ func TestHandler_ServeHTTP(t *testing.T) {
4848
}
4949
}
5050

51-
func TestHandler_healthHandler(t *testing.T) {
52-
c := Context{
53-
Context: context.Background(),
54-
}
55-
56-
data, err := healthHandler(&c)
57-
58-
assert.Equal(t, "OK", data, "TEST Failed.\n")
59-
60-
assert.NoError(t, err, "TEST Failed.\n")
61-
}
62-
6351
func TestHandler_faviconHandler(t *testing.T) {
6452
c := Context{
6553
Context: context.Background(),

0 commit comments

Comments
 (0)