github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/date/date_test.go (about)

     1  // Copyright 2012 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //  created by Manoel Vilela (manoel_vilela@engineer.com)
     6  
     7  package main
     8  
     9  import (
    10  	"bytes"
    11  	"flag"
    12  	"os"
    13  	"regexp"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  // without any flag
    20  func TestDateNoFlags(t *testing.T) {
    21  	t.Log("::  Printing date with default location (no flags)...")
    22  	n := time.Now()
    23  	d := date(n, time.Local)
    24  	t.Logf("Date: %v\n", d)
    25  	dParsed, err := time.Parse(time.UnixDate, d)
    26  	if err != nil {
    27  		t.Error(err)
    28  	}
    29  	dTest := dParsed.Format(time.UnixDate)
    30  	if d != dTest {
    31  		t.Errorf("Mismatched dates; want %v, got %v\n", d, dTest)
    32  	}
    33  }
    34  
    35  // using u flag
    36  func TestDateUniversal(t *testing.T) {
    37  	t.Log("::  Printing date with UTC (using -u flag)...")
    38  	n := time.Now()
    39  	d := date(n, time.UTC)
    40  	t.Logf("Date: %v\n", d)
    41  	dParsed, err := time.Parse(time.UnixDate, d)
    42  	if err != nil {
    43  		t.Error(err)
    44  	}
    45  	dTest := dParsed.Format(time.UnixDate)
    46  	if d != dTest {
    47  		t.Errorf("Mismatched dates; want %v, got %v\n", d, dTest)
    48  	}
    49  }
    50  
    51  func TestFormatParser(t *testing.T) {
    52  	test := "%d %w %x %D %% asdf qwer qwe s sd fqwer % qwer"
    53  	expected := []string{"%d", "%w", "%x", "%D"}
    54  	t.Log(":: Test of FormatParser greping the n flags")
    55  	for index, match := range formatParser(test) {
    56  		t.Logf(":: Parsed on iteration %d: %v", index, match)
    57  		if match != expected[index] {
    58  			t.Errorf("Parsing Error; Want %v, got %v\n", expected[index], match)
    59  		}
    60  	}
    61  }
    62  
    63  func TestDateMap(t *testing.T) {
    64  	t.Log(":: Test of DateMap formatting")
    65  	posixFormat := "%a %b %e %H:%M:%S %Z %Y"
    66  	n := time.Now()
    67  	test := dateMap(n, time.Local, posixFormat)
    68  	expected := n.Format(time.UnixDate)
    69  
    70  	if test != expected {
    71  		t.Errorf("Mismatch outputs; \nwant %v, \n got %v", expected, test)
    72  	}
    73  }
    74  
    75  func TestDateMapExamples(t *testing.T) {
    76  	type dateTest struct {
    77  		format  string // format flags
    78  		example string // correct example
    79  	}
    80  
    81  	tests := []dateTest{
    82  		{
    83  			"%a %b %e %H:%M:%S %Z %Y",
    84  			"Tue Jun 26 09:58:10 PDT 1990",
    85  		},
    86  		{
    87  			"DATE: %m/%d/%y%nTIME: %H:%M:%S",
    88  			"DATE: 11/02/91\nTIME: 13:36:16",
    89  		},
    90  		{
    91  			"TIME: %r",
    92  			"TIME: 01:36:32 PM",
    93  		},
    94  	}
    95  
    96  	t.Log(":: Sequence of examples for dateMap")
    97  	n := time.Now()
    98  	for _, test := range tests {
    99  		t.Logf(" Format: \n%v\n", test.format)
   100  		t.Logf("Example: \n%v\n", test.example)
   101  		t.Logf(" Output: \n%v\n", dateMap(n, time.Local, test.format))
   102  	}
   103  }
   104  
   105  func TestRun(t *testing.T) {
   106  	testfile, err := os.CreateTemp("", "testfile-for-modtime")
   107  	if err != nil {
   108  		t.Errorf("Unable to create testile-for-modtime: %q", err)
   109  	}
   110  	testfile.Close()
   111  	defer os.RemoveAll(testfile.Name())
   112  	fileStats, err := os.Stat(testfile.Name())
   113  	if err != nil {
   114  		t.Errorf("Unable to get testile-for-modtim stats: %q", err)
   115  	}
   116  	modTime := fileStats.ModTime().In(time.UTC).Format(time.UnixDate)
   117  	for _, tt := range []struct {
   118  		name    string
   119  		arg     []string
   120  		univ    bool
   121  		fileref string
   122  		expExp  string
   123  		wantErr string
   124  	}{
   125  		{
   126  			name:    "Time Now UTC",
   127  			arg:     make([]string, 0),
   128  			univ:    true,
   129  			fileref: "",
   130  		},
   131  		{
   132  			name:    "Time Now Local",
   133  			arg:     make([]string, 0),
   134  			univ:    false,
   135  			fileref: "",
   136  		},
   137  		{
   138  			name:    "Now Format+%C",
   139  			arg:     []string{"+%C"},
   140  			univ:    true,
   141  			fileref: "",
   142  			expExp:  "\\d{1,2}",
   143  		},
   144  		{
   145  			name:    "Now Format+%D",
   146  			arg:     []string{"+%D"},
   147  			univ:    true,
   148  			fileref: "",
   149  			expExp:  "\\d{1,2}\\D\\d{1,2}\\D\\d{1,2}",
   150  		},
   151  		{
   152  			name:    "Now Format+%j",
   153  			arg:     []string{"+%j"},
   154  			univ:    true,
   155  			fileref: "",
   156  			expExp:  "\\d*",
   157  		},
   158  		{
   159  			name:    "Now Format+%r",
   160  			arg:     []string{"+%r"},
   161  			univ:    true,
   162  			fileref: "",
   163  			expExp:  "\\d{1,2}\\D\\d{1,2}\\D\\d{1,2}\\s[A,M|P,M]",
   164  		},
   165  		{
   166  			name:    "Now Format+'%'T",
   167  			arg:     []string{"+%T"},
   168  			univ:    true,
   169  			fileref: "",
   170  			expExp:  "\\d\\d\\D\\d\\d\\D\\d\\d",
   171  		},
   172  		{
   173  			name:    "Now Format+%W",
   174  			arg:     []string{"+%W"},
   175  			univ:    true,
   176  			fileref: "",
   177  			expExp:  "\\d{1,2}",
   178  		},
   179  		{
   180  			name:    "Now Format+'%'w",
   181  			arg:     []string{"+%w"},
   182  			univ:    true,
   183  			fileref: "",
   184  			expExp:  "\\d",
   185  		},
   186  		{
   187  			name:    "Now Format+%V",
   188  			arg:     []string{"+%V"},
   189  			univ:    true,
   190  			fileref: "",
   191  			expExp:  "\\d{1,2}",
   192  		},
   193  		{
   194  			name:    "Now Format+'%'x",
   195  			arg:     []string{"+%x"},
   196  			univ:    true,
   197  			fileref: "",
   198  			expExp:  "\\d{0,2}\\D\\d{0,2}\\D\\d{1,2}",
   199  		},
   200  		{
   201  			name:    "Now Format+'%'F",
   202  			arg:     []string{"+%F"},
   203  			univ:    true,
   204  			fileref: "",
   205  			expExp:  "\\d\\d\\D\\d*\\d\\D\\d\\d",
   206  		},
   207  		{
   208  			name:    "Now Format+'%'X",
   209  			arg:     []string{"+%X"},
   210  			univ:    true,
   211  			fileref: "",
   212  			expExp:  "\\d{0,2}\\D\\d{0,2}\\D\\d{1,2}\\s[A,M|P,M]",
   213  		},
   214  		{
   215  			name:    "Now Format+'%'X'%'t",
   216  			arg:     []string{"+%X%t"},
   217  			univ:    true,
   218  			fileref: "",
   219  			expExp:  "\\d{0,2}\\D\\d{0,2}\\D\\d{1,2}\\s[A,M|P,M]",
   220  		},
   221  		{
   222  			name:    "File modification time",
   223  			univ:    true,
   224  			fileref: testfile.Name(),
   225  			expExp:  modTime,
   226  		},
   227  		{
   228  			name:    "File modification time fail",
   229  			univ:    true,
   230  			fileref: "not-existing-test-file",
   231  			wantErr: "unable to gather stats of file",
   232  		},
   233  		{
   234  			name: "flag usage",
   235  			arg:  []string{"This", "dont", "work"},
   236  		},
   237  	} {
   238  		t.Run(tt.name, func(t *testing.T) {
   239  			var buf bytes.Buffer
   240  			rc := RealClock{}
   241  			// Avoid spamming our CI with errors -- we don't
   242  			// look at error output (yet), but when we do, this
   243  			// bytes.Buffer will make it more convenient.
   244  			var stderr bytes.Buffer
   245  			flag.CommandLine.SetOutput(&stderr)
   246  			if err := run(tt.arg, tt.univ, tt.fileref, rc, &buf); err != nil {
   247  				if !strings.Contains(err.Error(), tt.wantErr) {
   248  					t.Errorf("%q failed: %q", tt.name, err)
   249  				}
   250  				return
   251  			}
   252  			outString := buf.String()
   253  			match, err := regexp.MatchString(tt.expExp, outString)
   254  			if err != nil {
   255  				t.Error(err)
   256  			}
   257  			if !match {
   258  				t.Errorf("%q faile. Format of Got: %q, Want: %q", tt.name, outString, tt.expExp)
   259  			}
   260  		})
   261  	}
   262  }
   263  
   264  type fakeClock struct {
   265  	time.Time
   266  }
   267  
   268  func (f fakeClock) Now() time.Time {
   269  	return f.Time
   270  }
   271  
   272  func TestGetTime(t *testing.T) {
   273  	for _, tt := range []struct {
   274  		name      string
   275  		time      string
   276  		wantYear  int
   277  		wantMonth time.Month
   278  		wantDay   int
   279  		wantHour  int
   280  		wantMin   int
   281  		wantSec   int
   282  		wantNsec  int
   283  		location  *time.Location
   284  		wantErr   string
   285  	}{
   286  		{
   287  			name:      "WithoutOpt",
   288  			time:      "11220405",
   289  			wantYear:  time.Now().Year(),
   290  			wantMonth: time.Month(11),
   291  			wantDay:   22,
   292  			wantHour:  4,
   293  			wantMin:   05,
   294  			wantSec:   0,
   295  			location:  time.Local,
   296  		},
   297  		{
   298  			name:      "WithOpt-2",
   299  			time:      "1122040520",
   300  			wantYear:  2020,
   301  			wantMonth: time.Month(11),
   302  			wantDay:   22,
   303  			wantHour:  4,
   304  			wantMin:   05,
   305  			wantSec:   0,
   306  			location:  time.Local,
   307  		},
   308  		{
   309  			name:      "WithOpt-3",
   310  			time:      "11220405202",
   311  			wantYear:  time.Now().Year(),
   312  			wantMonth: time.Month(11),
   313  			wantDay:   22,
   314  			wantHour:  4,
   315  			wantMin:   05,
   316  			wantSec:   02,
   317  			location:  time.Local,
   318  		},
   319  		{
   320  			name:      "WithOpt-4",
   321  			time:      "112204052022",
   322  			wantYear:  2022,
   323  			wantMonth: time.Month(11),
   324  			wantDay:   22,
   325  			wantHour:  4,
   326  			wantMin:   5,
   327  			wantSec:   0,
   328  			location:  time.Local,
   329  		},
   330  		{
   331  			name:      "WithOpt-5",
   332  			time:      "1122040520221",
   333  			wantYear:  2020,
   334  			wantMonth: time.Month(11),
   335  			wantDay:   22,
   336  			wantHour:  4,
   337  			wantMin:   5,
   338  			wantSec:   21,
   339  			location:  time.UTC,
   340  		},
   341  		{
   342  			name:      "WithOpt-all",
   343  			time:      "112204052022.55",
   344  			wantYear:  2022,
   345  			wantMonth: time.Month(11),
   346  			wantDay:   22,
   347  			wantHour:  4,
   348  			wantMin:   5,
   349  			wantSec:   55,
   350  			location:  time.Local,
   351  		},
   352  		{
   353  			name:     "WithOpt-all",
   354  			time:     "11223344201135",
   355  			location: time.Local,
   356  			wantErr:  "instead of [[CC]YY][.ss]",
   357  		},
   358  	} {
   359  		t.Run(tt.name, func(t *testing.T) {
   360  			fc := fakeClock{}
   361  			fc.Time = time.Date(tt.wantYear, time.Month(tt.wantMonth), tt.wantDay, tt.wantHour, tt.wantMin, tt.wantSec, tt.wantNsec, tt.location)
   362  			testTime, err := getTime(tt.location, tt.time, fc)
   363  			if err != nil {
   364  				if !strings.Contains(err.Error(), tt.wantErr) {
   365  					t.Errorf("%q failed. Got: %q, Want: %q", tt.name, err, tt.wantErr)
   366  				}
   367  			}
   368  			if err == nil && !strings.Contains(fc.Time.String(), testTime.String()) {
   369  				t.Errorf("test %q failed. Got: %q, Want: %q", tt.name, testTime, fc.Time.String())
   370  			}
   371  		})
   372  	}
   373  }