go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/collections/heap_test.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package collections
     9  
    10  import (
    11  	"cmp"
    12  	"testing"
    13  
    14  	. "go.charczuk.com/sdk/assert"
    15  )
    16  
    17  func Test_Heap(t *testing.T) {
    18  	h := NewHeap(
    19  		cmp.Less,
    20  		2, 1, 5,
    21  	)
    22  	h.Push(3)
    23  	ItsEqual(t, 1, okValue(h.Peek()))
    24  	var values []int
    25  	for h.Len() > 0 {
    26  		values = append(values, okValue(h.Pop()))
    27  	}
    28  	ItsEqual(t, []int{1, 2, 3, 5}, values)
    29  }
    30  
    31  func Test_Heap_FixAt(t *testing.T) {
    32  	h := NewHeap(
    33  		More[int],
    34  		2, 1, 5, 4, 3,
    35  	)
    36  	h.Values[2] = 10
    37  	h.FixAt(2)
    38  
    39  	max, ok := h.Peek()
    40  	ItsEqual(t, true, ok)
    41  	ItsEqual(t, 10, max)
    42  }
    43  
    44  func Test_Heap_RemoveAt(t *testing.T) {
    45  	h := NewHeap(
    46  		cmp.Less[int],
    47  		2, 1, 5,
    48  	)
    49  
    50  	indexOf := func(val int) (outputIndex int, ok bool) {
    51  		for index, elem := range h.Values {
    52  			if elem == val {
    53  				outputIndex = index
    54  				ok = true
    55  				return
    56  			}
    57  		}
    58  		return
    59  	}
    60  
    61  	removed, ok := h.RemoveAt(okValue(indexOf(1)))
    62  	ItsEqual(t, true, ok)
    63  	ItsEqual(t, 1, removed)
    64  
    65  	removed, ok = h.RemoveAt(okValue(indexOf(2)))
    66  	ItsEqual(t, true, ok)
    67  	ItsEqual(t, 2, removed)
    68  
    69  	removed, ok = h.RemoveAt(okValue(indexOf(5)))
    70  	ItsEqual(t, true, ok)
    71  	ItsEqual(t, 5, removed)
    72  
    73  	removed, ok = h.RemoveAt(okValue(indexOf(-1)))
    74  	ItsEqual(t, false, ok)
    75  	ItsEqual(t, 0, removed)
    76  }
    77  
    78  func Test_Heap_PushPop(t *testing.T) {
    79  	empty := NewHeap(cmp.Less[int])
    80  	value, ok := empty.PushPop(10)
    81  	ItsEqual(t, false, ok)
    82  	ItsEqual(t, 0, value)
    83  
    84  	value, ok = empty.PushPop(12)
    85  	ItsEqual(t, true, ok)
    86  	ItsEqual(t, 10, value)
    87  
    88  	value, ok = empty.PushPop(13)
    89  	ItsEqual(t, true, ok)
    90  	ItsEqual(t, 12, value)
    91  
    92  	h := NewHeap(
    93  		cmp.Less[int],
    94  		2, 1, 5, 4, 3,
    95  	)
    96  
    97  	value, ok = h.PushPop(10)
    98  	ItsEqual(t, true, ok)
    99  	ItsEqual(t, 1, value)
   100  
   101  	value, ok = h.PushPop(15)
   102  	ItsEqual(t, true, ok)
   103  	ItsEqual(t, 2, value)
   104  
   105  	value, ok = h.PushPop(12)
   106  	ItsEqual(t, true, ok)
   107  	ItsEqual(t, 3, value)
   108  
   109  	value, ok = h.PushPop(14)
   110  	ItsEqual(t, true, ok)
   111  	ItsEqual(t, 4, value)
   112  
   113  	value, ok = h.PushPop(11)
   114  	ItsEqual(t, true, ok)
   115  	ItsEqual(t, 5, value)
   116  
   117  	value, ok = h.PushPop(1)
   118  	ItsEqual(t, true, ok)
   119  	ItsEqual(t, 10, value)
   120  
   121  	value, ok = h.PushPop(1)
   122  	ItsEqual(t, true, ok)
   123  	ItsEqual(t, 1, value)
   124  }
   125  
   126  func Test_Heap_ctor(t *testing.T) {
   127  	// NOTE(wc): it's nice to have a test to make sure
   128  	// that there are no regressions in the constructor itself,
   129  	// specifically to make sure we initialize the heap
   130  	// based on provided values!
   131  	h := NewHeap(cmp.Less[int], 4, 5, 8, 2)
   132  	ItsEqual(t, 2, h.Values[0])
   133  }