mirror of https://github.com/velour/catbase.git
history: add history module
This commit is contained in:
parent
6a11ddc98a
commit
fc0c6ccd46
|
@ -0,0 +1,84 @@
|
|||
package history
|
||||
|
||||
import (
|
||||
"container/ring"
|
||||
"fmt"
|
||||
|
||||
"github.com/velour/catbase/bot/msg"
|
||||
)
|
||||
|
||||
// History is a ring buffer of messages
|
||||
type History struct {
|
||||
r *ring.Ring
|
||||
}
|
||||
|
||||
// New returns a history of sz size
|
||||
func New(sz int) *History {
|
||||
return &History{ring.New(sz)}
|
||||
}
|
||||
|
||||
// Edit looks for an entry and ammends it
|
||||
// returns error if the id is not found
|
||||
func (h *History) Edit(id string, update *msg.Message) error {
|
||||
r := h.r
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
m := r.Value.(*msg.Message)
|
||||
if m != nil && m.ID == id {
|
||||
r.Value = update
|
||||
return nil
|
||||
}
|
||||
r = r.Next()
|
||||
}
|
||||
return fmt.Errorf("entry not found")
|
||||
}
|
||||
|
||||
// Append adds a message to the history
|
||||
func (h *History) Append(m *msg.Message) {
|
||||
h.r.Value = m
|
||||
h.r = h.r.Next()
|
||||
}
|
||||
|
||||
// Find looks for an entry by id and returns an error if not found
|
||||
func (h *History) Find(id string) (*msg.Message, error) {
|
||||
r := h.r
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
m := r.Value.(*msg.Message)
|
||||
if m != nil && m.ID == id {
|
||||
return m, nil
|
||||
}
|
||||
r = r.Next()
|
||||
}
|
||||
return nil, fmt.Errorf("entry not found")
|
||||
}
|
||||
|
||||
// Last gets the last known message
|
||||
func (h *History) Last() *msg.Message {
|
||||
return h.r.Prev().Value.(*msg.Message)
|
||||
}
|
||||
|
||||
// LastInChannel searches backwards for the last message matching channel ch
|
||||
func (h *History) LastInChannel(ch string) (*msg.Message, error) {
|
||||
r := h.r
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
m := r.Value.(*msg.Message)
|
||||
if m != nil && m.Channel == ch {
|
||||
return m, nil
|
||||
}
|
||||
r = r.Prev()
|
||||
}
|
||||
return nil, fmt.Errorf("entry not found")
|
||||
}
|
||||
|
||||
// InChannel returns all knows messages from channel ch in reverse order
|
||||
func (h *History) InChannel(ch string) []*msg.Message {
|
||||
out := []*msg.Message{}
|
||||
r := h.r
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
m := r.Value.(*msg.Message)
|
||||
if m != nil && m.Channel == ch {
|
||||
out = append(out, m)
|
||||
}
|
||||
r = r.Prev()
|
||||
}
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package history
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/velour/catbase/bot/msg"
|
||||
)
|
||||
|
||||
var sampleMessages []*msg.Message
|
||||
|
||||
func init() {
|
||||
sampleMessages = []*msg.Message{}
|
||||
for i := 0; i < 100; i++ {
|
||||
txt := fmt.Sprintf("Message #%d", i)
|
||||
m := &msg.Message{
|
||||
ID: txt,
|
||||
Body: txt,
|
||||
}
|
||||
|
||||
sampleMessages = append(sampleMessages, m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppend(t *testing.T) {
|
||||
h := New(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
h.Append(sampleMessages[i])
|
||||
}
|
||||
previous := h.r.Prev().Value.(*msg.Message)
|
||||
assert.Equal(t, sampleMessages[9].ID, previous.ID)
|
||||
}
|
||||
|
||||
func TestFindExists(t *testing.T) {
|
||||
h := New(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
h.Append(sampleMessages[i])
|
||||
}
|
||||
id := sampleMessages[5].ID
|
||||
elt, err := h.Find(id)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, id, elt.ID)
|
||||
}
|
||||
|
||||
func TestFindMissing(t *testing.T) {
|
||||
h := New(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
h.Append(sampleMessages[i])
|
||||
}
|
||||
id := sampleMessages[15].ID
|
||||
elt, err := h.Find(id)
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, elt)
|
||||
}
|
||||
|
||||
func TestEditExists(t *testing.T) {
|
||||
h := New(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
h.Append(sampleMessages[i])
|
||||
}
|
||||
id := sampleMessages[5].ID
|
||||
m := sampleMessages[15]
|
||||
m.ID = id
|
||||
err := h.Edit(id, m)
|
||||
assert.Nil(t, err)
|
||||
actual, err := h.Find(id)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, m.Body, actual.Body)
|
||||
}
|
||||
|
||||
func TestEditMissing(t *testing.T) {
|
||||
h := New(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
h.Append(sampleMessages[i])
|
||||
}
|
||||
id := sampleMessages[10].ID
|
||||
m := sampleMessages[6]
|
||||
t.Logf("id: %s, editID: %s", id, m.ID)
|
||||
err := h.Edit(id, m)
|
||||
assert.NotNil(t, err)
|
||||
}
|
Loading…
Reference in New Issue