Selaa lähdekoodia

Add bound checks. Add test for bound checks.

Antoine Grondin 11 vuotta sitten
vanhempi
commit
d8809f0b75
2 muutettua tiedostoa jossa 63 lisäystä ja 24 poistoa
  1. 7 1
      queue.go
  2. 56 23
      queue_test.go

+ 7 - 1
queue.go

@@ -56,6 +56,9 @@ func (q *Queue) Add(elem interface{}) {
 // Peek returns the element at the head of the queue. If the queue is empty (Length == 0),
 // Peek does not panic, it simply returns garbage.
 func (q *Queue) Peek() interface{} {
+	if q.Length() <= 0 {
+		panic("queue: empty queue")
+	}
 	return q.buf[q.head]
 }
 
@@ -63,7 +66,7 @@ func (q *Queue) Peek() interface{} {
 // call will panic.
 func (q *Queue) Get(i int) interface{} {
 	if i >= q.Length() || i < 0 {
-		panic("index out of range")
+		panic("queue: index out of range")
 	}
 	modi := (q.head + i) % len(q.buf)
 	return q.buf[modi]
@@ -73,6 +76,9 @@ func (q *Queue) Get(i int) interface{} {
 // call Peek first. If the queue is empty (Length == 0), Remove will put the queue in a bad
 // state and all further operations will be undefined.
 func (q *Queue) Remove() {
+	if q.Length() <= 0 {
+		panic("queue: empty queue")
+	}
 	q.buf[q.head] = nil
 	q.head = (q.head + 1) % len(q.buf)
 	q.count--

+ 56 - 23
queue_test.go

@@ -43,33 +43,55 @@ func TestQueueGetOutOfRangePanics(t *testing.T) {
 	q.Add(2)
 	q.Add(3)
 
-	func() {
-		defer func() {
-			if r := recover(); r == nil {
-				t.Errorf("should panic when negative index")
-			} else {
-				t.Logf("got panic as expected: %v", r)
-			}
-		}()
+	assertPanics(t, "should panic when negative index", func() {
+		q.Get(-1)
+	})
 
-		func() {
-			q.Get(-1)
-		}()
-	}()
+	assertPanics(t, "should panic when index greater than length", func() {
+		q.Get(4)
+	})
+}
 
-	func() {
-		defer func() {
-			if r := recover(); r == nil {
-				t.Errorf("should panic when index greater than length")
-			} else {
-				t.Logf("got panic as expected: %v", r)
-			}
-		}()
+func TestQueuePeekOutOfRangePanics(t *testing.T) {
+	q := New()
+
+	assertPanics(t, "should panic when peeking empty queue", func() {
+		q.Peek()
+	})
+
+	q.Add(1)
+	q.Remove()
 
-		func() {
-			q.Get(4)
-		}()
+	assertPanics(t, "should panic when peeking emptied queue", func() {
+		q.Peek()
+	})
+}
+
+func TestQueueRemoveOutOfRangePanics(t *testing.T) {
+	q := New()
+
+	assertPanics(t, "should panic when removing empty queue", func() {
+		q.Remove()
+	})
+
+	q.Add(1)
+	q.Remove()
+
+	assertPanics(t, "should panic when removing emptied queue", func() {
+		q.Remove()
+	})
+}
+
+func assertPanics(t *testing.T, name string, f func()) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("%s: didn't panic as expected", name)
+		} else {
+			t.Logf("%s: got panic as expected: %v", name, r)
+		}
 	}()
+
+	f()
 }
 
 // General warning: Go's benchmark utility (go test -bench .) increases the number of
@@ -87,6 +109,17 @@ func BenchmarkQueueSerial(b *testing.B) {
 	}
 }
 
+func BenchmarkQueueGet(b *testing.B) {
+	q := New()
+	for i := 0; i < b.N; i++ {
+		q.Add(i)
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		q.Get(i)
+	}
+}
+
 func BenchmarkQueueTickTock(b *testing.B) {
 	q := New()
 	for i := 0; i < b.N; i++ {