Recv is a smuggler operator. It reads from a channel or a pointer
to a channel and compares the read value to expectedValue.
expectedValue can be any value including a TestDeep operator. It
can also be RecvNothing to test nothing can be read from the
channel or RecvClosed to check the channel is closed.
If timeout is passed it should be only one item. It means: try to
read the channel during this duration to get a value before giving
up. If timeout is missing or ≤ 0, it defaults to 0 meaning Recv
does not wait for a value but gives up instantly if no value is
available on the channel.
ch:=make(chanint,6)td.Cmp(t,ch,td.Recv(td.RecvNothing))// succeedstd.Cmp(t,ch,td.Recv(42))// fails, nothing to receive// recv(DATA): values differ// got: nothing received on channel// expected: 42ch<-42td.Cmp(t,ch,td.Recv(td.RecvNothing))// fails, 42 received instead// recv(DATA): values differ// got: 42// expected: nothing received on channeltd.Cmp(t,ch,td.Recv(42))// fails, nothing to receive anymore// recv(DATA): values differ// got: nothing received on channel// expected: 42ch<-666td.Cmp(t,ch,td.Recv(td.Between(600,700)))// succeedsclose(ch)td.Cmp(t,ch,td.Recv(td.RecvNothing))// fails as channel is closed// recv(DATA): values differ// got: channel is closed// expected: nothing received on channeltd.Cmp(t,ch,td.Recv(td.RecvClosed))// succeeds
Note that for convenience Recv accepts pointer on channel:
Each time Recv is called, it tries to consume one item from the
channel, immediately or, if given, before timeout duration. To
consume several items in a same Cmp call, one can use All
operator as in:
note that in case of success, the above Cmp call always lasts 100ms.
To check 42 can be received from channel ch during the next 100ms
(if nothing is received during these 100ms or something different
from 42, including a close, it fails):
td.Cmp(t,ch,td.Recv(42,100*time.Millisecond))
note that in case of success, the above Cmp call lasts less than 100ms.
A nil channel is not handled specifically, so it “is never ready
for communication” as specification says:
varchchaninttd.Cmp(t,ch,td.Recv(td.RecvNothing))// always succeedstd.Cmp(t,ch,td.Recv(42))// or any other value, always failstd.Cmp(t,ch,td.Recv(td.RecvClosed))// always fails
so to check if a channel is not nil before reading from it, one can
either do:
t:=&testing.T{}got:=make(chanint,3)ok:=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=td.Cmp(t,got,td.Recv(1))fmt.Println("1st receive is 1:",ok)ok=td.Cmp(t,got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
ChannelPointer example
t:=&testing.T{}got:=make(chanint,3)ok:=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=td.Cmp(t,&got,td.Recv(1))fmt.Println("1st receive is 1:",ok)ok=td.Cmp(t,&got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
WithTimeout example
t:=&testing.T{}got:=make(chanint,1)tick:=make(chanstruct{})gofunc(){// ①<-ticktime.Sleep(100*time.Millisecond)got<-0// ②<-ticktime.Sleep(100*time.Millisecond)got<-1// ③<-ticktime.Sleep(100*time.Millisecond)close(got)}()td.Cmp(t,got,td.Recv(td.RecvNothing))// ①tick<-struct{}{}ok:=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("① RecvNothing:",ok)ok=td.Cmp(t,got,td.Recv(0,150*time.Millisecond))fmt.Println("① receive 0 w/150ms timeout:",ok)ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("① RecvNothing:",ok)// ②tick<-struct{}{}ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("② RecvNothing:",ok)ok=td.Cmp(t,got,td.Recv(1,150*time.Millisecond))fmt.Println("② receive 1 w/150ms timeout:",ok)ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("② RecvNothing:",ok)// ③tick<-struct{}{}ok=td.Cmp(t,got,td.Recv(td.RecvNothing))fmt.Println("③ RecvNothing:",ok)ok=td.Cmp(t,got,td.Recv(td.RecvClosed,150*time.Millisecond))fmt.Println("③ check closed w/150ms timeout:",ok)// Output:// ① RecvNothing: true// ① receive 0 w/150ms timeout: true// ① RecvNothing: true// ② RecvNothing: true// ② receive 1 w/150ms timeout: true// ② RecvNothing: true// ③ RecvNothing: true// ③ check closed w/150ms timeout: true
NilChannel example
t:=&testing.T{}varchchanintok:=td.Cmp(t,ch,td.Recv(td.RecvNothing))fmt.Println("nothing to receive from nil channel:",ok)ok=td.Cmp(t,ch,td.Recv(42))fmt.Println("something to receive from nil channel:",ok)ok=td.Cmp(t,ch,td.Recv(td.RecvClosed))fmt.Println("is a nil channel closed:",ok)// Output:// nothing to receive from nil channel: true// something to receive from nil channel: false// is a nil channel closed: false
args… are optional and allow to name the test. This name is
used in case of failure to qualify the test. If len(args) > 1 and
the first item of args is a string and contains a ‘%’ rune then
fmt.Fprintf is used to compose the name, else args are passed to
fmt.Fprint. Do not forget it is the name of the test, not the
reason of a potential failure.
t:=&testing.T{}got:=make(chanint,3)ok:=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=td.CmpRecv(t,got,1,0)fmt.Println("1st receive is 1:",ok)ok=td.Cmp(t,got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
ChannelPointer example
t:=&testing.T{}got:=make(chanint,3)ok:=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=td.CmpRecv(t,&got,1,0)fmt.Println("1st receive is 1:",ok)ok=td.Cmp(t,&got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
WithTimeout example
t:=&testing.T{}got:=make(chanint,1)tick:=make(chanstruct{})gofunc(){// ①<-ticktime.Sleep(100*time.Millisecond)got<-0// ②<-ticktime.Sleep(100*time.Millisecond)got<-1// ③<-ticktime.Sleep(100*time.Millisecond)close(got)}()td.CmpRecv(t,got,td.RecvNothing,0)// ①tick<-struct{}{}ok:=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("① RecvNothing:",ok)ok=td.CmpRecv(t,got,0,150*time.Millisecond)fmt.Println("① receive 0 w/150ms timeout:",ok)ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("① RecvNothing:",ok)// ②tick<-struct{}{}ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("② RecvNothing:",ok)ok=td.CmpRecv(t,got,1,150*time.Millisecond)fmt.Println("② receive 1 w/150ms timeout:",ok)ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("② RecvNothing:",ok)// ③tick<-struct{}{}ok=td.CmpRecv(t,got,td.RecvNothing,0)fmt.Println("③ RecvNothing:",ok)ok=td.CmpRecv(t,got,td.RecvClosed,150*time.Millisecond)fmt.Println("③ check closed w/150ms timeout:",ok)// Output:// ① RecvNothing: true// ① receive 0 w/150ms timeout: true// ① RecvNothing: true// ② RecvNothing: true// ② receive 1 w/150ms timeout: true// ② RecvNothing: true// ③ RecvNothing: true// ③ check closed w/150ms timeout: true
NilChannel example
t:=&testing.T{}varchchanintok:=td.CmpRecv(t,ch,td.RecvNothing,0)fmt.Println("nothing to receive from nil channel:",ok)ok=td.CmpRecv(t,ch,42,0)fmt.Println("something to receive from nil channel:",ok)ok=td.CmpRecv(t,ch,td.RecvClosed,0)fmt.Println("is a nil channel closed:",ok)// Output:// nothing to receive from nil channel: true// something to receive from nil channel: false// is a nil channel closed: false
Recv optional parameter timeout is here mandatory.
0 value should be passed to mimic its absence in
original Recv call.
Returns true if the test is OK, false if it fails.
args… are optional and allow to name the test. This name is
used in case of failure to qualify the test. If len(args) > 1 and
the first item of args is a string and contains a ‘%’ rune then
fmt.Fprintf is used to compose the name, else args are passed to
fmt.Fprint. Do not forget it is the name of the test, not the
reason of a potential failure.
t:=td.NewT(&testing.T{})got:=make(chanint,3)ok:=t.Recv(got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=t.Recv(got,1,0)fmt.Println("1st receive is 1:",ok)ok=t.Cmp(got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=t.Recv(got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
ChannelPointer example
t:=td.NewT(&testing.T{})got:=make(chanint,3)ok:=t.Recv(got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)got<-1got<-2got<-3close(got)ok=t.Recv(&got,1,0)fmt.Println("1st receive is 1:",ok)ok=t.Cmp(&got,td.All(td.Recv(2),td.Recv(td.Between(3,4)),td.Recv(td.RecvClosed),))fmt.Println("next receives are 2, 3 then closed:",ok)ok=t.Recv(got,td.RecvNothing,0)fmt.Println("nothing to receive:",ok)// Output:// nothing to receive: true// 1st receive is 1: true// next receives are 2, 3 then closed: true// nothing to receive: false
WithTimeout example
t:=td.NewT(&testing.T{})got:=make(chanint,1)tick:=make(chanstruct{})gofunc(){// ①<-ticktime.Sleep(100*time.Millisecond)got<-0// ②<-ticktime.Sleep(100*time.Millisecond)got<-1// ③<-ticktime.Sleep(100*time.Millisecond)close(got)}()t.Recv(got,td.RecvNothing,0)// ①tick<-struct{}{}ok:=t.Recv(got,td.RecvNothing,0)fmt.Println("① RecvNothing:",ok)ok=t.Recv(got,0,150*time.Millisecond)fmt.Println("① receive 0 w/150ms timeout:",ok)ok=t.Recv(got,td.RecvNothing,0)fmt.Println("① RecvNothing:",ok)// ②tick<-struct{}{}ok=t.Recv(got,td.RecvNothing,0)fmt.Println("② RecvNothing:",ok)ok=t.Recv(got,1,150*time.Millisecond)fmt.Println("② receive 1 w/150ms timeout:",ok)ok=t.Recv(got,td.RecvNothing,0)fmt.Println("② RecvNothing:",ok)// ③tick<-struct{}{}ok=t.Recv(got,td.RecvNothing,0)fmt.Println("③ RecvNothing:",ok)ok=t.Recv(got,td.RecvClosed,150*time.Millisecond)fmt.Println("③ check closed w/150ms timeout:",ok)// Output:// ① RecvNothing: true// ① receive 0 w/150ms timeout: true// ① RecvNothing: true// ② RecvNothing: true// ② receive 1 w/150ms timeout: true// ② RecvNothing: true// ③ RecvNothing: true// ③ check closed w/150ms timeout: true
NilChannel example
t:=td.NewT(&testing.T{})varchchanintok:=t.Recv(ch,td.RecvNothing,0)fmt.Println("nothing to receive from nil channel:",ok)ok=t.Recv(ch,42,0)fmt.Println("something to receive from nil channel:",ok)ok=t.Recv(ch,td.RecvClosed,0)fmt.Println("is a nil channel closed:",ok)// Output:// nothing to receive from nil channel: true// something to receive from nil channel: false// is a nil channel closed: false