2014-10-06 22:29:52 +00:00
|
|
|
package seq
|
|
|
|
|
|
|
|
import (
|
|
|
|
. "testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/mediocregopher/ginger/types"
|
|
|
|
)
|
|
|
|
|
2014-10-19 00:03:16 +00:00
|
|
|
// Test that Lazy implements types.Elem (compile-time check)
|
|
|
|
func TestLazyElem(t *T) {
|
|
|
|
_ = types.Elem(NewLazy(nil))
|
|
|
|
}
|
|
|
|
|
2014-10-06 22:29:52 +00:00
|
|
|
// Test lazy operation and thread-safety
|
|
|
|
func TestLazyBasic(t *T) {
|
2014-10-19 00:03:16 +00:00
|
|
|
ch := make(chan types.GoType)
|
2014-10-06 22:29:52 +00:00
|
|
|
mapfn := func(el types.Elem) types.Elem {
|
2014-10-19 00:03:16 +00:00
|
|
|
i := el.(types.GoType)
|
2014-10-06 22:29:52 +00:00
|
|
|
ch <- i
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
2014-10-19 00:03:16 +00:00
|
|
|
intl := elemSliceV(0, 1, 2, 3, 4)
|
2014-10-06 22:29:52 +00:00
|
|
|
l := NewList(intl...)
|
|
|
|
ml := LMap(mapfn, l)
|
|
|
|
|
2014-10-19 00:03:16 +00:00
|
|
|
// ml is a lazy list of intl, which will write to ch the first time any of
|
|
|
|
// the elements are read. This for loop ensures ml is thread-safe
|
2014-10-06 22:29:52 +00:00
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
go func() {
|
|
|
|
mlintl := ToSlice(ml)
|
|
|
|
if !intSlicesEq(mlintl, intl) {
|
|
|
|
panic("contents not right")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2014-10-19 00:03:16 +00:00
|
|
|
// This loop and subsequent close ensure that ml only ever "creates" each
|
|
|
|
// element once
|
2014-10-06 22:29:52 +00:00
|
|
|
for _, el := range intl {
|
|
|
|
select {
|
|
|
|
case elch := <-ch:
|
|
|
|
assertValue(el, elch, t)
|
|
|
|
case <-time.After(1 * time.Millisecond):
|
|
|
|
t.Fatalf("Took too long reading result")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that arbitrary Seqs can turn into Lazy
|
|
|
|
func TestToLazy(t *T) {
|
2014-10-19 00:03:16 +00:00
|
|
|
intl := elemSliceV(0, 1, 2, 3, 4)
|
2014-10-06 22:29:52 +00:00
|
|
|
l := NewList(intl...)
|
|
|
|
ll := ToLazy(l)
|
|
|
|
assertSeqContents(ll, intl, t)
|
|
|
|
}
|