gromer

#golang#htmx#ssr

git clone https://git.pyrossh.dev/gromer

gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.


ab4b506 — Peter John 2021-12-05T14:52:50+05:30
add validation errors

Generated files not shown: go.sum

Files changed (4) hide show
  1. go.mod +2 -0
  2. hooks_test.go +7 -5
  3. html_test.go +3 -2
  4. http.go +24 -3
go.mod CHANGED
@@ -8,9 +8,11 @@ require (
8
8
  github.com/bradleyjkemp/cupaloy v2.3.0+incompatible
9
9
  github.com/fatih/color v1.13.0
10
10
  github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
11
+ github.com/go-playground/validator/v10 v10.9.0 // indirect
11
12
  github.com/gobuffalo/velvet v0.0.0-20170320144106-d97471bf5d8f
12
13
  github.com/google/uuid v1.3.0
13
14
  github.com/gorilla/mux v1.8.0
15
+ github.com/iancoleman/strcase v0.2.0 // indirect
14
16
  github.com/lib/pq v1.10.4
15
17
  github.com/markbates/inflect v1.0.4
16
18
  github.com/microcosm-cc/bluemonday v1.0.15 // indirect
hooks_test.go CHANGED
@@ -1,6 +1,7 @@
1
1
  package gromer
2
2
 
3
3
  import (
4
+ "context"
4
5
  "testing"
5
6
 
6
7
  . "github.com/franela/goblin"
@@ -9,13 +10,14 @@ import (
9
10
  func TestHooks(t *testing.T) {
10
11
  g := Goblin(t)
11
12
  g.Describe("useState", func() {
12
- ctx := &Context{index: 0, datas: []interface{}{}}
13
+ ctx := WithState(context.Background())
14
+ stateCtx := getState(ctx)
13
15
  getValue, setValue := UseState(ctx, 12)
14
16
 
15
17
  g.It("should be initialized ", func() {
16
- g.Assert(1).Equal(ctx.index)
18
+ g.Assert(1).Equal(stateCtx.index)
17
- g.Assert(1).Equal(len(ctx.datas))
19
+ g.Assert(1).Equal(len(stateCtx.datas))
18
- g.Assert(ctx.datas[0]).Equal(12)
20
+ g.Assert(stateCtx.datas[0]).Equal(12)
19
21
  })
20
22
 
21
23
  g.It("should get value ", func() {
@@ -24,7 +26,7 @@ func TestHooks(t *testing.T) {
24
26
 
25
27
  g.It("should set value", func() {
26
28
  setValue(15)
27
- g.Assert(ctx.datas[0]).Equal(15)
29
+ g.Assert(stateCtx.datas[0]).Equal(15)
28
30
  g.Assert(getValue()).Equal(15)
29
31
  })
30
32
  })
html_test.go CHANGED
@@ -2,6 +2,7 @@ package gromer
2
2
 
3
3
  import (
4
4
  "bytes"
5
+ "context"
5
6
  "strconv"
6
7
  "testing"
7
8
 
@@ -27,7 +28,7 @@ func Col(uis ...interface{}) *Element {
27
28
  return NewElement("div", false, append([]interface{}{Css("flex flex-col justify-center items-center")}, uis...)...)
28
29
  }
29
30
 
30
- func Counter(c *Context, start int) *Element {
31
+ func Counter(c context.Context, start int) *Element {
31
32
  count, setCount := UseState(c, start)
32
33
  increment := func() {
33
34
  setCount(count().(int) + 1)
@@ -80,7 +81,7 @@ func TestHtml(t *testing.T) {
80
81
  g := Goblin(t)
81
82
  g.Describe("Html", func() {
82
83
  g.It("should match snapshot", func() {
83
- ctx := &Context{index: 0, datas: []interface{}{}}
84
+ ctx := WithState(context.Background())
84
85
  b := bytes.NewBuffer(nil)
85
86
  p := Html(
86
87
  Head(
http.go CHANGED
@@ -10,7 +10,9 @@ import (
10
10
  "strings"
11
11
 
12
12
  "github.com/fatih/color"
13
+ "github.com/go-playground/validator/v10"
13
14
  "github.com/gorilla/mux"
15
+ "github.com/iancoleman/strcase"
14
16
  "github.com/rs/zerolog"
15
17
  "github.com/rs/zerolog/log"
16
18
  )
@@ -21,11 +23,30 @@ func init() {
21
23
  }
22
24
 
23
25
  func RespondError(w http.ResponseWriter, status int, err error) {
24
- w.WriteHeader(status)
25
26
  w.Header().Set("Content-Type", "application/json")
27
+ w.WriteHeader(status) // always write status last
26
- data, _ := json.Marshal(map[string]string{
28
+ merror := map[string]interface{}{
27
29
  "error": err.Error(),
28
- })
30
+ }
31
+ validationErrors, ok := err.(validator.ValidationErrors)
32
+ if ok {
33
+ emap := map[string]string{}
34
+ for _, e := range validationErrors {
35
+ parts := strings.Split(e.StructNamespace(), ".")
36
+ lowerParts := []string{}
37
+ for _, p := range parts[1:] {
38
+ lowerParts = append(lowerParts, strcase.ToLowerCamel(p))
39
+ }
40
+ k := strings.Join(lowerParts, ".")
41
+ if e.Tag() == "required" {
42
+ emap[k] = "is required"
43
+ } else {
44
+ emap[k] = e.Error()
45
+ }
46
+ }
47
+ merror["error"] = emap
48
+ }
49
+ data, _ := json.Marshal(merror)
29
50
  w.Write(data)
30
51
  }
31
52