pq_test.go 2.25 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 56
	for q.Len() > 0 {
		i := q.Pop().(*TestElem).Priority
Jakub Sztandera's avatar
Jakub Sztandera committed
57
		t.Logf("popped %v", i)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
58
		priorities = append(priorities, i)
Dirk McCormick's avatar
Dirk McCormick committed
59
		peekPriorities = append(peekPriorities, i)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	}
	if !sort.IntsAreSorted(priorities) {
		t.Fatal("the values were not returned in sorted order")
	}
}

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
78 79 80
	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
81 82 83 84 85 86
	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
87 88 89
	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
90 91 92 93
	if q.Pop().(*TestElem).Key != middle.Key {
		t.Fatal("middle element should now have the highest priority")
	}
}