From 4d889f2bc75295e84ac993a2f85e736143b8292e Mon Sep 17 00:00:00 2001 From: Putra Fajar H Date: Mon, 17 Feb 2025 07:14:27 +0700 Subject: [PATCH 1/2] feat: add validation for weekends --- baked_in.go | 31 ++++++++++++++++++++++ validator_test.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/baked_in.go b/baked_in.go index cca3e0917..c0f757fc6 100644 --- a/baked_in.go +++ b/baked_in.go @@ -220,6 +220,7 @@ var ( "uppercase": isUppercase, "datetime": isDatetime, "timezone": isTimeZone, + "weekend": isWeekend, "iso3166_1_alpha2": isIso3166Alpha2, "iso3166_1_alpha2_eu": isIso3166Alpha2EU, "iso3166_1_alpha3": isIso3166Alpha3, @@ -2817,6 +2818,36 @@ func isTimeZone(fl FieldLevel) bool { panic(fmt.Sprintf("Bad field type %T", field.Interface())) } +func isWeekend(fl FieldLevel) bool { + field := fl.Field() + kind := field.Kind() + param := fl.Param() + + fmt.Println("param", param) + fmt.Println("field", field.String()) + + if kind == reflect.String { + fmt.Println("reflect", "string") + parsedTime, err := time.Parse(param, field.String()) + if err != nil { + panic(fmt.Sprintf("Bad time format: %s", err)) + } + weekday := parsedTime.Weekday() + fmt.Println("weekday", weekday) + return weekday == time.Saturday || weekday == time.Sunday + } + + if kind == reflect.Struct { + fmt.Println("reflect", "struct") + if field.Type().ConvertibleTo(timeType) { + weekday := field.Convert(timeType).Interface().(time.Time).Weekday() + return weekday == time.Saturday || weekday == time.Sunday + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + // isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 country code. func isIso3166Alpha2(fl FieldLevel) bool { _, ok := iso3166_1_alpha2[fl.Field().String()] diff --git a/validator_test.go b/validator_test.go index af05d19d6..fbf7fef90 100644 --- a/validator_test.go +++ b/validator_test.go @@ -12080,7 +12080,7 @@ func TestExcludedIf(t *testing.T) { test11 := struct { Field1 bool - Field2 *string `validate:"excluded_if=Field1 false"` + Field2 *string `validate:"excluded_if=Field1 false"` }{ Field1: false, Field2: nil, @@ -12609,6 +12609,70 @@ func TestDatetimeValidation(t *testing.T) { }, "Bad field type int") } +func TestWeekendStringValidation(t *testing.T) { + tests := []struct { + value string `validate:"weekend=2006-01-02"` + expected bool + }{ + {"2025-01-25", true}, // Saturday + {"2025-01-26", true}, // Sunday + {"2025-01-27", false}, // Monday + {"2025-01-28", false}, // Tuesday + {"2025-01-29", false}, // Wednesday + {"2025-01-30", false}, // Thursday + {"2025-01-31", false}, // Friday + } + + validate := New() + + for i, test := range tests { + + errs := validate.Var(test.value, "weekend=2006-01-02") + + if test.expected { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d weekend failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d weekend failed Error: %s", i, errs) + } + } + } + + PanicMatches(t, func() { + _ = validate.Var(2, "weekend") + }, "Bad field type int") +} + +func TestWeekendStructValidation(t *testing.T) { + type ChosenDate struct { + Datetime time.Time `validate:"weekend"` + } + + type testInput struct { + data time.Time + expected bool + } + testData := []testInput{ + {time.Date(2025, 1, 25, 0, 0, 0, 0, time.UTC), true}, // Saturday + {time.Date(2025, 1, 26, 0, 0, 0, 0, time.UTC), true}, // Sunday + {time.Date(2025, 1, 27, 0, 0, 0, 0, time.UTC), false}, // Monday + {time.Date(2025, 1, 28, 0, 0, 0, 0, time.UTC), false}, // Tuesday + {time.Date(2025, 1, 29, 0, 0, 0, 0, time.UTC), false}, // Wednesday + {time.Date(2025, 1, 30, 0, 0, 0, 0, time.UTC), false}, // Thursday + {time.Date(2025, 1, 31, 0, 0, 0, 0, time.UTC), false}, // Friday + } + for _, td := range testData { + c := ChosenDate{Datetime: td.data} + v := New() + err := v.Struct(c) + if td.expected != (err == nil) { + t.Fatalf("Test failed for data: %v Error: %v", td.data, err) + } + } +} + func TestIsIso3166Alpha2Validation(t *testing.T) { tests := []struct { value string `validate:"iso3166_1_alpha2"` From ab2e3573e76fedd9ef87d940d7f26de7d8146ed0 Mon Sep 17 00:00:00 2001 From: Putra Fajar H Date: Mon, 17 Feb 2025 07:18:03 +0700 Subject: [PATCH 2/2] cleanup --- baked_in.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/baked_in.go b/baked_in.go index c0f757fc6..9e75921ec 100644 --- a/baked_in.go +++ b/baked_in.go @@ -2823,22 +2823,16 @@ func isWeekend(fl FieldLevel) bool { kind := field.Kind() param := fl.Param() - fmt.Println("param", param) - fmt.Println("field", field.String()) - if kind == reflect.String { - fmt.Println("reflect", "string") parsedTime, err := time.Parse(param, field.String()) if err != nil { panic(fmt.Sprintf("Bad time format: %s", err)) } weekday := parsedTime.Weekday() - fmt.Println("weekday", weekday) return weekday == time.Saturday || weekday == time.Sunday } if kind == reflect.Struct { - fmt.Println("reflect", "struct") if field.Type().ConvertibleTo(timeType) { weekday := field.Convert(timeType).Interface().(time.Time).Weekday() return weekday == time.Saturday || weekday == time.Sunday