move and rename common/time.go (#3215)

moves common/time.go to common/dttm/dttm.go, and renames many of the consts and funcs with names that better explain their design and intent of usage.

Only code movement, no logical changes.

---

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

- [x] 🧹 Tech Debt/Cleanup

#### Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-05-02 13:39:29 -06:00 committed by GitHub
parent 8cca7f12df
commit c152ce8b25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 252 additions and 251 deletions

View File

@ -9,7 +9,7 @@ import (
"github.com/alcionai/corso/src/cli/options" "github.com/alcionai/corso/src/cli/options"
. "github.com/alcionai/corso/src/cli/print" . "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
) )
@ -95,7 +95,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
defer utils.CloseRepo(ctx, r) defer utils.CloseRepo(ctx, r)
dest := control.DefaultRestoreDestination(common.SimpleDateTime) dest := control.DefaultRestoreDestination(dttm.HumanReadable)
Infof(ctx, "Restoring to folder %s", dest.ContainerName) Infof(ctx, "Restoring to folder %s", dest.ContainerName)
sel := utils.IncludeExchangeRestoreDataSelectors(opts) sel := utils.IncludeExchangeRestoreDataSelectors(opts)

View File

@ -9,7 +9,7 @@ import (
"github.com/alcionai/corso/src/cli/options" "github.com/alcionai/corso/src/cli/options"
. "github.com/alcionai/corso/src/cli/print" . "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
) )
@ -97,7 +97,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
defer utils.CloseRepo(ctx, r) defer utils.CloseRepo(ctx, r)
dest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive) dest := control.DefaultRestoreDestination(dttm.HumanReadableDriveItem)
Infof(ctx, "Restoring to folder %s", dest.ContainerName) Infof(ctx, "Restoring to folder %s", dest.ContainerName)
sel := utils.IncludeOneDriveRestoreDataSelectors(opts) sel := utils.IncludeOneDriveRestoreDataSelectors(opts)

View File

@ -9,7 +9,7 @@ import (
"github.com/alcionai/corso/src/cli/options" "github.com/alcionai/corso/src/cli/options"
. "github.com/alcionai/corso/src/cli/print" . "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
) )
@ -96,7 +96,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
defer utils.CloseRepo(ctx, r) defer utils.CloseRepo(ctx, r)
dest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive) dest := control.DefaultRestoreDestination(dttm.HumanReadableDriveItem)
Infof(ctx, "Restoring to folder %s", dest.ContainerName) Infof(ctx, "Restoring to folder %s", dest.ContainerName)
sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts) sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts)

View File

