github.com/fluhus/gostuff@v0.4.1-0.20240331134726-be71864f2b5d/heaps/heaps_test.go (about)

     1  package heaps
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand/v2"
     6  	"slices"
     7  	"testing"
     8  
     9  	"github.com/fluhus/gostuff/snm"
    10  )
    11  
    12  func TestHeap(t *testing.T) {
    13  	input := []string{"bb", "a", "ffff", "ddddd"}
    14  	want := []string{"a", "bb", "ddddd", "ffff"}
    15  	h := Min[string]()
    16  	for _, v := range input {
    17  		h.Push(v)
    18  	}
    19  	if ln := h.Len(); ln != len(input) {
    20  		t.Fatalf("Len()=%d, want %d", ln, len(input))
    21  	}
    22  	var got []string
    23  	for h.Len() > 0 {
    24  		got = append(got, h.Pop())
    25  	}
    26  	if !slices.Equal(got, want) {
    27  		t.Fatalf("Pop=%v, want %v", got, want)
    28  	}
    29  }
    30  
    31  func TestHeap_big(t *testing.T) {
    32  	input := []int{
    33  		5, 8, 25, 21, 22, 15, 13, 20, 1, 14,
    34  		24, 12, 7, 18, 27, 3, 30, 28, 23, 29,
    35  		19, 2, 6, 4, 26, 9, 17, 10, 11, 16,
    36  	}
    37  	want := []int{
    38  		1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    39  		11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    40  		21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
    41  	}
    42  	h := New(func(i1, i2 int) bool {
    43  		return i1 < i2
    44  	})
    45  	for _, v := range input {
    46  		h.Push(v)
    47  	}
    48  	if ln := h.Len(); ln != len(input) {
    49  		t.Fatalf("Len()=%d, want %d", ln, len(input))
    50  	}
    51  	var got []int
    52  	for h.Len() > 0 {
    53  		got = append(got, h.Pop())
    54  	}
    55  	if !slices.Equal(got, want) {
    56  		t.Fatalf("Pop=%v, want %v", got, want)
    57  	}
    58  }
    59  
    60  func TestHeap_pushSlice(t *testing.T) {
    61  	input := []int{
    62  		5, 8, 25, 21, 22, 15, 13, 20, 1, 14,
    63  		24, 12, 7, 18, 27, 3, 30, 28, 23, 29,
    64  		19, 2, 6, 4, 26, 9, 17, 10, 11, 16,
    65  	}
    66  	h := Min[int]()
    67  	h.PushSlice(input)
    68  	for i := range h.a {
    69  		if i == 0 {
    70  			continue
    71  		}
    72  		ia := (i - 1) / 2
    73  		if h.a[i] < h.a[ia] {
    74  			t.Errorf("h[%d] < h[%d]: %d < %d", i, ia, h.a[i], h.a[ia])
    75  		}
    76  	}
    77  }
    78  
    79  func Benchmark(b *testing.B) {
    80  	for _, n := range []int{1000, 10000, 100000, 1000000} {
    81  		nums := snm.Slice(n, func(i int) int {
    82  			return rand.Int()
    83  		})
    84  		b.Run(fmt.Sprint("Heap.Push.", n), func(b *testing.B) {
    85  			for range b.N {
    86  				h := Min[int]()
    87  				for _, i := range nums {
    88  					h.Push(i)
    89  				}
    90  			}
    91  		})
    92  		b.Run(fmt.Sprint("Heap.PushSlice.", n), func(b *testing.B) {
    93  			for range b.N {
    94  				h := Min[int]()
    95  				h.PushSlice(nums)
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  func FuzzHeap(f *testing.F) {
   102  	f.Add(0, 0, 0, 0, 0, 0, 0)
   103  	f.Fuzz(func(t *testing.T, a, b, c, d, e, f, g int) {
   104  		h := Min[int]()
   105  		h.Push(a)
   106  		h.Push(b)
   107  		h.Push(c)
   108  		h.Push(d)
   109  		h.Push(e)
   110  		h.Push(f)
   111  		h.Push(g)
   112  		got := make([]int, 0, 7)
   113  		for h.Len() > 0 {
   114  			got = append(got, h.Pop())
   115  		}
   116  		if !slices.IsSorted(got) {
   117  			t.Fatalf("Min().Pop()=%v, want sorted", got)
   118  		}
   119  	})
   120  }