From b636ff0bc55a04bd98b85b7f05ad09a0b47e8b71 Mon Sep 17 00:00:00 2001 From: Higan Date: Fri, 12 Jul 2024 09:28:53 +0800 Subject: [PATCH] issue-677: test NewTask for the case where the last parameter is variadic. --- scheduler.go | 69 +++++++++++++++++++++++++++-------------------- scheduler_test.go | 5 ++++ 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/scheduler.go b/scheduler.go index a594eec..c6b7666 100644 --- a/scheduler.go +++ b/scheduler.go @@ -535,45 +535,56 @@ func (s *scheduler) NewJob(jobDefinition JobDefinition, task Task, options ...Jo return s.addOrUpdateJob(uuid.Nil, jobDefinition, task, options) } -func (s *scheduler) verifyParameterType(taskFunc reflect.Value, tsk task) error { - isVariadic := taskFunc.Type().IsVariadic() +func (s *scheduler) verifyVariadic(taskFunc reflect.Value, tsk task, variadicStart int) error { + if err := s.verifyNonVariadic(taskFunc, tsk, variadicStart); err != nil { + return err + } + parameterType := taskFunc.Type().In(variadicStart).Elem().Kind() + if parameterType == reflect.Interface || parameterType == reflect.Pointer { + parameterType = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(0))).Kind() + } - if isVariadic { - parameterType := taskFunc.Type().In(0).Elem().Kind() - if parameterType == reflect.Interface || parameterType == reflect.Pointer { - parameterType = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(0))).Kind() + for i := variadicStart; i < len(tsk.parameters); i++ { + argumentType := reflect.TypeOf(tsk.parameters[i]).Kind() + if argumentType == reflect.Interface || argumentType == reflect.Pointer { + argumentType = reflect.TypeOf(tsk.parameters[i]).Elem().Kind() + } + if argumentType != parameterType { + return ErrNewJobWrongTypeOfParameters } + } + return nil +} - for i := range tsk.parameters { - argumentType := reflect.TypeOf(tsk.parameters[i]).Kind() - if argumentType == reflect.Interface || argumentType == reflect.Pointer { - argumentType = reflect.TypeOf(tsk.parameters[i]).Elem().Kind() - } - if argumentType != parameterType { - return ErrNewJobWrongTypeOfParameters - } +func (s *scheduler) verifyNonVariadic(taskFunc reflect.Value, tsk task, length int) error { + for i := 0; i < length; i++ { + t1 := reflect.TypeOf(tsk.parameters[i]).Kind() + if t1 == reflect.Interface || t1 == reflect.Pointer { + t1 = reflect.TypeOf(tsk.parameters[i]).Elem().Kind() + } + t2 := reflect.New(taskFunc.Type().In(i)).Elem().Kind() + if t2 == reflect.Interface || t2 == reflect.Pointer { + t2 = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(i))).Kind() + } + if t1 != t2 { + return ErrNewJobWrongTypeOfParameters } + } + return nil +} + +func (s *scheduler) verifyParameterType(taskFunc reflect.Value, tsk task) error { + isVariadic := taskFunc.Type().IsVariadic() + if isVariadic { + variadicStart := taskFunc.Type().NumIn() - 1 + return s.verifyVariadic(taskFunc, tsk, variadicStart) } else { expectedParameterLength := taskFunc.Type().NumIn() if len(tsk.parameters) != expectedParameterLength { return ErrNewJobWrongNumberOfParameters } - - for i := 0; i < expectedParameterLength; i++ { - t1 := reflect.TypeOf(tsk.parameters[i]).Kind() - if t1 == reflect.Interface || t1 == reflect.Pointer { - t1 = reflect.TypeOf(tsk.parameters[i]).Elem().Kind() - } - t2 := reflect.New(taskFunc.Type().In(i)).Elem().Kind() - if t2 == reflect.Interface || t2 == reflect.Pointer { - t2 = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(i))).Kind() - } - if t1 != t2 { - return ErrNewJobWrongTypeOfParameters - } - } + return s.verifyNonVariadic(taskFunc, tsk, expectedParameterLength) } - return nil } func (s *scheduler) addOrUpdateJob(id uuid.UUID, definition JobDefinition, taskWrapper Task, options []JobOption) (Job, error) { diff --git a/scheduler_test.go b/scheduler_test.go index cf7b9a2..52fb8e2 100644 --- a/scheduler_test.go +++ b/scheduler_test.go @@ -909,6 +909,11 @@ func TestScheduler_NewJobTask(t *testing.T) { NewTask(func(args ...string) {}, "one", "two"), nil, }, + { + "all good mixed variadic", + NewTask(func(arg int, args ...string) {}, 1, "one", "two"), + nil, + }, { "all good struct - variadic", NewTask(func(args ...interface{}) {}, struct{}{}),