@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
) )
@ -42,7 +42,7 @@ func (suite *ExchangeUtilsSuite) TestValidateRestoreFlags() {
{ {
name: "valid time", name: "valid time",
backupID: "bid", backupID: "bid",
opts: utils.ExchangeOpts{EmailReceivedAfter: common.Now()}, opts: utils.ExchangeOpts{EmailReceivedAfter: dttm.Now()},
expect: assert.NoError, expect: assert.NoError,
}, },
{ {

View File

@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
) )
@ -198,7 +198,7 @@ func GetPopulatedFlags(cmd *cobra.Command) PopulatedFlags {
// IsValidTimeFormat returns true if the input is recognized as a // IsValidTimeFormat returns true if the input is recognized as a
// supported format by the common time parser. // supported format by the common time parser.
func IsValidTimeFormat(in string) bool { func IsValidTimeFormat(in string) bool {
_, err := common.ParseTime(in) _, err := dttm.ParseTime(in)
return err == nil return err == nil
} }

View File

@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
) )
@ -280,10 +280,10 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
WebURL: []string{"www.corsobackup.io/sites/foo"}, WebURL: []string{"www.corsobackup.io/sites/foo"},
FileCreatedAfter: common.Now(), FileCreatedAfter: dttm.Now(),
FileCreatedBefore: common.Now(), FileCreatedBefore: dttm.Now(),
FileModifiedAfter: common.Now(), FileModifiedAfter: dttm.Now(),
FileModifiedBefore: common.Now(), FileModifiedBefore: dttm.Now(),
Populated: utils.PopulatedFlags{ Populated: utils.PopulatedFlags{
utils.SiteFN: {}, utils.SiteFN: {},
utils.FileCreatedAfterFN: {}, utils.FileCreatedAfterFN: {},

View File

@ -7,7 +7,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/backup" "github.com/alcionai/corso/src/pkg/backup"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/backup/details/testdata" "github.com/alcionai/corso/src/pkg/backup/details/testdata"
@ -195,7 +195,7 @@ var (
Name: "MailReceivedTime", Name: "MailReceivedTime",
Expected: []details.Entry{testdata.ExchangeEmailItems[0]}, Expected: []details.Entry{testdata.ExchangeEmailItems[0]},
Opts: utils.ExchangeOpts{ Opts: utils.ExchangeOpts{
EmailReceivedBefore: common.FormatTime(testdata.Time1.Add(time.Second)), EmailReceivedBefore: dttm.Format(testdata.Time1.Add(time.Second)),
}, },
}, },
{ {
@ -430,7 +430,7 @@ var (
Name: "CreatedBefore", Name: "CreatedBefore",
Expected: []details.Entry{testdata.OneDriveItems[1]}, Expected: []details.Entry{testdata.OneDriveItems[1]},
Opts: utils.OneDriveOpts{ Opts: utils.OneDriveOpts{
FileCreatedBefore: common.FormatTime(testdata.Time1.Add(time.Second)), FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)),
}, },
}, },
} }
@ -556,7 +556,7 @@ var (
// Name: "CreatedBefore", // Name: "CreatedBefore",
// Expected: []details.DetailsEntry{testdata.SharePointLibraryItems[1]}, // Expected: []details.DetailsEntry{testdata.SharePointLibraryItems[1]},
// Opts: utils.SharePointOpts{ // Opts: utils.SharePointOpts{
// FileCreatedBefore: common.FormatTime(testdata.Time1.Add(time.Second)), // FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)),
// }, // },
// }, // },
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector" "github.com/alcionai/corso/src/internal/connector"
@ -68,8 +69,8 @@ func generateAndRestoreItems(
for i := 0; i < howMany; i++ { for i := 0; i < howMany; i++ {
var ( var (
now = common.Now() now = dttm.Now()
nowLegacy = common.FormatLegacyTime(time.Now()) nowLegacy = dttm.FormatToLegacy(time.Now())
id = uuid.NewString() id = uuid.NewString()
subject = "automated " + now[:16] + " - " + id[:8] subject = "automated " + now[:16] + " - " + id[:8]
body = "automated " + cat.String() + " generation for " + userID + " at " + now + " - " + id body = "automated " + cat.String() + " generation for " + userID + " at " + now + " - " + id
@ -87,7 +88,7 @@ func generateAndRestoreItems(
items: items, items: items,
}} }}
dest := control.DefaultRestoreDestination(common.SimpleTimeTesting) dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
dest.ContainerName = destFldr dest.ContainerName = destFldr
print.Infof(ctx, "Restoring to folder %s", dest.ContainerName) print.Infof(ctx, "Restoring to folder %s", dest.ContainerName)
@ -269,7 +270,7 @@ func generateAndRestoreOnedriveItems(
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
defer flush() defer flush()
dest := control.DefaultRestoreDestination(common.SimpleTimeTesting) dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
dest.ContainerName = destFldr dest.ContainerName = destFldr
print.Infof(ctx, "Restoring to folder %s", dest.ContainerName) print.Infof(ctx, "Restoring to folder %s", dest.ContainerName)

View File

@ -12,6 +12,7 @@ import (
. "github.com/alcionai/corso/src/cli/print" . "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/connector" "github.com/alcionai/corso/src/internal/connector"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/onedrive" "github.com/alcionai/corso/src/internal/connector/onedrive"
@ -226,8 +227,8 @@ func purgeFolders(
// compare the folder time to the deletion boundary time first // compare the folder time to the deletion boundary time first
displayName := *fld.GetDisplayName() displayName := *fld.GetDisplayName()
dnTime, err := common.ExtractTime(displayName) dnTime, err := dttm.ExtractTime(displayName)
if err != nil && !errors.Is(err, common.ErrNoTimeString) { if err != nil && !errors.Is(err, dttm.ErrNoTimeString) {
err = clues.Wrap(err, "!! Error: parsing container: "+displayName) err = clues.Wrap(err, "!! Error: parsing container: "+displayName)
Info(ctx, err) Info(ctx, err)
@ -282,7 +283,7 @@ func getBoundaryTime(ctx context.Context) (time.Time, error) {
) )
if len(before) > 0 { if len(before) > 0 {
boundaryTime, err = common.ParseTime(before) boundaryTime, err = dttm.ParseTime(before)
if err != nil { if err != nil {
return time.Time{}, Only(ctx, clues.Wrap(err, "parsing before flag to time")) return time.Time{}, Only(ctx, clues.Wrap(err, "parsing before flag to time"))
} }

View File

@ -15,7 +15,7 @@ import (
"github.com/microsoftgraph/msgraph-sdk-go/users" "github.com/microsoftgraph/msgraph-sdk-go/users"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -644,12 +644,12 @@ func fatal(ctx context.Context, msg string, err error) {
} }
func mustGetTimeFromName(ctx context.Context, name string) (time.Time, bool) { func mustGetTimeFromName(ctx context.Context, name string) (time.Time, bool) {
t, err := common.ExtractTime(name) t, err := dttm.ExtractTime(name)
if err != nil && !errors.Is(err, common.ErrNoTimeString) { if err != nil && !errors.Is(err, dttm.ErrNoTimeString) {
fatal(ctx, "extracting time from name: "+name, err) fatal(ctx, "extracting time from name: "+name, err)
} }
return t, !errors.Is(err, common.ErrNoTimeString) return t, !errors.Is(err, dttm.ErrNoTimeString)
} }
func isWithinTimeBound(ctx context.Context, bound, check time.Time, hasTime bool) bool { func isWithinTimeBound(ctx context.Context, bound, check time.Time, hasTime bool) bool {

View File

@ -1,4 +1,4 @@
package common package dttm
import ( import (
"regexp" "regexp"
@ -10,8 +10,8 @@ import (
type TimeFormat string type TimeFormat string
const ( const (
// StandardTime is the canonical format used for all data storage in corso // Standard is the canonical format used for all data storage in corso
StandardTime TimeFormat = time.RFC3339Nano Standard TimeFormat = time.RFC3339Nano
// DateOnly is accepted by the CLI as a valid input for timestamp-based // DateOnly is accepted by the CLI as a valid input for timestamp-based
// filters. Time and timezone are assumed to be 00:00:00 and UTC. // filters. Time and timezone are assumed to be 00:00:00 and UTC.
@ -21,23 +21,23 @@ const (
// non-json cli outputs. // non-json cli outputs.
TabularOutput TimeFormat = "2006-01-02T15:04:05Z" TabularOutput TimeFormat = "2006-01-02T15:04:05Z"
// LegacyTime is used in /exchange/service_restore to comply with certain // Legacy is used in /exchange/service_restore to comply with certain
// graphAPI time format requirements. // graphAPI time format requirements.
LegacyTime TimeFormat = time.RFC3339 Legacy TimeFormat = time.RFC3339
// SimpleDateTime is the default value appended to the root restoration folder name. // HumanReadable is the default value appended to the root restoration folder name.
SimpleDateTime TimeFormat = "02-Jan-2006_15:04:05" HumanReadable TimeFormat = "02-Jan-2006_15:04:05"
// SimpleDateTimeOneDrive modifies SimpleDateTimeFormat to comply with onedrive folder // HumanReadableDriveItem modifies SimpleDateTimeFormat to comply with onedrive folder
// restrictions: primarily swapping `-` instead of `:` which is a reserved character. // restrictions: primarily swapping `-` instead of `:` which is a reserved character.
SimpleDateTimeOneDrive TimeFormat = "02-Jan-2006_15-04-05" HumanReadableDriveItem TimeFormat = "02-Jan-2006_15-04-05"
// m365 will remove the :00 second suffix on folder names, resulting in the following formats. // m365 will remove the :00 second suffix on folder names, resulting in the following formats.
ClippedSimple TimeFormat = "02-Jan-2006_15:04" ClippedHuman TimeFormat = "02-Jan-2006_15:04"
ClippedSimpleOneDrive TimeFormat = "02-Jan-2006_15-04" ClippedHumanDriveItem TimeFormat = "02-Jan-2006_15-04"
// SimpleTimeTesting is used for testing restore destination folders. // SafeForTesting is used for testing restore destination folders.
// Microsecond granularity prevents collisions in parallel package or workflow runs. // Microsecond granularity prevents collisions in parallel package or workflow runs.
SimpleTimeTesting TimeFormat = SimpleDateTimeOneDrive + ".000000" SafeForTesting TimeFormat = HumanReadableDriveItem + ".000000"
// M365dateTimeTimeZoneTimeFormat is the format used by M365 for datetimetimezone resource // M365dateTimeTimeZoneTimeFormat is the format used by M365 for datetimetimezone resource
// https://learn.microsoft.com/en-us/graph/api/resources/datetimetimezone?view=graph-rest-1.0 // https://learn.microsoft.com/en-us/graph/api/resources/datetimetimezone?view=graph-rest-1.0
@ -48,42 +48,42 @@ const (
// identify the folders produced in external data during automated testing. For safety, each // identify the folders produced in external data during automated testing. For safety, each
// time format described above should have a matching regexp. // time format described above should have a matching regexp.
var ( var (
clippedSimpleRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}).*`) clippedHumanRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}).*`)
clippedSimpleOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}).*`) clippedHumanOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}).*`)
dateOnlyRE = regexp.MustCompile(`.*(\d{4}-\d{2}-\d{2}).*`) dateOnlyRE = regexp.MustCompile(`.*(\d{4}-\d{2}-\d{2}).*`)
legacyTimeRE = regexp.MustCompile( legacyRE = regexp.MustCompile(
`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`) `.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`)
simpleTimeTestingRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}-\d{2}.\d{6}).*`) SafeForTestingRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}-\d{2}.\d{6}).*`)
simpleDateTimeRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}:\d{2}).*`) HumanReadableRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}:\d{2}).*`)
simpleDateTimeOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}-\d{2}).*`) HumanReadableOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}-\d{2}).*`)
standardTimeRE = regexp.MustCompile( standardRE = regexp.MustCompile(
`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`) `.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`)
tabularOutputTimeRE = regexp.MustCompile(`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([Zz]|[a-zA-Z]{2})).*`) tabularOutputRE = regexp.MustCompile(`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([Zz]|[a-zA-Z]{2})).*`)
) )
var ( var (
// shortened formats (clipped*, DateOnly) must follow behind longer formats, otherwise they'll // shortened formats (clipped*, DateOnly) must follow behind longer formats, otherwise they'll
// get eagerly chosen as the parsable format, slicing out some data. // get eagerly chosen as the parsable format, slicing out some data.
formats = []TimeFormat{ formats = []TimeFormat{
StandardTime, Standard,
SimpleTimeTesting, SafeForTesting,
SimpleDateTime, HumanReadable,
SimpleDateTimeOneDrive, HumanReadableDriveItem,
LegacyTime, Legacy,
TabularOutput, TabularOutput,
ClippedSimple, ClippedHuman,
ClippedSimpleOneDrive, ClippedHumanDriveItem,
DateOnly, DateOnly,
} }
regexes = []*regexp.Regexp{ regexes = []*regexp.Regexp{
standardTimeRE, standardRE,
simpleTimeTestingRE, SafeForTestingRE,
simpleDateTimeRE, HumanReadableRE,
simpleDateTimeOneDriveRE, HumanReadableOneDriveRE,
legacyTimeRE, legacyRE,
tabularOutputTimeRE, tabularOutputRE,
clippedSimpleRE, clippedHumanRE,
clippedSimpleOneDriveRE, clippedHumanOneDriveRE,
dateOnlyRE, dateOnlyRE,
} }
) )
@ -95,43 +95,43 @@ var (
// Now produces the current time as a string in the standard format. // Now produces the current time as a string in the standard format.
func Now() string { func Now() string {
return FormatNow(StandardTime) return FormatNow(Standard)
} }
// FormatNow produces the current time in UTC using the provided // FormatNow produces the current time in UTC using the provided
// time format. // time format.
func FormatNow(fmt TimeFormat) string { func FormatNow(fmt TimeFormat) string {
return FormatTimeWith(time.Now(), fmt) return FormatTo(time.Now(), fmt)
} }
// FormatTimeWith produces the a datetime with the given format. // FormatTo produces the a datetime with the given format.
func FormatTimeWith(t time.Time, fmt TimeFormat) string { func FormatTo(t time.Time, fmt TimeFormat) string {
return t.UTC().Format(string(fmt)) return t.UTC().Format(string(fmt))
} }
// FormatTime produces the standard format for corso time values. // Format produces the standard format for corso time values.
// Always formats into the UTC timezone. // Always formats into the UTC timezone.
func FormatTime(t time.Time) string { func Format(t time.Time) string {
return FormatTimeWith(t, StandardTime) return FormatTo(t, Standard)
} }
// FormatSimpleDateTime produces a simple datetime of the format // FormatToHumanReadable produces a simple datetime of the format
// "02-Jan-2006_15:04:05" // "02-Jan-2006_15:04:05"
func FormatSimpleDateTime(t time.Time) string { func FormatToHumanReadable(t time.Time) string {
return FormatTimeWith(t, SimpleDateTime) return FormatTo(t, HumanReadable)
} }
// FormatTabularDisplayTime produces the standard format for displaying // FormatToTabularDisplay produces the standard format for displaying
// a timestamp as part of user-readable cli output. // a timestamp as part of user-readable cli output.
// "2016-01-02T15:04:05Z" // "2016-01-02T15:04:05Z"
func FormatTabularDisplayTime(t time.Time) string { func FormatToTabularDisplay(t time.Time) string {
return FormatTimeWith(t, TabularOutput) return FormatTo(t, TabularOutput)
} }
// FormatLegacyTime produces standard format for string values // FormatToLegacy produces standard format for string values
// that are placed in SingleValueExtendedProperty tags // that are placed in SingleValueExtendedProperty tags
func FormatLegacyTime(t time.Time) string { func FormatToLegacy(t time.Time) string {
return FormatTimeWith(t, LegacyTime) return FormatTo(t, Legacy)
} }
// ParseTime makes a best attempt to produce a time value from // ParseTime makes a best attempt to produce a time value from

View File

@ -1,4 +1,4 @@
package common_test package dttm_test
import ( import (
"testing" "testing"
@ -9,65 +9,64 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
) )
type CommonTimeUnitSuite struct { type DTTMUnitSuite struct {
tester.Suite tester.Suite
} }
func TestCommonTimeUnitSuite(t *testing.T) { func TestDTTMUnitSuite(t *testing.T) {
s := &CommonTimeUnitSuite{Suite: tester.NewUnitSuite(t)} suite.Run(t, &DTTMUnitSuite{Suite: tester.NewUnitSuite(t)})
suite.Run(t, s)
} }
func (suite *CommonTimeUnitSuite) TestFormatTime() { func (suite *DTTMUnitSuite) TestFormatTime() {
t := suite.T() t := suite.T()
now := time.Now() now := time.Now()
result := common.FormatTime(now) result := dttm.Format(now)
assert.Equal(t, now.UTC().Format(time.RFC3339Nano), result) assert.Equal(t, now.UTC().Format(time.RFC3339Nano), result)
} }
func (suite *CommonTimeUnitSuite) TestLegacyTime() { func (suite *DTTMUnitSuite) TestLegacyTime() {
t := suite.T() t := suite.T()
now := time.Now() now := time.Now()
result := common.FormatLegacyTime(now) result := dttm.FormatToLegacy(now)
assert.Equal(t, now.UTC().Format(time.RFC3339), result) assert.Equal(t, now.UTC().Format(time.RFC3339), result)
} }
func (suite *CommonTimeUnitSuite) TestFormatTabularDisplayTime() { func (suite *DTTMUnitSuite) TestFormatTabularDisplayTime() {
t := suite.T() t := suite.T()
now := time.Now() now := time.Now()
result := common.FormatTabularDisplayTime(now) result := dttm.FormatToTabularDisplay(now)
assert.Equal(t, now.UTC().Format(string(common.TabularOutput)), result) assert.Equal(t, now.UTC().Format(string(dttm.TabularOutput)), result)
} }
func (suite *CommonTimeUnitSuite) TestParseTime() { func (suite *DTTMUnitSuite) TestParseTime() {
t := suite.T() t := suite.T()
now := time.Now() now := time.Now()
nowStr := now.Format(time.RFC3339Nano) nowStr := now.Format(time.RFC3339Nano)
result, err := common.ParseTime(nowStr) result, err := dttm.ParseTime(nowStr)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, now.UTC(), result) assert.Equal(t, now.UTC(), result)
_, err = common.ParseTime("") _, err = dttm.ParseTime("")
require.Error(t, err, clues.ToCore(err)) require.Error(t, err, clues.ToCore(err))
_, err = common.ParseTime("flablabls") _, err = dttm.ParseTime("flablabls")
require.Error(t, err, clues.ToCore(err)) require.Error(t, err, clues.ToCore(err))
} }
func (suite *CommonTimeUnitSuite) TestExtractTime() { func (suite *DTTMUnitSuite) TestExtractTime() {
comparable := func(t *testing.T, tt time.Time, shortFormat common.TimeFormat) time.Time { comparable := func(t *testing.T, tt time.Time, shortFormat dttm.TimeFormat) time.Time {
ts := common.FormatLegacyTime(tt.UTC()) ts := dttm.FormatToLegacy(tt.UTC())
if len(shortFormat) > 0 { if len(shortFormat) > 0 {
ts = tt.UTC().Format(string(shortFormat)) ts = tt.UTC().Format(string(shortFormat))
} }
c, err := common.ParseTime(ts) c, err := dttm.ParseTime(ts)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -92,16 +91,16 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
parseT("2006-01-02T03:00:04-01:00"), parseT("2006-01-02T03:00:04-01:00"),
} }
formats := []common.TimeFormat{ formats := []dttm.TimeFormat{
common.ClippedSimple, dttm.ClippedHuman,
common.ClippedSimpleOneDrive, dttm.ClippedHumanDriveItem,
common.LegacyTime, dttm.Legacy,
common.SimpleDateTime, dttm.HumanReadable,
common.SimpleDateTimeOneDrive, dttm.HumanReadableDriveItem,
common.StandardTime, dttm.Standard,
common.TabularOutput, dttm.TabularOutput,
common.SimpleTimeTesting, dttm.SafeForTesting,
common.DateOnly, dttm.DateOnly,
} }
type presuf struct { type presuf struct {
@ -118,7 +117,7 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
type testable struct { type testable struct {
input string input string
clippedFormat common.TimeFormat clippedFormat dttm.TimeFormat
expect time.Time expect time.Time
} }
@ -129,13 +128,13 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
for _, f := range formats { for _, f := range formats {
shortFormat := f shortFormat := f
if f != common.ClippedSimple && if f != dttm.ClippedHuman &&
f != common.ClippedSimpleOneDrive && f != dttm.ClippedHumanDriveItem &&
f != common.DateOnly { f != dttm.DateOnly {
shortFormat = "" shortFormat = ""
} }
v := common.FormatTimeWith(in, f) v := dttm.FormatTo(in, f)
for _, ps := range pss { for _, ps := range pss {
table = append(table, testable{ table = append(table, testable{
@ -151,7 +150,7 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
suite.Run(test.input, func() { suite.Run(test.input, func() {
t := suite.T() t := suite.T()
result, err := common.ExtractTime(test.input) result, err := dttm.ExtractTime(test.input)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, test.expect, comparable(t, result, test.clippedFormat)) assert.Equal(t, test.expect, comparable(t, result, test.clippedFormat))
}) })

View File

@ -12,7 +12,7 @@ import (
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/microsoftgraph/msgraph-sdk-go/users" "github.com/microsoftgraph/msgraph-sdk-go/users"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/graph/api" "github.com/alcionai/corso/src/internal/connector/graph/api"
@ -407,7 +407,7 @@ func EventInfo(evt models.Eventable) *details.ExchangeInfo {
// DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC) // DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
startTime := ptr.Val(evt.GetStart().GetDateTime()) + "Z" startTime := ptr.Val(evt.GetStart().GetDateTime()) + "Z"
output, err := common.ParseTime(startTime) output, err := dttm.ParseTime(startTime)
if err == nil { if err == nil {
start = output start = output
} }
@ -418,7 +418,7 @@ func EventInfo(evt models.Eventable) *details.ExchangeInfo {
// DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC) // DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
endTime := ptr.Val(evt.GetEnd().GetDateTime()) + "Z" endTime := ptr.Val(evt.GetEnd().GetDateTime()) + "Z"
output, err := common.ParseTime(endTime) output, err := dttm.ParseTime(endTime)
if err == nil { if err == nil {
end = output end = output
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
exchMock "github.com/alcionai/corso/src/internal/connector/exchange/mock" exchMock "github.com/alcionai/corso/src/internal/connector/exchange/mock"
"github.com/alcionai/corso/src/internal/connector/support" "github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -31,7 +31,7 @@ func (suite *EventsAPIUnitSuite) TestEventInfo() {
// Exchange stores start/end times in UTC and the below compares hours // Exchange stores start/end times in UTC and the below compares hours
// directly so we need to "normalize" the timezone here. // directly so we need to "normalize" the timezone here.
initial := time.Now().UTC() initial := time.Now().UTC()
now := common.FormatTimeWith(initial, common.M365DateTimeTimeZone) now := dttm.FormatTo(initial, dttm.M365DateTimeTimeZone)
suite.T().Logf("Initial: %v\nFormatted: %v\n", initial, now) suite.T().Logf("Initial: %v\nFormatted: %v\n", initial, now)
@ -87,7 +87,7 @@ func (suite *EventsAPIUnitSuite) TestEventInfo() {
startTime.SetDateTime(&now) startTime.SetDateTime(&now)
event.SetStart(startTime) event.SetStart(startTime)
nowp30m := common.FormatTimeWith(initial.Add(30*time.Minute), common.M365DateTimeTimeZone) nowp30m := dttm.FormatTo(initial.Add(30*time.Minute), dttm.M365DateTimeTimeZone)
endTime.SetDateTime(&nowp30m) endTime.SetDateTime(&nowp30m)
event.SetEnd(endTime) event.SetEnd(endTime)

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
) )
// Order of fields to fill in: // Order of fields to fill in:
@ -221,8 +221,8 @@ func EventBytes(subject string) []byte {
func EventWithSubjectBytes(subject string) []byte { func EventWithSubjectBytes(subject string) []byte {
tomorrow := time.Now().UTC().AddDate(0, 0, 1) tomorrow := time.Now().UTC().AddDate(0, 0, 1)
at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC) at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC)
atTime := common.FormatTime(at) atTime := dttm.Format(at)
endTime := common.FormatTime(at.Add(30 * time.Minute)) endTime := dttm.Format(at.Add(30 * time.Minute))
return EventWith( return EventWith(
defaultEventOrganizer, subject, defaultEventOrganizer, subject,
@ -234,7 +234,7 @@ func EventWithSubjectBytes(subject string) []byte {
func EventWithAttachment(subject string) []byte { func EventWithAttachment(subject string) []byte {
tomorrow := time.Now().UTC().AddDate(0, 0, 1) tomorrow := time.Now().UTC().AddDate(0, 0, 1)
at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC) at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC)
atTime := common.FormatTime(at) atTime := dttm.Format(at)
return EventWith( return EventWith(
defaultEventOrganizer, subject, defaultEventOrganizer, subject,
@ -246,7 +246,7 @@ func EventWithAttachment(subject string) []byte {
func EventWithRecurrenceBytes(subject, recurrenceTimeZone string) []byte { func EventWithRecurrenceBytes(subject, recurrenceTimeZone string) []byte {
tomorrow := time.Now().UTC().AddDate(0, 0, 1) tomorrow := time.Now().UTC().AddDate(0, 0, 1)
at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC) at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC)
atTime := common.FormatTime(at) atTime := dttm.Format(at)
timeSlice := strings.Split(atTime, "T") timeSlice := strings.Split(atTime, "T")
recurrence := string(fmt.Sprintf( recurrence := string(fmt.Sprintf(
@ -265,7 +265,7 @@ func EventWithRecurrenceBytes(subject, recurrenceTimeZone string) []byte {
func EventWithAttendeesBytes(subject string) []byte { func EventWithAttendeesBytes(subject string) []byte {
tomorrow := time.Now().UTC().AddDate(0, 0, 1) tomorrow := time.Now().UTC().AddDate(0, 0, 1)
at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC) at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC)
atTime := common.FormatTime(at) atTime := dttm.Format(at)
return EventWith( return EventWith(
defaultEventOrganizer, subject, defaultEventOrganizer, subject,

View File

@ -11,7 +11,7 @@ import (
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
) )
//nolint:lll //nolint:lll
@ -107,7 +107,7 @@ const (
// Contents verified as working with sample data from kiota-serialization-json-go v0.5.5 // Contents verified as working with sample data from kiota-serialization-json-go v0.5.5
func MessageBytes(subject string) []byte { func MessageBytes(subject string) []byte {
return MessageWithBodyBytes( return MessageWithBodyBytes(
"TPS Report "+subject+" "+common.FormatNow(common.SimpleDateTime), "TPS Report "+subject+" "+dttm.FormatNow(dttm.HumanReadable),
defaultMessageBody, defaultMessagePreview) defaultMessageBody, defaultMessagePreview)
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/exchange/api" "github.com/alcionai/corso/src/internal/connector/exchange/api"
exchMock "github.com/alcionai/corso/src/internal/connector/exchange/mock" exchMock "github.com/alcionai/corso/src/internal/connector/exchange/mock"
@ -68,7 +68,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreContact() {
t = suite.T() t = suite.T()
userID = tester.M365UserID(t) userID = tester.M365UserID(t)
now = time.Now() now = time.Now()
folderName = "TestRestoreContact: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName = "TestRestoreContact: " + dttm.FormatTo(now, dttm.SafeForTesting)
) )
aFolder, err := suite.ac.Contacts().CreateContactFolder(ctx, userID, folderName) aFolder, err := suite.ac.Contacts().CreateContactFolder(ctx, userID, folderName)
@ -102,7 +102,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreEvent() {
var ( var (
t = suite.T() t = suite.T()
userID = tester.M365UserID(t) userID = tester.M365UserID(t)
subject = "TestRestoreEvent: " + common.FormatNow(common.SimpleTimeTesting) subject = "TestRestoreEvent: " + dttm.FormatNow(dttm.SafeForTesting)
) )
calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, subject) calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, subject)
@ -184,7 +184,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageBytes("Restore Exchange Object"), bytes: exchMock.MessageBytes("Restore Exchange Object"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailObject: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailObject: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -196,7 +196,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithDirectAttachment("Restore 1 Attachment"), bytes: exchMock.MessageWithDirectAttachment("Restore 1 Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailwithAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailwithAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -208,7 +208,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithItemAttachmentEvent("Event Item Attachment"), bytes: exchMock.MessageWithItemAttachmentEvent("Event Item Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreEventItemAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreEventItemAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -220,7 +220,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithItemAttachmentMail("Mail Item Attachment"), bytes: exchMock.MessageWithItemAttachmentMail("Mail Item Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailItemAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailItemAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -235,7 +235,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
), ),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailBasicItemAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailBasicItemAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -250,7 +250,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
), ),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "ItemMailAttachmentwAttachment " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "ItemMailAttachmentwAttachment " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -265,7 +265,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
), ),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "ItemMailAttachment_Contact " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "ItemMailAttachment_Contact " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -277,7 +277,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithNestedItemAttachmentEvent("Nested Item Attachment"), bytes: exchMock.MessageWithNestedItemAttachmentEvent("Nested Item Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreNestedEventItemAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreNestedEventItemAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -289,7 +289,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithLargeAttachment("Restore Large Attachment"), bytes: exchMock.MessageWithLargeAttachment("Restore Large Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailwithLargeAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailwithLargeAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -301,7 +301,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithTwoAttachments("Restore 2 Attachments"), bytes: exchMock.MessageWithTwoAttachments("Restore 2 Attachments"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailwithAttachments: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailwithAttachments: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -313,7 +313,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.MessageWithOneDriveAttachment("Restore Reference(OneDrive) Attachment"), bytes: exchMock.MessageWithOneDriveAttachment("Restore Reference(OneDrive) Attachment"),
category: path.EmailCategory, category: path.EmailCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreMailwithReferenceAttachment: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreMailwithReferenceAttachment: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName) folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -326,7 +326,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.ContactBytes("Test_Omega"), bytes: exchMock.ContactBytes("Test_Omega"),
category: path.ContactsCategory, category: path.ContactsCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
folderName := "TestRestoreContactObject: " + common.FormatTimeWith(now, common.SimpleTimeTesting) folderName := "TestRestoreContactObject: " + dttm.FormatTo(now, dttm.SafeForTesting)
folder, err := suite.ac.Contacts().CreateContactFolder(ctx, userID, folderName) folder, err := suite.ac.Contacts().CreateContactFolder(ctx, userID, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -338,7 +338,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.EventBytes("Restored Event Object"), bytes: exchMock.EventBytes("Restored Event Object"),
category: path.EventsCategory, category: path.EventsCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
calendarName := "TestRestoreEventObject: " + common.FormatTimeWith(now, common.SimpleTimeTesting) calendarName := "TestRestoreEventObject: " + dttm.FormatTo(now, dttm.SafeForTesting)
calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, calendarName) calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, calendarName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -350,7 +350,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
bytes: exchMock.EventWithAttachment("Restored Event Attachment"), bytes: exchMock.EventWithAttachment("Restored Event Attachment"),
category: path.EventsCategory, category: path.EventsCategory,
destination: func(t *testing.T, ctx context.Context) string { destination: func(t *testing.T, ctx context.Context) string {
calendarName := "TestRestoreEventObject_" + common.FormatTimeWith(now, common.SimpleTimeTesting) calendarName := "TestRestoreEventObject_" + dttm.FormatTo(now, dttm.SafeForTesting)
calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, calendarName) calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, calendarName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))

View File

@ -10,7 +10,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/exchange/api" "github.com/alcionai/corso/src/internal/connector/exchange/api"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
@ -194,7 +194,7 @@ func RestoreMailMessage(
if clone.GetSentDateTime() != nil { if clone.GetSentDateTime() != nil {
sv2 := models.NewSingleValueLegacyExtendedProperty() sv2 := models.NewSingleValueLegacyExtendedProperty()
sendPropertyValue := common.FormatLegacyTime(ptr.Val(clone.GetSentDateTime())) sendPropertyValue := dttm.FormatToLegacy(ptr.Val(clone.GetSentDateTime()))
sendPropertyTag := MailSendDateTimeOverrideProperty sendPropertyTag := MailSendDateTimeOverrideProperty
sv2.SetId(&sendPropertyTag) sv2.SetId(&sendPropertyTag)
sv2.SetValue(&sendPropertyValue) sv2.SetValue(&sendPropertyValue)
@ -204,7 +204,7 @@ func RestoreMailMessage(
if clone.GetReceivedDateTime() != nil { if clone.GetReceivedDateTime() != nil {
sv3 := models.NewSingleValueLegacyExtendedProperty() sv3 := models.NewSingleValueLegacyExtendedProperty()
recvPropertyValue := common.FormatLegacyTime(ptr.Val(clone.GetReceivedDateTime())) recvPropertyValue := dttm.FormatToLegacy(ptr.Val(clone.GetReceivedDateTime()))
recvPropertyTag := MailReceiveDateTimeOverriveProperty recvPropertyTag := MailReceiveDateTimeOverriveProperty
sv3.SetId(&recvPropertyTag) sv3.SetId(&recvPropertyTag)
sv3.SetValue(&recvPropertyValue) sv3.SetValue(&recvPropertyValue)

View File

@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/onedrive/api" "github.com/alcionai/corso/src/internal/connector/onedrive/api"
@ -302,7 +302,7 @@ func (suite *OneDriveSuite) TestCreateGetDeleteFolder() {
var ( var (
t = suite.T() t = suite.T()
folderIDs = []string{} folderIDs = []string{}
folderName1 = "Corso_Folder_Test_" + common.FormatNow(common.SimpleTimeTesting) folderName1 = "Corso_Folder_Test_" + dttm.FormatNow(dttm.SafeForTesting)
folderElements = []string{folderName1} folderElements = []string{folderName1}
gs = loadTestService(t) gs = loadTestService(t)
) )
@ -340,7 +340,7 @@ func (suite *OneDriveSuite) TestCreateGetDeleteFolder() {
folderIDs = append(folderIDs, folderID) folderIDs = append(folderIDs, folderID)
folderName2 := "Corso_Folder_Test_" + common.FormatNow(common.SimpleTimeTesting) folderName2 := "Corso_Folder_Test_" + dttm.FormatNow(dttm.SafeForTesting)
restoreFolders = restoreFolders.Append(folderName2) restoreFolders = restoreFolders.Append(folderName2)
folderID, err = CreateRestoreFolders(ctx, gs, driveID, ptr.Val(rootFolder.GetId()), restoreFolders, NewFolderCache()) folderID, err = CreateRestoreFolders(ctx, gs, driveID, ptr.Val(rootFolder.GetId()), restoreFolders, NewFolderCache())

View File

@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/onedrive/api" "github.com/alcionai/corso/src/internal/connector/onedrive/api"
@ -158,7 +158,7 @@ func (suite *ItemIntegrationSuite) TestItemWriter() {
folder, err := api.GetFolderByName(ctx, srv, test.driveID, ptr.Val(root.GetId()), "Test Folder") folder, err := api.GetFolderByName(ctx, srv, test.driveID, ptr.Val(root.GetId()), "Test Folder")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
newFolderName := "testfolder_" + common.FormatNow(common.SimpleTimeTesting) newFolderName := "testfolder_" + dttm.FormatNow(dttm.SafeForTesting)
t.Logf("Test will create folder %s", newFolderName) t.Logf("Test will create folder %s", newFolderName)
newFolder, err := CreateItem( newFolder, err := CreateItem(
@ -170,7 +170,7 @@ func (suite *ItemIntegrationSuite) TestItemWriter() {
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.NotNil(t, newFolder.GetId()) require.NotNil(t, newFolder.GetId())
newItemName := "testItem_" + common.FormatNow(common.SimpleTimeTesting) newItemName := "testItem_" + dttm.FormatNow(dttm.SafeForTesting)
t.Logf("Test will create item %s", newItemName) t.Logf("Test will create item %s", newItemName)
newItem, err := CreateItem( newItem, err := CreateItem(

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/connector/sharepoint" "github.com/alcionai/corso/src/internal/connector/sharepoint"
"github.com/alcionai/corso/src/internal/connector/sharepoint/api" "github.com/alcionai/corso/src/internal/connector/sharepoint/api"
spMock "github.com/alcionai/corso/src/internal/connector/sharepoint/mock" spMock "github.com/alcionai/corso/src/internal/connector/sharepoint/mock"
@ -81,7 +81,7 @@ func (suite *SharePointPageSuite) TestRestoreSinglePage() {
t := suite.T() t := suite.T()
destName := "Corso_Restore_" + common.FormatNow(common.SimpleTimeTesting) destName := "Corso_Restore_" + dttm.FormatNow(dttm.SafeForTesting)
testName := "MockPage" testName := "MockPage"
// Create Test Page // Create Test Page

View File

@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/sharepoint/api" "github.com/alcionai/corso/src/internal/connector/sharepoint/api"
spMock "github.com/alcionai/corso/src/internal/connector/sharepoint/mock" spMock "github.com/alcionai/corso/src/internal/connector/sharepoint/mock"
@ -193,7 +193,7 @@ func (suite *SharePointCollectionSuite) TestListCollection_Restore() {
info: sharePointListInfo(listing, int64(len(byteArray))), info: sharePointListInfo(listing, int64(len(byteArray))),
} }
destName := "Corso_Restore_" + common.FormatNow(common.SimpleTimeTesting) destName := "Corso_Restore_" + dttm.FormatNow(dttm.SafeForTesting)
deets, err := restoreListItem(ctx, service, listData, suite.siteID, destName) deets, err := restoreListItem(ctx, service, listData, suite.siteID, destName)
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))

View File

@ -7,8 +7,8 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/common/crash" "github.com/alcionai/corso/src/internal/common/crash"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/diagnostics" "github.com/alcionai/corso/src/internal/diagnostics"
@ -872,10 +872,10 @@ func (op *BackupOperation) createBackupModels(
events.BackupID: b.ID, events.BackupID: b.ID,
events.DataStored: op.Results.BytesUploaded, events.DataStored: op.Results.BytesUploaded,
events.Duration: op.Results.CompletedAt.Sub(op.Results.StartedAt), events.Duration: op.Results.CompletedAt.Sub(op.Results.StartedAt),
events.EndTime: common.FormatTime(op.Results.CompletedAt), events.EndTime: dttm.Format(op.Results.CompletedAt),
events.Resources: op.Results.ResourceOwners, events.Resources: op.Results.ResourceOwners,
events.Service: op.Selectors.PathService().String(), events.Service: op.Selectors.PathService().String(),
events.StartTime: common.FormatTime(op.Results.StartedAt), events.StartTime: dttm.Format(op.Results.StartedAt),
events.Status: op.Status.String(), events.Status: op.Status.String(),
}) })

View File

@ -16,7 +16,7 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
inMock "github.com/alcionai/corso/src/internal/common/idname/mock" inMock "github.com/alcionai/corso/src/internal/common/idname/mock"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
@ -375,7 +375,7 @@ func generateContainerOfItems(
items: items, items: items,
}} }}
dest := control.DefaultRestoreDestination(common.SimpleTimeTesting) dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
dest.ContainerName = destFldr dest.ContainerName = destFldr
dataColls := buildCollections( dataColls := buildCollections(
@ -410,8 +410,8 @@ func generateItemData(
dbf dataBuilderFunc, dbf dataBuilderFunc,
) (string, []byte) { ) (string, []byte) {
var ( var (
now = common.Now() now = dttm.Now()
nowLegacy = common.FormatLegacyTime(time.Now()) nowLegacy = dttm.FormatToLegacy(time.Now())
id = uuid.NewString() id = uuid.NewString()
subject = "incr_test " + now[:16] + " - " + id[:8] subject = "incr_test " + now[:16] + " - " + id[:8]
body = "incr_test " + category.String() + " generation for " + resourceOwner + " at " + now + " - " + id body = "incr_test " + category.String() + " generation for " + resourceOwner + " at " + now + " - " + id
@ -702,7 +702,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
acct = tester.NewM365Account(t) acct = tester.NewM365Account(t)
ffs = control.Toggles{} ffs = control.Toggles{}
mb = evmock.NewBus() mb = evmock.NewBus()
now = common.Now() now = dttm.Now()
categories = map[path.CategoryType][]string{ categories = map[path.CategoryType][]string{
path.EmailCategory: exchange.MetadataFileNames(path.EmailCategory), path.EmailCategory: exchange.MetadataFileNames(path.EmailCategory),
path.ContactsCategory: exchange.MetadataFileNames(path.ContactsCategory), path.ContactsCategory: exchange.MetadataFileNames(path.ContactsCategory),
@ -1232,7 +1232,7 @@ func runDriveIncrementalTest(
// `now` has to be formatted with SimpleDateTimeTesting as // `now` has to be formatted with SimpleDateTimeTesting as
// some drives cannot have `:` in file/folder names // some drives cannot have `:` in file/folder names
now = common.FormatNow(common.SimpleTimeTesting) now = dttm.FormatNow(dttm.SafeForTesting)
categories = map[path.CategoryType][]string{ categories = map[path.CategoryType][]string{
category: {graph.DeltaURLsFileName, graph.PreviousPathFileName}, category: {graph.DeltaURLsFileName, graph.PreviousPathFileName},

View File

@ -8,8 +8,8 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/common/crash" "github.com/alcionai/corso/src/internal/common/crash"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/connector/onedrive" "github.com/alcionai/corso/src/internal/connector/onedrive"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/diagnostics" "github.com/alcionai/corso/src/internal/diagnostics"
@ -289,13 +289,13 @@ func (op *RestoreOperation) persistResults(
events.BackupID: op.BackupID, events.BackupID: op.BackupID,
events.DataRetrieved: op.Results.BytesRead, events.DataRetrieved: op.Results.BytesRead,
events.Duration: op.Results.CompletedAt.Sub(op.Results.StartedAt), events.Duration: op.Results.CompletedAt.Sub(op.Results.StartedAt),
events.EndTime: common.FormatTime(op.Results.CompletedAt), events.EndTime: dttm.Format(op.Results.CompletedAt),
events.ItemsRead: op.Results.ItemsRead, events.ItemsRead: op.Results.ItemsRead,
events.ItemsWritten: op.Results.ItemsWritten, events.ItemsWritten: op.Results.ItemsWritten,
events.Resources: op.Results.ResourceOwners, events.Resources: op.Results.ResourceOwners,
events.RestoreID: opStats.restoreID, events.RestoreID: opStats.restoreID,
events.Service: op.Selectors.Service.String(), events.Service: op.Selectors.Service.String(),
events.StartTime: common.FormatTime(op.Results.StartedAt), events.StartTime: dttm.Format(op.Results.StartedAt),
events.Status: op.Status.String(), events.Status: op.Status.String(),
}, },
) )

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
inMock "github.com/alcionai/corso/src/internal/common/idname/mock" inMock "github.com/alcionai/corso/src/internal/common/idname/mock"
"github.com/alcionai/corso/src/internal/connector" "github.com/alcionai/corso/src/internal/connector"
"github.com/alcionai/corso/src/internal/connector/exchange" "github.com/alcionai/corso/src/internal/connector/exchange"
@ -404,7 +404,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
{ {
name: "SharePoint_Restore", name: "SharePoint_Restore",
owner: tester.M365SiteID(suite.T()), owner: tester.M365SiteID(suite.T()),
dest: control.DefaultRestoreDestination(common.SimpleTimeTesting), dest: control.DefaultRestoreDestination(dttm.SafeForTesting),
getSelector: func(t *testing.T, owners []string) selectors.Selector { getSelector: func(t *testing.T, owners []string) selectors.Selector {
rsel := selectors.NewSharePointRestore(owners) rsel := selectors.NewSharePointRestore(owners)
rsel.Include(rsel.AllData()) rsel.Include(rsel.AllData())

View File

@ -9,7 +9,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/logger" "github.com/alcionai/corso/src/pkg/logger"
) )
@ -17,7 +17,7 @@ import (
// the root command for integration testing on the CLI // the root command for integration testing on the CLI
func StubRootCmd(args ...string) *cobra.Command { func StubRootCmd(args ...string) *cobra.Command {
id := uuid.NewString() id := uuid.NewString()
now := common.FormatTime(time.Now()) now := dttm.Format(time.Now())
cmdArg := "testing-corso" cmdArg := "testing-corso"
c := &cobra.Command{ c := &cobra.Command{
Use: cmdArg, Use: cmdArg,

View File

@ -1,11 +1,11 @@
package tester package tester
import ( import (
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
) )
func DefaultTestRestoreDestination() control.RestoreDestination { func DefaultTestRestoreDestination() control.RestoreDestination {
// Use microsecond granularity to help reduce collisions. // Use microsecond granularity to help reduce collisions.
return control.DefaultRestoreDestination(common.SimpleTimeTesting) return control.DefaultRestoreDestination(dttm.SafeForTesting)
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/model" "github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats" "github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
@ -264,7 +264,7 @@ func (b Backup) Values() []string {
return []string{ return []string{
string(b.ID), string(b.ID),
common.FormatTabularDisplayTime(b.StartedAt), dttm.FormatToTabularDisplay(b.StartedAt),
bs.EndedAt.Sub(bs.StartedAt).String(), bs.EndedAt.Sub(bs.StartedAt).String(),
status, status,
name, name,

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/model" "github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats" "github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -74,7 +74,7 @@ func (suite *BackupUnitSuite) TestBackup_HeadersValues() {
"Status", "Status",
"Resource Owner", "Resource Owner",
} }
nowFmt = common.FormatTabularDisplayTime(now) nowFmt = dttm.FormatToTabularDisplay(now)
expectVs = []string{ expectVs = []string{
"id", "id",
nowFmt, nowFmt,

View File

@ -14,7 +14,7 @@ import (
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/connector/onedrive/metadata" "github.com/alcionai/corso/src/internal/connector/onedrive/metadata"
"github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/internal/version"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
@ -804,8 +804,8 @@ func (i ExchangeInfo) Values() []string {
return []string{ return []string{
i.Organizer, i.Organizer,
i.Subject, i.Subject,
common.FormatTabularDisplayTime(i.EventStart), dttm.FormatToTabularDisplay(i.EventStart),
common.FormatTabularDisplayTime(i.EventEnd), dttm.FormatToTabularDisplay(i.EventEnd),
strconv.FormatBool(i.EventRecurs), strconv.FormatBool(i.EventRecurs),
} }
@ -815,7 +815,7 @@ func (i ExchangeInfo) Values() []string {
case ExchangeMail: case ExchangeMail:
return []string{ return []string{
i.Sender, i.ParentPath, i.Subject, i.Sender, i.ParentPath, i.Subject,
common.FormatTabularDisplayTime(i.Received), dttm.FormatToTabularDisplay(i.Received),
} }
} }
@ -887,8 +887,8 @@ func (i SharePointInfo) Values() []string {
i.ParentPath, i.ParentPath,
humanize.Bytes(uint64(i.Size)), humanize.Bytes(uint64(i.Size)),
i.Owner, i.Owner,
common.FormatTabularDisplayTime(i.Created), dttm.FormatToTabularDisplay(i.Created),
common.FormatTabularDisplayTime(i.Modified), dttm.FormatToTabularDisplay(i.Modified),
} }
} }
@ -944,8 +944,8 @@ func (i OneDriveInfo) Values() []string {
i.ParentPath, i.ParentPath,
humanize.Bytes(uint64(i.Size)), humanize.Bytes(uint64(i.Size)),
i.Owner, i.Owner,
common.FormatTabularDisplayTime(i.Created), dttm.FormatToTabularDisplay(i.Created),
common.FormatTabularDisplayTime(i.Modified), dttm.FormatToTabularDisplay(i.Modified),
} }
} }

View File

@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/connector/onedrive/metadata" "github.com/alcionai/corso/src/internal/connector/onedrive/metadata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/internal/version"
@ -34,8 +34,8 @@ func TestDetailsUnitSuite(t *testing.T) {
func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() { func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
initial := time.Now() initial := time.Now()
nowStr := common.FormatTimeWith(initial, common.TabularOutput) nowStr := dttm.FormatTo(initial, dttm.TabularOutput)
now, err := common.ParseTime(nowStr) now, err := dttm.ParseTime(nowStr)
require.NoError(suite.T(), err, clues.ToCore(err)) require.NoError(suite.T(), err, clues.ToCore(err))
table := []struct { table := []struct {

View File

@ -1,7 +1,7 @@
package control package control
import ( import (
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/control/repository" "github.com/alcionai/corso/src/pkg/control/repository"
) )
@ -83,9 +83,9 @@ type RestoreDestination struct {
ContainerName string ContainerName string
} }
func DefaultRestoreDestination(timeFormat common.TimeFormat) RestoreDestination { func DefaultRestoreDestination(timeFormat dttm.TimeFormat) RestoreDestination {
return RestoreDestination{ return RestoreDestination{
ContainerName: defaultRestoreLocation + common.FormatNow(timeFormat), ContainerName: defaultRestoreLocation + dttm.FormatNow(timeFormat),
} }
} }

View File

@ -7,7 +7,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/filters" "github.com/alcionai/corso/src/pkg/filters"
@ -776,7 +776,7 @@ func (s ExchangeScope) matchesInfo(dii details.ItemInfo) bool {
case ExchangeInfoEventRecurs: case ExchangeInfoEventRecurs:
i = strconv.FormatBool(info.EventRecurs) i = strconv.FormatBool(info.EventRecurs)
case ExchangeInfoEventStartsAfter, ExchangeInfoEventStartsBefore: case ExchangeInfoEventStartsAfter, ExchangeInfoEventStartsBefore:
i = common.FormatTime(info.EventStart) i = dttm.Format(info.EventStart)
case ExchangeInfoEventSubject: case ExchangeInfoEventSubject:
i = info.Subject i = info.Subject
case ExchangeInfoMailSender: case ExchangeInfoMailSender:
@ -784,7 +784,7 @@ func (s ExchangeScope) matchesInfo(dii details.ItemInfo) bool {
case ExchangeInfoMailSubject: case ExchangeInfoMailSubject:
i = info.Subject i = info.Subject
case ExchangeInfoMailReceivedAfter, ExchangeInfoMailReceivedBefore: case ExchangeInfoMailReceivedAfter, ExchangeInfoMailReceivedBefore:
i = common.FormatTime(info.Received) i = dttm.Format(info.Received)
} }
return s.Matches(infoCat, i) return s.Matches(infoCat, i)

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
@ -642,25 +642,25 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
{"mail with a different subject", details.ExchangeMail, es.MailSubject("fancy"), assert.False}, {"mail with a different subject", details.ExchangeMail, es.MailSubject("fancy"), assert.False},
{"mail with the matching subject", details.ExchangeMail, es.MailSubject(subject), assert.True}, {"mail with the matching subject", details.ExchangeMail, es.MailSubject(subject), assert.True},
{"mail with a substring subject match", details.ExchangeMail, es.MailSubject(subject[5:9]), assert.True}, {"mail with a substring subject match", details.ExchangeMail, es.MailSubject(subject[5:9]), assert.True},
{"mail received after the epoch", details.ExchangeMail, es.MailReceivedAfter(common.FormatTime(epoch)), assert.True}, {"mail received after the epoch", details.ExchangeMail, es.MailReceivedAfter(dttm.Format(epoch)), assert.True},
{"mail received after now", details.ExchangeMail, es.MailReceivedAfter(common.FormatTime(now)), assert.False}, {"mail received after now", details.ExchangeMail, es.MailReceivedAfter(dttm.Format(now)), assert.False},
{ {
"mail received after sometime later", "mail received after sometime later",
details.ExchangeMail, details.ExchangeMail,
es.MailReceivedAfter(common.FormatTime(future)), es.MailReceivedAfter(dttm.Format(future)),
assert.False, assert.False,
}, },
{ {
"mail received before the epoch", "mail received before the epoch",
details.ExchangeMail, details.ExchangeMail,
es.MailReceivedBefore(common.FormatTime(epoch)), es.MailReceivedBefore(dttm.Format(epoch)),
assert.False, assert.False,
}, },
{"mail received before now", details.ExchangeMail, es.MailReceivedBefore(common.FormatTime(now)), assert.False}, {"mail received before now", details.ExchangeMail, es.MailReceivedBefore(dttm.Format(now)), assert.False},
{ {
"mail received before sometime later", "mail received before sometime later",
details.ExchangeMail, details.ExchangeMail,
es.MailReceivedBefore(common.FormatTime(future)), es.MailReceivedBefore(dttm.Format(future)),
assert.True, assert.True,
}, },
{"event with any organizer", details.ExchangeEvent, es.EventOrganizer(AnyTgt), assert.True}, {"event with any organizer", details.ExchangeEvent, es.EventOrganizer(AnyTgt), assert.True},
@ -669,25 +669,25 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
{"event with the matching organizer", details.ExchangeEvent, es.EventOrganizer(organizer), assert.True}, {"event with the matching organizer", details.ExchangeEvent, es.EventOrganizer(organizer), assert.True},
{"event that recurs", details.ExchangeEvent, es.EventRecurs("true"), assert.True}, {"event that recurs", details.ExchangeEvent, es.EventRecurs("true"), assert.True},
{"event that does not recur", details.ExchangeEvent, es.EventRecurs("false"), assert.False}, {"event that does not recur", details.ExchangeEvent, es.EventRecurs("false"), assert.False},
{"event starting after the epoch", details.ExchangeEvent, es.EventStartsAfter(common.FormatTime(epoch)), assert.True}, {"event starting after the epoch", details.ExchangeEvent, es.EventStartsAfter(dttm.Format(epoch)), assert.True},
{"event starting after now", details.ExchangeEvent, es.EventStartsAfter(common.FormatTime(now)), assert.False}, {"event starting after now", details.ExchangeEvent, es.EventStartsAfter(dttm.Format(now)), assert.False},
{ {
"event starting after sometime later", "event starting after sometime later",
details.ExchangeEvent, details.ExchangeEvent,
es.EventStartsAfter(common.FormatTime(future)), es.EventStartsAfter(dttm.Format(future)),
assert.False, assert.False,
}, },
{ {
"event starting before the epoch", "event starting before the epoch",
details.ExchangeEvent, details.ExchangeEvent,
es.EventStartsBefore(common.FormatTime(epoch)), es.EventStartsBefore(dttm.Format(epoch)),
assert.False, assert.False,
}, },
{"event starting before now", details.ExchangeEvent, es.EventStartsBefore(common.FormatTime(now)), assert.False}, {"event starting before now", details.ExchangeEvent, es.EventStartsBefore(dttm.Format(now)), assert.False},
{ {
"event starting before sometime later", "event starting before sometime later",
details.ExchangeEvent, details.ExchangeEvent,
es.EventStartsBefore(common.FormatTime(future)), es.EventStartsBefore(dttm.Format(future)),
assert.True, assert.True,
}, },
{"event with any subject", details.ExchangeEvent, es.EventSubject(AnyTgt), assert.True}, {"event with any subject", details.ExchangeEvent, es.EventSubject(AnyTgt), assert.True},

View File

@ -6,7 +6,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/filters" "github.com/alcionai/corso/src/pkg/filters"
@ -543,9 +543,9 @@ func (s OneDriveScope) matchesInfo(dii details.ItemInfo) bool {
switch infoCat { switch infoCat {
case FileInfoCreatedAfter, FileInfoCreatedBefore: case FileInfoCreatedAfter, FileInfoCreatedBefore:
i = common.FormatTime(info.Created) i = dttm.Format(info.Created)
case FileInfoModifiedAfter, FileInfoModifiedBefore: case FileInfoModifiedAfter, FileInfoModifiedBefore:
i = common.FormatTime(info.Modified) i = dttm.Format(info.Modified)
} }
return s.Matches(infoCat, i) return s.Matches(infoCat, i)

View File

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
@ -406,18 +406,18 @@ func (suite *OneDriveSelectorSuite) TestOneDriveScope_MatchesInfo() {
scope []OneDriveScope scope []OneDriveScope
expect assert.BoolAssertionFunc expect assert.BoolAssertionFunc
}{ }{
{"file create after the epoch", ods.CreatedAfter(common.FormatTime(epoch)), assert.True}, {"file create after the epoch", ods.CreatedAfter(dttm.Format(epoch)), assert.True},
{"file create after now", ods.CreatedAfter(common.FormatTime(now)), assert.False}, {"file create after now", ods.CreatedAfter(dttm.Format(now)), assert.False},
{"file create after later", ods.CreatedAfter(common.FormatTime(future)), assert.False}, {"file create after later", ods.CreatedAfter(dttm.Format(future)), assert.False},
{"file create before future", ods.CreatedBefore(common.FormatTime(future)), assert.True}, {"file create before future", ods.CreatedBefore(dttm.Format(future)), assert.True},
{"file create before now", ods.CreatedBefore(common.FormatTime(now)), assert.False}, {"file create before now", ods.CreatedBefore(dttm.Format(now)), assert.False},
{"file create before epoch", ods.CreatedBefore(common.FormatTime(now)), assert.False}, {"file create before epoch", ods.CreatedBefore(dttm.Format(now)), assert.False},
{"file modified after the epoch", ods.ModifiedAfter(common.FormatTime(epoch)), assert.True}, {"file modified after the epoch", ods.ModifiedAfter(dttm.Format(epoch)), assert.True},
{"file modified after now", ods.ModifiedAfter(common.FormatTime(now)), assert.False}, {"file modified after now", ods.ModifiedAfter(dttm.Format(now)), assert.False},
{"file modified after later", ods.ModifiedAfter(common.FormatTime(future)), assert.False}, {"file modified after later", ods.ModifiedAfter(dttm.Format(future)), assert.False},
{"file modified before future", ods.ModifiedBefore(common.FormatTime(future)), assert.True}, {"file modified before future", ods.ModifiedBefore(dttm.Format(future)), assert.True},
{"file modified before now", ods.ModifiedBefore(common.FormatTime(now)), assert.False}, {"file modified before now", ods.ModifiedBefore(dttm.Format(now)), assert.False},
{"file modified before epoch", ods.ModifiedBefore(common.FormatTime(now)), assert.False}, {"file modified before epoch", ods.ModifiedBefore(dttm.Format(now)), assert.False},
} }
for _, test := range table { for _, test := range table {
suite.Run(test.name, func() { suite.Run(test.name, func() {

View File

@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/backup/details/testdata" "github.com/alcionai/corso/src/pkg/backup/details/testdata"
@ -97,7 +97,7 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Filter(sel.MailReceivedBefore( sel.Filter(sel.MailReceivedBefore(
common.FormatTime(testdata.Time1.Add(time.Second)), dttm.Format(testdata.Time1.Add(time.Second)),
)) ))
return sel return sel

View File

@ -6,7 +6,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/filters" "github.com/alcionai/corso/src/pkg/filters"
@ -703,9 +703,9 @@ func (s SharePointScope) matchesInfo(dii details.ItemInfo) bool {
case SharePointWebURL: case SharePointWebURL:
i = info.WebURL i = info.WebURL
case SharePointInfoCreatedAfter, SharePointInfoCreatedBefore: case SharePointInfoCreatedAfter, SharePointInfoCreatedBefore:
i = common.FormatTime(info.Created) i = dttm.Format(info.Created)
case SharePointInfoModifiedAfter, SharePointInfoModifiedBefore: case SharePointInfoModifiedAfter, SharePointInfoModifiedBefore:
i = common.FormatTime(info.Modified) i = dttm.Format(info.Modified)
case SharePointInfoLibraryDrive: case SharePointInfoLibraryDrive:
ds := []string{} ds := []string{}

View File

@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
@ -524,19 +524,19 @@ func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
{"host does not contain substring", host, sel.WebURL([]string{"website"}), assert.False}, {"host does not contain substring", host, sel.WebURL([]string{"website"}), assert.False},
{"url does not suffix substring", url, sel.WebURL([]string{"oo"}, SuffixMatch()), assert.False}, {"url does not suffix substring", url, sel.WebURL([]string{"oo"}, SuffixMatch()), assert.False},
{"host mismatch", host, sel.WebURL([]string{"www.google.com"}), assert.False}, {"host mismatch", host, sel.WebURL([]string{"www.google.com"}), assert.False},
{"file create after the epoch", host, sel.CreatedAfter(common.FormatTime(epoch)), assert.True}, {"file create after the epoch", host, sel.CreatedAfter(dttm.Format(epoch)), assert.True},
{"file create after now", host, sel.CreatedAfter(common.FormatTime(now)), assert.False}, {"file create after now", host, sel.CreatedAfter(dttm.Format(now)), assert.False},
{"file create after later", url, sel.CreatedAfter(common.FormatTime(future)), assert.False}, {"file create after later", url, sel.CreatedAfter(dttm.Format(future)), assert.False},
{"file create before future", host, sel.CreatedBefore(common.FormatTime(future)), assert.True}, {"file create before future", host, sel.CreatedBefore(dttm.Format(future)), assert.True},
{"file create before now", host, sel.CreatedBefore(common.FormatTime(now)), assert.False}, {"file create before now", host, sel.CreatedBefore(dttm.Format(now)), assert.False},
{"file create before modification", host, sel.CreatedBefore(common.FormatTime(modification)), assert.True}, {"file create before modification", host, sel.CreatedBefore(dttm.Format(modification)), assert.True},
{"file create before epoch", host, sel.CreatedBefore(common.FormatTime(now)), assert.False}, {"file create before epoch", host, sel.CreatedBefore(dttm.Format(now)), assert.False},
{"file modified after the epoch", host, sel.ModifiedAfter(common.FormatTime(epoch)), assert.True}, {"file modified after the epoch", host, sel.ModifiedAfter(dttm.Format(epoch)), assert.True},
{"file modified after now", host, sel.ModifiedAfter(common.FormatTime(now)), assert.True}, {"file modified after now", host, sel.ModifiedAfter(dttm.Format(now)), assert.True},
{"file modified after later", host, sel.ModifiedAfter(common.FormatTime(future)), assert.False}, {"file modified after later", host, sel.ModifiedAfter(dttm.Format(future)), assert.False},
{"file modified before future", host, sel.ModifiedBefore(common.FormatTime(future)), assert.True}, {"file modified before future", host, sel.ModifiedBefore(dttm.Format(future)), assert.True},
{"file modified before now", host, sel.ModifiedBefore(common.FormatTime(now)), assert.False}, {"file modified before now", host, sel.ModifiedBefore(dttm.Format(now)), assert.False},
{"file modified before epoch", host, sel.ModifiedBefore(common.FormatTime(now)), assert.False}, {"file modified before epoch", host, sel.ModifiedBefore(dttm.Format(now)), assert.False},
{"in library", host, sel.Library("included-library"), assert.True}, {"in library", host, sel.Library("included-library"), assert.True},
{"not in library", host, sel.Library("not-included-library"), assert.False}, {"not in library", host, sel.Library("not-included-library"), assert.False},
{"library id", host, sel.Library("1234"), assert.True}, {"library id", host, sel.Library("1234"), assert.True},