소스 검색

implemented feed, which a kind of append-only, random access double-ended queue

Benton Edmondson 1 년 전
부모
커밋
7539db98c5
2개의 변경된 파일122개의 추가작업 그리고 0개의 파일을 삭제
  1. 57 0
      feed/feed.go
  2. 65 0
      feed/feed_test.go

+ 57 - 0
feed/feed.go

@@ -0,0 +1,57 @@
+package feed
+
+import (
+	"mimicry/pub"
+	"fmt"
+)
+
+type Feed struct {
+	feed map[int]pub.Tangible
+	upperBound int
+	lowerBound int
+}
+
+func Create(input pub.Tangible) *Feed {
+	return &Feed {
+		feed: map[int]pub.Tangible {
+			0: input,
+		},
+		upperBound: 0,
+		lowerBound: 0,
+	}
+}
+
+func CreateAndAppend(input []pub.Tangible) *Feed {
+	f := &Feed{
+		feed: map[int]pub.Tangible{},
+	}
+	f.Append(input)
+	f.lowerBound = 1
+	return f
+}
+
+func (f *Feed) Append(input []pub.Tangible) {
+	for i, element := range input {
+		f.feed[f.upperBound+i+1] = element
+	}
+	f.upperBound += len(input)
+}
+
+func (f *Feed) Prepend(input []pub.Tangible) {
+	for i, element := range input {
+		f.feed[f.lowerBound-i-1] = element
+	}
+	f.lowerBound -= len(input)
+}
+
+func (f *Feed) Get(index int) pub.Tangible {
+	if index > f.upperBound || index < f.lowerBound {
+		panic(fmt.Sprintf("indexing feed at %d whereas bounds are %d and %d", index, f.lowerBound, f.upperBound))
+	}
+
+	return f.feed[index]
+}
+
+func (f *Feed) Contains(index int) bool {
+	return index <= f.upperBound && index >= f.lowerBound
+}

+ 65 - 0
feed/feed_test.go

@@ -0,0 +1,65 @@
+package feed
+
+import (
+	"testing"
+	"mimicry/pub"
+	"mimicry/object"
+)
+
+var post1, _ = pub.NewPost(object.Object {
+	"type": "Note",
+	"content": "Hello!",
+}, nil)
+
+var post2, _ = pub.NewPost(object.Object {
+	"type": "Video",
+	"content": "Goodbye!",
+}, nil)
+
+func TestCreate(t *testing.T) {
+	feed := Create(post1)
+	shouldBePost1 := feed.Get(0)
+	if shouldBePost1 != post1 {
+		t.Fatalf("Center Posts differ after Create, is %#v but should be %#v", shouldBePost1, post1)
+	}
+}
+
+func TestCreateCreateAndAppend(t *testing.T) {
+	feed := CreateAndAppend([]pub.Tangible{post1})
+	shouldBePost1 := feed.Get(1)
+	if shouldBePost1 != post1 {
+		t.Fatalf("Posts differed after create centerless, is %#v but should be %#v", shouldBePost1, post1)
+	}
+	defer func() {
+        if recover() == nil {
+            t.Fatalf("After create centerless, Get(0) should have panicked but did not")
+        }
+    }()
+	feed.Get(0)
+}
+
+func TestAppend(t *testing.T) {
+	feed := Create(post1)
+	feed.Append([]pub.Tangible{post2})
+	shouldBePost1 := feed.Get(0)
+	shouldBePost2 := feed.Get(1)
+	if shouldBePost1 != post1 {
+		t.Fatalf("Center Posts differ after Append, is %#v but should be %#v", shouldBePost1, post1)
+	}
+	if shouldBePost2 != post2 {
+		t.Fatalf("Appended posts differ, is %#v but should be %#v", shouldBePost2, post2)
+	}
+}
+
+func TestPrepend(t *testing.T) {
+	feed := Create(post1)
+	feed.Prepend([]pub.Tangible{post2})
+	shouldBePost1 := feed.Get(0)
+	shouldBePost2 := feed.Get(-1)
+	if shouldBePost1 != post1 {
+		t.Fatalf("Center Posts differ after Prepend, is %#v but should be %#v", shouldBePost1, post1)
+	}
+	if shouldBePost2 != post2 {
+		t.Fatalf("Prepended posts differ, is %#v but should be %#v", shouldBePost2, post2)
+	}
+}