github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/maps/maps_test.go (about)

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package maps
     6  
     7  import (
     8  	"math"
     9  	"slices"
    10  	"sort"
    11  	"strconv"
    12  	"testing"
    13  )
    14  
    15  var m1 = map[int]int{1: 2, 2: 4, 4: 8, 8: 16}
    16  var m2 = map[int]string{1: "2", 2: "4", 4: "8", 8: "16"}
    17  
    18  func TestKeys(t *testing.T) {
    19  	want := []int{1, 2, 4, 8}
    20  
    21  	got1 := Keys(m1)
    22  	sort.Ints(got1)
    23  	if !slices.Equal(got1, want) {
    24  		t.Errorf("Keys(%v) = %v, want %v", m1, got1, want)
    25  	}
    26  
    27  	got2 := Keys(m2)
    28  	sort.Ints(got2)
    29  	if !slices.Equal(got2, want) {
    30  		t.Errorf("Keys(%v) = %v, want %v", m2, got2, want)
    31  	}
    32  }
    33  
    34  func TestValues(t *testing.T) {
    35  	got1 := Values(m1)
    36  	want1 := []int{2, 4, 8, 16}
    37  	sort.Ints(got1)
    38  	if !slices.Equal(got1, want1) {
    39  		t.Errorf("Values(%v) = %v, want %v", m1, got1, want1)
    40  	}
    41  
    42  	got2 := Values(m2)
    43  	want2 := []string{"16", "2", "4", "8"}
    44  	sort.Strings(got2)
    45  	if !slices.Equal(got2, want2) {
    46  		t.Errorf("Values(%v) = %v, want %v", m2, got2, want2)
    47  	}
    48  }
    49  
    50  func TestEqual(t *testing.T) {
    51  	if !Equal(m1, m1) {
    52  		t.Errorf("Equal(%v, %v) = false, want true", m1, m1)
    53  	}
    54  	if Equal(m1, (map[int]int)(nil)) {
    55  		t.Errorf("Equal(%v, nil) = true, want false", m1)
    56  	}
    57  	if Equal((map[int]int)(nil), m1) {
    58  		t.Errorf("Equal(nil, %v) = true, want false", m1)
    59  	}
    60  	if !Equal[map[int]int, map[int]int](nil, nil) {
    61  		t.Error("Equal(nil, nil) = false, want true")
    62  	}
    63  	if ms := map[int]int{1: 2}; Equal(m1, ms) {
    64  		t.Errorf("Equal(%v, %v) = true, want false", m1, ms)
    65  	}
    66  
    67  	// Comparing NaN for equality is expected to fail.
    68  	mf := map[int]float64{1: 0, 2: math.NaN()}
    69  	if Equal(mf, mf) {
    70  		t.Errorf("Equal(%v, %v) = true, want false", mf, mf)
    71  	}
    72  }
    73  
    74  // equal is simply ==.
    75  func equal[T comparable](v1, v2 T) bool {
    76  	return v1 == v2
    77  }
    78  
    79  // equalNaN is like == except that all NaNs are equal.
    80  func equalNaN[T comparable](v1, v2 T) bool {
    81  	isNaN := func(f T) bool { return f != f }
    82  	return v1 == v2 || (isNaN(v1) && isNaN(v2))
    83  }
    84  
    85  // equalStr compares ints and strings.
    86  func equalIntStr(v1 int, v2 string) bool {
    87  	return strconv.Itoa(v1) == v2
    88  }
    89  
    90  func TestEqualFunc(t *testing.T) {
    91  	if !EqualFunc(m1, m1, equal[int]) {
    92  		t.Errorf("EqualFunc(%v, %v, equal) = false, want true", m1, m1)
    93  	}
    94  	if EqualFunc(m1, (map[int]int)(nil), equal[int]) {
    95  		t.Errorf("EqualFunc(%v, nil, equal) = true, want false", m1)
    96  	}
    97  	if EqualFunc((map[int]int)(nil), m1, equal[int]) {
    98  		t.Errorf("EqualFunc(nil, %v, equal) = true, want false", m1)
    99  	}
   100  	if !EqualFunc[map[int]int, map[int]int](nil, nil, equal[int]) {
   101  		t.Error("EqualFunc(nil, nil, equal) = false, want true")
   102  	}
   103  	if ms := map[int]int{1: 2}; EqualFunc(m1, ms, equal[int]) {
   104  		t.Errorf("EqualFunc(%v, %v, equal) = true, want false", m1, ms)
   105  	}
   106  
   107  	// Comparing NaN for equality is expected to fail.
   108  	mf := map[int]float64{1: 0, 2: math.NaN()}
   109  	if EqualFunc(mf, mf, equal[float64]) {
   110  		t.Errorf("EqualFunc(%v, %v, equal) = true, want false", mf, mf)
   111  	}
   112  	// But it should succeed using equalNaN.
   113  	if !EqualFunc(mf, mf, equalNaN[float64]) {
   114  		t.Errorf("EqualFunc(%v, %v, equalNaN) = false, want true", mf, mf)
   115  	}
   116  
   117  	if !EqualFunc(m1, m2, equalIntStr) {
   118  		t.Errorf("EqualFunc(%v, %v, equalIntStr) = false, want true", m1, m2)
   119  	}
   120  }
   121  
   122  func TestClone(t *testing.T) {
   123  	mc := Clone(m1)
   124  	if !Equal(mc, m1) {
   125  		t.Errorf("Clone(%v) = %v, want %v", m1, mc, m1)
   126  	}
   127  	mc[16] = 32
   128  	if Equal(mc, m1) {
   129  		t.Errorf("Equal(%v, %v) = true, want false", mc, m1)
   130  	}
   131  }
   132  
   133  func TestCloneNil(t *testing.T) {
   134  	var m1 map[string]int
   135  	mc := Clone(m1)
   136  	if mc != nil {
   137  		t.Errorf("Clone(%v) = %v, want %v", m1, mc, m1)
   138  	}
   139  }
   140  
   141  func TestCopy(t *testing.T) {
   142  	mc := Clone(m1)
   143  	Copy(mc, mc)
   144  	if !Equal(mc, m1) {
   145  		t.Errorf("Copy(%v, %v) = %v, want %v", m1, m1, mc, m1)
   146  	}
   147  	Copy(mc, map[int]int{16: 32})
   148  	want := map[int]int{1: 2, 2: 4, 4: 8, 8: 16, 16: 32}
   149  	if !Equal(mc, want) {
   150  		t.Errorf("Copy result = %v, want %v", mc, want)
   151  	}
   152  
   153  	type M1 map[int]bool
   154  	type M2 map[int]bool
   155  	Copy(make(M1), make(M2))
   156  }
   157  
   158  func TestDeleteFunc(t *testing.T) {
   159  	mc := Clone(m1)
   160  	DeleteFunc(mc, func(int, int) bool { return false })
   161  	if !Equal(mc, m1) {
   162  		t.Errorf("DeleteFunc(%v, true) = %v, want %v", m1, mc, m1)
   163  	}
   164  	DeleteFunc(mc, func(k, v int) bool { return k > 3 })
   165  	want := map[int]int{1: 2, 2: 4}
   166  	if !Equal(mc, want) {
   167  		t.Errorf("DeleteFunc result = %v, want %v", mc, want)
   168  	}
   169  }
   170  
   171  var n map[int]int
   172  
   173  func BenchmarkMapClone(b *testing.B) {
   174  	var m = make(map[int]int)
   175  	for i := 0; i < 1000000; i++ {
   176  		m[i] = i
   177  	}
   178  	b.ResetTimer()
   179  	for i := 0; i < b.N; i++ {
   180  		n = Clone(m)
   181  	}
   182  }
   183  
   184  func TestCloneWithDelete(t *testing.T) {
   185  	var m = make(map[int]int)
   186  	for i := 0; i < 32; i++ {
   187  		m[i] = i
   188  	}
   189  	for i := 8; i < 32; i++ {
   190  		delete(m, i)
   191  	}
   192  	m2 := Clone(m)
   193  	if len(m2) != 8 {
   194  		t.Errorf("len2(m2) = %d, want %d", len(m2), 8)
   195  	}
   196  	for i := 0; i < 8; i++ {
   197  		if m2[i] != m[i] {
   198  			t.Errorf("m2[%d] = %d, want %d", i, m2[i], m[i])
   199  		}
   200  	}
   201  }
   202  
   203  func TestCloneWithMapAssign(t *testing.T) {
   204  	var m = make(map[int]int)
   205  	const N = 25
   206  	for i := 0; i < N; i++ {
   207  		m[i] = i
   208  	}
   209  	m2 := Clone(m)
   210  	if len(m2) != N {
   211  		t.Errorf("len2(m2) = %d, want %d", len(m2), N)
   212  	}
   213  	for i := 0; i < N; i++ {
   214  		if m2[i] != m[i] {
   215  			t.Errorf("m2[%d] = %d, want %d", i, m2[i], m[i])
   216  		}
   217  	}
   218  }