github.com/sunvim/utils@v0.1.0/priorityqueue/pq_test.go (about)

     1  package priorityqueue
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  type mockItem int
    11  
    12  func (mi mockItem) Compare(other Item) int {
    13  	omi := other.(mockItem)
    14  	if mi > omi {
    15  		return 1
    16  	} else if mi == omi {
    17  		return 0
    18  	}
    19  	return -1
    20  }
    21  
    22  func TestPriorityPut(t *testing.T) {
    23  	q := NewPriorityQueue(1, false)
    24  
    25  	q.Put(mockItem(2))
    26  
    27  	assert.Len(t, q.items, 1)
    28  	assert.Equal(t, mockItem(2), q.items[0])
    29  
    30  	q.Put(mockItem(1))
    31  
    32  	if !assert.Len(t, q.items, 2) {
    33  		return
    34  	}
    35  	assert.Equal(t, mockItem(1), q.items[0])
    36  	assert.Equal(t, mockItem(2), q.items[1])
    37  }
    38  
    39  func TestPriorityGet(t *testing.T) {
    40  	q := NewPriorityQueue(1, false)
    41  
    42  	q.Put(mockItem(2))
    43  	result, err := q.Get(2)
    44  	if !assert.Nil(t, err) {
    45  		return
    46  	}
    47  
    48  	if !assert.Len(t, result, 1) {
    49  		return
    50  	}
    51  
    52  	assert.Equal(t, mockItem(2), result[0])
    53  	assert.Len(t, q.items, 0)
    54  
    55  	q.Put(mockItem(2))
    56  	q.Put(mockItem(1))
    57  
    58  	result, err = q.Get(1)
    59  	if !assert.Nil(t, err) {
    60  		return
    61  	}
    62  
    63  	if !assert.Len(t, result, 1) {
    64  		return
    65  	}
    66  
    67  	assert.Equal(t, mockItem(1), result[0])
    68  	assert.Len(t, q.items, 1)
    69  
    70  	result, err = q.Get(2)
    71  	if !assert.Nil(t, err) {
    72  		return
    73  	}
    74  
    75  	if !assert.Len(t, result, 1) {
    76  		return
    77  	}
    78  
    79  	assert.Equal(t, mockItem(2), result[0])
    80  }
    81  
    82  func TestAddEmptyPriorityPut(t *testing.T) {
    83  	q := NewPriorityQueue(1, false)
    84  
    85  	q.Put()
    86  
    87  	assert.Len(t, q.items, 0)
    88  }
    89  
    90  func TestPriorityGetNonPositiveNumber(t *testing.T) {
    91  	q := NewPriorityQueue(1, false)
    92  
    93  	q.Put(mockItem(1))
    94  
    95  	result, err := q.Get(0)
    96  	if !assert.Nil(t, err) {
    97  		return
    98  	}
    99  
   100  	assert.Len(t, result, 0)
   101  
   102  	result, err = q.Get(-1)
   103  	if !assert.Nil(t, err) {
   104  		return
   105  	}
   106  
   107  	assert.Len(t, result, 0)
   108  }
   109  
   110  func TestPriorityEmpty(t *testing.T) {
   111  	q := NewPriorityQueue(1, false)
   112  	assert.True(t, q.Empty())
   113  
   114  	q.Put(mockItem(1))
   115  
   116  	assert.False(t, q.Empty())
   117  }
   118  
   119  func TestPriorityGetEmpty(t *testing.T) {
   120  	q := NewPriorityQueue(1, false)
   121  
   122  	go func() {
   123  		q.Put(mockItem(1))
   124  	}()
   125  
   126  	result, err := q.Get(1)
   127  	if !assert.Nil(t, err) {
   128  		return
   129  	}
   130  
   131  	if !assert.Len(t, result, 1) {
   132  		return
   133  	}
   134  	assert.Equal(t, mockItem(1), result[0])
   135  }
   136  
   137  func TestMultiplePriorityGetEmpty(t *testing.T) {
   138  	q := NewPriorityQueue(1, false)
   139  	var wg sync.WaitGroup
   140  	wg.Add(2)
   141  	results := make([][]Item, 2)
   142  
   143  	go func() {
   144  		wg.Done()
   145  		local, _ := q.Get(1)
   146  		results[0] = local
   147  		wg.Done()
   148  	}()
   149  
   150  	go func() {
   151  		wg.Done()
   152  		local, _ := q.Get(1)
   153  		results[1] = local
   154  		wg.Done()
   155  	}()
   156  
   157  	wg.Wait()
   158  	wg.Add(2)
   159  
   160  	q.Put(mockItem(1), mockItem(3), mockItem(2))
   161  	wg.Wait()
   162  
   163  	if !assert.Len(t, results[0], 1) || !assert.Len(t, results[1], 1) {
   164  		return
   165  	}
   166  
   167  	assert.True(
   168  		t, (results[0][0] == mockItem(1) && results[1][0] == mockItem(2)) ||
   169  			results[0][0] == mockItem(2) && results[1][0] == mockItem(1),
   170  	)
   171  }
   172  
   173  func TestEmptyPriorityGetWithDispose(t *testing.T) {
   174  	q := NewPriorityQueue(1, false)
   175  	var wg sync.WaitGroup
   176  	wg.Add(1)
   177  
   178  	var err error
   179  	go func() {
   180  		wg.Done()
   181  		_, err = q.Get(1)
   182  		wg.Done()
   183  	}()
   184  
   185  	wg.Wait()
   186  	wg.Add(1)
   187  
   188  	q.Dispose()
   189  
   190  	wg.Wait()
   191  
   192  	assert.IsType(t, ErrDisposed, err)
   193  }
   194  
   195  func TestPriorityGetPutDisposed(t *testing.T) {
   196  	q := NewPriorityQueue(1, false)
   197  	q.Dispose()
   198  
   199  	_, err := q.Get(1)
   200  	assert.IsType(t, ErrDisposed, err)
   201  
   202  	err = q.Put(mockItem(1))
   203  	assert.IsType(t, ErrDisposed, err)
   204  }
   205  
   206  func BenchmarkPriorityQueue(b *testing.B) {
   207  	q := NewPriorityQueue(b.N, false)
   208  	var wg sync.WaitGroup
   209  	wg.Add(1)
   210  	i := 0
   211  
   212  	go func() {
   213  		for {
   214  			q.Get(1)
   215  			i++
   216  			if i == b.N {
   217  				wg.Done()
   218  				break
   219  			}
   220  		}
   221  	}()
   222  
   223  	for i := 0; i < b.N; i++ {
   224  		q.Put(mockItem(i))
   225  	}
   226  
   227  	wg.Wait()
   228  }
   229  
   230  func TestPriorityPeek(t *testing.T) {
   231  	q := NewPriorityQueue(1, false)
   232  	q.Put(mockItem(1))
   233  
   234  	assert.Equal(t, mockItem(1), q.Peek())
   235  }
   236  
   237  func TestInsertDuplicate(t *testing.T) {
   238  	q := NewPriorityQueue(1, false)
   239  	q.Put(mockItem(1))
   240  	q.Put(mockItem(1))
   241  
   242  	assert.Equal(t, 1, q.Len())
   243  }
   244  
   245  func TestAllowDuplicates(t *testing.T) {
   246  	q := NewPriorityQueue(2, true)
   247  	q.Put(mockItem(1))
   248  	q.Put(mockItem(1))
   249  
   250  	assert.Equal(t, 2, q.Len())
   251  }