github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/internal/examples/sliceexamples/slice_examples_test.go (about)

     1  package sliceexamples
     2  
     3  import (
     4  	"strconv"
     5  	// "strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  
    10  	"github.com/m4gshm/gollections/op"
    11  	"github.com/m4gshm/gollections/predicate/one"
    12  	"github.com/m4gshm/gollections/slice"
    13  	"github.com/m4gshm/gollections/slice/clone"
    14  	"github.com/m4gshm/gollections/slice/convert"
    15  	"github.com/m4gshm/gollections/slice/filter"
    16  
    17  	// "github.com/m4gshm/gollections/slice/flat"
    18  	// "github.com/m4gshm/gollections/slice/group"
    19  	"github.com/m4gshm/gollections/slice/reverse"
    20  )
    21  
    22  // func Test_GroupBySeveralKeysAndConvertMapValues(t *testing.T) {
    23  // 	namesByRole := group.ByMultipleKeys(users, func(u User) []string {
    24  // 		return convert.AndConvert(u.Roles(), Role.Name, strings.ToLower)
    25  // 	}, User.Name)
    26  
    27  // 	assert.Equal(t, namesByRole[""], []string{"Tom"})
    28  // 	assert.Equal(t, namesByRole["manager"], []string{"Bob", "Alice"})
    29  // 	assert.Equal(t, namesByRole["admin"], []string{"Bob"})
    30  // }
    31  
    32  // func Test_FindFirsManager(t *testing.T) {
    33  // 	alice, _ := slice.First(users, func(user User) bool {
    34  // 		roles := slice.Convert(user.Roles(), Role.Name)
    35  // 		return slice.Contains(roles, "Manager")
    36  // 	})
    37  
    38  // 	assert.Equal(t, "Alice", alice.Name())
    39  // }
    40  
    41  // func Test_AggregateFilteredRoles(t *testing.T) {
    42  // 	roles := flat.AndConvert(users, User.Roles, Role.Name)
    43  // 	roleNamesExceptManager := slice.Filter(roles, not.Eq("Manager"))
    44  
    45  // 	assert.Equal(t, slice.Of("Admin", "manager"), roleNamesExceptManager)
    46  // }
    47  
    48  func Test_SortStructs(t *testing.T) {
    49  
    50  	var users = []User{
    51  		{name: "Bob", age: 26},
    52  		{name: "Alice", age: 35},
    53  		{name: "Tom", age: 18},
    54  		{name: "Chris", age: 41},
    55  	}
    56  	var byName = slice.Sort(slice.Clone(users), func(u1, u2 User) int { return op.Compare(u1.name, u2.name) })
    57  	var byAgeReverse = slice.Sort(slice.Clone(users), func(u1, u2 User) int { return -op.Compare(u1.age, u2.age) })
    58  
    59  	assert.Equal(t, []User{
    60  		{name: "Alice", age: 35},
    61  		{name: "Bob", age: 26},
    62  		{name: "Chris", age: 41},
    63  		{name: "Tom", age: 18},
    64  	}, byName)
    65  
    66  	assert.Equal(t, []User{
    67  		{name: "Chris", age: 41},
    68  		{name: "Alice", age: 35},
    69  		{name: "Bob", age: 26},
    70  		{name: "Tom", age: 18},
    71  	}, byAgeReverse)
    72  
    73  }
    74  
    75  func Test_Reverse(t *testing.T) {
    76  	assert.Equal(t, []int{-1, 0, 1, 2, 3}, slice.Reverse([]int{3, 2, 1, 0, -1}))
    77  	assert.Equal(t, []int{-1, 0, 1, 2, 3}, reverse.Of([]int{3, 2, 1, 0, -1}))
    78  }
    79  
    80  func Test_Clone(t *testing.T) {
    81  	type entity struct{ val string }
    82  	var (
    83  		entities = []*entity{{"first"}, {"second"}, {"third"}}
    84  		c        = clone.Of(entities)
    85  	)
    86  
    87  	assert.Equal(t, entities, c)
    88  	assert.NotSame(t, entities, c)
    89  
    90  	for i := range entities {
    91  		assert.Same(t, entities[i], c[i])
    92  	}
    93  }
    94  
    95  func Test_DeepClone(t *testing.T) {
    96  	type entity struct{ val string }
    97  	var (
    98  		entities = []*entity{{"first"}, {"second"}, {"third"}}
    99  		c        = clone.Deep(entities, clone.Ptr[entity])
   100  	)
   101  
   102  	assert.Equal(t, entities, c)
   103  	assert.NotSame(t, entities, c)
   104  
   105  	for i := range entities {
   106  		assert.Equal(t, entities[i], c[i])
   107  		assert.NotSame(t, entities[i], c[i])
   108  	}
   109  }
   110  
   111  var even = func(v int) bool { return v%2 == 0 }
   112  
   113  func Test_ConvertFiltered(t *testing.T) {
   114  	var (
   115  		source   = []int{1, 3, 4, 5, 7, 8, 9, 11}
   116  		result   = filter.AndConvert(source, even, strconv.Itoa)
   117  		expected = []string{"4", "8"}
   118  	)
   119  	assert.Equal(t, expected, result)
   120  }
   121  
   122  func Test_FilterConverted(t *testing.T) {
   123  	var (
   124  		source = []int{1, 3, 4, 5, 7, 8, 9, 11}
   125  		result = convert.AndFilter(source, strconv.Itoa, func(s string) bool {
   126  			return len(s) == 2
   127  		})
   128  		expected = []string{"11"}
   129  	)
   130  	assert.Equal(t, expected, result)
   131  }
   132  
   133  func Test_ConvertNilSafe(t *testing.T) {
   134  	type entity struct{ val *string }
   135  	var (
   136  		first  = "first"
   137  		third  = "third"
   138  		fifth  = "fifth"
   139  		source = []*entity{{&first}, {}, {&third}, nil, {&fifth}}
   140  		result = convert.NilSafe(source, func(e *entity) *string {
   141  			return e.val
   142  		})
   143  		expected = []*string{&first, &third, &fifth}
   144  	)
   145  	assert.Equal(t, expected, result)
   146  }
   147  
   148  func Test_ConvertFilteredWithIndexInPlace(t *testing.T) {
   149  	var (
   150  		source = slice.Of(1, 3, 4, 5, 7, 8, 9, 11)
   151  		result = convert.CheckIndexed(source, func(index int, elem int) (string, bool) {
   152  			return strconv.Itoa(index + elem), even(elem)
   153  		})
   154  		expected = []string{"6", "13"}
   155  	)
   156  	assert.Equal(t, expected, result)
   157  }
   158  
   159  func Test_Slice_Filter(t *testing.T) {
   160  
   161  	var even = slice.Filter([]int{1, 2, 3, 4, 5, 6}, func(v int) bool { return v%2 == 0 })
   162  	//[]int{2, 4, 6}
   163  
   164  	assert.Equal(t, []int{2, 4, 6}, even)
   165  }
   166  
   167  func Test_FilterNotNil(t *testing.T) {
   168  	type entity struct{ val string }
   169  	var (
   170  		source   = []*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}
   171  		result   = slice.NotNil(source)
   172  		expected = []*entity{{"first"}, {"third"}, {"fifth"}}
   173  	)
   174  	assert.Equal(t, expected, result)
   175  }
   176  
   177  func Test_ConvertPointersToValues(t *testing.T) {
   178  	type entity struct{ val string }
   179  	var (
   180  		source   = []*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}
   181  		result   = slice.ToValues(source)
   182  		expected = []entity{{"first"}, {}, {"third"}, {}, {"fifth"}}
   183  	)
   184  	assert.Equal(t, expected, result)
   185  }
   186  
   187  func Test_ConvertNotnilPointersToValues(t *testing.T) {
   188  	type entity struct{ val string }
   189  	var (
   190  		source   = []*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}
   191  		result   = slice.GetValues(source)
   192  		expected = []entity{{"first"}, {"third"}, {"fifth"}}
   193  	)
   194  	assert.Equal(t, expected, result)
   195  }
   196  
   197  func Test_Xor(t *testing.T) {
   198  	result := slice.Filter(slice.Of(1, 3, 5, 7, 9, 11), one.Of(1, 3, 5, 7).Xor(one.Of(7, 9, 11)))
   199  	assert.Equal(t, slice.Of(1, 3, 5, 9, 11), result)
   200  }
   201  
   202  func Test_BehaveAsStrings(t *testing.T) {
   203  	type (
   204  		TypeBasedOnString      string
   205  		ArrayTypeBasedOnString []TypeBasedOnString
   206  	)
   207  
   208  	var (
   209  		source   = ArrayTypeBasedOnString{"1", "2", "3"}
   210  		result   = slice.BehaveAsStrings(source)
   211  		expected = []string{"1", "2", "3"}
   212  	)
   213  
   214  	assert.Equal(t, expected, result)
   215  }
   216  
   217  type rows[T any] struct {
   218  	row    []T
   219  	cursor int
   220  }
   221  
   222  func (r *rows[T]) hasNext() bool    { return r.cursor < len(r.row) }
   223  func (r *rows[T]) next() (T, error) { e := r.row[r.cursor]; r.cursor++; return e, nil }
   224  
   225  func Test_OfLoop(t *testing.T) {
   226  	var (
   227  		stream    = &rows[int]{slice.Of(1, 2, 3), 0}
   228  		result, _ = slice.OfLoop(stream, (*rows[int]).hasNext, (*rows[int]).next)
   229  		expected  = slice.Of(1, 2, 3)
   230  	)
   231  	assert.Equal(t, expected, result)
   232  }