diff --git a/pkg/search/match_test.go b/pkg/search/match_test.go new file mode 100644 index 000000000..abb0e1218 --- /dev/null +++ b/pkg/search/match_test.go @@ -0,0 +1,73 @@ +package search + +import ( + "testing" + "time" +) + +const year = time.Hour * 24 * 365 + +func TestTimeConstraint(t *testing.T) { + tests := []struct { + c *TimeConstraint + t time.Time + want bool + }{ + { + &TimeConstraint{ + Before: time.Unix(124, 0), + }, + time.Unix(123, 0), + true, + }, + { + &TimeConstraint{ + Before: time.Unix(123, 0), + }, + time.Unix(123, 1), + false, + }, + { + &TimeConstraint{ + After: time.Unix(123, 0), + }, + time.Unix(123, 0), + true, + }, + { + &TimeConstraint{ + After: time.Unix(123, 0), + }, + time.Unix(123, 1), + true, + }, + { + &TimeConstraint{ + After: time.Unix(123, 0), + }, + time.Unix(122, 0), + false, + }, + { + // This test will pass for 20 years at least. + &TimeConstraint{ + InLast: 20 * year, + }, + time.Unix(1384034605, 0), + true, + }, + { + &TimeConstraint{ + InLast: 1 * year, + }, + time.Unix(123, 0), + false, + }, + } + for i, tt := range tests { + got := tt.c.timeMatches(tt.t) + if got != tt.want { + t.Errorf("%d. matches(tc=%+v, t=%v) = %v; want %v", i, tt.c, tt.t, got, tt.want) + } + } +} diff --git a/pkg/search/query.go b/pkg/search/query.go index cca310563..18b749699 100644 --- a/pkg/search/query.go +++ b/pkg/search/query.go @@ -470,8 +470,37 @@ func (c *FileConstraint) blobMatches(s *search, br blob.Ref, bm BlobMeta) (bool, if sc := c.MIMEType; sc != nil && !sc.stringMatches(fi.MIMEType) { return false, nil } - // TOOD: Time timeconstraint - // TOOD: ModTime timeconstraint + if tc := c.Time; tc != nil { + if fi.Time == nil || !tc.timeMatches(fi.Time.Time()) { + return false, nil + } + } + if tc := c.ModTime; tc != nil { + if fi.ModTime == nil || !tc.timeMatches(fi.ModTime.Time()) { + return false, nil + } + } // TOOD: EXIF timeconstraint return true, nil } + +func (c *TimeConstraint) timeMatches(t time.Time) bool { + if t.IsZero() { + return false + } + if !c.Before.IsZero() { + if !t.Before(c.Before) { + return false + } + } + after := c.After + if after.IsZero() && c.InLast > 0 { + after = time.Now().Add(-c.InLast) + } + if !after.IsZero() { + if !(t.Equal(after) || t.After(after)) { // after is >= + return false + } + } + return true +}