func TestScheduler_WeekdaysTodayBefore(t *testing.T) {
	scheduler := NewScheduler()
	now := time.Now()
	timeToSchedule := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()+1, 0, 0, time.Local)
	job := callTodaysWeekday(scheduler.Every(1)).At(fmt.Sprintf("%02d:%02d", timeToSchedule.Hour(), timeToSchedule.Minute()))
	job.Do(task)
	t.Logf("job is scheduled for %s", job.NextScheduledTime())
	if !job.NextScheduledTime().Equal(timeToSchedule) {
		t.Error("Job should be run today, at the set time.")
	}
}
This is to ensure that if you schedule a job for today's weekday, and the time hasn't yet passed, the next run time
will be scheduled for today.
package gocron
import (
	"fmt"
	"log"
	"sync"
	"testing"
	"time"
	"github.com/stretchr/testify/assert"
)
func task() {
	fmt.Println("I am a running job.")
}
func taskWithParams(a int, b string) {
	fmt.Println(a, b)
}
func TestSecond(t *testing.T) {
	sched := NewScheduler()
	job := sched.Every(1).Second()
	testJobWithInterval(t, sched, job, 1)
}
func TestSeconds(t *testing.T) {
	sched := NewScheduler()
	job := sched.Every(2).Seconds()
	testJobWithInterval(t, sched, job, 2)
}
func testJobWithInterval(t *testing.T, sched *Scheduler, job *Job, expectedTimeBetweenRuns int64) {
	jobDone := make(chan bool)
	executionTimes := make([]int64, 0)
	numberOfIterations := 2
	job.Do(func() {
		executionTimes = append(executionTimes, time.Now().Unix())
		if len(executionTimes) >= numberOfIterations {
			jobDone <- true
		}
	})
	stop := sched.Start()
	<-jobDone  
	close(stop)
	assert.Equal(t, numberOfIterations, len(executionTimes), "did not run expected number of times")
	for i := 1; i < numberOfIterations; i++ {
		durationBetweenExecutions := executionTimes[i] - executionTimes[i-1]
		assert.Equal(t, expectedTimeBetweenRuns, durationBetweenExecutions, "Duration between tasks does not correspond to expectations")
	}
}
func TestSafeExecution(t *testing.T) {
	sched := NewScheduler()
	success := false
	var wc sync.WaitGroup
	wc.Add(1)
	sched.Every(1).Second().Do(func(mutableValue *bool) {
		*mutableValue = !*mutableValue
		wc.Done()
	}, &success)
	sched.RunAll()
	wc.Wait()
	assert.Equal(t, true, success, "Task did not get called")
}
func TestSafeExecutionWithPanic(t *testing.T) {
	defer func() {
		if r := recover(); r != nil {
			t.Errorf("Unexpected internal panic occurred: %s", r)
		}
	}()
	sched := NewScheduler()
	sched.Every(1).Second().DoSafely(func() {
		log.Panic("I am panicking!")
	})
	sched.RunAll()
}
func TestScheduled(t *testing.T) {
	n := NewScheduler()
	n.Every(1).Second().Do(task)
	if !n.Scheduled(task) {
		t.Fatal("Task was scheduled but function couldn't find it")
	}
}
func TestScheduler_Weekdays(t *testing.T) {
	scheduler := NewScheduler()
	job1 := scheduler.Every(1).Monday().At("23:59")
	job2 := scheduler.Every(1).Wednesday().At("23:59")
	job1.Do(task)
	job2.Do(task)
	t.Logf("job1 scheduled for %s", job1.NextScheduledTime())
	t.Logf("job2 scheduled for %s", job2.NextScheduledTime())
	assert.NotEqual(t, job1.NextScheduledTime(), job2.NextScheduledTime(), "Two jobs scheduled at the same time on two different weekdays should never run at the same time")
}
func TestScheduler_WeekdaysTodayAfter(t *testing.T) {
	scheduler := NewScheduler()
	now := time.Now()
	timeToSchedule := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-1, 0, 0, time.Local)
	job := callTodaysWeekday(scheduler.Every(1)).At(fmt.Sprintf("%02d:%02d", timeToSchedule.Hour(), timeToSchedule.Minute()))
	job.Do(task)
	t.Logf("job is scheduled for %s", job.NextScheduledTime())
	if job.NextScheduledTime().Weekday() != timeToSchedule.Weekday() {
		t.Errorf("Job scheduled for current weekday for earlier time, should still be scheduled for current weekday (but next week)")
	}
	nextWeek := time.Date(now.Year(), now.Month(), now.Day()+7, now.Hour(), now.Minute()-1, 0, 0, time.Local)
	if !job.NextScheduledTime().Equal(nextWeek) {
		t.Errorf("Job should be scheduled for the correct time next week.\nGot %+v, expected %+v", job.NextScheduledTime(), nextWeek)
	}
}
func TestScheduler_JobLocsSetProperly(t *testing.T) {
	defaultScheduledJob := NewJob(10)
	assert.Equal(t, defaultScheduledJob.loc, time.Local)
	defaultScheduledJobFromScheduler := Every(10)
	assert.Equal(t, defaultScheduledJobFromScheduler.loc, time.Local)
	laLocation, err := time.LoadLocation("America/Los_Angeles")
	if err != nil {
		t.Fatalf("unable to load America/Los_Angeles time location")
	}
	ChangeLoc(laLocation)
	modifiedGlobalLocJob := NewJob(10)
	assert.Equal(t, modifiedGlobalLocJob.loc, laLocation)
	modifiedGlobalLocJobFromScheduler := Every(10)
	assert.Equal(t, modifiedGlobalLocJobFromScheduler.loc, laLocation)
	chiLocation, err := time.LoadLocation("America/Chicago")
	if err != nil {
		t.Fatalf("unable to load America/Chicago time location")
	}
	scheduler := NewScheduler()
	scheduler.ChangeLoc(chiLocation)
	modifiedGlobalLocJobFromScheduler = scheduler.Every(10)
	assert.Equal(t, modifiedGlobalLocJobFromScheduler.loc, chiLocation)
	ChangeLoc(time.Local)
}
func TestScheduleNextRunLoc(t *testing.T) {
	laLocation, err := time.LoadLocation("America/Los_Angeles")
	if err != nil {
		t.Fatalf("unable to load America/Los_Angeles time location")
	}
	sched := NewScheduler()
	sched.ChangeLoc(time.UTC)
	job := sched.Every(1).Day().At("20:44")
	today := time.Now().In(laLocation)
	job.lastRun = time.Date(today.Year(), today.Month(), today.Day(), 13, 45, 0, 0, laLocation)
	job.Do(task)
	tomorrow := today.AddDate(0, 0, 1)
	assert.Equal(t, 20, job.NextScheduledTime().UTC().Hour())
	assert.Equal(t, 44, job.NextScheduledTime().UTC().Minute())
	assert.Equal(t, tomorrow.Day(), job.NextScheduledTime().UTC().Day())
}
func TestScheduleNextRunFromNow(t *testing.T) {
	now := time.Now()
	sched := NewScheduler()
	sched.ChangeLoc(time.UTC)
	job := sched.Every(1).Hour().From(NextTick())
	job.Do(task)
	next := job.NextScheduledTime()
	nextRounded := time.Date(next.Year(), next.Month(), next.Day(), next.Hour(), next.Minute(), next.Second(), 0, time.UTC)
	expected := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.UTC).Add(time.Second)
	assert.Exactly(t, expected, nextRounded)
}