github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/break/loop/test/api_test.go (about)

     1  package test
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  
    10  	breakKvLoop "github.com/m4gshm/gollections/break/kv/loop"
    11  	breakLoop "github.com/m4gshm/gollections/break/loop"
    12  	"github.com/m4gshm/gollections/convert/as"
    13  	"github.com/m4gshm/gollections/loop"
    14  	"github.com/m4gshm/gollections/loop/convert"
    15  	"github.com/m4gshm/gollections/op"
    16  	"github.com/m4gshm/gollections/predicate/eq"
    17  	"github.com/m4gshm/gollections/predicate/more"
    18  	"github.com/m4gshm/gollections/slice"
    19  )
    20  
    21  func Test_ReduceSum(t *testing.T) {
    22  	s := loop.Of(1, 3, 5, 7, 9, 11)
    23  	r, _ := breakLoop.Reduce(breakLoop.From(s), op.Sum[int])
    24  	assert.Equal(t, 1+3+5+7+9+11, r)
    25  }
    26  
    27  func Test_ReduceeSum(t *testing.T) {
    28  	s := loop.Of(1, 3, 5, 7, 9, 11)
    29  	r, _ := breakLoop.Reducee(breakLoop.From(s), func(i1, i2 int) (int, error) {
    30  		return i1 + i2, nil
    31  	})
    32  	assert.Equal(t, 1+3+5+7+9+11, r)
    33  }
    34  
    35  func Test_EmptyLoop(t *testing.T) {
    36  	s := breakLoop.Of[int]()
    37  	r, _ := breakLoop.Reduce(s, op.Sum[int])
    38  	assert.Equal(t, 0, r)
    39  }
    40  
    41  func Test_Sum(t *testing.T) {
    42  	s := loop.Of(1, 3, 5, 7, 9, 11)
    43  	r, _ := breakLoop.Sum(breakLoop.From(s))
    44  	assert.Equal(t, 1+3+5+7+9+11, r)
    45  }
    46  
    47  func Test_Convert(t *testing.T) {
    48  	s := loop.Of(1, 3, 5, 7, 9, 11)
    49  	r := breakLoop.Convert(breakLoop.From(s), strconv.Itoa)
    50  	o, _ := breakLoop.Slice(r)
    51  	assert.Equal(t, []string{"1", "3", "5", "7", "9", "11"}, o)
    52  }
    53  
    54  func Test_IterWitErr(t *testing.T) {
    55  	s := breakLoop.From(loop.Of("1", "3", "5", "7eee", "9", "11"))
    56  	r := []int{}
    57  	var outErr error
    58  	for {
    59  		it := breakLoop.Conv(s, strconv.Atoi)
    60  		i, ok, err := it()
    61  		if err != nil {
    62  			assert.False(t, ok)
    63  			outErr = err
    64  			break
    65  		}
    66  		r = append(r, i)
    67  	}
    68  
    69  	assert.Error(t, outErr)
    70  	assert.Equal(t, []int{1, 3, 5}, r)
    71  
    72  	s = breakLoop.From(loop.Of("1", "3", "5", "7eee", "9", "11"))
    73  	r = []int{}
    74  	//ignore err
    75  	for {
    76  		it := breakLoop.Conv(s, strconv.Atoi)
    77  		i, ok, err := it()
    78  		if !ok && err == nil {
    79  			break
    80  		}
    81  		if err == nil {
    82  			r = append(r, i)
    83  		}
    84  	}
    85  	assert.Equal(t, []int{1, 3, 5, 9, 11}, r)
    86  }
    87  
    88  func Test_NotNil(t *testing.T) {
    89  	type entity struct{ val string }
    90  	var (
    91  		source   = breakLoop.Of([]*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}...)
    92  		result   = breakLoop.NotNil(source)
    93  		expected = []*entity{{"first"}, {"third"}, {"fifth"}}
    94  	)
    95  	o, _ := breakLoop.Slice(result)
    96  	assert.Equal(t, expected, o)
    97  }
    98  
    99  func Test_ConvertPointersToValues(t *testing.T) {
   100  	type entity struct{ val string }
   101  	var (
   102  		source   = breakLoop.Of([]*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}...)
   103  		result   = breakLoop.PtrVal(source)
   104  		expected = []entity{{"first"}, {}, {"third"}, {}, {"fifth"}}
   105  	)
   106  	o, _ := breakLoop.Slice(result)
   107  	assert.Equal(t, expected, o)
   108  }
   109  
   110  func Test_ConvertNotnilPointersToValues(t *testing.T) {
   111  	type entity struct{ val string }
   112  	var (
   113  		source   = breakLoop.Of([]*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}...)
   114  		result   = breakLoop.NoNilPtrVal(source)
   115  		expected = []entity{{"first"}, {"third"}, {"fifth"}}
   116  	)
   117  	o, _ := breakLoop.Slice(result)
   118  	assert.Equal(t, expected, o)
   119  }
   120  
   121  func Test_ConvertNotNil(t *testing.T) {
   122  	type entity struct{ val string }
   123  	var (
   124  		source   = loop.Of([]*entity{{"first"}, nil, {"third"}, nil, {"fifth"}}...)
   125  		result   = convert.NotNil(source, func(e *entity) string { return e.val })
   126  		expected = []string{"first", "third", "fifth"}
   127  	)
   128  	assert.Equal(t, expected, loop.Slice(result))
   129  }
   130  
   131  func Test_ConvertToNotNil(t *testing.T) {
   132  	type entity struct{ val *string }
   133  	var (
   134  		first    = "first"
   135  		third    = "third"
   136  		fifth    = "fifth"
   137  		source   = loop.Of([]entity{{&first}, {}, {&third}, {}, {&fifth}}...)
   138  		result   = convert.ToNotNil(source, func(e entity) *string { return e.val })
   139  		expected = []*string{&first, &third, &fifth}
   140  	)
   141  	assert.Equal(t, expected, loop.Slice(result))
   142  }
   143  
   144  func Test_ConvertNilSafe(t *testing.T) {
   145  	type entity struct{ val *string }
   146  	var (
   147  		first    = "first"
   148  		third    = "third"
   149  		fifth    = "fifth"
   150  		source   = loop.Of([]*entity{{&first}, {}, {&third}, nil, {&fifth}}...)
   151  		result   = convert.NilSafe(source, func(e *entity) *string { return e.val })
   152  		expected = []*string{&first, &third, &fifth}
   153  	)
   154  	assert.Equal(t, expected, loop.Slice(result))
   155  }
   156  
   157  var even = func(v int) bool { return v%2 == 0 }
   158  
   159  func Test_ConvertFiltered(t *testing.T) {
   160  	s := loop.Of(1, 3, 4, 5, 7, 8, 9, 11)
   161  	r := breakLoop.FilterAndConvert(breakLoop.From(s), even, strconv.Itoa)
   162  	o, _ := breakLoop.Slice(r)
   163  	assert.Equal(t, []string{"4", "8"}, o)
   164  }
   165  
   166  func Test_ConvertFilteredInplace(t *testing.T) {
   167  	s := loop.Of(1, 3, 4, 5, 7, 8, 9, 11)
   168  	r := breakLoop.ConvCheck(breakLoop.From(s), func(i int) (string, bool, error) { return strconv.Itoa(i), even(i), nil })
   169  	o, _ := breakLoop.Slice(r)
   170  	assert.Equal(t, []string{"4", "8"}, o)
   171  }
   172  
   173  func Test_Flatt(t *testing.T) {
   174  	md := loop.Of([][]int{{1, 2, 3}, {4}, {5, 6}}...)
   175  	f := breakLoop.Flat(breakLoop.From(md), as.Is)
   176  	e := []int{1, 2, 3, 4, 5, 6}
   177  	o, _ := breakLoop.Slice(f)
   178  	assert.Equal(t, e, o)
   179  }
   180  
   181  func Test_FlattFilter(t *testing.T) {
   182  	md := loop.Of([][]int{{1, 2, 3}, {4}, {5, 6}}...)
   183  	f := breakLoop.FilterAndFlat(breakLoop.From(md), func(from []int) bool { return len(from) > 1 }, as.Is)
   184  	e := []int{1, 2, 3, 5, 6}
   185  	o, _ := breakLoop.Slice(f)
   186  	assert.Equal(t, e, o)
   187  }
   188  
   189  func Test_FlattElemFilter(t *testing.T) {
   190  	md := loop.Of([][]int{{1, 2, 3}, {4}, {5, 6}}...)
   191  	f := breakLoop.FlattAndFilter(breakLoop.From(md), as.Is, even)
   192  	e := []int{2, 4, 6}
   193  	o, _ := breakLoop.Slice(f)
   194  	assert.Equal(t, e, o)
   195  }
   196  
   197  func Test_FilterAndFlattFilt(t *testing.T) {
   198  	md := loop.Of([][]int{{1, 2, 3}, {4}, {5, 6}}...)
   199  	f := breakLoop.FilterFlatFilter(breakLoop.From(md), func(from []int) bool { return len(from) > 1 }, as.Is, even)
   200  	e := []int{2, 6}
   201  	o, _ := breakLoop.Slice(f)
   202  	assert.Equal(t, e, o)
   203  }
   204  
   205  func Test_Filter(t *testing.T) {
   206  	s := loop.Of(1, 3, 4, 5, 7, 8, 9, 11)
   207  	f := breakLoop.Filter(breakLoop.From(s), even)
   208  	e := []int{4, 8}
   209  	o, _ := breakLoop.Slice(f)
   210  	assert.Equal(t, e, o)
   211  }
   212  
   213  func Test_Filtering(t *testing.T) {
   214  	r := breakLoop.Filt(breakLoop.From(loop.Of(1, 2, 3, 4, 5, 6)), func(i int) (bool, error) { return i%2 == 0, nil })
   215  	o, _ := breakLoop.Slice(r)
   216  	assert.Equal(t, []int{2, 4, 6}, o)
   217  }
   218  
   219  func Test_MatchAny(t *testing.T) {
   220  	elements := loop.Of(1, 2, 3, 4)
   221  
   222  	ok, _ := breakLoop.HasAny(breakLoop.From(elements), eq.To(4))
   223  	assert.True(t, ok)
   224  
   225  	noOk, _ := breakLoop.HasAny(breakLoop.From(elements), more.Than(5))
   226  	assert.False(t, noOk)
   227  }
   228  
   229  type Role struct {
   230  	name string
   231  }
   232  
   233  type User struct {
   234  	name  string
   235  	age   int
   236  	roles []Role
   237  }
   238  
   239  func (u User) Name() string  { return u.name }
   240  func (u User) Age() int      { return u.age }
   241  func (u User) Roles() []Role { return u.roles }
   242  
   243  var users = []User{
   244  	{name: "Bob", age: 26, roles: []Role{{"Admin"}, {"manager"}}},
   245  	{name: "Alice", age: 35, roles: []Role{{"Manager"}}},
   246  	{name: "Tom", age: 18}, {},
   247  }
   248  
   249  func Test_KeyValuer(t *testing.T) {
   250  	m, _ := breakKvLoop.Group(breakLoop.KeyValue(breakLoop.From(loop.Of(users...)), User.Name, User.Age))
   251  
   252  	assert.Equal(t, m["Alice"], slice.Of(35))
   253  	assert.Equal(t, m["Bob"], slice.Of(26))
   254  	assert.Equal(t, m["Tom"], slice.Of(18))
   255  
   256  	g, _ := breakLoop.Group(breakLoop.From(loop.Of(users...)), User.Name, User.Age)
   257  	assert.Equal(t, m, g)
   258  }
   259  
   260  func Test_Keyer(t *testing.T) {
   261  	m, _ := breakKvLoop.Group(breakLoop.ExtraKey(breakLoop.From(loop.Of(users...)), User.Name))
   262  
   263  	assert.Equal(t, m["Alice"], slice.Of(users[1]))
   264  	assert.Equal(t, m["Bob"], slice.Of(users[0]))
   265  	assert.Equal(t, m["Tom"], slice.Of(users[2]))
   266  
   267  	g := loop.Group(loop.Of(users...), User.Name, as.Is)
   268  	assert.Equal(t, m, g)
   269  }
   270  
   271  func Test_Valuer(t *testing.T) {
   272  	bob, bobRoles, _, _ := breakLoop.ExtraValue(breakLoop.From(loop.Of(users...)), User.Roles)()
   273  
   274  	assert.Equal(t, bob, users[0])
   275  	assert.Equal(t, bobRoles, users[0].roles)
   276  }
   277  
   278  func Test_MultiValuer(t *testing.T) {
   279  	l := breakLoop.ExtraVals(breakLoop.From(loop.Of(users...)), User.Roles)
   280  	bob, bobRole, _, _ := l()
   281  	bob2, bobRole2, _, _ := l()
   282  
   283  	assert.Equal(t, bob, users[0])
   284  	assert.Equal(t, bob2, users[0])
   285  	assert.Equal(t, bobRole, users[0].roles[0])
   286  	assert.Equal(t, bobRole2, users[0].roles[1])
   287  }
   288  
   289  func Test_MultipleKeyValuer(t *testing.T) {
   290  	m, _ := breakKvLoop.Group(breakLoop.KeysValues(breakLoop.From(loop.Of(users...)),
   291  		func(u User) ([]string, error) {
   292  			return slice.Convert(u.roles, func(r Role) string { return strings.ToLower(r.name) }), nil
   293  		},
   294  		func(u User) ([]string, error) { return []string{u.name, strings.ToLower(u.name)}, nil },
   295  	))
   296  
   297  	assert.Equal(t, m["admin"], slice.Of("Bob", "bob"))
   298  	assert.Equal(t, m["manager"], slice.Of("Bob", "bob", "Alice", "alice"))
   299  	assert.Equal(t, m[""], slice.Of("Tom", "tom", "", ""))
   300  }