diff options
author | Russ Cox <rsc@golang.org> | 2011-03-11 14:47:44 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2011-03-11 14:47:44 -0500 |
commit | cd7ff82c4f7f8cdd828dca2ffdfaaafa88e68dff (patch) | |
tree | e27ed488b523939eb09324b9fcb863d042fc7743 /test | |
parent | 7d84874adb56c2e0d79f3792ab007a88759f22e0 (diff) | |
download | go-cd7ff82c4f7f8cdd828dca2ffdfaaafa88e68dff.tar.gz |
go code: replace closed(c) with x, ok := <-c
R=golang-dev, rog, bradfitzwork, r
CC=golang-dev
http://codereview.appspot.com/4243072
Diffstat (limited to 'test')
-rw-r--r-- | test/chan/perm.go | 15 | ||||
-rw-r--r-- | test/chan/select3.go | 20 | ||||
-rw-r--r-- | test/closedchan.go | 157 | ||||
-rw-r--r-- | test/ddd1.go | 1 | ||||
-rw-r--r-- | test/named1.go | 9 |
5 files changed, 133 insertions, 69 deletions
diff --git a/test/chan/perm.go b/test/chan/perm.go index c725829d1..038ff94e3 100644 --- a/test/chan/perm.go +++ b/test/chan/perm.go @@ -22,21 +22,18 @@ func main() { c <- 0 // ok <-c // ok - //TODO(rsc): uncomment when this syntax is valid for receive+check closed - // x, ok := <-c // ok - // _, _ = x, ok + x, ok := <-c // ok + _, _ = x, ok cr <- 0 // ERROR "send" <-cr // ok - //TODO(rsc): uncomment when this syntax is valid for receive+check closed - // x, ok = <-cr // ok - // _, _ = x, ok + x, ok = <-cr // ok + _, _ = x, ok cs <- 0 // ok <-cs // ERROR "receive" - ////TODO(rsc): uncomment when this syntax is valid for receive+check closed - //// x, ok = <-cs // ERROR "receive" - //// _, _ = x, ok + x, ok = <-cs // ERROR "receive" + _, _ = x, ok select { case c <- 0: // ok diff --git a/test/chan/select3.go b/test/chan/select3.go index 47941063c..b4e8f8e4b 100644 --- a/test/chan/select3.go +++ b/test/chan/select3.go @@ -88,12 +88,16 @@ func main() { ch <- 7 }) - // receiving (a small number of times) from a closed channel never blocks + // receiving from a closed channel never blocks testBlock(never, func() { for i := 0; i < 10; i++ { if <-closedch != 0 { panic("expected zero value when reading from closed channel") } + if x, ok := <-closedch; x != 0 || ok { + println("closedch:", x, ok) + panic("expected 0, false from closed channel") + } } }) @@ -191,12 +195,24 @@ func main() { case <-closedch: } }) + testBlock(never, func() { + select { + case x := <-closedch: + _ = x + } + }) + testBlock(never, func() { + select { + case x, ok := <-closedch: + _, _ = x, ok + } + }) testPanic(always, func() { select { case closedch <- 7: } }) - + // select should not get confused if it sees itself testBlock(always, func() { c := make(chan int) diff --git a/test/closedchan.go b/test/closedchan.go index 46d9d0f5d..95314b334 100644 --- a/test/closedchan.go +++ b/test/closedchan.go @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Test close(c), closed(c). +// Test close(c), receive of closed channel. // // TODO(rsc): Doesn't check behavior of close(c) when there // are blocked senders/receivers. @@ -14,10 +14,11 @@ package main type Chan interface { Send(int) Nbsend(int) bool - Recv() int + Recv() (int) Nbrecv() (int, bool) + Recv2() (int, bool) + Nbrecv2() (int, bool, bool) Close() - Closed() bool Impl() string } @@ -52,12 +53,23 @@ func (c XChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c XChan) Close() { - close(c) +func (c XChan) Recv2() (int, bool) { + x, ok := <-c + return x, ok +} + +func (c XChan) Nbrecv2() (int, bool, bool) { + select { + case x, ok := <-c: + return x, ok, true + default: + return 0, false, false + } + panic("nbrecv2") } -func (c XChan) Closed() bool { - return closed(c) +func (c XChan) Close() { + close(c) } func (c XChan) Impl() string { @@ -101,12 +113,26 @@ func (c SChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c SChan) Close() { - close(c) +func (c SChan) Recv2() (int, bool) { + select { + case x, ok := <-c: + return x, ok + } + panic("recv") } -func (c SChan) Closed() bool { - return closed(c) +func (c SChan) Nbrecv2() (int, bool, bool) { + select { + default: + return 0, false, false + case x, ok := <-c: + return x, ok, true + } + panic("nbrecv") +} + +func (c SChan) Close() { + close(c) } func (c SChan) Impl() string { @@ -156,12 +182,28 @@ func (c SSChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c SSChan) Close() { - close(c) +func (c SSChan) Recv2() (int, bool) { + select { + case <-dummy: + case x, ok := <-c: + return x, ok + } + panic("recv") } -func (c SSChan) Closed() bool { - return closed(c) +func (c SSChan) Nbrecv2() (int, bool, bool) { + select { + case <-dummy: + default: + return 0, false, false + case x, ok := <-c: + return x, ok, true + } + panic("nbrecv") +} + +func (c SSChan) Close() { + close(c) } func (c SSChan) Impl() string { @@ -179,29 +221,23 @@ func shouldPanic(f func()) { } func test1(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("test1: Closed before Recv zero:", c.Impl()) - } - for i := 0; i < 3; i++ { // recv a close signal (a zero value) if x := c.Recv(); x != 0 { - println("test1: recv on closed got non-zero:", x, c.Impl()) + println("test1: recv on closed:", x, c.Impl()) } - - // should now be closed. - if !c.Closed() { - println("test1: not closed after recv zero", c.Impl()) + if x, ok := c.Recv2(); x != 0 || ok { + println("test1: recv2 on closed:", x, ok, c.Impl()) } - // should work with ,ok: received a value without blocking, so ok == true. - x, ok := c.Nbrecv() - if !ok { - println("test1: recv on closed got not ok", c.Impl()) + // should work with select: received a value without blocking, so selected == true. + x, selected := c.Nbrecv() + if x != 0 || !selected { + println("test1: recv on closed nb:", x, selected, c.Impl()) } - if x != 0 { - println("test1: recv ,ok on closed got non-zero:", x, c.Impl()) + x, ok, selected := c.Nbrecv2() + if x != 0 || ok || !selected { + println("test1: recv2 on closed nb:", x, ok, selected, c.Impl()) } } @@ -221,11 +257,6 @@ func test1(c Chan) { } func testasync1(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("testasync1: Closed before Recv zero:", c.Impl()) - } - // should be able to get the last value via Recv if x := c.Recv(); x != 1 { println("testasync1: Recv did not get 1:", x, c.Impl()) @@ -235,19 +266,31 @@ func testasync1(c Chan) { } func testasync2(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("testasync2: Closed before Recv zero:", c.Impl()) + // should be able to get the last value via Recv2 + if x, ok := c.Recv2(); x != 1 || !ok { + println("testasync1: Recv did not get 1, true:", x, ok, c.Impl()) } + test1(c) +} + +func testasync3(c Chan) { // should be able to get the last value via Nbrecv - if x, ok := c.Nbrecv(); !ok || x != 1 { - println("testasync2: Nbrecv did not get 1, true:", x, ok, c.Impl()) + if x, selected := c.Nbrecv(); x != 1 || !selected { + println("testasync2: Nbrecv did not get 1, true:", x, selected, c.Impl()) } test1(c) } +func testasync4(c Chan) { + // should be able to get the last value via Nbrecv2 + if x, ok, selected := c.Nbrecv2(); x != 1 || !ok || !selected { + println("testasync2: Nbrecv did not get 1, true, true:", x, ok, selected, c.Impl()) + } + test1(c) +} + func closedsync() chan int { c := make(chan int) close(c) @@ -261,15 +304,27 @@ func closedasync() chan int { return c } +var mks = []func(chan int) Chan { + func(c chan int) Chan { return XChan(c) }, + func(c chan int) Chan { return SChan(c) }, + func(c chan int) Chan { return SSChan(c) }, +} + +var testcloseds = []func(Chan) { + testasync1, + testasync2, + testasync3, + testasync4, +} + func main() { - test1(XChan(closedsync())) - test1(SChan(closedsync())) - test1(SSChan(closedsync())) - - testasync1(XChan(closedasync())) - testasync1(SChan(closedasync())) - testasync1(SSChan(closedasync())) - testasync2(XChan(closedasync())) - testasync2(SChan(closedasync())) - testasync2(SSChan(closedasync())) + for _, mk := range mks { + test1(mk(closedsync())) + } + + for _, testclosed := range testcloseds { + for _, mk := range mks { + testclosed(mk(closedasync())) + } + } } diff --git a/test/ddd1.go b/test/ddd1.go index fcd32c282..ff6342843 100644 --- a/test/ddd1.go +++ b/test/ddd1.go @@ -35,7 +35,6 @@ func bad(args ...int) { ch := make(chan int) close(ch...) // ERROR "[.][.][.]" _ = len(args...) // ERROR "[.][.][.]" - _ = closed(ch...) // ERROR "[.][.][.]" _ = new(int...) // ERROR "[.][.][.]" n := 10 _ = make([]byte, n...) // ERROR "[.][.][.]" diff --git a/test/named1.go b/test/named1.go index 1776313f0..7e7aab9c1 100644 --- a/test/named1.go +++ b/test/named1.go @@ -43,10 +43,6 @@ func main() { _, b = m[2] // ERROR "cannot .* bool.*type Bool" m[2] = 1, b // ERROR "cannot use.*type Bool.*as type bool" - ////TODO(rsc): uncomment when this syntax is valid for receive+check closed - //// _, b = <-c // ERROR "cannot .* bool.*type Bool" - //// _ = b - var inter interface{} _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool" _ = b @@ -57,8 +53,9 @@ func main() { _, b = minter.(Map) // ERROR "cannot .* bool.*type Bool" _ = b - asBool(closed(c)) // ERROR "cannot use.*type bool.*as type Bool" - b = closed(c) // ERROR "cannot use.*type bool.*type Bool" + _, bb := <-c + asBool(bb) // ERROR "cannot use.*type bool.*as type Bool" + _, b = <-c // ERROR "cannot .* bool.*type Bool" _ = b asString(String(slice)) // ERROR "cannot .*type Slice.*type String" |