func TestUpdateEntryWithEtag(t *testing.T) { origEntry := *kOrigEntry var store FakeStore newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry) if err != nil { t.Fatalf("Error saving original entry %v", err) } var origEntryWithEtag vsafe.EntryWithEtag if err := vsafedb.EntryByIdWithEtag( store, nil, newId, kKey, &origEntryWithEtag); err != nil { t.Fatalf("Error reading original entry %v", err) } update := functional.NewFilterer(changeToAnEntry) if err := vsafedb.UpdateEntryWithEtag( store, kTransaction, newId, origEntryWithEtag.Etag, kKey, update); err != nil { t.Fatalf("Error updating store: %v", err) } var readEntry vsafe.Entry if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil { t.Fatalf("Error reading store: %v", err) } entry := *kAnEntry entry.Owner = readEntry.Owner entry.Id = readEntry.Id if readEntry != entry { t.Errorf("Expected %v, got %v", entry, readEntry) } }
func TestUpdateEntryWithEtagBadKey(t *testing.T) { origEntry := *kOrigEntry var store FakeStore newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry) if err != nil { t.Fatalf("Error saving original entry %v", err) } var origEntryWithEtag vsafe.EntryWithEtag if err := vsafedb.EntryByIdWithEtag( store, nil, newId, kKey, &origEntryWithEtag); err != nil { t.Fatalf("Error readingoriginal entry %v", err) } update := functional.NewFilterer(changeToAnEntry) badKey := *kKey badKey.Id++ if err := vsafedb.UpdateEntryWithEtag( store, kTransaction, newId, origEntryWithEtag.Etag, &badKey, update); err != vsafedb.ErrNoSuchId { t.Errorf("Expected ErrNoSuchId, got %v", err) } var readEntry vsafe.Entry if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil { t.Fatalf("Error reading store: %v", err) } if readEntry != origEntryWithEtag.Entry { t.Errorf("Entry should not have been updated") } }
func TestUpdateEntryConcurrent(t *testing.T) { origEntry := *kOrigEntry var store FakeStore newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry) if err != nil { t.Fatalf("Error saving original entry %v", err) } var origEntryWithEtag vsafe.EntryWithEtag if err := vsafedb.EntryByIdWithEtag( store, nil, newId, kKey, &origEntryWithEtag); err != nil { t.Fatalf("Error reading original entry %v", err) } update := functional.NewFilterer(changeToAnEntry) updateSkipped := functional.NewFilterer(func(ptr interface{}) error { entryPtr := ptr.(*vsafe.Entry) *entryPtr = *kAnEntry return functional.Skipped }) // An update that skips shouldn't throw an error even if etag is wrong if err := vsafedb.UpdateEntryWithEtag( store, kTransaction, newId, origEntryWithEtag.Etag+1, kKey, updateSkipped); err != nil { t.Fatalf("Error updating store: %v", err) } if err := vsafedb.UpdateEntryWithEtag( store, kTransaction, newId, origEntryWithEtag.Etag+1, kKey, update); err != vsafedb.ErrConcurrentModification { t.Errorf("Expected ErrConcurrentModfication, got %v", err) } var readEntry vsafe.Entry if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil { t.Fatalf("Error reading store: %v", err) } if readEntry != origEntryWithEtag.Entry { t.Errorf("Entry should not have been updated") } }
// OnDays filters times by day of week. dayMask is the desired days of the // week ored together e.g functional.Monday | functional.Tuesday func OnDays(dayMask DaysOfWeek) functional.Filterer { return functional.NewFilterer(func(ptr interface{}) error { p := ptr.(*time.Time) ourWeekday := uint((7 - p.Weekday()) % 7) if dayMask&(1<<ourWeekday) != 0 { return nil } return functional.Skipped }) }
func (f FakeStore) EntriesByOwner( t db.Transaction, owner int64, consumer functional.Consumer) error { s := functional.NewStreamFromPtrs(f, nil) s = functional.Filter(functional.NewFilterer(func(ptr interface{}) error { p := ptr.(*vsafe.Entry) if p.Owner == owner { return nil } return functional.Skipped }), s) return consumer.Consume(s) }
// OnOrBefore ensures that the times in r happen on or before // hour:min. If a time is after hour:min, it is moved earlier to be // hour:min. If a time is 12 hours or more after hour:min, then it is // considered to be before hour:min on the next day, and no adjustment is // made. func OnOrBefore(r tasks_recurring.R, hour, min int) tasks_recurring.R { return tasks_recurring.RFunc(func(t time.Time) functional.Stream { s := r.ForTime(t) return functional.DropWhile( functional.NewFilterer(func(ptr interface{}) error { p := ptr.(*time.Time) if p.After(t) { return functional.Skipped } return nil }), &happensBefore{ Stream: s, hour: hour, min: min, hm: toHourMinute(hour, min)}) }) }
func toEntry(values url.Values) (mutation functional.Filterer, err error) { url, err := safeUrlParse(values.Get("url")) if err != nil { return } title := values.Get("title") desc := values.Get("desc") uName := values.Get("uname") password := values.Get("password") special := values.Get("special") mutation = functional.NewFilterer(func(ptr interface{}) error { // We have to skip if nothing changed. Otherwise the etag will change // when we update even if we don't change anything. This is because // of the random seed added to the encryption. entryPtr := ptr.(*vsafe.Entry) changed := false if safeUrlString(entryPtr.Url) != safeUrlString(url) { entryPtr.Url = url changed = true } if entryPtr.Title != title { entryPtr.Title = title changed = true } if entryPtr.Desc != desc { entryPtr.Desc = desc changed = true } if entryPtr.UName != uName { entryPtr.UName = uName changed = true } if entryPtr.Password != password { entryPtr.Password = password changed = true } if entryPtr.Special != special { entryPtr.Special = special changed = true } if changed { return nil } return functional.Skipped }) return }
func TestFilterNested(t *testing.T) { firstTime := time.Date(2013, 9, 12, 18, 0, 0, 0, time.Local) r := recurring.Until( recurring.Filter( recurring.Filter( recurring.AtTime(18, 0), recurring.OnDays(recurring.Weekdays)), functional.NewFilterer(func(ptr interface{}) error { p := ptr.(*time.Time) if p.Day()%2 != 0 { return functional.Skipped } return nil })), firstTime.AddDate(0, 0, 8)) verifyTimes( t, r.ForTime(kNow), firstTime, // Thursday firstTime.AddDate(0, 0, 4), // Monday firstTime.AddDate(0, 0, 6)) // Wednesday }