Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add validation for weekends #1377

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions baked_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -2817,6 +2818,30 @@ 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()

if kind == reflect.String {
parsedTime, err := time.Parse(param, field.String())
if err != nil {
panic(fmt.Sprintf("Bad time format: %s", err))
}
weekday := parsedTime.Weekday()
return weekday == time.Saturday || weekday == time.Sunday
}

if kind == 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()]
Expand Down
66 changes: 65 additions & 1 deletion validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"`
Expand Down
Loading