pq_test.go 2.89 KB
Newer Older
Brian Tiger Chow's avatar
Brian Tiger Chow committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
package pq

import (
	"sort"
	"testing"
)

type TestElem struct {
	Key      string
	Priority int
	index    int
}

func (e *TestElem) Index() int {
	return e.index
}

func (e *TestElem) SetIndex(i int) {
	e.index = i
}

var PriorityComparator = func(i, j Elem) bool {
	return i.(*TestElem).Priority > j.(*TestElem).Priority
}

func TestQueuesReturnTypeIsSameAsParameterToPush(t *testing.T) {
	q := New(PriorityComparator)
	expectedKey := "foo"
	elem := &TestElem{Key: expectedKey}
	q.Push(elem)
	switch v := q.Pop().(type) {
	case *TestElem:
		if v.Key != expectedKey {
			t.Fatal("the key doesn't match the pushed value")
		}
	default:
		t.Fatal("the queue is not casting values appropriately")
	}
}

func TestCorrectnessOfPop(t *testing.T) {
	q := New(PriorityComparator)
	tasks := []TestElem{
rht's avatar
rht committed
44 45 46 47 48
		{Key: "a", Priority: 9},
		{Key: "b", Priority: 4},
		{Key: "c", Priority: 3},
		{Key: "d", Priority: 0},
		{Key: "e", Priority: 6},
Brian Tiger Chow's avatar
Brian Tiger Chow committed
49 50 51 52 53
	}
	for _, e := range tasks {
		q.Push(&e)
	}
	var priorities []int
Dirk McCormick's avatar
Dirk McCormick committed
54
	var peekPriorities []int
Brian Tiger Chow's avatar
Brian Tiger Chow committed
55
	for q.Len() > 0 {
Dirk McCormick's avatar
Dirk McCormick committed
56
		i := q.Peek().(*TestElem).Priority
Dirk McCormick's avatar
Dirk McCormick committed
57
		peekPriorities = append(peekPriorities, i)
Dirk McCormick's avatar
Dirk McCormick committed
58 59 60
		j := q.Pop().(*TestElem).Priority
		t.Logf("popped %v", j)
		priorities = append(priorities, j)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
61
	}
62
	if !sort.IntsAreSorted(peekPriorities) {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
63
		t.Fatal("the values were not returned in sorted order")
64 65 66
	}
	if !sort.IntsAreSorted(priorities) {
		t.Fatal("the popped values were not returned in sorted order")
Brian Tiger Chow's avatar
Brian Tiger Chow committed
67 68 69
	}
}

Dirk McCormick's avatar
Dirk McCormick committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
func TestRemove(t *testing.T) {
	q := New(PriorityComparator)
	tasks := []TestElem{
		{Key: "a", Priority: 9},
		{Key: "b", Priority: 4},
		{Key: "c", Priority: 3},
	}
	for i := range tasks {
		q.Push(&tasks[i])
	}
	removed := q.Remove(1).(*TestElem)
	if q.Len() != 2 {
		t.Fatal("expected item to have been removed")
	}
	if q.Pop().(*TestElem).Key == removed.Key {
		t.Fatal("Remove() returned wrong element")
	}
	if q.Pop().(*TestElem).Key == removed.Key {
		t.Fatal("Remove() returned wrong element")
	}
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
92 93 94 95 96 97 98 99 100 101 102 103
func TestUpdate(t *testing.T) {
	t.Log(`
	Add 3 elements.
	Update the highest priority element to have the lowest priority and fix the queue.
	It should come out last.`)
	q := New(PriorityComparator)
	lowest := &TestElem{Key: "originallyLowest", Priority: 1}
	middle := &TestElem{Key: "originallyMiddle", Priority: 2}
	highest := &TestElem{Key: "toBeUpdated", Priority: 3}
	q.Push(middle)
	q.Push(highest)
	q.Push(lowest)
Dirk McCormick's avatar
Dirk McCormick committed
104 105 106
	if q.Peek().(*TestElem).Key != highest.Key {
		t.Fatal("head element doesn't have the highest priority")
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
107 108 109 110 111 112
	if q.Pop().(*TestElem).Key != highest.Key {
		t.Fatal("popped element doesn't have the highest priority")
	}
	q.Push(highest)           // re-add the popped element
	highest.Priority = 0      // update the PQ
	q.Update(highest.Index()) // fix the PQ
Dirk McCormick's avatar
Dirk McCormick committed
113 114 115
	if q.Peek().(*TestElem).Key != middle.Key {
		t.Fatal("middle element should now have the highest priority")
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
116 117 118 119
	if q.Pop().(*TestElem).Key != middle.Key {
		t.Fatal("middle element should now have the highest priority")
	}
}