| 
									
										
										
										
											2021-12-13 22:56:14 +08:00
										 |  |  | package web | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StructWithInt struct { | 
					
						
							|  |  |  | 	A int `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StructWithPrimitives struct { | 
					
						
							|  |  |  | 	A int     `binding:"Required"` | 
					
						
							|  |  |  | 	B string  `binding:"Required"` | 
					
						
							|  |  |  | 	C bool    `binding:"Required"` | 
					
						
							|  |  |  | 	D float64 `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StructWithPrivateFields struct { | 
					
						
							|  |  |  | 	A int `binding:"Required"` // must be validated
 | 
					
						
							|  |  |  | 	b int `binding:"Required"` // will not be used
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StructWithInterface struct { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	A any `binding:"Required"` | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | } | 
					
						
							|  |  |  | type StructWithSliceInts struct { | 
					
						
							|  |  |  | 	A []int `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type StructWithSliceStructs struct { | 
					
						
							|  |  |  | 	A []StructWithInt `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type StructWithSliceInterfaces struct { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	A []any `binding:"Required"` | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | } | 
					
						
							|  |  |  | type StructWithStruct struct { | 
					
						
							|  |  |  | 	A StructWithInt `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type StructWithStructPointer struct { | 
					
						
							|  |  |  | 	A *StructWithInt `binding:"Required"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type StructWithValidation struct { | 
					
						
							|  |  |  | 	A int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (sv StructWithValidation) Validate() error { | 
					
						
							|  |  |  | 	if sv.A < 10 { | 
					
						
							|  |  |  | 		return errors.New("too small") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-24 23:43:44 +08:00
										 |  |  | type StructWithPointerValidation struct { | 
					
						
							|  |  |  | 	A int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (sv *StructWithPointerValidation) Validate() error { | 
					
						
							|  |  |  | 	if sv.A < 10 { | 
					
						
							|  |  |  | 		return errors.New("too small") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | func TestValidationSuccess(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-01-24 23:43:44 +08:00
										 |  |  | 	var nilInterface *StructWithPointerValidation | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	for _, x := range []any{ | 
					
						
							| 
									
										
										
										
											2022-01-24 23:43:44 +08:00
										 |  |  | 		nil, | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 		42, | 
					
						
							|  |  |  | 		"foo", | 
					
						
							|  |  |  | 		struct{ A int }{}, | 
					
						
							|  |  |  | 		StructWithInt{42}, | 
					
						
							|  |  |  | 		StructWithPrimitives{42, "foo", true, 12.34}, | 
					
						
							|  |  |  | 		StructWithPrivateFields{12, 0}, | 
					
						
							|  |  |  | 		StructWithInterface{"foo"}, | 
					
						
							|  |  |  | 		StructWithSliceInts{[]int{1, 2, 3}}, | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 		StructWithSliceInterfaces{[]any{1, 2, 3}}, | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 		StructWithSliceStructs{[]StructWithInt{{1}, {2}}}, | 
					
						
							|  |  |  | 		StructWithStruct{StructWithInt{3}}, | 
					
						
							|  |  |  | 		StructWithStructPointer{&StructWithInt{3}}, | 
					
						
							|  |  |  | 		StructWithValidation{42}, | 
					
						
							| 
									
										
										
										
											2022-01-24 23:43:44 +08:00
										 |  |  | 		&StructWithPointerValidation{42}, | 
					
						
							|  |  |  | 		nilInterface, | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 	} { | 
					
						
							|  |  |  | 		if err := validate(x); err != nil { | 
					
						
							|  |  |  | 			t.Error("Validation failed:", x, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func TestValidationFailure(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	for i, x := range []any{ | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 		StructWithInt{0}, | 
					
						
							|  |  |  | 		StructWithPrimitives{0, "foo", true, 12.34}, | 
					
						
							|  |  |  | 		StructWithPrimitives{42, "", true, 12.34}, | 
					
						
							|  |  |  | 		StructWithPrimitives{42, "foo", false, 12.34}, | 
					
						
							|  |  |  | 		StructWithPrimitives{42, "foo", true, 0}, | 
					
						
							|  |  |  | 		StructWithPrivateFields{0, 1}, | 
					
						
							|  |  |  | 		StructWithInterface{}, | 
					
						
							|  |  |  | 		StructWithInterface{nil}, | 
					
						
							|  |  |  | 		StructWithSliceInts{}, | 
					
						
							|  |  |  | 		StructWithSliceInts{[]int{}}, | 
					
						
							|  |  |  | 		StructWithSliceStructs{[]StructWithInt{}}, | 
					
						
							|  |  |  | 		StructWithSliceStructs{[]StructWithInt{{0}, {2}}}, | 
					
						
							|  |  |  | 		StructWithSliceStructs{[]StructWithInt{{2}, {0}}}, | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 		StructWithSliceInterfaces{[]any{}}, | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 		StructWithSliceInterfaces{nil}, | 
					
						
							|  |  |  | 		StructWithStruct{StructWithInt{}}, | 
					
						
							|  |  |  | 		StructWithStruct{StructWithInt{0}}, | 
					
						
							|  |  |  | 		StructWithStructPointer{}, | 
					
						
							|  |  |  | 		StructWithStructPointer{&StructWithInt{}}, | 
					
						
							|  |  |  | 		StructWithValidation{2}, | 
					
						
							| 
									
										
										
										
											2022-01-24 23:43:44 +08:00
										 |  |  | 		&StructWithPointerValidation{2}, | 
					
						
							| 
									
										
										
										
											2021-10-06 18:52:27 +08:00
										 |  |  | 	} { | 
					
						
							|  |  |  | 		if err := validate(x); err == nil { | 
					
						
							|  |  |  | 			t.Error("Validation should fail:", i, x) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |