Skip to content

Commit

Permalink
Send func (#88)
Browse files Browse the repository at this point in the history
Fixes #84
  • Loading branch information
zhiburt authored and elliotchance committed May 5, 2019
1 parent e441a35 commit 57366d4
Show file tree
Hide file tree
Showing 15 changed files with 580 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ This will only generate `myInts.Average`, `myInts.Sum` and `myStrings.Select`.
| `Min` ||| | | n | The minimum value, or a zeroed value. |
| `Random` |||| | 1 | Select a random element, or a zeroed value if empty. |
| `Reverse` |||| | n | Reverse elements. |
| `Send` |||| | n | Send all element to channel. |
| `Select` |||| | n | A new slice containing only the elements that returned true from the condition. |
| `Sort` ||| | | n⋅log(n) | Return a new sorted slice. |
| `Sum` | || | | n | Sum (total) of all elements. |
Expand Down
1 change: 1 addition & 0 deletions functions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var Functions = []struct {
{"Min", "min.go", ForNumbersAndStrings},
{"Random", "random.go", ForAll},
{"Reverse", "reverse.go", ForAll},
{"Send", "send.go", ForAll},
{"Select", "select.go", ForAll},
{"Sort", "sort.go", ForNumbersAndStrings},
{"Sum", "sum.go", ForNumbers},
Expand Down
24 changes: 24 additions & 0 deletions functions/send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package functions

import (
"context"
)

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
// it locks execution of gorutine
// it doesn't close channel after work
// returns sended elements if len(this) != len(old) considered func was canceled
func (ss SliceType) Send(ctx context.Context, ch chan<- ElementType) SliceType {
for i, s := range ss {
select {
case <-ctx.Done():
return ss[:i]
default:
ch <- s
}
}

return ss
}
20 changes: 20 additions & 0 deletions pie/carpointers_pie.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pie

import (
"context"
"encoding/json"
"github.com/elliotchance/pie/pie/util"
"math/rand"
Expand Down Expand Up @@ -194,6 +195,25 @@ func (ss carPointers) Reverse() carPointers {
return sorted
}

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
// it locks execution of gorutine
// it doesn't close channel after work
// returns sended elements if len(this) != len(old) considered func was canceled
func (ss carPointers) Send(ctx context.Context, ch chan<- *car) carPointers {
for i, s := range ss {
select {
case <-ctx.Done():
return ss[:i]
default:
ch <- s
}
}

return ss
}

// Select will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
Expand Down
50 changes: 50 additions & 0 deletions pie/carpointers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/rand"
"strings"
"testing"
"time"

"github.com/elliotchance/testify-stats/assert"
)
Expand Down Expand Up @@ -628,3 +629,52 @@ func TestCarPointers_Random(t *testing.T) {
})
}
}

var carPointersSendTests = []struct {
ss carPointers
recieveDelay time.Duration
canceledDelay time.Duration
expected carPointers
}{
{
nil,
0,
0,
nil,
},
{
carPointers{&car{"bar", "yellow"}, &car{"Baz", "black"}},
0,
0,
carPointers{&car{"bar", "yellow"}, &car{"Baz", "black"}},
},
{
carPointers{&car{"bar", "yellow"}, &car{"Baz", "black"}},
time.Millisecond * 30,
time.Millisecond * 10,
carPointers{&car{"bar", "yellow"}},
},
{
carPointers{&car{"bar", "yellow"}, &car{"Baz", "black"}},
time.Millisecond * 3,
time.Millisecond * 10,
carPointers{&car{"bar", "yellow"}, &car{"Baz", "black"}},
},
}

func TestCarPointers_Send(t *testing.T) {
for _, test := range carPointersSendTests {
t.Run("", func(t *testing.T) {
defer assertImmutableCarPointers(t, &test.ss)()
ch := make(chan *car)
actual := getCarPointersFromChan(ch, test.recieveDelay)
ctx := createContextByDelay(test.canceledDelay)

actualSended := test.ss.Send(ctx, ch)
close(ch)

assert.Equal(t, test.expected, actualSended)
assert.Equal(t, test.expected, actual())
})
}
}
20 changes: 20 additions & 0 deletions pie/cars_pie.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pie

