Merge pull request #105 from miraclesu/form
Add ParseForm Function & utils test
Showing
3 changed files
with
224 additions
and
0 deletions
| ... | @@ -264,6 +264,10 @@ func (c *Controller) Input() url.Values { | ... | @@ -264,6 +264,10 @@ func (c *Controller) Input() url.Values { |
| 264 | return c.Ctx.Request.Form | 264 | return c.Ctx.Request.Form |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | func (c *Controller) ParseForm(obj interface{}) error { | ||
| 268 | return ParseForm(c.Input(), obj) | ||
| 269 | } | ||
| 270 | |||
| 267 | func (c *Controller) GetString(key string) string { | 271 | func (c *Controller) GetString(key string) string { |
| 268 | return c.Input().Get(key) | 272 | return c.Input().Get(key) |
| 269 | } | 273 | } | ... | ... |
| ... | @@ -3,7 +3,10 @@ package beego | ... | @@ -3,7 +3,10 @@ package beego |
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | "html/template" | 5 | "html/template" |
| 6 | "net/url" | ||
| 7 | "reflect" | ||
| 6 | "regexp" | 8 | "regexp" |
| 9 | "strconv" | ||
| 7 | "strings" | 10 | "strings" |
| 8 | "time" | 11 | "time" |
| 9 | ) | 12 | ) |
| ... | @@ -170,3 +173,80 @@ func inSlice(v string, sl []string) bool { | ... | @@ -170,3 +173,80 @@ func inSlice(v string, sl []string) bool { |
| 170 | } | 173 | } |
| 171 | return false | 174 | return false |
| 172 | } | 175 | } |
| 176 | |||
| 177 | // parse form values to struct via tag | ||
| 178 | func ParseForm(form url.Values, obj interface{}) error { | ||
| 179 | objT := reflect.TypeOf(obj) | ||
| 180 | objV := reflect.ValueOf(obj) | ||
| 181 | if !(objT.Kind() == reflect.Ptr && objT.Elem().Kind() == reflect.Struct) { | ||
| 182 | return fmt.Errorf("%v must be a struct pointer", obj) | ||
| 183 | } | ||
| 184 | objT = objT.Elem() | ||
| 185 | objV = objV.Elem() | ||
| 186 | |||
| 187 | for i := 0; i < objT.NumField(); i++ { | ||
| 188 | fieldV := objV.Field(i) | ||
| 189 | if !fieldV.CanSet() { | ||
| 190 | continue | ||
| 191 | } | ||
| 192 | fieldT := objT.Field(i) | ||
| 193 | tag := fieldT.Tag.Get("form") | ||
| 194 | if len(tag) == 0 { | ||
| 195 | tag = fieldT.Name | ||
| 196 | } | ||
| 197 | value := form.Get(tag) | ||
| 198 | if len(value) == 0 { | ||
| 199 | continue | ||
| 200 | } | ||
| 201 | |||
| 202 | switch fieldT.Type.Kind() { | ||
| 203 | case reflect.Bool: | ||
| 204 | b, err := strconv.ParseBool(value) | ||
| 205 | if err != nil { | ||
| 206 | return err | ||
| 207 | } | ||
| 208 | fieldV.SetBool(b) | ||
| 209 | case reflect.Int: | ||
| 210 | fallthrough | ||
| 211 | case reflect.Int8: | ||
| 212 | fallthrough | ||
| 213 | case reflect.Int16: | ||
| 214 | fallthrough | ||
| 215 | case reflect.Int32: | ||
| 216 | fallthrough | ||
| 217 | case reflect.Int64: | ||
| 218 | x, err := strconv.ParseInt(value, 10, 64) | ||
| 219 | if err != nil { | ||
| 220 | return err | ||
| 221 | } | ||
| 222 | fieldV.SetInt(x) | ||
| 223 | case reflect.Uint: | ||
| 224 | fallthrough | ||
| 225 | case reflect.Uint8: | ||
| 226 | fallthrough | ||
| 227 | case reflect.Uint16: | ||
| 228 | fallthrough | ||
| 229 | case reflect.Uint32: | ||
| 230 | fallthrough | ||
| 231 | case reflect.Uint64: | ||
| 232 | x, err := strconv.ParseUint(value, 10, 64) | ||
| 233 | if err != nil { | ||
| 234 | return err | ||
| 235 | } | ||
| 236 | fieldV.SetUint(x) | ||
| 237 | case reflect.Float32: | ||
| 238 | fallthrough | ||
| 239 | case reflect.Float64: | ||
| 240 | x, err := strconv.ParseFloat(value, 64) | ||
| 241 | if err != nil { | ||
| 242 | return err | ||
| 243 | } | ||
| 244 | fieldV.SetFloat(x) | ||
| 245 | case reflect.Interface: | ||
| 246 | fieldV.Set(reflect.ValueOf(value)) | ||
| 247 | case reflect.String: | ||
| 248 | fieldV.SetString(value) | ||
| 249 | } | ||
| 250 | } | ||
| 251 | return nil | ||
| 252 | } | ... | ... |
utils_test.go
0 → 100644
| 1 | package beego | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "net/url" | ||
| 5 | "testing" | ||
| 6 | "time" | ||
| 7 | ) | ||
| 8 | |||
| 9 | func TestWebTime(t *testing.T) { | ||
| 10 | ts := "Fri, 26 Jul 2013 12:27:42 CST" | ||
| 11 | tt, _ := time.Parse(time.RFC1123, ts) | ||
| 12 | if ts != webTime(tt) { | ||
| 13 | t.Error("should be equal") | ||
| 14 | } | ||
| 15 | if "Fri, 26 Jul 2013 04:27:42 GMT" != webTime(tt.UTC()) { | ||
| 16 | t.Error("should be equal") | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | func TestSubstr(t *testing.T) { | ||
| 21 | s := `012345` | ||
| 22 | if Substr(s, 0, 2) != "01" { | ||
| 23 | t.Error("should be equal") | ||
| 24 | } | ||
| 25 | if Substr(s, 0, 100) != "012345" { | ||
| 26 | t.Error("should be equal") | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | func TestHtml2str(t *testing.T) { | ||
| 31 | h := `<HTML><style></style><script>x<x</script></HTML><123> 123\n | ||
| 32 | |||
| 33 | |||
| 34 | \n` | ||
| 35 | if Html2str(h) != "123\\n\n\\n" { | ||
| 36 | t.Error("should be equal") | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | func TestDateFormat(t *testing.T) { | ||
| 41 | ts := "Mon, 01 Jul 2013 13:27:42 CST" | ||
| 42 | tt, _ := time.Parse(time.RFC1123, ts) | ||
| 43 | if DateFormat(tt, "2006-01-02 15:04:05") != "2013-07-01 13:27:42" { | ||
| 44 | t.Error("should be equal") | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | func TestDate(t *testing.T) { | ||
| 49 | ts := "Mon, 01 Jul 2013 13:27:42 CST" | ||
| 50 | tt, _ := time.Parse(time.RFC1123, ts) | ||
| 51 | if Date(tt, "Y-m-d H:i:s") != "2013-07-01 13:27:42" { | ||
| 52 | t.Error("should be equal") | ||
| 53 | } | ||
| 54 | if Date(tt, "y-n-j h:i:s A") != "13-7-1 01:27:42 PM" { | ||
| 55 | t.Error("should be equal") | ||
| 56 | } | ||
| 57 | if Date(tt, "D, d M Y g:i:s a") != "Mon, 01 Jul 2013 1:27:42 pm" { | ||
| 58 | t.Error("should be equal") | ||
| 59 | } | ||
| 60 | if Date(tt, "l, d F Y G:i:s") != "Monday, 01 July 2013 13:27:42" { | ||
| 61 | t.Error("should be equal") | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | func TestCompare(t *testing.T) { | ||
| 66 | if !Compare("abc", "abc") { | ||
| 67 | t.Error("should be equal") | ||
| 68 | } | ||
| 69 | if Compare("abc", "aBc") { | ||
| 70 | t.Error("should be not equal") | ||
| 71 | } | ||
| 72 | if !Compare("1", 1) { | ||
| 73 | t.Error("should be equal") | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | func TestHtmlquote(t *testing.T) { | ||
| 78 | h := `<' ”“&">` | ||
| 79 | s := `<' ”“&">` | ||
| 80 | if Htmlquote(s) != h { | ||
| 81 | t.Error("should be equal") | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | func TestHtmlunquote(t *testing.T) { | ||
| 86 | h := `<' ”“&">` | ||
| 87 | s := `<' ”“&">` | ||
| 88 | if Htmlunquote(h) != s { | ||
| 89 | t.Error("should be equal") | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | func TestInSlice(t *testing.T) { | ||
| 94 | sl := []string{"A", "b"} | ||
| 95 | if !inSlice("A", sl) { | ||
| 96 | t.Error("should be true") | ||
| 97 | } | ||
| 98 | if inSlice("B", sl) { | ||
| 99 | t.Error("should be false") | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | func TestParseForm(t *testing.T) { | ||
| 104 | type user struct { | ||
| 105 | Id int | ||
| 106 | tag string `form:tag` | ||
| 107 | Name interface{} `form:"username"` | ||
| 108 | Age int `form:"age"` | ||
| 109 | Email string | ||
| 110 | } | ||
| 111 | |||
| 112 | u := user{} | ||
| 113 | form := url.Values{ | ||
| 114 | "tag": []string{"no"}, | ||
| 115 | "username": []string{"test"}, | ||
| 116 | "age": []string{"40"}, | ||
| 117 | "Email": []string{"test@gmail.com"}, | ||
| 118 | } | ||
| 119 | if err := ParseForm(form, u); err == nil { | ||
| 120 | t.Fatal("nothing will be changed") | ||
| 121 | } | ||
| 122 | if err := ParseForm(form, &u); err != nil { | ||
| 123 | t.Fatal(err) | ||
| 124 | } | ||
| 125 | if u.Id != 0 { | ||
| 126 | t.Error("Id should not be changed") | ||
| 127 | } | ||
| 128 | if len(u.tag) != 0 { | ||
| 129 | t.Error("tag should not be changed") | ||
| 130 | } | ||
| 131 | if u.Name.(string) != "test" { | ||
| 132 | t.Error("should be equal") | ||
| 133 | } | ||
| 134 | if u.Age != 40 { | ||
| 135 | t.Error("should be equal") | ||
| 136 | } | ||
| 137 | if u.Email != "test@gmail.com" { | ||
| 138 | t.Error("should be equal") | ||
| 139 | } | ||
| 140 | } |
-
Please register or sign in to post a comment