github.com/searKing/golang/go@v1.2.117/exp/maps/filter_test.go (about)

     1  // Copyright 2023 The searKing Author. 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_test
     6  
     7  import (
     8  	"fmt"
     9  	"maps"
    10  	"reflect"
    11  	"strconv"
    12  	"testing"
    13  
    14  	maps_ "github.com/searKing/golang/go/exp/maps"
    15  )
    16  
    17  func TestFilter(t *testing.T) {
    18  	tests := []struct {
    19  		data map[int]int
    20  		want map[int]int
    21  	}{
    22  		{nil, nil},
    23  		{map[int]int{}, map[int]int{}},
    24  		{map[int]int{0: 0}, map[int]int{}},
    25  		{map[int]int{1: 1, 0: 0}, map[int]int{1: 1}},
    26  		{map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}},
    27  		{map[int]int{0: 0, 1: 1, 2: 2}, map[int]int{1: 1, 2: 2}},
    28  		{map[int]int{0: 0, 1: 1, 3: 0, 2: 2}, map[int]int{1: 1, 2: 2}},
    29  	}
    30  	for _, tt := range tests {
    31  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
    32  			{
    33  				got := maps_.Filter(tt.data)
    34  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
    35  					t.Errorf("maps_.Filter(%v) = %v, want %v", tt.data, got, tt.want)
    36  					return
    37  				}
    38  
    39  				if !maps.Equal(got, tt.want) {
    40  					t.Errorf("maps_.Filter(%v) = %v, want %v", tt.data, got, tt.want)
    41  				}
    42  			}
    43  		})
    44  	}
    45  }
    46  
    47  func TestFilterFunc(t *testing.T) {
    48  	tests := []struct {
    49  		data map[int]int
    50  		want map[int]int
    51  	}{
    52  		{nil, nil},
    53  		{map[int]int{}, map[int]int{}},
    54  		{map[int]int{0: 0}, map[int]int{}},
    55  		{map[int]int{1: 1, 0: 0}, map[int]int{1: 1}},
    56  		{map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}},
    57  		{map[int]int{0: 0, 1: 1, 2: 2}, map[int]int{1: 1, 2: 2}},
    58  		{map[int]int{0: 0, 1: 1, 3: 0, 2: 2}, map[int]int{1: 1, 2: 2}},
    59  	}
    60  	for _, tt := range tests {
    61  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
    62  			{
    63  				copy := maps.Clone(tt.data)
    64  				got := maps_.FilterFunc(copy, func(k, v int) bool {
    65  					return v != 0
    66  				})
    67  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
    68  					t.Errorf("maps_.FilterFunc(%v, func(e int) bool {return e != 0}) = %v, want %v", tt.data, got, tt.want)
    69  					return
    70  				}
    71  
    72  				if !maps.Equal(got, tt.want) {
    73  					t.Errorf("maps_.FilterFunc(%v, func(e int) bool {return e != 0}) = %v, want %v", tt.data, got, tt.want)
    74  				}
    75  			}
    76  		})
    77  	}
    78  }
    79  
    80  func TestTypeAssertFilter(t *testing.T) {
    81  	tests := []struct {
    82  		data map[int]int
    83  		want map[int8]int8
    84  	}{
    85  		{nil, nil},
    86  		{map[int]int{}, map[int8]int8{}},
    87  		{map[int]int{0: 0}, map[int8]int8{0: 0}},
    88  		{map[int]int{3: 0}, map[int8]int8{3: 0}},
    89  		{map[int]int{0: 3}, map[int8]int8{0: 3}},
    90  		{map[int]int{2: 3}, map[int8]int8{2: 3}},
    91  		{map[int]int{1: 1, 0: 0}, map[int8]int8{1: 1, 0: 0}},
    92  		{map[int]int{1: 1, 2: 2}, map[int8]int8{1: 1, 2: 2}},
    93  		{map[int]int{0: 0, 1: 1, 2: 2}, map[int8]int8{0: 0, 1: 1, 2: 2}},
    94  		{map[int]int{0: 0, 1: 1, 3: 0, 2: 2}, map[int8]int8{0: 0, 1: 1, 3: 0, 2: 2}},
    95  	}
    96  	for _, tt := range tests {
    97  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
    98  			{
    99  				copy := maps.Clone(tt.data)
   100  				got := maps_.TypeAssertFilter[map[int]int, map[int8]int8](copy)
   101  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
   102  					t.Errorf("maps_.TypeAssertFilter(%v) = %v, want %v", tt.data, got, tt.want)
   103  					return
   104  				}
   105  
   106  				if !maps.Equal(got, tt.want) {
   107  					t.Errorf("maps_.TypeAssertFilter(%v) = %v, want %v", tt.data, got, tt.want)
   108  				}
   109  			}
   110  		})
   111  	}
   112  }
   113  
   114  func TestTypeAssertFilterFunc(t *testing.T) {
   115  	tests := []struct {
   116  		data map[int]int
   117  		want map[int8]int8
   118  	}{
   119  		{nil, nil},
   120  		{map[int]int{}, map[int8]int8{}},
   121  		{map[int]int{0: 0}, map[int8]int8{0: 0}},
   122  		{map[int]int{3: 0}, map[int8]int8{3: 0}},
   123  		{map[int]int{0: 3}, map[int8]int8{0: 3}},
   124  		{map[int]int{2: 3}, map[int8]int8{2: 3}},
   125  		{map[int]int{1: 1, 0: 0}, map[int8]int8{1: 1, 0: 0}},
   126  		{map[int]int{1: 1, 2: 2}, map[int8]int8{1: 1, 2: 2}},
   127  		{map[int]int{0: 0, 1: 1, 2: 2}, map[int8]int8{0: 0, 1: 1, 2: 2}},
   128  		{map[int]int{0: 0, 1: 1, 3: 0, 2: 2}, map[int8]int8{0: 0, 1: 1, 3: 0, 2: 2}},
   129  	}
   130  	for _, tt := range tests {
   131  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
   132  			{
   133  				copy := maps.Clone(tt.data)
   134  				got := maps_.TypeAssertFilterFunc[map[int]int, map[int8]int8](copy, func(k int, v int) (int8, int8, bool) {
   135  					return int8(k), int8(v), true
   136  				})
   137  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
   138  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(k int, v int) (int8, int8, bool) {return int8(k), int8(v), true}) = %v, want %v", tt.data, got, tt.want)
   139  					return
   140  				}
   141  
   142  				if !maps.Equal(got, tt.want) {
   143  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(k int, v int) (int8, int8, bool) {return int8(k), int8(v), true}) = %v, want %v", tt.data, got, tt.want)
   144  				}
   145  			}
   146  		})
   147  	}
   148  }
   149  
   150  func TestTypeAssertFilterFuncItoa(t *testing.T) {
   151  	tests := []struct {
   152  		data map[int]int
   153  		want map[string]string
   154  	}{
   155  		{nil, nil},
   156  		{map[int]int{}, map[string]string{}},
   157  		{map[int]int{0: 0}, map[string]string{"0": "0"}},
   158  		{map[int]int{3: 0}, map[string]string{"3": "0"}},
   159  		{map[int]int{0: 3}, map[string]string{"0": "3"}},
   160  		{map[int]int{2: 3}, map[string]string{"2": "3"}},
   161  		{map[int]int{1: 1, 0: 0}, map[string]string{"1": "1", "0": "0"}},
   162  		{map[int]int{1: 1, 2: 2}, map[string]string{"1": "1", "2": "2"}},
   163  		{map[int]int{0: 0, 1: 1, 2: 2}, map[string]string{"0": "0", "1": "1", "2": "2"}},
   164  		{map[int]int{0: 0, 1: 1, 3: 0, 2: 2}, map[string]string{"0": "0", "1": "1", "3": "0", "2": "2"}},
   165  	}
   166  	for _, tt := range tests {
   167  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
   168  			{
   169  				copy := maps.Clone(tt.data)
   170  				got := maps_.TypeAssertFilterFunc[map[int]int, map[string]string](copy, func(k int, v int) (string, string, bool) {
   171  					return strconv.Itoa(k), strconv.Itoa(v), true
   172  				})
   173  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
   174  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(k int, v int) (int8, int8, bool) {return strconv.Itoa(k), strconv.Itoa(v), true}) = %v, want %v", tt.data, got, tt.want)
   175  					return
   176  				}
   177  
   178  				if !maps.Equal(got, tt.want) {
   179  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(k int, v int) (int8, int8, bool) {return strconv.Itoa(k), strconv.Itoa(v), true}) = %v, want %v", tt.data, got, tt.want)
   180  				}
   181  			}
   182  		})
   183  	}
   184  }
   185  
   186  func TestTypeAssertFilterConvert(t *testing.T) {
   187  	var zeroDog Dog
   188  	var zeroMale Male
   189  	_ = zeroDog
   190  	_ = zeroMale
   191  	tests := []struct {
   192  		data map[any]any
   193  		want map[Human]Human
   194  	}{
   195  		{nil, nil},
   196  		{map[any]any{}, map[Human]Human{}},
   197  		{map[any]any{nil: nil}, map[Human]Human{nil: nil}},
   198  		{map[any]any{0: 0, nil: nil}, map[Human]Human{nil: nil}},
   199  		{map[any]any{0: 0, nil: nil, 1: 0, nil: nil}, map[Human]Human{nil: nil, nil: nil}},
   200  		{map[any]any{1: 1, 0: 0, &Dog{}: &Dog{}, &Male{}: &Male{}, Dog{}: Dog{}, Male{}: Male{}}, map[Human]Human{&Male{}: &Male{}, Male{}: Male{}}},
   201  		{map[any]any{1: 1, 2: 2, zeroDog: &zeroDog, zeroMale: &zeroMale}, map[Human]Human{zeroMale: &zeroMale}},
   202  		{map[any]any{1: 1, 2: 2, zeroDog: &zeroMale, zeroDog: &zeroMale}, map[Human]Human{}},
   203  	}
   204  	for _, tt := range tests {
   205  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
   206  			{
   207  				copy := maps.Clone(tt.data)
   208  				got := maps_.TypeAssertFilter[map[any]any, map[Human]Human](copy)
   209  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
   210  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) = %v, want %v", tt.data, got, tt.want)
   211  					return
   212  				}
   213  				if len(got) != len(tt.want) {
   214  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) = %v, want %v", tt.data, got, tt.want)
   215  					return
   216  				}
   217  
   218  				for k, v := range got {
   219  					if reflect.TypeOf(v) != reflect.TypeOf(tt.want[k]) {
   220  						t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) =[%d]: %v, want %v", tt.data, k, reflect.TypeOf(v).String(), reflect.TypeOf(tt.want[k]).String())
   221  					}
   222  				}
   223  			}
   224  		})
   225  	}
   226  }
   227  
   228  func TestTypeAssertFilterFuncConvert(t *testing.T) {
   229  	var zeroDog Dog
   230  	var zeroMale Male
   231  	_ = zeroDog
   232  	_ = zeroMale
   233  	tests := []struct {
   234  		data map[any]any
   235  		want map[Human]Human
   236  	}{
   237  		{nil, nil},
   238  		{map[any]any{}, map[Human]Human{}},
   239  		{map[any]any{nil: nil}, map[Human]Human{nil: nil}},
   240  		{map[any]any{0: 0, nil: nil}, map[Human]Human{nil: nil}},
   241  		{map[any]any{0: 0, nil: nil, 1: 0, nil: nil}, map[Human]Human{nil: nil, nil: nil}},
   242  		{map[any]any{1: 1, 0: 0, &Dog{}: &Dog{}, &Male{}: &Male{}, Dog{}: Dog{}, Male{}: Male{}}, map[Human]Human{&Male{}: &Male{}, Male{}: Male{}}},
   243  		{map[any]any{1: 1, 2: 2, zeroDog: &zeroDog, zeroMale: &zeroMale}, map[Human]Human{zeroMale: &zeroMale}},
   244  		{map[any]any{1: 1, 2: 2, zeroDog: &zeroMale, zeroDog: &zeroMale}, map[Human]Human{}},
   245  	}
   246  	for _, tt := range tests {
   247  		t.Run(fmt.Sprintf("%v", tt.data), func(t *testing.T) {
   248  			{
   249  				copy := maps.Clone(tt.data)
   250  				got := maps_.TypeAssertFilterFunc[map[any]any, map[Human]Human](copy, func(k any, v any) (Human, Human, bool) {
   251  					k2, ok := k.(Human)
   252  					v2, ov := v.(Human)
   253  					return k2, v2, (ok || k == nil) && (ov || v == nil)
   254  				})
   255  				if (got == nil && tt.data != nil) || (got != nil && tt.data == nil) {
   256  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) = %v, want %v", tt.data, got, tt.want)
   257  					return
   258  				}
   259  				if len(got) != len(tt.want) {
   260  					t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) = %v, want %v", tt.data, got, tt.want)
   261  					return
   262  				}
   263  
   264  				for k, v := range got {
   265  					if reflect.TypeOf(v) != reflect.TypeOf(tt.want[k]) {
   266  						t.Errorf("maps_.TypeAssertFilterFunc(%v, func(e any) (Human, bool) {h, ok := e.(Human); return h, ok}) =[%d]: %v, want %v", tt.data, k, reflect.TypeOf(v).String(), reflect.TypeOf(tt.want[k]).String())
   267  					}
   268  				}
   269  			}
   270  		})
   271  	}
   272  }
   273  
   274  type Animal interface {
   275  	Kind() string
   276  }
   277  type Human interface {
   278  	Name() string
   279  	Animal
   280  }
   281  
   282  var _ Human = (*Male)(nil)
   283  
   284  type Male struct{}
   285  
   286  func (m Male) Kind() string {
   287  	return "male"
   288  }
   289  
   290  func (Male) Name() string {
   291  	return "bob"
   292  }
   293  
   294  var _ Animal = (*Dog)(nil)
   295  
   296  type Dog struct{}
   297  
   298  func (d Dog) Kind() string {
   299  	return "dog"
   300  }