github.com/wangyougui/gf/v2@v2.6.5/os/gcron/gcron_z_unit_schedule_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  package gcron
     8  
     9  import (
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/wangyougui/gf/v2/test/gtest"
    15  )
    16  
    17  func TestSlash(t *testing.T) {
    18  	runs := []struct {
    19  		spec     string
    20  		expected map[int]struct{}
    21  	}{
    22  		{"0 0 0 * Feb Mon/2", map[int]struct{}{1: {}, 3: {}, 5: {}}},
    23  		{"0 0 0 * Feb *", map[int]struct{}{1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 0: {}}},
    24  	}
    25  	gtest.C(t, func(t *gtest.T) {
    26  		for _, c := range runs {
    27  			s, err := newSchedule(c.spec)
    28  			if err != nil {
    29  				t.Fatal(err)
    30  
    31  			}
    32  			t.AssertEQ(s.weekMap, c.expected)
    33  		}
    34  	})
    35  }
    36  
    37  func TestNext(t *testing.T) {
    38  	runs := []struct {
    39  		time, spec string
    40  		expected   string
    41  	}{
    42  		// Simple cases
    43  		{"Mon Jul 9 14:45 2012", "0 0/15 * * * *", "Mon Jul 9 15:00 2012"},
    44  		{"Mon Jul 9 14:59 2012", "0 0/15 * * * *", "Mon Jul 9 15:00 2012"},
    45  		{"Mon Jul 9 14:59:59 2012", "0 0/15 * * * *", "Mon Jul 9 15:00 2012"},
    46  
    47  		// Wrap around hours
    48  		{"Mon Jul 9 15:45 2012", "0 20-35/15 * * * *", "Mon Jul 9 16:20 2012"},
    49  
    50  		// Wrap around days
    51  		{"Mon Jul 9 23:46 2012", "0 */15 * * * *", "Tue Jul 10 00:00 2012"},
    52  		{"Mon Jul 9 23:45 2012", "0 20-35/15 * * * *", "Tue Jul 10 00:20 2012"},
    53  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * * * *", "Tue Jul 10 00:20:15 2012"},
    54  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 1/2 * * *", "Tue Jul 10 01:20:15 2012"},
    55  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 10-12 * * *", "Tue Jul 10 10:20:15 2012"},
    56  
    57  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 1/2 */2 * *", "Thu Jul 11 01:20:15 2012"},
    58  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * 9-20 * *", "Wed Jul 10 00:20:15 2012"},
    59  		{"Mon Jul 9 23:35:51 2012", "15/35 20-35/15 * 9-20 Jul *", "Wed Jul 10 00:20:15 2012"},
    60  
    61  		// Wrap around months
    62  		{"Mon Jul 9 23:35 2012", "0 0 0 9 Apr-Oct ?", "Thu Aug 9 00:00 2012"},
    63  		{"Mon Jul 9 23:35 2012", "0 0 0 */5 Apr,Aug,Oct Mon", "Mon Aug 6 00:00 2012"},
    64  		{"Mon Jul 9 23:35 2012", "0 0 0 */5 Oct Mon", "Mon Oct 1 00:00 2012"},
    65  
    66  		// Wrap around years
    67  		{"Mon Jul 9 23:35 2012", "0 0 0 * Feb Mon", "Mon Feb 4 00:00 2013"},
    68  		{"Mon Jul 9 23:35 2012", "0 0 0 * Feb Mon/2", "Fri Feb 1 00:00 2013"},
    69  
    70  		// Wrap around minute, hour, day, month, and year
    71  		{"Mon Dec 31 23:59:45 2012", "0 * * * * *", "Tue Jan 1 00:00:00 2013"},
    72  
    73  		// Leap year
    74  		{"Mon Jul 9 23:35 2012", "0 0 0 29 Feb ?", "Mon Feb 29 00:00 2016"},
    75  
    76  		// Predefined pattern map.
    77  		{"Mon Jul 9 23:35 2012", "@yearly", "Sun Jan 1 00:00:00 2013"},
    78  		{"Mon Jul 9 23:35 2012", "@annually", "Sun Jan 1 00:00:00 2013"},
    79  		{"Mon Jul 9 23:35 2012", "@monthly", "Mon Aug 1 00:00:00 2012"},
    80  		{"Mon Jul 9 23:35 2012", "@weekly", "Sun Jul 15 00:00:00 2012"},
    81  		{"Mon Jul 9 23:35 2012", "@daily", "Tue Jul 10 00:00:00 2012"},
    82  		{"Mon Jul 9 23:35 2012", "@midnight", "Tue Jul 10 00:00:00 2012"},
    83  		{"Mon Jul 9 23:35 2012", "@hourly", "Tue Jul 10 00:00:00 2012"},
    84  
    85  		// Ignore seconds.
    86  		{"Mon Jul 9 23:35 2012", "# * * * * *", "Mon Jul 9 23:36 2012"},
    87  		{"Mon Jul 9 23:35 2012", "# */2 * * * *", "Mon Jul 9 23:36 2012"},
    88  	}
    89  
    90  	for _, c := range runs {
    91  		s, err := newSchedule(c.spec)
    92  		if err != nil {
    93  			t.Error(err)
    94  			continue
    95  		}
    96  		// fmt.Printf("%+v", sched)
    97  		actual := s.Next(getTime(c.time))
    98  		expected := getTime(c.expected)
    99  		if !(actual.Unix() == expected.Unix()) {
   100  			t.Errorf(
   101  				"%s, \"%s\": (expected) %v != %v (actual)",
   102  				c.time, c.spec, expected, actual,
   103  			)
   104  		}
   105  	}
   106  }
   107  
   108  func getTime(value string) time.Time {
   109  	if value == "" {
   110  		return time.Time{}
   111  	}
   112  
   113  	var location = time.Local
   114  	if strings.HasPrefix(value, "TZ=") {
   115  		parts := strings.Fields(value)
   116  		loc, err := time.LoadLocation(parts[0][len("TZ="):])
   117  		if err != nil {
   118  			panic("could not parse location:" + err.Error())
   119  		}
   120  		location = loc
   121  		value = parts[1]
   122  	}
   123  
   124  	var layouts = []string{
   125  		"Mon Jan 2 15:04 2006",
   126  		"Mon Jan 2 15:04:05 2006",
   127  	}
   128  	for _, layout := range layouts {
   129  		if t, err := time.ParseInLocation(layout, value, location); err == nil {
   130  			return t
   131  		}
   132  	}
   133  	if t, err := time.ParseInLocation("2006-01-02T15:04:05-0700", value, location); err == nil {
   134  		return t
   135  	}
   136  	panic("could not parse time value " + value)
   137  }