import (
"context"
"encoding/json"
"github.com/elliotchance/pie/pie/util"
"math/rand"
Expand Down Expand Up @@ -194,6 +195,25 @@ func (ss cars) Reverse() cars {
return sorted
}

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
// it locks execution of gorutine
// it doesn't close channel after work
// returns sended elements if len(this) != len(old) considered func was canceled
func (ss cars) Send(ctx context.Context, ch chan<- car) cars {
for i, s := range ss {
select {
case <-ctx.Done():
return ss[:i]
default:
ch <- s
}
}

return ss
}

// Select will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
Expand Down
50 changes: 50 additions & 0 deletions pie/cars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/rand"
"strings"
"testing"
"time"

"github.com/elliotchance/testify-stats/assert"
)
Expand Down Expand Up @@ -612,3 +613,52 @@ func TestCars_Random(t *testing.T) {
})
}
}

var carsSendTests = []struct {
ss cars
recieveDelay time.Duration
canceledDelay time.Duration
expected cars
}{
{
nil,
0,
0,
nil,
},
{
cars{car{"bar", "yellow"}, car{"Baz", "black"}},
0,
0,
cars{car{"bar", "yellow"}, car{"Baz", "black"}},
},
{
cars{car{"bar", "yellow"}, car{"Baz", "black"}},
time.Millisecond * 30,
time.Millisecond * 10,
cars{car{"bar", "yellow"}},
},
{
cars{car{"bar", "yellow"}, car{"Baz", "black"}},
time.Millisecond * 3,
time.Millisecond * 10,
cars{car{"bar", "yellow"}, car{"Baz", "black"}},
},
}

func TestCar_Send(t *testing.T) {
for _, test := range carsSendTests {
t.Run("", func(t *testing.T) {
defer assertImmutableCars(t, &test.ss)()
ch := make(chan car)
actual := getCarsFromChan(ch, test.recieveDelay)
ctx := createContextByDelay(test.canceledDelay)

actualSended := test.ss.Send(ctx, ch)
close(ch)

assert.Equal(t, test.expected, actualSended)
assert.Equal(t, test.expected, actual())
})
}
}
20 changes: 20 additions & 0 deletions pie/float64s_pie.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pie

import (
"context"
"encoding/json"
"github.com/elliotchance/pie/pie/util"
"math"
Expand Down Expand Up @@ -285,6 +286,25 @@ func (ss Float64s) Reverse() Float64s {
return sorted
}

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
// it locks execution of gorutine
// it doesn't close channel after work
// returns sended elements if len(this) != len(old) considered func was canceled
func (ss Float64s) Send(ctx context.Context, ch chan<- float64) Float64s {
for i, s := range ss {
select {
case <-ctx.Done():
return ss[:i]
default:
ch <- s
}
}

return ss
}

// Select will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
Expand Down
50 changes: 50 additions & 0 deletions pie/float64s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"testing"
"time"

"github.com/elliotchance/testify-stats/assert"
)
Expand Down Expand Up @@ -757,3 +758,52 @@ func TestFloat64s_Abs(t *testing.T) {
})
}
}

var float64sSendTests = []struct {
ss Float64s
recieveDelay time.Duration
canceledDelay time.Duration
expected Float64s
}{
{
nil,
0,
0,
nil,
},
{
Float64s{1.2, 3.2},
0,
0,
Float64s{1.2, 3.2},
},
{
Float64s{1.2, 3.2},
time.Millisecond * 30,
time.Millisecond * 10,
Float64s{1.2},
},
{
Float64s{1.2, 3.2},
time.Millisecond * 3,
time.Millisecond * 10,
Float64s{1.2, 3.2},
},
}

func TestFloat64s_Send(t *testing.T) {
for _, test := range float64sSendTests {
t.Run("", func(t *testing.T) {
defer assertImmutableFloat64s(t, &test.ss)()
ch := make(chan float64)
actual := getFloat64sFromChan(ch, test.recieveDelay)
ctx := createContextByDelay(test.canceledDelay)

actualSended := test.ss.Send(ctx, ch)
close(ch)

assert.Equal(t, test.expected, actualSended)
assert.Equal(t, test.expected, actual())
})
}
}
20 changes: 20 additions & 0 deletions pie/ints_pie.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pie

import (
"context"
"encoding/json"
"github.com/elliotchance/pie/pie/util"
"math"
Expand Down Expand Up @@ -285,6 +286,25 @@ func (ss Ints) Reverse() Ints {
return sorted
}

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
// it locks execution of gorutine
// it doesn't close channel after work
// returns sended elements if len(this) != len(old) considered func was canceled
func (ss Ints) Send(ctx context.Context, ch chan<- int) Ints {
for i, s := range ss {
select {
case <-ctx.Done():
return ss[:i]
default:
ch <- s
}
}

return ss
}

// Select will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
Expand Down
Loading

0 comments on commit 57366d4

Please sign in to comment.