blob: b9ccdbd5ba226245e993bc6fe8ab9293fb7293e9 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package timeutil
import (
"reflect"
"testing"
"time"
)
func TestTimeutil_StartOfPreviousMonth(t *testing.T) {
testCases := []struct {
Input time.Time
Expected time.Time
}{
{
Input: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
Expected: time.Date(2019, 12, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 15, 0, 0, 0, 0, time.UTC),
Expected: time.Date(2019, 12, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 3, 31, 23, 59, 59, 999999999, time.UTC),
Expected: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
},
}
for _, tc := range testCases {
result := StartOfPreviousMonth(tc.Input)
if !result.Equal(tc.Expected) {
t.Errorf("start of month before %v is %v, got %v", tc.Input, tc.Expected, result)
}
}
}
func TestTimeutil_StartOfMonth(t *testing.T) {
testCases := []struct {
Input time.Time
Expected time.Time
}{
{
Input: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
Expected: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC),
Expected: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 1, 0, 0, 0, 1, time.UTC),
Expected: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 31, 23, 59, 59, 999999999, time.UTC),
Expected: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
Input: time.Date(2020, 2, 28, 1, 2, 3, 4, time.UTC),
Expected: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
},
}
for _, tc := range testCases {
result := StartOfMonth(tc.Input)
if !result.Equal(tc.Expected) {
t.Errorf("start of %v is %v, expected %v", tc.Input, result, tc.Expected)
}
}
}
func TestTimeutil_IsMonthStart(t *testing.T) {
testCases := []struct {
input time.Time
expected bool
}{
{
input: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: true,
},
{
input: time.Date(2020, 1, 1, 0, 0, 0, 1, time.UTC),
expected: false,
},
{
input: time.Date(2020, 4, 5, 0, 0, 0, 0, time.UTC),
expected: false,
},
{
input: time.Date(2020, 1, 31, 23, 59, 59, 999999999, time.UTC),
expected: false,
},
}
for _, tc := range testCases {
result := IsMonthStart(tc.input)
if result != tc.expected {
t.Errorf("is %v the start of the month? expected %t, got %t", tc.input, tc.expected, result)
}
}
}
func TestTimeutil_EndOfMonth(t *testing.T) {
testCases := []struct {
Input time.Time
Expected time.Time
}{
{
// The current behavior does not use the nanoseconds
// because we didn't want to clutter the result of end-of-month reporting.
Input: time.Date(2020, 1, 31, 23, 59, 59, 0, time.UTC),
Expected: time.Date(2020, 1, 31, 23, 59, 59, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 31, 23, 59, 59, 999999999, time.UTC),
Expected: time.Date(2020, 1, 31, 23, 59, 59, 0, time.UTC),
},
{
Input: time.Date(2020, 1, 15, 1, 2, 3, 4, time.UTC),
Expected: time.Date(2020, 1, 31, 23, 59, 59, 0, time.UTC),
},
{
// Leap year
Input: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
Expected: time.Date(2020, 2, 29, 23, 59, 59, 0, time.UTC),
},
{
// non-leap year
Input: time.Date(2100, 2, 1, 0, 0, 0, 0, time.UTC),
Expected: time.Date(2100, 2, 28, 23, 59, 59, 0, time.UTC),
},
}
for _, tc := range testCases {
result := EndOfMonth(tc.Input)
if !result.Equal(tc.Expected) {
t.Errorf("end of %v is %v, expected %v", tc.Input, result, tc.Expected)
}
}
}
func TestTimeutil_IsPreviousMonth(t *testing.T) {
testCases := []struct {
tInput time.Time
compareInput time.Time
expected bool
}{
{
tInput: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
compareInput: time.Date(2020, 1, 31, 0, 0, 0, 0, time.UTC),
expected: false,
},
{
tInput: time.Date(2019, 12, 31, 0, 0, 0, 0, time.UTC),
compareInput: time.Date(2020, 1, 31, 0, 0, 0, 0, time.UTC),
expected: true,
},
{
// leap year (false)
tInput: time.Date(2019, 12, 29, 10, 10, 10, 0, time.UTC),
compareInput: time.Date(2020, 2, 29, 10, 10, 10, 0, time.UTC),
expected: false,
},
{
// leap year (true)
tInput: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
compareInput: time.Date(2020, 2, 29, 10, 10, 10, 0, time.UTC),
expected: true,
},
{
tInput: time.Date(2018, 5, 5, 5, 0, 0, 0, time.UTC),
compareInput: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: false,
},
{
// test normalization. want to make subtracting 1 month from 3/30/2020 doesn't yield 2/30/2020, normalized
// to 3/1/2020
tInput: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
compareInput: time.Date(2020, 3, 30, 0, 0, 0, 0, time.UTC),
expected: true,
},
}
for _, tc := range testCases {
result := IsPreviousMonth(tc.tInput, tc.compareInput)
if result != tc.expected {
t.Errorf("%v in previous month to %v? expected %t, got %t", tc.tInput, tc.compareInput, tc.expected, result)
}
}
}
func TestTimeutil_IsCurrentMonth(t *testing.T) {
now := time.Now()
testCases := []struct {
input time.Time
expected bool
}{
{
input: now,
expected: true,
},
{
input: StartOfMonth(now).AddDate(0, 0, -1),
expected: false,
},
{
input: EndOfMonth(now).AddDate(0, 0, -1),
expected: true,
},
{
input: StartOfMonth(now).AddDate(-1, 0, 0),
expected: false,
},
}
for _, tc := range testCases {
result := IsCurrentMonth(tc.input, now)
if result != tc.expected {
t.Errorf("invalid result. expected %t for %v", tc.expected, tc.input)
}
}
}
func TestTimeUtil_ContiguousMonths(t *testing.T) {
testCases := []struct {
input []time.Time
expected []time.Time
}{
{
input: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 3, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 2, 5, 0, 0, 0, 0, time.UTC),
time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
expected: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 3, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 2, 5, 0, 0, 0, 0, time.UTC),
},
},
{
input: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 3, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
expected: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 3, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
},
},
{
input: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
},
expected: []time.Time{
time.Date(2020, 4, 1, 0, 0, 0, 0, time.UTC),
},
},
{
input: []time.Time{},
expected: []time.Time{},
},
{
input: nil,
expected: nil,
},
{
input: []time.Time{
time.Date(2020, 2, 2, 0, 0, 0, 0, time.UTC),
time.Date(2020, 1, 15, 0, 0, 0, 0, time.UTC),
},
expected: []time.Time{
time.Date(2020, 2, 2, 0, 0, 0, 0, time.UTC),
},
},
}
for _, tc := range testCases {
result := GetMostRecentContiguousMonths(tc.input)
if !reflect.DeepEqual(tc.expected, result) {
t.Errorf("invalid contiguous segment returned. expected %v, got %v", tc.expected, result)
}
}
}
func TestTimeUtil_ParseTimeFromPath(t *testing.T) {
testCases := []struct {
input string
expectedOut time.Time
expectError bool
}{
{
input: "719020800/1",
expectedOut: time.Unix(719020800, 0).UTC(),
expectError: false,
},
{
input: "1601415205/3",
expectedOut: time.Unix(1601415205, 0).UTC(),
expectError: false,
},
{
input: "baddata/3",
expectedOut: time.Time{},
expectError: true,
},
}
for _, tc := range testCases {
result, err := ParseTimeFromPath(tc.input)
gotError := err != nil
if result != tc.expectedOut {
t.Errorf("bad timestamp on input %q. expected: %v got: %v", tc.input, tc.expectedOut, result)
}
if gotError != tc.expectError {
t.Errorf("bad error status on input %q. expected error: %t, got error: %t", tc.input, tc.expectError, gotError)
}
}
}