Пример #1
0
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)
	}
}
Пример #2
0
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")
	}
}
Пример #3
0
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")
	}
}
Пример #4
0
// 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
	})
}
Пример #5
0
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)
}
Пример #6
0
// 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)})
	})
}
Пример #7
0
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
}
Пример #8
0
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
}